diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 4efd081..6805bb8 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -54,6 +54,7 @@
 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;
@@ -1575,21 +1576,19 @@
             int flags) throws PackageParserException {
         final String apkPath = fd != null ? debugPathName : apkFile.getAbsolutePath();
 
-        AssetManager assets = null;
+        ApkAssets apkAssets = null;
         XmlResourceParser parser = null;
         try {
-            assets = newConfiguredAssetManager();
-            int cookie = fd != null
-                    ? assets.addAssetFd(fd, debugPathName) : assets.addAssetPath(apkPath);
-            if (cookie == 0) {
+            try {
+                apkAssets = fd != null
+                        ? ApkAssets.loadFromFd(fd, debugPathName, false, false)
+                        : ApkAssets.loadFromPath(apkPath);
+            } catch (IOException e) {
                 throw new PackageParserException(INSTALL_PARSE_FAILED_NOT_APK,
                         "Failed to parse " + apkPath);
             }
 
-            final DisplayMetrics metrics = new DisplayMetrics();
-            metrics.setToDefaults();
-
-            parser = assets.openXmlResourceParser(cookie, ANDROID_MANIFEST_FILENAME);
+            parser = apkAssets.openXml(ANDROID_MANIFEST_FILENAME);
 
             final SigningDetails signingDetails;
             if ((flags & PARSE_COLLECT_CERTIFICATES) != 0) {
@@ -1615,7 +1614,7 @@
                     "Failed to parse " + apkPath, e);
         } finally {
             IoUtils.closeQuietly(parser);
-            IoUtils.closeQuietly(assets);
+            IoUtils.closeQuietly(apkAssets);
         }
     }
 
diff --git a/core/java/android/content/res/ApkAssets.java b/core/java/android/content/res/ApkAssets.java
new file mode 100644
index 0000000..b087c48
--- /dev/null
+++ b/core/java/android/content/res/ApkAssets.java
@@ -0,0 +1,221 @@
+/*
+ * 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 7866560..78370f4 100644
--- a/core/java/android/content/res/AssetManager.java
+++ b/core/java/android/content/res/AssetManager.java
@@ -18,9 +18,11 @@
 
 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;
@@ -28,10 +30,18 @@
 import android.util.SparseArray;
 import android.util.TypedValue;
 
-import java.io.FileDescriptor;
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.util.Preconditions;
+
+import java.io.BufferedReader;
+import java.io.FileInputStream;
 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;
 
 /**
@@ -42,7 +52,17 @@
  * bytes.
  */
 public final class AssetManager implements AutoCloseable {
-    /* modes used when opening an asset */
+    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];
 
     /**
      * Mode for {@link #open(String, int)}: no specific information about how
@@ -65,146 +85,246 @@
      */
     public static final int ACCESS_BUFFER = 3;
 
-    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;
+    @GuardedBy("this") private final TypedValue mValue = new TypedValue();
+    @GuardedBy("this") private final long[] mOffsets = new long[2];
 
-    private final TypedValue mValue = new TypedValue();
-    private final long[] mOffsets = new long[2];
-    
-    // For communication with native code.
-    private long mObject;
+    // Pointer to native implementation, stuffed inside a long.
+    @GuardedBy("this") private long mObject;
 
-    private StringBlock mStringBlocks[] = null;
-    
-    private int mNumRefs = 1;
-    private boolean mOpen = true;
-    private HashMap<Long, RuntimeException> mRefStacks;
- 
+    // The loaded asset paths.
+    @GuardedBy("this") private ApkAssets[] mApkAssets;
+
+    // Debug/reference counting implementation.
+    @GuardedBy("this") private boolean mOpen = true;
+    @GuardedBy("this") private int mNumRefs = 1;
+    @GuardedBy("this") 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() {
-        synchronized (this) {
-            if (DEBUG_REFS) {
-                mNumRefs = 0;
-                incRefsLocked(this.hashCode());
-            }
-            init(false);
-            if (localLOGV) Log.v(TAG, "New asset manager: " + this);
-            ensureSystemAssets();
+        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());
         }
     }
 
-    private static void ensureSystemAssets() {
-        synchronized (sSync) {
-            if (sSystem == null) {
-                AssetManager system = new AssetManager(true);
-                system.makeStringBlocks(null);
-                sSystem = system;
-            }
+    /**
+     * This must be called from Zygote so that system assets are shared by all applications.
+     * @hide
+     */
+    private static void createSystemAssetsInZygoteLocked() {
+        if (sSystem != null) {
+            return;
         }
-    }
-    
-    private AssetManager(boolean isSystem) {
-        if (DEBUG_REFS) {
-            synchronized (this) {
-                mNumRefs = 0;
-                incRefsLocked(this.hashCode());
+
+        // 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*/));
+
+            // Load all static RROs.
+            try (FileInputStream fis = new FileInputStream(
+                    "/data/resource-cache/overlays.list");
+                 BufferedReader br = new BufferedReader(new InputStreamReader(fis))) {
+                // Acquire a lock so that any idmap scanning doesn't impact the current set.
+                try (FileLock flock = fis.getChannel().lock(0, Long.MAX_VALUE,
+                        true /*shared*/)) {
+                    for (String line; (line = br.readLine()) != null; ) {
+                        String idmapPath = line.split(" ")[1];
+                        apkAssets.add(
+                                ApkAssets.loadOverlayFromPath(idmapPath, true /*system*/));
+                    }
+                }
             }
+
+            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);
         }
-        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() {
-        ensureSystemAssets();
-        return sSystem;
+        synchronized (sSync) {
+            createSystemAssetsInZygoteLocked();
+            return sSystem;
+        }
     }
 
     /**
      * Close this asset manager.
      */
+    @Override
     public void close() {
-        synchronized(this) {
-            //System.out.println("Release: num=" + mNumRefs
-            //                   + ", released=" + mReleased);
-            if (mOpen) {
-                mOpen = false;
-                decRefsLocked(this.hashCode());
-            }
-        }
-    }
-
-    /**
-     * Retrieves the string value associated with a particular resource
-     * identifier for the current configuration.
-     *
-     * @param resId the resource identifier to load
-     * @return the string value, or {@code null}
-     */
-    @Nullable
-    final CharSequence getResourceText(@StringRes int resId) {
         synchronized (this) {
-            final TypedValue outValue = mValue;
-            if (getResourceValue(resId, 0, outValue, true)) {
-                return outValue.coerceToString();
+            if (!mOpen) {
+                return;
             }
-            return null;
+
+            mOpen = false;
+            decRefsLocked(hashCode());
         }
     }
 
     /**
-     * Retrieves the string value associated with a particular resource
-     * identifier for the current configuration.
+     * Changes the asset paths in this AssetManager. This replaces the {@link #addAssetPath(String)}
+     * family of methods.
      *
-     * @param resId the resource identifier to load
-     * @param bagEntryId
-     * @return the string value, or {@code null}
+     * @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
      */
-    @Nullable
-    final CharSequence getResourceBagText(@StringRes int resId, int bagEntryId) {
+    public void setApkAssets(@NonNull ApkAssets[] apkAssets, boolean invalidateCaches) {
+        Preconditions.checkNotNull(apkAssets, "apkAssets");
         synchronized (this) {
-            final TypedValue outValue = mValue;
-            final int block = loadResourceBagValue(resId, bagEntryId, outValue, true);
-            if (block < 0) {
-                return null;
+            ensureValidLocked();
+            mApkAssets = apkAssets;
+            nativeSetApkAssets(mObject, apkAssets, invalidateCaches);
+            if (invalidateCaches) {
+                // Invalidate all caches.
+                invalidateCachesLocked(-1);
             }
-
-            // Convert the changing configurations flags populated by native code.
-            outValue.changingConfigurations = ActivityInfo.activityInfoConfigNativeToJava(
-                    outValue.changingConfigurations);
-
-            if (outValue.type == TypedValue.TYPE_STRING) {
-                return mStringBlocks[block].get(outValue.data);
-            }
-            return outValue.coerceToString();
         }
     }
 
     /**
-     * Retrieves the string array associated with a particular resource
-     * identifier for the current configuration.
+     * Invalidates the caches in this AssetManager according to the bitmask `diff`.
      *
-     * @param resId the resource identifier of the string array
-     * @return the string array, or {@code null}
+     * @param diff The bitmask of changes generated by {@link Configuration#diff(Configuration)}.
+     * @see ActivityInfo.Config
      */
-    @Nullable
-    final String[] getResourceStringArray(@ArrayRes int resId) {
-        return getArrayStringResource(resId);
+    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.
+     */
+    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.
+     */
+    private void ensureOpenLocked() {
+        if (!mOpen) {
+            throw new RuntimeException("AssetManager has been closed");
+        }
     }
 
     /**
@@ -219,11 +339,14 @@
      * @return {@code true} if the data was loaded into {@code outValue},
      *         {@code false} otherwise
      */
-    final boolean getResourceValue(@AnyRes int resId, int densityDpi, @NonNull TypedValue outValue,
+    boolean getResourceValue(@AnyRes int resId, int densityDpi, @NonNull TypedValue outValue,
             boolean resolveRefs) {
+        Preconditions.checkNotNull(outValue, "outValue");
         synchronized (this) {
-            final int block = loadResourceValue(resId, (short) densityDpi, outValue, resolveRefs);
-            if (block < 0) {
+            ensureValidLocked();
+            final int cookie = nativeGetResourceValue(
+                    mObject, resId, (short) densityDpi, outValue, resolveRefs);
+            if (cookie <= 0) {
                 return false;
             }
 
@@ -232,38 +355,156 @@
                     outValue.changingConfigurations);
 
             if (outValue.type == TypedValue.TYPE_STRING) {
-                outValue.string = mStringBlocks[block].get(outValue.data);
+                outValue.string = mApkAssets[cookie - 1].getStringFromPool(outValue.data);
             }
             return true;
         }
     }
 
     /**
+     * Retrieves the string value associated with a particular resource
+     * identifier for the current configuration.
+     *
+     * @param resId the resource identifier to load
+     * @return the string value, or {@code null}
+     */
+    @Nullable CharSequence getResourceText(@StringRes int resId) {
+        synchronized (this) {
+            final TypedValue outValue = mValue;
+            if (getResourceValue(resId, 0, outValue, true)) {
+                return outValue.coerceToString();
+            }
+            return null;
+        }
+    }
+
+    /**
+     * Retrieves the string value associated with a particular resource
+     * identifier for the current configuration.
+     *
+     * @param resId the resource identifier to load
+     * @param bagEntryId the index into the bag to load
+     * @return the string value, or {@code null}
+     */
+    @Nullable 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) {
+                return null;
+            }
+
+            // Convert the changing configurations flags populated by native code.
+            outValue.changingConfigurations = ActivityInfo.activityInfoConfigNativeToJava(
+                    outValue.changingConfigurations);
+
+            if (outValue.type == TypedValue.TYPE_STRING) {
+                return mApkAssets[cookie - 1].getStringFromPool(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.
+     *
+     * @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
+     */
+    int getResourceArray(@ArrayRes int resId, @NonNull int[] outData) {
+        Preconditions.checkNotNull(outData, "outData");
+        synchronized (this) {
+            ensureValidLocked();
+            return nativeGetResourceArray(mObject, resId, outData);
+        }
+    }
+
+    /**
+     * Retrieves the string array associated with a particular resource
+     * identifier for the current configuration.
+     *
+     * @param resId the resource identifier of the string array
+     * @return the string array, or {@code null}
+     */
+    @Nullable String[] getResourceStringArray(@ArrayRes int resId) {
+        synchronized (this) {
+            ensureValidLocked();
+            return nativeGetResourceStringArray(mObject, resId);
+        }
+    }
+
+    /**
      * Retrieve the text array associated with a particular resource
      * identifier.
      *
      * @param resId the resource id of the string array
      */
-    final @Nullable CharSequence[] getResourceTextArray(@ArrayRes int resId) {
+    @Nullable CharSequence[] getResourceTextArray(@ArrayRes int resId) {
         synchronized (this) {
-            final int[] rawInfoArray = getArrayStringInfo(resId);
+            ensureValidLocked();
+            final int[] rawInfoArray = nativeGetResourceStringArrayInfo(mObject, 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++) {
-                block = rawInfoArray[i];
-                index = rawInfoArray[i + 1];
-                retArray[j] = index >= 0 ? mStringBlocks[block].get(index) : null;
+                int cookie = rawInfoArray[i];
+                int index = rawInfoArray[i + 1];
+                retArray[j] = (index >= 0 && cookie > 0)
+                        ? mApkAssets[cookie - 1].getStringFromPool(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
@@ -277,73 +518,88 @@
      * @return {@code true} if the data was loaded into {@code outValue},
      *         {@code false} otherwise
      */
-    final boolean getThemeValue(long theme, @AnyRes int resId, @NonNull TypedValue outValue,
+    boolean getThemeValue(long theme, @AnyRes int resId, @NonNull TypedValue outValue,
             boolean resolveRefs) {
-        final int block = loadThemeAttributeValue(theme, resId, 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) {
-            final StringBlock[] blocks = ensureStringBlocks();
-            outValue.string = blocks[block].get(outValue.data);
-        }
-        return true;
-    }
-
-    /**
-     * Ensures the string blocks are loaded.
-     *
-     * @return the string blocks
-     */
-    @NonNull
-    final StringBlock[] ensureStringBlocks() {
+        Preconditions.checkNotNull(outValue, "outValue");
         synchronized (this) {
-            if (mStringBlocks == null) {
-                makeStringBlocks(sSystem.mStringBlocks);
+            ensureValidLocked();
+            final int cookie = nativeThemeGetAttributeValue(mObject, theme, resId, outValue,
+                    resolveRefs);
+            if (cookie <= 0) {
+                return false;
             }
-            return mStringBlocks;
+
+            // 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;
         }
     }
 
-    /*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);
-            }
-        }
-    }
-
-    /*package*/ final CharSequence getPooledStringForCookie(int cookie, int id) {
+    void dumpTheme(long theme, int priority, String tag, String prefix) {
         synchronized (this) {
-            // Cookies map to string blocks starting at 1.
-            return mStringBlocks[cookie - 1].get(id);
+            ensureValidLocked();
+            nativeThemeDump(mObject, theme, priority, tag, prefix);
         }
     }
 
+    @Nullable String getResourceName(@AnyRes int resId) {
+        synchronized (this) {
+            ensureValidLocked();
+            return nativeGetResourceName(mObject, resId);
+        }
+    }
+
+    @Nullable String getResourcePackageName(@AnyRes int resId) {
+        synchronized (this) {
+            ensureValidLocked();
+            return nativeGetResourcePackageName(mObject, resId);
+        }
+    }
+
+    @Nullable String getResourceTypeName(@AnyRes int resId) {
+        synchronized (this) {
+            ensureValidLocked();
+            return nativeGetResourceTypeName(mObject, resId);
+        }
+    }
+
+    @Nullable String getResourceEntryName(@AnyRes int resId) {
+        synchronized (this) {
+            ensureValidLocked();
+            return nativeGetResourceEntryName(mObject, resId);
+        }
+    }
+
+    @AnyRes int getResourceIdentifier(@NonNull String name, @Nullable String defType,
+            @Nullable String defPackage) {
+        synchronized (this) {
+            ensureValidLocked();
+            // name is checked in JNI.
+            return nativeGetResourceIdentifier(mObject, name, defType, defPackage);
+        }
+    }
+
+    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 final InputStream open(String fileName) throws IOException {
+    public @NonNull InputStream open(@NonNull String fileName) throws IOException {
         return open(fileName, ACCESS_STREAMING);
     }
 
@@ -353,8 +609,7 @@
      * 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
@@ -364,34 +619,40 @@
      * @see #open(String)
      * @see #list
      */
-    public final InputStream open(String fileName, int accessMode)
-        throws IOException {
+    public @NonNull InputStream open(@NonNull String fileName, int accessMode) throws IOException {
+        Preconditions.checkNotNull(fileName, "fileName");
         synchronized (this) {
-            if (!mOpen) {
-                throw new RuntimeException("Assetmanager has been closed");
+            ensureOpenLocked();
+            final long asset = nativeOpenAsset(mObject, fileName, accessMode);
+            if (asset == 0) {
+                throw new FileNotFoundException("Asset file: " + fileName);
             }
-            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);
     }
 
-    public final AssetFileDescriptor openFd(String fileName)
-            throws IOException {
+    /**
+     * 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");
         synchronized (this) {
-            if (!mOpen) {
-                throw new RuntimeException("Assetmanager has been closed");
+            ensureOpenLocked();
+            final ParcelFileDescriptor pfd = nativeOpenAssetFd(mObject, fileName, mOffsets);
+            if (pfd == null) {
+                throw new FileNotFoundException("Asset file: " + fileName);
             }
-            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);
     }
 
     /**
@@ -406,90 +667,121 @@
      * 
      * @see #open
      */
-    public native final String[] list(String path)
-        throws IOException;
+    public @Nullable String[] list(@NonNull String path) throws IOException {
+        Preconditions.checkNotNull(path, "path");
+        synchronized (this) {
+            ensureValidLocked();
+            return nativeList(mObject, path);
+        }
+    }
 
     /**
-     * {@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 final InputStream openNonAsset(String fileName) throws IOException {
+    public @NonNull InputStream openNonAsset(@NonNull 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 final InputStream openNonAsset(String fileName, int accessMode)
-        throws IOException {
+    public @NonNull InputStream openNonAsset(@NonNull 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 final InputStream openNonAsset(int cookie, String fileName)
-        throws IOException {
+    public @NonNull InputStream openNonAsset(int cookie, @NonNull 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 final InputStream openNonAsset(int cookie, String fileName, int accessMode)
-        throws IOException {
+    public @NonNull InputStream openNonAsset(int cookie, @NonNull String fileName, int accessMode)
+            throws IOException {
+        Preconditions.checkNotNull(fileName, "fileName");
         synchronized (this) {
-            if (!mOpen) {
-                throw new RuntimeException("Assetmanager has been closed");
+            ensureOpenLocked();
+            final long asset = nativeOpenNonAsset(mObject, cookie, fileName, accessMode);
+            if (asset == 0) {
+                throw new FileNotFoundException("Asset absolute file: " + fileName);
             }
-            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);
     }
 
-    public final AssetFileDescriptor openNonAssetFd(String 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)
             throws IOException {
         return openNonAssetFd(0, fileName);
     }
-    
-    public final AssetFileDescriptor openNonAssetFd(int cookie,
-            String fileName) throws IOException {
+
+    /**
+     * 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");
         synchronized (this) {
-            if (!mOpen) {
-                throw new RuntimeException("Assetmanager has been closed");
+            ensureOpenLocked();
+            final ParcelFileDescriptor pfd =
+                    nativeOpenNonAssetFd(mObject, cookie, fileName, mOffsets);
+            if (pfd == null) {
+                throw new FileNotFoundException("Asset absolute file: " + fileName);
             }
-            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);
     }
     
     /**
@@ -497,7 +789,7 @@
      * 
      * @param fileName The name of the file to retrieve.
      */
-    public final XmlResourceParser openXmlResourceParser(String fileName)
+    public @NonNull XmlResourceParser openXmlResourceParser(@NonNull String fileName)
             throws IOException {
         return openXmlResourceParser(0, fileName);
     }
@@ -508,270 +800,265 @@
      * @param cookie Identifier of the package to be opened.
      * @param fileName The name of the file to retrieve.
      */
-    public final XmlResourceParser openXmlResourceParser(int cookie,
-            String fileName) throws IOException {
-        XmlBlock block = openXmlBlockAsset(cookie, fileName);
-        XmlResourceParser rp = block.newParser();
-        block.close();
-        return rp;
+    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;
+        }
     }
 
     /**
-     * {@hide}
-     * Retrieve a non-asset as a compiled XML file.  Not for use by
-     * applications.
+     * Retrieve a non-asset as a compiled XML file.  Not for use by applications.
      * 
      * @param fileName The name of the file to retrieve.
+     * @hide
      */
-    /*package*/ final XmlBlock openXmlBlockAsset(String fileName)
-            throws IOException {
+    @NonNull XmlBlock openXmlBlockAsset(@NonNull 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
      */
-    /*package*/ final XmlBlock openXmlBlockAsset(int cookie, String fileName)
-        throws IOException {
+    @NonNull XmlBlock openXmlBlockAsset(int cookie, @NonNull String fileName) throws IOException {
+        Preconditions.checkNotNull(fileName, "fileName");
         synchronized (this) {
-            if (!mOpen) {
-                throw new RuntimeException("Assetmanager has been closed");
+            ensureOpenLocked();
+            final long xmlBlock = nativeOpenXmlAsset(mObject, cookie, fileName);
+            if (xmlBlock == 0) {
+                throw new FileNotFoundException("Asset XML file: " + fileName);
             }
-            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);
     }
 
-    /*package*/ void xmlBlockGone(int id) {
+    void xmlBlockGone(int id) {
         synchronized (this) {
             decRefsLocked(id);
         }
     }
 
-    /*package*/ final long createTheme() {
+    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");
         synchronized (this) {
-            if (!mOpen) {
-                throw new RuntimeException("Assetmanager has been closed");
-            }
-            long res = newTheme();
-            incRefsLocked(res);
-            return res;
+            // 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);
         }
     }
 
-    /*package*/ final void releaseTheme(long theme) {
+    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) {
-            deleteTheme(theme);
-            decRefsLocked(theme);
+            // 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);
+        }
+    }
+
+    void applyStyleToTheme(long themePtr, @StyleRes int resId, boolean force) {
+        synchronized (this) {
+            // Need to synchronize on AssetManager because we will be accessing
+            // the native implementation of AssetManager.
+            ensureValidLocked();
+            nativeThemeApplyStyle(mObject, themePtr, resId, force);
+        }
+    }
+
+    @Override
     protected void finalize() throws Throwable {
-        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 (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);
                 }
             }
-            destroy();
-        } finally {
-            super.finalize();
+        }
+
+        if (mObject != 0) {
+            nativeDestroy(mObject);
         }
     }
-    
+
+    /* 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 mAsset;
+            return mAssetNativePtr;
         }
-        private AssetInputStream(long asset)
-        {
-            mAsset = asset;
-            mLength = getAssetLength(asset);
+
+        private AssetInputStream(long assetNativePtr) {
+            mAssetNativePtr = assetNativePtr;
+            mLength = nativeAssetGetLength(assetNativePtr);
         }
+
+        @Override
         public final int read() throws IOException {
-            return readAssetChar(mAsset);
+            ensureOpen();
+            return nativeAssetReadChar(mAssetNativePtr);
         }
-        public final boolean markSupported() {
-            return true;
+
+        @Override
+        public final int read(@NonNull byte[] b) throws IOException {
+            ensureOpen();
+            Preconditions.checkNotNull(b, "b");
+            return nativeAssetRead(mAssetNativePtr, b, 0, b.length);
         }
-        public final int available() throws IOException {
-            long len = getAssetRemainingLength(mAsset);
-            return len > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int)len;
+
+        @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 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 {
-            long pos = seekAsset(mAsset, 0, 0);
-            if ((pos+n) > mLength) {
-                n = mLength-pos;
+            ensureOpen();
+            long pos = nativeAssetSeek(mAssetNativePtr, 0, 0);
+            if ((pos + n) > mLength) {
+                n = mLength - pos;
             }
             if (n > 0) {
-                seekAsset(mAsset, n, 0);
+                nativeAssetSeek(mAssetNativePtr, n, 0);
             }
             return n;
         }
 
-        protected void finalize() throws Throwable
-        {
+        @Override
+        public final int available() throws IOException {
+            ensureOpen();
+            final long len = nativeAssetGetRemainingLength(mAssetNativePtr);
+            return len > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) len;
+        }
+
+        @Override
+        public final boolean markSupported() {
+            return true;
+        }
+
+        @Override
+        public final void mark(int readlimit) {
+            ensureOpen();
+            mMarkPos = nativeAssetSeek(mAssetNativePtr, 0, 0);
+        }
+
+        @Override
+        public final void reset() throws IOException {
+            ensureOpen();
+            nativeAssetSeek(mAssetNativePtr, mMarkPos, -1);
+        }
+
+        @Override
+        public final void close() throws IOException {
+            if (mAssetNativePtr != 0) {
+                nativeAssetDestroy(mAssetNativePtr);
+                mAssetNativePtr = 0;
+
+                synchronized (AssetManager.this) {
+                    decRefsLocked(hashCode());
+                }
+            }
+        }
+
+        @Override
+        protected void finalize() throws Throwable {
             close();
         }
 
-        private long mAsset;
-        private long mLength;
-        private long mMarkPos;
-    }
-
-    /**
-     * 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;
+        private void ensureOpen() {
+            if (mAssetNativePtr == 0) {
+                throw new IllegalStateException("AssetInputStream is closed");
+            }
         }
     }
 
-    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;
-        }
-    }
-
-    private native int addAssetFdNative(FileDescriptor fd, String debugPathName,
-            boolean appAsLib);
-
-    /**
-     * 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;
-        }
-    }
-
-    /**
-     * 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;
-        }
-
-        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 native final boolean isUpToDate();
+    public boolean isUpToDate() {
+        for (ApkAssets apkAssets : getApkAssets()) {
+            if (!apkAssets.isUpToDate()) {
+                return false;
+            }
+        }
+        return true;
+    }
 
     /**
      * Get the locales that this asset manager contains data for.
@@ -784,7 +1071,12 @@
      * 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 native final String[] getLocales();
+    public String[] getLocales() {
+        synchronized (this) {
+            ensureValidLocked();
+            return nativeGetLocales(mObject, false /*excludeSystem*/);
+        }
+    }
 
     /**
      * Same as getLocales(), except that locales that are only provided by the system (i.e. those
@@ -794,131 +1086,57 @@
      * assets support Cherokee and French, getLocales() would return
      * [Cherokee, English, French, German], while getNonSystemLocales() would return
      * [Cherokee, French].
-     * {@hide}
+     * @hide
      */
-    public native final String[] getNonSystemLocales();
-
-    /** {@hide} */
-    public native final Configuration[] getSizeConfigurations();
+    public String[] getNonSystemLocales() {
+        synchronized (this) {
+            ensureValidLocked();
+            return nativeGetLocales(mObject, true /*excludeSystem*/);
+        }
+    }
 
     /**
-     * Change the configuation used when retrieving resources.  Not for use by
+     * @hide
+     */
+    Configuration[] getSizeConfigurations() {
+        synchronized (this) {
+            ensureValidLocked();
+            return nativeGetSizeConfigurations(mObject);
+        }
+    }
+
+    /**
+     * Change the configuration used when retrieving resources.  Not for use by
      * applications.
-     * {@hide}
+     * @hide
      */
-    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);
+    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);
+        }
+    }
 
     /**
-     * Retrieve the resource identifier for the given resource name.
+     * @hide
      */
-    /*package*/ native final int getResourceIdentifier(String name,
-                                                       String defType,
-                                                       String defPackage);
+    public SparseArray<String> getAssignedPackageIdentifiers() {
+        synchronized (this) {
+            ensureValidLocked();
+            return nativeGetAssignedPackageIdentifiers(mObject);
+        }
+    }
 
-    /*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}
-     */
-    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();
-
-    private final void incRefsLocked(long id) {
+    private void incRefsLocked(long id) {
         if (DEBUG_REFS) {
             if (mRefStacks == null) {
-                mRefStacks = new HashMap<Long, RuntimeException>();
+                mRefStacks = new HashMap<>();
             }
             RuntimeException ex = new RuntimeException();
             ex.fillInStackTrace();
@@ -926,16 +1144,117 @@
         }
         mNumRefs++;
     }
-    
-    private final void decRefsLocked(long id) {
+
+    private void decRefsLocked(long id) {
         if (DEBUG_REFS && mRefStacks != null) {
             mRefStacks.remove(id);
         }
         mNumRefs--;
-        //System.out.println("Dec streams: mNumRefs=" + mNumRefs
-        //                   + " mReleased=" + mReleased);
-        if (mNumRefs == 0) {
-            destroy();
+        if (mNumRefs == 0 && mObject != 0) {
+            nativeDestroy(mObject);
+            mObject = 0;
         }
     }
+
+    // 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 e173653c..8f58891 100644
--- a/core/java/android/content/res/Resources.java
+++ b/core/java/android/content/res/Resources.java
@@ -590,7 +590,7 @@
      */
     @NonNull
     public int[] getIntArray(@ArrayRes int id) throws NotFoundException {
-        int[] res = mResourcesImpl.getAssets().getArrayIntResource(id);
+        int[] res = mResourcesImpl.getAssets().getResourceIntArray(id);
         if (res != null) {
             return res;
         }
@@ -613,13 +613,13 @@
     @NonNull
     public TypedArray obtainTypedArray(@ArrayRes int id) throws NotFoundException {
         final ResourcesImpl impl = mResourcesImpl;
-        int len = impl.getAssets().getArraySize(id);
+        int len = impl.getAssets().getResourceArraySize(id);
         if (len < 0) {
             throw new NotFoundException("Array resource ID #0x" + Integer.toHexString(id));
         }
         
         TypedArray array = TypedArray.obtain(this, len);
-        array.mLength = impl.getAssets().retrieveArray(id, array.mData);
+        array.mLength = impl.getAssets().getResourceArray(id, array.mData);
         array.mIndices[0] = 0;
         
         return array;
@@ -1789,8 +1789,7 @@
         // 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.mParseState, attrs,
-                array.mData, array.mIndices);
+        mResourcesImpl.getAssets().retrieveAttributes(parser, 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 97cb78b..2a4b278 100644
--- a/core/java/android/content/res/ResourcesImpl.java
+++ b/core/java/android/content/res/ResourcesImpl.java
@@ -168,7 +168,6 @@
         mDisplayAdjustments = displayAdjustments;
         mConfiguration.setToDefaults();
         updateConfiguration(config, metrics, displayAdjustments.getCompatibilityInfo());
-        mAssets.ensureStringBlocks();
     }
 
     public DisplayAdjustments getDisplayAdjustments() {
@@ -1274,8 +1273,7 @@
 
         void applyStyle(int resId, boolean force) {
             synchronized (mKey) {
-                AssetManager.applyThemeStyle(mTheme, resId, force);
-
+                mAssets.applyStyleToTheme(mTheme, resId, force);
                 mThemeResId = resId;
                 mKey.append(resId, force);
             }
@@ -1284,7 +1282,7 @@
         void setTo(ThemeImpl other) {
             synchronized (mKey) {
                 synchronized (other.mKey) {
-                    AssetManager.copyTheme(mTheme, other.mTheme);
+                    AssetManager.nativeThemeCopy(mTheme, other.mTheme);
 
                     mThemeResId = other.mThemeResId;
                     mKey.setTo(other.getKey());
@@ -1307,12 +1305,10 @@
                 // out the attributes from the XML file (applying type information
                 // contained in the resources and such).
                 final XmlBlock.Parser parser = (XmlBlock.Parser) set;
-                AssetManager.applyStyle(mTheme, defStyleAttr, defStyleRes,
-                        parser != null ? parser.mParseState : 0,
-                        attrs, attrs.length, array.mDataAddress, array.mIndicesAddress);
+                mAssets.applyStyle(mTheme, defStyleAttr, defStyleRes, parser, attrs,
+                        array.mDataAddress, array.mIndicesAddress);
                 array.mTheme = wrapper;
                 array.mXml = parser;
-
                 return array;
             }
         }
@@ -1329,7 +1325,7 @@
                 }
 
                 final TypedArray array = TypedArray.obtain(wrapper.getResources(), len);
-                AssetManager.resolveAttrs(mTheme, 0, 0, values, attrs, array.mData, array.mIndices);
+                mAssets.resolveAttrs(mTheme, 0, 0, values, attrs, array.mData, array.mIndices);
                 array.mTheme = wrapper;
                 array.mXml = null;
                 return array;
@@ -1349,14 +1345,14 @@
         @Config int getChangingConfigurations() {
             synchronized (mKey) {
                 final @NativeConfig int nativeChangingConfig =
-                        AssetManager.getThemeChangingConfigurations(mTheme);
+                        AssetManager.nativeThemeGetChangingConfigurations(mTheme);
                 return ActivityInfo.activityInfoConfigNativeToJava(nativeChangingConfig);
             }
         }
 
         public void dump(int priority, String tag, String prefix) {
             synchronized (mKey) {
-                AssetManager.dumpTheme(mTheme, priority, tag, prefix);
+                mAssets.dumpTheme(mTheme, priority, tag, prefix);
             }
         }
 
@@ -1385,13 +1381,13 @@
          */
         void rebase() {
             synchronized (mKey) {
-                AssetManager.clearTheme(mTheme);
+                AssetManager.nativeThemeClear(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];
-                    AssetManager.applyThemeStyle(mTheme, resId, force);
+                    mAssets.applyStyleToTheme(mTheme, resId, force);
                 }
             }
         }
diff --git a/core/java/android/content/res/TypedArray.java b/core/java/android/content/res/TypedArray.java
index f33c7516..cbb3c6d 100644
--- a/core/java/android/content/res/TypedArray.java
+++ b/core/java/android/content/res/TypedArray.java
@@ -61,6 +61,15 @@
         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;
@@ -78,7 +87,7 @@
 
     private void resize(int len) {
         mLength = len;
-        final int dataLen = len * AssetManager.STYLE_NUM_ENTRIES;
+        final int dataLen = len * STYLE_NUM_ENTRIES;
         final int indicesLen = len + 1;
         final VMRuntime runtime = VMRuntime.getRuntime();
         if (mDataAddress == 0 || mData.length < dataLen) {
@@ -166,9 +175,9 @@
             throw new RuntimeException("Cannot make calls to a recycled instance!");
         }
 
-        index *= AssetManager.STYLE_NUM_ENTRIES;
+        index *= STYLE_NUM_ENTRIES;
         final int[] data = mData;
-        final int type = data[index+AssetManager.STYLE_TYPE];
+        final int type = data[index + STYLE_TYPE];
         if (type == TypedValue.TYPE_NULL) {
             return null;
         } else if (type == TypedValue.TYPE_STRING) {
@@ -203,9 +212,9 @@
             throw new RuntimeException("Cannot make calls to a recycled instance!");
         }
 
-        index *= AssetManager.STYLE_NUM_ENTRIES;
+        index *= STYLE_NUM_ENTRIES;
         final int[] data = mData;
-        final int type = data[index+AssetManager.STYLE_TYPE];
+        final int type = data[index + STYLE_TYPE];
         if (type == TypedValue.TYPE_NULL) {
             return null;
         } else if (type == TypedValue.TYPE_STRING) {
@@ -242,14 +251,13 @@
             throw new RuntimeException("Cannot make calls to a recycled instance!");
         }
 
-        index *= AssetManager.STYLE_NUM_ENTRIES;
+        index *= STYLE_NUM_ENTRIES;
         final int[] data = mData;
-        final int type = data[index+AssetManager.STYLE_TYPE];
+        final int type = data[index + STYLE_TYPE];
         if (type == TypedValue.TYPE_STRING) {
-            final int cookie = data[index+AssetManager.STYLE_ASSET_COOKIE];
+            final int cookie = data[index + STYLE_ASSET_COOKIE];
             if (cookie < 0) {
-                return mXml.getPooledString(
-                    data[index+AssetManager.STYLE_DATA]).toString();
+                return mXml.getPooledString(data[index + STYLE_DATA]).toString();
             }
         }
         return null;
@@ -274,11 +282,11 @@
             throw new RuntimeException("Cannot make calls to a recycled instance!");
         }
 
-        index *= AssetManager.STYLE_NUM_ENTRIES;
+        index *= STYLE_NUM_ENTRIES;
         final int[] data = mData;
-        final int type = data[index+AssetManager.STYLE_TYPE];
+        final int type = data[index + STYLE_TYPE];
         final @Config int changingConfigs = ActivityInfo.activityInfoConfigNativeToJava(
-                data[index + AssetManager.STYLE_CHANGING_CONFIGURATIONS]);
+                data[index + STYLE_CHANGING_CONFIGURATIONS]);
         if ((changingConfigs & ~allowedChangingConfigs) != 0) {
             return null;
         }
@@ -320,14 +328,14 @@
             throw new RuntimeException("Cannot make calls to a recycled instance!");
         }
 
-        index *= AssetManager.STYLE_NUM_ENTRIES;
+        index *= STYLE_NUM_ENTRIES;
         final int[] data = mData;
-        final int type = data[index+AssetManager.STYLE_TYPE];
+        final int type = data[index + STYLE_TYPE];
         if (type == TypedValue.TYPE_NULL) {
             return defValue;
         } else if (type >= TypedValue.TYPE_FIRST_INT
                 && type <= TypedValue.TYPE_LAST_INT) {
-            return data[index+AssetManager.STYLE_DATA] != 0;
+            return data[index + STYLE_DATA] != 0;
         }
 
         final TypedValue v = mValue;
@@ -359,14 +367,14 @@
             throw new RuntimeException("Cannot make calls to a recycled instance!");
         }
 
-        index *= AssetManager.STYLE_NUM_ENTRIES;
+        index *= STYLE_NUM_ENTRIES;
         final int[] data = mData;
-        final int type = data[index+AssetManager.STYLE_TYPE];
+        final int type = data[index + STYLE_TYPE];
         if (type == TypedValue.TYPE_NULL) {
             return defValue;
         } else if (type >= TypedValue.TYPE_FIRST_INT
                 && type <= TypedValue.TYPE_LAST_INT) {
-            return data[index+AssetManager.STYLE_DATA];
+            return data[index + STYLE_DATA];
         }
 
         final TypedValue v = mValue;
@@ -396,16 +404,16 @@
             throw new RuntimeException("Cannot make calls to a recycled instance!");
         }
 
-        index *= AssetManager.STYLE_NUM_ENTRIES;
+        index *= STYLE_NUM_ENTRIES;
         final int[] data = mData;
-        final int type = data[index+AssetManager.STYLE_TYPE];
+        final int type = data[index + STYLE_TYPE];
         if (type == TypedValue.TYPE_NULL) {
             return defValue;
         } else if (type == TypedValue.TYPE_FLOAT) {
-            return Float.intBitsToFloat(data[index+AssetManager.STYLE_DATA]);
+            return Float.intBitsToFloat(data[index + STYLE_DATA]);
         } else if (type >= TypedValue.TYPE_FIRST_INT
                 && type <= TypedValue.TYPE_LAST_INT) {
-            return data[index+AssetManager.STYLE_DATA];
+            return data[index + STYLE_DATA];
         }
 
         final TypedValue v = mValue;
@@ -446,15 +454,15 @@
         }
 
         final int attrIndex = index;
-        index *= AssetManager.STYLE_NUM_ENTRIES;
+        index *= STYLE_NUM_ENTRIES;
 
         final int[] data = mData;
-        final int type = data[index+AssetManager.STYLE_TYPE];
+        final int type = data[index + STYLE_TYPE];
         if (type == TypedValue.TYPE_NULL) {
             return defValue;
         } else if (type >= TypedValue.TYPE_FIRST_INT
                 && type <= TypedValue.TYPE_LAST_INT) {
-            return data[index+AssetManager.STYLE_DATA];
+            return data[index + STYLE_DATA];
         } else if (type == TypedValue.TYPE_STRING) {
             final TypedValue value = mValue;
             if (getValueAt(index, value)) {
@@ -498,7 +506,7 @@
         }
 
         final TypedValue value = mValue;
-        if (getValueAt(index*AssetManager.STYLE_NUM_ENTRIES, value)) {
+        if (getValueAt(index * STYLE_NUM_ENTRIES, value)) {
             if (value.type == TypedValue.TYPE_ATTRIBUTE) {
                 throw new UnsupportedOperationException(
                         "Failed to resolve attribute at index " + index + ": " + value);
@@ -533,7 +541,7 @@
         }
 
         final TypedValue value = mValue;
-        if (getValueAt(index*AssetManager.STYLE_NUM_ENTRIES, value)) {
+        if (getValueAt(index * STYLE_NUM_ENTRIES, value)) {
             if (value.type == TypedValue.TYPE_ATTRIBUTE) {
                 throw new UnsupportedOperationException(
                         "Failed to resolve attribute at index " + index + ": " + value);
@@ -564,15 +572,15 @@
         }
 
         final int attrIndex = index;
-        index *= AssetManager.STYLE_NUM_ENTRIES;
+        index *= STYLE_NUM_ENTRIES;
 
         final int[] data = mData;
-        final int type = data[index+AssetManager.STYLE_TYPE];
+        final int type = data[index + STYLE_TYPE];
         if (type == TypedValue.TYPE_NULL) {
             return defValue;
         } else if (type >= TypedValue.TYPE_FIRST_INT
                 && type <= TypedValue.TYPE_LAST_INT) {
-            return data[index+AssetManager.STYLE_DATA];
+            return data[index + STYLE_DATA];
         } else if (type == TypedValue.TYPE_ATTRIBUTE) {
             final TypedValue value = mValue;
             getValueAt(index, value);
@@ -612,15 +620,14 @@
         }
 
         final int attrIndex = index;
-        index *= AssetManager.STYLE_NUM_ENTRIES;
+        index *= STYLE_NUM_ENTRIES;
 
         final int[] data = mData;
-        final int type = data[index+AssetManager.STYLE_TYPE];
+        final int type = data[index + STYLE_TYPE];
         if (type == TypedValue.TYPE_NULL) {
             return defValue;
         } else if (type == TypedValue.TYPE_DIMENSION) {
-            return TypedValue.complexToDimension(
-                    data[index + AssetManager.STYLE_DATA], mMetrics);
+            return TypedValue.complexToDimension(data[index + STYLE_DATA], mMetrics);
         } else if (type == TypedValue.TYPE_ATTRIBUTE) {
             final TypedValue value = mValue;
             getValueAt(index, value);
@@ -661,15 +668,14 @@
         }
 
         final int attrIndex = index;
-        index *= AssetManager.STYLE_NUM_ENTRIES;
+        index *= STYLE_NUM_ENTRIES;
 
         final int[] data = mData;
-        final int type = data[index+AssetManager.STYLE_TYPE];
+        final int type = data[index + STYLE_TYPE];
         if (type == TypedValue.TYPE_NULL) {
             return defValue;
         } else if (type == TypedValue.TYPE_DIMENSION) {
-            return TypedValue.complexToDimensionPixelOffset(
-                    data[index + AssetManager.STYLE_DATA], mMetrics);
+            return TypedValue.complexToDimensionPixelOffset(data[index + STYLE_DATA], mMetrics);
         } else if (type == TypedValue.TYPE_ATTRIBUTE) {
             final TypedValue value = mValue;
             getValueAt(index, value);
@@ -711,15 +717,14 @@
         }
 
         final int attrIndex = index;
-        index *= AssetManager.STYLE_NUM_ENTRIES;
+        index *= STYLE_NUM_ENTRIES;
 
         final int[] data = mData;
-        final int type = data[index+AssetManager.STYLE_TYPE];
+        final int type = data[index + STYLE_TYPE];
         if (type == TypedValue.TYPE_NULL) {
             return defValue;
         } else if (type == TypedValue.TYPE_DIMENSION) {
-            return TypedValue.complexToDimensionPixelSize(
-                data[index+AssetManager.STYLE_DATA], mMetrics);
+            return TypedValue.complexToDimensionPixelSize(data[index + STYLE_DATA], mMetrics);
         } else if (type == TypedValue.TYPE_ATTRIBUTE) {
             final TypedValue value = mValue;
             getValueAt(index, value);
@@ -755,16 +760,15 @@
         }
 
         final int attrIndex = index;
-        index *= AssetManager.STYLE_NUM_ENTRIES;
+        index *= STYLE_NUM_ENTRIES;
 
         final int[] data = mData;
-        final int type = data[index+AssetManager.STYLE_TYPE];
+        final int type = data[index + STYLE_TYPE];
         if (type >= TypedValue.TYPE_FIRST_INT
                 && type <= TypedValue.TYPE_LAST_INT) {
-            return data[index+AssetManager.STYLE_DATA];
+            return data[index + STYLE_DATA];
         } else if (type == TypedValue.TYPE_DIMENSION) {
-            return TypedValue.complexToDimensionPixelSize(
-                data[index+AssetManager.STYLE_DATA], mMetrics);
+            return TypedValue.complexToDimensionPixelSize(data[index + STYLE_DATA], mMetrics);
         } else if (type == TypedValue.TYPE_ATTRIBUTE) {
             final TypedValue value = mValue;
             getValueAt(index, value);
@@ -795,15 +799,14 @@
             throw new RuntimeException("Cannot make calls to a recycled instance!");
         }
 
-        index *= AssetManager.STYLE_NUM_ENTRIES;
+        index *= STYLE_NUM_ENTRIES;
         final int[] data = mData;
-        final int type = data[index+AssetManager.STYLE_TYPE];
+        final int type = data[index + STYLE_TYPE];
         if (type >= TypedValue.TYPE_FIRST_INT
                 && type <= TypedValue.TYPE_LAST_INT) {
-            return data[index+AssetManager.STYLE_DATA];
+            return data[index + STYLE_DATA];
         } else if (type == TypedValue.TYPE_DIMENSION) {
-            return TypedValue.complexToDimensionPixelSize(
-                    data[index + AssetManager.STYLE_DATA], mMetrics);
+            return TypedValue.complexToDimensionPixelSize(data[index + STYLE_DATA], mMetrics);
         }
 
         return defValue;
@@ -833,15 +836,14 @@
         }
 
         final int attrIndex = index;
-        index *= AssetManager.STYLE_NUM_ENTRIES;
+        index *= STYLE_NUM_ENTRIES;
 
         final int[] data = mData;
-        final int type = data[index+AssetManager.STYLE_TYPE];
+        final int type = data[index + STYLE_TYPE];
         if (type == TypedValue.TYPE_NULL) {
             return defValue;
         } else if (type == TypedValue.TYPE_FRACTION) {
-            return TypedValue.complexToFraction(
-                data[index+AssetManager.STYLE_DATA], base, pbase);
+            return TypedValue.complexToFraction(data[index + STYLE_DATA], base, pbase);
         } else if (type == TypedValue.TYPE_ATTRIBUTE) {
             final TypedValue value = mValue;
             getValueAt(index, value);
@@ -874,10 +876,10 @@
             throw new RuntimeException("Cannot make calls to a recycled instance!");
         }
 
-        index *= AssetManager.STYLE_NUM_ENTRIES;
+        index *= STYLE_NUM_ENTRIES;
         final int[] data = mData;
-        if (data[index+AssetManager.STYLE_TYPE] != TypedValue.TYPE_NULL) {
-            final int resid = data[index+AssetManager.STYLE_RESOURCE_ID];
+        if (data[index + STYLE_TYPE] != TypedValue.TYPE_NULL) {
+            final int resid = data[index + STYLE_RESOURCE_ID];
             if (resid != 0) {
                 return resid;
             }
@@ -902,10 +904,10 @@
             throw new RuntimeException("Cannot make calls to a recycled instance!");
         }
 
-        index *= AssetManager.STYLE_NUM_ENTRIES;
+        index *= STYLE_NUM_ENTRIES;
         final int[] data = mData;
-        if (data[index + AssetManager.STYLE_TYPE] == TypedValue.TYPE_ATTRIBUTE) {
-            return data[index + AssetManager.STYLE_DATA];
+        if (data[index + STYLE_TYPE] == TypedValue.TYPE_ATTRIBUTE) {
+            return data[index + STYLE_DATA];
         }
         return defValue;
     }
@@ -939,7 +941,7 @@
         }
 
         final TypedValue value = mValue;
-        if (getValueAt(index*AssetManager.STYLE_NUM_ENTRIES, value)) {
+        if (getValueAt(index * STYLE_NUM_ENTRIES, value)) {
             if (value.type == TypedValue.TYPE_ATTRIBUTE) {
                 throw new UnsupportedOperationException(
                         "Failed to resolve attribute at index " + index + ": " + value);
@@ -975,7 +977,7 @@
         }
 
         final TypedValue value = mValue;
-        if (getValueAt(index*AssetManager.STYLE_NUM_ENTRIES, value)) {
+        if (getValueAt(index * STYLE_NUM_ENTRIES, value)) {
             if (value.type == TypedValue.TYPE_ATTRIBUTE) {
                 throw new UnsupportedOperationException(
                         "Failed to resolve attribute at index " + index + ": " + value);
@@ -1006,7 +1008,7 @@
         }
 
         final TypedValue value = mValue;
-        if (getValueAt(index*AssetManager.STYLE_NUM_ENTRIES, value)) {
+        if (getValueAt(index * STYLE_NUM_ENTRIES, value)) {
             return mResources.getTextArray(value.resourceId);
         }
         return null;
@@ -1027,7 +1029,7 @@
             throw new RuntimeException("Cannot make calls to a recycled instance!");
         }
 
-        return getValueAt(index*AssetManager.STYLE_NUM_ENTRIES, outValue);
+        return getValueAt(index * STYLE_NUM_ENTRIES, outValue);
     }
 
     /**
@@ -1043,8 +1045,8 @@
             throw new RuntimeException("Cannot make calls to a recycled instance!");
         }
 
-        index *= AssetManager.STYLE_NUM_ENTRIES;
-        return mData[index + AssetManager.STYLE_TYPE];
+        index *= STYLE_NUM_ENTRIES;
+        return mData[index + STYLE_TYPE];
     }
 
     /**
@@ -1063,9 +1065,9 @@
             throw new RuntimeException("Cannot make calls to a recycled instance!");
         }
 
-        index *= AssetManager.STYLE_NUM_ENTRIES;
+        index *= STYLE_NUM_ENTRIES;
         final int[] data = mData;
-        final int type = data[index+AssetManager.STYLE_TYPE];
+        final int type = data[index + STYLE_TYPE];
         return type != TypedValue.TYPE_NULL;
     }
 
@@ -1084,11 +1086,11 @@
             throw new RuntimeException("Cannot make calls to a recycled instance!");
         }
 
-        index *= AssetManager.STYLE_NUM_ENTRIES;
+        index *= STYLE_NUM_ENTRIES;
         final int[] data = mData;
-        final int type = data[index+AssetManager.STYLE_TYPE];
+        final int type = data[index + STYLE_TYPE];
         return type != TypedValue.TYPE_NULL
-                || data[index+AssetManager.STYLE_DATA] == TypedValue.DATA_NULL_EMPTY;
+                || data[index + STYLE_DATA] == TypedValue.DATA_NULL_EMPTY;
     }
 
     /**
@@ -1109,7 +1111,7 @@
         }
 
         final TypedValue value = mValue;
-        if (getValueAt(index*AssetManager.STYLE_NUM_ENTRIES, value)) {
+        if (getValueAt(index * STYLE_NUM_ENTRIES, value)) {
             return value;
         }
         return null;
@@ -1181,16 +1183,16 @@
         final int[] data = mData;
         final int N = length();
         for (int i = 0; i < N; i++) {
-            final int index = i * AssetManager.STYLE_NUM_ENTRIES;
-            if (data[index + AssetManager.STYLE_TYPE] != TypedValue.TYPE_ATTRIBUTE) {
+            final int index = i * STYLE_NUM_ENTRIES;
+            if (data[index + STYLE_TYPE] != TypedValue.TYPE_ATTRIBUTE) {
                 // Not an attribute, ignore.
                 continue;
             }
 
             // Null the entry so that we can safely call getZzz().
-            data[index + AssetManager.STYLE_TYPE] = TypedValue.TYPE_NULL;
+            data[index + STYLE_TYPE] = TypedValue.TYPE_NULL;
 
-            final int attr = data[index + AssetManager.STYLE_DATA];
+            final int attr = data[index + STYLE_DATA];
             if (attr == 0) {
                 // Useless data, ignore.
                 continue;
@@ -1231,45 +1233,44 @@
         final int[] data = mData;
         final int N = length();
         for (int i = 0; i < N; i++) {
-            final int index = i * AssetManager.STYLE_NUM_ENTRIES;
-            final int type = data[index + AssetManager.STYLE_TYPE];
+            final int index = i * STYLE_NUM_ENTRIES;
+            final int type = data[index + STYLE_TYPE];
             if (type == TypedValue.TYPE_NULL) {
                 continue;
             }
             changingConfig |= ActivityInfo.activityInfoConfigNativeToJava(
-                    data[index + AssetManager.STYLE_CHANGING_CONFIGURATIONS]);
+                    data[index + STYLE_CHANGING_CONFIGURATIONS]);
         }
         return changingConfig;
     }
 
     private boolean getValueAt(int index, TypedValue outValue) {
         final int[] data = mData;
-        final int type = data[index+AssetManager.STYLE_TYPE];
+        final int type = data[index + STYLE_TYPE];
         if (type == TypedValue.TYPE_NULL) {
             return false;
         }
         outValue.type = type;
-        outValue.data = data[index+AssetManager.STYLE_DATA];
-        outValue.assetCookie = data[index+AssetManager.STYLE_ASSET_COOKIE];
-        outValue.resourceId = data[index+AssetManager.STYLE_RESOURCE_ID];
+        outValue.data = data[index + STYLE_DATA];
+        outValue.assetCookie = data[index + STYLE_ASSET_COOKIE];
+        outValue.resourceId = data[index + STYLE_RESOURCE_ID];
         outValue.changingConfigurations = ActivityInfo.activityInfoConfigNativeToJava(
-                data[index + AssetManager.STYLE_CHANGING_CONFIGURATIONS]);
-        outValue.density = data[index+AssetManager.STYLE_DENSITY];
+                data[index + STYLE_CHANGING_CONFIGURATIONS]);
+        outValue.density = data[index + 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+AssetManager.STYLE_ASSET_COOKIE];
+        final int cookie = data[index + STYLE_ASSET_COOKIE];
         if (cookie < 0) {
             if (mXml != null) {
-                return mXml.getPooledString(
-                    data[index+AssetManager.STYLE_DATA]);
+                return mXml.getPooledString(data[index + STYLE_DATA]);
             }
             return null;
         }
-        return mAssets.getPooledStringForCookie(cookie, data[index+AssetManager.STYLE_DATA]);
+        return mAssets.getPooledStringForCookie(cookie, data[index + STYLE_DATA]);
     }
 
     /** @hide */
diff --git a/core/java/android/content/res/XmlBlock.java b/core/java/android/content/res/XmlBlock.java
index e6b95741..d4ccffb 100644
--- a/core/java/android/content/res/XmlBlock.java
+++ b/core/java/android/content/res/XmlBlock.java
@@ -16,6 +16,7 @@
 
 package android.content.res;
 
+import android.annotation.Nullable;
 import android.util.TypedValue;
 
 import com.android.internal.util.XmlUtils;
@@ -33,7 +34,7 @@
  * 
  * {@hide}
  */
-final class XmlBlock {
+final class XmlBlock implements AutoCloseable {
     private static final boolean DEBUG=false;
 
     public XmlBlock(byte[] data) {
@@ -48,6 +49,7 @@
         mStrings = new StringBlock(nativeGetStringBlock(mNative), false);
     }
 
+    @Override
     public void close() {
         synchronized (this) {
             if (mOpen) {
@@ -478,13 +480,13 @@
      *  are doing!  The given native object must exist for the entire lifetime
      *  of this newly creating XmlBlock.
      */
-    XmlBlock(AssetManager assets, long xmlBlock) {
+    XmlBlock(@Nullable AssetManager assets, long xmlBlock) {
         mAssets = assets;
         mNative = xmlBlock;
         mStrings = new StringBlock(nativeGetStringBlock(xmlBlock), false);
     }
 
-    private final AssetManager mAssets;
+    private @Nullable final AssetManager mAssets;
     private final long mNative;
     /*package*/ final StringBlock mStrings;
     private boolean mOpen = true;
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index 543acc7..19cc2d0 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -110,8 +110,8 @@
         "android_util_AssetManager.cpp",
         "android_util_Binder.cpp",
         "android_util_EventLog.cpp",
-        "android_util_MemoryIntArray.cpp",
         "android_util_Log.cpp",
+        "android_util_MemoryIntArray.cpp",
         "android_util_PathParser.cpp",
         "android_util_Process.cpp",
         "android_util_StringBlock.cpp",
@@ -189,6 +189,7 @@
         "android_backup_FileBackupHelperBase.cpp",
         "android_backup_BackupHelperDispatcher.cpp",
         "android_app_backup_FullBackup.cpp",
+        "android_content_res_ApkAssets.cpp",
         "android_content_res_ObbScanner.cpp",
         "android_content_res_Configuration.cpp",
         "android_animation_PropertyValuesHolder.cpp",
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index aa9a824..e3b5c8f 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -122,6 +122,7 @@
 extern int register_android_util_PathParser(JNIEnv* env);
 extern int register_android_content_StringBlock(JNIEnv* env);
 extern int register_android_content_XmlBlock(JNIEnv* env);
+extern int register_android_content_res_ApkAssets(JNIEnv* env);
 extern int register_android_graphics_Canvas(JNIEnv* env);
 extern int register_android_graphics_CanvasProperty(JNIEnv* env);
 extern int register_android_graphics_ColorFilter(JNIEnv* env);
@@ -1340,6 +1341,7 @@
     REG_JNI(register_android_content_AssetManager),
     REG_JNI(register_android_content_StringBlock),
     REG_JNI(register_android_content_XmlBlock),
+    REG_JNI(register_android_content_res_ApkAssets),
     REG_JNI(register_android_text_AndroidCharacter),
     REG_JNI(register_android_text_Hyphenator),
     REG_JNI(register_android_text_MeasuredParagraph),
diff --git a/core/jni/android/graphics/FontFamily.cpp b/core/jni/android/graphics/FontFamily.cpp
index dd3e6f0..c50026e 100644
--- a/core/jni/android/graphics/FontFamily.cpp
+++ b/core/jni/android/graphics/FontFamily.cpp
@@ -28,7 +28,7 @@
 #include <nativehelper/ScopedUtfChars.h>
 #include <android_runtime/AndroidRuntime.h>
 #include <android_runtime/android_util_AssetManager.h>
-#include <androidfw/AssetManager.h>
+#include <androidfw/AssetManager2.h>
 #include "Utils.h"
 #include "FontUtils.h"
 
@@ -224,7 +224,8 @@
     NPE_CHECK_RETURN_ZERO(env, jpath);
 
     NativeFamilyBuilder* builder = reinterpret_cast<NativeFamilyBuilder*>(builderPtr);
-    AssetManager* mgr = assetManagerForJavaObject(env, jassetMgr);
+
+    Guarded<AssetManager2>* mgr = AssetManagerForJavaObject(env, jassetMgr);
     if (NULL == mgr) {
         builder->axes.clear();
         return false;
@@ -236,27 +237,33 @@
         return false;
     }
 
-    Asset* asset;
-    if (isAsset) {
-        asset = mgr->open(str.c_str(), Asset::ACCESS_BUFFER);
-    } else {
-        asset = cookie ? mgr->openNonAsset(static_cast<int32_t>(cookie), str.c_str(),
-                Asset::ACCESS_BUFFER) : mgr->openNonAsset(str.c_str(), Asset::ACCESS_BUFFER);
+    std::unique_ptr<Asset> asset;
+    {
+      ScopedLock<AssetManager2> locked_mgr(*mgr);
+      if (isAsset) {
+          asset = locked_mgr->Open(str.c_str(), Asset::ACCESS_BUFFER);
+      } else if (cookie > 0) {
+          // Valid java cookies are 1-based, but AssetManager cookies are 0-based.
+          asset = locked_mgr->OpenNonAsset(str.c_str(), static_cast<ApkAssetsCookie>(cookie - 1),
+                  Asset::ACCESS_BUFFER);
+      } else {
+          asset = locked_mgr->OpenNonAsset(str.c_str(), Asset::ACCESS_BUFFER);
+      }
     }
 
-    if (NULL == asset) {
+    if (nullptr == asset) {
         builder->axes.clear();
         return false;
     }
 
     const void* buf = asset->getBuffer(false);
     if (NULL == buf) {
-        delete asset;
         builder->axes.clear();
         return false;
     }
 
-    sk_sp<SkData> data(SkData::MakeWithProc(buf, asset->getLength(), releaseAsset, asset));
+    sk_sp<SkData> data(SkData::MakeWithProc(buf, asset->getLength(), releaseAsset,
+            asset.release()));
     return addSkTypeface(builder, std::move(data), ttcIndex, weight, isItalic);
 }
 
diff --git a/core/jni/android_app_NativeActivity.cpp b/core/jni/android_app_NativeActivity.cpp
index 09e37e1..49a24a3 100644
--- a/core/jni/android_app_NativeActivity.cpp
+++ b/core/jni/android_app_NativeActivity.cpp
@@ -361,7 +361,7 @@
     code->sdkVersion = sdkVersion;
 
     code->javaAssetManager = env->NewGlobalRef(jAssetMgr);
-    code->assetManager = assetManagerForJavaObject(env, jAssetMgr);
+    code->assetManager = NdkAssetManagerForJavaObject(env, jAssetMgr);
 
     if (obbDir != NULL) {
         dirStr = env->GetStringUTFChars(obbDir, NULL);
diff --git a/core/jni/android_content_res_ApkAssets.cpp b/core/jni/android_content_res_ApkAssets.cpp
new file mode 100644
index 0000000..c0f151b
--- /dev/null
+++ b/core/jni/android_content_res_ApkAssets.cpp
@@ -0,0 +1,150 @@
+/*
+ * 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.
+ */
+
+#include "android-base/macros.h"
+#include "android-base/stringprintf.h"
+#include "android-base/unique_fd.h"
+#include "androidfw/ApkAssets.h"
+#include "utils/misc.h"
+
+#include "core_jni_helpers.h"
+#include "jni.h"
+#include "nativehelper/ScopedUtfChars.h"
+
+using ::android::base::unique_fd;
+
+namespace android {
+
+static jlong NativeLoad(JNIEnv* env, jclass /*clazz*/, jstring java_path, jboolean system,
+                        jboolean force_shared_lib, jboolean overlay) {
+  ScopedUtfChars path(env, java_path);
+  if (path.c_str() == nullptr) {
+    return 0;
+  }
+
+  std::unique_ptr<const ApkAssets> apk_assets;
+  if (overlay) {
+    apk_assets = ApkAssets::LoadOverlay(path.c_str(), system);
+  } else if (force_shared_lib) {
+    apk_assets = ApkAssets::LoadAsSharedLibrary(path.c_str(), system);
+  } else {
+    apk_assets = ApkAssets::Load(path.c_str(), system);
+  }
+
+  if (apk_assets == nullptr) {
+    std::string error_msg = base::StringPrintf("Failed to load asset path %s", path.c_str());
+    jniThrowException(env, "java/io/IOException", error_msg.c_str());
+    return 0;
+  }
+  return reinterpret_cast<jlong>(apk_assets.release());
+}
+
+static jlong NativeLoadFromFd(JNIEnv* env, jclass /*clazz*/, jobject file_descriptor,
+                              jstring friendly_name, jboolean system, jboolean force_shared_lib) {
+  ScopedUtfChars friendly_name_utf8(env, friendly_name);
+  if (friendly_name_utf8.c_str() == nullptr) {
+    return 0;
+  }
+
+  int fd = jniGetFDFromFileDescriptor(env, file_descriptor);
+  if (fd < 0) {
+    jniThrowException(env, "java/lang/IllegalArgumentException", "Bad FileDescriptor");
+    return 0;
+  }
+
+  unique_fd dup_fd(::dup(fd));
+  if (dup_fd < 0) {
+    jniThrowIOException(env, errno);
+    return 0;
+  }
+
+  std::unique_ptr<const ApkAssets> apk_assets = ApkAssets::LoadFromFd(std::move(dup_fd),
+                                                                      friendly_name_utf8.c_str(),
+                                                                      system, force_shared_lib);
+  if (apk_assets == nullptr) {
+    std::string error_msg = base::StringPrintf("Failed to load asset path %s from fd %d",
+                                               friendly_name_utf8.c_str(), dup_fd.get());
+    jniThrowException(env, "java/io/IOException", error_msg.c_str());
+    return 0;
+  }
+  return reinterpret_cast<jlong>(apk_assets.release());
+}
+
+static void NativeDestroy(JNIEnv* /*env*/, jclass /*clazz*/, jlong ptr) {
+  delete reinterpret_cast<ApkAssets*>(ptr);
+}
+
+static jstring NativeGetAssetPath(JNIEnv* env, jclass /*clazz*/, jlong ptr) {
+  const ApkAssets* apk_assets = reinterpret_cast<const ApkAssets*>(ptr);
+  return env->NewStringUTF(apk_assets->GetPath().c_str());
+}
+
+static jlong NativeGetStringBlock(JNIEnv* /*env*/, jclass /*clazz*/, jlong ptr) {
+  const ApkAssets* apk_assets = reinterpret_cast<const ApkAssets*>(ptr);
+  return reinterpret_cast<jlong>(apk_assets->GetLoadedArsc()->GetStringPool());
+}
+
+static jboolean NativeIsUpToDate(JNIEnv* /*env*/, jclass /*clazz*/, jlong ptr) {
+  const ApkAssets* apk_assets = reinterpret_cast<const ApkAssets*>(ptr);
+  (void)apk_assets;
+  return JNI_TRUE;
+}
+
+static jlong NativeOpenXml(JNIEnv* env, jclass /*clazz*/, jlong ptr, jstring file_name) {
+  ScopedUtfChars path_utf8(env, file_name);
+  if (path_utf8.c_str() == nullptr) {
+    return 0;
+  }
+
+  const ApkAssets* apk_assets = reinterpret_cast<const ApkAssets*>(ptr);
+  std::unique_ptr<Asset> asset = apk_assets->Open(path_utf8.c_str(),
+                                                  Asset::AccessMode::ACCESS_RANDOM);
+  if (asset == nullptr) {
+    jniThrowException(env, "java/io/FileNotFoundException", path_utf8.c_str());
+    return 0;
+  }
+
+  // DynamicRefTable is only needed when looking up resource references. Opening an XML file
+  // directly from an ApkAssets has no notion of proper resource references.
+  std::unique_ptr<ResXMLTree> xml_tree = util::make_unique<ResXMLTree>(nullptr /*dynamicRefTable*/);
+  status_t err = xml_tree->setTo(asset->getBuffer(true), asset->getLength(), true);
+  asset.reset();
+
+  if (err != NO_ERROR) {
+    jniThrowException(env, "java/io/FileNotFoundException", "Corrupt XML binary file");
+    return 0;
+  }
+  return reinterpret_cast<jlong>(xml_tree.release());
+}
+
+// JNI registration.
+static const JNINativeMethod gApkAssetsMethods[] = {
+    {"nativeLoad", "(Ljava/lang/String;ZZZ)J", (void*)NativeLoad},
+    {"nativeLoadFromFd", "(Ljava/io/FileDescriptor;Ljava/lang/String;ZZ)J",
+        (void*)NativeLoadFromFd},
+    {"nativeDestroy", "(J)V", (void*)NativeDestroy},
+    {"nativeGetAssetPath", "(J)Ljava/lang/String;", (void*)NativeGetAssetPath},
+    {"nativeGetStringBlock", "(J)J", (void*)NativeGetStringBlock},
+    {"nativeIsUpToDate", "(J)Z", (void*)NativeIsUpToDate},
+    {"nativeOpenXml", "(JLjava/lang/String;)J", (void*)NativeOpenXml},
+};
+
+int register_android_content_res_ApkAssets(JNIEnv* env) {
+  return RegisterMethodsOrDie(env, "android/content/res/ApkAssets", gApkAssetsMethods,
+                              arraysize(gApkAssetsMethods));
+}
+
+}  // namespace android
diff --git a/core/jni/android_util_AssetManager.cpp b/core/jni/android_util_AssetManager.cpp
index c6828c4..403937b 100644
--- a/core/jni/android_util_AssetManager.cpp
+++ b/core/jni/android_util_AssetManager.cpp
@@ -1,1846 +1,1437 @@
-/* //device/libs/android_runtime/android_util_AssetManager.cpp
-**
-** Copyright 2006, 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.
-*/
+/*
+ * Copyright 2006, 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.
+ */
 
 #define LOG_TAG "asset"
 
-#include <android_runtime/android_util_AssetManager.h>
-
 #include <inttypes.h>
 #include <linux/capability.h>
 #include <stdio.h>
-#include <sys/types.h>
-#include <sys/wait.h>
 #include <sys/stat.h>
 #include <sys/system_properties.h>
+#include <sys/types.h>
+#include <sys/wait.h>
 
 #include <private/android_filesystem_config.h> // for AID_SYSTEM
 
-#include "androidfw/Asset.h"
-#include "androidfw/AssetManager.h"
-#include "androidfw/AttributeResolution.h"
-#include "androidfw/ResourceTypes.h"
+#include "android-base/logging.h"
+#include "android-base/properties.h"
+#include "android-base/stringprintf.h"
+#include "android_runtime/android_util_AssetManager.h"
 #include "android_runtime/AndroidRuntime.h"
 #include "android_util_Binder.h"
+#include "androidfw/Asset.h"
+#include "androidfw/AssetManager.h"
+#include "androidfw/AssetManager2.h"
+#include "androidfw/AttributeResolution.h"
+#include "androidfw/MutexGuard.h"
+#include "androidfw/ResourceTypes.h"
 #include "core_jni_helpers.h"
 #include "jni.h"
-#include <nativehelper/JNIHelp.h>
-#include <nativehelper/ScopedStringChars.h>
-#include <nativehelper/ScopedUtfChars.h>
+#include "nativehelper/JNIHelp.h"
+#include "nativehelper/ScopedPrimitiveArray.h"
+#include "nativehelper/ScopedStringChars.h"
+#include "nativehelper/ScopedUtfChars.h"
 #include "utils/Log.h"
-#include "utils/misc.h"
 #include "utils/String8.h"
+#include "utils/misc.h"
 
 extern "C" int capget(cap_user_header_t hdrp, cap_user_data_t datap);
 extern "C" int capset(cap_user_header_t hdrp, const cap_user_data_t datap);
 
+using ::android::base::StringPrintf;
 
 namespace android {
 
-static const bool kThrowOnBadId = false;
-
 // ----------------------------------------------------------------------------
 
-static struct typedvalue_offsets_t
-{
-    jfieldID mType;
-    jfieldID mData;
-    jfieldID mString;
-    jfieldID mAssetCookie;
-    jfieldID mResourceId;
-    jfieldID mChangingConfigurations;
-    jfieldID mDensity;
+static struct typedvalue_offsets_t {
+  jfieldID mType;
+  jfieldID mData;
+  jfieldID mString;
+  jfieldID mAssetCookie;
+  jfieldID mResourceId;
+  jfieldID mChangingConfigurations;
+  jfieldID mDensity;
 } gTypedValueOffsets;
 
-static struct assetfiledescriptor_offsets_t
-{
-    jfieldID mFd;
-    jfieldID mStartOffset;
-    jfieldID mLength;
+static struct assetfiledescriptor_offsets_t {
+  jfieldID mFd;
+  jfieldID mStartOffset;
+  jfieldID mLength;
 } gAssetFileDescriptorOffsets;
 
-static struct assetmanager_offsets_t
-{
-    jfieldID mObject;
+static struct assetmanager_offsets_t {
+  jfieldID mObject;
 } gAssetManagerOffsets;
 
-static struct sparsearray_offsets_t
-{
-    jclass classObject;
-    jmethodID constructor;
-    jmethodID put;
+static struct {
+  jfieldID native_ptr;
+} gApkAssetsFields;
+
+static struct sparsearray_offsets_t {
+  jclass classObject;
+  jmethodID constructor;
+  jmethodID put;
 } gSparseArrayOffsets;
 
-static struct configuration_offsets_t
-{
-    jclass classObject;
-    jmethodID constructor;
-    jfieldID mSmallestScreenWidthDpOffset;
-    jfieldID mScreenWidthDpOffset;
-    jfieldID mScreenHeightDpOffset;
+static struct configuration_offsets_t {
+  jclass classObject;
+  jmethodID constructor;
+  jfieldID mSmallestScreenWidthDpOffset;
+  jfieldID mScreenWidthDpOffset;
+  jfieldID mScreenHeightDpOffset;
 } gConfigurationOffsets;
 
-jclass g_stringClass = NULL;
+jclass g_stringClass = nullptr;
 
 // ----------------------------------------------------------------------------
 
-static jint copyValue(JNIEnv* env, jobject outValue, const ResTable* table,
-                      const Res_value& value, uint32_t ref, ssize_t block,
-                      uint32_t typeSpecFlags, ResTable_config* config = NULL);
+// Java asset cookies have 0 as an invalid cookie, but TypedArray expects < 0.
+constexpr inline static jint ApkAssetsCookieToJavaCookie(ApkAssetsCookie cookie) {
+  return cookie != kInvalidCookie ? static_cast<jint>(cookie + 1) : -1;
+}
 
-jint copyValue(JNIEnv* env, jobject outValue, const ResTable* table,
-               const Res_value& value, uint32_t ref, ssize_t block,
-               uint32_t typeSpecFlags, ResTable_config* config)
-{
-    env->SetIntField(outValue, gTypedValueOffsets.mType, value.dataType);
-    env->SetIntField(outValue, gTypedValueOffsets.mAssetCookie,
-                     static_cast<jint>(table->getTableCookie(block)));
-    env->SetIntField(outValue, gTypedValueOffsets.mData, value.data);
-    env->SetObjectField(outValue, gTypedValueOffsets.mString, NULL);
-    env->SetIntField(outValue, gTypedValueOffsets.mResourceId, ref);
-    env->SetIntField(outValue, gTypedValueOffsets.mChangingConfigurations,
-            typeSpecFlags);
-    if (config != NULL) {
-        env->SetIntField(outValue, gTypedValueOffsets.mDensity, config->density);
-    }
-    return block;
+constexpr inline static ApkAssetsCookie JavaCookieToApkAssetsCookie(jint cookie) {
+  return cookie > 0 ? static_cast<ApkAssetsCookie>(cookie - 1) : kInvalidCookie;
 }
 
 // This is called by zygote (running as user root) as part of preloadResources.
-static void verifySystemIdmaps()
-{
-    pid_t pid;
-    char system_id[10];
+static void NativeVerifySystemIdmaps(JNIEnv* /*env*/, jclass /*clazz*/) {
+  switch (pid_t pid = fork()) {
+    case -1:
+      PLOG(ERROR) << "failed to fork for idmap";
+      break;
 
-    snprintf(system_id, sizeof(system_id), "%d", AID_SYSTEM);
+    // child
+    case 0: {
+      struct __user_cap_header_struct capheader;
+      struct __user_cap_data_struct capdata;
 
-    switch (pid = fork()) {
-        case -1:
-            ALOGE("failed to fork for idmap: %s", strerror(errno));
-            break;
-        case 0: // child
-            {
-                struct __user_cap_header_struct capheader;
-                struct __user_cap_data_struct capdata;
+      memset(&capheader, 0, sizeof(capheader));
+      memset(&capdata, 0, sizeof(capdata));
 
-                memset(&capheader, 0, sizeof(capheader));
-                memset(&capdata, 0, sizeof(capdata));
+      capheader.version = _LINUX_CAPABILITY_VERSION;
+      capheader.pid = 0;
 
-                capheader.version = _LINUX_CAPABILITY_VERSION;
-                capheader.pid = 0;
+      if (capget(&capheader, &capdata) != 0) {
+        PLOG(ERROR) << "capget";
+        exit(1);
+      }
 
-                if (capget(&capheader, &capdata) != 0) {
-                    ALOGE("capget: %s\n", strerror(errno));
-                    exit(1);
-                }
+      capdata.effective = capdata.permitted;
+      if (capset(&capheader, &capdata) != 0) {
+        PLOG(ERROR) << "capset";
+        exit(1);
+      }
 
-                capdata.effective = capdata.permitted;
-                if (capset(&capheader, &capdata) != 0) {
-                    ALOGE("capset: %s\n", strerror(errno));
-                    exit(1);
-                }
+      if (setgid(AID_SYSTEM) != 0) {
+        PLOG(ERROR) << "setgid";
+        exit(1);
+      }
 
-                if (setgid(AID_SYSTEM) != 0) {
-                    ALOGE("setgid: %s\n", strerror(errno));
-                    exit(1);
-                }
+      if (setuid(AID_SYSTEM) != 0) {
+        PLOG(ERROR) << "setuid";
+        exit(1);
+      }
 
-                if (setuid(AID_SYSTEM) != 0) {
-                    ALOGE("setuid: %s\n", strerror(errno));
-                    exit(1);
-                }
+      // Generic idmap parameters
+      const char* argv[8];
+      int argc = 0;
+      struct stat st;
 
-                // Generic idmap parameters
-                const char* argv[8];
-                int argc = 0;
-                struct stat st;
+      memset(argv, 0, sizeof(argv));
+      argv[argc++] = AssetManager::IDMAP_BIN;
+      argv[argc++] = "--scan";
+      argv[argc++] = AssetManager::TARGET_PACKAGE_NAME;
+      argv[argc++] = AssetManager::TARGET_APK_PATH;
+      argv[argc++] = AssetManager::IDMAP_DIR;
 
-                memset(argv, NULL, sizeof(argv));
-                argv[argc++] = AssetManager::IDMAP_BIN;
-                argv[argc++] = "--scan";
-                argv[argc++] = AssetManager::TARGET_PACKAGE_NAME;
-                argv[argc++] = AssetManager::TARGET_APK_PATH;
-                argv[argc++] = AssetManager::IDMAP_DIR;
+      // Directories to scan for overlays: if OVERLAY_THEME_DIR_PROPERTY is defined,
+      // use OVERLAY_DIR/<value of OVERLAY_THEME_DIR_PROPERTY> in addition to OVERLAY_DIR.
+      std::string overlay_theme_path = base::GetProperty(AssetManager::OVERLAY_THEME_DIR_PROPERTY,
+                                                         "");
+      if (!overlay_theme_path.empty()) {
+        overlay_theme_path = std::string(AssetManager::OVERLAY_DIR) + "/" + overlay_theme_path;
+        if (stat(overlay_theme_path.c_str(), &st) == 0) {
+          argv[argc++] = overlay_theme_path.c_str();
+        }
+      }
 
-                // Directories to scan for overlays: if OVERLAY_THEME_DIR_PROPERTY is defined,
-                // use OVERLAY_DIR/<value of OVERLAY_THEME_DIR_PROPERTY> in addition to OVERLAY_DIR.
-                char subdir[PROP_VALUE_MAX];
-                int len = __system_property_get(AssetManager::OVERLAY_THEME_DIR_PROPERTY, subdir);
-                if (len > 0) {
-                    String8 overlayPath = String8(AssetManager::OVERLAY_DIR) + "/" + subdir;
-                    if (stat(overlayPath.string(), &st) == 0) {
-                        argv[argc++] = overlayPath.string();
-                    }
-                }
-                if (stat(AssetManager::OVERLAY_DIR, &st) == 0) {
-                    argv[argc++] = AssetManager::OVERLAY_DIR;
-                }
+      if (stat(AssetManager::OVERLAY_DIR, &st) == 0) {
+          argv[argc++] = AssetManager::OVERLAY_DIR;
+      }
 
-                // Finally, invoke idmap (if any overlay directory exists)
-                if (argc > 5) {
-                    execv(AssetManager::IDMAP_BIN, (char* const*)argv);
-                    ALOGE("failed to execv for idmap: %s", strerror(errno));
-                    exit(1); // should never get here
-                } else {
-                    exit(0);
-                }
-            }
-            break;
-        default: // parent
-            waitpid(pid, NULL, 0);
-            break;
-    }
+      // Finally, invoke idmap (if any overlay directory exists)
+      if (argc > 5) {
+        execv(AssetManager::IDMAP_BIN, (char* const*)argv);
+        PLOG(ERROR) << "failed to execv for idmap";
+        exit(1); // should never get here
+      } else {
+        exit(0);
+      }
+  } break;
+
+  // parent
+  default:
+    waitpid(pid, nullptr, 0);
+    break;
+  }
+}
+
+static jint CopyValue(JNIEnv* env, ApkAssetsCookie cookie, const Res_value& value, uint32_t ref,
+                      uint32_t type_spec_flags, ResTable_config* config, jobject out_typed_value) {
+  env->SetIntField(out_typed_value, gTypedValueOffsets.mType, value.dataType);
+  env->SetIntField(out_typed_value, gTypedValueOffsets.mAssetCookie,
+                   ApkAssetsCookieToJavaCookie(cookie));
+  env->SetIntField(out_typed_value, gTypedValueOffsets.mData, value.data);
+  env->SetObjectField(out_typed_value, gTypedValueOffsets.mString, nullptr);
+  env->SetIntField(out_typed_value, gTypedValueOffsets.mResourceId, ref);
+  env->SetIntField(out_typed_value, gTypedValueOffsets.mChangingConfigurations, type_spec_flags);
+  if (config != nullptr) {
+    env->SetIntField(out_typed_value, gTypedValueOffsets.mDensity, config->density);
+  }
+  return static_cast<jint>(ApkAssetsCookieToJavaCookie(cookie));
 }
 
 // ----------------------------------------------------------------------------
 
-// this guy is exported to other jni routines
-AssetManager* assetManagerForJavaObject(JNIEnv* env, jobject obj)
-{
-    jlong amHandle = env->GetLongField(obj, gAssetManagerOffsets.mObject);
-    AssetManager* am = reinterpret_cast<AssetManager*>(amHandle);
-    if (am != NULL) {
-        return am;
-    }
-    jniThrowException(env, "java/lang/IllegalStateException", "AssetManager has been finalized!");
-    return NULL;
-}
-
-static jlong android_content_AssetManager_openAsset(JNIEnv* env, jobject clazz,
-                                                jstring fileName, jint mode)
-{
-    AssetManager* am = assetManagerForJavaObject(env, clazz);
-    if (am == NULL) {
-        return 0;
-    }
-
-    ALOGV("openAsset in %p (Java object %p)\n", am, clazz);
-
-    ScopedUtfChars fileName8(env, fileName);
-    if (fileName8.c_str() == NULL) {
-        jniThrowException(env, "java/lang/IllegalArgumentException", "Empty file name");
-        return -1;
-    }
-
-    if (mode != Asset::ACCESS_UNKNOWN && mode != Asset::ACCESS_RANDOM
-        && mode != Asset::ACCESS_STREAMING && mode != Asset::ACCESS_BUFFER) {
-        jniThrowException(env, "java/lang/IllegalArgumentException", "Bad access mode");
-        return -1;
-    }
-
-    Asset* a = am->open(fileName8.c_str(), (Asset::AccessMode)mode);
-
-    if (a == NULL) {
-        jniThrowException(env, "java/io/FileNotFoundException", fileName8.c_str());
-        return -1;
-    }
-
-    //printf("Created Asset Stream: %p\n", a);
-
-    return reinterpret_cast<jlong>(a);
-}
-
-static jobject returnParcelFileDescriptor(JNIEnv* env, Asset* a, jlongArray outOffsets)
-{
-    off64_t startOffset, length;
-    int fd = a->openFileDescriptor(&startOffset, &length);
-    delete a;
-
-    if (fd < 0) {
-        jniThrowException(env, "java/io/FileNotFoundException",
-                "This file can not be opened as a file descriptor; it is probably compressed");
-        return NULL;
-    }
-
-    jlong* offsets = (jlong*)env->GetPrimitiveArrayCritical(outOffsets, 0);
-    if (offsets == NULL) {
-        close(fd);
-        return NULL;
-    }
-
-    offsets[0] = startOffset;
-    offsets[1] = length;
-
-    env->ReleasePrimitiveArrayCritical(outOffsets, offsets, 0);
-
-    jobject fileDesc = jniCreateFileDescriptor(env, fd);
-    if (fileDesc == NULL) {
-        close(fd);
-        return NULL;
-    }
-
-    return newParcelFileDescriptor(env, fileDesc);
-}
-
-static jobject android_content_AssetManager_openAssetFd(JNIEnv* env, jobject clazz,
-                                                jstring fileName, jlongArray outOffsets)
-{
-    AssetManager* am = assetManagerForJavaObject(env, clazz);
-    if (am == NULL) {
-        return NULL;
-    }
-
-    ALOGV("openAssetFd in %p (Java object %p)\n", am, clazz);
-
-    ScopedUtfChars fileName8(env, fileName);
-    if (fileName8.c_str() == NULL) {
-        return NULL;
-    }
-
-    Asset* a = am->open(fileName8.c_str(), Asset::ACCESS_RANDOM);
-
-    if (a == NULL) {
-        jniThrowException(env, "java/io/FileNotFoundException", fileName8.c_str());
-        return NULL;
-    }
-
-    //printf("Created Asset Stream: %p\n", a);
-
-    return returnParcelFileDescriptor(env, a, outOffsets);
-}
-
-static jlong android_content_AssetManager_openNonAssetNative(JNIEnv* env, jobject clazz,
-                                                         jint cookie,
-                                                         jstring fileName,
-                                                         jint mode)
-{
-    AssetManager* am = assetManagerForJavaObject(env, clazz);
-    if (am == NULL) {
-        return 0;
-    }
-
-    ALOGV("openNonAssetNative in %p (Java object %p)\n", am, clazz);
-
-    ScopedUtfChars fileName8(env, fileName);
-    if (fileName8.c_str() == NULL) {
-        return -1;
-    }
-
-    if (mode != Asset::ACCESS_UNKNOWN && mode != Asset::ACCESS_RANDOM
-        && mode != Asset::ACCESS_STREAMING && mode != Asset::ACCESS_BUFFER) {
-        jniThrowException(env, "java/lang/IllegalArgumentException", "Bad access mode");
-        return -1;
-    }
-
-    Asset* a = cookie
-        ? am->openNonAsset(static_cast<int32_t>(cookie), fileName8.c_str(),
-                (Asset::AccessMode)mode)
-        : am->openNonAsset(fileName8.c_str(), (Asset::AccessMode)mode);
-
-    if (a == NULL) {
-        jniThrowException(env, "java/io/FileNotFoundException", fileName8.c_str());
-        return -1;
-    }
-
-    //printf("Created Asset Stream: %p\n", a);
-
-    return reinterpret_cast<jlong>(a);
-}
-
-static jobject android_content_AssetManager_openNonAssetFdNative(JNIEnv* env, jobject clazz,
-                                                         jint cookie,
-                                                         jstring fileName,
-                                                         jlongArray outOffsets)
-{
-    AssetManager* am = assetManagerForJavaObject(env, clazz);
-    if (am == NULL) {
-        return NULL;
-    }
-
-    ALOGV("openNonAssetFd in %p (Java object %p)\n", am, clazz);
-
-    ScopedUtfChars fileName8(env, fileName);
-    if (fileName8.c_str() == NULL) {
-        return NULL;
-    }
-
-    Asset* a = cookie
-        ? am->openNonAsset(static_cast<int32_t>(cookie), fileName8.c_str(), Asset::ACCESS_RANDOM)
-        : am->openNonAsset(fileName8.c_str(), Asset::ACCESS_RANDOM);
-
-    if (a == NULL) {
-        jniThrowException(env, "java/io/FileNotFoundException", fileName8.c_str());
-        return NULL;
-    }
-
-    //printf("Created Asset Stream: %p\n", a);
-
-    return returnParcelFileDescriptor(env, a, outOffsets);
-}
-
-static jobjectArray android_content_AssetManager_list(JNIEnv* env, jobject clazz,
-                                                   jstring fileName)
-{
-    AssetManager* am = assetManagerForJavaObject(env, clazz);
-    if (am == NULL) {
-        return NULL;
-    }
-
-    ScopedUtfChars fileName8(env, fileName);
-    if (fileName8.c_str() == NULL) {
-        return NULL;
-    }
-
-    AssetDir* dir = am->openDir(fileName8.c_str());
-
-    if (dir == NULL) {
-        jniThrowException(env, "java/io/FileNotFoundException", fileName8.c_str());
-        return NULL;
-    }
-
-    size_t N = dir->getFileCount();
-
-    jobjectArray array = env->NewObjectArray(dir->getFileCount(),
-                                                g_stringClass, NULL);
-    if (array == NULL) {
-        delete dir;
-        return NULL;
-    }
-
-    for (size_t i=0; i<N; i++) {
-        const String8& name = dir->getFileName(i);
-        jstring str = env->NewStringUTF(name.string());
-        if (str == NULL) {
-            delete dir;
-            return NULL;
-        }
-        env->SetObjectArrayElement(array, i, str);
-        env->DeleteLocalRef(str);
-    }
-
-    delete dir;
-
-    return array;
-}
-
-static void android_content_AssetManager_destroyAsset(JNIEnv* env, jobject clazz,
-                                                      jlong assetHandle)
-{
-    Asset* a = reinterpret_cast<Asset*>(assetHandle);
-
-    //printf("Destroying Asset Stream: %p\n", a);
-
-    if (a == NULL) {
-        jniThrowNullPointerException(env, "asset");
-        return;
-    }
-
-    delete a;
-}
-
-static jint android_content_AssetManager_readAssetChar(JNIEnv* env, jobject clazz,
-                                                       jlong assetHandle)
-{
-    Asset* a = reinterpret_cast<Asset*>(assetHandle);
-
-    if (a == NULL) {
-        jniThrowNullPointerException(env, "asset");
-        return -1;
-    }
-
-    uint8_t b;
-    ssize_t res = a->read(&b, 1);
-    return res == 1 ? b : -1;
-}
-
-static jint android_content_AssetManager_readAsset(JNIEnv* env, jobject clazz,
-                                                jlong assetHandle, jbyteArray bArray,
-                                                jint off, jint len)
-{
-    Asset* a = reinterpret_cast<Asset*>(assetHandle);
-
-    if (a == NULL || bArray == NULL) {
-        jniThrowNullPointerException(env, "asset");
-        return -1;
-    }
-
-    if (len == 0) {
-        return 0;
-    }
-
-    jsize bLen = env->GetArrayLength(bArray);
-    if (off < 0 || off >= bLen || len < 0 || len > bLen || (off+len) > bLen) {
-        jniThrowException(env, "java/lang/IndexOutOfBoundsException", "");
-        return -1;
-    }
-
-    jbyte* b = env->GetByteArrayElements(bArray, NULL);
-    ssize_t res = a->read(b+off, len);
-    env->ReleaseByteArrayElements(bArray, b, 0);
-
-    if (res > 0) return static_cast<jint>(res);
-
-    if (res < 0) {
-        jniThrowException(env, "java/io/IOException", "");
-    }
-    return -1;
-}
-
-static jlong android_content_AssetManager_seekAsset(JNIEnv* env, jobject clazz,
-                                                 jlong assetHandle,
-                                                 jlong offset, jint whence)
-{
-    Asset* a = reinterpret_cast<Asset*>(assetHandle);
-
-    if (a == NULL) {
-        jniThrowNullPointerException(env, "asset");
-        return -1;
-    }
-
-    return a->seek(
-        offset, (whence > 0) ? SEEK_END : (whence < 0 ? SEEK_SET : SEEK_CUR));
-}
-
-static jlong android_content_AssetManager_getAssetLength(JNIEnv* env, jobject clazz,
-                                                      jlong assetHandle)
-{
-    Asset* a = reinterpret_cast<Asset*>(assetHandle);
-
-    if (a == NULL) {
-        jniThrowNullPointerException(env, "asset");
-        return -1;
-    }
-
-    return a->getLength();
-}
-
-static jlong android_content_AssetManager_getAssetRemainingLength(JNIEnv* env, jobject clazz,
-                                                               jlong assetHandle)
-{
-    Asset* a = reinterpret_cast<Asset*>(assetHandle);
-
-    if (a == NULL) {
-        jniThrowNullPointerException(env, "asset");
-        return -1;
-    }
-
-    return a->getRemainingLength();
-}
-
-static jint android_content_AssetManager_addAssetPath(JNIEnv* env, jobject clazz,
-                                                       jstring path, jboolean appAsLib)
-{
-    ScopedUtfChars path8(env, path);
-    if (path8.c_str() == NULL) {
-        return 0;
-    }
-
-    AssetManager* am = assetManagerForJavaObject(env, clazz);
-    if (am == NULL) {
-        return 0;
-    }
-
-    int32_t cookie;
-    bool res = am->addAssetPath(String8(path8.c_str()), &cookie, appAsLib);
-
-    return (res) ? static_cast<jint>(cookie) : 0;
-}
-
-static jint android_content_AssetManager_addOverlayPath(JNIEnv* env, jobject clazz,
-                                                     jstring idmapPath)
-{
-    ScopedUtfChars idmapPath8(env, idmapPath);
-    if (idmapPath8.c_str() == NULL) {
-        return 0;
-    }
-
-    AssetManager* am = assetManagerForJavaObject(env, clazz);
-    if (am == NULL) {
-        return 0;
-    }
-
-    int32_t cookie;
-    bool res = am->addOverlayPath(String8(idmapPath8.c_str()), &cookie);
-
-    return (res) ? (jint)cookie : 0;
-}
-
-static jint android_content_AssetManager_addAssetFd(JNIEnv* env, jobject clazz,
-                                                    jobject fileDescriptor, jstring debugPathName,
-                                                    jboolean appAsLib)
-{
-    ScopedUtfChars debugPathName8(env, debugPathName);
-
-    int fd = jniGetFDFromFileDescriptor(env, fileDescriptor);
-    if (fd < 0) {
-        jniThrowException(env, "java/lang/IllegalArgumentException", "Bad FileDescriptor");
-        return 0;
-    }
-
-    AssetManager* am = assetManagerForJavaObject(env, clazz);
-    if (am == NULL) {
-        return 0;
-    }
-
-    int dupfd = ::dup(fd);
-    if (dupfd < 0) {
-        jniThrowIOException(env, errno);
-        return 0;
-    }
-
-    int32_t cookie;
-    bool res = am->addAssetFd(dupfd, String8(debugPathName8.c_str()), &cookie, appAsLib);
-
-    return (res) ? static_cast<jint>(cookie) : 0;
-}
-
-static jboolean android_content_AssetManager_isUpToDate(JNIEnv* env, jobject clazz)
-{
-    AssetManager* am = assetManagerForJavaObject(env, clazz);
-    if (am == NULL) {
-        return JNI_TRUE;
-    }
-    return am->isUpToDate() ? JNI_TRUE : JNI_FALSE;
-}
-
-static jobjectArray getLocales(JNIEnv* env, jobject clazz, bool includeSystemLocales)
-{
-    Vector<String8> locales;
-
-    AssetManager* am = assetManagerForJavaObject(env, clazz);
-    if (am == NULL) {
-        return NULL;
-    }
-
-    am->getLocales(&locales, includeSystemLocales);
-
-    const int N = locales.size();
-
-    jobjectArray result = env->NewObjectArray(N, g_stringClass, NULL);
-    if (result == NULL) {
-        return NULL;
-    }
-
-    for (int i=0; i<N; i++) {
-        jstring str = env->NewStringUTF(locales[i].string());
-        if (str == NULL) {
-            return NULL;
-        }
-        env->SetObjectArrayElement(result, i, str);
-        env->DeleteLocalRef(str);
-    }
-
-    return result;
-}
-
-static jobjectArray android_content_AssetManager_getLocales(JNIEnv* env, jobject clazz)
-{
-    return getLocales(env, clazz, true /* include system locales */);
-}
-
-static jobjectArray android_content_AssetManager_getNonSystemLocales(JNIEnv* env, jobject clazz)
-{
-    return getLocales(env, clazz, false /* don't include system locales */);
-}
-
-static jobject constructConfigurationObject(JNIEnv* env, const ResTable_config& config) {
-    jobject result = env->NewObject(gConfigurationOffsets.classObject,
-            gConfigurationOffsets.constructor);
-    if (result == NULL) {
-        return NULL;
-    }
-
-    env->SetIntField(result, gConfigurationOffsets.mSmallestScreenWidthDpOffset,
-            config.smallestScreenWidthDp);
-    env->SetIntField(result, gConfigurationOffsets.mScreenWidthDpOffset, config.screenWidthDp);
-    env->SetIntField(result, gConfigurationOffsets.mScreenHeightDpOffset, config.screenHeightDp);
-
-    return result;
-}
-
-static jobjectArray getSizeConfigurationsInternal(JNIEnv* env,
-        const Vector<ResTable_config>& configs) {
-    const int N = configs.size();
-    jobjectArray result = env->NewObjectArray(N, gConfigurationOffsets.classObject, NULL);
-    if (result == NULL) {
-        return NULL;
-    }
-
-    for (int i=0; i<N; i++) {
-        jobject config = constructConfigurationObject(env, configs[i]);
-        if (config == NULL) {
-            env->DeleteLocalRef(result);
-            return NULL;
-        }
-
-        env->SetObjectArrayElement(result, i, config);
-        env->DeleteLocalRef(config);
-    }
-
-    return result;
-}
-
-static jobjectArray android_content_AssetManager_getSizeConfigurations(JNIEnv* env, jobject clazz) {
-    AssetManager* am = assetManagerForJavaObject(env, clazz);
-    if (am == NULL) {
-        return NULL;
-    }
-
-    const ResTable& res(am->getResources());
-    Vector<ResTable_config> configs;
-    res.getConfigurations(&configs, false /* ignoreMipmap */, true /* ignoreAndroidPackage */);
-
-    return getSizeConfigurationsInternal(env, configs);
-}
-
-static void android_content_AssetManager_setConfiguration(JNIEnv* env, jobject clazz,
-                                                          jint mcc, jint mnc,
-                                                          jstring locale, jint orientation,
-                                                          jint touchscreen, jint density,
-                                                          jint keyboard, jint keyboardHidden,
-                                                          jint navigation,
-                                                          jint screenWidth, jint screenHeight,
-                                                          jint smallestScreenWidthDp,
-                                                          jint screenWidthDp, jint screenHeightDp,
-                                                          jint screenLayout, jint uiMode,
-                                                          jint colorMode, jint sdkVersion)
-{
-    AssetManager* am = assetManagerForJavaObject(env, clazz);
-    if (am == NULL) {
-        return;
-    }
-
-    ResTable_config config;
-    memset(&config, 0, sizeof(config));
-
-    const char* locale8 = locale != NULL ? env->GetStringUTFChars(locale, NULL) : NULL;
-
-    // Constants duplicated from Java class android.content.res.Configuration.
-    static const jint kScreenLayoutRoundMask = 0x300;
-    static const jint kScreenLayoutRoundShift = 8;
-
-    config.mcc = (uint16_t)mcc;
-    config.mnc = (uint16_t)mnc;
-    config.orientation = (uint8_t)orientation;
-    config.touchscreen = (uint8_t)touchscreen;
-    config.density = (uint16_t)density;
-    config.keyboard = (uint8_t)keyboard;
-    config.inputFlags = (uint8_t)keyboardHidden;
-    config.navigation = (uint8_t)navigation;
-    config.screenWidth = (uint16_t)screenWidth;
-    config.screenHeight = (uint16_t)screenHeight;
-    config.smallestScreenWidthDp = (uint16_t)smallestScreenWidthDp;
-    config.screenWidthDp = (uint16_t)screenWidthDp;
-    config.screenHeightDp = (uint16_t)screenHeightDp;
-    config.screenLayout = (uint8_t)screenLayout;
-    config.uiMode = (uint8_t)uiMode;
-    config.colorMode = (uint8_t)colorMode;
-    config.sdkVersion = (uint16_t)sdkVersion;
-    config.minorVersion = 0;
-
-    // In Java, we use a 32bit integer for screenLayout, while we only use an 8bit integer
-    // in C++. We must extract the round qualifier out of the Java screenLayout and put it
-    // into screenLayout2.
-    config.screenLayout2 =
-            (uint8_t)((screenLayout & kScreenLayoutRoundMask) >> kScreenLayoutRoundShift);
-
-    am->setConfiguration(config, locale8);
-
-    if (locale != NULL) env->ReleaseStringUTFChars(locale, locale8);
-}
-
-static jint android_content_AssetManager_getResourceIdentifier(JNIEnv* env, jobject clazz,
-                                                            jstring name,
-                                                            jstring defType,
-                                                            jstring defPackage)
-{
-    ScopedStringChars name16(env, name);
-    if (name16.get() == NULL) {
-        return 0;
-    }
-
-    AssetManager* am = assetManagerForJavaObject(env, clazz);
-    if (am == NULL) {
-        return 0;
-    }
-
-    const char16_t* defType16 = reinterpret_cast<const char16_t*>(defType)
-        ? reinterpret_cast<const char16_t*>(env->GetStringChars(defType, NULL))
-        : NULL;
-    jsize defTypeLen = defType
-        ? env->GetStringLength(defType) : 0;
-    const char16_t* defPackage16 = reinterpret_cast<const char16_t*>(defPackage)
-        ? reinterpret_cast<const char16_t*>(env->GetStringChars(defPackage,
-                                                                NULL))
-        : NULL;
-    jsize defPackageLen = defPackage
-        ? env->GetStringLength(defPackage) : 0;
-
-    jint ident = am->getResources().identifierForName(
-        reinterpret_cast<const char16_t*>(name16.get()), name16.size(),
-        defType16, defTypeLen, defPackage16, defPackageLen);
-
-    if (defPackage16) {
-        env->ReleaseStringChars(defPackage,
-                                reinterpret_cast<const jchar*>(defPackage16));
-    }
-    if (defType16) {
-        env->ReleaseStringChars(defType,
-                                reinterpret_cast<const jchar*>(defType16));
-    }
-
-    return ident;
-}
-
-static jstring android_content_AssetManager_getResourceName(JNIEnv* env, jobject clazz,
-                                                            jint resid)
-{
-    AssetManager* am = assetManagerForJavaObject(env, clazz);
-    if (am == NULL) {
-        return NULL;
-    }
-
-    ResTable::resource_name name;
-    if (!am->getResources().getResourceName(resid, true, &name)) {
-        return NULL;
-    }
-
-    String16 str;
-    if (name.package != NULL) {
-        str.setTo(name.package, name.packageLen);
-    }
-    if (name.type8 != NULL || name.type != NULL) {
-        if (str.size() > 0) {
-            char16_t div = ':';
-            str.append(&div, 1);
-        }
-        if (name.type8 != NULL) {
-            str.append(String16(name.type8, name.typeLen));
-        } else {
-            str.append(name.type, name.typeLen);
-        }
-    }
-    if (name.name8 != NULL || name.name != NULL) {
-        if (str.size() > 0) {
-            char16_t div = '/';
-            str.append(&div, 1);
-        }
-        if (name.name8 != NULL) {
-            str.append(String16(name.name8, name.nameLen));
-        } else {
-            str.append(name.name, name.nameLen);
-        }
-    }
-
-    return env->NewString((const jchar*)str.string(), str.size());
-}
-
-static jstring android_content_AssetManager_getResourcePackageName(JNIEnv* env, jobject clazz,
-                                                                   jint resid)
-{
-    AssetManager* am = assetManagerForJavaObject(env, clazz);
-    if (am == NULL) {
-        return NULL;
-    }
-
-    ResTable::resource_name name;
-    if (!am->getResources().getResourceName(resid, true, &name)) {
-        return NULL;
-    }
-
-    if (name.package != NULL) {
-        return env->NewString((const jchar*)name.package, name.packageLen);
-    }
-
-    return NULL;
-}
-
-static jstring android_content_AssetManager_getResourceTypeName(JNIEnv* env, jobject clazz,
-                                                                jint resid)
-{
-    AssetManager* am = assetManagerForJavaObject(env, clazz);
-    if (am == NULL) {
-        return NULL;
-    }
-
-    ResTable::resource_name name;
-    if (!am->getResources().getResourceName(resid, true, &name)) {
-        return NULL;
-    }
-
-    if (name.type8 != NULL) {
-        return env->NewStringUTF(name.type8);
-    }
-
-    if (name.type != NULL) {
-        return env->NewString((const jchar*)name.type, name.typeLen);
-    }
-
-    return NULL;
-}
-
-static jstring android_content_AssetManager_getResourceEntryName(JNIEnv* env, jobject clazz,
-                                                                 jint resid)
-{
-    AssetManager* am = assetManagerForJavaObject(env, clazz);
-    if (am == NULL) {
-        return NULL;
-    }
-
-    ResTable::resource_name name;
-    if (!am->getResources().getResourceName(resid, true, &name)) {
-        return NULL;
-    }
-
-    if (name.name8 != NULL) {
-        return env->NewStringUTF(name.name8);
-    }
-
-    if (name.name != NULL) {
-        return env->NewString((const jchar*)name.name, name.nameLen);
-    }
-
-    return NULL;
-}
-
-static jint android_content_AssetManager_loadResourceValue(JNIEnv* env, jobject clazz,
-                                                           jint ident,
-                                                           jshort density,
-                                                           jobject outValue,
-                                                           jboolean resolve)
-{
-    if (outValue == NULL) {
-         jniThrowNullPointerException(env, "outValue");
-         return 0;
-    }
-    AssetManager* am = assetManagerForJavaObject(env, clazz);
-    if (am == NULL) {
-        return 0;
-    }
-    const ResTable& res(am->getResources());
-
-    Res_value value;
-    ResTable_config config;
-    uint32_t typeSpecFlags;
-    ssize_t block = res.getResource(ident, &value, false, density, &typeSpecFlags, &config);
-    if (kThrowOnBadId) {
-        if (block == BAD_INDEX) {
-            jniThrowException(env, "java/lang/IllegalStateException", "Bad resource!");
-            return 0;
-        }
-    }
-    uint32_t ref = ident;
-    if (resolve) {
-        block = res.resolveReference(&value, block, &ref, &typeSpecFlags, &config);
-        if (kThrowOnBadId) {
-            if (block == BAD_INDEX) {
-                jniThrowException(env, "java/lang/IllegalStateException", "Bad resource!");
-                return 0;
-            }
-        }
-    }
-    if (block >= 0) {
-        return copyValue(env, outValue, &res, value, ref, block, typeSpecFlags, &config);
-    }
-
-    return static_cast<jint>(block);
-}
-
-static jint android_content_AssetManager_loadResourceBagValue(JNIEnv* env, jobject clazz,
-                                                           jint ident, jint bagEntryId,
-                                                           jobject outValue, jboolean resolve)
-{
-    AssetManager* am = assetManagerForJavaObject(env, clazz);
-    if (am == NULL) {
-        return 0;
-    }
-    const ResTable& res(am->getResources());
-
-    // Now lock down the resource object and start pulling stuff from it.
-    res.lock();
-
-    ssize_t block = -1;
-    Res_value value;
-
-    const ResTable::bag_entry* entry = NULL;
-    uint32_t typeSpecFlags;
-    ssize_t entryCount = res.getBagLocked(ident, &entry, &typeSpecFlags);
-
-    for (ssize_t i=0; i<entryCount; i++) {
-        if (((uint32_t)bagEntryId) == entry->map.name.ident) {
-            block = entry->stringBlock;
-            value = entry->map.value;
-        }
-        entry++;
-    }
-
-    res.unlock();
-
-    if (block < 0) {
-        return static_cast<jint>(block);
-    }
-
-    uint32_t ref = ident;
-    if (resolve) {
-        block = res.resolveReference(&value, block, &ref, &typeSpecFlags);
-        if (kThrowOnBadId) {
-            if (block == BAD_INDEX) {
-                jniThrowException(env, "java/lang/IllegalStateException", "Bad resource!");
-                return 0;
-            }
-        }
-    }
-    if (block >= 0) {
-        return copyValue(env, outValue, &res, value, ref, block, typeSpecFlags);
-    }
-
-    return static_cast<jint>(block);
-}
-
-static jint android_content_AssetManager_getStringBlockCount(JNIEnv* env, jobject clazz)
-{
-    AssetManager* am = assetManagerForJavaObject(env, clazz);
-    if (am == NULL) {
-        return 0;
-    }
-    return am->getResources().getTableCount();
-}
-
-static jlong android_content_AssetManager_getNativeStringBlock(JNIEnv* env, jobject clazz,
-                                                           jint block)
-{
-    AssetManager* am = assetManagerForJavaObject(env, clazz);
-    if (am == NULL) {
-        return 0;
-    }
-    return reinterpret_cast<jlong>(am->getResources().getTableStringBlock(block));
-}
-
-static jstring android_content_AssetManager_getCookieName(JNIEnv* env, jobject clazz,
-                                                       jint cookie)
-{
-    AssetManager* am = assetManagerForJavaObject(env, clazz);
-    if (am == NULL) {
-        return NULL;
-    }
-    String8 name(am->getAssetPath(static_cast<int32_t>(cookie)));
-    if (name.length() == 0) {
-        jniThrowException(env, "java/lang/IndexOutOfBoundsException", "Empty cookie name");
-        return NULL;
-    }
-    jstring str = env->NewStringUTF(name.string());
-    return str;
-}
-
-static jobject android_content_AssetManager_getAssignedPackageIdentifiers(JNIEnv* env, jobject clazz)
-{
-    AssetManager* am = assetManagerForJavaObject(env, clazz);
-    if (am == NULL) {
-        return 0;
-    }
-
-    const ResTable& res = am->getResources();
-
-    jobject sparseArray = env->NewObject(gSparseArrayOffsets.classObject,
-            gSparseArrayOffsets.constructor);
-    const size_t N = res.getBasePackageCount();
-    for (size_t i = 0; i < N; i++) {
-        const String16 name = res.getBasePackageName(i);
-        env->CallVoidMethod(
-            sparseArray, gSparseArrayOffsets.put,
-            static_cast<jint>(res.getBasePackageId(i)),
-            env->NewString(reinterpret_cast<const jchar*>(name.string()),
-                           name.size()));
-    }
-    return sparseArray;
-}
-
-static jlong android_content_AssetManager_newTheme(JNIEnv* env, jobject clazz)
-{
-    AssetManager* am = assetManagerForJavaObject(env, clazz);
-    if (am == NULL) {
-        return 0;
-    }
-    return reinterpret_cast<jlong>(new ResTable::Theme(am->getResources()));
-}
-
-static void android_content_AssetManager_deleteTheme(JNIEnv* env, jobject clazz,
-                                                     jlong themeHandle)
-{
-    ResTable::Theme* theme = reinterpret_cast<ResTable::Theme*>(themeHandle);
-    delete theme;
-}
-
-static void android_content_AssetManager_applyThemeStyle(JNIEnv* env, jobject clazz,
-                                                         jlong themeHandle,
-                                                         jint styleRes,
-                                                         jboolean force)
-{
-    ResTable::Theme* theme = reinterpret_cast<ResTable::Theme*>(themeHandle);
-    theme->applyStyle(styleRes, force ? true : false);
-}
-
-static void android_content_AssetManager_copyTheme(JNIEnv* env, jobject clazz,
-                                                   jlong destHandle, jlong srcHandle)
-{
-    ResTable::Theme* dest = reinterpret_cast<ResTable::Theme*>(destHandle);
-    ResTable::Theme* src = reinterpret_cast<ResTable::Theme*>(srcHandle);
-    dest->setTo(*src);
-}
-
-static void android_content_AssetManager_clearTheme(JNIEnv* env, jobject clazz, jlong themeHandle)
-{
-    ResTable::Theme* theme = reinterpret_cast<ResTable::Theme*>(themeHandle);
-    theme->clear();
-}
-
-static jint android_content_AssetManager_loadThemeAttributeValue(
-    JNIEnv* env, jobject clazz, jlong themeHandle, jint ident, jobject outValue, jboolean resolve)
-{
-    ResTable::Theme* theme = reinterpret_cast<ResTable::Theme*>(themeHandle);
-    const ResTable& res(theme->getResTable());
-
-    Res_value value;
-    // XXX value could be different in different configs!
-    uint32_t typeSpecFlags = 0;
-    ssize_t block = theme->getAttribute(ident, &value, &typeSpecFlags);
-    uint32_t ref = 0;
-    if (resolve) {
-        block = res.resolveReference(&value, block, &ref, &typeSpecFlags);
-        if (kThrowOnBadId) {
-            if (block == BAD_INDEX) {
-                jniThrowException(env, "java/lang/IllegalStateException", "Bad resource!");
-                return 0;
-            }
-        }
-    }
-    return block >= 0 ? copyValue(env, outValue, &res, value, ref, block, typeSpecFlags) : block;
-}
-
-static jint android_content_AssetManager_getThemeChangingConfigurations(JNIEnv* env, jobject clazz,
-                                                                        jlong themeHandle)
-{
-    ResTable::Theme* theme = reinterpret_cast<ResTable::Theme*>(themeHandle);
-    return theme->getChangingConfigurations();
-}
-
-static void android_content_AssetManager_dumpTheme(JNIEnv* env, jobject clazz,
-                                                   jlong themeHandle, jint pri,
-                                                   jstring tag, jstring prefix)
-{
-    ResTable::Theme* theme = reinterpret_cast<ResTable::Theme*>(themeHandle);
-    const ResTable& res(theme->getResTable());
-    (void)res;
-
-    // XXX Need to use params.
-    theme->dumpToLog();
-}
-
-static jboolean android_content_AssetManager_resolveAttrs(JNIEnv* env, jobject clazz,
-                                                          jlong themeToken,
-                                                          jint defStyleAttr,
-                                                          jint defStyleRes,
-                                                          jintArray inValues,
-                                                          jintArray attrs,
-                                                          jintArray outValues,
-                                                          jintArray outIndices)
-{
-    if (themeToken == 0) {
-        jniThrowNullPointerException(env, "theme token");
-        return JNI_FALSE;
-    }
-    if (attrs == NULL) {
-        jniThrowNullPointerException(env, "attrs");
-        return JNI_FALSE;
-    }
-    if (outValues == NULL) {
-        jniThrowNullPointerException(env, "out values");
-        return JNI_FALSE;
-    }
-
-    const jsize NI = env->GetArrayLength(attrs);
-    const jsize NV = env->GetArrayLength(outValues);
-    if (NV < (NI*STYLE_NUM_ENTRIES)) {
-        jniThrowException(env, "java/lang/IndexOutOfBoundsException", "out values too small");
-        return JNI_FALSE;
-    }
-
-    jint* src = (jint*)env->GetPrimitiveArrayCritical(attrs, 0);
-    if (src == NULL) {
-        return JNI_FALSE;
-    }
-
-    jint* srcValues = (jint*)env->GetPrimitiveArrayCritical(inValues, 0);
-    const jsize NSV = srcValues == NULL ? 0 : env->GetArrayLength(inValues);
-
-    jint* baseDest = (jint*)env->GetPrimitiveArrayCritical(outValues, 0);
-    if (baseDest == NULL) {
-        env->ReleasePrimitiveArrayCritical(attrs, src, 0);
-        return JNI_FALSE;
-    }
-
-    jint* indices = NULL;
-    if (outIndices != NULL) {
-        if (env->GetArrayLength(outIndices) > NI) {
-            indices = (jint*)env->GetPrimitiveArrayCritical(outIndices, 0);
-        }
-    }
-
-    ResTable::Theme* theme = reinterpret_cast<ResTable::Theme*>(themeToken);
-    bool result = ResolveAttrs(theme, defStyleAttr, defStyleRes,
-                               (uint32_t*) srcValues, NSV,
-                               (uint32_t*) src, NI,
-                               (uint32_t*) baseDest,
-                               (uint32_t*) indices);
-
-    if (indices != NULL) {
-        env->ReleasePrimitiveArrayCritical(outIndices, indices, 0);
-    }
-    env->ReleasePrimitiveArrayCritical(outValues, baseDest, 0);
-    env->ReleasePrimitiveArrayCritical(inValues, srcValues, 0);
-    env->ReleasePrimitiveArrayCritical(attrs, src, 0);
-    return result ? JNI_TRUE : JNI_FALSE;
-}
-
-static void android_content_AssetManager_applyStyle(JNIEnv* env, jobject, jlong themeToken,
-        jint defStyleAttr, jint defStyleRes, jlong xmlParserToken, jintArray attrsObj, jint length,
-        jlong outValuesAddress, jlong outIndicesAddress) {
-    jint* attrs = env->GetIntArrayElements(attrsObj, 0);
-    ResTable::Theme* theme = reinterpret_cast<ResTable::Theme*>(themeToken);
-    ResXMLParser* xmlParser = reinterpret_cast<ResXMLParser*>(xmlParserToken);
-    uint32_t* outValues = reinterpret_cast<uint32_t*>(static_cast<uintptr_t>(outValuesAddress));
-    uint32_t* outIndices = reinterpret_cast<uint32_t*>(static_cast<uintptr_t>(outIndicesAddress));
-    ApplyStyle(theme, xmlParser, defStyleAttr, defStyleRes,
-            reinterpret_cast<const uint32_t*>(attrs), length, outValues, outIndices);
-    env->ReleaseIntArrayElements(attrsObj, attrs, JNI_ABORT);
-}
-
-static jboolean android_content_AssetManager_retrieveAttributes(JNIEnv* env, jobject clazz,
-                                                        jlong xmlParserToken,
-                                                        jintArray attrs,
-                                                        jintArray outValues,
-                                                        jintArray outIndices)
-{
-    if (xmlParserToken == 0) {
-        jniThrowNullPointerException(env, "xmlParserToken");
-        return JNI_FALSE;
-    }
-    if (attrs == NULL) {
-        jniThrowNullPointerException(env, "attrs");
-        return JNI_FALSE;
-    }
-    if (outValues == NULL) {
-        jniThrowNullPointerException(env, "out values");
-        return JNI_FALSE;
-    }
-
-    AssetManager* am = assetManagerForJavaObject(env, clazz);
-    if (am == NULL) {
-        return JNI_FALSE;
-    }
-    const ResTable& res(am->getResources());
-    ResXMLParser* xmlParser = (ResXMLParser*)xmlParserToken;
-
-    const jsize NI = env->GetArrayLength(attrs);
-    const jsize NV = env->GetArrayLength(outValues);
-    if (NV < (NI*STYLE_NUM_ENTRIES)) {
-        jniThrowException(env, "java/lang/IndexOutOfBoundsException", "out values too small");
-        return JNI_FALSE;
-    }
-
-    jint* src = (jint*)env->GetPrimitiveArrayCritical(attrs, 0);
-    if (src == NULL) {
-        return JNI_FALSE;
-    }
-
-    jint* baseDest = (jint*)env->GetPrimitiveArrayCritical(outValues, 0);
-    if (baseDest == NULL) {
-        env->ReleasePrimitiveArrayCritical(attrs, src, 0);
-        return JNI_FALSE;
-    }
-
-    jint* indices = NULL;
-    if (outIndices != NULL) {
-        if (env->GetArrayLength(outIndices) > NI) {
-            indices = (jint*)env->GetPrimitiveArrayCritical(outIndices, 0);
-        }
-    }
-
-    bool result = RetrieveAttributes(&res, xmlParser,
-                                     (uint32_t*) src, NI,
-                                     (uint32_t*) baseDest,
-                                     (uint32_t*) indices);
-
-    if (indices != NULL) {
-        env->ReleasePrimitiveArrayCritical(outIndices, indices, 0);
-    }
-    env->ReleasePrimitiveArrayCritical(outValues, baseDest, 0);
-    env->ReleasePrimitiveArrayCritical(attrs, src, 0);
-    return result ? JNI_TRUE : JNI_FALSE;
-}
-
-static jint android_content_AssetManager_getArraySize(JNIEnv* env, jobject clazz,
-                                                       jint id)
-{
-    AssetManager* am = assetManagerForJavaObject(env, clazz);
-    if (am == NULL) {
-        return 0;
-    }
-    const ResTable& res(am->getResources());
-
-    res.lock();
-    const ResTable::bag_entry* defStyleEnt = NULL;
-    ssize_t bagOff = res.getBagLocked(id, &defStyleEnt);
-    res.unlock();
-
-    return static_cast<jint>(bagOff);
-}
-
-static jint android_content_AssetManager_retrieveArray(JNIEnv* env, jobject clazz,
-                                                        jint id,
-                                                        jintArray outValues)
-{
-    if (outValues == NULL) {
-        jniThrowNullPointerException(env, "out values");
-        return JNI_FALSE;
-    }
-
-    AssetManager* am = assetManagerForJavaObject(env, clazz);
-    if (am == NULL) {
-        return JNI_FALSE;
-    }
-    const ResTable& res(am->getResources());
-    ResTable_config config;
-    Res_value value;
-    ssize_t block;
-
-    const jsize NV = env->GetArrayLength(outValues);
-
-    jint* baseDest = (jint*)env->GetPrimitiveArrayCritical(outValues, 0);
-    jint* dest = baseDest;
-    if (dest == NULL) {
-        jniThrowException(env, "java/lang/OutOfMemoryError", "");
-        return JNI_FALSE;
-    }
-
-    // Now lock down the resource object and start pulling stuff from it.
-    res.lock();
-
-    const ResTable::bag_entry* arrayEnt = NULL;
-    uint32_t arrayTypeSetFlags = 0;
-    ssize_t bagOff = res.getBagLocked(id, &arrayEnt, &arrayTypeSetFlags);
-    const ResTable::bag_entry* endArrayEnt = arrayEnt +
-        (bagOff >= 0 ? bagOff : 0);
-
-    int i = 0;
-    uint32_t typeSetFlags;
-    while (i < NV && arrayEnt < endArrayEnt) {
-        block = arrayEnt->stringBlock;
-        typeSetFlags = arrayTypeSetFlags;
-        config.density = 0;
-        value = arrayEnt->map.value;
-
-        uint32_t resid = 0;
-        if (value.dataType != Res_value::TYPE_NULL) {
-            // Take care of resolving the found resource to its final value.
-            //printf("Resolving attribute reference\n");
-            ssize_t newBlock = res.resolveReference(&value, block, &resid,
-                    &typeSetFlags, &config);
-            if (kThrowOnBadId) {
-                if (newBlock == BAD_INDEX) {
-                    jniThrowException(env, "java/lang/IllegalStateException", "Bad resource!");
-                    return JNI_FALSE;
-                }
-            }
-            if (newBlock >= 0) block = newBlock;
-        }
-
-        // Deal with the special @null value -- it turns back to TYPE_NULL.
-        if (value.dataType == Res_value::TYPE_REFERENCE && value.data == 0) {
-            value.dataType = Res_value::TYPE_NULL;
-            value.data = Res_value::DATA_NULL_UNDEFINED;
-        }
-
-        //printf("Attribute 0x%08x: final type=0x%x, data=0x%08x\n", curIdent, value.dataType, value.data);
-
-        // Write the final value back to Java.
-        dest[STYLE_TYPE] = value.dataType;
-        dest[STYLE_DATA] = value.data;
-        dest[STYLE_ASSET_COOKIE] = reinterpret_cast<jint>(res.getTableCookie(block));
-        dest[STYLE_RESOURCE_ID] = resid;
-        dest[STYLE_CHANGING_CONFIGURATIONS] = typeSetFlags;
-        dest[STYLE_DENSITY] = config.density;
-        dest += STYLE_NUM_ENTRIES;
-        i+= STYLE_NUM_ENTRIES;
-        arrayEnt++;
-    }
-
-    i /= STYLE_NUM_ENTRIES;
-
-    res.unlock();
-
-    env->ReleasePrimitiveArrayCritical(outValues, baseDest, 0);
-
-    return i;
-}
-
-static jlong android_content_AssetManager_openXmlAssetNative(JNIEnv* env, jobject clazz,
-                                                         jint cookie,
-                                                         jstring fileName)
-{
-    AssetManager* am = assetManagerForJavaObject(env, clazz);
-    if (am == NULL) {
-        return 0;
-    }
-
-    ALOGV("openXmlAsset in %p (Java object %p)\n", am, clazz);
-
-    ScopedUtfChars fileName8(env, fileName);
-    if (fileName8.c_str() == NULL) {
-        return 0;
-    }
-
-    int32_t assetCookie = static_cast<int32_t>(cookie);
-    Asset* a = assetCookie
-        ? am->openNonAsset(assetCookie, fileName8.c_str(), Asset::ACCESS_BUFFER)
-        : am->openNonAsset(fileName8.c_str(), Asset::ACCESS_BUFFER, &assetCookie);
-
-    if (a == NULL) {
-        jniThrowException(env, "java/io/FileNotFoundException", fileName8.c_str());
-        return 0;
-    }
-
-    const DynamicRefTable* dynamicRefTable =
-            am->getResources().getDynamicRefTableForCookie(assetCookie);
-    ResXMLTree* block = new ResXMLTree(dynamicRefTable);
-    status_t err = block->setTo(a->getBuffer(true), a->getLength(), true);
-    a->close();
-    delete a;
-
-    if (err != NO_ERROR) {
-        jniThrowException(env, "java/io/FileNotFoundException", "Corrupt XML binary file");
-        return 0;
-    }
-
-    return reinterpret_cast<jlong>(block);
-}
-
-static jintArray android_content_AssetManager_getArrayStringInfo(JNIEnv* env, jobject clazz,
-                                                                 jint arrayResId)
-{
-    AssetManager* am = assetManagerForJavaObject(env, clazz);
-    if (am == NULL) {
-        return NULL;
-    }
-    const ResTable& res(am->getResources());
-
-    const ResTable::bag_entry* startOfBag;
-    const ssize_t N = res.lockBag(arrayResId, &startOfBag);
-    if (N < 0) {
-        return NULL;
-    }
-
-    jintArray array = env->NewIntArray(N * 2);
-    if (array == NULL) {
-        res.unlockBag(startOfBag);
-        return NULL;
-    }
-
-    Res_value value;
-    const ResTable::bag_entry* bag = startOfBag;
-    for (size_t i = 0, j = 0; ((ssize_t)i)<N; i++, bag++) {
-        jint stringIndex = -1;
-        jint stringBlock = 0;
-        value = bag->map.value;
-
-        // Take care of resolving the found resource to its final value.
-        stringBlock = res.resolveReference(&value, bag->stringBlock, NULL);
-        if (value.dataType == Res_value::TYPE_STRING) {
-            stringIndex = value.data;
-        }
-
-        if (kThrowOnBadId) {
-            if (stringBlock == BAD_INDEX) {
-                jniThrowException(env, "java/lang/IllegalStateException", "Bad resource!");
-                return array;
-            }
-        }
-
-        //todo: It might be faster to allocate a C array to contain
-        //      the blocknums and indices, put them in there and then
-        //      do just one SetIntArrayRegion()
-        env->SetIntArrayRegion(array, j, 1, &stringBlock);
-        env->SetIntArrayRegion(array, j + 1, 1, &stringIndex);
-        j = j + 2;
-    }
-    res.unlockBag(startOfBag);
-    return array;
-}
-
-static jobjectArray android_content_AssetManager_getArrayStringResource(JNIEnv* env, jobject clazz,
-                                                                        jint arrayResId)
-{
-    AssetManager* am = assetManagerForJavaObject(env, clazz);
-    if (am == NULL) {
-        return NULL;
-    }
-    const ResTable& res(am->getResources());
-
-    const ResTable::bag_entry* startOfBag;
-    const ssize_t N = res.lockBag(arrayResId, &startOfBag);
-    if (N < 0) {
-        return NULL;
-    }
-
-    jobjectArray array = env->NewObjectArray(N, g_stringClass, NULL);
-    if (env->ExceptionCheck()) {
-        res.unlockBag(startOfBag);
-        return NULL;
-    }
-
-    Res_value value;
-    const ResTable::bag_entry* bag = startOfBag;
-    size_t strLen = 0;
-    for (size_t i=0; ((ssize_t)i)<N; i++, bag++) {
-        value = bag->map.value;
-        jstring str = NULL;
-
-        // Take care of resolving the found resource to its final value.
-        ssize_t block = res.resolveReference(&value, bag->stringBlock, NULL);
-        if (kThrowOnBadId) {
-            if (block == BAD_INDEX) {
-                jniThrowException(env, "java/lang/IllegalStateException", "Bad resource!");
-                return array;
-            }
-        }
-        if (value.dataType == Res_value::TYPE_STRING) {
-            const ResStringPool* pool = res.getTableStringBlock(block);
-            const char* str8 = pool->string8At(value.data, &strLen);
-            if (str8 != NULL) {
-                str = env->NewStringUTF(str8);
-            } else {
-                const char16_t* str16 = pool->stringAt(value.data, &strLen);
-                str = env->NewString(reinterpret_cast<const jchar*>(str16),
-                                     strLen);
-            }
-
-            // If one of our NewString{UTF} calls failed due to memory, an
-            // exception will be pending.
-            if (env->ExceptionCheck()) {
-                res.unlockBag(startOfBag);
-                return NULL;
-            }
-
-            env->SetObjectArrayElement(array, i, str);
-
-            // str is not NULL at that point, otherwise ExceptionCheck would have been true.
-            // If we have a large amount of strings in our array, we might
-            // overflow the local reference table of the VM.
-            env->DeleteLocalRef(str);
-        }
-    }
-    res.unlockBag(startOfBag);
-    return array;
-}
-
-static jintArray android_content_AssetManager_getArrayIntResource(JNIEnv* env, jobject clazz,
-                                                                        jint arrayResId)
-{
-    AssetManager* am = assetManagerForJavaObject(env, clazz);
-    if (am == NULL) {
-        return NULL;
-    }
-    const ResTable& res(am->getResources());
-
-    const ResTable::bag_entry* startOfBag;
-    const ssize_t N = res.lockBag(arrayResId, &startOfBag);
-    if (N < 0) {
-        return NULL;
-    }
-
-    jintArray array = env->NewIntArray(N);
-    if (array == NULL) {
-        res.unlockBag(startOfBag);
-        return NULL;
-    }
-
-    Res_value value;
-    const ResTable::bag_entry* bag = startOfBag;
-    for (size_t i=0; ((ssize_t)i)<N; i++, bag++) {
-        value = bag->map.value;
-
-        // Take care of resolving the found resource to its final value.
-        ssize_t block = res.resolveReference(&value, bag->stringBlock, NULL);
-        if (kThrowOnBadId) {
-            if (block == BAD_INDEX) {
-                jniThrowException(env, "java/lang/IllegalStateException", "Bad resource!");
-                return array;
-            }
-        }
-        if (value.dataType >= Res_value::TYPE_FIRST_INT
-                && value.dataType <= Res_value::TYPE_LAST_INT) {
-            int intVal = value.data;
-            env->SetIntArrayRegion(array, i, 1, &intVal);
-        }
-    }
-    res.unlockBag(startOfBag);
-    return array;
-}
-
-static jintArray android_content_AssetManager_getStyleAttributes(JNIEnv* env, jobject clazz,
-                                                                 jint styleId)
-{
-    AssetManager* am = assetManagerForJavaObject(env, clazz);
-    if (am == NULL) {
-        return NULL;
-    }
-    const ResTable& res(am->getResources());
-
-    const ResTable::bag_entry* startOfBag;
-    const ssize_t N = res.lockBag(styleId, &startOfBag);
-    if (N < 0) {
-        return NULL;
-    }
-
-    jintArray array = env->NewIntArray(N);
-    if (array == NULL) {
-        res.unlockBag(startOfBag);
-        return NULL;
-    }
-
-    const ResTable::bag_entry* bag = startOfBag;
-    for (size_t i=0; ((ssize_t)i)<N; i++, bag++) {
-        int resourceId = bag->map.name.ident;
-        env->SetIntArrayRegion(array, i, 1, &resourceId);
-    }
-    res.unlockBag(startOfBag);
-    return array;
-}
-
-static void android_content_AssetManager_init(JNIEnv* env, jobject clazz, jboolean isSystem)
-{
-    if (isSystem) {
-        verifySystemIdmaps();
-    }
-    AssetManager* am = new AssetManager();
-    if (am == NULL) {
-        jniThrowException(env, "java/lang/OutOfMemoryError", "");
-        return;
-    }
-
-    am->addDefaultAssets();
-
-    ALOGV("Created AssetManager %p for Java object %p\n", am, clazz);
-    env->SetLongField(clazz, gAssetManagerOffsets.mObject, reinterpret_cast<jlong>(am));
-}
-
-static void android_content_AssetManager_destroy(JNIEnv* env, jobject clazz)
-{
-    AssetManager* am = (AssetManager*)
-        (env->GetLongField(clazz, gAssetManagerOffsets.mObject));
-    ALOGV("Destroying AssetManager %p for Java object %p\n", am, clazz);
-    if (am != NULL) {
-        delete am;
-        env->SetLongField(clazz, gAssetManagerOffsets.mObject, 0);
-    }
-}
-
-static jint android_content_AssetManager_getGlobalAssetCount(JNIEnv* env, jobject clazz)
-{
-    return Asset::getGlobalCount();
-}
-
-static jobject android_content_AssetManager_getAssetAllocations(JNIEnv* env, jobject clazz)
-{
-    String8 alloc = Asset::getAssetAllocations();
-    if (alloc.length() <= 0) {
-        return NULL;
-    }
-
-    jstring str = env->NewStringUTF(alloc.string());
-    return str;
-}
-
-static jint android_content_AssetManager_getGlobalAssetManagerCount(JNIEnv* env, jobject clazz)
-{
-    return AssetManager::getGlobalCount();
-}
-
-// ----------------------------------------------------------------------------
-
-/*
- * JNI registration.
- */
-static const JNINativeMethod gAssetManagerMethods[] = {
-    /* name, signature, funcPtr */
-
-    // Basic asset stuff.
-    { "openAsset",      "(Ljava/lang/String;I)J",
-        (void*) android_content_AssetManager_openAsset },
-    { "openAssetFd",      "(Ljava/lang/String;[J)Landroid/os/ParcelFileDescriptor;",
-        (void*) android_content_AssetManager_openAssetFd },
-    { "openNonAssetNative", "(ILjava/lang/String;I)J",
-        (void*) android_content_AssetManager_openNonAssetNative },
-    { "openNonAssetFdNative", "(ILjava/lang/String;[J)Landroid/os/ParcelFileDescriptor;",
-        (void*) android_content_AssetManager_openNonAssetFdNative },
-    { "list",           "(Ljava/lang/String;)[Ljava/lang/String;",
-        (void*) android_content_AssetManager_list },
-    { "destroyAsset",   "(J)V",
-        (void*) android_content_AssetManager_destroyAsset },
-    { "readAssetChar",  "(J)I",
-        (void*) android_content_AssetManager_readAssetChar },
-    { "readAsset",      "(J[BII)I",
-        (void*) android_content_AssetManager_readAsset },
-    { "seekAsset",      "(JJI)J",
-        (void*) android_content_AssetManager_seekAsset },
-    { "getAssetLength", "(J)J",
-        (void*) android_content_AssetManager_getAssetLength },
-    { "getAssetRemainingLength", "(J)J",
-        (void*) android_content_AssetManager_getAssetRemainingLength },
-    { "addAssetPathNative", "(Ljava/lang/String;Z)I",
-        (void*) android_content_AssetManager_addAssetPath },
-    { "addAssetFdNative", "(Ljava/io/FileDescriptor;Ljava/lang/String;Z)I",
-        (void*) android_content_AssetManager_addAssetFd },
-    { "addOverlayPathNative",   "(Ljava/lang/String;)I",
-        (void*) android_content_AssetManager_addOverlayPath },
-    { "isUpToDate",     "()Z",
-        (void*) android_content_AssetManager_isUpToDate },
-
-    // Resources.
-    { "getLocales",      "()[Ljava/lang/String;",
-        (void*) android_content_AssetManager_getLocales },
-    { "getNonSystemLocales", "()[Ljava/lang/String;",
-        (void*) android_content_AssetManager_getNonSystemLocales },
-    { "getSizeConfigurations", "()[Landroid/content/res/Configuration;",
-        (void*) android_content_AssetManager_getSizeConfigurations },
-    { "setConfiguration", "(IILjava/lang/String;IIIIIIIIIIIIIII)V",
-        (void*) android_content_AssetManager_setConfiguration },
-    { "getResourceIdentifier","(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I",
-        (void*) android_content_AssetManager_getResourceIdentifier },
-    { "getResourceName","(I)Ljava/lang/String;",
-        (void*) android_content_AssetManager_getResourceName },
-    { "getResourcePackageName","(I)Ljava/lang/String;",
-        (void*) android_content_AssetManager_getResourcePackageName },
-    { "getResourceTypeName","(I)Ljava/lang/String;",
-        (void*) android_content_AssetManager_getResourceTypeName },
-    { "getResourceEntryName","(I)Ljava/lang/String;",
-        (void*) android_content_AssetManager_getResourceEntryName },
-    { "loadResourceValue","(ISLandroid/util/TypedValue;Z)I",
-        (void*) android_content_AssetManager_loadResourceValue },
-    { "loadResourceBagValue","(IILandroid/util/TypedValue;Z)I",
-        (void*) android_content_AssetManager_loadResourceBagValue },
-    { "getStringBlockCount","()I",
-        (void*) android_content_AssetManager_getStringBlockCount },
-    { "getNativeStringBlock","(I)J",
-        (void*) android_content_AssetManager_getNativeStringBlock },
-    { "getCookieName","(I)Ljava/lang/String;",
-        (void*) android_content_AssetManager_getCookieName },
-    { "getAssignedPackageIdentifiers","()Landroid/util/SparseArray;",
-        (void*) android_content_AssetManager_getAssignedPackageIdentifiers },
-
-    // Themes.
-    { "newTheme", "()J",
-        (void*) android_content_AssetManager_newTheme },
-    { "deleteTheme", "(J)V",
-        (void*) android_content_AssetManager_deleteTheme },
-    { "applyThemeStyle", "(JIZ)V",
-        (void*) android_content_AssetManager_applyThemeStyle },
-    { "copyTheme", "(JJ)V",
-        (void*) android_content_AssetManager_copyTheme },
-    { "clearTheme", "(J)V",
-        (void*) android_content_AssetManager_clearTheme },
-    { "loadThemeAttributeValue", "(JILandroid/util/TypedValue;Z)I",
-        (void*) android_content_AssetManager_loadThemeAttributeValue },
-    { "getThemeChangingConfigurations", "(J)I",
-        (void*) android_content_AssetManager_getThemeChangingConfigurations },
-    { "dumpTheme", "(JILjava/lang/String;Ljava/lang/String;)V",
-        (void*) android_content_AssetManager_dumpTheme },
-    { "applyStyle","(JIIJ[IIJJ)V",
-        (void*) android_content_AssetManager_applyStyle },
-    { "resolveAttrs","(JII[I[I[I[I)Z",
-        (void*) android_content_AssetManager_resolveAttrs },
-    { "retrieveAttributes","(J[I[I[I)Z",
-        (void*) android_content_AssetManager_retrieveAttributes },
-    { "getArraySize","(I)I",
-        (void*) android_content_AssetManager_getArraySize },
-    { "retrieveArray","(I[I)I",
-        (void*) android_content_AssetManager_retrieveArray },
-
-    // XML files.
-    { "openXmlAssetNative", "(ILjava/lang/String;)J",
-        (void*) android_content_AssetManager_openXmlAssetNative },
-
-    // Arrays.
-    { "getArrayStringResource","(I)[Ljava/lang/String;",
-        (void*) android_content_AssetManager_getArrayStringResource },
-    { "getArrayStringInfo","(I)[I",
-        (void*) android_content_AssetManager_getArrayStringInfo },
-    { "getArrayIntResource","(I)[I",
-        (void*) android_content_AssetManager_getArrayIntResource },
-    { "getStyleAttributes","(I)[I",
-        (void*) android_content_AssetManager_getStyleAttributes },
-
-    // Bookkeeping.
-    { "init",           "(Z)V",
-        (void*) android_content_AssetManager_init },
-    { "destroy",        "()V",
-        (void*) android_content_AssetManager_destroy },
-    { "getGlobalAssetCount", "()I",
-        (void*) android_content_AssetManager_getGlobalAssetCount },
-    { "getAssetAllocations", "()Ljava/lang/String;",
-        (void*) android_content_AssetManager_getAssetAllocations },
-    { "getGlobalAssetManagerCount", "()I",
-        (void*) android_content_AssetManager_getGlobalAssetManagerCount },
+// Let the opaque type AAssetManager refer to a guarded AssetManager2 instance.
+struct GuardedAssetManager : public ::AAssetManager {
+  Guarded<AssetManager2> guarded_assetmanager;
 };
 
-int register_android_content_AssetManager(JNIEnv* env)
-{
-    jclass typedValue = FindClassOrDie(env, "android/util/TypedValue");
-    gTypedValueOffsets.mType = GetFieldIDOrDie(env, typedValue, "type", "I");
-    gTypedValueOffsets.mData = GetFieldIDOrDie(env, typedValue, "data", "I");
-    gTypedValueOffsets.mString = GetFieldIDOrDie(env, typedValue, "string",
-                                                 "Ljava/lang/CharSequence;");
-    gTypedValueOffsets.mAssetCookie = GetFieldIDOrDie(env, typedValue, "assetCookie", "I");
-    gTypedValueOffsets.mResourceId = GetFieldIDOrDie(env, typedValue, "resourceId", "I");
-    gTypedValueOffsets.mChangingConfigurations = GetFieldIDOrDie(env, typedValue,
-                                                                 "changingConfigurations", "I");
-    gTypedValueOffsets.mDensity = GetFieldIDOrDie(env, typedValue, "density", "I");
+::AAssetManager* NdkAssetManagerForJavaObject(JNIEnv* env, jobject jassetmanager) {
+  jlong assetmanager_handle = env->GetLongField(jassetmanager, gAssetManagerOffsets.mObject);
+  ::AAssetManager* am = reinterpret_cast<::AAssetManager*>(assetmanager_handle);
+  if (am == nullptr) {
+    jniThrowException(env, "java/lang/IllegalStateException", "AssetManager has been finalized!");
+    return nullptr;
+  }
+  return am;
+}
 
-    jclass assetFd = FindClassOrDie(env, "android/content/res/AssetFileDescriptor");
-    gAssetFileDescriptorOffsets.mFd = GetFieldIDOrDie(env, assetFd, "mFd",
-                                                      "Landroid/os/ParcelFileDescriptor;");
-    gAssetFileDescriptorOffsets.mStartOffset = GetFieldIDOrDie(env, assetFd, "mStartOffset", "J");
-    gAssetFileDescriptorOffsets.mLength = GetFieldIDOrDie(env, assetFd, "mLength", "J");
+Guarded<AssetManager2>* AssetManagerForNdkAssetManager(::AAssetManager* assetmanager) {
+  if (assetmanager == nullptr) {
+    return nullptr;
+  }
+  return &reinterpret_cast<GuardedAssetManager*>(assetmanager)->guarded_assetmanager;
+}
 
-    jclass assetManager = FindClassOrDie(env, "android/content/res/AssetManager");
-    gAssetManagerOffsets.mObject = GetFieldIDOrDie(env, assetManager, "mObject", "J");
+Guarded<AssetManager2>* AssetManagerForJavaObject(JNIEnv* env, jobject jassetmanager) {
+  return AssetManagerForNdkAssetManager(NdkAssetManagerForJavaObject(env, jassetmanager));
+}
 
-    jclass stringClass = FindClassOrDie(env, "java/lang/String");
-    g_stringClass = MakeGlobalRefOrDie(env, stringClass);
+static Guarded<AssetManager2>& AssetManagerFromLong(jlong ptr) {
+  return *AssetManagerForNdkAssetManager(reinterpret_cast<AAssetManager*>(ptr));
+}
 
-    jclass sparseArrayClass = FindClassOrDie(env, "android/util/SparseArray");
-    gSparseArrayOffsets.classObject = MakeGlobalRefOrDie(env, sparseArrayClass);
-    gSparseArrayOffsets.constructor = GetMethodIDOrDie(env, gSparseArrayOffsets.classObject,
-                                                       "<init>", "()V");
-    gSparseArrayOffsets.put = GetMethodIDOrDie(env, gSparseArrayOffsets.classObject, "put",
-                                               "(ILjava/lang/Object;)V");
+static jobject ReturnParcelFileDescriptor(JNIEnv* env, std::unique_ptr<Asset> asset,
+                                          jlongArray out_offsets) {
+  off64_t start_offset, length;
+  int fd = asset->openFileDescriptor(&start_offset, &length);
+  asset.reset();
 
-    jclass configurationClass = FindClassOrDie(env, "android/content/res/Configuration");
-    gConfigurationOffsets.classObject = MakeGlobalRefOrDie(env, configurationClass);
-    gConfigurationOffsets.constructor = GetMethodIDOrDie(env, configurationClass,
-            "<init>", "()V");
-    gConfigurationOffsets.mSmallestScreenWidthDpOffset = GetFieldIDOrDie(env, configurationClass,
-            "smallestScreenWidthDp", "I");
-    gConfigurationOffsets.mScreenWidthDpOffset = GetFieldIDOrDie(env, configurationClass,
-            "screenWidthDp", "I");
-    gConfigurationOffsets.mScreenHeightDpOffset = GetFieldIDOrDie(env, configurationClass,
-            "screenHeightDp", "I");
+  if (fd < 0) {
+    jniThrowException(env, "java/io/FileNotFoundException",
+                      "This file can not be opened as a file descriptor; it is probably "
+                      "compressed");
+    return nullptr;
+  }
 
-    return RegisterMethodsOrDie(env, "android/content/res/AssetManager", gAssetManagerMethods,
-                                NELEM(gAssetManagerMethods));
+  jlong* offsets = reinterpret_cast<jlong*>(env->GetPrimitiveArrayCritical(out_offsets, 0));
+  if (offsets == nullptr) {
+    close(fd);
+    return nullptr;
+  }
+
+  offsets[0] = start_offset;
+  offsets[1] = length;
+
+  env->ReleasePrimitiveArrayCritical(out_offsets, offsets, 0);
+
+  jobject file_desc = jniCreateFileDescriptor(env, fd);
+  if (file_desc == nullptr) {
+    close(fd);
+    return nullptr;
+  }
+  return newParcelFileDescriptor(env, file_desc);
+}
+
+static jint NativeGetGlobalAssetCount(JNIEnv* /*env*/, jobject /*clazz*/) {
+  return Asset::getGlobalCount();
+}
+
+static jobject NativeGetAssetAllocations(JNIEnv* env, jobject /*clazz*/) {
+  String8 alloc = Asset::getAssetAllocations();
+  if (alloc.length() <= 0) {
+    return nullptr;
+  }
+  return env->NewStringUTF(alloc.string());
+}
+
+static jint NativeGetGlobalAssetManagerCount(JNIEnv* /*env*/, jobject /*clazz*/) {
+  // TODO(adamlesinski): Switch to AssetManager2.
+  return AssetManager::getGlobalCount();
+}
+
+static jlong NativeCreate(JNIEnv* /*env*/, jclass /*clazz*/) {
+  // AssetManager2 needs to be protected by a lock. To avoid cache misses, we allocate the lock and
+  // AssetManager2 in a contiguous block (GuardedAssetManager).
+  return reinterpret_cast<jlong>(new GuardedAssetManager());
+}
+
+static void NativeDestroy(JNIEnv* /*env*/, jclass /*clazz*/, jlong ptr) {
+  delete reinterpret_cast<GuardedAssetManager*>(ptr);
+}
+
+static void NativeSetApkAssets(JNIEnv* env, jclass /*clazz*/, jlong ptr,
+                               jobjectArray apk_assets_array, jboolean invalidate_caches) {
+  const jsize apk_assets_len = env->GetArrayLength(apk_assets_array);
+  std::vector<const ApkAssets*> apk_assets;
+  apk_assets.reserve(apk_assets_len);
+  for (jsize i = 0; i < apk_assets_len; i++) {
+    jobject obj = env->GetObjectArrayElement(apk_assets_array, i);
+    if (obj == nullptr) {
+      std::string msg = StringPrintf("ApkAssets at index %d is null", i);
+      jniThrowNullPointerException(env, msg.c_str());
+      return;
+    }
+
+    jlong apk_assets_native_ptr = env->GetLongField(obj, gApkAssetsFields.native_ptr);
+    if (env->ExceptionCheck()) {
+      return;
+    }
+    apk_assets.push_back(reinterpret_cast<const ApkAssets*>(apk_assets_native_ptr));
+  }
+
+  ScopedLock<AssetManager2> assetmanager(AssetManagerFromLong(ptr));
+  assetmanager->SetApkAssets(apk_assets, invalidate_caches);
+}
+
+static void NativeSetConfiguration(JNIEnv* env, jclass /*clazz*/, jlong ptr, jint mcc, jint mnc,
+                                   jstring locale, jint orientation, jint touchscreen, jint density,
+                                   jint keyboard, jint keyboard_hidden, jint navigation,
+                                   jint screen_width, jint screen_height,
+                                   jint smallest_screen_width_dp, jint screen_width_dp,
+                                   jint screen_height_dp, jint screen_layout, jint ui_mode,
+                                   jint color_mode, jint major_version) {
+  ResTable_config configuration;
+  memset(&configuration, 0, sizeof(configuration));
+  configuration.mcc = static_cast<uint16_t>(mcc);
+  configuration.mnc = static_cast<uint16_t>(mnc);
+  configuration.orientation = static_cast<uint8_t>(orientation);
+  configuration.touchscreen = static_cast<uint8_t>(touchscreen);
+  configuration.density = static_cast<uint16_t>(density);
+  configuration.keyboard = static_cast<uint8_t>(keyboard);
+  configuration.inputFlags = static_cast<uint8_t>(keyboard_hidden);
+  configuration.navigation = static_cast<uint8_t>(navigation);
+  configuration.screenWidth = static_cast<uint16_t>(screen_width);
+  configuration.screenHeight = static_cast<uint16_t>(screen_height);
+  configuration.smallestScreenWidthDp = static_cast<uint16_t>(smallest_screen_width_dp);
+  configuration.screenWidthDp = static_cast<uint16_t>(screen_width_dp);
+  configuration.screenHeightDp = static_cast<uint16_t>(screen_height_dp);
+  configuration.screenLayout = static_cast<uint8_t>(screen_layout);
+  configuration.uiMode = static_cast<uint8_t>(ui_mode);
+  configuration.colorMode = static_cast<uint8_t>(color_mode);
+  configuration.sdkVersion = static_cast<uint16_t>(major_version);
+
+  if (locale != nullptr) {
+    ScopedUtfChars locale_utf8(env, locale);
+    CHECK(locale_utf8.c_str() != nullptr);
+    configuration.setBcp47Locale(locale_utf8.c_str());
+  }
+
+  // Constants duplicated from Java class android.content.res.Configuration.
+  static const jint kScreenLayoutRoundMask = 0x300;
+  static const jint kScreenLayoutRoundShift = 8;
+
+  // In Java, we use a 32bit integer for screenLayout, while we only use an 8bit integer
+  // in C++. We must extract the round qualifier out of the Java screenLayout and put it
+  // into screenLayout2.
+  configuration.screenLayout2 =
+      static_cast<uint8_t>((screen_layout & kScreenLayoutRoundMask) >> kScreenLayoutRoundShift);
+
+  ScopedLock<AssetManager2> assetmanager(AssetManagerFromLong(ptr));
+  assetmanager->SetConfiguration(configuration);
+}
+
+static jobject NativeGetAssignedPackageIdentifiers(JNIEnv* env, jclass /*clazz*/, jlong ptr) {
+  ScopedLock<AssetManager2> assetmanager(AssetManagerFromLong(ptr));
+
+  jobject sparse_array =
+        env->NewObject(gSparseArrayOffsets.classObject, gSparseArrayOffsets.constructor);
+
+  if (sparse_array == nullptr) {
+    // An exception is pending.
+    return nullptr;
+  }
+
+  assetmanager->ForEachPackage([&](const std::string& package_name, uint8_t package_id) {
+    jstring jpackage_name = env->NewStringUTF(package_name.c_str());
+    if (jpackage_name == nullptr) {
+      // An exception is pending.
+      return;
+    }
+
+    env->CallVoidMethod(sparse_array, gSparseArrayOffsets.put, static_cast<jint>(package_id),
+                        jpackage_name);
+  });
+  return sparse_array;
+}
+
+static jobjectArray NativeList(JNIEnv* env, jclass /*clazz*/, jlong ptr, jstring path) {
+  ScopedUtfChars path_utf8(env, path);
+  if (path_utf8.c_str() == nullptr) {
+    // This will throw NPE.
+    return nullptr;
+  }
+
+  std::vector<std::string> all_file_paths;
+  {
+    StringPiece normalized_path = path_utf8.c_str();
+    if (normalized_path.data()[0] == '/') {
+      normalized_path = normalized_path.substr(1);
+    }
+    std::string root_path = StringPrintf("assets/%s", normalized_path.data());
+    ScopedLock<AssetManager2> assetmanager(AssetManagerFromLong(ptr));
+    for (const ApkAssets* assets : assetmanager->GetApkAssets()) {
+      assets->ForEachFile(root_path, [&](const StringPiece& file_path, FileType type) {
+        if (type == FileType::kFileTypeRegular) {
+          all_file_paths.push_back(file_path.to_string());
+        }
+      });
+    }
+  }
+
+  jobjectArray array = env->NewObjectArray(all_file_paths.size(), g_stringClass, nullptr);
+  if (array == nullptr) {
+    return nullptr;
+  }
+
+  jsize index = 0;
+  for (const std::string& file_path : all_file_paths) {
+    jstring java_string = env->NewStringUTF(file_path.c_str());
+
+    // Check for errors creating the strings (if malformed or no memory).
+    if (env->ExceptionCheck()) {
+     return nullptr;
+    }
+
+    env->SetObjectArrayElement(array, index++, java_string);
+
+    // If we have a large amount of string in our array, we might overflow the
+    // local reference table of the VM.
+    env->DeleteLocalRef(java_string);
+  }
+  return array;
+}
+
+static jlong NativeOpenAsset(JNIEnv* env, jclass /*clazz*/, jlong ptr, jstring asset_path,
+                             jint access_mode) {
+  ScopedUtfChars asset_path_utf8(env, asset_path);
+  if (asset_path_utf8.c_str() == nullptr) {
+    // This will throw NPE.
+    return 0;
+  }
+
+  if (access_mode != Asset::ACCESS_UNKNOWN && access_mode != Asset::ACCESS_RANDOM &&
+      access_mode != Asset::ACCESS_STREAMING && access_mode != Asset::ACCESS_BUFFER) {
+    jniThrowException(env, "java/lang/IllegalArgumentException", "Bad access mode");
+    return 0;
+  }
+
+  ScopedLock<AssetManager2> assetmanager(AssetManagerFromLong(ptr));
+  std::unique_ptr<Asset> asset =
+      assetmanager->Open(asset_path_utf8.c_str(), static_cast<Asset::AccessMode>(access_mode));
+  if (!asset) {
+    jniThrowException(env, "java/io/FileNotFoundException", asset_path_utf8.c_str());
+    return 0;
+  }
+  return reinterpret_cast<jlong>(asset.release());
+}
+
+static jobject NativeOpenAssetFd(JNIEnv* env, jclass /*clazz*/, jlong ptr, jstring asset_path,
+                                 jlongArray out_offsets) {
+  ScopedUtfChars asset_path_utf8(env, asset_path);
+  if (asset_path_utf8.c_str() == nullptr) {
+    // This will throw NPE.
+    return nullptr;
+  }
+
+  ScopedLock<AssetManager2> assetmanager(AssetManagerFromLong(ptr));
+  std::unique_ptr<Asset> asset = assetmanager->Open(asset_path_utf8.c_str(), Asset::ACCESS_RANDOM);
+  if (!asset) {
+    jniThrowException(env, "java/io/FileNotFoundException", asset_path_utf8.c_str());
+    return nullptr;
+  }
+  return ReturnParcelFileDescriptor(env, std::move(asset), out_offsets);
+}
+
+static jlong NativeOpenNonAsset(JNIEnv* env, jclass /*clazz*/, jlong ptr, jint jcookie,
+                                jstring asset_path, jint access_mode) {
+  ApkAssetsCookie cookie = JavaCookieToApkAssetsCookie(jcookie);
+  ScopedUtfChars asset_path_utf8(env, asset_path);
+  if (asset_path_utf8.c_str() == nullptr) {
+    // This will throw NPE.
+    return 0;
+  }
+
+  if (access_mode != Asset::ACCESS_UNKNOWN && access_mode != Asset::ACCESS_RANDOM &&
+      access_mode != Asset::ACCESS_STREAMING && access_mode != Asset::ACCESS_BUFFER) {
+    jniThrowException(env, "java/lang/IllegalArgumentException", "Bad access mode");
+    return 0;
+  }
+
+  ScopedLock<AssetManager2> assetmanager(AssetManagerFromLong(ptr));
+  std::unique_ptr<Asset> asset;
+  if (cookie != kInvalidCookie) {
+    asset = assetmanager->OpenNonAsset(asset_path_utf8.c_str(), cookie,
+                                       static_cast<Asset::AccessMode>(access_mode));
+  } else {
+    asset = assetmanager->OpenNonAsset(asset_path_utf8.c_str(),
+                                       static_cast<Asset::AccessMode>(access_mode));
+  }
+
+  if (!asset) {
+    jniThrowException(env, "java/io/FileNotFoundException", asset_path_utf8.c_str());
+    return 0;
+  }
+  return reinterpret_cast<jlong>(asset.release());
+}
+
+static jobject NativeOpenNonAssetFd(JNIEnv* env, jclass /*clazz*/, jlong ptr, jint jcookie,
+                                    jstring asset_path, jlongArray out_offsets) {
+  ApkAssetsCookie cookie = JavaCookieToApkAssetsCookie(jcookie);
+  ScopedUtfChars asset_path_utf8(env, asset_path);
+  if (asset_path_utf8.c_str() == nullptr) {
+    // This will throw NPE.
+    return nullptr;
+  }
+
+  ScopedLock<AssetManager2> assetmanager(AssetManagerFromLong(ptr));
+  std::unique_ptr<Asset> asset;
+  if (cookie != kInvalidCookie) {
+    asset = assetmanager->OpenNonAsset(asset_path_utf8.c_str(), cookie, Asset::ACCESS_RANDOM);
+  } else {
+    asset = assetmanager->OpenNonAsset(asset_path_utf8.c_str(), Asset::ACCESS_RANDOM);
+  }
+
+  if (!asset) {
+    jniThrowException(env, "java/io/FileNotFoundException", asset_path_utf8.c_str());
+    return nullptr;
+  }
+  return ReturnParcelFileDescriptor(env, std::move(asset), out_offsets);
+}
+
+static jlong NativeOpenXmlAsset(JNIEnv* env, jobject /*clazz*/, jlong ptr, jint jcookie,
+                                jstring asset_path) {
+  ApkAssetsCookie cookie = JavaCookieToApkAssetsCookie(jcookie);
+  ScopedUtfChars asset_path_utf8(env, asset_path);
+  if (asset_path_utf8.c_str() == nullptr) {
+    // This will throw NPE.
+    return 0;
+  }
+
+  ScopedLock<AssetManager2> assetmanager(AssetManagerFromLong(ptr));
+  std::unique_ptr<Asset> asset;
+  if (cookie != kInvalidCookie) {
+    asset = assetmanager->OpenNonAsset(asset_path_utf8.c_str(), cookie, Asset::ACCESS_RANDOM);
+  } else {
+    asset = assetmanager->OpenNonAsset(asset_path_utf8.c_str(), Asset::ACCESS_RANDOM, &cookie);
+  }
+
+  if (!asset) {
+    jniThrowException(env, "java/io/FileNotFoundException", asset_path_utf8.c_str());
+    return 0;
+  }
+
+  // May be nullptr.
+  const DynamicRefTable* dynamic_ref_table = assetmanager->GetDynamicRefTableForCookie(cookie);
+
+  std::unique_ptr<ResXMLTree> xml_tree = util::make_unique<ResXMLTree>(dynamic_ref_table);
+  status_t err = xml_tree->setTo(asset->getBuffer(true), asset->getLength(), true);
+  asset.reset();
+
+  if (err != NO_ERROR) {
+    jniThrowException(env, "java/io/FileNotFoundException", "Corrupt XML binary file");
+    return 0;
+  }
+  return reinterpret_cast<jlong>(xml_tree.release());
+}
+
+static jint NativeGetResourceValue(JNIEnv* env, jclass /*clazz*/, jlong ptr, jint resid,
+                                   jshort density, jobject typed_value,
+                                   jboolean resolve_references) {
+  ScopedLock<AssetManager2> assetmanager(AssetManagerFromLong(ptr));
+  Res_value value;
+  ResTable_config selected_config;
+  uint32_t flags;
+  ApkAssetsCookie cookie =
+      assetmanager->GetResource(static_cast<uint32_t>(resid), false /*may_be_bag*/,
+                                static_cast<uint16_t>(density), &value, &selected_config, &flags);
+  if (cookie == kInvalidCookie) {
+    return ApkAssetsCookieToJavaCookie(kInvalidCookie);
+  }
+
+  uint32_t ref = static_cast<uint32_t>(resid);
+  if (resolve_references) {
+    cookie = assetmanager->ResolveReference(cookie, &value, &selected_config, &flags, &ref);
+    if (cookie == kInvalidCookie) {
+      return ApkAssetsCookieToJavaCookie(kInvalidCookie);
+    }
+  }
+  return CopyValue(env, cookie, value, ref, flags, &selected_config, typed_value);
+}
+
+static jint NativeGetResourceBagValue(JNIEnv* env, jclass /*clazz*/, jlong ptr, jint resid,
+                                      jint bag_entry_id, jobject typed_value) {
+  ScopedLock<AssetManager2> assetmanager(AssetManagerFromLong(ptr));
+  const ResolvedBag* bag = assetmanager->GetBag(static_cast<uint32_t>(resid));
+  if (bag == nullptr) {
+    return ApkAssetsCookieToJavaCookie(kInvalidCookie);
+  }
+
+  uint32_t type_spec_flags = bag->type_spec_flags;
+  ApkAssetsCookie cookie = kInvalidCookie;
+  const Res_value* bag_value = nullptr;
+  for (const ResolvedBag::Entry& entry : bag) {
+    if (entry.key == static_cast<uint32_t>(bag_entry_id)) {
+      cookie = entry.cookie;
+      bag_value = &entry.value;
+
+      // Keep searching (the old implementation did that).
+    }
+  }
+
+  if (cookie == kInvalidCookie) {
+    return ApkAssetsCookieToJavaCookie(kInvalidCookie);
+  }
+
+  Res_value value = *bag_value;
+  uint32_t ref = static_cast<uint32_t>(resid);
+  ResTable_config selected_config;
+  cookie = assetmanager->ResolveReference(cookie, &value, &selected_config, &type_spec_flags, &ref);
+  if (cookie == kInvalidCookie) {
+    return ApkAssetsCookieToJavaCookie(kInvalidCookie);
+  }
+  return CopyValue(env, cookie, value, ref, type_spec_flags, nullptr, typed_value);
+}
+
+static jintArray NativeGetStyleAttributes(JNIEnv* env, jclass /*clazz*/, jlong ptr, jint resid) {
+  ScopedLock<AssetManager2> assetmanager(AssetManagerFromLong(ptr));
+  const ResolvedBag* bag = assetmanager->GetBag(static_cast<uint32_t>(resid));
+  if (bag == nullptr) {
+    return nullptr;
+  }
+
+  jintArray array = env->NewIntArray(bag->entry_count);
+  if (env->ExceptionCheck()) {
+    return nullptr;
+  }
+
+  for (uint32_t i = 0; i < bag->entry_count; i++) {
+    jint attr_resid = bag->entries[i].key;
+    env->SetIntArrayRegion(array, i, 1, &attr_resid);
+  }
+  return array;
+}
+
+static jobjectArray NativeGetResourceStringArray(JNIEnv* env, jclass /*clazz*/, jlong ptr,
+                                                 jint resid) {
+  ScopedLock<AssetManager2> assetmanager(AssetManagerFromLong(ptr));
+  const ResolvedBag* bag = assetmanager->GetBag(static_cast<uint32_t>(resid));
+  if (bag == nullptr) {
+    return nullptr;
+  }
+
+  jobjectArray array = env->NewObjectArray(bag->entry_count, g_stringClass, nullptr);
+  if (array == nullptr) {
+    return nullptr;
+  }
+
+  for (uint32_t i = 0; i < bag->entry_count; i++) {
+    const ResolvedBag::Entry& entry = bag->entries[i];
+
+    // Resolve any references to their final value.
+    Res_value value = entry.value;
+    ResTable_config selected_config;
+    uint32_t flags;
+    uint32_t ref;
+    ApkAssetsCookie cookie =
+        assetmanager->ResolveReference(entry.cookie, &value, &selected_config, &flags, &ref);
+    if (cookie == kInvalidCookie) {
+      return nullptr;
+    }
+
+    if (value.dataType == Res_value::TYPE_STRING) {
+      const ApkAssets* apk_assets = assetmanager->GetApkAssets()[cookie];
+      const ResStringPool* pool = apk_assets->GetLoadedArsc()->GetStringPool();
+
+      jstring java_string = nullptr;
+      size_t str_len;
+      const char* str_utf8 = pool->string8At(value.data, &str_len);
+      if (str_utf8 != nullptr) {
+        java_string = env->NewStringUTF(str_utf8);
+      } else {
+        const char16_t* str_utf16 = pool->stringAt(value.data, &str_len);
+        java_string = env->NewString(reinterpret_cast<const jchar*>(str_utf16), str_len);
+      }
+
+      // Check for errors creating the strings (if malformed or no memory).
+      if (env->ExceptionCheck()) {
+        return nullptr;
+      }
+
+      env->SetObjectArrayElement(array, i, java_string);
+
+      // If we have a large amount of string in our array, we might overflow the
+      // local reference table of the VM.
+      env->DeleteLocalRef(java_string);
+    }
+  }
+  return array;
+}
+
+static jintArray NativeGetResourceStringArrayInfo(JNIEnv* env, jclass /*clazz*/, jlong ptr,
+                                                  jint resid) {
+  ScopedLock<AssetManager2> assetmanager(AssetManagerFromLong(ptr));
+  const ResolvedBag* bag = assetmanager->GetBag(static_cast<uint32_t>(resid));
+  if (bag == nullptr) {
+    return nullptr;
+  }
+
+  jintArray array = env->NewIntArray(bag->entry_count * 2);
+  if (array == nullptr) {
+    return nullptr;
+  }
+
+  jint* buffer = reinterpret_cast<jint*>(env->GetPrimitiveArrayCritical(array, nullptr));
+  if (buffer == nullptr) {
+    return nullptr;
+  }
+
+  for (size_t i = 0; i < bag->entry_count; i++) {
+    const ResolvedBag::Entry& entry = bag->entries[i];
+    Res_value value = entry.value;
+    ResTable_config selected_config;
+    uint32_t flags;
+    uint32_t ref;
+    ApkAssetsCookie cookie =
+        assetmanager->ResolveReference(entry.cookie, &value, &selected_config, &flags, &ref);
+    if (cookie == kInvalidCookie) {
+      env->ReleasePrimitiveArrayCritical(array, buffer, JNI_ABORT);
+      return nullptr;
+    }
+
+    jint string_index = -1;
+    if (value.dataType == Res_value::TYPE_STRING) {
+      string_index = static_cast<jint>(value.data);
+    }
+
+    buffer[i * 2] = ApkAssetsCookieToJavaCookie(cookie);
+    buffer[(i * 2) + 1] = string_index;
+  }
+  env->ReleasePrimitiveArrayCritical(array, buffer, 0);
+  return array;
+}
+
+static jintArray NativeGetResourceIntArray(JNIEnv* env, jclass /*clazz*/, jlong ptr, jint resid) {
+  ScopedLock<AssetManager2> assetmanager(AssetManagerFromLong(ptr));
+  const ResolvedBag* bag = assetmanager->GetBag(static_cast<uint32_t>(resid));
+  if (bag == nullptr) {
+    return nullptr;
+  }
+
+  jintArray array = env->NewIntArray(bag->entry_count);
+  if (array == nullptr) {
+    return nullptr;
+  }
+
+  jint* buffer = reinterpret_cast<jint*>(env->GetPrimitiveArrayCritical(array, nullptr));
+  if (buffer == nullptr) {
+    return nullptr;
+  }
+
+  for (size_t i = 0; i < bag->entry_count; i++) {
+    const ResolvedBag::Entry& entry = bag->entries[i];
+    Res_value value = entry.value;
+    ResTable_config selected_config;
+    uint32_t flags;
+    uint32_t ref;
+    ApkAssetsCookie cookie =
+        assetmanager->ResolveReference(entry.cookie, &value, &selected_config, &flags, &ref);
+    if (cookie == kInvalidCookie) {
+      env->ReleasePrimitiveArrayCritical(array, buffer, JNI_ABORT);
+      return nullptr;
+    }
+
+    if (value.dataType >= Res_value::TYPE_FIRST_INT && value.dataType <= Res_value::TYPE_LAST_INT) {
+      buffer[i] = static_cast<jint>(value.data);
+    }
+  }
+  env->ReleasePrimitiveArrayCritical(array, buffer, 0);
+  return array;
+}
+
+static jint NativeGetResourceArraySize(JNIEnv* /*env*/, jclass /*clazz*/, jlong ptr, jint resid) {
+  ScopedLock<AssetManager2> assetmanager(AssetManagerFromLong(ptr));
+  const ResolvedBag* bag = assetmanager->GetBag(static_cast<uint32_t>(resid));
+  if (bag == nullptr) {
+    return -1;
+  }
+  return static_cast<jint>(bag->entry_count);
+}
+
+static jint NativeGetResourceArray(JNIEnv* env, jclass /*clazz*/, jlong ptr, jint resid,
+                                   jintArray out_data) {
+  ScopedLock<AssetManager2> assetmanager(AssetManagerFromLong(ptr));
+  const ResolvedBag* bag = assetmanager->GetBag(static_cast<uint32_t>(resid));
+  if (bag == nullptr) {
+    return -1;
+  }
+
+  const jsize out_data_length = env->GetArrayLength(out_data);
+  if (env->ExceptionCheck()) {
+    return -1;
+  }
+
+  if (static_cast<jsize>(bag->entry_count) > out_data_length * STYLE_NUM_ENTRIES) {
+    jniThrowException(env, "java/lang/IllegalArgumentException", "Input array is not large enough");
+    return -1;
+  }
+
+  jint* buffer = reinterpret_cast<jint*>(env->GetPrimitiveArrayCritical(out_data, nullptr));
+  if (buffer == nullptr) {
+    return -1;
+  }
+
+  jint* cursor = buffer;
+  for (size_t i = 0; i < bag->entry_count; i++) {
+    const ResolvedBag::Entry& entry = bag->entries[i];
+    Res_value value = entry.value;
+    ResTable_config selected_config;
+    selected_config.density = 0;
+    uint32_t flags = bag->type_spec_flags;
+    uint32_t ref;
+    ApkAssetsCookie cookie =
+        assetmanager->ResolveReference(entry.cookie, &value, &selected_config, &flags, &ref);
+    if (cookie == kInvalidCookie) {
+      env->ReleasePrimitiveArrayCritical(out_data, buffer, JNI_ABORT);
+      return -1;
+    }
+
+    // Deal with the special @null value -- it turns back to TYPE_NULL.
+    if (value.dataType == Res_value::TYPE_REFERENCE && value.data == 0) {
+      value.dataType = Res_value::TYPE_NULL;
+      value.data = Res_value::DATA_NULL_UNDEFINED;
+    }
+
+    cursor[STYLE_TYPE] = static_cast<jint>(value.dataType);
+    cursor[STYLE_DATA] = static_cast<jint>(value.data);
+    cursor[STYLE_ASSET_COOKIE] = ApkAssetsCookieToJavaCookie(cookie);
+    cursor[STYLE_RESOURCE_ID] = static_cast<jint>(ref);
+    cursor[STYLE_CHANGING_CONFIGURATIONS] = static_cast<jint>(flags);
+    cursor[STYLE_DENSITY] = static_cast<jint>(selected_config.density);
+    cursor += STYLE_NUM_ENTRIES;
+  }
+  env->ReleasePrimitiveArrayCritical(out_data, buffer, 0);
+  return static_cast<jint>(bag->entry_count);
+}
+
+static jint NativeGetResourceIdentifier(JNIEnv* env, jclass /*clazz*/, jlong ptr, jstring name,
+                                        jstring def_type, jstring def_package) {
+  ScopedUtfChars name_utf8(env, name);
+  if (name_utf8.c_str() == nullptr) {
+    // This will throw NPE.
+    return 0;
+  }
+
+  std::string type;
+  if (def_type != nullptr) {
+    ScopedUtfChars type_utf8(env, def_type);
+    CHECK(type_utf8.c_str() != nullptr);
+    type = type_utf8.c_str();
+  }
+
+  std::string package;
+  if (def_package != nullptr) {
+    ScopedUtfChars package_utf8(env, def_package);
+    CHECK(package_utf8.c_str() != nullptr);
+    package = package_utf8.c_str();
+  }
+  ScopedLock<AssetManager2> assetmanager(AssetManagerFromLong(ptr));
+  return static_cast<jint>(assetmanager->GetResourceId(name_utf8.c_str(), type, package));
+}
+
+static jstring NativeGetResourceName(JNIEnv* env, jclass /*clazz*/, jlong ptr, jint resid) {
+  ScopedLock<AssetManager2> assetmanager(AssetManagerFromLong(ptr));
+  AssetManager2::ResourceName name;
+  if (!assetmanager->GetResourceName(static_cast<uint32_t>(resid), &name)) {
+    return nullptr;
+  }
+
+  std::string result;
+  if (name.package != nullptr) {
+    result.append(name.package, name.package_len);
+  }
+
+  if (name.type != nullptr || name.type16 != nullptr) {
+    if (!result.empty()) {
+      result += ":";
+    }
+
+    if (name.type != nullptr) {
+      result.append(name.type, name.type_len);
+    } else {
+      result += util::Utf16ToUtf8(StringPiece16(name.type16, name.type_len));
+    }
+  }
+
+  if (name.entry != nullptr || name.entry16 != nullptr) {
+    if (!result.empty()) {
+      result += "/";
+    }
+
+    if (name.entry != nullptr) {
+      result.append(name.entry, name.entry_len);
+    } else {
+      result += util::Utf16ToUtf8(StringPiece16(name.entry16, name.entry_len));
+    }
+  }
+  return env->NewStringUTF(result.c_str());
+}
+
+static jstring NativeGetResourcePackageName(JNIEnv* env, jclass /*clazz*/, jlong ptr, jint resid) {
+  ScopedLock<AssetManager2> assetmanager(AssetManagerFromLong(ptr));
+  AssetManager2::ResourceName name;
+  if (!assetmanager->GetResourceName(static_cast<uint32_t>(resid), &name)) {
+    return nullptr;
+  }
+
+  if (name.package != nullptr) {
+    return env->NewStringUTF(name.package);
+  }
+  return nullptr;
+}
+
+static jstring NativeGetResourceTypeName(JNIEnv* env, jclass /*clazz*/, jlong ptr, jint resid) {
+  ScopedLock<AssetManager2> assetmanager(AssetManagerFromLong(ptr));
+  AssetManager2::ResourceName name;
+  if (!assetmanager->GetResourceName(static_cast<uint32_t>(resid), &name)) {
+    return nullptr;
+  }
+
+  if (name.type != nullptr) {
+    return env->NewStringUTF(name.type);
+  } else if (name.type16 != nullptr) {
+    return env->NewString(reinterpret_cast<const jchar*>(name.type16), name.type_len);
+  }
+  return nullptr;
+}
+
+static jstring NativeGetResourceEntryName(JNIEnv* env, jclass /*clazz*/, jlong ptr, jint resid) {
+  ScopedLock<AssetManager2> assetmanager(AssetManagerFromLong(ptr));
+  AssetManager2::ResourceName name;
+  if (!assetmanager->GetResourceName(static_cast<uint32_t>(resid), &name)) {
+    return nullptr;
+  }
+
+  if (name.entry != nullptr) {
+    return env->NewStringUTF(name.entry);
+  } else if (name.entry16 != nullptr) {
+    return env->NewString(reinterpret_cast<const jchar*>(name.entry16), name.entry_len);
+  }
+  return nullptr;
+}
+
+static jobjectArray NativeGetLocales(JNIEnv* env, jclass /*class*/, jlong ptr,
+                                     jboolean exclude_system) {
+  ScopedLock<AssetManager2> assetmanager(AssetManagerFromLong(ptr));
+  std::set<std::string> locales =
+      assetmanager->GetResourceLocales(exclude_system, true /*merge_equivalent_languages*/);
+
+  jobjectArray array = env->NewObjectArray(locales.size(), g_stringClass, nullptr);
+  if (array == nullptr) {
+    return nullptr;
+  }
+
+  size_t idx = 0;
+  for (const std::string& locale : locales) {
+    jstring java_string = env->NewStringUTF(locale.c_str());
+    if (java_string == nullptr) {
+      return nullptr;
+    }
+    env->SetObjectArrayElement(array, idx++, java_string);
+    env->DeleteLocalRef(java_string);
+  }
+  return array;
+}
+
+static jobject ConstructConfigurationObject(JNIEnv* env, const ResTable_config& config) {
+  jobject result =
+      env->NewObject(gConfigurationOffsets.classObject, gConfigurationOffsets.constructor);
+  if (result == nullptr) {
+    return nullptr;
+  }
+
+  env->SetIntField(result, gConfigurationOffsets.mSmallestScreenWidthDpOffset,
+                   config.smallestScreenWidthDp);
+  env->SetIntField(result, gConfigurationOffsets.mScreenWidthDpOffset, config.screenWidthDp);
+  env->SetIntField(result, gConfigurationOffsets.mScreenHeightDpOffset, config.screenHeightDp);
+  return result;
+}
+
+static jobjectArray NativeGetSizeConfigurations(JNIEnv* env, jclass /*clazz*/, jlong ptr) {
+  ScopedLock<AssetManager2> assetmanager(AssetManagerFromLong(ptr));
+  std::set<ResTable_config> configurations =
+      assetmanager->GetResourceConfigurations(true /*exclude_system*/, false /*exclude_mipmap*/);
+
+  jobjectArray array =
+      env->NewObjectArray(configurations.size(), gConfigurationOffsets.classObject, nullptr);
+  if (array == nullptr) {
+    return nullptr;
+  }
+
+  size_t idx = 0;
+  for (const ResTable_config& configuration : configurations) {
+    jobject java_configuration = ConstructConfigurationObject(env, configuration);
+    if (java_configuration == nullptr) {
+      return nullptr;
+    }
+
+    env->SetObjectArrayElement(array, idx++, java_configuration);
+    env->DeleteLocalRef(java_configuration);
+  }
+  return array;
+}
+
+static void NativeApplyStyle(JNIEnv* env, jclass /*clazz*/, jlong ptr, jlong theme_ptr,
+                             jint def_style_attr, jint def_style_resid, jlong xml_parser_ptr,
+                             jintArray java_attrs, jlong out_values_ptr, jlong out_indices_ptr) {
+  ScopedLock<AssetManager2> assetmanager(AssetManagerFromLong(ptr));
+  Theme* theme = reinterpret_cast<Theme*>(theme_ptr);
+  CHECK(theme->GetAssetManager() == &(*assetmanager));
+  (void) assetmanager;
+
+  ResXMLParser* xml_parser = reinterpret_cast<ResXMLParser*>(xml_parser_ptr);
+  uint32_t* out_values = reinterpret_cast<uint32_t*>(out_values_ptr);
+  uint32_t* out_indices = reinterpret_cast<uint32_t*>(out_indices_ptr);
+
+  jsize attrs_len = env->GetArrayLength(java_attrs);
+  jint* attrs = reinterpret_cast<jint*>(env->GetPrimitiveArrayCritical(java_attrs, nullptr));
+  if (attrs == nullptr) {
+    return;
+  }
+
+  ApplyStyle(theme, xml_parser, static_cast<uint32_t>(def_style_attr),
+             static_cast<uint32_t>(def_style_resid), reinterpret_cast<uint32_t*>(attrs), attrs_len,
+             out_values, out_indices);
+  env->ReleasePrimitiveArrayCritical(java_attrs, attrs, JNI_ABORT);
+}
+
+static jboolean NativeResolveAttrs(JNIEnv* env, jclass /*clazz*/, jlong ptr, jlong theme_ptr,
+                                   jint def_style_attr, jint def_style_resid, jintArray java_values,
+                                   jintArray java_attrs, jintArray out_java_values,
+                                   jintArray out_java_indices) {
+  const jsize attrs_len = env->GetArrayLength(java_attrs);
+  const jsize out_values_len = env->GetArrayLength(out_java_values);
+  if (out_values_len < (attrs_len * STYLE_NUM_ENTRIES)) {
+    jniThrowException(env, "java/lang/IndexOutOfBoundsException", "outValues too small");
+    return JNI_FALSE;
+  }
+
+  jint* attrs = reinterpret_cast<jint*>(env->GetPrimitiveArrayCritical(java_attrs, nullptr));
+  if (attrs == nullptr) {
+    return JNI_FALSE;
+  }
+
+  jint* values = nullptr;
+  jsize values_len = 0;
+  if (java_values != nullptr) {
+    values_len = env->GetArrayLength(java_values);
+    values = reinterpret_cast<jint*>(env->GetPrimitiveArrayCritical(java_values, nullptr));
+    if (values == nullptr) {
+      env->ReleasePrimitiveArrayCritical(java_attrs, attrs, JNI_ABORT);
+      return JNI_FALSE;
+    }
+  }
+
+  jint* out_values =
+      reinterpret_cast<jint*>(env->GetPrimitiveArrayCritical(out_java_values, nullptr));
+  if (out_values == nullptr) {
+    env->ReleasePrimitiveArrayCritical(java_attrs, attrs, JNI_ABORT);
+    if (values != nullptr) {
+      env->ReleasePrimitiveArrayCritical(java_values, values, JNI_ABORT);
+    }
+    return JNI_FALSE;
+  }
+
+  jint* out_indices = nullptr;
+  if (out_java_indices != nullptr) {
+    jsize out_indices_len = env->GetArrayLength(out_java_indices);
+    if (out_indices_len > attrs_len) {
+      out_indices =
+          reinterpret_cast<jint*>(env->GetPrimitiveArrayCritical(out_java_indices, nullptr));
+      if (out_indices == nullptr) {
+        env->ReleasePrimitiveArrayCritical(java_attrs, attrs, JNI_ABORT);
+        if (values != nullptr) {
+          env->ReleasePrimitiveArrayCritical(java_values, values, JNI_ABORT);
+        }
+        env->ReleasePrimitiveArrayCritical(out_java_values, out_values, JNI_ABORT);
+        return JNI_FALSE;
+      }
+    }
+  }
+
+  ScopedLock<AssetManager2> assetmanager(AssetManagerFromLong(ptr));
+  Theme* theme = reinterpret_cast<Theme*>(theme_ptr);
+  CHECK(theme->GetAssetManager() == &(*assetmanager));
+  (void) assetmanager;
+
+  bool result = ResolveAttrs(
+      theme, static_cast<uint32_t>(def_style_attr), static_cast<uint32_t>(def_style_resid),
+      reinterpret_cast<uint32_t*>(values), values_len, reinterpret_cast<uint32_t*>(attrs),
+      attrs_len, reinterpret_cast<uint32_t*>(out_values), reinterpret_cast<uint32_t*>(out_indices));
+  if (out_indices != nullptr) {
+    env->ReleasePrimitiveArrayCritical(out_java_indices, out_indices, 0);
+  }
+
+  env->ReleasePrimitiveArrayCritical(out_java_values, out_values, 0);
+  if (values != nullptr) {
+    env->ReleasePrimitiveArrayCritical(java_values, values, JNI_ABORT);
+  }
+  env->ReleasePrimitiveArrayCritical(java_attrs, attrs, JNI_ABORT);
+  return result ? JNI_TRUE : JNI_FALSE;
+}
+
+static jboolean NativeRetrieveAttributes(JNIEnv* env, jclass /*clazz*/, jlong ptr,
+                                         jlong xml_parser_ptr, jintArray java_attrs,
+                                         jintArray out_java_values, jintArray out_java_indices) {
+  const jsize attrs_len = env->GetArrayLength(java_attrs);
+  const jsize out_values_len = env->GetArrayLength(out_java_values);
+  if (out_values_len < (attrs_len * STYLE_NUM_ENTRIES)) {
+    jniThrowException(env, "java/lang/IndexOutOfBoundsException", "outValues too small");
+    return JNI_FALSE;
+  }
+
+  jint* attrs = reinterpret_cast<jint*>(env->GetPrimitiveArrayCritical(java_attrs, nullptr));
+  if (attrs == nullptr) {
+    return JNI_FALSE;
+  }
+
+  jint* out_values =
+      reinterpret_cast<jint*>(env->GetPrimitiveArrayCritical(out_java_values, nullptr));
+  if (out_values == nullptr) {
+    env->ReleasePrimitiveArrayCritical(java_attrs, attrs, JNI_ABORT);
+    return JNI_FALSE;
+  }
+
+  jint* out_indices = nullptr;
+  if (out_java_indices != nullptr) {
+    jsize out_indices_len = env->GetArrayLength(out_java_indices);
+    if (out_indices_len > attrs_len) {
+      out_indices =
+          reinterpret_cast<jint*>(env->GetPrimitiveArrayCritical(out_java_indices, nullptr));
+      if (out_indices == nullptr) {
+        env->ReleasePrimitiveArrayCritical(java_attrs, attrs, JNI_ABORT);
+        env->ReleasePrimitiveArrayCritical(out_java_values, out_values, JNI_ABORT);
+        return JNI_FALSE;
+      }
+    }
+  }
+
+  ScopedLock<AssetManager2> assetmanager(AssetManagerFromLong(ptr));
+  ResXMLParser* xml_parser = reinterpret_cast<ResXMLParser*>(xml_parser_ptr);
+
+  bool result = RetrieveAttributes(assetmanager.get(), xml_parser,
+                                   reinterpret_cast<uint32_t*>(attrs), attrs_len,
+                                   reinterpret_cast<uint32_t*>(out_values),
+                                   reinterpret_cast<uint32_t*>(out_indices));
+
+  if (out_indices != nullptr) {
+    env->ReleasePrimitiveArrayCritical(out_java_indices, out_indices, 0);
+  }
+  env->ReleasePrimitiveArrayCritical(out_java_values, out_values, 0);
+  env->ReleasePrimitiveArrayCritical(java_attrs, attrs, JNI_ABORT);
+  return result ? JNI_TRUE : JNI_FALSE;
+}
+
+static jlong NativeThemeCreate(JNIEnv* /*env*/, jclass /*clazz*/, jlong ptr) {
+  ScopedLock<AssetManager2> assetmanager(AssetManagerFromLong(ptr));
+  return reinterpret_cast<jlong>(assetmanager->NewTheme().release());
+}
+
+static void NativeThemeDestroy(JNIEnv* /*env*/, jclass /*clazz*/, jlong theme_ptr) {
+  delete reinterpret_cast<Theme*>(theme_ptr);
+}
+
+static void NativeThemeApplyStyle(JNIEnv* env, jclass /*clazz*/, jlong ptr, jlong theme_ptr,
+                                  jint resid, jboolean force) {
+  // AssetManager is accessed via the theme, so grab an explicit lock here.
+  ScopedLock<AssetManager2> assetmanager(AssetManagerFromLong(ptr));
+  Theme* theme = reinterpret_cast<Theme*>(theme_ptr);
+  CHECK(theme->GetAssetManager() == &(*assetmanager));
+  (void) assetmanager;
+  theme->ApplyStyle(static_cast<uint32_t>(resid), force);
+
+  // TODO(adamlesinski): Consider surfacing exception when result is failure.
+  // CTS currently expects no exceptions from this method.
+  // std::string error_msg = StringPrintf("Failed to apply style 0x%08x to theme", resid);
+  // jniThrowException(env, "java/lang/IllegalArgumentException", error_msg.c_str());
+}
+
+static void NativeThemeCopy(JNIEnv* env, jclass /*clazz*/, jlong dst_theme_ptr,
+                            jlong src_theme_ptr) {
+  Theme* dst_theme = reinterpret_cast<Theme*>(dst_theme_ptr);
+  Theme* src_theme = reinterpret_cast<Theme*>(src_theme_ptr);
+  if (!dst_theme->SetTo(*src_theme)) {
+    jniThrowException(env, "java/lang/IllegalArgumentException",
+                      "Themes are from different AssetManagers");
+  }
+}
+
+static void NativeThemeClear(JNIEnv* /*env*/, jclass /*clazz*/, jlong theme_ptr) {
+  reinterpret_cast<Theme*>(theme_ptr)->Clear();
+}
+
+static jint NativeThemeGetAttributeValue(JNIEnv* env, jclass /*clazz*/, jlong ptr, jlong theme_ptr,
+                                         jint resid, jobject typed_value,
+                                         jboolean resolve_references) {
+  ScopedLock<AssetManager2> assetmanager(AssetManagerFromLong(ptr));
+  Theme* theme = reinterpret_cast<Theme*>(theme_ptr);
+  CHECK(theme->GetAssetManager() == &(*assetmanager));
+  (void) assetmanager;
+
+  Res_value value;
+  uint32_t flags;
+  ApkAssetsCookie cookie = theme->GetAttribute(static_cast<uint32_t>(resid), &value, &flags);
+  if (cookie == kInvalidCookie) {
+    return ApkAssetsCookieToJavaCookie(kInvalidCookie);
+  }
+
+  uint32_t ref = 0u;
+  if (resolve_references) {
+    ResTable_config selected_config;
+    cookie =
+        theme->GetAssetManager()->ResolveReference(cookie, &value, &selected_config, &flags, &ref);
+    if (cookie == kInvalidCookie) {
+      return ApkAssetsCookieToJavaCookie(kInvalidCookie);
+    }
+  }
+  return CopyValue(env, cookie, value, ref, flags, nullptr, typed_value);
+}
+
+static void NativeThemeDump(JNIEnv* /*env*/, jclass /*clazz*/, jlong ptr, jlong theme_ptr,
+                            jint priority, jstring tag, jstring prefix) {
+  ScopedLock<AssetManager2> assetmanager(AssetManagerFromLong(ptr));
+  Theme* theme = reinterpret_cast<Theme*>(theme_ptr);
+  CHECK(theme->GetAssetManager() == &(*assetmanager));
+  (void) assetmanager;
+  (void) theme;
+  (void) priority;
+  (void) tag;
+  (void) prefix;
+}
+
+static jint NativeThemeGetChangingConfigurations(JNIEnv* /*env*/, jclass /*clazz*/,
+                                                 jlong theme_ptr) {
+  Theme* theme = reinterpret_cast<Theme*>(theme_ptr);
+  return static_cast<jint>(theme->GetChangingConfigurations());
+}
+
+static void NativeAssetDestroy(JNIEnv* /*env*/, jclass /*clazz*/, jlong asset_ptr) {
+  delete reinterpret_cast<Asset*>(asset_ptr);
+}
+
+static jint NativeAssetReadChar(JNIEnv* /*env*/, jclass /*clazz*/, jlong asset_ptr) {
+  Asset* asset = reinterpret_cast<Asset*>(asset_ptr);
+  uint8_t b;
+  ssize_t res = asset->read(&b, sizeof(b));
+  return res == sizeof(b) ? static_cast<jint>(b) : -1;
+}
+
+static jint NativeAssetRead(JNIEnv* env, jclass /*clazz*/, jlong asset_ptr, jbyteArray java_buffer,
+                            jint offset, jint len) {
+  if (len == 0) {
+    return 0;
+  }
+
+  jsize buffer_len = env->GetArrayLength(java_buffer);
+  if (offset < 0 || offset >= buffer_len || len < 0 || len > buffer_len ||
+      offset > buffer_len - len) {
+    jniThrowException(env, "java/lang/IndexOutOfBoundsException", "");
+    return -1;
+  }
+
+  ScopedByteArrayRW byte_array(env, java_buffer);
+  if (byte_array.get() == nullptr) {
+    return -1;
+  }
+
+  Asset* asset = reinterpret_cast<Asset*>(asset_ptr);
+  ssize_t res = asset->read(byte_array.get() + offset, len);
+  if (res < 0) {
+    jniThrowException(env, "java/io/IOException", "");
+    return -1;
+  }
+  return res > 0 ? static_cast<jint>(res) : -1;
+}
+
+static jlong NativeAssetSeek(JNIEnv* env, jclass /*clazz*/, jlong asset_ptr, jlong offset,
+                             jint whence) {
+  Asset* asset = reinterpret_cast<Asset*>(asset_ptr);
+  return static_cast<jlong>(asset->seek(
+      static_cast<off64_t>(offset), (whence > 0 ? SEEK_END : (whence < 0 ? SEEK_SET : SEEK_CUR))));
+}
+
+static jlong NativeAssetGetLength(JNIEnv* /*env*/, jclass /*clazz*/, jlong asset_ptr) {
+  Asset* asset = reinterpret_cast<Asset*>(asset_ptr);
+  return static_cast<jlong>(asset->getLength());
+}
+
+static jlong NativeAssetGetRemainingLength(JNIEnv* /*env*/, jclass /*clazz*/, jlong asset_ptr) {
+  Asset* asset = reinterpret_cast<Asset*>(asset_ptr);
+  return static_cast<jlong>(asset->getRemainingLength());
+}
+
+// ----------------------------------------------------------------------------
+
+// JNI registration.
+static const JNINativeMethod gAssetManagerMethods[] = {
+    // AssetManager setup methods.
+    {"nativeCreate", "()J", (void*)NativeCreate},
+    {"nativeDestroy", "(J)V", (void*)NativeDestroy},
+    {"nativeSetApkAssets", "(J[Landroid/content/res/ApkAssets;Z)V", (void*)NativeSetApkAssets},
+    {"nativeSetConfiguration", "(JIILjava/lang/String;IIIIIIIIIIIIIII)V",
+     (void*)NativeSetConfiguration},
+    {"nativeGetAssignedPackageIdentifiers", "(J)Landroid/util/SparseArray;",
+     (void*)NativeGetAssignedPackageIdentifiers},
+
+    // AssetManager file methods.
+    {"nativeList", "(JLjava/lang/String;)[Ljava/lang/String;", (void*)NativeList},
+    {"nativeOpenAsset", "(JLjava/lang/String;I)J", (void*)NativeOpenAsset},
+    {"nativeOpenAssetFd", "(JLjava/lang/String;[J)Landroid/os/ParcelFileDescriptor;",
+     (void*)NativeOpenAssetFd},
+    {"nativeOpenNonAsset", "(JILjava/lang/String;I)J", (void*)NativeOpenNonAsset},
+    {"nativeOpenNonAssetFd", "(JILjava/lang/String;[J)Landroid/os/ParcelFileDescriptor;",
+     (void*)NativeOpenNonAssetFd},
+    {"nativeOpenXmlAsset", "(JILjava/lang/String;)J", (void*)NativeOpenXmlAsset},
+
+    // AssetManager resource methods.
+    {"nativeGetResourceValue", "(JISLandroid/util/TypedValue;Z)I", (void*)NativeGetResourceValue},
+    {"nativeGetResourceBagValue", "(JIILandroid/util/TypedValue;)I",
+     (void*)NativeGetResourceBagValue},
+    {"nativeGetStyleAttributes", "(JI)[I", (void*)NativeGetStyleAttributes},
+    {"nativeGetResourceStringArray", "(JI)[Ljava/lang/String;",
+     (void*)NativeGetResourceStringArray},
+    {"nativeGetResourceStringArrayInfo", "(JI)[I", (void*)NativeGetResourceStringArrayInfo},
+    {"nativeGetResourceIntArray", "(JI)[I", (void*)NativeGetResourceIntArray},
+    {"nativeGetResourceArraySize", "(JI)I", (void*)NativeGetResourceArraySize},
+    {"nativeGetResourceArray", "(JI[I)I", (void*)NativeGetResourceArray},
+
+    // AssetManager resource name/ID methods.
+    {"nativeGetResourceIdentifier", "(JLjava/lang/String;Ljava/lang/String;Ljava/lang/String;)I",
+     (void*)NativeGetResourceIdentifier},
+    {"nativeGetResourceName", "(JI)Ljava/lang/String;", (void*)NativeGetResourceName},
+    {"nativeGetResourcePackageName", "(JI)Ljava/lang/String;", (void*)NativeGetResourcePackageName},
+    {"nativeGetResourceTypeName", "(JI)Ljava/lang/String;", (void*)NativeGetResourceTypeName},
+    {"nativeGetResourceEntryName", "(JI)Ljava/lang/String;", (void*)NativeGetResourceEntryName},
+    {"nativeGetLocales", "(JZ)[Ljava/lang/String;", (void*)NativeGetLocales},
+    {"nativeGetSizeConfigurations", "(J)[Landroid/content/res/Configuration;",
+     (void*)NativeGetSizeConfigurations},
+
+    // Style attribute related methods.
+    {"nativeApplyStyle", "(JJIIJ[IJJ)V", (void*)NativeApplyStyle},
+    {"nativeResolveAttrs", "(JJII[I[I[I[I)Z", (void*)NativeResolveAttrs},
+    {"nativeRetrieveAttributes", "(JJ[I[I[I)Z", (void*)NativeRetrieveAttributes},
+
+    // Theme related methods.
+    {"nativeThemeCreate", "(J)J", (void*)NativeThemeCreate},
+    {"nativeThemeDestroy", "(J)V", (void*)NativeThemeDestroy},
+    {"nativeThemeApplyStyle", "(JJIZ)V", (void*)NativeThemeApplyStyle},
+    {"nativeThemeCopy", "(JJ)V", (void*)NativeThemeCopy},
+    {"nativeThemeClear", "(J)V", (void*)NativeThemeClear},
+    {"nativeThemeGetAttributeValue", "(JJILandroid/util/TypedValue;Z)I",
+     (void*)NativeThemeGetAttributeValue},
+    {"nativeThemeDump", "(JJILjava/lang/String;Ljava/lang/String;)V", (void*)NativeThemeDump},
+    {"nativeThemeGetChangingConfigurations", "(J)I", (void*)NativeThemeGetChangingConfigurations},
+
+    // AssetInputStream methods.
+    {"nativeAssetDestroy", "(J)V", (void*)NativeAssetDestroy},
+    {"nativeAssetReadChar", "(J)I", (void*)NativeAssetReadChar},
+    {"nativeAssetRead", "(J[BII)I", (void*)NativeAssetRead},
+    {"nativeAssetSeek", "(JJI)J", (void*)NativeAssetSeek},
+    {"nativeAssetGetLength", "(J)J", (void*)NativeAssetGetLength},
+    {"nativeAssetGetRemainingLength", "(J)J", (void*)NativeAssetGetRemainingLength},
+
+    // System/idmap related methods.
+    {"nativeVerifySystemIdmaps", "()V", (void*)NativeVerifySystemIdmaps},
+
+    // Global management/debug methods.
+    {"getGlobalAssetCount", "()I", (void*)NativeGetGlobalAssetCount},
+    {"getAssetAllocations", "()Ljava/lang/String;", (void*)NativeGetAssetAllocations},
+    {"getGlobalAssetManagerCount", "()I", (void*)NativeGetGlobalAssetManagerCount},
+};
+
+int register_android_content_AssetManager(JNIEnv* env) {
+  jclass apk_assets_class = FindClassOrDie(env, "android/content/res/ApkAssets");
+  gApkAssetsFields.native_ptr = GetFieldIDOrDie(env, apk_assets_class, "mNativePtr", "J");
+
+  jclass typedValue = FindClassOrDie(env, "android/util/TypedValue");
+  gTypedValueOffsets.mType = GetFieldIDOrDie(env, typedValue, "type", "I");
+  gTypedValueOffsets.mData = GetFieldIDOrDie(env, typedValue, "data", "I");
+  gTypedValueOffsets.mString =
+      GetFieldIDOrDie(env, typedValue, "string", "Ljava/lang/CharSequence;");
+  gTypedValueOffsets.mAssetCookie = GetFieldIDOrDie(env, typedValue, "assetCookie", "I");
+  gTypedValueOffsets.mResourceId = GetFieldIDOrDie(env, typedValue, "resourceId", "I");
+  gTypedValueOffsets.mChangingConfigurations =
+      GetFieldIDOrDie(env, typedValue, "changingConfigurations", "I");
+  gTypedValueOffsets.mDensity = GetFieldIDOrDie(env, typedValue, "density", "I");
+
+  jclass assetFd = FindClassOrDie(env, "android/content/res/AssetFileDescriptor");
+  gAssetFileDescriptorOffsets.mFd =
+      GetFieldIDOrDie(env, assetFd, "mFd", "Landroid/os/ParcelFileDescriptor;");
+  gAssetFileDescriptorOffsets.mStartOffset = GetFieldIDOrDie(env, assetFd, "mStartOffset", "J");
+  gAssetFileDescriptorOffsets.mLength = GetFieldIDOrDie(env, assetFd, "mLength", "J");
+
+  jclass assetManager = FindClassOrDie(env, "android/content/res/AssetManager");
+  gAssetManagerOffsets.mObject = GetFieldIDOrDie(env, assetManager, "mObject", "J");
+
+  jclass stringClass = FindClassOrDie(env, "java/lang/String");
+  g_stringClass = MakeGlobalRefOrDie(env, stringClass);
+
+  jclass sparseArrayClass = FindClassOrDie(env, "android/util/SparseArray");
+  gSparseArrayOffsets.classObject = MakeGlobalRefOrDie(env, sparseArrayClass);
+  gSparseArrayOffsets.constructor =
+      GetMethodIDOrDie(env, gSparseArrayOffsets.classObject, "<init>", "()V");
+  gSparseArrayOffsets.put =
+      GetMethodIDOrDie(env, gSparseArrayOffsets.classObject, "put", "(ILjava/lang/Object;)V");
+
+  jclass configurationClass = FindClassOrDie(env, "android/content/res/Configuration");
+  gConfigurationOffsets.classObject = MakeGlobalRefOrDie(env, configurationClass);
+  gConfigurationOffsets.constructor = GetMethodIDOrDie(env, configurationClass, "<init>", "()V");
+  gConfigurationOffsets.mSmallestScreenWidthDpOffset =
+      GetFieldIDOrDie(env, configurationClass, "smallestScreenWidthDp", "I");
+  gConfigurationOffsets.mScreenWidthDpOffset =
+      GetFieldIDOrDie(env, configurationClass, "screenWidthDp", "I");
+  gConfigurationOffsets.mScreenHeightDpOffset =
+      GetFieldIDOrDie(env, configurationClass, "screenHeightDp", "I");
+
+  return RegisterMethodsOrDie(env, "android/content/res/AssetManager", gAssetManagerMethods,
+                              NELEM(gAssetManagerMethods));
 }
 
 }; // namespace android
diff --git a/core/jni/include/android_runtime/android_util_AssetManager.h b/core/jni/include/android_runtime/android_util_AssetManager.h
index 8dd9337..2c1e357 100644
--- a/core/jni/include/android_runtime/android_util_AssetManager.h
+++ b/core/jni/include/android_runtime/android_util_AssetManager.h
@@ -14,17 +14,20 @@
  * limitations under the License.
  */
 
-#ifndef android_util_AssetManager_H
-#define android_util_AssetManager_H
+#ifndef ANDROID_RUNTIME_ASSETMANAGER_H
+#define ANDROID_RUNTIME_ASSETMANAGER_H
 
-#include <androidfw/AssetManager.h>
+#include "androidfw/AssetManager2.h"
+#include "androidfw/MutexGuard.h"
 
 #include "jni.h"
 
 namespace android {
 
-extern AssetManager* assetManagerForJavaObject(JNIEnv* env, jobject assetMgr);
+extern AAssetManager* NdkAssetManagerForJavaObject(JNIEnv* env, jobject jassetmanager);
+extern Guarded<AssetManager2>* AssetManagerForJavaObject(JNIEnv* env, jobject jassetmanager);
+extern Guarded<AssetManager2>* AssetManagerForNdkAssetManager(AAssetManager* assetmanager);
 
-}
+}  // namespace android
 
-#endif
+#endif  // ANDROID_RUNTIME_ASSETMANAGER_H
diff --git a/libs/androidfw/AssetManager2.cpp b/libs/androidfw/AssetManager2.cpp
index 415d3e3..2fc8e95 100644
--- a/libs/androidfw/AssetManager2.cpp
+++ b/libs/androidfw/AssetManager2.cpp
@@ -265,8 +265,6 @@
 
 ApkAssetsCookie AssetManager2::FindEntry(uint32_t resid, uint16_t density_override,
                                          bool stop_at_first_match, FindEntryResult* out_entry) {
-  ATRACE_CALL();
-
   // Might use this if density_override != 0.
   ResTable_config density_override_config;
 
@@ -429,9 +427,7 @@
   for (size_t iteration = 0u; in_out_value->dataType == Res_value::TYPE_REFERENCE &&
                               in_out_value->data != 0u && iteration < kMaxIterations;
        iteration++) {
-    if (out_last_reference != nullptr) {
-      *out_last_reference = in_out_value->data;
-    }
+    *out_last_reference = in_out_value->data;
     uint32_t new_flags = 0u;
     cookie = GetResource(in_out_value->data, true /*may_be_bag*/, 0u /*density_override*/,
                          in_out_value, in_out_selected_config, &new_flags);
diff --git a/libs/androidfw/AttributeResolution.cpp b/libs/androidfw/AttributeResolution.cpp
index 60e3845..f912af4 100644
--- a/libs/androidfw/AttributeResolution.cpp
+++ b/libs/androidfw/AttributeResolution.cpp
@@ -20,13 +20,18 @@
 
 #include <log/log.h>
 
+#include "androidfw/AssetManager2.h"
 #include "androidfw/AttributeFinder.h"
-#include "androidfw/ResourceTypes.h"
 
 constexpr bool kDebugStyles = false;
 
 namespace android {
 
+// Java asset cookies have 0 as an invalid cookie, but TypedArray expects < 0.
+static uint32_t ApkAssetsCookieToJavaCookie(ApkAssetsCookie cookie) {
+  return cookie != kInvalidCookie ? static_cast<uint32_t>(cookie + 1) : static_cast<uint32_t>(-1);
+}
+
 class XmlAttributeFinder
     : public BackTrackingAttributeFinder<XmlAttributeFinder, size_t> {
  public:
@@ -44,58 +49,53 @@
 };
 
 class BagAttributeFinder
-    : public BackTrackingAttributeFinder<BagAttributeFinder, const ResTable::bag_entry*> {
+    : public BackTrackingAttributeFinder<BagAttributeFinder, const ResolvedBag::Entry*> {
  public:
-  BagAttributeFinder(const ResTable::bag_entry* start,
-                     const ResTable::bag_entry* end)
-      : BackTrackingAttributeFinder(start, end) {}
+  BagAttributeFinder(const ResolvedBag* bag)
+      : BackTrackingAttributeFinder(bag != nullptr ? bag->entries : nullptr,
+                                    bag != nullptr ? bag->entries + bag->entry_count : nullptr) {
+  }
 
-  inline uint32_t GetAttribute(const ResTable::bag_entry* entry) const {
-    return entry->map.name.ident;
+  inline uint32_t GetAttribute(const ResolvedBag::Entry* entry) const {
+    return entry->key;
   }
 };
 
-bool ResolveAttrs(ResTable::Theme* theme, uint32_t def_style_attr,
-                  uint32_t def_style_res, uint32_t* src_values,
-                  size_t src_values_length, uint32_t* attrs,
-                  size_t attrs_length, uint32_t* out_values,
-                  uint32_t* out_indices) {
+bool ResolveAttrs(Theme* theme, uint32_t def_style_attr, uint32_t def_style_res,
+                  uint32_t* src_values, size_t src_values_length, uint32_t* attrs,
+                  size_t attrs_length, uint32_t* out_values, uint32_t* out_indices) {
   if (kDebugStyles) {
     ALOGI("APPLY STYLE: theme=0x%p defStyleAttr=0x%x defStyleRes=0x%x", theme,
           def_style_attr, def_style_res);
   }
 
-  const ResTable& res = theme->getResTable();
+  AssetManager2* assetmanager = theme->GetAssetManager();
   ResTable_config config;
   Res_value value;
 
   int indices_idx = 0;
 
   // Load default style from attribute, if specified...
-  uint32_t def_style_bag_type_set_flags = 0;
+  uint32_t def_style_flags = 0u;
   if (def_style_attr != 0) {
     Res_value value;
-    if (theme->getAttribute(def_style_attr, &value, &def_style_bag_type_set_flags) >= 0) {
+    if (theme->GetAttribute(def_style_attr, &value, &def_style_flags) != kInvalidCookie) {
       if (value.dataType == Res_value::TYPE_REFERENCE) {
         def_style_res = value.data;
       }
     }
   }
 
-  // Now lock down the resource object and start pulling stuff from it.
-  res.lock();
-
   // Retrieve the default style bag, if requested.
-  const ResTable::bag_entry* def_style_start = nullptr;
-  uint32_t def_style_type_set_flags = 0;
-  ssize_t bag_off = def_style_res != 0
-                        ? res.getBagLocked(def_style_res, &def_style_start,
-                                           &def_style_type_set_flags)
-                        : -1;
-  def_style_type_set_flags |= def_style_bag_type_set_flags;
-  const ResTable::bag_entry* const def_style_end =
-      def_style_start + (bag_off >= 0 ? bag_off : 0);
-  BagAttributeFinder def_style_attr_finder(def_style_start, def_style_end);
+  const ResolvedBag* default_style_bag = nullptr;
+  if (def_style_res != 0) {
+    default_style_bag = assetmanager->GetBag(def_style_res);
+    if (default_style_bag != nullptr) {
+      def_style_flags |= default_style_bag->type_spec_flags;
+    }
+  }
+
+  BagAttributeFinder def_style_attr_finder(default_style_bag);
 
   // Now iterate through all of the attributes that the client has requested,
   // filling in each with whatever data we can find.
@@ -106,7 +106,7 @@
       ALOGI("RETRIEVING ATTR 0x%08x...", cur_ident);
     }
 
-    ssize_t block = -1;
+    ApkAssetsCookie cookie = kInvalidCookie;
     uint32_t type_set_flags = 0;
 
     value.dataType = Res_value::TYPE_NULL;
@@ -122,15 +122,14 @@
       value.dataType = Res_value::TYPE_ATTRIBUTE;
       value.data = src_values[ii];
       if (kDebugStyles) {
-        ALOGI("-> From values: type=0x%x, data=0x%08x", value.dataType,
-              value.data);
+        ALOGI("-> From values: type=0x%x, data=0x%08x", value.dataType, value.data);
       }
     } else {
-      const ResTable::bag_entry* const def_style_entry = def_style_attr_finder.Find(cur_ident);
-      if (def_style_entry != def_style_end) {
-        block = def_style_entry->stringBlock;
-        type_set_flags = def_style_type_set_flags;
-        value = def_style_entry->map.value;
+      const ResolvedBag::Entry* const entry = def_style_attr_finder.Find(cur_ident);
+      if (entry != def_style_attr_finder.end()) {
+        cookie = entry->cookie;
+        type_set_flags = def_style_flags;
+        value = entry->value;
         if (kDebugStyles) {
           ALOGI("-> From def style: type=0x%x, data=0x%08x", value.dataType, value.data);
         }
@@ -140,22 +139,26 @@
     uint32_t resid = 0;
     if (value.dataType != Res_value::TYPE_NULL) {
       // Take care of resolving the found resource to its final value.
-      ssize_t new_block =
-          theme->resolveAttributeReference(&value, block, &resid, &type_set_flags, &config);
-      if (new_block >= 0) block = new_block;
+      ApkAssetsCookie new_cookie =
+          theme->ResolveAttributeReference(cookie, &value, &config, &type_set_flags, &resid);
+      if (new_cookie != kInvalidCookie) {
+        cookie = new_cookie;
+      }
       if (kDebugStyles) {
         ALOGI("-> Resolved attr: type=0x%x, data=0x%08x", value.dataType, value.data);
       }
     } else if (value.data != Res_value::DATA_NULL_EMPTY) {
-      // If we still don't have a value for this attribute, try to find
-      // it in the theme!
-      ssize_t new_block = theme->getAttribute(cur_ident, &value, &type_set_flags);
-      if (new_block >= 0) {
+      // If we still don't have a value for this attribute, try to find it in the theme!
+      ApkAssetsCookie new_cookie = theme->GetAttribute(cur_ident, &value, &type_set_flags);
+      if (new_cookie != kInvalidCookie) {
         if (kDebugStyles) {
           ALOGI("-> From theme: type=0x%x, data=0x%08x", value.dataType, value.data);
         }
-        new_block = res.resolveReference(&value, new_block, &resid, &type_set_flags, &config);
-        if (new_block >= 0) block = new_block;
+        new_cookie =
+            assetmanager->ResolveReference(new_cookie, &value, &config, &type_set_flags, &resid);
+        if (new_cookie != kInvalidCookie) {
+          cookie = new_cookie;
+        }
         if (kDebugStyles) {
           ALOGI("-> Resolved theme: type=0x%x, data=0x%08x", value.dataType, value.data);
         }
@@ -169,7 +172,7 @@
       }
       value.dataType = Res_value::TYPE_NULL;
       value.data = Res_value::DATA_NULL_UNDEFINED;
-      block = -1;
+      cookie = kInvalidCookie;
     }
 
     if (kDebugStyles) {
@@ -179,9 +182,7 @@
     // Write the final value back to Java.
     out_values[STYLE_TYPE] = value.dataType;
     out_values[STYLE_DATA] = value.data;
-    out_values[STYLE_ASSET_COOKIE] =
-        block != -1 ? static_cast<uint32_t>(res.getTableCookie(block))
-                    : static_cast<uint32_t>(-1);
+    out_values[STYLE_ASSET_COOKIE] = ApkAssetsCookieToJavaCookie(cookie);
     out_values[STYLE_RESOURCE_ID] = resid;
     out_values[STYLE_CHANGING_CONFIGURATIONS] = type_set_flags;
     out_values[STYLE_DENSITY] = config.density;
@@ -195,90 +196,80 @@
     out_values += STYLE_NUM_ENTRIES;
   }
 
-  res.unlock();
-
   if (out_indices != nullptr) {
     out_indices[0] = indices_idx;
   }
   return true;
 }
 
-void ApplyStyle(ResTable::Theme* theme, ResXMLParser* xml_parser, uint32_t def_style_attr,
-                uint32_t def_style_res, const uint32_t* attrs, size_t attrs_length,
+void ApplyStyle(Theme* theme, ResXMLParser* xml_parser, uint32_t def_style_attr,
+                uint32_t def_style_resid, const uint32_t* attrs, size_t attrs_length,
                 uint32_t* out_values, uint32_t* out_indices) {
   if (kDebugStyles) {
-    ALOGI("APPLY STYLE: theme=0x%p defStyleAttr=0x%x defStyleRes=0x%x xml=0x%p",
-          theme, def_style_attr, def_style_res, xml_parser);
+    ALOGI("APPLY STYLE: theme=0x%p defStyleAttr=0x%x defStyleRes=0x%x xml=0x%p", theme,
+          def_style_attr, def_style_resid, xml_parser);
   }
 
-  const ResTable& res = theme->getResTable();
+  AssetManager2* assetmanager = theme->GetAssetManager();
   ResTable_config config;
   Res_value value;
 
   int indices_idx = 0;
 
   // Load default style from attribute, if specified...
-  uint32_t def_style_bag_type_set_flags = 0;
+  uint32_t def_style_flags = 0u;
   if (def_style_attr != 0) {
     Res_value value;
-    if (theme->getAttribute(def_style_attr, &value,
-                            &def_style_bag_type_set_flags) >= 0) {
+    if (theme->GetAttribute(def_style_attr, &value, &def_style_flags) != kInvalidCookie) {
       if (value.dataType == Res_value::TYPE_REFERENCE) {
-        def_style_res = value.data;
+        def_style_resid = value.data;
       }
     }
   }
 
-  // Retrieve the style class associated with the current XML tag.
-  int style = 0;
-  uint32_t style_bag_type_set_flags = 0;
+  // Retrieve the style resource ID associated with the current XML tag's style attribute.
+  uint32_t style_resid = 0u;
+  uint32_t style_flags = 0u;
   if (xml_parser != nullptr) {
     ssize_t idx = xml_parser->indexOfStyle();
     if (idx >= 0 && xml_parser->getAttributeValue(idx, &value) >= 0) {
       if (value.dataType == value.TYPE_ATTRIBUTE) {
-        if (theme->getAttribute(value.data, &value, &style_bag_type_set_flags) < 0) {
+        // Resolve the attribute with out theme.
+        if (theme->GetAttribute(value.data, &value, &style_flags) == kInvalidCookie) {
           value.dataType = Res_value::TYPE_NULL;
         }
       }
+
       if (value.dataType == value.TYPE_REFERENCE) {
-        style = value.data;
+        style_resid = value.data;
       }
     }
   }
 
-  // Now lock down the resource object and start pulling stuff from it.
-  res.lock();
-
   // Retrieve the default style bag, if requested.
-  const ResTable::bag_entry* def_style_attr_start = nullptr;
-  uint32_t def_style_type_set_flags = 0;
-  ssize_t bag_off = def_style_res != 0
-                        ? res.getBagLocked(def_style_res, &def_style_attr_start,
-                                           &def_style_type_set_flags)
-                        : -1;
-  def_style_type_set_flags |= def_style_bag_type_set_flags;
-  const ResTable::bag_entry* const def_style_attr_end =
-      def_style_attr_start + (bag_off >= 0 ? bag_off : 0);
-  BagAttributeFinder def_style_attr_finder(def_style_attr_start,
-                                           def_style_attr_end);
+  const ResolvedBag* default_style_bag = nullptr;
+  if (def_style_resid != 0) {
+    default_style_bag = assetmanager->GetBag(def_style_resid);
+    if (default_style_bag != nullptr) {
+      def_style_flags |= default_style_bag->type_spec_flags;
+    }
+  }
+
+  BagAttributeFinder def_style_attr_finder(default_style_bag);
 
   // Retrieve the style class bag, if requested.
-  const ResTable::bag_entry* style_attr_start = nullptr;
-  uint32_t style_type_set_flags = 0;
-  bag_off =
-      style != 0
-          ? res.getBagLocked(style, &style_attr_start, &style_type_set_flags)
-          : -1;
-  style_type_set_flags |= style_bag_type_set_flags;
-  const ResTable::bag_entry* const style_attr_end =
-      style_attr_start + (bag_off >= 0 ? bag_off : 0);
-  BagAttributeFinder style_attr_finder(style_attr_start, style_attr_end);
+  const ResolvedBag* xml_style_bag = nullptr;
+  if (style_resid != 0) {
+    xml_style_bag = assetmanager->GetBag(style_resid);
+    if (xml_style_bag != nullptr) {
+      style_flags |= xml_style_bag->type_spec_flags;
+    }
+  }
+
+  BagAttributeFinder xml_style_attr_finder(xml_style_bag);
 
   // Retrieve the XML attributes, if requested.
-  static const ssize_t kXmlBlock = 0x10000000;
   XmlAttributeFinder xml_attr_finder(xml_parser);
-  const size_t xml_attr_end =
-      xml_parser != nullptr ? xml_parser->getAttributeCount() : 0;
 
   // Now iterate through all of the attributes that the client has requested,
   // filling in each with whatever data we can find.
@@ -289,8 +280,8 @@
       ALOGI("RETRIEVING ATTR 0x%08x...", cur_ident);
     }
 
-    ssize_t block = kXmlBlock;
-    uint32_t type_set_flags = 0;
+    ApkAssetsCookie cookie = kInvalidCookie;
+    uint32_t type_set_flags = 0u;
 
     value.dataType = Res_value::TYPE_NULL;
     value.data = Res_value::DATA_NULL_UNDEFINED;
@@ -302,7 +293,7 @@
 
     // Walk through the xml attributes looking for the requested attribute.
     const size_t xml_attr_idx = xml_attr_finder.Find(cur_ident);
-    if (xml_attr_idx != xml_attr_end) {
+    if (xml_attr_idx != xml_attr_finder.end()) {
       // We found the attribute we were looking for.
       xml_parser->getAttributeValue(xml_attr_idx, &value);
       if (kDebugStyles) {
@@ -312,12 +303,12 @@
 
     if (value.dataType == Res_value::TYPE_NULL && value.data != Res_value::DATA_NULL_EMPTY) {
       // Walk through the style class values looking for the requested attribute.
-      const ResTable::bag_entry* const style_attr_entry = style_attr_finder.Find(cur_ident);
-      if (style_attr_entry != style_attr_end) {
+      const ResolvedBag::Entry* entry = xml_style_attr_finder.Find(cur_ident);
+      if (entry != xml_style_attr_finder.end()) {
         // We found the attribute we were looking for.
-        block = style_attr_entry->stringBlock;
-        type_set_flags = style_type_set_flags;
-        value = style_attr_entry->map.value;
+        cookie = entry->cookie;
+        type_set_flags = style_flags;
+        value = entry->value;
         if (kDebugStyles) {
           ALOGI("-> From style: type=0x%x, data=0x%08x", value.dataType, value.data);
         }
@@ -326,25 +317,25 @@
 
     if (value.dataType == Res_value::TYPE_NULL && value.data != Res_value::DATA_NULL_EMPTY) {
       // Walk through the default style values looking for the requested attribute.
-      const ResTable::bag_entry* const def_style_attr_entry = def_style_attr_finder.Find(cur_ident);
-      if (def_style_attr_entry != def_style_attr_end) {
+      const ResolvedBag::Entry* entry = def_style_attr_finder.Find(cur_ident);
+      if (entry != def_style_attr_finder.end()) {
         // We found the attribute we were looking for.
-        block = def_style_attr_entry->stringBlock;
-        type_set_flags = style_type_set_flags;
-        value = def_style_attr_entry->map.value;
+        cookie = entry->cookie;
+        type_set_flags = def_style_flags;
+        value = entry->value;
         if (kDebugStyles) {
           ALOGI("-> From def style: type=0x%x, data=0x%08x", value.dataType, value.data);
         }
       }
     }
 
-    uint32_t resid = 0;
+    uint32_t resid = 0u;
     if (value.dataType != Res_value::TYPE_NULL) {
       // Take care of resolving the found resource to its final value.
-      ssize_t new_block =
-          theme->resolveAttributeReference(&value, block, &resid, &type_set_flags, &config);
-      if (new_block >= 0) {
-        block = new_block;
+      ApkAssetsCookie new_cookie =
+          theme->ResolveAttributeReference(cookie, &value, &config, &type_set_flags, &resid);
+      if (new_cookie != kInvalidCookie) {
+        cookie = new_cookie;
       }
 
       if (kDebugStyles) {
@@ -352,14 +343,15 @@
       }
     } else if (value.data != Res_value::DATA_NULL_EMPTY) {
       // If we still don't have a value for this attribute, try to find it in the theme!
-      ssize_t new_block = theme->getAttribute(cur_ident, &value, &type_set_flags);
-      if (new_block >= 0) {
+      ApkAssetsCookie new_cookie = theme->GetAttribute(cur_ident, &value, &type_set_flags);
+      if (new_cookie != kInvalidCookie) {
         if (kDebugStyles) {
           ALOGI("-> From theme: type=0x%x, data=0x%08x", value.dataType, value.data);
         }
-        new_block = res.resolveReference(&value, new_block, &resid, &type_set_flags, &config);
-        if (new_block >= 0) {
-          block = new_block;
+        new_cookie =
+            assetmanager->ResolveReference(new_cookie, &value, &config, &type_set_flags, &resid);
+        if (new_cookie != kInvalidCookie) {
+          cookie = new_cookie;
         }
 
         if (kDebugStyles) {
@@ -375,7 +367,7 @@
       }
       value.dataType = Res_value::TYPE_NULL;
       value.data = Res_value::DATA_NULL_UNDEFINED;
-      block = kXmlBlock;
+      cookie = kInvalidCookie;
     }
 
     if (kDebugStyles) {
@@ -385,9 +377,7 @@
     // Write the final value back to Java.
     out_values[STYLE_TYPE] = value.dataType;
     out_values[STYLE_DATA] = value.data;
-    out_values[STYLE_ASSET_COOKIE] =
-        block != kXmlBlock ? static_cast<uint32_t>(res.getTableCookie(block))
-                           : static_cast<uint32_t>(-1);
+    out_values[STYLE_ASSET_COOKIE] = ApkAssetsCookieToJavaCookie(cookie);
     out_values[STYLE_RESOURCE_ID] = resid;
     out_values[STYLE_CHANGING_CONFIGURATIONS] = type_set_flags;
     out_values[STYLE_DENSITY] = config.density;
@@ -402,36 +392,28 @@
     out_values += STYLE_NUM_ENTRIES;
   }
 
-  res.unlock();
-
   // out_indices must NOT be nullptr.
   out_indices[0] = indices_idx;
 }
 
-bool RetrieveAttributes(const ResTable* res, ResXMLParser* xml_parser,
-                        uint32_t* attrs, size_t attrs_length,
-                        uint32_t* out_values, uint32_t* out_indices) {
+bool RetrieveAttributes(AssetManager2* assetmanager, ResXMLParser* xml_parser, uint32_t* attrs,
+                        size_t attrs_length, uint32_t* out_values, uint32_t* out_indices) {
   ResTable_config config;
   Res_value value;
 
   int indices_idx = 0;
 
-  // Now lock down the resource object and start pulling stuff from it.
-  res->lock();
-
   // Retrieve the XML attributes, if requested.
   const size_t xml_attr_count = xml_parser->getAttributeCount();
   size_t ix = 0;
   uint32_t cur_xml_attr = xml_parser->getAttributeNameResID(ix);
 
-  static const ssize_t kXmlBlock = 0x10000000;
-
   // Now iterate through all of the attributes that the client has requested,
   // filling in each with whatever data we can find.
   for (size_t ii = 0; ii < attrs_length; ii++) {
     const uint32_t cur_ident = attrs[ii];
-    ssize_t block = kXmlBlock;
-    uint32_t type_set_flags = 0;
+    ApkAssetsCookie cookie = kInvalidCookie;
+    uint32_t type_set_flags = 0u;
 
     value.dataType = Res_value::TYPE_NULL;
     value.data = Res_value::DATA_NULL_UNDEFINED;
@@ -450,28 +432,27 @@
       cur_xml_attr = xml_parser->getAttributeNameResID(ix);
     }
 
-    uint32_t resid = 0;
+    uint32_t resid = 0u;
     if (value.dataType != Res_value::TYPE_NULL) {
       // Take care of resolving the found resource to its final value.
-      // printf("Resolving attribute reference\n");
-      ssize_t new_block = res->resolveReference(&value, block, &resid,
-                                                &type_set_flags, &config);
-      if (new_block >= 0) block = new_block;
+      ApkAssetsCookie new_cookie =
+          assetmanager->ResolveReference(cookie, &value, &config, &type_set_flags, &resid);
+      if (new_cookie != kInvalidCookie) {
+        cookie = new_cookie;
+      }
     }
 
     // Deal with the special @null value -- it turns back to TYPE_NULL.
     if (value.dataType == Res_value::TYPE_REFERENCE && value.data == 0) {
       value.dataType = Res_value::TYPE_NULL;
       value.data = Res_value::DATA_NULL_UNDEFINED;
-      block = kXmlBlock;
+      cookie = kInvalidCookie;
     }
 
     // Write the final value back to Java.
     out_values[STYLE_TYPE] = value.dataType;
     out_values[STYLE_DATA] = value.data;
-    out_values[STYLE_ASSET_COOKIE] =
-        block != kXmlBlock ? static_cast<uint32_t>(res->getTableCookie(block))
-                           : static_cast<uint32_t>(-1);
+    out_values[STYLE_ASSET_COOKIE] = ApkAssetsCookieToJavaCookie(cookie);
     out_values[STYLE_RESOURCE_ID] = resid;
     out_values[STYLE_CHANGING_CONFIGURATIONS] = type_set_flags;
     out_values[STYLE_DENSITY] = config.density;
@@ -485,8 +466,6 @@
     out_values += STYLE_NUM_ENTRIES;
   }
 
-  res->unlock();
-
   if (out_indices != nullptr) {
     out_indices[0] = indices_idx;
   }
diff --git a/libs/androidfw/LoadedArsc.cpp b/libs/androidfw/LoadedArsc.cpp
index 28548e2..e08848f 100644
--- a/libs/androidfw/LoadedArsc.cpp
+++ b/libs/androidfw/LoadedArsc.cpp
@@ -324,8 +324,6 @@
 
 bool LoadedPackage::FindEntry(uint8_t type_idx, uint16_t entry_idx, const ResTable_config& config,
                               FindEntryResult* out_entry) const {
-  ATRACE_CALL();
-
   // If the type IDs are offset in this package, we need to take that into account when searching
   // for a type.
   const TypeSpecPtr& ptr = type_specs_[type_idx - type_id_offset_];
diff --git a/libs/androidfw/include/androidfw/AttributeFinder.h b/libs/androidfw/include/androidfw/AttributeFinder.h
index f281921..03fad49 100644
--- a/libs/androidfw/include/androidfw/AttributeFinder.h
+++ b/libs/androidfw/include/androidfw/AttributeFinder.h
@@ -58,6 +58,7 @@
   BackTrackingAttributeFinder(const Iterator& begin, const Iterator& end);
 
   Iterator Find(uint32_t attr);
+  inline Iterator end();
 
  private:
   void JumpToClosestAttribute(uint32_t package_id);
@@ -201,6 +202,11 @@
   return end_;
 }
 
+template <typename Derived, typename Iterator>
+Iterator BackTrackingAttributeFinder<Derived, Iterator>::end() {
+  return end_;
+}
+
 }  // namespace android
 
 #endif  // ANDROIDFW_ATTRIBUTE_FINDER_H
diff --git a/libs/androidfw/include/androidfw/AttributeResolution.h b/libs/androidfw/include/androidfw/AttributeResolution.h
index 69b76041..35ef98d 100644
--- a/libs/androidfw/include/androidfw/AttributeResolution.h
+++ b/libs/androidfw/include/androidfw/AttributeResolution.h
@@ -17,7 +17,8 @@
 #ifndef ANDROIDFW_ATTRIBUTERESOLUTION_H
 #define ANDROIDFW_ATTRIBUTERESOLUTION_H
 
-#include <androidfw/ResourceTypes.h>
+#include "androidfw/AssetManager2.h"
+#include "androidfw/ResourceTypes.h"
 
 namespace android {
 
@@ -42,19 +43,19 @@
 
 // `out_values` must NOT be nullptr.
 // `out_indices` may be nullptr.
-bool ResolveAttrs(ResTable::Theme* theme, uint32_t def_style_attr, uint32_t def_style_res,
+bool ResolveAttrs(Theme* theme, uint32_t def_style_attr, uint32_t def_style_resid,
                   uint32_t* src_values, size_t src_values_length, uint32_t* attrs,
                   size_t attrs_length, uint32_t* out_values, uint32_t* out_indices);
 
 // `out_values` must NOT be nullptr.
 // `out_indices` is NOT optional and must NOT be nullptr.
-void ApplyStyle(ResTable::Theme* theme, ResXMLParser* xml_parser, uint32_t def_style_attr,
-                uint32_t def_style_res, const uint32_t* attrs, size_t attrs_length,
+void ApplyStyle(Theme* theme, ResXMLParser* xml_parser, uint32_t def_style_attr,
+                uint32_t def_style_resid, const uint32_t* attrs, size_t attrs_length,
                 uint32_t* out_values, uint32_t* out_indices);
 
 // `out_values` must NOT be nullptr.
 // `out_indices` may be nullptr.
-bool RetrieveAttributes(const ResTable* res, ResXMLParser* xml_parser, uint32_t* attrs,
+bool RetrieveAttributes(AssetManager2* assetmanager, ResXMLParser* xml_parser, uint32_t* attrs,
                         size_t attrs_length, uint32_t* out_values, uint32_t* out_indices);
 
 }  // namespace android
diff --git a/libs/androidfw/include/androidfw/LoadedArsc.h b/libs/androidfw/include/androidfw/LoadedArsc.h
index 965e2db..1775f50 100644
--- a/libs/androidfw/include/androidfw/LoadedArsc.h
+++ b/libs/androidfw/include/androidfw/LoadedArsc.h
@@ -45,16 +45,17 @@
   // A pointer to the resource table entry for this resource.
   // If the size of the entry is > sizeof(ResTable_entry), it can be cast to
   // a ResTable_map_entry and processed as a bag/map.
-  const ResTable_entry* entry = nullptr;
+  const ResTable_entry* entry;
 
-  // The configuration for which the resulting entry was defined.
-  const ResTable_config* config = nullptr;
+  // The configuration for which the resulting entry was defined. This points to a structure that
+  // is already swapped to host endianness.
+  const ResTable_config* config;
 
-  // Stores the resulting bitmask of configuration axis with which the resource value varies.
-  uint32_t type_flags = 0u;
+  // The bitmask of configuration axis with which the resource value varies.
+  uint32_t type_flags;
 
   // The dynamic package ID map for the package from which this resource came from.
-  const DynamicRefTable* dynamic_ref_table = nullptr;
+  const DynamicRefTable* dynamic_ref_table;
 
   // The string pool reference to the type's name. This uses a different string pool than
   // the global string pool, but this is hidden from the caller.
diff --git a/libs/androidfw/include/androidfw/MutexGuard.h b/libs/androidfw/include/androidfw/MutexGuard.h
new file mode 100644
index 0000000..64924f4
--- /dev/null
+++ b/libs/androidfw/include/androidfw/MutexGuard.h
@@ -0,0 +1,101 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROIDFW_MUTEXGUARD_H
+#define ANDROIDFW_MUTEXGUARD_H
+
+#include <mutex>
+#include <type_traits>
+
+#include "android-base/macros.h"
+
+namespace android {
+
+template <typename T>
+class ScopedLock;
+
+// Owns the guarded object and protects access to it via a mutex.
+// The guarded object is inaccessible via this class.
+// The mutex is locked and the object accessed via the ScopedLock<T> class.
+//
+// NOTE: The template parameter T should not be a raw pointer, since ownership
+// is ambiguous and error-prone. Instead use an std::unique_ptr<>.
+//
+// Example use:
+//
+//   Guarded<std::string> shared_string("hello");
+//   {
+//     ScopedLock<std::string> locked_string(shared_string);
+//     *locked_string += " world";
+//   }
+//
+template <typename T>
+class Guarded {
+  static_assert(!std::is_pointer<T>::value, "T must not be a raw pointer");
+
+ public:
+  explicit Guarded() : guarded_() {
+  }
+
+  template <typename U = T>
+  explicit Guarded(const T& guarded,
+                   typename std::enable_if<std::is_copy_constructible<U>::value>::type = void())
+      : guarded_(guarded) {
+  }
+
+  template <typename U = T>
+  explicit Guarded(T&& guarded,
+                   typename std::enable_if<std::is_move_constructible<U>::value>::type = void())
+      : guarded_(std::move(guarded)) {
+  }
+
+ private:
+  friend class ScopedLock<T>;
+
+  DISALLOW_COPY_AND_ASSIGN(Guarded);
+
+  std::mutex lock_;
+  T guarded_;
+};
+
+template <typename T>
+class ScopedLock {
+ public:
+  explicit ScopedLock(Guarded<T>& guarded) : lock_(guarded.lock_), guarded_(guarded.guarded_) {
+  }
+
+  T& operator*() {
+    return guarded_;
+  }
+
+  T* operator->() {
+    return &guarded_;
+  }
+
+  T* get() {
+    return &guarded_;
+  }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(ScopedLock);
+
+  std::lock_guard<std::mutex> lock_;
+  T& guarded_;
+};
+
+}  // namespace android
+
+#endif  // ANDROIDFW_MUTEXGUARD_H
diff --git a/libs/androidfw/tests/AttributeResolution_test.cpp b/libs/androidfw/tests/AttributeResolution_test.cpp
index 2d73ce8..cc30537 100644
--- a/libs/androidfw/tests/AttributeResolution_test.cpp
+++ b/libs/androidfw/tests/AttributeResolution_test.cpp
@@ -21,6 +21,7 @@
 #include "android-base/file.h"
 #include "android-base/logging.h"
 #include "android-base/macros.h"
+#include "androidfw/AssetManager2.h"
 
 #include "TestHelpers.h"
 #include "data/styles/R.h"
@@ -32,15 +33,14 @@
 class AttributeResolutionTest : public ::testing::Test {
  public:
   virtual void SetUp() override {
-    std::string contents;
-    ASSERT_TRUE(ReadFileFromZipToString(
-        GetTestDataPath() + "/styles/styles.apk", "resources.arsc", &contents));
-    ASSERT_EQ(NO_ERROR, table_.add(contents.data(), contents.size(),
-                                   1 /*cookie*/, true /*copyData*/));
+    styles_assets_ = ApkAssets::Load(GetTestDataPath() + "/styles/styles.apk");
+    ASSERT_NE(nullptr, styles_assets_);
+    assetmanager_.SetApkAssets({styles_assets_.get()});
   }
 
  protected:
-  ResTable table_;
+  std::unique_ptr<const ApkAssets> styles_assets_;
+  AssetManager2 assetmanager_;
 };
 
 class AttributeResolutionXmlTest : public AttributeResolutionTest {
@@ -48,13 +48,12 @@
   virtual void SetUp() override {
     AttributeResolutionTest::SetUp();
 
-    std::string contents;
-    ASSERT_TRUE(
-        ReadFileFromZipToString(GetTestDataPath() + "/styles/styles.apk",
-                                "res/layout/layout.xml", &contents));
+    std::unique_ptr<Asset> asset =
+        assetmanager_.OpenNonAsset("res/layout/layout.xml", Asset::ACCESS_BUFFER);
+    ASSERT_NE(nullptr, asset);
 
-    ASSERT_EQ(NO_ERROR, xml_parser_.setTo(contents.data(), contents.size(),
-                                          true /*copyData*/));
+    ASSERT_EQ(NO_ERROR,
+              xml_parser_.setTo(asset->getBuffer(true), asset->getLength(), true /*copyData*/));
 
     // Skip to the first tag.
     while (xml_parser_.next() != ResXMLParser::START_TAG) {
@@ -66,14 +65,14 @@
 };
 
 TEST_F(AttributeResolutionTest, Theme) {
-  ResTable::Theme theme(table_);
-  ASSERT_EQ(NO_ERROR, theme.applyStyle(R::style::StyleTwo));
+  std::unique_ptr<Theme> theme = assetmanager_.NewTheme();
+  ASSERT_TRUE(theme->ApplyStyle(R::style::StyleTwo));
 
   std::array<uint32_t, 5> attrs{{R::attr::attr_one, R::attr::attr_two, R::attr::attr_three,
                                  R::attr::attr_four, R::attr::attr_empty}};
   std::array<uint32_t, attrs.size() * STYLE_NUM_ENTRIES> values;
 
-  ASSERT_TRUE(ResolveAttrs(&theme, 0 /*def_style_attr*/, 0 /*def_style_res*/,
+  ASSERT_TRUE(ResolveAttrs(theme.get(), 0u /*def_style_attr*/, 0u /*def_style_res*/,
                            nullptr /*src_values*/, 0 /*src_values_length*/, attrs.data(),
                            attrs.size(), values.data(), nullptr /*out_indices*/));
 
@@ -126,8 +125,8 @@
                                  R::attr::attr_four, R::attr::attr_empty}};
   std::array<uint32_t, attrs.size() * STYLE_NUM_ENTRIES> values;
 
-  ASSERT_TRUE(RetrieveAttributes(&table_, &xml_parser_, attrs.data(), attrs.size(), values.data(),
-                                 nullptr /*out_indices*/));
+  ASSERT_TRUE(RetrieveAttributes(&assetmanager_, &xml_parser_, attrs.data(), attrs.size(),
+                                 values.data(), nullptr /*out_indices*/));
 
   uint32_t* values_cursor = values.data();
   EXPECT_EQ(Res_value::TYPE_NULL, values_cursor[STYLE_TYPE]);
@@ -171,15 +170,15 @@
 }
 
 TEST_F(AttributeResolutionXmlTest, ThemeAndXmlParser) {
-  ResTable::Theme theme(table_);
-  ASSERT_EQ(NO_ERROR, theme.applyStyle(R::style::StyleTwo));
+  std::unique_ptr<Theme> theme = assetmanager_.NewTheme();
+  ASSERT_TRUE(theme->ApplyStyle(R::style::StyleTwo));
 
   std::array<uint32_t, 6> attrs{{R::attr::attr_one, R::attr::attr_two, R::attr::attr_three,
                                  R::attr::attr_four, R::attr::attr_five, R::attr::attr_empty}};
   std::array<uint32_t, attrs.size() * STYLE_NUM_ENTRIES> values;
   std::array<uint32_t, attrs.size() + 1> indices;
 
-  ApplyStyle(&theme, &xml_parser_, 0 /*def_style_attr*/, 0 /*def_style_res*/, attrs.data(),
+  ApplyStyle(theme.get(), &xml_parser_, 0u /*def_style_attr*/, 0u /*def_style_res*/, attrs.data(),
              attrs.size(), values.data(), indices.data());
 
   const uint32_t public_flag = ResTable_typeSpec::SPEC_PUBLIC;
diff --git a/libs/androidfw/tests/BenchmarkHelpers.cpp b/libs/androidfw/tests/BenchmarkHelpers.cpp
index 7149bee..a8abcb5 100644
--- a/libs/androidfw/tests/BenchmarkHelpers.cpp
+++ b/libs/androidfw/tests/BenchmarkHelpers.cpp
@@ -33,12 +33,12 @@
     }
   }
 
+  // Make sure to force creation of the ResTable first, or else the configuration doesn't get set.
+  const ResTable& table = assetmanager.getResources(true);
   if (config != nullptr) {
     assetmanager.setConfiguration(*config);
   }
 
-  const ResTable& table = assetmanager.getResources(true);
-
   Res_value value;
   ResTable_config selected_config;
   uint32_t flags;
diff --git a/native/android/asset_manager.cpp b/native/android/asset_manager.cpp
index 98e9a42..e70d5ea 100644
--- a/native/android/asset_manager.cpp
+++ b/native/android/asset_manager.cpp
@@ -18,9 +18,11 @@
 #include <utils/Log.h>
 
 #include <android/asset_manager_jni.h>
+#include <android_runtime/android_util_AssetManager.h>
 #include <androidfw/Asset.h>
 #include <androidfw/AssetDir.h>
 #include <androidfw/AssetManager.h>
+#include <androidfw/AssetManager2.h>
 #include <utils/threads.h>
 
 #include "jni.h"
@@ -35,21 +37,20 @@
 
 // -----
 struct AAssetDir {
-    AssetDir* mAssetDir;
+    std::unique_ptr<AssetDir> mAssetDir;
     size_t mCurFileIndex;
     String8 mCachedFileName;
 
-    explicit AAssetDir(AssetDir* dir) : mAssetDir(dir), mCurFileIndex(0) { }
-    ~AAssetDir() { delete mAssetDir; }
+    explicit AAssetDir(std::unique_ptr<AssetDir> dir) :
+        mAssetDir(std::move(dir)), mCurFileIndex(0) { }
 };
 
 
 // -----
 struct AAsset {
-    Asset* mAsset;
+    std::unique_ptr<Asset> mAsset;
 
-    explicit AAsset(Asset* asset) : mAsset(asset) { }
-    ~AAsset() { delete mAsset; }
+    explicit AAsset(std::unique_ptr<Asset> asset) : mAsset(std::move(asset)) { }
 };
 
 // -------------------- Public native C API --------------------
@@ -104,19 +105,18 @@
         return NULL;
     }
 
-    AssetManager* mgr = static_cast<AssetManager*>(amgr);
-    Asset* asset = mgr->open(filename, amMode);
-    if (asset == NULL) {
-        return NULL;
+    ScopedLock<AssetManager2> locked_mgr(*AssetManagerForNdkAssetManager(amgr));
+    std::unique_ptr<Asset> asset = locked_mgr->Open(filename, amMode);
+    if (asset == nullptr) {
+        return nullptr;
     }
-
-    return new AAsset(asset);
+    return new AAsset(std::move(asset));
 }
 
 AAssetDir* AAssetManager_openDir(AAssetManager* amgr, const char* dirName)
 {
-    AssetManager* mgr = static_cast<AssetManager*>(amgr);
-    return new AAssetDir(mgr->openDir(dirName));
+    ScopedLock<AssetManager2> locked_mgr(*AssetManagerForNdkAssetManager(amgr));
+    return new AAssetDir(locked_mgr->OpenDir(dirName));
 }
 
 /**
diff --git a/rs/jni/android_renderscript_RenderScript.cpp b/rs/jni/android_renderscript_RenderScript.cpp
index b32be73..52d0e08e 100644
--- a/rs/jni/android_renderscript_RenderScript.cpp
+++ b/rs/jni/android_renderscript_RenderScript.cpp
@@ -24,8 +24,9 @@
 #include <utils/misc.h>
 #include <inttypes.h>
 
+#include <android-base/macros.h>
 #include <androidfw/Asset.h>
-#include <androidfw/AssetManager.h>
+#include <androidfw/AssetManager2.h>
 #include <androidfw/ResourceTypes.h>
 #include <android-base/macros.h>
 
@@ -1664,18 +1665,22 @@
 static jlong
 nFileA3DCreateFromAsset(JNIEnv *_env, jobject _this, jlong con, jobject _assetMgr, jstring _path)
 {
-    AssetManager* mgr = assetManagerForJavaObject(_env, _assetMgr);
+    Guarded<AssetManager2>* mgr = AssetManagerForJavaObject(_env, _assetMgr);
     if (mgr == nullptr) {
         return 0;
     }
 
     AutoJavaStringToUTF8 str(_env, _path);
-    Asset* asset = mgr->open(str.c_str(), Asset::ACCESS_BUFFER);
-    if (asset == nullptr) {
-        return 0;
+    std::unique_ptr<Asset> asset;
+    {
+        ScopedLock<AssetManager2> locked_mgr(*mgr);
+        asset = locked_mgr->Open(str.c_str(), Asset::ACCESS_BUFFER);
+        if (asset == nullptr) {
+            return 0;
+        }
     }
 
-    jlong id = (jlong)(uintptr_t)rsaFileA3DCreateFromAsset((RsContext)con, asset);
+    jlong id = (jlong)(uintptr_t)rsaFileA3DCreateFromAsset((RsContext)con, asset.release());
     return id;
 }
 
@@ -1752,22 +1757,25 @@
 nFontCreateFromAsset(JNIEnv *_env, jobject _this, jlong con, jobject _assetMgr, jstring _path,
                      jfloat fontSize, jint dpi)
 {
-    AssetManager* mgr = assetManagerForJavaObject(_env, _assetMgr);
+    Guarded<AssetManager2>* mgr = AssetManagerForJavaObject(_env, _assetMgr);
     if (mgr == nullptr) {
         return 0;
     }
 
     AutoJavaStringToUTF8 str(_env, _path);
-    Asset* asset = mgr->open(str.c_str(), Asset::ACCESS_BUFFER);
-    if (asset == nullptr) {
-        return 0;
+    std::unique_ptr<Asset> asset;
+    {
+        ScopedLock<AssetManager2> locked_mgr(*mgr);
+        asset = locked_mgr->Open(str.c_str(), Asset::ACCESS_BUFFER);
+        if (asset == nullptr) {
+            return 0;
+        }
     }
 
     jlong id = (jlong)(uintptr_t)rsFontCreateFromMemory((RsContext)con,
                                            str.c_str(), str.length(),
                                            fontSize, dpi,
                                            asset->getBuffer(false), asset->getLength());
-    delete asset;
     return id;
 }
 
