diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index d5c88aa..3d26af1 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -54,7 +54,6 @@
 import android.content.pm.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;
@@ -1595,19 +1594,21 @@
             int flags) throws PackageParserException {
         final String apkPath = fd != null ? debugPathName : apkFile.getAbsolutePath();
 
-        ApkAssets apkAssets = null;
+        AssetManager assets = null;
         XmlResourceParser parser = null;
         try {
-            try {
-                apkAssets = fd != null
-                        ? ApkAssets.loadFromFd(fd, debugPathName, false, false)
-                        : ApkAssets.loadFromPath(apkPath);
-            } catch (IOException e) {
+            assets = newConfiguredAssetManager();
+            int cookie = fd != null
+                    ? assets.addAssetFd(fd, debugPathName) : assets.addAssetPath(apkPath);
+            if (cookie == 0) {
                 throw new PackageParserException(INSTALL_PARSE_FAILED_NOT_APK,
                         "Failed to parse " + apkPath);
             }
 
-            parser = apkAssets.openXml(ANDROID_MANIFEST_FILENAME);
+            final DisplayMetrics metrics = new DisplayMetrics();
+            metrics.setToDefaults();
+
+            parser = assets.openXmlResourceParser(cookie, ANDROID_MANIFEST_FILENAME);
 
             final SigningDetails signingDetails;
             if ((flags & PARSE_COLLECT_CERTIFICATES) != 0) {
@@ -1634,7 +1635,7 @@
                     "Failed to parse " + apkPath, e);
         } finally {
             IoUtils.closeQuietly(parser);
-            IoUtils.closeQuietly(apkAssets);
+            IoUtils.closeQuietly(assets);
         }
     }
 
diff --git a/core/java/android/content/res/ApkAssets.java b/core/java/android/content/res/ApkAssets.java
deleted file mode 100644
index b087c48..0000000
--- a/core/java/android/content/res/ApkAssets.java
+++ /dev/null
@@ -1,221 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.content.res;
-
-import android.annotation.NonNull;
-
-import com.android.internal.annotations.GuardedBy;
-import com.android.internal.util.Preconditions;
-
-import java.io.FileDescriptor;
-import java.io.IOException;
-
-/**
- * The loaded, immutable, in-memory representation of an APK.
- *
- * The main implementation is native C++ and there is very little API surface exposed here. The APK
- * is mainly accessed via {@link AssetManager}.
- *
- * Since the ApkAssets instance is immutable, it can be reused and shared across AssetManagers,
- * making the creation of AssetManagers very cheap.
- * @hide
- */
-public final class ApkAssets implements AutoCloseable {
-    @GuardedBy("this") private long mNativePtr;
-    @GuardedBy("this") private StringBlock mStringBlock;
-
-    /**
-     * Creates a new ApkAssets instance from the given path on disk.
-     *
-     * @param path The path to an APK on disk.
-     * @return a new instance of ApkAssets.
-     * @throws IOException if a disk I/O error or parsing error occurred.
-     */
-    public static @NonNull ApkAssets loadFromPath(@NonNull String path) throws IOException {
-        return new ApkAssets(path, false /*system*/, false /*forceSharedLib*/, false /*overlay*/);
-    }
-
-    /**
-     * Creates a new ApkAssets instance from the given path on disk.
-     *
-     * @param path The path to an APK on disk.
-     * @param system When true, the APK is loaded as a system APK (framework).
-     * @return a new instance of ApkAssets.
-     * @throws IOException if a disk I/O error or parsing error occurred.
-     */
-    public static @NonNull ApkAssets loadFromPath(@NonNull String path, boolean system)
-            throws IOException {
-        return new ApkAssets(path, system, false /*forceSharedLib*/, false /*overlay*/);
-    }
-
-    /**
-     * Creates a new ApkAssets instance from the given path on disk.
-     *
-     * @param path The path to an APK on disk.
-     * @param system When true, the APK is loaded as a system APK (framework).
-     * @param forceSharedLibrary When true, any packages within the APK with package ID 0x7f are
-     *                           loaded as a shared library.
-     * @return a new instance of ApkAssets.
-     * @throws IOException if a disk I/O error or parsing error occurred.
-     */
-    public static @NonNull ApkAssets loadFromPath(@NonNull String path, boolean system,
-            boolean forceSharedLibrary) throws IOException {
-        return new ApkAssets(path, system, forceSharedLibrary, false /*overlay*/);
-    }
-
-    /**
-     * Creates a new ApkAssets instance from the given file descriptor. Not for use by applications.
-     *
-     * Performs a dup of the underlying fd, so you must take care of still closing
-     * the FileDescriptor yourself (and can do that whenever you want).
-     *
-     * @param fd The FileDescriptor of an open, readable APK.
-     * @param friendlyName The friendly name used to identify this ApkAssets when logging.
-     * @param system When true, the APK is loaded as a system APK (framework).
-     * @param forceSharedLibrary When true, any packages within the APK with package ID 0x7f are
-     *                           loaded as a shared library.
-     * @return a new instance of ApkAssets.
-     * @throws IOException if a disk I/O error or parsing error occurred.
-     */
-    public static @NonNull ApkAssets loadFromFd(@NonNull FileDescriptor fd,
-            @NonNull String friendlyName, boolean system, boolean forceSharedLibrary)
-            throws IOException {
-        return new ApkAssets(fd, friendlyName, system, forceSharedLibrary);
-    }
-
-    /**
-     * Creates a new ApkAssets instance from the IDMAP at idmapPath. The overlay APK path
-     * is encoded within the IDMAP.
-     *
-     * @param idmapPath Path to the IDMAP of an overlay APK.
-     * @param system When true, the APK is loaded as a system APK (framework).
-     * @return a new instance of ApkAssets.
-     * @throws IOException if a disk I/O error or parsing error occurred.
-     */
-    public static @NonNull ApkAssets loadOverlayFromPath(@NonNull String idmapPath, boolean system)
-            throws IOException {
-        return new ApkAssets(idmapPath, system, false /*forceSharedLibrary*/, true /*overlay*/);
-    }
-
-    private ApkAssets(@NonNull String path, boolean system, boolean forceSharedLib, boolean overlay)
-            throws IOException {
-        Preconditions.checkNotNull(path, "path");
-        mNativePtr = nativeLoad(path, system, forceSharedLib, overlay);
-        mStringBlock = new StringBlock(nativeGetStringBlock(mNativePtr), true /*useSparse*/);
-    }
-
-    private ApkAssets(@NonNull FileDescriptor fd, @NonNull String friendlyName, boolean system,
-            boolean forceSharedLib) throws IOException {
-        Preconditions.checkNotNull(fd, "fd");
-        Preconditions.checkNotNull(friendlyName, "friendlyName");
-        mNativePtr = nativeLoadFromFd(fd, friendlyName, system, forceSharedLib);
-        mStringBlock = new StringBlock(nativeGetStringBlock(mNativePtr), true /*useSparse*/);
-    }
-
-    @NonNull String getAssetPath() {
-        synchronized (this) {
-            ensureValidLocked();
-            return nativeGetAssetPath(mNativePtr);
-        }
-    }
-
-    CharSequence getStringFromPool(int idx) {
-        synchronized (this) {
-            ensureValidLocked();
-            return mStringBlock.get(idx);
-        }
-    }
-
-    /**
-     * Retrieve a parser for a compiled XML file. This is associated with a single APK and
-     * <em>NOT</em> a full AssetManager. This means that shared-library references will not be
-     * dynamically assigned runtime package IDs.
-     *
-     * @param fileName The path to the file within the APK.
-     * @return An XmlResourceParser.
-     * @throws IOException if the file was not found or an error occurred retrieving it.
-     */
-    public @NonNull XmlResourceParser openXml(@NonNull String fileName) throws IOException {
-        Preconditions.checkNotNull(fileName, "fileName");
-        synchronized (this) {
-            ensureValidLocked();
-            long nativeXmlPtr = nativeOpenXml(mNativePtr, fileName);
-            try (XmlBlock block = new XmlBlock(null, nativeXmlPtr)) {
-                XmlResourceParser parser = block.newParser();
-                // If nativeOpenXml doesn't throw, it will always return a valid native pointer,
-                // which makes newParser always return non-null. But let's be paranoid.
-                if (parser == null) {
-                    throw new AssertionError("block.newParser() returned a null parser");
-                }
-                return parser;
-            }
-        }
-    }
-
-    /**
-     * Returns false if the underlying APK was changed since this ApkAssets was loaded.
-     */
-    public boolean isUpToDate() {
-        synchronized (this) {
-            ensureValidLocked();
-            return nativeIsUpToDate(mNativePtr);
-        }
-    }
-
-    /**
-     * Closes the ApkAssets and destroys the underlying native implementation. Further use of the
-     * ApkAssets object will cause exceptions to be thrown.
-     *
-     * Calling close on an already closed ApkAssets does nothing.
-     */
-    @Override
-    public void close() {
-        synchronized (this) {
-            if (mNativePtr == 0) {
-                return;
-            }
-
-            mStringBlock = null;
-            nativeDestroy(mNativePtr);
-            mNativePtr = 0;
-        }
-    }
-
-    @Override
-    protected void finalize() throws Throwable {
-        if (mNativePtr != 0) {
-            nativeDestroy(mNativePtr);
-        }
-    }
-
-    private void ensureValidLocked() {
-        if (mNativePtr == 0) {
-            throw new RuntimeException("ApkAssets is closed");
-        }
-    }
-
-    private static native long nativeLoad(
-            @NonNull String path, boolean system, boolean forceSharedLib, boolean overlay)
-            throws IOException;
-    private static native long nativeLoadFromFd(@NonNull FileDescriptor fd,
-            @NonNull String friendlyName, boolean system, boolean forceSharedLib)
-            throws IOException;
-    private static native void nativeDestroy(long ptr);
-    private static native @NonNull String nativeGetAssetPath(long ptr);
-    private static native long nativeGetStringBlock(long ptr);
-    private static native boolean nativeIsUpToDate(long ptr);
-    private static native long nativeOpenXml(long ptr, @NonNull String fileName) throws IOException;
-}
diff --git a/core/java/android/content/res/AssetManager.java b/core/java/android/content/res/AssetManager.java
index 78370f4..7866560 100644
--- a/core/java/android/content/res/AssetManager.java
+++ b/core/java/android/content/res/AssetManager.java
@@ -18,11 +18,9 @@
 
 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;
@@ -30,18 +28,10 @@
 import android.util.SparseArray;
 import android.util.TypedValue;
 
-import com.android.internal.annotations.GuardedBy;
-import com.android.internal.util.Preconditions;
-
-import java.io.BufferedReader;
-import java.io.FileInputStream;
+import java.io.FileDescriptor;
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.nio.channels.FileLock;
-import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.HashMap;
 
 /**
@@ -52,17 +42,7 @@
  * bytes.
  */
 public final class AssetManager implements AutoCloseable {
-    private static final String TAG = "AssetManager";
-    private static final boolean DEBUG_REFS = false;
-
-    private static final String FRAMEWORK_APK_PATH = "/system/framework/framework-res.apk";
-
-    private static final Object sSync = new Object();
-
-    // Not private for LayoutLib's BridgeAssetManager.
-    @GuardedBy("sSync") static AssetManager sSystem = null;
-
-    @GuardedBy("sSync") private static ApkAssets[] sSystemApkAssets = new ApkAssets[0];
+    /* modes used when opening an asset */
 
     /**
      * Mode for {@link #open(String, int)}: no specific information about how
@@ -85,279 +65,87 @@
      */
     public static final int ACCESS_BUFFER = 3;
 
-    @GuardedBy("this") private final TypedValue mValue = new TypedValue();
-    @GuardedBy("this") private final long[] mOffsets = new long[2];
+    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;
 
-    // Pointer to native implementation, stuffed inside a long.
-    @GuardedBy("this") private long mObject;
+    private final TypedValue mValue = new TypedValue();
+    private final long[] mOffsets = new long[2];
+    
+    // For communication with native code.
+    private long mObject;
 
-    // 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;
-
+    private StringBlock mStringBlocks[] = null;
+    
+    private int mNumRefs = 1;
+    private boolean mOpen = true;
+    private HashMap<Long, RuntimeException> mRefStacks;
+ 
     /**
      * Create a new AssetManager containing only the basic system assets.
      * Applications will not generally use this method, instead retrieving the
      * appropriate asset manager with {@link Resources#getAssets}.    Not for
      * use by applications.
-     * @hide
+     * {@hide}
      */
     public AssetManager() {
-        final ApkAssets[] assets;
-        synchronized (sSync) {
-            createSystemAssetsInZygoteLocked();
-            assets = sSystemApkAssets;
-        }
-
-        mObject = nativeCreate();
-        if (DEBUG_REFS) {
-            mNumRefs = 0;
-            incRefsLocked(hashCode());
-        }
-
-        // Always set the framework resources.
-        setApkAssets(assets, false /*invalidateCaches*/);
-    }
-
-    /**
-     * Private constructor that doesn't call ensureSystemAssets.
-     * Used for the creation of system assets.
-     */
-    @SuppressWarnings("unused")
-    private AssetManager(boolean sentinel) {
-        mObject = nativeCreate();
-        if (DEBUG_REFS) {
-            mNumRefs = 0;
-            incRefsLocked(hashCode());
-        }
-    }
-
-    /**
-     * This must be called from Zygote so that system assets are shared by all applications.
-     * @hide
-     */
-    private static void createSystemAssetsInZygoteLocked() {
-        if (sSystem != null) {
-            return;
-        }
-
-        // Make sure that all IDMAPs are up to date.
-        nativeVerifySystemIdmaps();
-
-        try {
-            ArrayList<ApkAssets> apkAssets = new ArrayList<>();
-            apkAssets.add(ApkAssets.loadFromPath(FRAMEWORK_APK_PATH, true /*system*/));
-
-            // 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*/));
-                    }
-                }
+        synchronized (this) {
+            if (DEBUG_REFS) {
+                mNumRefs = 0;
+                incRefsLocked(this.hashCode());
             }
-
-            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(false);
+            if (localLOGV) Log.v(TAG, "New asset manager: " + this);
+            ensureSystemAssets();
         }
     }
 
+    private static void ensureSystemAssets() {
+        synchronized (sSync) {
+            if (sSystem == null) {
+                AssetManager system = new AssetManager(true);
+                system.makeStringBlocks(null);
+                sSystem = system;
+            }
+        }
+    }
+    
+    private AssetManager(boolean isSystem) {
+        if (DEBUG_REFS) {
+            synchronized (this) {
+                mNumRefs = 0;
+                incRefsLocked(this.hashCode());
+            }
+        }
+        init(true);
+        if (localLOGV) Log.v(TAG, "New asset manager: " + this);
+    }
+
     /**
      * Return a global shared asset manager that provides access to only
      * system assets (no application assets).
-     * @hide
+     * {@hide}
      */
     public static AssetManager getSystem() {
-        synchronized (sSync) {
-            createSystemAssetsInZygoteLocked();
-            return sSystem;
-        }
+        ensureSystemAssets();
+        return sSystem;
     }
 
     /**
      * Close this asset manager.
      */
-    @Override
     public void close() {
-        synchronized (this) {
-            if (!mOpen) {
-                return;
+        synchronized(this) {
+            //System.out.println("Release: num=" + mNumRefs
+            //                   + ", released=" + mReleased);
+            if (mOpen) {
+                mOpen = false;
+                decRefsLocked(this.hashCode());
             }
-
-            mOpen = false;
-            decRefsLocked(hashCode());
-        }
-    }
-
-    /**
-     * Changes the asset paths in this AssetManager. This replaces the {@link #addAssetPath(String)}
-     * family of methods.
-     *
-     * @param apkAssets The new set of paths.
-     * @param invalidateCaches Whether to invalidate any caches. This should almost always be true.
-     *                         Set this to false if you are appending new resources
-     *                         (not new configurations).
-     * @hide
-     */
-    public void setApkAssets(@NonNull ApkAssets[] apkAssets, boolean invalidateCaches) {
-        Preconditions.checkNotNull(apkAssets, "apkAssets");
-        synchronized (this) {
-            ensureValidLocked();
-            mApkAssets = apkAssets;
-            nativeSetApkAssets(mObject, apkAssets, invalidateCaches);
-            if (invalidateCaches) {
-                // Invalidate all caches.
-                invalidateCachesLocked(-1);
-            }
-        }
-    }
-
-    /**
-     * Invalidates the caches in this AssetManager according to the bitmask `diff`.
-     *
-     * @param diff The bitmask of changes generated by {@link Configuration#diff(Configuration)}.
-     * @see ActivityInfo.Config
-     */
-    private void invalidateCachesLocked(int diff) {
-        // TODO(adamlesinski): Currently there are no caches to invalidate in Java code.
-    }
-
-    /**
-     * @hide
-     */
-    public @NonNull ApkAssets[] getApkAssets() {
-        synchronized (this) {
-            ensureValidLocked();
-            return mApkAssets;
-        }
-    }
-
-    /**
-     * @deprecated Use {@link #setApkAssets(ApkAssets[], boolean)}
-     * @hide
-     */
-    @Deprecated
-    public int addAssetPath(String path) {
-        return addAssetPathInternal(path, false /*overlay*/, false /*appAsLib*/);
-    }
-
-    /**
-     * @deprecated Use {@link #setApkAssets(ApkAssets[], boolean)}
-     * @hide
-     */
-    @Deprecated
-    public int addAssetPathAsSharedLibrary(String path) {
-        return addAssetPathInternal(path, false /*overlay*/, true /*appAsLib*/);
-    }
-
-    /**
-     * @deprecated Use {@link #setApkAssets(ApkAssets[], boolean)}
-     * @hide
-     */
-    @Deprecated
-    public int addOverlayPath(String path) {
-        return addAssetPathInternal(path, true /*overlay*/, false /*appAsLib*/);
-    }
-
-    private int addAssetPathInternal(String path, boolean overlay, boolean appAsLib) {
-        Preconditions.checkNotNull(path, "path");
-        synchronized (this) {
-            ensureOpenLocked();
-            final int count = mApkAssets.length;
-            for (int i = 0; i < count; i++) {
-                if (mApkAssets[i].getAssetPath().equals(path)) {
-                    return i + 1;
-                }
-            }
-
-            final ApkAssets assets;
-            try {
-                if (overlay) {
-                    // TODO(b/70343104): This hardcoded path will be removed once
-                    // addAssetPathInternal is deleted.
-                    final String idmapPath = "/data/resource-cache/"
-                            + path.substring(1).replace('/', '@')
-                            + "@idmap";
-                    assets = ApkAssets.loadOverlayFromPath(idmapPath, false /*system*/);
-                } else {
-                    assets = ApkAssets.loadFromPath(path, false /*system*/, appAsLib);
-                }
-            } catch (IOException e) {
-                return 0;
-            }
-
-            final ApkAssets[] newApkAssets = Arrays.copyOf(mApkAssets, count + 1);
-            newApkAssets[count] = assets;
-            setApkAssets(newApkAssets, true);
-            return count + 1;
-        }
-    }
-
-    /**
-     * Ensures that the native implementation has not been destroyed.
-     * The AssetManager may have been closed, but references to it still exist
-     * and therefore the native implementation is not destroyed.
-     */
-    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");
-        }
-    }
-
-    /**
-     * Populates {@code outValue} with the data associated a particular
-     * resource identifier for the current configuration.
-     *
-     * @param resId the resource identifier to load
-     * @param densityDpi the density bucket for which to load the resource
-     * @param outValue the typed value in which to put the data
-     * @param resolveRefs {@code true} to resolve references, {@code false}
-     *                    to leave them unresolved
-     * @return {@code true} if the data was loaded into {@code outValue},
-     *         {@code false} otherwise
-     */
-    boolean getResourceValue(@AnyRes int resId, int densityDpi, @NonNull TypedValue outValue,
-            boolean resolveRefs) {
-        Preconditions.checkNotNull(outValue, "outValue");
-        synchronized (this) {
-            ensureValidLocked();
-            final int cookie = nativeGetResourceValue(
-                    mObject, resId, (short) densityDpi, outValue, resolveRefs);
-            if (cookie <= 0) {
-                return false;
-            }
-
-            // Convert the changing configurations flags populated by native code.
-            outValue.changingConfigurations = ActivityInfo.activityInfoConfigNativeToJava(
-                    outValue.changingConfigurations);
-
-            if (outValue.type == TypedValue.TYPE_STRING) {
-                outValue.string = mApkAssets[cookie - 1].getStringFromPool(outValue.data);
-            }
-            return true;
         }
     }
 
@@ -368,7 +156,8 @@
      * @param resId the resource identifier to load
      * @return the string value, or {@code null}
      */
-    @Nullable CharSequence getResourceText(@StringRes int resId) {
+    @Nullable
+    final CharSequence getResourceText(@StringRes int resId) {
         synchronized (this) {
             final TypedValue outValue = mValue;
             if (getResourceValue(resId, 0, outValue, true)) {
@@ -383,15 +172,15 @@
      * identifier for the current configuration.
      *
      * @param resId the resource identifier to load
-     * @param bagEntryId the index into the bag to load
+     * @param bagEntryId
      * @return the string value, or {@code null}
      */
-    @Nullable CharSequence getResourceBagText(@StringRes int resId, int bagEntryId) {
+    @Nullable
+    final CharSequence getResourceBagText(@StringRes int resId, int bagEntryId) {
         synchronized (this) {
-            ensureValidLocked();
             final TypedValue outValue = mValue;
-            final int cookie = nativeGetResourceBagValue(mObject, resId, bagEntryId, outValue);
-            if (cookie <= 0) {
+            final int block = loadResourceBagValue(resId, bagEntryId, outValue, true);
+            if (block < 0) {
                 return null;
             }
 
@@ -400,49 +189,12 @@
                     outValue.changingConfigurations);
 
             if (outValue.type == TypedValue.TYPE_STRING) {
-                return mApkAssets[cookie - 1].getStringFromPool(outValue.data);
+                return mStringBlocks[block].get(outValue.data);
             }
             return outValue.coerceToString();
         }
     }
 
-    int getResourceArraySize(@ArrayRes int resId) {
-        synchronized (this) {
-            ensureValidLocked();
-            return nativeGetResourceArraySize(mObject, resId);
-        }
-    }
-
-    /**
-     * Populates `outData` with array elements of `resId`. `outData` is normally
-     * used with
-     * {@link TypedArray}.
-     *
-     * Each logical element in `outData` is {@link TypedArray#STYLE_NUM_ENTRIES}
-     * long,
-     * with the indices of the data representing the type, value, asset cookie,
-     * resource ID,
-     * configuration change mask, and density of the element.
-     *
-     * @param resId The resource ID of an array resource.
-     * @param outData The array to populate with data.
-     * @return The length of the array.
-     *
-     * @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.
@@ -450,10 +202,39 @@
      * @param resId the resource identifier of the string array
      * @return the string array, or {@code null}
      */
-    @Nullable String[] getResourceStringArray(@ArrayRes int resId) {
+    @Nullable
+    final String[] getResourceStringArray(@ArrayRes int resId) {
+        return getArrayStringResource(resId);
+    }
+
+    /**
+     * Populates {@code outValue} with the data associated a particular
+     * resource identifier for the current configuration.
+     *
+     * @param resId the resource identifier to load
+     * @param densityDpi the density bucket for which to load the resource
+     * @param outValue the typed value in which to put the data
+     * @param resolveRefs {@code true} to resolve references, {@code false}
+     *                    to leave them unresolved
+     * @return {@code true} if the data was loaded into {@code outValue},
+     *         {@code false} otherwise
+     */
+    final boolean getResourceValue(@AnyRes int resId, int densityDpi, @NonNull TypedValue outValue,
+            boolean resolveRefs) {
         synchronized (this) {
-            ensureValidLocked();
-            return nativeGetResourceStringArray(mObject, resId);
+            final int block = loadResourceValue(resId, (short) densityDpi, outValue, resolveRefs);
+            if (block < 0) {
+                return false;
+            }
+
+            // Convert the changing configurations flags populated by native code.
+            outValue.changingConfigurations = ActivityInfo.activityInfoConfigNativeToJava(
+                    outValue.changingConfigurations);
+
+            if (outValue.type == TypedValue.TYPE_STRING) {
+                outValue.string = mStringBlocks[block].get(outValue.data);
+            }
+            return true;
         }
     }
 
@@ -463,48 +244,26 @@
      *
      * @param resId the resource id of the string array
      */
-    @Nullable CharSequence[] getResourceTextArray(@ArrayRes int resId) {
+    final @Nullable CharSequence[] getResourceTextArray(@ArrayRes int resId) {
         synchronized (this) {
-            ensureValidLocked();
-            final int[] rawInfoArray = nativeGetResourceStringArrayInfo(mObject, resId);
+            final int[] rawInfoArray = getArrayStringInfo(resId);
             if (rawInfoArray == null) {
                 return null;
             }
-
             final int rawInfoArrayLen = rawInfoArray.length;
             final int infoArrayLen = rawInfoArrayLen / 2;
+            int block;
+            int index;
             final CharSequence[] retArray = new CharSequence[infoArrayLen];
             for (int i = 0, j = 0; i < rawInfoArrayLen; i = i + 2, j++) {
-                int cookie = rawInfoArray[i];
-                int index = rawInfoArray[i + 1];
-                retArray[j] = (index >= 0 && cookie > 0)
-                        ? mApkAssets[cookie - 1].getStringFromPool(index) : null;
+                block = rawInfoArray[i];
+                index = rawInfoArray[i + 1];
+                retArray[j] = index >= 0 ? mStringBlocks[block].get(index) : null;
             }
             return retArray;
         }
     }
 
-    @Nullable int[] getResourceIntArray(@ArrayRes int resId) {
-        synchronized (this) {
-            ensureValidLocked();
-            return nativeGetResourceIntArray(mObject, resId);
-        }
-    }
-
-    /**
-     * Get the attributes for a style resource. These are the &lt;item&gt;
-     * elements in
-     * a &lt;style&gt; resource.
-     * @param resId The resource ID of the style
-     * @return An array of attribute IDs.
-     */
-    @AttrRes int[] getStyleAttributes(@StyleRes int resId) {
-        synchronized (this) {
-            ensureValidLocked();
-            return nativeGetStyleAttributes(mObject, resId);
-        }
-    }
-
     /**
      * Populates {@code outValue} with the data associated with a particular
      * resource identifier for the current configuration. Resolves theme
@@ -518,88 +277,73 @@
      * @return {@code true} if the data was loaded into {@code outValue},
      *         {@code false} otherwise
      */
-    boolean getThemeValue(long theme, @AnyRes int resId, @NonNull TypedValue outValue,
+    final boolean getThemeValue(long theme, @AnyRes int resId, @NonNull TypedValue outValue,
             boolean resolveRefs) {
-        Preconditions.checkNotNull(outValue, "outValue");
+        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() {
         synchronized (this) {
-            ensureValidLocked();
-            final int cookie = nativeThemeGetAttributeValue(mObject, theme, resId, outValue,
-                    resolveRefs);
-            if (cookie <= 0) {
-                return false;
+            if (mStringBlocks == null) {
+                makeStringBlocks(sSystem.mStringBlocks);
             }
+            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);
+    /*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);
             }
-            return true;
         }
     }
 
-    void dumpTheme(long theme, int priority, String tag, String prefix) {
+    /*package*/ final CharSequence getPooledStringForCookie(int cookie, int id) {
         synchronized (this) {
-            ensureValidLocked();
-            nativeThemeDump(mObject, theme, priority, tag, prefix);
+            // Cookies map to string blocks starting at 1.
+            return mStringBlocks[cookie - 1].get(id);
         }
     }
 
-    @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 @NonNull InputStream open(@NonNull String fileName) throws IOException {
+    public final InputStream open(String fileName) throws IOException {
         return open(fileName, ACCESS_STREAMING);
     }
 
@@ -609,7 +353,8 @@
      * 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
@@ -619,40 +364,34 @@
      * @see #open(String)
      * @see #list
      */
-    public @NonNull InputStream open(@NonNull String fileName, int accessMode) throws IOException {
-        Preconditions.checkNotNull(fileName, "fileName");
+    public final InputStream open(String fileName, int accessMode)
+        throws IOException {
         synchronized (this) {
-            ensureOpenLocked();
-            final long asset = nativeOpenAsset(mObject, fileName, accessMode);
-            if (asset == 0) {
-                throw new FileNotFoundException("Asset file: " + fileName);
+            if (!mOpen) {
+                throw new RuntimeException("Assetmanager has been closed");
             }
-            final AssetInputStream assetInputStream = new AssetInputStream(asset);
-            incRefsLocked(assetInputStream.hashCode());
-            return assetInputStream;
+            long asset = openAsset(fileName, accessMode);
+            if (asset != 0) {
+                AssetInputStream res = new AssetInputStream(asset);
+                incRefsLocked(res.hashCode());
+                return res;
+            }
         }
+        throw new FileNotFoundException("Asset file: " + fileName);
     }
 
-    /**
-     * Open an uncompressed asset by mmapping it and returning an {@link AssetFileDescriptor}.
-     * This provides access to files that have been bundled with an application as assets -- that
-     * is, files placed in to the "assets" directory.
-     *
-     * The asset must be uncompressed, or an exception will be thrown.
-     *
-     * @param fileName The name of the asset to open.  This name can be hierarchical.
-     * @return An open AssetFileDescriptor.
-     */
-    public @NonNull AssetFileDescriptor openFd(@NonNull String fileName) throws IOException {
-        Preconditions.checkNotNull(fileName, "fileName");
+    public final AssetFileDescriptor openFd(String fileName)
+            throws IOException {
         synchronized (this) {
-            ensureOpenLocked();
-            final ParcelFileDescriptor pfd = nativeOpenAssetFd(mObject, fileName, mOffsets);
-            if (pfd == null) {
-                throw new FileNotFoundException("Asset file: " + fileName);
+            if (!mOpen) {
+                throw new RuntimeException("Assetmanager has been closed");
             }
-            return new AssetFileDescriptor(pfd, mOffsets[0], mOffsets[1]);
+            ParcelFileDescriptor pfd = openAssetFd(fileName, mOffsets);
+            if (pfd != null) {
+                return new AssetFileDescriptor(pfd, mOffsets[0], mOffsets[1]);
+            }
         }
+        throw new FileNotFoundException("Asset file: " + fileName);
     }
 
     /**
@@ -667,121 +406,90 @@
      * 
      * @see #open
      */
-    public @Nullable String[] list(@NonNull String path) throws IOException {
-        Preconditions.checkNotNull(path, "path");
-        synchronized (this) {
-            ensureValidLocked();
-            return nativeList(mObject, path);
-        }
-    }
+    public native final String[] list(String path)
+        throws IOException;
 
     /**
+     * {@hide}
      * Open a non-asset file as an asset using ACCESS_STREAMING mode.  This
      * provides direct access to all of the files included in an application
      * package (not only its assets).  Applications should not normally use
      * this.
-     *
-     * @param fileName Name of the asset to retrieve.
-     *
+     * 
      * @see #open(String)
-     * @hide
      */
-    public @NonNull InputStream openNonAsset(@NonNull String fileName) throws IOException {
+    public final InputStream openNonAsset(String fileName) throws IOException {
         return openNonAsset(0, fileName, ACCESS_STREAMING);
     }
 
     /**
+     * {@hide}
      * Open a non-asset file as an asset using a specific access mode.  This
      * provides direct access to all of the files included in an application
      * package (not only its assets).  Applications should not normally use
      * this.
-     *
-     * @param fileName Name of the asset to retrieve.
-     * @param accessMode Desired access mode for retrieving the data.
-     *
-     * @see #ACCESS_UNKNOWN
-     * @see #ACCESS_STREAMING
-     * @see #ACCESS_RANDOM
-     * @see #ACCESS_BUFFER
+     * 
      * @see #open(String, int)
-     * @hide
      */
-    public @NonNull InputStream openNonAsset(@NonNull String fileName, int accessMode)
-            throws IOException {
+    public final InputStream openNonAsset(String fileName, int accessMode)
+        throws IOException {
         return openNonAsset(0, fileName, accessMode);
     }
 
     /**
+     * {@hide}
      * Open a non-asset in a specified package.  Not for use by applications.
-     *
+     * 
      * @param cookie Identifier of the package to be opened.
      * @param fileName Name of the asset to retrieve.
-     * @hide
      */
-    public @NonNull InputStream openNonAsset(int cookie, @NonNull String fileName)
-            throws IOException {
+    public final InputStream openNonAsset(int cookie, String fileName)
+        throws IOException {
         return openNonAsset(cookie, fileName, ACCESS_STREAMING);
     }
 
     /**
+     * {@hide}
      * Open a non-asset in a specified package.  Not for use by applications.
-     *
+     * 
      * @param cookie Identifier of the package to be opened.
      * @param fileName Name of the asset to retrieve.
      * @param accessMode Desired access mode for retrieving the data.
-     * @hide
      */
-    public @NonNull InputStream openNonAsset(int cookie, @NonNull String fileName, int accessMode)
-            throws IOException {
-        Preconditions.checkNotNull(fileName, "fileName");
+    public final InputStream openNonAsset(int cookie, String fileName, int accessMode)
+        throws IOException {
         synchronized (this) {
-            ensureOpenLocked();
-            final long asset = nativeOpenNonAsset(mObject, cookie, fileName, accessMode);
-            if (asset == 0) {
-                throw new FileNotFoundException("Asset absolute file: " + fileName);
+            if (!mOpen) {
+                throw new RuntimeException("Assetmanager has been closed");
             }
-            final AssetInputStream assetInputStream = new AssetInputStream(asset);
-            incRefsLocked(assetInputStream.hashCode());
-            return assetInputStream;
+            long asset = openNonAssetNative(cookie, fileName, accessMode);
+            if (asset != 0) {
+                AssetInputStream res = new AssetInputStream(asset);
+                incRefsLocked(res.hashCode());
+                return res;
+            }
         }
+        throw new FileNotFoundException("Asset absolute file: " + fileName);
     }
 
-    /**
-     * Open a non-asset as an asset by mmapping it and returning an {@link AssetFileDescriptor}.
-     * This provides direct access to all of the files included in an application
-     * package (not only its assets).  Applications should not normally use this.
-     *
-     * The asset must not be compressed, or an exception will be thrown.
-     *
-     * @param fileName Name of the asset to retrieve.
-     */
-    public @NonNull AssetFileDescriptor openNonAssetFd(@NonNull String fileName)
+    public final AssetFileDescriptor openNonAssetFd(String fileName)
             throws IOException {
         return openNonAssetFd(0, fileName);
     }
-
-    /**
-     * Open a non-asset as an asset by mmapping it and returning an {@link AssetFileDescriptor}.
-     * This provides direct access to all of the files included in an application
-     * package (not only its assets).  Applications should not normally use this.
-     *
-     * The asset must not be compressed, or an exception will be thrown.
-     *
-     * @param cookie Identifier of the package to be opened.
-     * @param fileName Name of the asset to retrieve.
-     */
-    public @NonNull AssetFileDescriptor openNonAssetFd(int cookie, @NonNull String fileName)
-            throws IOException {
-        Preconditions.checkNotNull(fileName, "fileName");
+    
+    public final AssetFileDescriptor openNonAssetFd(int cookie,
+            String fileName) throws IOException {
         synchronized (this) {
-            ensureOpenLocked();
-            final ParcelFileDescriptor pfd =
-                    nativeOpenNonAssetFd(mObject, cookie, fileName, mOffsets);
-            if (pfd == null) {
-                throw new FileNotFoundException("Asset absolute file: " + fileName);
+            if (!mOpen) {
+                throw new RuntimeException("Assetmanager has been closed");
             }
-            return new AssetFileDescriptor(pfd, mOffsets[0], mOffsets[1]);
+            ParcelFileDescriptor pfd = openNonAssetFdNative(cookie,
+                    fileName, mOffsets);
+            if (pfd != null) {
+                return new AssetFileDescriptor(pfd, mOffsets[0], mOffsets[1]);
+            }
         }
+        throw new FileNotFoundException("Asset absolute file: " + fileName);
     }
     
     /**
@@ -789,7 +497,7 @@
      * 
      * @param fileName The name of the file to retrieve.
      */
-    public @NonNull XmlResourceParser openXmlResourceParser(@NonNull String fileName)
+    public final XmlResourceParser openXmlResourceParser(String fileName)
             throws IOException {
         return openXmlResourceParser(0, fileName);
     }
@@ -800,265 +508,270 @@
      * @param cookie Identifier of the package to be opened.
      * @param fileName The name of the file to retrieve.
      */
-    public @NonNull XmlResourceParser openXmlResourceParser(int cookie, @NonNull String fileName)
-            throws IOException {
-        try (XmlBlock block = openXmlBlockAsset(cookie, fileName)) {
-            XmlResourceParser parser = block.newParser();
-            // If openXmlBlockAsset doesn't throw, it will always return an XmlBlock object with
-            // a valid native pointer, which makes newParser always return non-null. But let's
-            // be paranoid.
-            if (parser == null) {
-                throw new AssertionError("block.newParser() returned a null parser");
-            }
-            return parser;
-        }
+    public final XmlResourceParser openXmlResourceParser(int cookie,
+            String fileName) throws IOException {
+        XmlBlock block = openXmlBlockAsset(cookie, fileName);
+        XmlResourceParser rp = block.newParser();
+        block.close();
+        return rp;
     }
 
     /**
-     * Retrieve a non-asset as a compiled XML file.  Not for use by applications.
+     * {@hide}
+     * Retrieve a non-asset as a compiled XML file.  Not for use by
+     * applications.
      * 
      * @param fileName The name of the file to retrieve.
-     * @hide
      */
-    @NonNull XmlBlock openXmlBlockAsset(@NonNull String fileName) throws IOException {
+    /*package*/ final XmlBlock openXmlBlockAsset(String fileName)
+            throws IOException {
         return openXmlBlockAsset(0, fileName);
     }
 
     /**
+     * {@hide}
      * Retrieve a non-asset as a compiled XML file.  Not for use by
      * applications.
      * 
      * @param cookie Identifier of the package to be opened.
      * @param fileName Name of the asset to retrieve.
-     * @hide
      */
-    @NonNull XmlBlock openXmlBlockAsset(int cookie, @NonNull String fileName) throws IOException {
-        Preconditions.checkNotNull(fileName, "fileName");
+    /*package*/ final XmlBlock openXmlBlockAsset(int cookie, String fileName)
+        throws IOException {
         synchronized (this) {
-            ensureOpenLocked();
-            final long xmlBlock = nativeOpenXmlAsset(mObject, cookie, fileName);
-            if (xmlBlock == 0) {
-                throw new FileNotFoundException("Asset XML file: " + fileName);
+            if (!mOpen) {
+                throw new RuntimeException("Assetmanager has been closed");
             }
-            final XmlBlock block = new XmlBlock(this, xmlBlock);
-            incRefsLocked(block.hashCode());
-            return block;
+            long xmlBlock = openXmlAssetNative(cookie, fileName);
+            if (xmlBlock != 0) {
+                XmlBlock res = new XmlBlock(this, xmlBlock);
+                incRefsLocked(res.hashCode());
+                return res;
+            }
         }
+        throw new FileNotFoundException("Asset XML file: " + fileName);
     }
 
-    void xmlBlockGone(int id) {
+    /*package*/ void xmlBlockGone(int id) {
         synchronized (this) {
             decRefsLocked(id);
         }
     }
 
-    void applyStyle(long themePtr, @AttrRes int defStyleAttr, @StyleRes int defStyleRes,
-            @Nullable XmlBlock.Parser parser, @NonNull int[] inAttrs, long outValuesAddress,
-            long outIndicesAddress) {
-        Preconditions.checkNotNull(inAttrs, "inAttrs");
+    /*package*/ final long createTheme() {
         synchronized (this) {
-            // Need to synchronize on AssetManager because we will be accessing
-            // the native implementation of AssetManager.
-            ensureValidLocked();
-            nativeApplyStyle(mObject, themePtr, defStyleAttr, defStyleRes,
-                    parser != null ? parser.mParseState : 0, inAttrs, outValuesAddress,
-                    outIndicesAddress);
+            if (!mOpen) {
+                throw new RuntimeException("Assetmanager has been closed");
+            }
+            long res = newTheme();
+            incRefsLocked(res);
+            return res;
         }
     }
 
-    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");
+    /*package*/ final void releaseTheme(long theme) {
         synchronized (this) {
-            // Need to synchronize on AssetManager because we will be accessing
-            // the native implementation of AssetManager.
-            ensureValidLocked();
-            return nativeResolveAttrs(mObject,
-                    themePtr, defStyleAttr, defStyleRes, inValues, inAttrs, outValues, outIndices);
+            deleteTheme(theme);
+            decRefsLocked(theme);
         }
     }
 
-    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 {
-        if (DEBUG_REFS && mNumRefs != 0) {
-            Log.w(TAG, "AssetManager " + this + " finalized with non-zero refs: " + mNumRefs);
-            if (mRefStacks != null) {
-                for (RuntimeException e : mRefStacks.values()) {
-                    Log.w(TAG, "Reference from here", e);
+        try {
+            if (DEBUG_REFS && mNumRefs != 0) {
+                Log.w(TAG, "AssetManager " + this
+                        + " finalized with non-zero refs: " + mNumRefs);
+                if (mRefStacks != null) {
+                    for (RuntimeException e : mRefStacks.values()) {
+                        Log.w(TAG, "Reference from here", e);
+                    }
                 }
             }
-        }
-
-        if (mObject != 0) {
-            nativeDestroy(mObject);
+            destroy();
+        } finally {
+            super.finalize();
         }
     }
-
-    /* No Locking is needed for AssetInputStream because an AssetInputStream is not-thread
-    safe and it does not rely on AssetManager once it has been created. It completely owns the
-    underlying Asset. */
+    
     public final class AssetInputStream extends InputStream {
-        private long mAssetNativePtr;
-        private long mLength;
-        private long mMarkPos;
-
         /**
          * @hide
          */
         public final int getAssetInt() {
             throw new UnsupportedOperationException();
         }
-
         /**
          * @hide
          */
         public final long getNativeAsset() {
-            return mAssetNativePtr;
+            return mAsset;
         }
-
-        private AssetInputStream(long assetNativePtr) {
-            mAssetNativePtr = assetNativePtr;
-            mLength = nativeAssetGetLength(assetNativePtr);
+        private AssetInputStream(long asset)
+        {
+            mAsset = asset;
+            mLength = getAssetLength(asset);
         }
-
-        @Override
         public final int read() throws IOException {
-            ensureOpen();
-            return nativeAssetReadChar(mAssetNativePtr);
+            return readAssetChar(mAsset);
         }
-
-        @Override
-        public final int read(@NonNull byte[] b) throws IOException {
-            ensureOpen();
-            Preconditions.checkNotNull(b, "b");
-            return nativeAssetRead(mAssetNativePtr, b, 0, b.length);
-        }
-
-        @Override
-        public final int read(@NonNull byte[] b, int off, int len) throws IOException {
-            ensureOpen();
-            Preconditions.checkNotNull(b, "b");
-            return nativeAssetRead(mAssetNativePtr, b, off, len);
-        }
-
-        @Override
-        public final long skip(long n) throws IOException {
-            ensureOpen();
-            long pos = nativeAssetSeek(mAssetNativePtr, 0, 0);
-            if ((pos + n) > mLength) {
-                n = mLength - pos;
-            }
-            if (n > 0) {
-                nativeAssetSeek(mAssetNativePtr, n, 0);
-            }
-            return n;
-        }
-
-        @Override
-        public final int available() throws IOException {
-            ensureOpen();
-            final long len = nativeAssetGetRemainingLength(mAssetNativePtr);
-            return len > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) len;
-        }
-
-        @Override
         public final boolean markSupported() {
             return true;
         }
-
-        @Override
-        public final void mark(int readlimit) {
-            ensureOpen();
-            mMarkPos = nativeAssetSeek(mAssetNativePtr, 0, 0);
+        public final int available() throws IOException {
+            long len = getAssetRemainingLength(mAsset);
+            return len > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int)len;
         }
-
-        @Override
-        public final void reset() throws IOException {
-            ensureOpen();
-            nativeAssetSeek(mAssetNativePtr, mMarkPos, -1);
-        }
-
-        @Override
         public final void close() throws IOException {
-            if (mAssetNativePtr != 0) {
-                nativeAssetDestroy(mAssetNativePtr);
-                mAssetNativePtr = 0;
-
-                synchronized (AssetManager.this) {
+            synchronized (AssetManager.this) {
+                if (mAsset != 0) {
+                    destroyAsset(mAsset);
+                    mAsset = 0;
                     decRefsLocked(hashCode());
                 }
             }
         }
+        public final void mark(int readlimit) {
+            mMarkPos = seekAsset(mAsset, 0, 0);
+        }
+        public final void reset() throws IOException {
+            seekAsset(mAsset, mMarkPos, -1);
+        }
+        public final int read(byte[] b) throws IOException {
+            return readAsset(mAsset, b, 0, b.length);
+        }
+        public final int read(byte[] b, int off, int len) throws IOException {
+            return readAsset(mAsset, b, off, len);
+        }
+        public final long skip(long n) throws IOException {
+            long pos = seekAsset(mAsset, 0, 0);
+            if ((pos+n) > mLength) {
+                n = mLength-pos;
+            }
+            if (n > 0) {
+                seekAsset(mAsset, n, 0);
+            }
+            return n;
+        }
 
-        @Override
-        protected void finalize() throws Throwable {
+        protected void finalize() throws Throwable
+        {
             close();
         }
 
-        private void ensureOpen() {
-            if (mAssetNativePtr == 0) {
-                throw new IllegalStateException("AssetInputStream is closed");
-            }
+        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 boolean isUpToDate() {
-        for (ApkAssets apkAssets : getApkAssets()) {
-            if (!apkAssets.isUpToDate()) {
-                return false;
-            }
-        }
-        return true;
-    }
+    public native final boolean isUpToDate();
 
     /**
      * Get the locales that this asset manager contains data for.
@@ -1071,12 +784,7 @@
      * are of the form {@code ll_CC} where {@code ll} is a two letter language code,
      * and {@code CC} is a two letter country code.
      */
-    public String[] getLocales() {
-        synchronized (this) {
-            ensureValidLocked();
-            return nativeGetLocales(mObject, false /*excludeSystem*/);
-        }
-    }
+    public native final String[] getLocales();
 
     /**
      * Same as getLocales(), except that locales that are only provided by the system (i.e. those
@@ -1086,57 +794,131 @@
      * assets support Cherokee and French, getLocales() would return
      * [Cherokee, English, French, German], while getNonSystemLocales() would return
      * [Cherokee, French].
-     * @hide
+     * {@hide}
      */
-    public String[] getNonSystemLocales() {
-        synchronized (this) {
-            ensureValidLocked();
-            return nativeGetLocales(mObject, true /*excludeSystem*/);
-        }
-    }
+    public native final String[] getNonSystemLocales();
+
+    /** {@hide} */
+    public native final Configuration[] getSizeConfigurations();
 
     /**
-     * @hide
-     */
-    Configuration[] getSizeConfigurations() {
-        synchronized (this) {
-            ensureValidLocked();
-            return nativeGetSizeConfigurations(mObject);
-        }
-    }
-
-    /**
-     * Change the configuration used when retrieving resources.  Not for use by
+     * Change the configuation used when retrieving resources.  Not for use by
      * applications.
-     * @hide
+     * {@hide}
      */
-    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);
-        }
-    }
+    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);
 
     /**
-     * @hide
+     * Retrieve the resource identifier for the given resource name.
      */
-    public SparseArray<String> getAssignedPackageIdentifiers() {
-        synchronized (this) {
-            ensureValidLocked();
-            return nativeGetAssignedPackageIdentifiers(mObject);
-        }
-    }
+    /*package*/ native final int getResourceIdentifier(String name,
+                                                       String defType,
+                                                       String defPackage);
 
-    private void incRefsLocked(long id) {
+    /*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) {
         if (DEBUG_REFS) {
             if (mRefStacks == null) {
-                mRefStacks = new HashMap<>();
+                mRefStacks = new HashMap<Long, RuntimeException>();
             }
             RuntimeException ex = new RuntimeException();
             ex.fillInStackTrace();
@@ -1144,117 +926,16 @@
         }
         mNumRefs++;
     }
-
-    private void decRefsLocked(long id) {
+    
+    private final void decRefsLocked(long id) {
         if (DEBUG_REFS && mRefStacks != null) {
             mRefStacks.remove(id);
         }
         mNumRefs--;
-        if (mNumRefs == 0 && mObject != 0) {
-            nativeDestroy(mObject);
-            mObject = 0;
+        //System.out.println("Dec streams: mNumRefs=" + mNumRefs
+        //                   + " mReleased=" + mReleased);
+        if (mNumRefs == 0) {
+            destroy();
         }
     }
-
-    // AssetManager setup native methods.
-    private static native long nativeCreate();
-    private static native void nativeDestroy(long ptr);
-    private static native void nativeSetApkAssets(long ptr, @NonNull ApkAssets[] apkAssets,
-            boolean invalidateCaches);
-    private static native void nativeSetConfiguration(long ptr, int mcc, int mnc,
-            @Nullable String locale, int orientation, int touchscreen, int density, int keyboard,
-            int keyboardHidden, int navigation, int screenWidth, int screenHeight,
-            int smallestScreenWidthDp, int screenWidthDp, int screenHeightDp, int screenLayout,
-            int uiMode, int colorMode, int majorVersion);
-    private static native @NonNull SparseArray<String> nativeGetAssignedPackageIdentifiers(
-            long ptr);
-
-    // File native methods.
-    private static native @Nullable String[] nativeList(long ptr, @NonNull String path)
-            throws IOException;
-    private static native long nativeOpenAsset(long ptr, @NonNull String fileName, int accessMode);
-    private static native @Nullable ParcelFileDescriptor nativeOpenAssetFd(long ptr,
-            @NonNull String fileName, long[] outOffsets) throws IOException;
-    private static native long nativeOpenNonAsset(long ptr, int cookie, @NonNull String fileName,
-            int accessMode);
-    private static native @Nullable ParcelFileDescriptor nativeOpenNonAssetFd(long ptr, int cookie,
-            @NonNull String fileName, @NonNull long[] outOffsets) throws IOException;
-    private static native long nativeOpenXmlAsset(long ptr, int cookie, @NonNull String fileName);
-
-    // Primitive resource native methods.
-    private static native int nativeGetResourceValue(long ptr, @AnyRes int resId, short density,
-            @NonNull TypedValue outValue, boolean resolveReferences);
-    private static native int nativeGetResourceBagValue(long ptr, @AnyRes int resId, int bagEntryId,
-            @NonNull TypedValue outValue);
-
-    private static native @Nullable @AttrRes int[] nativeGetStyleAttributes(long ptr,
-            @StyleRes int resId);
-    private static native @Nullable String[] nativeGetResourceStringArray(long ptr,
-            @ArrayRes int resId);
-    private static native @Nullable int[] nativeGetResourceStringArrayInfo(long ptr,
-            @ArrayRes int resId);
-    private static native @Nullable int[] nativeGetResourceIntArray(long ptr, @ArrayRes int resId);
-    private static native int nativeGetResourceArraySize(long ptr, @ArrayRes int resId);
-    private static native int nativeGetResourceArray(long ptr, @ArrayRes int resId,
-            @NonNull int[] outValues);
-
-    // Resource name/ID native methods.
-    private static native @AnyRes int nativeGetResourceIdentifier(long ptr, @NonNull String name,
-            @Nullable String defType, @Nullable String defPackage);
-    private static native @Nullable String nativeGetResourceName(long ptr, @AnyRes int resid);
-    private static native @Nullable String nativeGetResourcePackageName(long ptr,
-            @AnyRes int resid);
-    private static native @Nullable String nativeGetResourceTypeName(long ptr, @AnyRes int resid);
-    private static native @Nullable String nativeGetResourceEntryName(long ptr, @AnyRes int resid);
-    private static native @Nullable String[] nativeGetLocales(long ptr, boolean excludeSystem);
-    private static native @Nullable Configuration[] nativeGetSizeConfigurations(long ptr);
-
-    // Style attribute retrieval native methods.
-    private static native void nativeApplyStyle(long ptr, long themePtr, @AttrRes int defStyleAttr,
-            @StyleRes int defStyleRes, long xmlParserPtr, @NonNull int[] inAttrs,
-            long outValuesAddress, long outIndicesAddress);
-    private static native boolean nativeResolveAttrs(long ptr, long themePtr,
-            @AttrRes int defStyleAttr, @StyleRes int defStyleRes, @Nullable int[] inValues,
-            @NonNull int[] inAttrs, @NonNull int[] outValues, @NonNull int[] outIndices);
-    private static native boolean nativeRetrieveAttributes(long ptr, long xmlParserPtr,
-            @NonNull int[] inAttrs, @NonNull int[] outValues, @NonNull int[] outIndices);
-
-    // Theme related native methods
-    private static native long nativeThemeCreate(long ptr);
-    private static native void nativeThemeDestroy(long themePtr);
-    private static native void nativeThemeApplyStyle(long ptr, long themePtr, @StyleRes int resId,
-            boolean force);
-    static native void nativeThemeCopy(long destThemePtr, long sourceThemePtr);
-    static native void nativeThemeClear(long themePtr);
-    private static native int nativeThemeGetAttributeValue(long ptr, long themePtr,
-            @AttrRes int resId, @NonNull TypedValue outValue, boolean resolve);
-    private static native void nativeThemeDump(long ptr, long themePtr, int priority, String tag,
-            String prefix);
-    static native @NativeConfig int nativeThemeGetChangingConfigurations(long themePtr);
-
-    // AssetInputStream related native methods.
-    private static native void nativeAssetDestroy(long assetPtr);
-    private static native int nativeAssetReadChar(long assetPtr);
-    private static native int nativeAssetRead(long assetPtr, byte[] b, int off, int len);
-    private static native long nativeAssetSeek(long assetPtr, long offset, int whence);
-    private static native long nativeAssetGetLength(long assetPtr);
-    private static native long nativeAssetGetRemainingLength(long assetPtr);
-
-    private static native void nativeVerifySystemIdmaps();
-
-    // Global debug native methods.
-    /**
-     * @hide
-     */
-    public static native int getGlobalAssetCount();
-
-    /**
-     * @hide
-     */
-    public static native String getAssetAllocations();
-
-    /**
-     * @hide
-     */
-    public static native int getGlobalAssetManagerCount();
 }
diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java
index 8f58891..e173653c 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().getResourceIntArray(id);
+        int[] res = mResourcesImpl.getAssets().getArrayIntResource(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().getResourceArraySize(id);
+        int len = impl.getAssets().getArraySize(id);
         if (len < 0) {
             throw new NotFoundException("Array resource ID #0x" + Integer.toHexString(id));
         }
         
         TypedArray array = TypedArray.obtain(this, len);
-        array.mLength = impl.getAssets().getResourceArray(id, array.mData);
+        array.mLength = impl.getAssets().retrieveArray(id, array.mData);
         array.mIndices[0] = 0;
         
         return array;
@@ -1789,7 +1789,8 @@
         // out the attributes from the XML file (applying type information
         // contained in the resources and such).
         XmlBlock.Parser parser = (XmlBlock.Parser)set;
-        mResourcesImpl.getAssets().retrieveAttributes(parser, attrs, array.mData, array.mIndices);
+        mResourcesImpl.getAssets().retrieveAttributes(parser.mParseState, attrs,
+                array.mData, array.mIndices);
 
         array.mXml = parser;
 
diff --git a/core/java/android/content/res/ResourcesImpl.java b/core/java/android/content/res/ResourcesImpl.java
index 2a4b278..97cb78b 100644
--- a/core/java/android/content/res/ResourcesImpl.java
+++ b/core/java/android/content/res/ResourcesImpl.java
@@ -168,6 +168,7 @@
         mDisplayAdjustments = displayAdjustments;
         mConfiguration.setToDefaults();
         updateConfiguration(config, metrics, displayAdjustments.getCompatibilityInfo());
+        mAssets.ensureStringBlocks();
     }
 
     public DisplayAdjustments getDisplayAdjustments() {
@@ -1273,7 +1274,8 @@
 
         void applyStyle(int resId, boolean force) {
             synchronized (mKey) {
-                mAssets.applyStyleToTheme(mTheme, resId, force);
+                AssetManager.applyThemeStyle(mTheme, resId, force);
+
                 mThemeResId = resId;
                 mKey.append(resId, force);
             }
@@ -1282,7 +1284,7 @@
         void setTo(ThemeImpl other) {
             synchronized (mKey) {
                 synchronized (other.mKey) {
-                    AssetManager.nativeThemeCopy(mTheme, other.mTheme);
+                    AssetManager.copyTheme(mTheme, other.mTheme);
 
                     mThemeResId = other.mThemeResId;
                     mKey.setTo(other.getKey());
@@ -1305,10 +1307,12 @@
                 // out the attributes from the XML file (applying type information
                 // contained in the resources and such).
                 final XmlBlock.Parser parser = (XmlBlock.Parser) set;
-                mAssets.applyStyle(mTheme, defStyleAttr, defStyleRes, parser, attrs,
-                        array.mDataAddress, array.mIndicesAddress);
+                AssetManager.applyStyle(mTheme, defStyleAttr, defStyleRes,
+                        parser != null ? parser.mParseState : 0,
+                        attrs, attrs.length, array.mDataAddress, array.mIndicesAddress);
                 array.mTheme = wrapper;
                 array.mXml = parser;
+
                 return array;
             }
         }
@@ -1325,7 +1329,7 @@
                 }
 
                 final TypedArray array = TypedArray.obtain(wrapper.getResources(), len);
-                mAssets.resolveAttrs(mTheme, 0, 0, values, attrs, array.mData, array.mIndices);
+                AssetManager.resolveAttrs(mTheme, 0, 0, values, attrs, array.mData, array.mIndices);
                 array.mTheme = wrapper;
                 array.mXml = null;
                 return array;
@@ -1345,14 +1349,14 @@
         @Config int getChangingConfigurations() {
             synchronized (mKey) {
                 final @NativeConfig int nativeChangingConfig =
-                        AssetManager.nativeThemeGetChangingConfigurations(mTheme);
+                        AssetManager.getThemeChangingConfigurations(mTheme);
                 return ActivityInfo.activityInfoConfigNativeToJava(nativeChangingConfig);
             }
         }
 
         public void dump(int priority, String tag, String prefix) {
             synchronized (mKey) {
-                mAssets.dumpTheme(mTheme, priority, tag, prefix);
+                AssetManager.dumpTheme(mTheme, priority, tag, prefix);
             }
         }
 
@@ -1381,13 +1385,13 @@
          */
         void rebase() {
             synchronized (mKey) {
-                AssetManager.nativeThemeClear(mTheme);
+                AssetManager.clearTheme(mTheme);
 
                 // Reapply the same styles in the same order.
                 for (int i = 0; i < mKey.mCount; i++) {
                     final int resId = mKey.mResId[i];
                     final boolean force = mKey.mForce[i];
-                    mAssets.applyStyleToTheme(mTheme, resId, force);
+                    AssetManager.applyThemeStyle(mTheme, resId, force);
                 }
             }
         }
diff --git a/core/java/android/content/res/TypedArray.java b/core/java/android/content/res/TypedArray.java
index cbb3c6d..f33c7516 100644
--- a/core/java/android/content/res/TypedArray.java
+++ b/core/java/android/content/res/TypedArray.java
@@ -61,15 +61,6 @@
         return attrs;
     }
 
-    // STYLE_ prefixed constants are offsets within the typed data array.
-    static final int STYLE_NUM_ENTRIES = 6;
-    static final int STYLE_TYPE = 0;
-    static final int STYLE_DATA = 1;
-    static final int STYLE_ASSET_COOKIE = 2;
-    static final int STYLE_RESOURCE_ID = 3;
-    static final int STYLE_CHANGING_CONFIGURATIONS = 4;
-    static final int STYLE_DENSITY = 5;
-
     private final Resources mResources;
     private DisplayMetrics mMetrics;
     private AssetManager mAssets;
@@ -87,7 +78,7 @@
 
     private void resize(int len) {
         mLength = len;
-        final int dataLen = len * STYLE_NUM_ENTRIES;
+        final int dataLen = len * AssetManager.STYLE_NUM_ENTRIES;
         final int indicesLen = len + 1;
         final VMRuntime runtime = VMRuntime.getRuntime();
         if (mDataAddress == 0 || mData.length < dataLen) {
@@ -175,9 +166,9 @@
             throw new RuntimeException("Cannot make calls to a recycled instance!");
         }
 
-        index *= STYLE_NUM_ENTRIES;
+        index *= AssetManager.STYLE_NUM_ENTRIES;
         final int[] data = mData;
-        final int type = data[index + STYLE_TYPE];
+        final int type = data[index+AssetManager.STYLE_TYPE];
         if (type == TypedValue.TYPE_NULL) {
             return null;
         } else if (type == TypedValue.TYPE_STRING) {
@@ -212,9 +203,9 @@
             throw new RuntimeException("Cannot make calls to a recycled instance!");
         }
 
-        index *= STYLE_NUM_ENTRIES;
+        index *= AssetManager.STYLE_NUM_ENTRIES;
         final int[] data = mData;
-        final int type = data[index + STYLE_TYPE];
+        final int type = data[index+AssetManager.STYLE_TYPE];
         if (type == TypedValue.TYPE_NULL) {
             return null;
         } else if (type == TypedValue.TYPE_STRING) {
@@ -251,13 +242,14 @@
             throw new RuntimeException("Cannot make calls to a recycled instance!");
         }
 
-        index *= STYLE_NUM_ENTRIES;
+        index *= AssetManager.STYLE_NUM_ENTRIES;
         final int[] data = mData;
-        final int type = data[index + STYLE_TYPE];
+        final int type = data[index+AssetManager.STYLE_TYPE];
         if (type == TypedValue.TYPE_STRING) {
-            final int cookie = data[index + STYLE_ASSET_COOKIE];
+            final int cookie = data[index+AssetManager.STYLE_ASSET_COOKIE];
             if (cookie < 0) {
-                return mXml.getPooledString(data[index + STYLE_DATA]).toString();
+                return mXml.getPooledString(
+                    data[index+AssetManager.STYLE_DATA]).toString();
             }
         }
         return null;
@@ -282,11 +274,11 @@
             throw new RuntimeException("Cannot make calls to a recycled instance!");
         }
 
-        index *= STYLE_NUM_ENTRIES;
+        index *= AssetManager.STYLE_NUM_ENTRIES;
         final int[] data = mData;
-        final int type = data[index + STYLE_TYPE];
+        final int type = data[index+AssetManager.STYLE_TYPE];
         final @Config int changingConfigs = ActivityInfo.activityInfoConfigNativeToJava(
-                data[index + STYLE_CHANGING_CONFIGURATIONS]);
+                data[index + AssetManager.STYLE_CHANGING_CONFIGURATIONS]);
         if ((changingConfigs & ~allowedChangingConfigs) != 0) {
             return null;
         }
@@ -328,14 +320,14 @@
             throw new RuntimeException("Cannot make calls to a recycled instance!");
         }
 
-        index *= STYLE_NUM_ENTRIES;
+        index *= AssetManager.STYLE_NUM_ENTRIES;
         final int[] data = mData;
-        final int type = data[index + STYLE_TYPE];
+        final int type = data[index+AssetManager.STYLE_TYPE];
         if (type == TypedValue.TYPE_NULL) {
             return defValue;
         } else if (type >= TypedValue.TYPE_FIRST_INT
                 && type <= TypedValue.TYPE_LAST_INT) {
-            return data[index + STYLE_DATA] != 0;
+            return data[index+AssetManager.STYLE_DATA] != 0;
         }
 
         final TypedValue v = mValue;
@@ -367,14 +359,14 @@
             throw new RuntimeException("Cannot make calls to a recycled instance!");
         }
 
-        index *= STYLE_NUM_ENTRIES;
+        index *= AssetManager.STYLE_NUM_ENTRIES;
         final int[] data = mData;
-        final int type = data[index + STYLE_TYPE];
+        final int type = data[index+AssetManager.STYLE_TYPE];
         if (type == TypedValue.TYPE_NULL) {
             return defValue;
         } else if (type >= TypedValue.TYPE_FIRST_INT
                 && type <= TypedValue.TYPE_LAST_INT) {
-            return data[index + STYLE_DATA];
+            return data[index+AssetManager.STYLE_DATA];
         }
 
         final TypedValue v = mValue;
@@ -404,16 +396,16 @@
             throw new RuntimeException("Cannot make calls to a recycled instance!");
         }
 
-        index *= STYLE_NUM_ENTRIES;
+        index *= AssetManager.STYLE_NUM_ENTRIES;
         final int[] data = mData;
-        final int type = data[index + STYLE_TYPE];
+        final int type = data[index+AssetManager.STYLE_TYPE];
         if (type == TypedValue.TYPE_NULL) {
             return defValue;
         } else if (type == TypedValue.TYPE_FLOAT) {
-            return Float.intBitsToFloat(data[index + STYLE_DATA]);
+            return Float.intBitsToFloat(data[index+AssetManager.STYLE_DATA]);
         } else if (type >= TypedValue.TYPE_FIRST_INT
                 && type <= TypedValue.TYPE_LAST_INT) {
-            return data[index + STYLE_DATA];
+            return data[index+AssetManager.STYLE_DATA];
         }
 
         final TypedValue v = mValue;
@@ -454,15 +446,15 @@
         }
 
         final int attrIndex = index;
-        index *= STYLE_NUM_ENTRIES;
+        index *= AssetManager.STYLE_NUM_ENTRIES;
 
         final int[] data = mData;
-        final int type = data[index + STYLE_TYPE];
+        final int type = data[index+AssetManager.STYLE_TYPE];
         if (type == TypedValue.TYPE_NULL) {
             return defValue;
         } else if (type >= TypedValue.TYPE_FIRST_INT
                 && type <= TypedValue.TYPE_LAST_INT) {
-            return data[index + STYLE_DATA];
+            return data[index+AssetManager.STYLE_DATA];
         } else if (type == TypedValue.TYPE_STRING) {
             final TypedValue value = mValue;
             if (getValueAt(index, value)) {
@@ -506,7 +498,7 @@
         }
 
         final TypedValue value = mValue;
-        if (getValueAt(index * STYLE_NUM_ENTRIES, value)) {
+        if (getValueAt(index*AssetManager.STYLE_NUM_ENTRIES, value)) {
             if (value.type == TypedValue.TYPE_ATTRIBUTE) {
                 throw new UnsupportedOperationException(
                         "Failed to resolve attribute at index " + index + ": " + value);
@@ -541,7 +533,7 @@
         }
 
         final TypedValue value = mValue;
-        if (getValueAt(index * STYLE_NUM_ENTRIES, value)) {
+        if (getValueAt(index*AssetManager.STYLE_NUM_ENTRIES, value)) {
             if (value.type == TypedValue.TYPE_ATTRIBUTE) {
                 throw new UnsupportedOperationException(
                         "Failed to resolve attribute at index " + index + ": " + value);
@@ -572,15 +564,15 @@
         }
 
         final int attrIndex = index;
-        index *= STYLE_NUM_ENTRIES;
+        index *= AssetManager.STYLE_NUM_ENTRIES;
 
         final int[] data = mData;
-        final int type = data[index + STYLE_TYPE];
+        final int type = data[index+AssetManager.STYLE_TYPE];
         if (type == TypedValue.TYPE_NULL) {
             return defValue;
         } else if (type >= TypedValue.TYPE_FIRST_INT
                 && type <= TypedValue.TYPE_LAST_INT) {
-            return data[index + STYLE_DATA];
+            return data[index+AssetManager.STYLE_DATA];
         } else if (type == TypedValue.TYPE_ATTRIBUTE) {
             final TypedValue value = mValue;
             getValueAt(index, value);
@@ -620,14 +612,15 @@
         }
 
         final int attrIndex = index;
-        index *= STYLE_NUM_ENTRIES;
+        index *= AssetManager.STYLE_NUM_ENTRIES;
 
         final int[] data = mData;
-        final int type = data[index + STYLE_TYPE];
+        final int type = data[index+AssetManager.STYLE_TYPE];
         if (type == TypedValue.TYPE_NULL) {
             return defValue;
         } else if (type == TypedValue.TYPE_DIMENSION) {
-            return TypedValue.complexToDimension(data[index + STYLE_DATA], mMetrics);
+            return TypedValue.complexToDimension(
+                    data[index + AssetManager.STYLE_DATA], mMetrics);
         } else if (type == TypedValue.TYPE_ATTRIBUTE) {
             final TypedValue value = mValue;
             getValueAt(index, value);
@@ -668,14 +661,15 @@
         }
 
         final int attrIndex = index;
-        index *= STYLE_NUM_ENTRIES;
+        index *= AssetManager.STYLE_NUM_ENTRIES;
 
         final int[] data = mData;
-        final int type = data[index + STYLE_TYPE];
+        final int type = data[index+AssetManager.STYLE_TYPE];
         if (type == TypedValue.TYPE_NULL) {
             return defValue;
         } else if (type == TypedValue.TYPE_DIMENSION) {
-            return TypedValue.complexToDimensionPixelOffset(data[index + STYLE_DATA], mMetrics);
+            return TypedValue.complexToDimensionPixelOffset(
+                    data[index + AssetManager.STYLE_DATA], mMetrics);
         } else if (type == TypedValue.TYPE_ATTRIBUTE) {
             final TypedValue value = mValue;
             getValueAt(index, value);
@@ -717,14 +711,15 @@
         }
 
         final int attrIndex = index;
-        index *= STYLE_NUM_ENTRIES;
+        index *= AssetManager.STYLE_NUM_ENTRIES;
 
         final int[] data = mData;
-        final int type = data[index + STYLE_TYPE];
+        final int type = data[index+AssetManager.STYLE_TYPE];
         if (type == TypedValue.TYPE_NULL) {
             return defValue;
         } else if (type == TypedValue.TYPE_DIMENSION) {
-            return TypedValue.complexToDimensionPixelSize(data[index + STYLE_DATA], mMetrics);
+            return TypedValue.complexToDimensionPixelSize(
+                data[index+AssetManager.STYLE_DATA], mMetrics);
         } else if (type == TypedValue.TYPE_ATTRIBUTE) {
             final TypedValue value = mValue;
             getValueAt(index, value);
@@ -760,15 +755,16 @@
         }
 
         final int attrIndex = index;
-        index *= STYLE_NUM_ENTRIES;
+        index *= AssetManager.STYLE_NUM_ENTRIES;
 
         final int[] data = mData;
-        final int type = data[index + STYLE_TYPE];
+        final int type = data[index+AssetManager.STYLE_TYPE];
         if (type >= TypedValue.TYPE_FIRST_INT
                 && type <= TypedValue.TYPE_LAST_INT) {
-            return data[index + STYLE_DATA];
+            return data[index+AssetManager.STYLE_DATA];
         } else if (type == TypedValue.TYPE_DIMENSION) {
-            return TypedValue.complexToDimensionPixelSize(data[index + STYLE_DATA], mMetrics);
+            return TypedValue.complexToDimensionPixelSize(
+                data[index+AssetManager.STYLE_DATA], mMetrics);
         } else if (type == TypedValue.TYPE_ATTRIBUTE) {
             final TypedValue value = mValue;
             getValueAt(index, value);
@@ -799,14 +795,15 @@
             throw new RuntimeException("Cannot make calls to a recycled instance!");
         }
 
-        index *= STYLE_NUM_ENTRIES;
+        index *= AssetManager.STYLE_NUM_ENTRIES;
         final int[] data = mData;
-        final int type = data[index + STYLE_TYPE];
+        final int type = data[index+AssetManager.STYLE_TYPE];
         if (type >= TypedValue.TYPE_FIRST_INT
                 && type <= TypedValue.TYPE_LAST_INT) {
-            return data[index + STYLE_DATA];
+            return data[index+AssetManager.STYLE_DATA];
         } else if (type == TypedValue.TYPE_DIMENSION) {
-            return TypedValue.complexToDimensionPixelSize(data[index + STYLE_DATA], mMetrics);
+            return TypedValue.complexToDimensionPixelSize(
+                    data[index + AssetManager.STYLE_DATA], mMetrics);
         }
 
         return defValue;
@@ -836,14 +833,15 @@
         }
 
         final int attrIndex = index;
-        index *= STYLE_NUM_ENTRIES;
+        index *= AssetManager.STYLE_NUM_ENTRIES;
 
         final int[] data = mData;
-        final int type = data[index + STYLE_TYPE];
+        final int type = data[index+AssetManager.STYLE_TYPE];
         if (type == TypedValue.TYPE_NULL) {
             return defValue;
         } else if (type == TypedValue.TYPE_FRACTION) {
-            return TypedValue.complexToFraction(data[index + STYLE_DATA], base, pbase);
+            return TypedValue.complexToFraction(
+                data[index+AssetManager.STYLE_DATA], base, pbase);
         } else if (type == TypedValue.TYPE_ATTRIBUTE) {
             final TypedValue value = mValue;
             getValueAt(index, value);
@@ -876,10 +874,10 @@
             throw new RuntimeException("Cannot make calls to a recycled instance!");
         }
 
-        index *= STYLE_NUM_ENTRIES;
+        index *= AssetManager.STYLE_NUM_ENTRIES;
         final int[] data = mData;
-        if (data[index + STYLE_TYPE] != TypedValue.TYPE_NULL) {
-            final int resid = data[index + STYLE_RESOURCE_ID];
+        if (data[index+AssetManager.STYLE_TYPE] != TypedValue.TYPE_NULL) {
+            final int resid = data[index+AssetManager.STYLE_RESOURCE_ID];
             if (resid != 0) {
                 return resid;
             }
@@ -904,10 +902,10 @@
             throw new RuntimeException("Cannot make calls to a recycled instance!");
         }
 
-        index *= STYLE_NUM_ENTRIES;
+        index *= AssetManager.STYLE_NUM_ENTRIES;
         final int[] data = mData;
-        if (data[index + STYLE_TYPE] == TypedValue.TYPE_ATTRIBUTE) {
-            return data[index + STYLE_DATA];
+        if (data[index + AssetManager.STYLE_TYPE] == TypedValue.TYPE_ATTRIBUTE) {
+            return data[index + AssetManager.STYLE_DATA];
         }
         return defValue;
     }
@@ -941,7 +939,7 @@
         }
 
         final TypedValue value = mValue;
-        if (getValueAt(index * STYLE_NUM_ENTRIES, value)) {
+        if (getValueAt(index*AssetManager.STYLE_NUM_ENTRIES, value)) {
             if (value.type == TypedValue.TYPE_ATTRIBUTE) {
                 throw new UnsupportedOperationException(
                         "Failed to resolve attribute at index " + index + ": " + value);
@@ -977,7 +975,7 @@
         }
 
         final TypedValue value = mValue;
-        if (getValueAt(index * STYLE_NUM_ENTRIES, value)) {
+        if (getValueAt(index*AssetManager.STYLE_NUM_ENTRIES, value)) {
             if (value.type == TypedValue.TYPE_ATTRIBUTE) {
                 throw new UnsupportedOperationException(
                         "Failed to resolve attribute at index " + index + ": " + value);
@@ -1008,7 +1006,7 @@
         }
 
         final TypedValue value = mValue;
-        if (getValueAt(index * STYLE_NUM_ENTRIES, value)) {
+        if (getValueAt(index*AssetManager.STYLE_NUM_ENTRIES, value)) {
             return mResources.getTextArray(value.resourceId);
         }
         return null;
@@ -1029,7 +1027,7 @@
             throw new RuntimeException("Cannot make calls to a recycled instance!");
         }
 
-        return getValueAt(index * STYLE_NUM_ENTRIES, outValue);
+        return getValueAt(index*AssetManager.STYLE_NUM_ENTRIES, outValue);
     }
 
     /**
@@ -1045,8 +1043,8 @@
             throw new RuntimeException("Cannot make calls to a recycled instance!");
         }
 
-        index *= STYLE_NUM_ENTRIES;
-        return mData[index + STYLE_TYPE];
+        index *= AssetManager.STYLE_NUM_ENTRIES;
+        return mData[index + AssetManager.STYLE_TYPE];
     }
 
     /**
@@ -1065,9 +1063,9 @@
             throw new RuntimeException("Cannot make calls to a recycled instance!");
         }
 
-        index *= STYLE_NUM_ENTRIES;
+        index *= AssetManager.STYLE_NUM_ENTRIES;
         final int[] data = mData;
-        final int type = data[index + STYLE_TYPE];
+        final int type = data[index+AssetManager.STYLE_TYPE];
         return type != TypedValue.TYPE_NULL;
     }
 
@@ -1086,11 +1084,11 @@
             throw new RuntimeException("Cannot make calls to a recycled instance!");
         }
 
-        index *= STYLE_NUM_ENTRIES;
+        index *= AssetManager.STYLE_NUM_ENTRIES;
         final int[] data = mData;
-        final int type = data[index + STYLE_TYPE];
+        final int type = data[index+AssetManager.STYLE_TYPE];
         return type != TypedValue.TYPE_NULL
-                || data[index + STYLE_DATA] == TypedValue.DATA_NULL_EMPTY;
+                || data[index+AssetManager.STYLE_DATA] == TypedValue.DATA_NULL_EMPTY;
     }
 
     /**
@@ -1111,7 +1109,7 @@
         }
 
         final TypedValue value = mValue;
-        if (getValueAt(index * STYLE_NUM_ENTRIES, value)) {
+        if (getValueAt(index*AssetManager.STYLE_NUM_ENTRIES, value)) {
             return value;
         }
         return null;
@@ -1183,16 +1181,16 @@
         final int[] data = mData;
         final int N = length();
         for (int i = 0; i < N; i++) {
-            final int index = i * STYLE_NUM_ENTRIES;
-            if (data[index + STYLE_TYPE] != TypedValue.TYPE_ATTRIBUTE) {
+            final int index = i * AssetManager.STYLE_NUM_ENTRIES;
+            if (data[index + AssetManager.STYLE_TYPE] != TypedValue.TYPE_ATTRIBUTE) {
                 // Not an attribute, ignore.
                 continue;
             }
 
             // Null the entry so that we can safely call getZzz().
-            data[index + STYLE_TYPE] = TypedValue.TYPE_NULL;
+            data[index + AssetManager.STYLE_TYPE] = TypedValue.TYPE_NULL;
 
-            final int attr = data[index + STYLE_DATA];
+            final int attr = data[index + AssetManager.STYLE_DATA];
             if (attr == 0) {
                 // Useless data, ignore.
                 continue;
@@ -1233,44 +1231,45 @@
         final int[] data = mData;
         final int N = length();
         for (int i = 0; i < N; i++) {
-            final int index = i * STYLE_NUM_ENTRIES;
-            final int type = data[index + STYLE_TYPE];
+            final int index = i * AssetManager.STYLE_NUM_ENTRIES;
+            final int type = data[index + AssetManager.STYLE_TYPE];
             if (type == TypedValue.TYPE_NULL) {
                 continue;
             }
             changingConfig |= ActivityInfo.activityInfoConfigNativeToJava(
-                    data[index + STYLE_CHANGING_CONFIGURATIONS]);
+                    data[index + AssetManager.STYLE_CHANGING_CONFIGURATIONS]);
         }
         return changingConfig;
     }
 
     private boolean getValueAt(int index, TypedValue outValue) {
         final int[] data = mData;
-        final int type = data[index + STYLE_TYPE];
+        final int type = data[index+AssetManager.STYLE_TYPE];
         if (type == TypedValue.TYPE_NULL) {
             return false;
         }
         outValue.type = type;
-        outValue.data = data[index + STYLE_DATA];
-        outValue.assetCookie = data[index + STYLE_ASSET_COOKIE];
-        outValue.resourceId = data[index + STYLE_RESOURCE_ID];
+        outValue.data = data[index+AssetManager.STYLE_DATA];
+        outValue.assetCookie = data[index+AssetManager.STYLE_ASSET_COOKIE];
+        outValue.resourceId = data[index+AssetManager.STYLE_RESOURCE_ID];
         outValue.changingConfigurations = ActivityInfo.activityInfoConfigNativeToJava(
-                data[index + STYLE_CHANGING_CONFIGURATIONS]);
-        outValue.density = data[index + STYLE_DENSITY];
+                data[index + AssetManager.STYLE_CHANGING_CONFIGURATIONS]);
+        outValue.density = data[index+AssetManager.STYLE_DENSITY];
         outValue.string = (type == TypedValue.TYPE_STRING) ? loadStringValueAt(index) : null;
         return true;
     }
 
     private CharSequence loadStringValueAt(int index) {
         final int[] data = mData;
-        final int cookie = data[index + STYLE_ASSET_COOKIE];
+        final int cookie = data[index+AssetManager.STYLE_ASSET_COOKIE];
         if (cookie < 0) {
             if (mXml != null) {
-                return mXml.getPooledString(data[index + STYLE_DATA]);
+                return mXml.getPooledString(
+                    data[index+AssetManager.STYLE_DATA]);
             }
             return null;
         }
-        return mAssets.getPooledStringForCookie(cookie, data[index + STYLE_DATA]);
+        return mAssets.getPooledStringForCookie(cookie, data[index+AssetManager.STYLE_DATA]);
     }
 
     /** @hide */
diff --git a/core/java/android/content/res/XmlBlock.java b/core/java/android/content/res/XmlBlock.java
index d4ccffb..e6b95741 100644
--- a/core/java/android/content/res/XmlBlock.java
+++ b/core/java/android/content/res/XmlBlock.java
@@ -16,7 +16,6 @@
 
 package android.content.res;
 
-import android.annotation.Nullable;
 import android.util.TypedValue;
 
 import com.android.internal.util.XmlUtils;
@@ -34,7 +33,7 @@
  * 
  * {@hide}
  */
-final class XmlBlock implements AutoCloseable {
+final class XmlBlock {
     private static final boolean DEBUG=false;
 
     public XmlBlock(byte[] data) {
@@ -49,7 +48,6 @@
         mStrings = new StringBlock(nativeGetStringBlock(mNative), false);
     }
 
-    @Override
     public void close() {
         synchronized (this) {
             if (mOpen) {
@@ -480,13 +478,13 @@
      *  are doing!  The given native object must exist for the entire lifetime
      *  of this newly creating XmlBlock.
      */
-    XmlBlock(@Nullable AssetManager assets, long xmlBlock) {
+    XmlBlock(AssetManager assets, long xmlBlock) {
         mAssets = assets;
         mNative = xmlBlock;
         mStrings = new StringBlock(nativeGetStringBlock(xmlBlock), false);
     }
 
-    private @Nullable final AssetManager mAssets;
+    private final AssetManager mAssets;
     private final long mNative;
     /*package*/ final StringBlock mStrings;
     private boolean mOpen = true;
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index 5751fc9..93f95c6 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -110,8 +110,8 @@
         "android_util_AssetManager.cpp",
         "android_util_Binder.cpp",
         "android_util_EventLog.cpp",
-        "android_util_Log.cpp",
         "android_util_MemoryIntArray.cpp",
+        "android_util_Log.cpp",
         "android_util_PathParser.cpp",
         "android_util_Process.cpp",
         "android_util_StringBlock.cpp",
@@ -190,7 +190,6 @@
         "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 e3b5c8f..aa9a824 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -122,7 +122,6 @@
 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);
@@ -1341,7 +1340,6 @@
     REG_JNI(register_android_content_AssetManager),
     REG_JNI(register_android_content_StringBlock),
     REG_JNI(register_android_content_XmlBlock),
-    REG_JNI(register_android_content_res_ApkAssets),
     REG_JNI(register_android_text_AndroidCharacter),
     REG_JNI(register_android_text_Hyphenator),
     REG_JNI(register_android_text_MeasuredParagraph),
diff --git a/core/jni/android/graphics/FontFamily.cpp b/core/jni/android/graphics/FontFamily.cpp
index c50026e..dd3e6f0 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/AssetManager2.h>
+#include <androidfw/AssetManager.h>
 #include "Utils.h"
 #include "FontUtils.h"
 
@@ -224,8 +224,7 @@
     NPE_CHECK_RETURN_ZERO(env, jpath);
 
     NativeFamilyBuilder* builder = reinterpret_cast<NativeFamilyBuilder*>(builderPtr);
-
-    Guarded<AssetManager2>* mgr = AssetManagerForJavaObject(env, jassetMgr);
+    AssetManager* mgr = assetManagerForJavaObject(env, jassetMgr);
     if (NULL == mgr) {
         builder->axes.clear();
         return false;
@@ -237,33 +236,27 @@
         return false;
     }
 
-    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);
-      }
+    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);
     }
 
-    if (nullptr == asset) {
+    if (NULL == 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.release()));
+    sk_sp<SkData> data(SkData::MakeWithProc(buf, asset->getLength(), releaseAsset, asset));
     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 49a24a3..09e37e1 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 = NdkAssetManagerForJavaObject(env, jAssetMgr);
+    code->assetManager = assetManagerForJavaObject(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
deleted file mode 100644
index c0f151b..0000000
--- a/core/jni/android_content_res_ApkAssets.cpp
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#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 7e17a49..683b4c4 100644
--- a/core/jni/android_util_AssetManager.cpp
+++ b/core/jni/android_util_AssetManager.cpp
@@ -1,1441 +1,1851 @@
-/*
- * 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.
- */
+/* //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.
+*/
 
 #define LOG_TAG "asset"
 
+#include <android_runtime/android_util_AssetManager.h>
+
 #include <inttypes.h>
 #include <linux/capability.h>
 #include <stdio.h>
-#include <sys/stat.h>
-#include <sys/system_properties.h>
 #include <sys/types.h>
 #include <sys/wait.h>
+#include <sys/stat.h>
+#include <sys/system_properties.h>
 
 #include <private/android_filesystem_config.h> // for AID_SYSTEM
 
-#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 "android_runtime/AndroidRuntime.h"
+#include "android_util_Binder.h"
 #include "core_jni_helpers.h"
 #include "jni.h"
-#include "nativehelper/JNIHelp.h"
-#include "nativehelper/ScopedPrimitiveArray.h"
-#include "nativehelper/ScopedStringChars.h"
-#include "nativehelper/ScopedUtfChars.h"
+#include <nativehelper/JNIHelp.h>
+#include <nativehelper/ScopedStringChars.h>
+#include <nativehelper/ScopedUtfChars.h>
 #include "utils/Log.h"
-#include "utils/String8.h"
 #include "utils/misc.h"
+#include "utils/String8.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 {
-  jfieldID native_ptr;
-} gApkAssetsFields;
-
-static struct sparsearray_offsets_t {
-  jclass classObject;
-  jmethodID constructor;
-  jmethodID put;
+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 = nullptr;
+jclass g_stringClass = 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;
-}
+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);
 
-constexpr inline static ApkAssetsCookie JavaCookieToApkAssetsCookie(jint cookie) {
-  return cookie > 0 ? static_cast<ApkAssetsCookie>(cookie - 1) : kInvalidCookie;
+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;
 }
 
 // This is called by zygote (running as user root) as part of preloadResources.
-static void NativeVerifySystemIdmaps(JNIEnv* /*env*/, jclass /*clazz*/) {
-  switch (pid_t pid = fork()) {
-    case -1:
-      PLOG(ERROR) << "failed to fork for idmap";
-      break;
+static void verifySystemIdmaps()
+{
+    pid_t pid;
+    char system_id[10];
 
-    // child
-    case 0: {
-      struct __user_cap_header_struct capheader;
-      struct __user_cap_data_struct capdata;
+    snprintf(system_id, sizeof(system_id), "%d", AID_SYSTEM);
 
-      memset(&capheader, 0, sizeof(capheader));
-      memset(&capdata, 0, sizeof(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;
 
-      capheader.version = _LINUX_CAPABILITY_VERSION;
-      capheader.pid = 0;
+                memset(&capheader, 0, sizeof(capheader));
+                memset(&capdata, 0, sizeof(capdata));
 
-      if (capget(&capheader, &capdata) != 0) {
-        PLOG(ERROR) << "capget";
-        exit(1);
-      }
+                capheader.version = _LINUX_CAPABILITY_VERSION;
+                capheader.pid = 0;
 
-      capdata.effective = capdata.permitted;
-      if (capset(&capheader, &capdata) != 0) {
-        PLOG(ERROR) << "capset";
-        exit(1);
-      }
+                if (capget(&capheader, &capdata) != 0) {
+                    ALOGE("capget: %s\n", strerror(errno));
+                    exit(1);
+                }
 
-      if (setgid(AID_SYSTEM) != 0) {
-        PLOG(ERROR) << "setgid";
-        exit(1);
-      }
+                capdata.effective = capdata.permitted;
+                if (capset(&capheader, &capdata) != 0) {
+                    ALOGE("capset: %s\n", strerror(errno));
+                    exit(1);
+                }
 
-      if (setuid(AID_SYSTEM) != 0) {
-        PLOG(ERROR) << "setuid";
-        exit(1);
-      }
+                if (setgid(AID_SYSTEM) != 0) {
+                    ALOGE("setgid: %s\n", strerror(errno));
+                    exit(1);
+                }
 
-      // Generic idmap parameters
-      const char* argv[8];
-      int argc = 0;
-      struct stat st;
+                if (setuid(AID_SYSTEM) != 0) {
+                    ALOGE("setuid: %s\n", strerror(errno));
+                    exit(1);
+                }
 
-      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;
+                // Generic idmap parameters
+                const char* argv[8];
+                int argc = 0;
+                struct stat st;
 
-      // 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();
-        }
-      }
+                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;
 
-      if (stat(AssetManager::OVERLAY_DIR, &st) == 0) {
-          argv[argc++] = AssetManager::OVERLAY_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.
+                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::PRODUCT_OVERLAY_DIR, &st) == 0) {
-          argv[argc++] = AssetManager::PRODUCT_OVERLAY_DIR;
-      }
+                if (stat(AssetManager::PRODUCT_OVERLAY_DIR, &st) == 0) {
+                    argv[argc++] = AssetManager::PRODUCT_OVERLAY_DIR;
+                }
 
-      // 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;
-  }
+                // 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;
+    }
 }
 
-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));
-}
 
 // ----------------------------------------------------------------------------
 
-// Let the opaque type AAssetManager refer to a guarded AssetManager2 instance.
-struct GuardedAssetManager : public ::AAssetManager {
-  Guarded<AssetManager2> guarded_assetmanager;
-};
-
-::AAssetManager* NdkAssetManagerForJavaObject(JNIEnv* env, jobject jassetmanager) {
-  jlong assetmanager_handle = env->GetLongField(jassetmanager, gAssetManagerOffsets.mObject);
-  ::AAssetManager* am = reinterpret_cast<::AAssetManager*>(assetmanager_handle);
-  if (am == nullptr) {
+// 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 nullptr;
-  }
-  return am;
+    return NULL;
 }
 
-Guarded<AssetManager2>* AssetManagerForNdkAssetManager(::AAssetManager* assetmanager) {
-  if (assetmanager == nullptr) {
-    return nullptr;
-  }
-  return &reinterpret_cast<GuardedAssetManager*>(assetmanager)->guarded_assetmanager;
-}
-
-Guarded<AssetManager2>* AssetManagerForJavaObject(JNIEnv* env, jobject jassetmanager) {
-  return AssetManagerForNdkAssetManager(NdkAssetManagerForJavaObject(env, jassetmanager));
-}
-
-static Guarded<AssetManager2>& AssetManagerFromLong(jlong ptr) {
-  return *AssetManagerForNdkAssetManager(reinterpret_cast<AAssetManager*>(ptr));
-}
-
-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();
-
-  if (fd < 0) {
-    jniThrowException(env, "java/io/FileNotFoundException",
-                      "This file can not be opened as a file descriptor; it is probably "
-                      "compressed");
-    return nullptr;
-  }
-
-  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;
+static jlong android_content_AssetManager_openAsset(JNIEnv* env, jobject clazz,
+                                                jstring fileName, jint mode)
+{
+    AssetManager* am = assetManagerForJavaObject(env, clazz);
+    if (am == NULL) {
+        return 0;
     }
 
-    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));
-  }
+    ALOGV("openAsset in %p (Java object %p)\n", am, clazz);
 
-  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;
+    ScopedUtfChars fileName8(env, fileName);
+    if (fileName8.c_str() == NULL) {
+        jniThrowException(env, "java/lang/IllegalArgumentException", "Empty file name");
+        return -1;
     }
 
-    env->CallVoidMethod(sparse_array, gSparseArrayOffsets.put, static_cast<jint>(package_id),
-                        jpackage_name);
-  });
-  return sparse_array;
+    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 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;
-  }
+static jobject returnParcelFileDescriptor(JNIEnv* env, Asset* a, jlongArray outOffsets)
+{
+    off64_t startOffset, length;
+    int fd = a->openFileDescriptor(&startOffset, &length);
+    delete a;
 
-  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);
+    if (fd < 0) {
+        jniThrowException(env, "java/io/FileNotFoundException",
+                "This file can not be opened as a file descriptor; it is probably compressed");
+        return NULL;
     }
-    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());
+
+    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;
         }
-      });
-    }
-  }
-
-  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, i, str);
+        env->DeleteLocalRef(str);
     }
 
-    env->SetObjectArrayElement(array, index++, java_string);
+    delete dir;
 
-    // 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;
+    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;
-  }
+static void android_content_AssetManager_destroyAsset(JNIEnv* env, jobject clazz,
+                                                      jlong assetHandle)
+{
+    Asset* a = reinterpret_cast<Asset*>(assetHandle);
 
-  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;
-  }
+    //printf("Destroying Asset Stream: %p\n", a);
 
-  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 (a == NULL) {
+        jniThrowNullPointerException(env, "asset");
+        return;
     }
 
-    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;
+    delete a;
 }
 
-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;
-  }
+static jint android_content_AssetManager_readAssetChar(JNIEnv* env, jobject clazz,
+                                                       jlong assetHandle)
+{
+    Asset* a = reinterpret_cast<Asset*>(assetHandle);
 
-  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;
+    if (a == NULL) {
+        jniThrowNullPointerException(env, "asset");
+        return -1;
     }
 
-    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;
+    uint8_t b;
+    ssize_t res = a->read(&b, 1);
+    return res == 1 ? b : -1;
 }
 
-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;
-  }
+static jint android_content_AssetManager_readAsset(JNIEnv* env, jobject clazz,
+                                                jlong assetHandle, jbyteArray bArray,
+                                                jint off, jint len)
+{
+    Asset* a = reinterpret_cast<Asset*>(assetHandle);
 
-  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 (a == NULL || bArray == NULL) {
+        jniThrowNullPointerException(env, "asset");
+        return -1;
     }
 
-    if (value.dataType >= Res_value::TYPE_FIRST_INT && value.dataType <= Res_value::TYPE_LAST_INT) {
-      buffer[i] = static_cast<jint>(value.data);
+    if (len == 0) {
+        return 0;
     }
-  }
-  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) {
+    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;
-  }
-  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;
-  }
+static jlong android_content_AssetManager_seekAsset(JNIEnv* env, jobject clazz,
+                                                 jlong assetHandle,
+                                                 jlong offset, jint whence)
+{
+    Asset* a = reinterpret_cast<Asset*>(assetHandle);
 
-  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;
+    if (a == NULL) {
+        jniThrowNullPointerException(env, "asset");
+        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;
+    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;
     }
 
-    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);
+    return a->getLength();
 }
 
-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;
-  }
+static jlong android_content_AssetManager_getAssetRemainingLength(JNIEnv* env, jobject clazz,
+                                                               jlong assetHandle)
+{
+    Asset* a = reinterpret_cast<Asset*>(assetHandle);
 
-  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 (a == NULL) {
+        jniThrowNullPointerException(env, "asset");
+        return -1;
     }
 
-    if (name.type != nullptr) {
-      result.append(name.type, name.type_len);
-    } else {
-      result += util::Utf16ToUtf8(StringPiece16(name.type16, name.type_len));
-    }
-  }
+    return a->getRemainingLength();
+}
 
-  if (name.entry != nullptr || name.entry16 != nullptr) {
-    if (!result.empty()) {
-      result += "/";
+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;
     }
 
-    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;
+    AssetManager* am = assetManagerForJavaObject(env, clazz);
+    if (am == NULL) {
+        return 0;
     }
 
-    env->SetObjectArrayElement(array, idx++, java_configuration);
-    env->DeleteLocalRef(java_configuration);
-  }
-  return array;
+    int32_t cookie;
+    bool res = am->addAssetPath(String8(path8.c_str()), &cookie, appAsLib);
+
+    return (res) ? static_cast<jint>(cookie) : 0;
 }
 
-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;
+static jint android_content_AssetManager_addOverlayPath(JNIEnv* env, jobject clazz,
+                                                     jstring idmapPath)
+{
+    ScopedUtfChars idmapPath8(env, idmapPath);
+    if (idmapPath8.c_str() == NULL) {
+        return 0;
+    }
 
-  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);
+    AssetManager* am = assetManagerForJavaObject(env, clazz);
+    if (am == NULL) {
+        return 0;
+    }
 
-  jsize attrs_len = env->GetArrayLength(java_attrs);
-  jint* attrs = reinterpret_cast<jint*>(env->GetPrimitiveArrayCritical(java_attrs, nullptr));
-  if (attrs == nullptr) {
-    return;
-  }
+    int32_t cookie;
+    bool res = am->addOverlayPath(String8(idmapPath8.c_str()), &cookie);
 
-  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);
+    return (res) ? (jint)cookie : 0;
 }
 
-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;
-  }
+static jint android_content_AssetManager_addAssetFd(JNIEnv* env, jobject clazz,
+                                                    jobject fileDescriptor, jstring debugPathName,
+                                                    jboolean appAsLib)
+{
+    ScopedUtfChars debugPathName8(env, debugPathName);
 
-  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;
+    int fd = jniGetFDFromFileDescriptor(env, fileDescriptor);
+    if (fd < 0) {
+        jniThrowException(env, "java/lang/IllegalArgumentException", "Bad FileDescriptor");
+        return 0;
     }
-  }
 
-  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);
+    AssetManager* am = assetManagerForJavaObject(env, clazz);
+    if (am == NULL) {
+        return 0;
     }
-    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);
+    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->ReleasePrimitiveArrayCritical(out_java_values, out_values, JNI_ABORT);
+        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;
-      }
     }
-  }
-
-  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);
+    if (attrs == NULL) {
+        jniThrowNullPointerException(env, "attrs");
         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);
+    if (outValues == NULL) {
+        jniThrowNullPointerException(env, "out values");
+        return JNI_FALSE;
     }
-  }
-  return CopyValue(env, cookie, value, ref, flags, nullptr, typed_value);
+
+    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 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 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 jint NativeThemeGetChangingConfigurations(JNIEnv* /*env*/, jclass /*clazz*/,
-                                                 jlong theme_ptr) {
-  Theme* theme = reinterpret_cast<Theme*>(theme_ptr);
-  return static_cast<jint>(theme->GetChangingConfigurations());
+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 void NativeAssetDestroy(JNIEnv* /*env*/, jclass /*clazz*/, jlong asset_ptr) {
-  delete reinterpret_cast<Asset*>(asset_ptr);
+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 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 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 jint NativeAssetRead(JNIEnv* env, jclass /*clazz*/, jlong asset_ptr, jbyteArray java_buffer,
-                            jint offset, jint len) {
-  if (len == 0) {
-    return 0;
-  }
+static jlong android_content_AssetManager_openXmlAssetNative(JNIEnv* env, jobject clazz,
+                                                         jint cookie,
+                                                         jstring fileName)
+{
+    AssetManager* am = assetManagerForJavaObject(env, clazz);
+    if (am == NULL) {
+        return 0;
+    }
 
-  jsize buffer_len = env->GetArrayLength(java_buffer);
-  if (offset < 0 || offset >= buffer_len || len < 0 || len > buffer_len ||
-      offset > buffer_len - len) {
-    jniThrowException(env, "java/lang/IndexOutOfBoundsException", "");
-    return -1;
-  }
+    ALOGV("openXmlAsset in %p (Java object %p)\n", am, clazz);
 
-  ScopedByteArrayRW byte_array(env, java_buffer);
-  if (byte_array.get() == nullptr) {
-    return -1;
-  }
+    ScopedUtfChars fileName8(env, fileName);
+    if (fileName8.c_str() == NULL) {
+        return 0;
+    }
 
-  Asset* asset = reinterpret_cast<Asset*>(asset_ptr);
-  ssize_t res = asset->read(byte_array.get() + offset, len);
-  if (res < 0) {
-    jniThrowException(env, "java/io/IOException", "");
-    return -1;
-  }
-  return res > 0 ? static_cast<jint>(res) : -1;
+    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 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 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 jlong NativeAssetGetLength(JNIEnv* /*env*/, jclass /*clazz*/, jlong asset_ptr) {
-  Asset* asset = reinterpret_cast<Asset*>(asset_ptr);
-  return static_cast<jlong>(asset->getLength());
+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 jlong NativeAssetGetRemainingLength(JNIEnv* /*env*/, jclass /*clazz*/, jlong asset_ptr) {
-  Asset* asset = reinterpret_cast<Asset*>(asset_ptr);
-  return static_cast<jlong>(asset->getRemainingLength());
+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.
+/*
+ * 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},
+    /* name, signature, funcPtr */
 
-    // 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},
+    // 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 },
 
-    // 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},
+    // 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 },
 
-    // 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},
+    // 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 },
 
-    // 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},
+    // XML files.
+    { "openXmlAssetNative", "(ILjava/lang/String;)J",
+        (void*) android_content_AssetManager_openXmlAssetNative },
 
-    // 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},
+    // 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 },
 
-    // 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},
+    // 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 },
 };
 
-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");
+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");
 
-  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 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 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 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 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");
 
-  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));
+    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 2c1e357..8dd9337 100644
--- a/core/jni/include/android_runtime/android_util_AssetManager.h
+++ b/core/jni/include/android_runtime/android_util_AssetManager.h
@@ -14,20 +14,17 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_RUNTIME_ASSETMANAGER_H
-#define ANDROID_RUNTIME_ASSETMANAGER_H
+#ifndef android_util_AssetManager_H
+#define android_util_AssetManager_H
 
-#include "androidfw/AssetManager2.h"
-#include "androidfw/MutexGuard.h"
+#include <androidfw/AssetManager.h>
 
 #include "jni.h"
 
 namespace android {
 
-extern AAssetManager* NdkAssetManagerForJavaObject(JNIEnv* env, jobject jassetmanager);
-extern Guarded<AssetManager2>* AssetManagerForJavaObject(JNIEnv* env, jobject jassetmanager);
-extern Guarded<AssetManager2>* AssetManagerForNdkAssetManager(AAssetManager* assetmanager);
+extern AssetManager* assetManagerForJavaObject(JNIEnv* env, jobject assetMgr);
 
-}  // namespace android
+}
 
-#endif  // ANDROID_RUNTIME_ASSETMANAGER_H
+#endif
diff --git a/libs/androidfw/AssetManager2.cpp b/libs/androidfw/AssetManager2.cpp
index 2fc8e95..415d3e3 100644
--- a/libs/androidfw/AssetManager2.cpp
+++ b/libs/androidfw/AssetManager2.cpp
@@ -265,6 +265,8 @@
 
 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;
 
@@ -427,7 +429,9 @@
   for (size_t iteration = 0u; in_out_value->dataType == Res_value::TYPE_REFERENCE &&
                               in_out_value->data != 0u && iteration < kMaxIterations;
        iteration++) {
-    *out_last_reference = in_out_value->data;
+    if (out_last_reference != nullptr) {
+      *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 f912af4..60e3845 100644
--- a/libs/androidfw/AttributeResolution.cpp
+++ b/libs/androidfw/AttributeResolution.cpp
@@ -20,18 +20,13 @@
 
 #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:
@@ -49,53 +44,58 @@
 };
 
 class BagAttributeFinder
-    : public BackTrackingAttributeFinder<BagAttributeFinder, const ResolvedBag::Entry*> {
+    : public BackTrackingAttributeFinder<BagAttributeFinder, const ResTable::bag_entry*> {
  public:
-  BagAttributeFinder(const ResolvedBag* bag)
-      : BackTrackingAttributeFinder(bag != nullptr ? bag->entries : nullptr,
-                                    bag != nullptr ? bag->entries + bag->entry_count : nullptr) {
-  }
+  BagAttributeFinder(const ResTable::bag_entry* start,
+                     const ResTable::bag_entry* end)
+      : BackTrackingAttributeFinder(start, end) {}
 
-  inline uint32_t GetAttribute(const ResolvedBag::Entry* entry) const {
-    return entry->key;
+  inline uint32_t GetAttribute(const ResTable::bag_entry* entry) const {
+    return entry->map.name.ident;
   }
 };
 
-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) {
+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) {
   if (kDebugStyles) {
     ALOGI("APPLY STYLE: theme=0x%p defStyleAttr=0x%x defStyleRes=0x%x", theme,
           def_style_attr, def_style_res);
   }
 
-  AssetManager2* assetmanager = theme->GetAssetManager();
+  const ResTable& res = theme->getResTable();
   ResTable_config config;
   Res_value value;
 
   int indices_idx = 0;
 
   // Load default style from attribute, if specified...
-  uint32_t def_style_flags = 0u;
+  uint32_t def_style_bag_type_set_flags = 0;
   if (def_style_attr != 0) {
     Res_value value;
-    if (theme->GetAttribute(def_style_attr, &value, &def_style_flags) != kInvalidCookie) {
+    if (theme->getAttribute(def_style_attr, &value, &def_style_bag_type_set_flags) >= 0) {
       if (value.dataType == Res_value::TYPE_REFERENCE) {
         def_style_res = value.data;
       }
     }
   }
 
-  // Retrieve the default style bag, if requested.
-  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;
-    }
-  }
+  // Now lock down the resource object and start pulling stuff from it.
+  res.lock();
 
-  BagAttributeFinder def_style_attr_finder(default_style_bag);
+  // 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);
 
   // 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);
     }
 
-    ApkAssetsCookie cookie = kInvalidCookie;
+    ssize_t block = -1;
     uint32_t type_set_flags = 0;
 
     value.dataType = Res_value::TYPE_NULL;
@@ -122,14 +122,15 @@
       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 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;
+      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;
         if (kDebugStyles) {
           ALOGI("-> From def style: type=0x%x, data=0x%08x", value.dataType, value.data);
         }
@@ -139,26 +140,22 @@
     uint32_t resid = 0;
     if (value.dataType != Res_value::TYPE_NULL) {
       // Take care of resolving the found resource to its final value.
-      ApkAssetsCookie new_cookie =
-          theme->ResolveAttributeReference(cookie, &value, &config, &type_set_flags, &resid);
-      if (new_cookie != kInvalidCookie) {
-        cookie = new_cookie;
-      }
+      ssize_t new_block =
+          theme->resolveAttributeReference(&value, block, &resid, &type_set_flags, &config);
+      if (new_block >= 0) block = new_block;
       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!
-      ApkAssetsCookie new_cookie = theme->GetAttribute(cur_ident, &value, &type_set_flags);
-      if (new_cookie != kInvalidCookie) {
+      // 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 (kDebugStyles) {
           ALOGI("-> From theme: type=0x%x, data=0x%08x", value.dataType, value.data);
         }
-        new_cookie =
-            assetmanager->ResolveReference(new_cookie, &value, &config, &type_set_flags, &resid);
-        if (new_cookie != kInvalidCookie) {
-          cookie = new_cookie;
-        }
+        new_block = res.resolveReference(&value, new_block, &resid, &type_set_flags, &config);
+        if (new_block >= 0) block = new_block;
         if (kDebugStyles) {
           ALOGI("-> Resolved theme: type=0x%x, data=0x%08x", value.dataType, value.data);
         }
@@ -172,7 +169,7 @@
       }
       value.dataType = Res_value::TYPE_NULL;
       value.data = Res_value::DATA_NULL_UNDEFINED;
-      cookie = kInvalidCookie;
+      block = -1;
     }
 
     if (kDebugStyles) {
@@ -182,7 +179,9 @@
     // Write the final value back to Java.
     out_values[STYLE_TYPE] = value.dataType;
     out_values[STYLE_DATA] = value.data;
-    out_values[STYLE_ASSET_COOKIE] = ApkAssetsCookieToJavaCookie(cookie);
+    out_values[STYLE_ASSET_COOKIE] =
+        block != -1 ? static_cast<uint32_t>(res.getTableCookie(block))
+                    : static_cast<uint32_t>(-1);
     out_values[STYLE_RESOURCE_ID] = resid;
     out_values[STYLE_CHANGING_CONFIGURATIONS] = type_set_flags;
     out_values[STYLE_DENSITY] = config.density;
@@ -196,80 +195,90 @@
     out_values += STYLE_NUM_ENTRIES;
   }
 
+  res.unlock();
+
   if (out_indices != nullptr) {
     out_indices[0] = indices_idx;
   }
   return true;
 }
 
-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,
+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,
                 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_resid, xml_parser);
+    ALOGI("APPLY STYLE: theme=0x%p defStyleAttr=0x%x defStyleRes=0x%x xml=0x%p",
+          theme, def_style_attr, def_style_res, xml_parser);
   }
 
-  AssetManager2* assetmanager = theme->GetAssetManager();
+  const ResTable& res = theme->getResTable();
   ResTable_config config;
   Res_value value;
 
   int indices_idx = 0;
 
   // Load default style from attribute, if specified...
-  uint32_t def_style_flags = 0u;
+  uint32_t def_style_bag_type_set_flags = 0;
   if (def_style_attr != 0) {
     Res_value value;
-    if (theme->GetAttribute(def_style_attr, &value, &def_style_flags) != kInvalidCookie) {
+    if (theme->getAttribute(def_style_attr, &value,
+                            &def_style_bag_type_set_flags) >= 0) {
       if (value.dataType == Res_value::TYPE_REFERENCE) {
-        def_style_resid = value.data;
+        def_style_res = value.data;
       }
     }
   }
 
-  // Retrieve the style resource ID associated with the current XML tag's style attribute.
-  uint32_t style_resid = 0u;
-  uint32_t style_flags = 0u;
+  // Retrieve the style class associated with the current XML tag.
+  int style = 0;
+  uint32_t style_bag_type_set_flags = 0;
   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) {
-        // Resolve the attribute with out theme.
-        if (theme->GetAttribute(value.data, &value, &style_flags) == kInvalidCookie) {
+        if (theme->getAttribute(value.data, &value, &style_bag_type_set_flags) < 0) {
           value.dataType = Res_value::TYPE_NULL;
         }
       }
-
       if (value.dataType == value.TYPE_REFERENCE) {
-        style_resid = value.data;
+        style = value.data;
       }
     }
   }
 
-  // Retrieve the default style bag, if requested.
-  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;
-    }
-  }
+  // Now lock down the resource object and start pulling stuff from it.
+  res.lock();
 
-  BagAttributeFinder def_style_attr_finder(default_style_bag);
+  // 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);
 
   // Retrieve the style class bag, if requested.
-  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);
+  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);
 
   // 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.
@@ -280,8 +289,8 @@
       ALOGI("RETRIEVING ATTR 0x%08x...", cur_ident);
     }
 
-    ApkAssetsCookie cookie = kInvalidCookie;
-    uint32_t type_set_flags = 0u;
+    ssize_t block = kXmlBlock;
+    uint32_t type_set_flags = 0;
 
     value.dataType = Res_value::TYPE_NULL;
     value.data = Res_value::DATA_NULL_UNDEFINED;
@@ -293,7 +302,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_finder.end()) {
+    if (xml_attr_idx != xml_attr_end) {
       // We found the attribute we were looking for.
       xml_parser->getAttributeValue(xml_attr_idx, &value);
       if (kDebugStyles) {
@@ -303,12 +312,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 ResolvedBag::Entry* entry = xml_style_attr_finder.Find(cur_ident);
-      if (entry != xml_style_attr_finder.end()) {
+      const ResTable::bag_entry* const style_attr_entry = style_attr_finder.Find(cur_ident);
+      if (style_attr_entry != style_attr_end) {
         // We found the attribute we were looking for.
-        cookie = entry->cookie;
-        type_set_flags = style_flags;
-        value = entry->value;
+        block = style_attr_entry->stringBlock;
+        type_set_flags = style_type_set_flags;
+        value = style_attr_entry->map.value;
         if (kDebugStyles) {
           ALOGI("-> From style: type=0x%x, data=0x%08x", value.dataType, value.data);
         }
@@ -317,25 +326,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 ResolvedBag::Entry* entry = def_style_attr_finder.Find(cur_ident);
-      if (entry != def_style_attr_finder.end()) {
+      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) {
         // We found the attribute we were looking for.
-        cookie = entry->cookie;
-        type_set_flags = def_style_flags;
-        value = entry->value;
+        block = def_style_attr_entry->stringBlock;
+        type_set_flags = style_type_set_flags;
+        value = def_style_attr_entry->map.value;
         if (kDebugStyles) {
           ALOGI("-> From def style: type=0x%x, data=0x%08x", value.dataType, value.data);
         }
       }
     }
 
-    uint32_t resid = 0u;
+    uint32_t resid = 0;
     if (value.dataType != Res_value::TYPE_NULL) {
       // Take care of resolving the found resource to its final value.
-      ApkAssetsCookie new_cookie =
-          theme->ResolveAttributeReference(cookie, &value, &config, &type_set_flags, &resid);
-      if (new_cookie != kInvalidCookie) {
-        cookie = new_cookie;
+      ssize_t new_block =
+          theme->resolveAttributeReference(&value, block, &resid, &type_set_flags, &config);
+      if (new_block >= 0) {
+        block = new_block;
       }
 
       if (kDebugStyles) {
@@ -343,15 +352,14 @@
       }
     } 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!
-      ApkAssetsCookie new_cookie = theme->GetAttribute(cur_ident, &value, &type_set_flags);
-      if (new_cookie != kInvalidCookie) {
+      ssize_t new_block = theme->getAttribute(cur_ident, &value, &type_set_flags);
+      if (new_block >= 0) {
         if (kDebugStyles) {
           ALOGI("-> From theme: type=0x%x, data=0x%08x", value.dataType, value.data);
         }
-        new_cookie =
-            assetmanager->ResolveReference(new_cookie, &value, &config, &type_set_flags, &resid);
-        if (new_cookie != kInvalidCookie) {
-          cookie = new_cookie;
+        new_block = res.resolveReference(&value, new_block, &resid, &type_set_flags, &config);
+        if (new_block >= 0) {
+          block = new_block;
         }
 
         if (kDebugStyles) {
@@ -367,7 +375,7 @@
       }
       value.dataType = Res_value::TYPE_NULL;
       value.data = Res_value::DATA_NULL_UNDEFINED;
-      cookie = kInvalidCookie;
+      block = kXmlBlock;
     }
 
     if (kDebugStyles) {
@@ -377,7 +385,9 @@
     // Write the final value back to Java.
     out_values[STYLE_TYPE] = value.dataType;
     out_values[STYLE_DATA] = value.data;
-    out_values[STYLE_ASSET_COOKIE] = ApkAssetsCookieToJavaCookie(cookie);
+    out_values[STYLE_ASSET_COOKIE] =
+        block != kXmlBlock ? static_cast<uint32_t>(res.getTableCookie(block))
+                           : static_cast<uint32_t>(-1);
     out_values[STYLE_RESOURCE_ID] = resid;
     out_values[STYLE_CHANGING_CONFIGURATIONS] = type_set_flags;
     out_values[STYLE_DENSITY] = config.density;
@@ -392,28 +402,36 @@
     out_values += STYLE_NUM_ENTRIES;
   }
 
+  res.unlock();
+
   // out_indices must NOT be nullptr.
   out_indices[0] = indices_idx;
 }
 
-bool RetrieveAttributes(AssetManager2* assetmanager, ResXMLParser* xml_parser, uint32_t* attrs,
-                        size_t attrs_length, uint32_t* out_values, uint32_t* out_indices) {
+bool RetrieveAttributes(const ResTable* res, 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];
-    ApkAssetsCookie cookie = kInvalidCookie;
-    uint32_t type_set_flags = 0u;
+    ssize_t block = kXmlBlock;
+    uint32_t type_set_flags = 0;
 
     value.dataType = Res_value::TYPE_NULL;
     value.data = Res_value::DATA_NULL_UNDEFINED;
@@ -432,27 +450,28 @@
       cur_xml_attr = xml_parser->getAttributeNameResID(ix);
     }
 
-    uint32_t resid = 0u;
+    uint32_t resid = 0;
     if (value.dataType != Res_value::TYPE_NULL) {
       // Take care of resolving the found resource to its final value.
-      ApkAssetsCookie new_cookie =
-          assetmanager->ResolveReference(cookie, &value, &config, &type_set_flags, &resid);
-      if (new_cookie != kInvalidCookie) {
-        cookie = new_cookie;
-      }
+      // 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;
     }
 
     // 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;
-      cookie = kInvalidCookie;
+      block = kXmlBlock;
     }
 
     // Write the final value back to Java.
     out_values[STYLE_TYPE] = value.dataType;
     out_values[STYLE_DATA] = value.data;
-    out_values[STYLE_ASSET_COOKIE] = ApkAssetsCookieToJavaCookie(cookie);
+    out_values[STYLE_ASSET_COOKIE] =
+        block != kXmlBlock ? static_cast<uint32_t>(res->getTableCookie(block))
+                           : static_cast<uint32_t>(-1);
     out_values[STYLE_RESOURCE_ID] = resid;
     out_values[STYLE_CHANGING_CONFIGURATIONS] = type_set_flags;
     out_values[STYLE_DENSITY] = config.density;
@@ -466,6 +485,8 @@
     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 e08848f..28548e2 100644
--- a/libs/androidfw/LoadedArsc.cpp
+++ b/libs/androidfw/LoadedArsc.cpp
@@ -324,6 +324,8 @@
 
 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 03fad49..f281921 100644
--- a/libs/androidfw/include/androidfw/AttributeFinder.h
+++ b/libs/androidfw/include/androidfw/AttributeFinder.h
@@ -58,7 +58,6 @@
   BackTrackingAttributeFinder(const Iterator& begin, const Iterator& end);
 
   Iterator Find(uint32_t attr);
-  inline Iterator end();
 
  private:
   void JumpToClosestAttribute(uint32_t package_id);
@@ -202,11 +201,6 @@
   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 35ef98d..69b76041 100644
--- a/libs/androidfw/include/androidfw/AttributeResolution.h
+++ b/libs/androidfw/include/androidfw/AttributeResolution.h
@@ -17,8 +17,7 @@
 #ifndef ANDROIDFW_ATTRIBUTERESOLUTION_H
 #define ANDROIDFW_ATTRIBUTERESOLUTION_H
 
-#include "androidfw/AssetManager2.h"
-#include "androidfw/ResourceTypes.h"
+#include <androidfw/ResourceTypes.h>
 
 namespace android {
 
@@ -43,19 +42,19 @@
 
 // `out_values` must NOT be nullptr.
 // `out_indices` may be nullptr.
-bool ResolveAttrs(Theme* theme, uint32_t def_style_attr, uint32_t def_style_resid,
+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);
 
 // `out_values` must NOT be nullptr.
 // `out_indices` is NOT optional and must NOT be nullptr.
-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,
+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,
                 uint32_t* out_values, uint32_t* out_indices);
 
 // `out_values` must NOT be nullptr.
 // `out_indices` may be nullptr.
-bool RetrieveAttributes(AssetManager2* assetmanager, ResXMLParser* xml_parser, uint32_t* attrs,
+bool RetrieveAttributes(const ResTable* res, 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 1775f50..965e2db 100644
--- a/libs/androidfw/include/androidfw/LoadedArsc.h
+++ b/libs/androidfw/include/androidfw/LoadedArsc.h
@@ -45,17 +45,16 @@
   // 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;
+  const ResTable_entry* entry = 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;
+  // The configuration for which the resulting entry was defined.
+  const ResTable_config* config = nullptr;
 
-  // The bitmask of configuration axis with which the resource value varies.
-  uint32_t type_flags;
+  // Stores the resulting bitmask of configuration axis with which the resource value varies.
+  uint32_t type_flags = 0u;
 
   // The dynamic package ID map for the package from which this resource came from.
-  const DynamicRefTable* dynamic_ref_table;
+  const DynamicRefTable* dynamic_ref_table = nullptr;
 
   // 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
deleted file mode 100644
index 64924f4..0000000
--- a/libs/androidfw/include/androidfw/MutexGuard.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#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 cc30537..2d73ce8 100644
--- a/libs/androidfw/tests/AttributeResolution_test.cpp
+++ b/libs/androidfw/tests/AttributeResolution_test.cpp
@@ -21,7 +21,6 @@
 #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"
@@ -33,14 +32,15 @@
 class AttributeResolutionTest : public ::testing::Test {
  public:
   virtual void SetUp() override {
-    styles_assets_ = ApkAssets::Load(GetTestDataPath() + "/styles/styles.apk");
-    ASSERT_NE(nullptr, styles_assets_);
-    assetmanager_.SetApkAssets({styles_assets_.get()});
+    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*/));
   }
 
  protected:
-  std::unique_ptr<const ApkAssets> styles_assets_;
-  AssetManager2 assetmanager_;
+  ResTable table_;
 };
 
 class AttributeResolutionXmlTest : public AttributeResolutionTest {
@@ -48,12 +48,13 @@
   virtual void SetUp() override {
     AttributeResolutionTest::SetUp();
 
-    std::unique_ptr<Asset> asset =
-        assetmanager_.OpenNonAsset("res/layout/layout.xml", Asset::ACCESS_BUFFER);
-    ASSERT_NE(nullptr, asset);
+    std::string contents;
+    ASSERT_TRUE(
+        ReadFileFromZipToString(GetTestDataPath() + "/styles/styles.apk",
+                                "res/layout/layout.xml", &contents));
 
-    ASSERT_EQ(NO_ERROR,
-              xml_parser_.setTo(asset->getBuffer(true), asset->getLength(), true /*copyData*/));
+    ASSERT_EQ(NO_ERROR, xml_parser_.setTo(contents.data(), contents.size(),
+                                          true /*copyData*/));
 
     // Skip to the first tag.
     while (xml_parser_.next() != ResXMLParser::START_TAG) {
@@ -65,14 +66,14 @@
 };
 
 TEST_F(AttributeResolutionTest, Theme) {
-  std::unique_ptr<Theme> theme = assetmanager_.NewTheme();
-  ASSERT_TRUE(theme->ApplyStyle(R::style::StyleTwo));
+  ResTable::Theme theme(table_);
+  ASSERT_EQ(NO_ERROR, 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.get(), 0u /*def_style_attr*/, 0u /*def_style_res*/,
+  ASSERT_TRUE(ResolveAttrs(&theme, 0 /*def_style_attr*/, 0 /*def_style_res*/,
                            nullptr /*src_values*/, 0 /*src_values_length*/, attrs.data(),
                            attrs.size(), values.data(), nullptr /*out_indices*/));
 
@@ -125,8 +126,8 @@
                                  R::attr::attr_four, R::attr::attr_empty}};
   std::array<uint32_t, attrs.size() * STYLE_NUM_ENTRIES> values;
 
-  ASSERT_TRUE(RetrieveAttributes(&assetmanager_, &xml_parser_, attrs.data(), attrs.size(),
-                                 values.data(), nullptr /*out_indices*/));
+  ASSERT_TRUE(RetrieveAttributes(&table_, &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]);
@@ -170,15 +171,15 @@
 }
 
 TEST_F(AttributeResolutionXmlTest, ThemeAndXmlParser) {
-  std::unique_ptr<Theme> theme = assetmanager_.NewTheme();
-  ASSERT_TRUE(theme->ApplyStyle(R::style::StyleTwo));
+  ResTable::Theme theme(table_);
+  ASSERT_EQ(NO_ERROR, 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.get(), &xml_parser_, 0u /*def_style_attr*/, 0u /*def_style_res*/, attrs.data(),
+  ApplyStyle(&theme, &xml_parser_, 0 /*def_style_attr*/, 0 /*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 a8abcb5..7149bee 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 e70d5ea..98e9a42 100644
--- a/native/android/asset_manager.cpp
+++ b/native/android/asset_manager.cpp
@@ -18,11 +18,9 @@
 #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"
@@ -37,20 +35,21 @@
 
 // -----
 struct AAssetDir {
-    std::unique_ptr<AssetDir> mAssetDir;
+    AssetDir* mAssetDir;
     size_t mCurFileIndex;
     String8 mCachedFileName;
 
-    explicit AAssetDir(std::unique_ptr<AssetDir> dir) :
-        mAssetDir(std::move(dir)), mCurFileIndex(0) { }
+    explicit AAssetDir(AssetDir* dir) : mAssetDir(dir), mCurFileIndex(0) { }
+    ~AAssetDir() { delete mAssetDir; }
 };
 
 
 // -----
 struct AAsset {
-    std::unique_ptr<Asset> mAsset;
+    Asset* mAsset;
 
-    explicit AAsset(std::unique_ptr<Asset> asset) : mAsset(std::move(asset)) { }
+    explicit AAsset(Asset* asset) : mAsset(asset) { }
+    ~AAsset() { delete mAsset; }
 };
 
 // -------------------- Public native C API --------------------
@@ -105,18 +104,19 @@
         return NULL;
     }
 
-    ScopedLock<AssetManager2> locked_mgr(*AssetManagerForNdkAssetManager(amgr));
-    std::unique_ptr<Asset> asset = locked_mgr->Open(filename, amMode);
-    if (asset == nullptr) {
-        return nullptr;
+    AssetManager* mgr = static_cast<AssetManager*>(amgr);
+    Asset* asset = mgr->open(filename, amMode);
+    if (asset == NULL) {
+        return NULL;
     }
-    return new AAsset(std::move(asset));
+
+    return new AAsset(asset);
 }
 
 AAssetDir* AAssetManager_openDir(AAssetManager* amgr, const char* dirName)
 {
-    ScopedLock<AssetManager2> locked_mgr(*AssetManagerForNdkAssetManager(amgr));
-    return new AAssetDir(locked_mgr->OpenDir(dirName));
+    AssetManager* mgr = static_cast<AssetManager*>(amgr);
+    return new AAssetDir(mgr->openDir(dirName));
 }
 
 /**
diff --git a/rs/jni/android_renderscript_RenderScript.cpp b/rs/jni/android_renderscript_RenderScript.cpp
index 52d0e08e..b32be73 100644
--- a/rs/jni/android_renderscript_RenderScript.cpp
+++ b/rs/jni/android_renderscript_RenderScript.cpp
@@ -24,9 +24,8 @@
 #include <utils/misc.h>
 #include <inttypes.h>
 
-#include <android-base/macros.h>
 #include <androidfw/Asset.h>
-#include <androidfw/AssetManager2.h>
+#include <androidfw/AssetManager.h>
 #include <androidfw/ResourceTypes.h>
 #include <android-base/macros.h>
 
@@ -1665,22 +1664,18 @@
 static jlong
 nFileA3DCreateFromAsset(JNIEnv *_env, jobject _this, jlong con, jobject _assetMgr, jstring _path)
 {
-    Guarded<AssetManager2>* mgr = AssetManagerForJavaObject(_env, _assetMgr);
+    AssetManager* mgr = assetManagerForJavaObject(_env, _assetMgr);
     if (mgr == nullptr) {
         return 0;
     }
 
     AutoJavaStringToUTF8 str(_env, _path);
-    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;
-        }
+    Asset* asset = mgr->open(str.c_str(), Asset::ACCESS_BUFFER);
+    if (asset == nullptr) {
+        return 0;
     }
 
-    jlong id = (jlong)(uintptr_t)rsaFileA3DCreateFromAsset((RsContext)con, asset.release());
+    jlong id = (jlong)(uintptr_t)rsaFileA3DCreateFromAsset((RsContext)con, asset);
     return id;
 }
 
@@ -1757,25 +1752,22 @@
 nFontCreateFromAsset(JNIEnv *_env, jobject _this, jlong con, jobject _assetMgr, jstring _path,
                      jfloat fontSize, jint dpi)
 {
-    Guarded<AssetManager2>* mgr = AssetManagerForJavaObject(_env, _assetMgr);
+    AssetManager* mgr = assetManagerForJavaObject(_env, _assetMgr);
     if (mgr == nullptr) {
         return 0;
     }
 
     AutoJavaStringToUTF8 str(_env, _path);
-    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;
-        }
+    Asset* asset = 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;
 }
 
