diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 77eb57f2..07af26b 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -55,6 +55,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;
@@ -1639,21 +1640,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 Signature[] signatures;
             final Certificate[][] certificates;
@@ -1682,7 +1681,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..4f614a7 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,252 @@
      * @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);
+            return nativeAssetReadChar(mAssetNativePtr);
         }
+
+        @Override
         public final boolean markSupported() {
             return true;
         }
+
+        @Override
         public final int available() throws IOException {
-            long len = getAssetRemainingLength(mAsset);
-            return len > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int)len;
+            final long len = nativeAssetGetRemainingLength(mAssetNativePtr);
+            return len > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) len;
         }
+
+        @Override
         public final void close() throws IOException {
-            synchronized (AssetManager.this) {
-                if (mAsset != 0) {
-                    destroyAsset(mAsset);
-                    mAsset = 0;
+            if (mAssetNativePtr != 0) {
+                nativeAssetDestroy(mAssetNativePtr);
+                mAssetNativePtr = 0;
+
+                synchronized (AssetManager.this) {
                     decRefsLocked(hashCode());
                 }
             }
         }
+
+        @Override
         public final void mark(int readlimit) {
-            mMarkPos = seekAsset(mAsset, 0, 0);
+            mMarkPos = nativeAssetSeek(mAssetNativePtr, 0, 0);
         }
+
+        @Override
         public final void reset() throws IOException {
-            seekAsset(mAsset, mMarkPos, -1);
+            nativeAssetSeek(mAssetNativePtr, mMarkPos, -1);
         }
-        public final int read(byte[] b) throws IOException {
-            return readAsset(mAsset, b, 0, b.length);
+
+        @Override
+        public final int read(@NonNull byte[] b) throws IOException {
+            Preconditions.checkNotNull(b, "b");
+            return nativeAssetRead(mAssetNativePtr, 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 int read(@NonNull byte[] b, int off, int len) throws IOException {
+            Preconditions.checkNotNull(b, "b");
+            return nativeAssetRead(mAssetNativePtr, 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;
+            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
+        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 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 +1058,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 +1073,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 +1131,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 3239212..b6a4f31 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 b3f66e9..c6dcb89 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -111,8 +111,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 6d7fe05..a307992 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -121,6 +121,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_MeasuredText),
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..557b3ab 100644
--- a/core/jni/android_util_AssetManager.cpp
+++ b/core/jni/android_util_AssetManager.cpp
@@ -1,1846 +1,1438 @@
-/* //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 + len) > buffer_len) {
+    jniThrowException(env, "java/lang/IndexOutOfBoundsException", "");
+    return -1;
+  }
+
+  Asset* asset = reinterpret_cast<Asset*>(asset_ptr);
+
+  ScopedByteArrayRW byte_array(env, java_buffer);
+  if (byte_array.get() == nullptr) {
+    return -1;
+  }
+
+  ssize_t res = asset->read(byte_array.get(), buffer_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;
 }
 
