Merge "Revert "AudioFlinger does not need libmedia any more""
diff --git a/api/current.txt b/api/current.txt
index 20b0be6..4398ea3 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -5204,6 +5204,7 @@
     field public static final java.lang.String LAYOUT_INFLATER_SERVICE = "layout_inflater";
     field public static final java.lang.String LOCATION_SERVICE = "location";
     field public static final int MODE_APPEND = 32768; // 0x8000
+    field public static final int MODE_ENABLE_WRITE_AHEAD_LOGGING = 8; // 0x8
     field public static final int MODE_MULTI_PROCESS = 4; // 0x4
     field public static final int MODE_PRIVATE = 0; // 0x0
     field public static final int MODE_WORLD_READABLE = 1; // 0x1
@@ -7334,6 +7335,7 @@
     method public deprecated boolean isDbLockedByOtherThreads();
     method public boolean isOpen();
     method public boolean isReadOnly();
+    method public boolean isWriteAheadLoggingEnabled();
     method public deprecated void markTableSyncable(java.lang.String, java.lang.String);
     method public deprecated void markTableSyncable(java.lang.String, java.lang.String, java.lang.String);
     method public boolean needUpgrade(int);
@@ -7375,6 +7377,7 @@
     field public static final int CONFLICT_REPLACE = 5; // 0x5
     field public static final int CONFLICT_ROLLBACK = 1; // 0x1
     field public static final int CREATE_IF_NECESSARY = 268435456; // 0x10000000
+    field public static final int ENABLE_WRITE_AHEAD_LOGGING = 536870912; // 0x20000000
     field public static final int MAX_SQL_CACHE_SIZE = 100; // 0x64
     field public static final int NO_LOCALIZED_COLLATORS = 16; // 0x10
     field public static final int OPEN_READONLY = 1; // 0x1
@@ -7438,6 +7441,7 @@
     method public void onDowngrade(android.database.sqlite.SQLiteDatabase, int, int);
     method public void onOpen(android.database.sqlite.SQLiteDatabase);
     method public abstract void onUpgrade(android.database.sqlite.SQLiteDatabase, int, int);
+    method public void setWriteAheadLoggingEnabled(boolean);
   }
 
   public class SQLiteOutOfMemoryException extends android.database.sqlite.SQLiteException {
@@ -23177,6 +23181,7 @@
     method public void buildLayer();
     method public boolean callOnClick();
     method public boolean canResolveLayoutDirection();
+    method public boolean canResolveTextDirection();
     method public boolean canScrollHorizontally(int);
     method public boolean canScrollVertically(int);
     method public void cancelLongPress();
@@ -23568,7 +23573,6 @@
     method public boolean willNotCacheDrawing();
     method public boolean willNotDraw();
     field public static final android.util.Property ALPHA;
-    field protected static int DEFAULT_TEXT_DIRECTION;
     field public static final int DRAWING_CACHE_QUALITY_AUTO = 0; // 0x0
     field public static final int DRAWING_CACHE_QUALITY_HIGH = 1048576; // 0x100000
     field public static final int DRAWING_CACHE_QUALITY_LOW = 524288; // 0x80000
@@ -23602,10 +23606,10 @@
     field public static final int LAYER_TYPE_HARDWARE = 2; // 0x2
     field public static final int LAYER_TYPE_NONE = 0; // 0x0
     field public static final int LAYER_TYPE_SOFTWARE = 1; // 0x1
-    field public static final int LAYOUT_DIRECTION_INHERIT = 4; // 0x4
-    field public static final int LAYOUT_DIRECTION_LOCALE = 8; // 0x8
-    field public static final int LAYOUT_DIRECTION_LTR = 1; // 0x1
-    field public static final int LAYOUT_DIRECTION_RTL = 2; // 0x2
+    field public static final int LAYOUT_DIRECTION_INHERIT = 2; // 0x2
+    field public static final int LAYOUT_DIRECTION_LOCALE = 3; // 0x3
+    field public static final int LAYOUT_DIRECTION_LTR = 0; // 0x0
+    field public static final int LAYOUT_DIRECTION_RTL = 1; // 0x1
     field public static final int MEASURED_HEIGHT_STATE_SHIFT = 16; // 0x10
     field public static final int MEASURED_SIZE_MASK = 16777215; // 0xffffff
     field public static final int MEASURED_STATE_MASK = -16777216; // 0xff000000
@@ -23652,6 +23656,7 @@
     field public static final int SYSTEM_UI_FLAG_LOW_PROFILE = 1; // 0x1
     field public static final int SYSTEM_UI_FLAG_VISIBLE = 0; // 0x0
     field public static final int TEXT_DIRECTION_ANY_RTL = 2; // 0x2
+    field protected static int TEXT_DIRECTION_DEFAULT;
     field public static final int TEXT_DIRECTION_FIRST_STRONG = 1; // 0x1
     field public static final int TEXT_DIRECTION_INHERIT = 0; // 0x0
     field public static final int TEXT_DIRECTION_LOCALE = 5; // 0x5
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 7043a73..d758ecae 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -766,17 +766,18 @@
 
     @Override
     public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory) {
-        File f = validateFilePath(name, true);
-        SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(f, factory);
-        setFilePermissionsFromMode(f.getPath(), mode, 0);
-        return db;
+        return openOrCreateDatabase(name, mode, factory, null);
     }
 
     @Override
     public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory,
             DatabaseErrorHandler errorHandler) {
         File f = validateFilePath(name, true);
-        SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(f.getPath(), factory, errorHandler);
+        int flags = SQLiteDatabase.CREATE_IF_NECESSARY;
+        if ((mode & MODE_ENABLE_WRITE_AHEAD_LOGGING) != 0) {
+            flags |= SQLiteDatabase.ENABLE_WRITE_AHEAD_LOGGING;
+        }
+        SQLiteDatabase db = SQLiteDatabase.openDatabase(f.getPath(), factory, flags, errorHandler);
         setFilePermissionsFromMode(f.getPath(), mode, 0);
         return db;
     }
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 741a6e9..2902504 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -99,6 +99,16 @@
     public static final int MODE_MULTI_PROCESS = 0x0004;
 
     /**
+     * Database open flag: when set, the database is opened with write-ahead
+     * logging enabled by default.
+     *
+     * @see #openOrCreateDatabase(String, int, CursorFactory)
+     * @see #openOrCreateDatabase(String, int, CursorFactory, DatabaseErrorHandler)
+     * @see SQLiteDatabase#enableWriteAheadLogging
+     */
+    public static final int MODE_ENABLE_WRITE_AHEAD_LOGGING = 0x0008;
+
+    /**
      * Flag for {@link #bindService}: automatically create the service as long
      * as the binding exists.  Note that while this will create the service,
      * its {@link android.app.Service#onStartCommand}
@@ -691,6 +701,7 @@
      * @param mode Operating mode.  Use 0 or {@link #MODE_PRIVATE} for the
      *     default operation, {@link #MODE_WORLD_READABLE}
      *     and {@link #MODE_WORLD_WRITEABLE} to control permissions.
+     *     Use {@link #MODE_ENABLE_WRITE_AHEAD_LOGGING} to enable write-ahead logging by default.
      * @param factory An optional factory class that is called to instantiate a
      *     cursor when query is called.
      *
@@ -700,6 +711,7 @@
      * @see #MODE_PRIVATE
      * @see #MODE_WORLD_READABLE
      * @see #MODE_WORLD_WRITEABLE
+     * @see #MODE_ENABLE_WRITE_AHEAD_LOGGING
      * @see #deleteDatabase
      */
     public abstract SQLiteDatabase openOrCreateDatabase(String name,
@@ -716,6 +728,7 @@
      * @param mode Operating mode.  Use 0 or {@link #MODE_PRIVATE} for the
      *     default operation, {@link #MODE_WORLD_READABLE}
      *     and {@link #MODE_WORLD_WRITEABLE} to control permissions.
+     *     Use {@link #MODE_ENABLE_WRITE_AHEAD_LOGGING} to enable write-ahead logging by default.
      * @param factory An optional factory class that is called to instantiate a
      *     cursor when query is called.
      * @param errorHandler the {@link DatabaseErrorHandler} to be used when sqlite reports database
@@ -726,6 +739,7 @@
      * @see #MODE_PRIVATE
      * @see #MODE_WORLD_READABLE
      * @see #MODE_WORLD_WRITEABLE
+     * @see #MODE_ENABLE_WRITE_AHEAD_LOGGING
      * @see #deleteDatabase
      */
     public abstract SQLiteDatabase openOrCreateDatabase(String name,
diff --git a/core/java/android/database/sqlite/SQLiteConnection.java b/core/java/android/database/sqlite/SQLiteConnection.java
index bf10bcb..e999316 100644
--- a/core/java/android/database/sqlite/SQLiteConnection.java
+++ b/core/java/android/database/sqlite/SQLiteConnection.java
@@ -269,7 +269,7 @@
 
     private void setWalModeFromConfiguration() {
         if (!mConfiguration.isInMemoryDb() && !mIsReadOnlyConnection) {
-            if (mConfiguration.walEnabled) {
+            if ((mConfiguration.openFlags & SQLiteDatabase.ENABLE_WRITE_AHEAD_LOGGING) != 0) {
                 setJournalMode("WAL");
                 setSyncMode(SQLiteGlobal.getWALSyncMode());
             } else {
@@ -389,7 +389,8 @@
         }
 
         // Remember what changed.
-        boolean walModeChanged = configuration.walEnabled != mConfiguration.walEnabled;
+        boolean walModeChanged = ((configuration.openFlags ^ mConfiguration.openFlags)
+                & SQLiteDatabase.ENABLE_WRITE_AHEAD_LOGGING) != 0;
         boolean localeChanged = !configuration.locale.equals(mConfiguration.locale);
 
         // Update configuration parameters.
diff --git a/core/java/android/database/sqlite/SQLiteConnectionPool.java b/core/java/android/database/sqlite/SQLiteConnectionPool.java
index 27c9ee5..0538ce4 100644
--- a/core/java/android/database/sqlite/SQLiteConnectionPool.java
+++ b/core/java/android/database/sqlite/SQLiteConnectionPool.java
@@ -81,6 +81,7 @@
     private final Object mLock = new Object();
     private final AtomicBoolean mConnectionLeaked = new AtomicBoolean();
     private final SQLiteDatabaseConfiguration mConfiguration;
+    private int mMaxConnectionPoolSize;
     private boolean mIsOpen;
     private int mNextConnectionId;
 
@@ -146,6 +147,7 @@
 
     private SQLiteConnectionPool(SQLiteDatabaseConfiguration configuration) {
         mConfiguration = new SQLiteDatabaseConfiguration(configuration);
+        setMaxConnectionPoolSizeLocked();
     }
 
     @Override
@@ -257,8 +259,9 @@
         synchronized (mLock) {
             throwIfClosedLocked();
 
-            boolean restrictToOneConnection = false;
-            if (mConfiguration.walEnabled != configuration.walEnabled) {
+            boolean walModeChanged = ((configuration.openFlags ^ mConfiguration.openFlags)
+                    & SQLiteDatabase.ENABLE_WRITE_AHEAD_LOGGING) != 0;
+            if (walModeChanged) {
                 // WAL mode can only be changed if there are no acquired connections
                 // because we need to close all but the primary connection first.
                 if (!mAcquiredConnections.isEmpty()) {
@@ -272,15 +275,13 @@
                 // because none of them are in use.
                 closeAvailableNonPrimaryConnectionsAndLogExceptionsLocked();
                 assert mAvailableNonPrimaryConnections.isEmpty();
-
-                restrictToOneConnection = true;
             }
 
             if (mConfiguration.openFlags != configuration.openFlags) {
                 // If we are changing open flags and WAL mode at the same time, then
                 // we have no choice but to close the primary connection beforehand
                 // because there can only be one connection open when we change WAL mode.
-                if (restrictToOneConnection) {
+                if (walModeChanged) {
                     closeAvailableConnectionsAndLogExceptionsLocked();
                 }
 
@@ -296,9 +297,11 @@
 
                 mAvailablePrimaryConnection = newPrimaryConnection;
                 mConfiguration.updateParametersFrom(configuration);
+                setMaxConnectionPoolSizeLocked();
             } else {
                 // Reconfigure the database connections in place.
                 mConfiguration.updateParametersFrom(configuration);
+                setMaxConnectionPoolSizeLocked();
 
                 closeExcessConnectionsAndLogExceptionsLocked();
                 reconfigureAllConnectionsLocked();
@@ -360,8 +363,7 @@
                     mAvailablePrimaryConnection = connection;
                 }
                 wakeConnectionWaitersLocked();
-            } else if (mAvailableNonPrimaryConnections.size() >=
-                    mConfiguration.maxConnectionPoolSize - 1) {
+            } else if (mAvailableNonPrimaryConnections.size() >= mMaxConnectionPoolSize - 1) {
                 closeConnectionAndLogExceptionsLocked(connection);
             } else {
                 if (recycleConnectionLocked(connection, status)) {
@@ -499,7 +501,7 @@
     // Can't throw.
     private void closeExcessConnectionsAndLogExceptionsLocked() {
         int availableCount = mAvailableNonPrimaryConnections.size();
-        while (availableCount-- > mConfiguration.maxConnectionPoolSize - 1) {
+        while (availableCount-- > mMaxConnectionPoolSize - 1) {
             SQLiteConnection connection =
                     mAvailableNonPrimaryConnections.remove(availableCount);
             closeConnectionAndLogExceptionsLocked(connection);
@@ -874,7 +876,7 @@
         if (mAvailablePrimaryConnection != null) {
             openConnections += 1;
         }
-        if (openConnections >= mConfiguration.maxConnectionPoolSize) {
+        if (openConnections >= mMaxConnectionPoolSize) {
             return null;
         }
         connection = openConnectionLocked(mConfiguration,
@@ -926,6 +928,18 @@
         return (connectionFlags & CONNECTION_FLAG_INTERACTIVE) != 0 ? 1 : 0;
     }
 
+    private void setMaxConnectionPoolSizeLocked() {
+        if ((mConfiguration.openFlags & SQLiteDatabase.ENABLE_WRITE_AHEAD_LOGGING) != 0) {
+            mMaxConnectionPoolSize = SQLiteGlobal.getWALConnectionPoolSize();
+        } else {
+            // TODO: We don't actually need to restrict the connection pool size to 1
+            // for non-WAL databases.  There might be reasons to use connection pooling
+            // with other journal modes.  For now, enabling connection pooling and
+            // using WAL are the same thing in the API.
+            mMaxConnectionPoolSize = 1;
+        }
+    }
+
     private void throwIfClosedLocked() {
         if (!mIsOpen) {
             throw new IllegalStateException("Cannot perform this operation "
@@ -972,7 +986,7 @@
         synchronized (mLock) {
             printer.println("Connection pool for " + mConfiguration.path + ":");
             printer.println("  Open: " + mIsOpen);
-            printer.println("  Max connections: " + mConfiguration.maxConnectionPoolSize);
+            printer.println("  Max connections: " + mMaxConnectionPoolSize);
 
             printer.println("  Available primary connection:");
             if (mAvailablePrimaryConnection != null) {
diff --git a/core/java/android/database/sqlite/SQLiteDatabase.java b/core/java/android/database/sqlite/SQLiteDatabase.java
index 0ecce4d..049a615 100644
--- a/core/java/android/database/sqlite/SQLiteDatabase.java
+++ b/core/java/android/database/sqlite/SQLiteDatabase.java
@@ -232,6 +232,18 @@
     public static final int CREATE_IF_NECESSARY = 0x10000000;     // update native code if changing
 
     /**
+     * Open flag: Flag for {@link #openDatabase} to open the database file with
+     * write-ahead logging enabled by default.  Using this flag is more efficient
+     * than calling {@link #enableWriteAheadLogging}.
+     *
+     * Write-ahead logging cannot be used with read-only databases so the value of
+     * this flag is ignored if the database is opened read-only.
+     *
+     * @see #enableWriteAheadLogging
+     */
+    public static final int ENABLE_WRITE_AHEAD_LOGGING = 0x20000000;
+
+    /**
      * Absolute max value that can be set by {@link #setMaxSqlCacheSize(int)}.
      *
      * Each prepared-statement is between 1K - 6K, depending on the complexity of the
@@ -654,7 +666,7 @@
      * @throws SQLiteException if the database cannot be opened
      */
     public static SQLiteDatabase openDatabase(String path, CursorFactory factory, int flags) {
-        return openDatabase(path, factory, flags, new DefaultDatabaseErrorHandler());
+        return openDatabase(path, factory, flags, null);
     }
 
     /**
@@ -694,7 +706,7 @@
      * Equivalent to openDatabase(path, factory, CREATE_IF_NECESSARY).
      */
     public static SQLiteDatabase openOrCreateDatabase(String path, CursorFactory factory) {
-        return openDatabase(path, factory, CREATE_IF_NECESSARY);
+        return openDatabase(path, factory, CREATE_IF_NECESSARY, null);
     }
 
     /**
@@ -1781,56 +1793,84 @@
     }
 
     /**
-     * This method enables parallel execution of queries from multiple threads on the same database.
-     * It does this by opening multiple handles to the database and using a different
-     * database handle for each query.
+     * This method enables parallel execution of queries from multiple threads on the
+     * same database.  It does this by opening multiple connections to the database
+     * and using a different database connection for each query.  The database
+     * journal mode is also changed to enable writes to proceed concurrently with reads.
      * <p>
-     * If a transaction is in progress on one connection handle and say, a table is updated in the
-     * transaction, then query on the same table on another connection handle will block for the
-     * transaction to complete. But this method enables such queries to execute by having them
-     * return old version of the data from the table. Most often it is the data that existed in the
-     * table prior to the above transaction updates on that table.
-     * <p>
-     * Maximum number of simultaneous handles used to execute queries in parallel is
+     * When write-ahead logging is not enabled (the default), it is not possible for
+     * reads and writes to occur on the database at the same time.  Before modifying the
+     * database, the writer implicitly acquires an exclusive lock on the database which
+     * prevents readers from accessing the database until the write is completed.
+     * </p><p>
+     * In contrast, when write-ahead logging is enabled (by calling this method), write
+     * operations occur in a separate log file which allows reads to proceed concurrently.
+     * While a write is in progress, readers on other threads will perceive the state
+     * of the database as it was before the write began.  When the write completes, readers
+     * on other threads will then perceive the new state of the database.
+     * </p><p>
+     * It is a good idea to enable write-ahead logging whenever a database will be
+     * concurrently accessed and modified by multiple threads at the same time.
+     * However, write-ahead logging uses significantly more memory than ordinary
+     * journaling because there are multiple connections to the same database.
+     * So if a database will only be used by a single thread, or if optimizing
+     * concurrency is not very important, then write-ahead logging should be disabled.
+     * </p><p>
+     * After calling this method, execution of queries in parallel is enabled as long as
+     * the database remains open.  To disable execution of queries in parallel, either
+     * call {@link #disableWriteAheadLogging} or close the database and reopen it.
+     * </p><p>
+     * The maximum number of connections used to execute queries in parallel is
      * dependent upon the device memory and possibly other properties.
-     * <p>
-     * After calling this method, execution of queries in parallel is enabled as long as this
-     * database handle is open. To disable execution of queries in parallel, database should
-     * be closed and reopened.
-     * <p>
+     * </p><p>
      * If a query is part of a transaction, then it is executed on the same database handle the
      * transaction was begun.
-     * <p>
-     * If the database has any attached databases, then execution of queries in paralel is NOT
-     * possible. In such cases, a message is printed to logcat and false is returned.
-     * <p>
-     * This feature is not available for :memory: databases. In such cases,
-     * a message is printed to logcat and false is returned.
-     * <p>
-     * A typical way to use this method is the following:
-     * <pre>
-     *     SQLiteDatabase db = SQLiteDatabase.openDatabase("db_filename", cursorFactory,
-     *             CREATE_IF_NECESSARY, myDatabaseErrorHandler);
-     *     db.enableWriteAheadLogging();
-     * </pre>
-     * <p>
+     * </p><p>
      * Writers should use {@link #beginTransactionNonExclusive()} or
      * {@link #beginTransactionWithListenerNonExclusive(SQLiteTransactionListener)}
-     * to start a trsnsaction.
-     * Non-exclusive mode allows database file to be in readable by threads executing queries.
+     * to start a transaction.  Non-exclusive mode allows database file to be in readable
+     * by other threads executing queries.
+     * </p><p>
+     * If the database has any attached databases, then execution of queries in parallel is NOT
+     * possible.  Likewise, write-ahead logging is not supported for read-only databases
+     * or memory databases.  In such cases, {@link #enableWriteAheadLogging} returns false.
+     * </p><p>
+     * The best way to enable write-ahead logging is to pass the
+     * {@link #ENABLE_WRITE_AHEAD_LOGGING} flag to {@link #openDatabase}.  This is
+     * more efficient than calling {@link #enableWriteAheadLogging}.
+     * <code><pre>
+     *     SQLiteDatabase db = SQLiteDatabase.openDatabase("db_filename", cursorFactory,
+     *             SQLiteDatabase.CREATE_IF_NECESSARY | SQLiteDatabase.ENABLE_WRITE_AHEAD_LOGGING,
+     *             myDatabaseErrorHandler);
+     *     db.enableWriteAheadLogging();
+     * </pre></code>
+     * </p><p>
+     * Another way to enable write-ahead logging is to call {@link #enableWriteAheadLogging}
+     * after opening the database.
+     * <code><pre>
+     *     SQLiteDatabase db = SQLiteDatabase.openDatabase("db_filename", cursorFactory,
+     *             SQLiteDatabase.CREATE_IF_NECESSARY, myDatabaseErrorHandler);
+     *     db.enableWriteAheadLogging();
+     * </pre></code>
+     * </p><p>
+     * See also <a href="http://sqlite.org/wal.html">SQLite Write-Ahead Logging</a> for
+     * more details about how write-ahead logging works.
      * </p>
      *
-     * @return true if write-ahead-logging is set. false otherwise
+     * @return True if write-ahead logging is enabled.
      *
      * @throws IllegalStateException if there are transactions in progress at the
      * time this method is called.  WAL mode can only be changed when there are no
      * transactions in progress.
+     *
+     * @see #ENABLE_WRITE_AHEAD_LOGGING
+     * @see #disableWriteAheadLogging
      */
     public boolean enableWriteAheadLogging() {
         synchronized (mLock) {
             throwIfNotOpenLocked();
 
-            if (mConfigurationLocked.walEnabled) {
+            if ((mConfigurationLocked.openFlags & ENABLE_WRITE_AHEAD_LOGGING) != 0) {
                 return true;
             }
 
@@ -1855,14 +1895,11 @@
                 return false;
             }
 
-            final int oldMaxConnectionPoolSize = mConfigurationLocked.maxConnectionPoolSize;
-            mConfigurationLocked.maxConnectionPoolSize = SQLiteGlobal.getWALConnectionPoolSize();
-            mConfigurationLocked.walEnabled = true;
+            mConfigurationLocked.openFlags |= ENABLE_WRITE_AHEAD_LOGGING;
             try {
                 mConnectionPoolLocked.reconfigure(mConfigurationLocked);
             } catch (RuntimeException ex) {
-                mConfigurationLocked.maxConnectionPoolSize = oldMaxConnectionPoolSize;
-                mConfigurationLocked.walEnabled = false;
+                mConfigurationLocked.openFlags &= ~ENABLE_WRITE_AHEAD_LOGGING;
                 throw ex;
             }
         }
@@ -1875,29 +1912,44 @@
      * @throws IllegalStateException if there are transactions in progress at the
      * time this method is called.  WAL mode can only be changed when there are no
      * transactions in progress.
+     *
+     * @see #enableWriteAheadLogging
      */
     public void disableWriteAheadLogging() {
         synchronized (mLock) {
             throwIfNotOpenLocked();
 
-            if (!mConfigurationLocked.walEnabled) {
+            if ((mConfigurationLocked.openFlags & ENABLE_WRITE_AHEAD_LOGGING) == 0) {
                 return;
             }
 
-            final int oldMaxConnectionPoolSize = mConfigurationLocked.maxConnectionPoolSize;
-            mConfigurationLocked.maxConnectionPoolSize = 1;
-            mConfigurationLocked.walEnabled = false;
+            mConfigurationLocked.openFlags &= ~ENABLE_WRITE_AHEAD_LOGGING;
             try {
                 mConnectionPoolLocked.reconfigure(mConfigurationLocked);
             } catch (RuntimeException ex) {
-                mConfigurationLocked.maxConnectionPoolSize = oldMaxConnectionPoolSize;
-                mConfigurationLocked.walEnabled = true;
+                mConfigurationLocked.openFlags |= ENABLE_WRITE_AHEAD_LOGGING;
                 throw ex;
             }
         }
     }
 
     /**
+     * Returns true if write-ahead logging has been enabled for this database.
+     *
+     * @return True if write-ahead logging has been enabled for this database.
+     *
+     * @see #enableWriteAheadLogging
+     * @see #ENABLE_WRITE_AHEAD_LOGGING
+     */
+    public boolean isWriteAheadLoggingEnabled() {
+        synchronized (mLock) {
+            throwIfNotOpenLocked();
+
+            return (mConfigurationLocked.openFlags & ENABLE_WRITE_AHEAD_LOGGING) != 0;
+        }
+    }
+
+    /**
      * Collect statistics about all open databases in the current process.
      * Used by bug report.
      */
diff --git a/core/java/android/database/sqlite/SQLiteDatabaseConfiguration.java b/core/java/android/database/sqlite/SQLiteDatabaseConfiguration.java
index e06a5ee..123c2c6 100644
--- a/core/java/android/database/sqlite/SQLiteDatabaseConfiguration.java
+++ b/core/java/android/database/sqlite/SQLiteDatabaseConfiguration.java
@@ -62,14 +62,6 @@
     public int openFlags;
 
     /**
-     * The maximum number of connections to retain in the connection pool.
-     * Must be at least 1.
-     *
-     * Default is 1.
-     */
-    public int maxConnectionPoolSize;
-
-    /**
      * The maximum size of the prepared statement cache for each database connection.
      * Must be non-negative.
      *
@@ -85,13 +77,6 @@
     public Locale locale;
 
     /**
-     * True if WAL mode is enabled.
-     *
-     * Default is false.
-     */
-    public boolean walEnabled;
-
-    /**
      * The custom functions to register.
      */
     public final ArrayList<SQLiteCustomFunction> customFunctions =
@@ -114,7 +99,6 @@
         this.openFlags = openFlags;
 
         // Set default values for optional parameters.
-        maxConnectionPoolSize = 1;
         maxSqlCacheSize = 25;
         locale = Locale.getDefault();
     }
@@ -150,10 +134,8 @@
         }
 
         openFlags = other.openFlags;
-        maxConnectionPoolSize = other.maxConnectionPoolSize;
         maxSqlCacheSize = other.maxSqlCacheSize;
         locale = other.locale;
-        walEnabled = other.walEnabled;
         customFunctions.clear();
         customFunctions.addAll(other.customFunctions);
     }
diff --git a/core/java/android/database/sqlite/SQLiteOpenHelper.java b/core/java/android/database/sqlite/SQLiteOpenHelper.java
index ffa4663..fe37b8f 100644
--- a/core/java/android/database/sqlite/SQLiteOpenHelper.java
+++ b/core/java/android/database/sqlite/SQLiteOpenHelper.java
@@ -58,6 +58,7 @@
 
     private SQLiteDatabase mDatabase;
     private boolean mIsInitializing;
+    private boolean mEnableWriteAheadLogging;
     private final DatabaseErrorHandler mErrorHandler;
 
     /**
@@ -74,7 +75,7 @@
      *     newer, {@link #onDowngrade} will be used to downgrade the database
      */
     public SQLiteOpenHelper(Context context, String name, CursorFactory factory, int version) {
-        this(context, name, factory, version, new DefaultDatabaseErrorHandler());
+        this(context, name, factory, version, null);
     }
 
     /**
@@ -92,14 +93,11 @@
      *     {@link #onUpgrade} will be used to upgrade the database; if the database is
      *     newer, {@link #onDowngrade} will be used to downgrade the database
      * @param errorHandler the {@link DatabaseErrorHandler} to be used when sqlite reports database
-     * corruption.
+     * corruption, or null to use the default error handler.
      */
     public SQLiteOpenHelper(Context context, String name, CursorFactory factory, int version,
             DatabaseErrorHandler errorHandler) {
         if (version < 1) throw new IllegalArgumentException("Version must be >= 1, was " + version);
-        if (errorHandler == null) {
-            throw new IllegalArgumentException("DatabaseErrorHandler param value can't be null.");
-        }
 
         mContext = context;
         mName = name;
@@ -117,6 +115,32 @@
     }
 
     /**
+     * Enables or disables the use of write-ahead logging for the database.
+     *
+     * Write-ahead logging cannot be used with read-only databases so the value of
+     * this flag is ignored if the database is opened read-only.
+     *
+     * @param enabled True if write-ahead logging should be enabled, false if it
+     * should be disabled.
+     *
+     * @see SQLiteDatabase#enableWriteAheadLogging()
+     */
+    public void setWriteAheadLoggingEnabled(boolean enabled) {
+        synchronized (this) {
+            if (mEnableWriteAheadLogging != enabled) {
+                if (mDatabase != null && mDatabase.isOpen() && !mDatabase.isReadOnly()) {
+                    if (enabled) {
+                        mDatabase.enableWriteAheadLogging();
+                    } else {
+                        mDatabase.disableWriteAheadLogging();
+                    }
+                }
+                mEnableWriteAheadLogging = enabled;
+            }
+        }
+    }
+
+    /**
      * Create and/or open a database that will be used for reading and writing.
      * The first time this is called, the database will be opened and
      * {@link #onCreate}, {@link #onUpgrade} and/or {@link #onOpen} will be
@@ -197,7 +221,9 @@
                         db = SQLiteDatabase.openDatabase(path, mFactory,
                                 SQLiteDatabase.OPEN_READONLY, mErrorHandler);
                     } else {
-                        db = mContext.openOrCreateDatabase(mName, 0, mFactory, mErrorHandler);
+                        db = mContext.openOrCreateDatabase(mName, mEnableWriteAheadLogging ?
+                                Context.MODE_ENABLE_WRITE_AHEAD_LOGGING : 0,
+                                mFactory, mErrorHandler);
                     }
                 } catch (SQLiteException ex) {
                     if (writable) {
diff --git a/core/java/android/view/DisplayList.java b/core/java/android/view/DisplayList.java
index 1dabad2..a50f09f 100644
--- a/core/java/android/view/DisplayList.java
+++ b/core/java/android/view/DisplayList.java
@@ -16,8 +16,6 @@
 
 package android.view;
 
-import android.os.Handler;
-
 /**
  * A display lists records a series of graphics related operation and can replay
  * them later. Display lists are usually built by recording operations on a
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java
index b98257c..1f140e95 100644
--- a/core/java/android/view/HardwareRenderer.java
+++ b/core/java/android/view/HardwareRenderer.java
@@ -464,8 +464,8 @@
         static final Object[] sEglLock = new Object[0];
         int mWidth = -1, mHeight = -1;
 
-        static final ThreadLocal<Gl20Renderer.Gl20RendererEglContext> sEglContextStorage
-                = new ThreadLocal<Gl20Renderer.Gl20RendererEglContext>();
+        static final ThreadLocal<ManagedEGLContext> sEglContextStorage
+                = new ThreadLocal<ManagedEGLContext>();
 
         EGLContext mEglContext;
         Thread mEglThread;
@@ -622,7 +622,7 @@
             }
         }
 
-        abstract GLES20Canvas createCanvas();
+        abstract HardwareCanvas createCanvas();
 
         abstract int[] getConfig(boolean dirtyRegions);
 
@@ -662,16 +662,18 @@
                 }
             }
 
-            Gl20Renderer.Gl20RendererEglContext managedContext = sEglContextStorage.get();
+            ManagedEGLContext managedContext = sEglContextStorage.get();
             mEglContext = managedContext != null ? managedContext.getContext() : null;
             mEglThread = Thread.currentThread();
 
             if (mEglContext == null) {
                 mEglContext = createContext(sEgl, sEglDisplay, sEglConfig);
-                sEglContextStorage.set(new Gl20Renderer.Gl20RendererEglContext(mEglContext));
+                sEglContextStorage.set(createManagedContext(mEglContext));
             }
         }
 
+        abstract ManagedEGLContext createManagedContext(EGLContext eglContext);
+
         private EGLConfig chooseEglConfig() {
             EGLConfig[] configs = new EGLConfig[1];
             int[] configsCount = new int[1];
@@ -1103,7 +1105,8 @@
                 // Make sure we do this on the correct thread.
                 if (mHandler.getLooper() != Looper.myLooper()) {
                     mHandler.post(new Runnable() {
-                        @Override public void run() {
+                        @Override
+                        public void run() {
                             onTerminate(eglContext);
                         }
                     });
@@ -1142,11 +1145,16 @@
         }
 
         @Override
-        GLES20Canvas createCanvas() {
+        HardwareCanvas createCanvas() {
             return mGlCanvas = new GLES20Canvas(mTranslucent);
         }
 
         @Override
+        ManagedEGLContext createManagedContext(EGLContext eglContext) {
+            return new Gl20Renderer.Gl20RendererEglContext(mEglContext);
+        }
+
+        @Override
         int[] getConfig(boolean dirtyRegions) {
             return new int[] {
                     EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
@@ -1249,7 +1257,8 @@
                 if (isEnabled() && checkCurrent() != SURFACE_STATE_ERROR) needsContext = false;
 
                 if (needsContext) {
-                    Gl20RendererEglContext managedContext = sEglContextStorage.get();
+                    Gl20RendererEglContext managedContext =
+                            (Gl20RendererEglContext) sEglContextStorage.get();
                     if (managedContext == null) return;
                     usePbufferSurface(managedContext.getContext());
                 }
@@ -1282,7 +1291,8 @@
         static void trimMemory(int level) {
             if (sEgl == null || sEglConfig == null) return;
 
-            Gl20RendererEglContext managedContext = sEglContextStorage.get();
+            Gl20RendererEglContext managedContext =
+                    (Gl20RendererEglContext) sEglContextStorage.get();
             // We do not have OpenGL objects
             if (managedContext == null) {
                 return;
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index ffffc73..770d899 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -1707,25 +1707,25 @@
      * Horizontal layout direction of this view is from Left to Right.
      * Use with {@link #setLayoutDirection}.
      */
-    public static final int LAYOUT_DIRECTION_LTR = 0x00000001;
+    public static final int LAYOUT_DIRECTION_LTR = 0;
 
     /**
      * Horizontal layout direction of this view is from Right to Left.
      * Use with {@link #setLayoutDirection}.
      */
-    public static final int LAYOUT_DIRECTION_RTL = 0x00000002;
+    public static final int LAYOUT_DIRECTION_RTL = 1;
 
     /**
      * Horizontal layout direction of this view is inherited from its parent.
      * Use with {@link #setLayoutDirection}.
      */
-    public static final int LAYOUT_DIRECTION_INHERIT = 0x00000004;
+    public static final int LAYOUT_DIRECTION_INHERIT = 2;
 
     /**
      * Horizontal layout direction of this view is from deduced from the default language
      * script for the locale. Use with {@link #setLayoutDirection}.
      */
-    public static final int LAYOUT_DIRECTION_LOCALE = 0x00000008;
+    public static final int LAYOUT_DIRECTION_LOCALE = 3;
 
     /**
      * Bit shift to get the horizontal layout direction. (bits after DRAG_HOVERED)
@@ -1737,34 +1737,38 @@
      * Mask for use with private flags indicating bits used for horizontal layout direction.
      * @hide
      */
-    static final int LAYOUT_DIRECTION_MASK = 0x0000000F << LAYOUT_DIRECTION_MASK_SHIFT;
+    static final int LAYOUT_DIRECTION_MASK = 0x00000003 << LAYOUT_DIRECTION_MASK_SHIFT;
 
     /**
      * Indicates whether the view horizontal layout direction has been resolved and drawn to the
      * right-to-left direction.
      * @hide
      */
-    static final int LAYOUT_DIRECTION_RESOLVED_RTL = 0x00000010 << LAYOUT_DIRECTION_MASK_SHIFT;
+    static final int LAYOUT_DIRECTION_RESOLVED_RTL = 4 << LAYOUT_DIRECTION_MASK_SHIFT;
 
     /**
      * Indicates whether the view horizontal layout direction has been resolved.
      * @hide
      */
-    static final int LAYOUT_DIRECTION_RESOLVED = 0x00000020 << LAYOUT_DIRECTION_MASK_SHIFT;
+    static final int LAYOUT_DIRECTION_RESOLVED = 8 << LAYOUT_DIRECTION_MASK_SHIFT;
 
     /**
      * Mask for use with private flags indicating bits used for resolved horizontal layout direction.
      * @hide
      */
-    static final int LAYOUT_DIRECTION_RESOLVED_MASK = 0x00000030 << LAYOUT_DIRECTION_MASK_SHIFT;
+    static final int LAYOUT_DIRECTION_RESOLVED_MASK = 0x0000000C << LAYOUT_DIRECTION_MASK_SHIFT;
 
     /*
      * Array of horizontal layout direction flags for mapping attribute "layoutDirection" to correct
      * flag value.
      * @hide
      */
-    private static final int[] LAYOUT_DIRECTION_FLAGS = {LAYOUT_DIRECTION_LTR,
-            LAYOUT_DIRECTION_RTL, LAYOUT_DIRECTION_INHERIT, LAYOUT_DIRECTION_LOCALE};
+    private static final int[] LAYOUT_DIRECTION_FLAGS = {
+            LAYOUT_DIRECTION_LTR,
+            LAYOUT_DIRECTION_RTL,
+            LAYOUT_DIRECTION_INHERIT,
+            LAYOUT_DIRECTION_LOCALE
+    };
 
     /**
      * Default horizontal layout direction.
@@ -1783,6 +1787,97 @@
     static final int HAS_TRANSIENT_STATE = 0x00000100;
 
 
+    /**
+     * Text direction is inherited thru {@link ViewGroup}
+     */
+    public static final int TEXT_DIRECTION_INHERIT = 0;
+
+    /**
+     * Text direction is using "first strong algorithm". The first strong directional character
+     * determines the paragraph direction. If there is no strong directional character, the
+     * paragraph direction is the view's resolved layout direction.
+     */
+    public static final int TEXT_DIRECTION_FIRST_STRONG = 1;
+
+    /**
+     * Text direction is using "any-RTL" algorithm. The paragraph direction is RTL if it contains
+     * any strong RTL character, otherwise it is LTR if it contains any strong LTR characters.
+     * If there are neither, the paragraph direction is the view's resolved layout direction.
+     */
+    public static final int TEXT_DIRECTION_ANY_RTL = 2;
+
+    /**
+     * Text direction is forced to LTR.
+     */
+    public static final int TEXT_DIRECTION_LTR = 3;
+
+    /**
+     * Text direction is forced to RTL.
+     */
+    public static final int TEXT_DIRECTION_RTL = 4;
+
+    /**
+     * Text direction is coming from the system Locale.
+     */
+    public static final int TEXT_DIRECTION_LOCALE = 5;
+
+    /**
+     * Bit shift to get the horizontal layout direction. (bits after LAYOUT_DIRECTION_RESOLVED)
+     * @hide
+     */
+    static final int TEXT_DIRECTION_MASK_SHIFT = 6;
+
+    /**
+     * Default text direction is inherited
+     */
+    protected static int TEXT_DIRECTION_DEFAULT = TEXT_DIRECTION_INHERIT;
+
+    /**
+     * Mask for use with private flags indicating bits used for text direction.
+     * @hide
+     */
+    static final int TEXT_DIRECTION_MASK = 0x00000007 << TEXT_DIRECTION_MASK_SHIFT;
+
+    /**
+     * Array of text direction flags for mapping attribute "textDirection" to correct
+     * flag value.
+     * @hide
+     */
+    private static final int[] TEXT_DIRECTION_FLAGS = {
+            TEXT_DIRECTION_INHERIT << TEXT_DIRECTION_MASK_SHIFT,
+            TEXT_DIRECTION_FIRST_STRONG << TEXT_DIRECTION_MASK_SHIFT,
+            TEXT_DIRECTION_ANY_RTL << TEXT_DIRECTION_MASK_SHIFT,
+            TEXT_DIRECTION_LTR << TEXT_DIRECTION_MASK_SHIFT,
+            TEXT_DIRECTION_RTL << TEXT_DIRECTION_MASK_SHIFT,
+            TEXT_DIRECTION_LOCALE << TEXT_DIRECTION_MASK_SHIFT
+    };
+
+    /**
+     * Indicates whether the view text direction has been resolved.
+     * @hide
+     */
+    static final int TEXT_DIRECTION_RESOLVED = 0x00000008 << TEXT_DIRECTION_MASK_SHIFT;
+
+    /**
+     * Bit shift to get the horizontal layout direction. (bits after DRAG_HOVERED)
+     * @hide
+     */
+    static final int TEXT_DIRECTION_RESOLVED_MASK_SHIFT = 10;
+
+    /**
+     * Mask for use with private flags indicating bits used for resolved text direction.
+     * @hide
+     */
+    static final int TEXT_DIRECTION_RESOLVED_MASK = 0x00000007 << TEXT_DIRECTION_RESOLVED_MASK_SHIFT;
+
+    /**
+     * Indicates whether the view text direction has been resolved to the "first strong" heuristic.
+     * @hide
+     */
+    static final int TEXT_DIRECTION_RESOLVED_DEFAULT =
+            TEXT_DIRECTION_FIRST_STRONG << TEXT_DIRECTION_RESOLVED_MASK_SHIFT;
+
+
     /* End of masks for mPrivateFlags2 */
 
     static final int DRAG_MASK = DRAG_CAN_ACCEPT | DRAG_HOVERED;
@@ -2657,82 +2752,6 @@
     AccessibilityDelegate mAccessibilityDelegate;
 
     /**
-     * Text direction is inherited thru {@link ViewGroup}
-     */
-    public static final int TEXT_DIRECTION_INHERIT = 0;
-
-    /**
-     * Text direction is using "first strong algorithm". The first strong directional character
-     * determines the paragraph direction. If there is no strong directional character, the
-     * paragraph direction is the view's resolved layout direction.
-     *
-     */
-    public static final int TEXT_DIRECTION_FIRST_STRONG = 1;
-
-    /**
-     * Text direction is using "any-RTL" algorithm. The paragraph direction is RTL if it contains
-     * any strong RTL character, otherwise it is LTR if it contains any strong LTR characters.
-     * If there are neither, the paragraph direction is the view's resolved layout direction.
-     *
-     */
-    public static final int TEXT_DIRECTION_ANY_RTL = 2;
-
-    /**
-     * Text direction is forced to LTR.
-     *
-     */
-    public static final int TEXT_DIRECTION_LTR = 3;
-
-    /**
-     * Text direction is forced to RTL.
-     *
-     */
-    public static final int TEXT_DIRECTION_RTL = 4;
-
-    /**
-     * Text direction is coming from the system Locale.
-     *
-     */
-    public static final int TEXT_DIRECTION_LOCALE = 5;
-
-    /**
-     * Default text direction is inherited
-     *
-     */
-    protected static int DEFAULT_TEXT_DIRECTION = TEXT_DIRECTION_INHERIT;
-
-    /**
-     * The text direction that has been defined by {@link #setTextDirection(int)}.
-     *
-     */
-    @ViewDebug.ExportedProperty(category = "text", mapping = {
-            @ViewDebug.IntToString(from = TEXT_DIRECTION_INHERIT, to = "INHERIT"),
-            @ViewDebug.IntToString(from = TEXT_DIRECTION_FIRST_STRONG, to = "FIRST_STRONG"),
-            @ViewDebug.IntToString(from = TEXT_DIRECTION_ANY_RTL, to = "ANY_RTL"),
-            @ViewDebug.IntToString(from = TEXT_DIRECTION_LTR, to = "LTR"),
-            @ViewDebug.IntToString(from = TEXT_DIRECTION_RTL, to = "RTL"),
-            @ViewDebug.IntToString(from = TEXT_DIRECTION_LOCALE, to = "LOCALE")
-    })
-    private int mTextDirection = DEFAULT_TEXT_DIRECTION;
-
-    /**
-     * The resolved text direction.  This needs resolution if the value is
-     * TEXT_DIRECTION_INHERIT.  The resolution matches mTextDirection if it is
-     * not TEXT_DIRECTION_INHERIT, otherwise resolution proceeds up the parent
-     * chain of the view.
-     *
-     */
-    @ViewDebug.ExportedProperty(category = "text", mapping = {
-            @ViewDebug.IntToString(from = TEXT_DIRECTION_INHERIT, to = "INHERIT"),
-            @ViewDebug.IntToString(from = TEXT_DIRECTION_FIRST_STRONG, to = "FIRST_STRONG"),
-            @ViewDebug.IntToString(from = TEXT_DIRECTION_ANY_RTL, to = "ANY_RTL"),
-            @ViewDebug.IntToString(from = TEXT_DIRECTION_LTR, to = "LTR"),
-            @ViewDebug.IntToString(from = TEXT_DIRECTION_RTL, to = "RTL"),
-            @ViewDebug.IntToString(from = TEXT_DIRECTION_LOCALE, to = "LOCALE")
-    })
-    private int mResolvedTextDirection = TEXT_DIRECTION_INHERIT;
-
-    /**
      * Consistency verifier for debugging purposes.
      * @hide
      */
@@ -2750,7 +2769,9 @@
         mContext = context;
         mResources = context != null ? context.getResources() : null;
         mViewFlags = SOUND_EFFECTS_ENABLED | HAPTIC_FEEDBACK_ENABLED;
-        mPrivateFlags2 |= (LAYOUT_DIRECTION_DEFAULT << LAYOUT_DIRECTION_MASK_SHIFT);
+        // Set layout and text direction defaults
+        mPrivateFlags2 = (LAYOUT_DIRECTION_DEFAULT << LAYOUT_DIRECTION_MASK_SHIFT) |
+                (TEXT_DIRECTION_DEFAULT << TEXT_DIRECTION_MASK_SHIFT);
         mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
         setOverScrollMode(OVER_SCROLL_IF_CONTENT_SCROLLS);
         mUserPaddingStart = -1;
@@ -3110,7 +3131,13 @@
                     setLayerType(a.getInt(attr, LAYER_TYPE_NONE), null);
                     break;
                 case R.styleable.View_textDirection:
-                    mTextDirection = a.getInt(attr, DEFAULT_TEXT_DIRECTION);
+                    // Clear any text direction flag already set
+                    mPrivateFlags2 &= ~TEXT_DIRECTION_MASK;
+                    // Set the text direction flags depending on the value of the attribute
+                    final int textDirection = a.getInt(attr, -1);
+                    if (textDirection != -1) {
+                        mPrivateFlags2 |= TEXT_DIRECTION_FLAGS[textDirection];
+                    }
                     break;
             }
         }
@@ -14491,8 +14518,16 @@
      * {@link #TEXT_DIRECTION_RTL},
      * {@link #TEXT_DIRECTION_LOCALE},
      */
+    @ViewDebug.ExportedProperty(category = "text", mapping = {
+            @ViewDebug.IntToString(from = TEXT_DIRECTION_INHERIT, to = "INHERIT"),
+            @ViewDebug.IntToString(from = TEXT_DIRECTION_FIRST_STRONG, to = "FIRST_STRONG"),
+            @ViewDebug.IntToString(from = TEXT_DIRECTION_ANY_RTL, to = "ANY_RTL"),
+            @ViewDebug.IntToString(from = TEXT_DIRECTION_LTR, to = "LTR"),
+            @ViewDebug.IntToString(from = TEXT_DIRECTION_RTL, to = "RTL"),
+            @ViewDebug.IntToString(from = TEXT_DIRECTION_LOCALE, to = "LOCALE")
+    })
     public int getTextDirection() {
-        return mTextDirection;
+        return (mPrivateFlags2 & TEXT_DIRECTION_MASK) >> TEXT_DIRECTION_MASK_SHIFT;
     }
 
     /**
@@ -14508,9 +14543,14 @@
      * {@link #TEXT_DIRECTION_LOCALE},
      */
     public void setTextDirection(int textDirection) {
-        if (textDirection != mTextDirection) {
-            mTextDirection = textDirection;
+        if (getTextDirection() != textDirection) {
+            // Reset the current text direction
+            mPrivateFlags2 &= ~TEXT_DIRECTION_MASK;
+            // Set the new text direction
+            mPrivateFlags2 |= ((textDirection << TEXT_DIRECTION_MASK_SHIFT) & TEXT_DIRECTION_MASK);
+            // Reset the current resolved text direction
             resetResolvedTextDirection();
+            // Ask for a layout pass
             requestLayout();
         }
     }
@@ -14518,7 +14558,12 @@
     /**
      * Return the resolved text direction.
      *
-     * @return the resolved text direction. Return one of:
+     * This needs resolution if the value is TEXT_DIRECTION_INHERIT. The resolution matches
+     * {@link #getTextDirection()}if it is not TEXT_DIRECTION_INHERIT, otherwise resolution proceeds
+     * up the parent chain of the view. if there is no parent, then it will return the default
+     * {@link #TEXT_DIRECTION_FIRST_STRONG}.
+     *
+     * @return the resolved text direction. Returns one of:
      *
      * {@link #TEXT_DIRECTION_FIRST_STRONG}
      * {@link #TEXT_DIRECTION_ANY_RTL},
@@ -14527,10 +14572,11 @@
      * {@link #TEXT_DIRECTION_LOCALE},
      */
     public int getResolvedTextDirection() {
-        if (mResolvedTextDirection == TEXT_DIRECTION_INHERIT) {
+        // The text direction is not inherited so return it back
+        if ((mPrivateFlags2 & TEXT_DIRECTION_RESOLVED) != TEXT_DIRECTION_RESOLVED) {
             resolveTextDirection();
         }
-        return mResolvedTextDirection;
+        return (mPrivateFlags2 & TEXT_DIRECTION_RESOLVED_MASK) >> TEXT_DIRECTION_RESOLVED_MASK_SHIFT;
     }
 
     /**
@@ -14538,17 +14584,51 @@
      * resolution is done.
      */
     public void resolveTextDirection() {
-        if (mResolvedTextDirection != TEXT_DIRECTION_INHERIT) {
-            // Resolution has already been done.
-            return;
+        // Reset any previous text direction resolution
+        mPrivateFlags2 &= ~(TEXT_DIRECTION_RESOLVED | TEXT_DIRECTION_RESOLVED_MASK);
+
+        // Set resolved text direction flag depending on text direction flag
+        final int textDirection = getTextDirection();
+        switch(textDirection) {
+            case TEXT_DIRECTION_INHERIT:
+                if (canResolveTextDirection()) {
+                    ViewGroup viewGroup = ((ViewGroup) mParent);
+
+                    // Set current resolved direction to the same value as the parent's one
+                    final int parentResolvedDirection = viewGroup.getResolvedTextDirection();
+                    switch (parentResolvedDirection) {
+                        case TEXT_DIRECTION_FIRST_STRONG:
+                        case TEXT_DIRECTION_ANY_RTL:
+                        case TEXT_DIRECTION_LTR:
+                        case TEXT_DIRECTION_RTL:
+                        case TEXT_DIRECTION_LOCALE:
+                            mPrivateFlags2 |=
+                                    (parentResolvedDirection << TEXT_DIRECTION_RESOLVED_MASK_SHIFT);
+                            break;
+                        default:
+                            // Default resolved direction is "first strong" heuristic
+                            mPrivateFlags2 |= TEXT_DIRECTION_RESOLVED_DEFAULT;
+                    }
+                } else {
+                    // We cannot do the resolution if there is no parent, so use the default one
+                    mPrivateFlags2 |= TEXT_DIRECTION_RESOLVED_DEFAULT;
+                }
+                break;
+            case TEXT_DIRECTION_FIRST_STRONG:
+            case TEXT_DIRECTION_ANY_RTL:
+            case TEXT_DIRECTION_LTR:
+            case TEXT_DIRECTION_RTL:
+            case TEXT_DIRECTION_LOCALE:
+                // Resolved direction is the same as text direction
+                mPrivateFlags2 |= (textDirection << TEXT_DIRECTION_RESOLVED_MASK_SHIFT);
+                break;
+            default:
+                // Default resolved direction is "first strong" heuristic
+                mPrivateFlags2 |= TEXT_DIRECTION_RESOLVED_DEFAULT;
         }
-        if (mTextDirection != TEXT_DIRECTION_INHERIT) {
-            mResolvedTextDirection = mTextDirection;
-        } else if (mParent != null && mParent instanceof ViewGroup) {
-            mResolvedTextDirection = ((ViewGroup) mParent).getResolvedTextDirection();
-        } else {
-            mResolvedTextDirection = TEXT_DIRECTION_FIRST_STRONG;
-        }
+
+        // Set to resolved
+        mPrivateFlags2 |= TEXT_DIRECTION_RESOLVED;
         onResolvedTextDirectionChanged();
     }
 
@@ -14562,12 +14642,26 @@
     }
 
     /**
+     * Check if text direction resolution can be done.
+     *
+     * @return true if text direction resolution can be done otherwise return false.
+     */
+    public boolean canResolveTextDirection() {
+        switch (getTextDirection()) {
+            case TEXT_DIRECTION_INHERIT:
+                return (mParent != null) && (mParent instanceof ViewGroup);
+            default:
+                return true;
+        }
+    }
+
+    /**
      * Reset resolved text direction. Text direction can be resolved with a call to
      * getResolvedTextDirection(). Will call {@link View#onResolvedTextDirectionReset} when
      * reset is done.
      */
     public void resetResolvedTextDirection() {
-        mResolvedTextDirection = TEXT_DIRECTION_INHERIT;
+        mPrivateFlags2 &= ~(TEXT_DIRECTION_RESOLVED | TEXT_DIRECTION_RESOLVED_MASK);
         onResolvedTextDirectionReset();
     }
 
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index 0e5ff20..17dbde8 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -403,6 +403,9 @@
                                 mIInputContext.finishComposingText();
                             } catch (RemoteException e) {
                             }
+                            // Check focus again in case that "onWindowFocus" is called before
+                            // handling this message.
+                            checkFocus(mHasBeenInactive);
                         }
                     }
                     return;
@@ -1173,13 +1176,17 @@
         }
     }
 
+    private void checkFocus(boolean forceNewFocus) {
+        if (checkFocusNoStartInput(forceNewFocus)) {
+            startInputInner(null, 0, 0, 0);
+        }
+    }
+
     /**
      * @hide
      */
     public void checkFocus() {
-        if (checkFocusNoStartInput(false)) {
-            startInputInner(null, 0, 0, 0);
-        }
+        checkFocus(false);
     }
 
     private boolean checkFocusNoStartInput(boolean forceNewFocus) {
diff --git a/core/java/android/webkit/WebViewDatabase.java b/core/java/android/webkit/WebViewDatabase.java
index 757a619..6c35f19 100644
--- a/core/java/android/webkit/WebViewDatabase.java
+++ b/core/java/android/webkit/WebViewDatabase.java
@@ -144,7 +144,6 @@
                         null);
             }
         }
-        mDatabase.enableWriteAheadLogging();
 
         // mDatabase should not be null,
         // the only case is RequestAPI test has problem to create db
@@ -163,11 +162,6 @@
                 mDatabase.endTransaction();
             }
         }
-
-        // use per table Mutex lock, turn off database lock, this
-        // improves performance as database's ReentrantLock is
-        // expansive
-        mDatabase.setLockingEnabled(false);
     }
 
     private static void upgradeDatabase() {
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index 0563846..af722a8 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -33,14 +33,17 @@
 import android.os.Bundle;
 import android.os.PatternMatcher;
 import android.util.Log;
+import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
-import android.view.LayoutInflater;
+import android.widget.AdapterView;
 import android.widget.BaseAdapter;
 import android.widget.CheckBox;
 import android.widget.CompoundButton;
 import android.widget.ImageView;
+import android.widget.ListView;
 import android.widget.TextView;
+
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashSet;
@@ -122,6 +125,11 @@
         }
 
         setupAlert();
+
+        ListView lv = mAlert.getListView();
+        if (lv != null) {
+            lv.setOnItemLongClickListener(new ItemLongClickListener());
+        }
     }
 
     @Override
@@ -489,5 +497,18 @@
             mClearDefaultHint.setVisibility(View.GONE);
         }
     }
+
+    class ItemLongClickListener implements AdapterView.OnItemLongClickListener {
+
+        @Override
+        public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
+            ResolveInfo ri = mAdapter.resolveInfoForPosition(position);
+            Intent in = new Intent().setAction("android.settings.APPLICATION_DETAILS_SETTINGS")
+                    .setData(Uri.fromParts("package", ri.activityInfo.packageName, null));
+            startActivity(in);
+            return true;
+        }
+
+    }
 }
 
diff --git a/core/jni/com_android_internal_content_NativeLibraryHelper.cpp b/core/jni/com_android_internal_content_NativeLibraryHelper.cpp
index afbcfc2..8d6fab4 100644
--- a/core/jni/com_android_internal_content_NativeLibraryHelper.cpp
+++ b/core/jni/com_android_internal_content_NativeLibraryHelper.cpp
@@ -20,8 +20,8 @@
 #include <android_runtime/AndroidRuntime.h>
 
 #include <utils/Log.h>
+#include <utils/ZipFileRO.h>
 #include <ScopedUtfChars.h>
-#include <androidfw/ZipFileRO.h>
 
 #include <zlib.h>
 
diff --git a/data/fonts/vendor_fonts.xml b/data/fonts/vendor_fonts.xml
index c1116d0..5850f94 100644
--- a/data/fonts/vendor_fonts.xml
+++ b/data/fonts/vendor_fonts.xml
@@ -3,7 +3,12 @@
     Vendor-provided fallback fonts
 
     This file can be edited to add references to fonts that are not installed or referenced in the
-    default system. The file should then be placed in /vendor/etc/fallback_fonts.xml.
+    default system. The file should then be placed in /vendor/etc/fallback_fonts.xml. Note
+    that in your makefile, this directory should be referenced as $(TARGET_COPY_OUT_VENDOR)/etc/:
+
+        PRODUCT_COPY_FILES += \
+            frameworks/base/data/fonts/vendor_fonts.xml:$(TARGET_COPY_OUT_VENDOR)/etc/fallback_fonts.xml \
+            frameworks/base/data/fonts/vendor_fonts-ja.xml:$(TARGET_COPY_OUT_VENDOR)/etc/fallback_fonts-ja.xml
 
     For example, vendors might want to build configurations for locales that are
     better served by fonts which either handle glyphs not supported in the default fonts or which
@@ -28,11 +33,31 @@
     Han languages (Chinese, Japanese, and Korean) share a common range of unicode characters;
     their ordering in the fallback or vendor files gives priority to the first in the list.
     Locale-specific ordering can be configured by adding language and region codes to the end
-    of the filename (e.g. /system/etc/fallback_fonts-ja.xml). When no region code is used,
+    of the filename (e.g. /vendor/etc/fallback_fonts-ja.xml). When no region code is used,
     as with this example, all regions are matched. Use separate files for each supported locale.
     The standard fallback file (fallback_fonts.xml) is used when a locale does not have its own
     file. All fallback files must contain the same complete set of fonts; only their ordering
-    can differ.
+    can differ. For example, on a device supporting Japanese, but with English as the default,
+    /vendor/etc/fallback_fonts.xml might contain:
+
+        <familyset>
+            <family>
+                <fileset>
+                    <file>DroidSansJapanese.ttf</file>
+                </fileset>
+            </family>
+        </familyset>
+
+    placing the Japanese font at the end of the fallback sequence for English, with a corresponding
+    /system/vendor/etc/fallback_fonts-ja.xml, placing it at the front of the list.
+
+        <familyset>
+            <family order="0">
+                <fileset>
+                    <file>DroidSansJapanese.ttf</file>
+                </fileset>
+            </family>
+        </familyset>
 
     The sample configuration below is an example of how one might provide two families of fonts
     that get inserted at the first and second (0  and 1) position in the overall fallback fonts.
diff --git a/graphics/java/android/renderscript/Allocation.java b/graphics/java/android/renderscript/Allocation.java
index 6539ff3..adeeaca 100644
--- a/graphics/java/android/renderscript/Allocation.java
+++ b/graphics/java/android/renderscript/Allocation.java
@@ -131,22 +131,13 @@
     public static final int USAGE_GRAPHICS_RENDER_TARGET = 0x0010;
 
     /**
-     * USAGE_GRAPHICS_SURFACE_TEXTURE_INPUT_OPAQUE The allocation
-     * will be used as a SurfaceTexture graphics consumer. This
-     * usage may only be used with USAGE_GRAPHICS_TEXTURE.
-     *
-     * @hide
-     */
-    public static final int USAGE_GRAPHICS_SURFACE_TEXTURE_INPUT_OPAQUE = 0x0020;
-
-    /**
      * USAGE_IO_INPUT The allocation will be used as SurfaceTexture
      * consumer.  This usage will cause the allocation to be created
      * read only.
      *
      * @hide
      */
-    public static final int USAGE_IO_INPUT = 0x0040;
+    public static final int USAGE_IO_INPUT = 0x0020;
 
     /**
      * USAGE_IO_OUTPUT The allocation will be used as a
@@ -155,7 +146,7 @@
      *
      * @hide
      */
-    public static final int USAGE_IO_OUTPUT = 0x0080;
+    public static final int USAGE_IO_OUTPUT = 0x0040;
 
     /**
      * Controls mipmap behavior when using the bitmap creation and
@@ -217,17 +208,15 @@
                        USAGE_GRAPHICS_VERTEX |
                        USAGE_GRAPHICS_CONSTANTS |
                        USAGE_GRAPHICS_RENDER_TARGET |
-                       USAGE_GRAPHICS_SURFACE_TEXTURE_INPUT_OPAQUE |
                        USAGE_IO_INPUT |
                        USAGE_IO_OUTPUT)) != 0) {
             throw new RSIllegalArgumentException("Unknown usage specified.");
         }
 
-        if ((usage & (USAGE_GRAPHICS_SURFACE_TEXTURE_INPUT_OPAQUE | USAGE_IO_INPUT)) != 0) {
+        if ((usage & USAGE_IO_INPUT) != 0) {
             mWriteAllowed = false;
 
-            if ((usage & ~(USAGE_GRAPHICS_SURFACE_TEXTURE_INPUT_OPAQUE |
-                           USAGE_IO_INPUT |
+            if ((usage & ~(USAGE_IO_INPUT |
                            USAGE_GRAPHICS_TEXTURE |
                            USAGE_SCRIPT)) != 0) {
                 throw new RSIllegalArgumentException("Invalid usage combination.");
@@ -348,7 +337,7 @@
     public void ioGetInput() {
         if ((mUsage & USAGE_IO_INPUT) == 0) {
             throw new RSIllegalArgumentException(
-                "Can only send buffer if IO_OUTPUT usage specified.");
+                "Can only receive if IO_INPUT usage specified.");
         }
         mRS.validate();
         mRS.nAllocationIoReceive(getID());
@@ -1134,13 +1123,15 @@
      *
      */
     public SurfaceTexture getSurfaceTexture() {
-        if ((mUsage & USAGE_GRAPHICS_SURFACE_TEXTURE_INPUT_OPAQUE) == 0) {
+        if ((mUsage & USAGE_IO_INPUT) == 0) {
             throw new RSInvalidStateException("Allocation is not a surface texture.");
         }
 
         int id = mRS.nAllocationGetSurfaceTextureID(getID());
-        return new SurfaceTexture(id);
+        SurfaceTexture st = new SurfaceTexture(id);
+        mRS.nAllocationGetSurfaceTextureID2(getID(), st);
 
+        return st;
     }
 
     /**
diff --git a/graphics/java/android/renderscript/RenderScript.java b/graphics/java/android/renderscript/RenderScript.java
index 6921f37..ab6ba54 100644
--- a/graphics/java/android/renderscript/RenderScript.java
+++ b/graphics/java/android/renderscript/RenderScript.java
@@ -16,8 +16,8 @@
 
 package android.renderscript;
 
-import java.lang.reflect.Field;
 import java.io.File;
+import java.lang.reflect.Field;
 
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
@@ -294,6 +294,11 @@
         validate();
         return rsnAllocationGetSurfaceTextureID(mContext, alloc);
     }
+    native void rsnAllocationGetSurfaceTextureID2(int con, int alloc, SurfaceTexture st);
+    synchronized void nAllocationGetSurfaceTextureID2(int alloc, SurfaceTexture st) {
+        validate();
+        rsnAllocationGetSurfaceTextureID2(mContext, alloc, st);
+    }
     native void rsnAllocationSetSurfaceTexture(int con, int alloc, SurfaceTexture sur);
     synchronized void nAllocationSetSurfaceTexture(int alloc, SurfaceTexture sur) {
         validate();
diff --git a/graphics/jni/android_renderscript_RenderScript.cpp b/graphics/jni/android_renderscript_RenderScript.cpp
index 9fc4fd4..9d4c64f 100644
--- a/graphics/jni/android_renderscript_RenderScript.cpp
+++ b/graphics/jni/android_renderscript_RenderScript.cpp
@@ -477,6 +477,15 @@
 }
 
 static void
+nAllocationGetSurfaceTextureID2(JNIEnv *_env, jobject _this, RsContext con, jint a, jobject jst)
+{
+    LOG_API("nAllocationGetSurfaceTextureID2, con(%p), a(%p)", con, (RsAllocation)a);
+    sp<SurfaceTexture> st = SurfaceTexture_getSurfaceTexture(_env, jst);
+
+    rsAllocationGetSurfaceTextureID2(con, (RsAllocation)a, st.get(), sizeof(SurfaceTexture *));
+}
+
+static void
 nAllocationSetSurfaceTexture(JNIEnv *_env, jobject _this, RsContext con,
                              RsAllocation alloc, jobject sur)
 {
@@ -1352,7 +1361,8 @@
 
 {"rsnAllocationSyncAll",             "(III)V",                                (void*)nAllocationSyncAll },
 {"rsnAllocationGetSurfaceTextureID", "(II)I",                                 (void*)nAllocationGetSurfaceTextureID },
-{"rsnAllocationSetSurfaceTexture",   "(IILandroid/graphics/SurfaceTexture;)V", (void*)nAllocationSetSurfaceTexture },
+{"rsnAllocationGetSurfaceTextureID2","(IILandroid/graphics/SurfaceTexture;)V",(void*)nAllocationGetSurfaceTextureID2 },
+{"rsnAllocationSetSurfaceTexture",   "(IILandroid/graphics/SurfaceTexture;)V",(void*)nAllocationSetSurfaceTexture },
 {"rsnAllocationIoSend",              "(II)V",                                 (void*)nAllocationIoSend },
 {"rsnAllocationIoReceive",           "(II)V",                                 (void*)nAllocationIoReceive },
 {"rsnAllocationData1D",              "(IIIII[II)V",                           (void*)nAllocationData1D_i },
diff --git a/include/androidfw/AssetManager.h b/include/androidfw/AssetManager.h
index d95b45e..d153c31 100644
--- a/include/androidfw/AssetManager.h
+++ b/include/androidfw/AssetManager.h
@@ -22,13 +22,13 @@
 
 #include <androidfw/Asset.h>
 #include <androidfw/AssetDir.h>
-#include <androidfw/ZipFileRO.h>
 #include <utils/KeyedVector.h>
 #include <utils/SortedVector.h>
 #include <utils/String16.h>
 #include <utils/String8.h>
 #include <utils/threads.h>
 #include <utils/Vector.h>
+#include <utils/ZipFileRO.h>
 
 /*
  * Native-app access is via the opaque typedef struct AAssetManager in the C namespace.
diff --git a/include/androidfw/ZipFileCRO.h b/include/androidfw/ZipFileCRO.h
deleted file mode 100644
index 3e42a95..0000000
--- a/include/androidfw/ZipFileCRO.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2008 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.
- */
-
-//
-// C API for ead-only access to Zip archives, with minimal heap allocation.
-//
-#ifndef __LIBS_ZIPFILECRO_H
-#define __LIBS_ZIPFILECRO_H
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#include <utils/Compat.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Trivial typedef to ensure that ZipFileCRO is not treated as a simple integer.
- */
-typedef void* ZipFileCRO;
-
-/*
- * Trivial typedef to ensure that ZipEntryCRO is not treated as a simple
- * integer.  We use NULL to indicate an invalid value.
- */
-typedef void* ZipEntryCRO;
-
-extern ZipFileCRO ZipFileXRO_open(const char* path);
-
-extern void ZipFileCRO_destroy(ZipFileCRO zip);
-
-extern ZipEntryCRO ZipFileCRO_findEntryByName(ZipFileCRO zip,
-        const char* fileName);
-
-extern bool ZipFileCRO_getEntryInfo(ZipFileCRO zip, ZipEntryCRO entry,
-        int* pMethod, size_t* pUncompLen,
-        size_t* pCompLen, off64_t* pOffset, long* pModWhen, long* pCrc32);
-
-extern bool ZipFileCRO_uncompressEntry(ZipFileCRO zip, ZipEntryCRO entry, int fd);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /*__LIBS_ZIPFILECRO_H*/
diff --git a/include/androidfw/ZipFileRO.h b/include/androidfw/ZipFileRO.h
deleted file mode 100644
index 547e36a..0000000
--- a/include/androidfw/ZipFileRO.h
+++ /dev/null
@@ -1,262 +0,0 @@
-/*
- * Copyright (C) 2007 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.
- */
-
-/*
- * Read-only access to Zip archives, with minimal heap allocation.
- *
- * This is similar to the more-complete ZipFile class, but no attempt
- * has been made to make them interchangeable.  This class operates under
- * a very different set of assumptions and constraints.
- *
- * One such assumption is that if you're getting file descriptors for
- * use with this class as a child of a fork() operation, you must be on
- * a pread() to guarantee correct operation. This is because pread() can
- * atomically read at a file offset without worrying about a lock around an
- * lseek() + read() pair.
- */
-#ifndef __LIBS_ZIPFILERO_H
-#define __LIBS_ZIPFILERO_H
-
-#include <utils/Compat.h>
-#include <utils/Errors.h>
-#include <utils/FileMap.h>
-#include <utils/threads.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <time.h>
-
-namespace android {
-
-/*
- * Trivial typedef to ensure that ZipEntryRO is not treated as a simple
- * integer.  We use NULL to indicate an invalid value.
- */
-typedef void* ZipEntryRO;
-
-/*
- * Open a Zip archive for reading.
- *
- * We want "open" and "find entry by name" to be fast operations, and we
- * want to use as little memory as possible.  We memory-map the file,
- * and load a hash table with pointers to the filenames (which aren't
- * null-terminated).  The other fields are at a fixed offset from the
- * filename, so we don't need to extract those (but we do need to byte-read
- * and endian-swap them every time we want them).
- *
- * To speed comparisons when doing a lookup by name, we could make the mapping
- * "private" (copy-on-write) and null-terminate the filenames after verifying
- * the record structure.  However, this requires a private mapping of
- * every page that the Central Directory touches.  Easier to tuck a copy
- * of the string length into the hash table entry.
- *
- * NOTE: If this is used on file descriptors inherited from a fork() operation,
- * you must be on a platform that implements pread() to guarantee correctness
- * on the shared file descriptors.
- */
-class ZipFileRO {
-public:
-    ZipFileRO()
-        : mFd(-1), mFileName(NULL), mFileLength(-1),
-          mDirectoryMap(NULL),
-          mNumEntries(-1), mDirectoryOffset(-1),
-          mHashTableSize(-1), mHashTable(NULL)
-        {}
-
-    ~ZipFileRO();
-
-    /*
-     * Open an archive.
-     */
-    status_t open(const char* zipFileName);
-
-    /*
-     * Find an entry, by name.  Returns the entry identifier, or NULL if
-     * not found.
-     *
-     * If two entries have the same name, one will be chosen at semi-random.
-     */
-    ZipEntryRO findEntryByName(const char* fileName) const;
-
-    /*
-     * Return the #of entries in the Zip archive.
-     */
-    int getNumEntries(void) const {
-        return mNumEntries;
-    }
-
-    /*
-     * Return the Nth entry.  Zip file entries are not stored in sorted
-     * order, and updated entries may appear at the end, so anyone walking
-     * the archive needs to avoid making ordering assumptions.  We take
-     * that further by returning the Nth non-empty entry in the hash table
-     * rather than the Nth entry in the archive.
-     *
-     * Valid values are [0..numEntries).
-     *
-     * [This is currently O(n).  If it needs to be fast we can allocate an
-     * additional data structure or provide an iterator interface.]
-     */
-    ZipEntryRO findEntryByIndex(int idx) const;
-
-    /*
-     * Copy the filename into the supplied buffer.  Returns 0 on success,
-     * -1 if "entry" is invalid, or the filename length if it didn't fit.  The
-     * length, and the returned string, include the null-termination.
-     */
-    int getEntryFileName(ZipEntryRO entry, char* buffer, int bufLen) const;
-
-    /*
-     * Get the vital stats for an entry.  Pass in NULL pointers for anything
-     * you don't need.
-     *
-     * "*pOffset" holds the Zip file offset of the entry's data.
-     *
-     * Returns "false" if "entry" is bogus or if the data in the Zip file
-     * appears to be bad.
-     */
-    bool getEntryInfo(ZipEntryRO entry, int* pMethod, size_t* pUncompLen,
-        size_t* pCompLen, off64_t* pOffset, long* pModWhen, long* pCrc32) const;
-
-    /*
-     * Create a new FileMap object that maps a subset of the archive.  For
-     * an uncompressed entry this effectively provides a pointer to the
-     * actual data, for a compressed entry this provides the input buffer
-     * for inflate().
-     */
-    FileMap* createEntryFileMap(ZipEntryRO entry) const;
-
-    /*
-     * Uncompress the data into a buffer.  Depending on the compression
-     * format, this is either an "inflate" operation or a memcpy.
-     *
-     * Use "uncompLen" from getEntryInfo() to determine the required
-     * buffer size.
-     *
-     * Returns "true" on success.
-     */
-    bool uncompressEntry(ZipEntryRO entry, void* buffer) const;
-
-    /*
-     * Uncompress the data to an open file descriptor.
-     */
-    bool uncompressEntry(ZipEntryRO entry, int fd) const;
-
-    /* Zip compression methods we support */
-    enum {
-        kCompressStored     = 0,        // no compression
-        kCompressDeflated   = 8,        // standard deflate
-    };
-
-    /*
-     * Utility function: uncompress deflated data, buffer to buffer.
-     */
-    static bool inflateBuffer(void* outBuf, const void* inBuf,
-        size_t uncompLen, size_t compLen);
-
-    /*
-     * Utility function: uncompress deflated data, buffer to fd.
-     */
-    static bool inflateBuffer(int fd, const void* inBuf,
-        size_t uncompLen, size_t compLen);
-
-    /*
-     * Utility function to convert ZIP's time format to a timespec struct.
-     */
-    static inline void zipTimeToTimespec(long when, struct tm* timespec) {
-        const long date = when >> 16;
-        timespec->tm_year = ((date >> 9) & 0x7F) + 80; // Zip is years since 1980
-        timespec->tm_mon = (date >> 5) & 0x0F;
-        timespec->tm_mday = date & 0x1F;
-
-        timespec->tm_hour = (when >> 11) & 0x1F;
-        timespec->tm_min = (when >> 5) & 0x3F;
-        timespec->tm_sec = (when & 0x1F) << 1;
-    }
-
-    /*
-     * Some basic functions for raw data manipulation.  "LE" means
-     * Little Endian.
-     */
-    static inline unsigned short get2LE(const unsigned char* buf) {
-        return buf[0] | (buf[1] << 8);
-    }
-    static inline unsigned long get4LE(const unsigned char* buf) {
-        return buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
-    }
-
-private:
-    /* these are private and not defined */ 
-    ZipFileRO(const ZipFileRO& src);
-    ZipFileRO& operator=(const ZipFileRO& src);
-
-    /* locate and parse the central directory */
-    bool mapCentralDirectory(void);
-
-    /* parse the archive, prepping internal structures */
-    bool parseZipArchive(void);
-
-    /* add a new entry to the hash table */
-    void addToHash(const char* str, int strLen, unsigned int hash);
-
-    /* compute string hash code */
-    static unsigned int computeHash(const char* str, int len);
-
-    /* convert a ZipEntryRO back to a hash table index */
-    int entryToIndex(const ZipEntryRO entry) const;
-
-    /*
-     * One entry in the hash table.
-     */
-    typedef struct HashEntry {
-        const char*     name;
-        unsigned short  nameLen;
-        //unsigned int    hash;
-    } HashEntry;
-
-    /* open Zip archive */
-    int         mFd;
-
-    /* Lock for handling the file descriptor (seeks, etc) */
-    mutable Mutex mFdLock;
-
-    /* zip file name */
-    char*       mFileName;
-
-    /* length of file */
-    size_t      mFileLength;
-
-    /* mapped file */
-    FileMap*    mDirectoryMap;
-
-    /* number of entries in the Zip archive */
-    int         mNumEntries;
-
-    /* CD directory offset in the Zip archive */
-    off64_t     mDirectoryOffset;
-
-    /*
-     * We know how many entries are in the Zip archive, so we have a
-     * fixed-size hash table.  We probe for an empty slot.
-     */
-    int         mHashTableSize;
-    HashEntry*  mHashTable;
-};
-
-}; // namespace android
-
-#endif /*__LIBS_ZIPFILERO_H*/
diff --git a/include/androidfw/ZipUtils.h b/include/androidfw/ZipUtils.h
deleted file mode 100644
index 42c42b6..0000000
--- a/include/androidfw/ZipUtils.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2007 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.
- */
-
-//
-// Miscellaneous zip/gzip utility functions.
-//
-#ifndef __LIBS_ZIPUTILS_H
-#define __LIBS_ZIPUTILS_H
-
-#include <stdio.h>
-
-namespace android {
-
-/*
- * Container class for utility functions, primarily for namespace reasons.
- */
-class ZipUtils {
-public:
-    /*
-     * General utility function for uncompressing "deflate" data from a file
-     * to a buffer.
-     */
-    static bool inflateToBuffer(int fd, void* buf, long uncompressedLen,
-        long compressedLen);
-    static bool inflateToBuffer(FILE* fp, void* buf, long uncompressedLen,
-        long compressedLen);
-
-    /*
-     * Someday we might want to make this generic and handle bzip2 ".bz2"
-     * files too.
-     *
-     * We could declare gzip to be a sub-class of zip that has exactly
-     * one always-compressed entry, but we currently want to treat Zip
-     * and gzip as distinct, so there's no value.
-     *
-     * The zlib library has some gzip utilities, but it has no interface
-     * for extracting the uncompressed length of the file (you do *not*
-     * want to gzseek to the end).
-     *
-     * Pass in a seeked file pointer for the gzip file.  If this is a gzip
-     * file, we set our return values appropriately and return "true" with
-     * the file seeked to the start of the compressed data.
-     */
-    static bool examineGzip(FILE* fp, int* pCompressionMethod,
-        long* pUncompressedLen, long* pCompressedLen, unsigned long* pCRC32);
-
-private:
-    ZipUtils() {}
-    ~ZipUtils() {}
-};
-
-}; // namespace android
-
-#endif /*__LIBS_ZIPUTILS_H*/
diff --git a/libs/androidfw/Android.mk b/libs/androidfw/Android.mk
index 4e89d87..a3f92cb 100644
--- a/libs/androidfw/Android.mk
+++ b/libs/androidfw/Android.mk
@@ -24,10 +24,7 @@
     AssetManager.cpp \
     ObbFile.cpp \
     ResourceTypes.cpp \
-    StreamingZipInflater.cpp \
-    ZipFileCRO.cpp \
-    ZipFileRO.cpp \
-    ZipUtils.cpp
+    StreamingZipInflater.cpp
 
 # formerly in libui
 commonUiSources:= \
diff --git a/libs/androidfw/Asset.cpp b/libs/androidfw/Asset.cpp
index cb7628d..fd5b3e4 100644
--- a/libs/androidfw/Asset.cpp
+++ b/libs/androidfw/Asset.cpp
@@ -23,11 +23,11 @@
 
 #include <androidfw/Asset.h>
 #include <androidfw/StreamingZipInflater.h>
-#include <androidfw/ZipFileRO.h>
-#include <androidfw/ZipUtils.h>
 #include <utils/Atomic.h>
 #include <utils/FileMap.h>
 #include <utils/Log.h>
+#include <utils/ZipFileRO.h>
+#include <utils/ZipUtils.h>
 #include <utils/threads.h>
 
 #include <assert.h>
diff --git a/libs/androidfw/AssetManager.cpp b/libs/androidfw/AssetManager.cpp
index 4829add..8d59d8e 100644
--- a/libs/androidfw/AssetManager.cpp
+++ b/libs/androidfw/AssetManager.cpp
@@ -25,13 +25,13 @@
 #include <androidfw/AssetDir.h>
 #include <androidfw/AssetManager.h>
 #include <androidfw/ResourceTypes.h>
-#include <androidfw/ZipFileRO.h>
 #include <utils/Atomic.h>
 #include <utils/Log.h>
 #include <utils/String8.h>
 #include <utils/String8.h>
 #include <utils/threads.h>
 #include <utils/Timers.h>
+#include <utils/ZipFileRO.h>
 
 #include <assert.h>
 #include <dirent.h>
diff --git a/libs/androidfw/ZipFileCRO.cpp b/libs/androidfw/ZipFileCRO.cpp
deleted file mode 100644
index c8df845..0000000
--- a/libs/androidfw/ZipFileCRO.cpp
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2008 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 <androidfw/ZipFileCRO.h>
-#include <androidfw/ZipFileRO.h>
-
-using namespace android;
-
-ZipFileCRO ZipFileXRO_open(const char* path) {
-    ZipFileRO* zip = new ZipFileRO();
-    if (zip->open(path) == NO_ERROR) {
-        return (ZipFileCRO)zip;
-    }
-    return NULL;
-}
-
-void ZipFileCRO_destroy(ZipFileCRO zipToken) {
-    ZipFileRO* zip = (ZipFileRO*)zipToken;
-    delete zip;
-}
-
-ZipEntryCRO ZipFileCRO_findEntryByName(ZipFileCRO zipToken,
-        const char* fileName) {
-    ZipFileRO* zip = (ZipFileRO*)zipToken;
-    return (ZipEntryCRO)zip->findEntryByName(fileName);
-}
-
-bool ZipFileCRO_getEntryInfo(ZipFileCRO zipToken, ZipEntryRO entryToken,
-        int* pMethod, size_t* pUncompLen,
-        size_t* pCompLen, off64_t* pOffset, long* pModWhen, long* pCrc32) {
-    ZipFileRO* zip = (ZipFileRO*)zipToken;
-    ZipEntryRO entry = (ZipEntryRO)entryToken;
-    return zip->getEntryInfo(entry, pMethod, pUncompLen, pCompLen, pOffset,
-            pModWhen, pCrc32);
-}
-
-bool ZipFileCRO_uncompressEntry(ZipFileCRO zipToken, ZipEntryRO entryToken, int fd) {
-    ZipFileRO* zip = (ZipFileRO*)zipToken;
-    ZipEntryRO entry = (ZipEntryRO)entryToken;
-    return zip->uncompressEntry(entry, fd);
-}
diff --git a/libs/androidfw/ZipFileRO.cpp b/libs/androidfw/ZipFileRO.cpp
deleted file mode 100644
index 4b7f1e7..0000000
--- a/libs/androidfw/ZipFileRO.cpp
+++ /dev/null
@@ -1,931 +0,0 @@
-/*
- * Copyright (C) 2007 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.
- */
-
-//
-// Read-only access to Zip archives, with minimal heap allocation.
-//
-#define LOG_TAG "zipro"
-//#define LOG_NDEBUG 0
-#include <androidfw/ZipFileRO.h>
-#include <utils/Log.h>
-#include <utils/misc.h>
-#include <utils/threads.h>
-
-#include <zlib.h>
-
-#include <string.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <assert.h>
-#include <unistd.h>
-
-#if HAVE_PRINTF_ZD
-#  define ZD "%zd"
-#  define ZD_TYPE ssize_t
-#else
-#  define ZD "%ld"
-#  define ZD_TYPE long
-#endif
-
-/*
- * We must open binary files using open(path, ... | O_BINARY) under Windows.
- * Otherwise strange read errors will happen.
- */
-#ifndef O_BINARY
-#  define O_BINARY  0
-#endif
-
-/*
- * TEMP_FAILURE_RETRY is defined by some, but not all, versions of
- * <unistd.h>. (Alas, it is not as standard as we'd hoped!) So, if it's
- * not already defined, then define it here.
- */
-#ifndef TEMP_FAILURE_RETRY
-/* Used to retry syscalls that can return EINTR. */
-#define TEMP_FAILURE_RETRY(exp) ({         \
-    typeof (exp) _rc;                      \
-    do {                                   \
-        _rc = (exp);                       \
-    } while (_rc == -1 && errno == EINTR); \
-    _rc; })
-#endif
-
-using namespace android;
-
-/*
- * Zip file constants.
- */
-#define kEOCDSignature      0x06054b50
-#define kEOCDLen            22
-#define kEOCDNumEntries     8               // offset to #of entries in file
-#define kEOCDSize           12              // size of the central directory
-#define kEOCDFileOffset     16              // offset to central directory
-
-#define kMaxCommentLen      65535           // longest possible in ushort
-#define kMaxEOCDSearch      (kMaxCommentLen + kEOCDLen)
-
-#define kLFHSignature       0x04034b50
-#define kLFHLen             30              // excluding variable-len fields
-#define kLFHNameLen         26              // offset to filename length
-#define kLFHExtraLen        28              // offset to extra length
-
-#define kCDESignature       0x02014b50
-#define kCDELen             46              // excluding variable-len fields
-#define kCDEMethod          10              // offset to compression method
-#define kCDEModWhen         12              // offset to modification timestamp
-#define kCDECRC             16              // offset to entry CRC
-#define kCDECompLen         20              // offset to compressed length
-#define kCDEUncompLen       24              // offset to uncompressed length
-#define kCDENameLen         28              // offset to filename length
-#define kCDEExtraLen        30              // offset to extra length
-#define kCDECommentLen      32              // offset to comment length
-#define kCDELocalOffset     42              // offset to local hdr
-
-/*
- * The values we return for ZipEntryRO use 0 as an invalid value, so we
- * want to adjust the hash table index by a fixed amount.  Using a large
- * value helps insure that people don't mix & match arguments, e.g. to
- * findEntryByIndex().
- */
-#define kZipEntryAdj        10000
-
-ZipFileRO::~ZipFileRO() {
-    free(mHashTable);
-    if (mDirectoryMap)
-        mDirectoryMap->release();
-    if (mFd >= 0)
-        TEMP_FAILURE_RETRY(close(mFd));
-    if (mFileName)
-        free(mFileName);
-}
-
-/*
- * Convert a ZipEntryRO to a hash table index, verifying that it's in a
- * valid range.
- */
-int ZipFileRO::entryToIndex(const ZipEntryRO entry) const
-{
-    long ent = ((long) entry) - kZipEntryAdj;
-    if (ent < 0 || ent >= mHashTableSize || mHashTable[ent].name == NULL) {
-        ALOGW("Invalid ZipEntryRO %p (%ld)\n", entry, ent);
-        return -1;
-    }
-    return ent;
-}
-
-
-/*
- * Open the specified file read-only.  We memory-map the entire thing and
- * close the file before returning.
- */
-status_t ZipFileRO::open(const char* zipFileName)
-{
-    int fd = -1;
-
-    assert(mDirectoryMap == NULL);
-
-    /*
-     * Open and map the specified file.
-     */
-    fd = ::open(zipFileName, O_RDONLY | O_BINARY);
-    if (fd < 0) {
-        ALOGW("Unable to open zip '%s': %s\n", zipFileName, strerror(errno));
-        return NAME_NOT_FOUND;
-    }
-
-    mFileLength = lseek64(fd, 0, SEEK_END);
-    if (mFileLength < kEOCDLen) {
-        TEMP_FAILURE_RETRY(close(fd));
-        return UNKNOWN_ERROR;
-    }
-
-    if (mFileName != NULL) {
-        free(mFileName);
-    }
-    mFileName = strdup(zipFileName);
-
-    mFd = fd;
-
-    /*
-     * Find the Central Directory and store its size and number of entries.
-     */
-    if (!mapCentralDirectory()) {
-        goto bail;
-    }
-
-    /*
-     * Verify Central Directory and create data structures for fast access.
-     */
-    if (!parseZipArchive()) {
-        goto bail;
-    }
-
-    return OK;
-
-bail:
-    free(mFileName);
-    mFileName = NULL;
-    TEMP_FAILURE_RETRY(close(fd));
-    return UNKNOWN_ERROR;
-}
-
-/*
- * Parse the Zip archive, verifying its contents and initializing internal
- * data structures.
- */
-bool ZipFileRO::mapCentralDirectory(void)
-{
-    ssize_t readAmount = kMaxEOCDSearch;
-    if (readAmount > (ssize_t) mFileLength)
-        readAmount = mFileLength;
-
-    unsigned char* scanBuf = (unsigned char*) malloc(readAmount);
-    if (scanBuf == NULL) {
-        ALOGW("couldn't allocate scanBuf: %s", strerror(errno));
-        free(scanBuf);
-        return false;
-    }
-
-    /*
-     * Make sure this is a Zip archive.
-     */
-    if (lseek64(mFd, 0, SEEK_SET) != 0) {
-        ALOGW("seek to start failed: %s", strerror(errno));
-        free(scanBuf);
-        return false;
-    }
-
-    ssize_t actual = TEMP_FAILURE_RETRY(read(mFd, scanBuf, sizeof(int32_t)));
-    if (actual != (ssize_t) sizeof(int32_t)) {
-        ALOGI("couldn't read first signature from zip archive: %s", strerror(errno));
-        free(scanBuf);
-        return false;
-    }
-
-    {
-        unsigned int header = get4LE(scanBuf);
-        if (header == kEOCDSignature) {
-            ALOGI("Found Zip archive, but it looks empty\n");
-            free(scanBuf);
-            return false;
-        } else if (header != kLFHSignature) {
-            ALOGV("Not a Zip archive (found 0x%08x)\n", header);
-            free(scanBuf);
-            return false;
-        }
-    }
-
-    /*
-     * Perform the traditional EOCD snipe hunt.
-     *
-     * We're searching for the End of Central Directory magic number,
-     * which appears at the start of the EOCD block.  It's followed by
-     * 18 bytes of EOCD stuff and up to 64KB of archive comment.  We
-     * need to read the last part of the file into a buffer, dig through
-     * it to find the magic number, parse some values out, and use those
-     * to determine the extent of the CD.
-     *
-     * We start by pulling in the last part of the file.
-     */
-    off64_t searchStart = mFileLength - readAmount;
-
-    if (lseek64(mFd, searchStart, SEEK_SET) != searchStart) {
-        ALOGW("seek %ld failed: %s\n",  (long) searchStart, strerror(errno));
-        free(scanBuf);
-        return false;
-    }
-    actual = TEMP_FAILURE_RETRY(read(mFd, scanBuf, readAmount));
-    if (actual != (ssize_t) readAmount) {
-        ALOGW("Zip: read " ZD ", expected " ZD ". Failed: %s\n",
-            (ZD_TYPE) actual, (ZD_TYPE) readAmount, strerror(errno));
-        free(scanBuf);
-        return false;
-    }
-
-    /*
-     * Scan backward for the EOCD magic.  In an archive without a trailing
-     * comment, we'll find it on the first try.  (We may want to consider
-     * doing an initial minimal read; if we don't find it, retry with a
-     * second read as above.)
-     */
-    int i;
-    for (i = readAmount - kEOCDLen; i >= 0; i--) {
-        if (scanBuf[i] == 0x50 && get4LE(&scanBuf[i]) == kEOCDSignature) {
-            ALOGV("+++ Found EOCD at buf+%d\n", i);
-            break;
-        }
-    }
-    if (i < 0) {
-        ALOGD("Zip: EOCD not found, %s is not zip\n", mFileName);
-        free(scanBuf);
-        return false;
-    }
-
-    off64_t eocdOffset = searchStart + i;
-    const unsigned char* eocdPtr = scanBuf + i;
-
-    assert(eocdOffset < mFileLength);
-
-    /*
-     * Grab the CD offset and size, and the number of entries in the
-     * archive. After that, we can release our EOCD hunt buffer.
-     */
-    unsigned int numEntries = get2LE(eocdPtr + kEOCDNumEntries);
-    unsigned int dirSize = get4LE(eocdPtr + kEOCDSize);
-    unsigned int dirOffset = get4LE(eocdPtr + kEOCDFileOffset);
-    free(scanBuf);
-
-    // Verify that they look reasonable.
-    if ((long long) dirOffset + (long long) dirSize > (long long) eocdOffset) {
-        ALOGW("bad offsets (dir %ld, size %u, eocd %ld)\n",
-            (long) dirOffset, dirSize, (long) eocdOffset);
-        return false;
-    }
-    if (numEntries == 0) {
-        ALOGW("empty archive?\n");
-        return false;
-    }
-
-    ALOGV("+++ numEntries=%d dirSize=%d dirOffset=%d\n",
-        numEntries, dirSize, dirOffset);
-
-    mDirectoryMap = new FileMap();
-    if (mDirectoryMap == NULL) {
-        ALOGW("Unable to create directory map: %s", strerror(errno));
-        return false;
-    }
-
-    if (!mDirectoryMap->create(mFileName, mFd, dirOffset, dirSize, true)) {
-        ALOGW("Unable to map '%s' (" ZD " to " ZD "): %s\n", mFileName,
-                (ZD_TYPE) dirOffset, (ZD_TYPE) (dirOffset + dirSize), strerror(errno));
-        return false;
-    }
-
-    mNumEntries = numEntries;
-    mDirectoryOffset = dirOffset;
-
-    return true;
-}
-
-bool ZipFileRO::parseZipArchive(void)
-{
-    bool result = false;
-    const unsigned char* cdPtr = (const unsigned char*) mDirectoryMap->getDataPtr();
-    size_t cdLength = mDirectoryMap->getDataLength();
-    int numEntries = mNumEntries;
-
-    /*
-     * Create hash table.  We have a minimum 75% load factor, possibly as
-     * low as 50% after we round off to a power of 2.
-     */
-    mHashTableSize = roundUpPower2(1 + (numEntries * 4) / 3);
-    mHashTable = (HashEntry*) calloc(mHashTableSize, sizeof(HashEntry));
-
-    /*
-     * Walk through the central directory, adding entries to the hash
-     * table.
-     */
-    const unsigned char* ptr = cdPtr;
-    for (int i = 0; i < numEntries; i++) {
-        if (get4LE(ptr) != kCDESignature) {
-            ALOGW("Missed a central dir sig (at %d)\n", i);
-            goto bail;
-        }
-        if (ptr + kCDELen > cdPtr + cdLength) {
-            ALOGW("Ran off the end (at %d)\n", i);
-            goto bail;
-        }
-
-        long localHdrOffset = (long) get4LE(ptr + kCDELocalOffset);
-        if (localHdrOffset >= mDirectoryOffset) {
-            ALOGW("bad LFH offset %ld at entry %d\n", localHdrOffset, i);
-            goto bail;
-        }
-
-        unsigned int fileNameLen, extraLen, commentLen, hash;
-
-        fileNameLen = get2LE(ptr + kCDENameLen);
-        extraLen = get2LE(ptr + kCDEExtraLen);
-        commentLen = get2LE(ptr + kCDECommentLen);
-
-        /* add the CDE filename to the hash table */
-        hash = computeHash((const char*)ptr + kCDELen, fileNameLen);
-        addToHash((const char*)ptr + kCDELen, fileNameLen, hash);
-
-        ptr += kCDELen + fileNameLen + extraLen + commentLen;
-        if ((size_t)(ptr - cdPtr) > cdLength) {
-            ALOGW("bad CD advance (%d vs " ZD ") at entry %d\n",
-                (int) (ptr - cdPtr), (ZD_TYPE) cdLength, i);
-            goto bail;
-        }
-    }
-    ALOGV("+++ zip good scan %d entries\n", numEntries);
-    result = true;
-
-bail:
-    return result;
-}
-
-/*
- * Simple string hash function for non-null-terminated strings.
- */
-/*static*/ unsigned int ZipFileRO::computeHash(const char* str, int len)
-{
-    unsigned int hash = 0;
-
-    while (len--)
-        hash = hash * 31 + *str++;
-
-    return hash;
-}
-
-/*
- * Add a new entry to the hash table.
- */
-void ZipFileRO::addToHash(const char* str, int strLen, unsigned int hash)
-{
-    int ent = hash & (mHashTableSize-1);
-
-    /*
-     * We over-allocate the table, so we're guaranteed to find an empty slot.
-     */
-    while (mHashTable[ent].name != NULL)
-        ent = (ent + 1) & (mHashTableSize-1);
-
-    mHashTable[ent].name = str;
-    mHashTable[ent].nameLen = strLen;
-}
-
-/*
- * Find a matching entry.
- *
- * Returns NULL if not found.
- */
-ZipEntryRO ZipFileRO::findEntryByName(const char* fileName) const
-{
-    /*
-     * If the ZipFileRO instance is not initialized, the entry number will
-     * end up being garbage since mHashTableSize is -1.
-     */
-    if (mHashTableSize <= 0) {
-        return NULL;
-    }
-
-    int nameLen = strlen(fileName);
-    unsigned int hash = computeHash(fileName, nameLen);
-    int ent = hash & (mHashTableSize-1);
-
-    while (mHashTable[ent].name != NULL) {
-        if (mHashTable[ent].nameLen == nameLen &&
-            memcmp(mHashTable[ent].name, fileName, nameLen) == 0)
-        {
-            /* match */
-            return (ZipEntryRO)(long)(ent + kZipEntryAdj);
-        }
-
-        ent = (ent + 1) & (mHashTableSize-1);
-    }
-
-    return NULL;
-}
-
-/*
- * Find the Nth entry.
- *
- * This currently involves walking through the sparse hash table, counting
- * non-empty entries.  If we need to speed this up we can either allocate
- * a parallel lookup table or (perhaps better) provide an iterator interface.
- */
-ZipEntryRO ZipFileRO::findEntryByIndex(int idx) const
-{
-    if (idx < 0 || idx >= mNumEntries) {
-        ALOGW("Invalid index %d\n", idx);
-        return NULL;
-    }
-
-    for (int ent = 0; ent < mHashTableSize; ent++) {
-        if (mHashTable[ent].name != NULL) {
-            if (idx-- == 0)
-                return (ZipEntryRO) (ent + kZipEntryAdj);
-        }
-    }
-
-    return NULL;
-}
-
-/*
- * Get the useful fields from the zip entry.
- *
- * Returns "false" if the offsets to the fields or the contents of the fields
- * appear to be bogus.
- */
-bool ZipFileRO::getEntryInfo(ZipEntryRO entry, int* pMethod, size_t* pUncompLen,
-    size_t* pCompLen, off64_t* pOffset, long* pModWhen, long* pCrc32) const
-{
-    bool ret = false;
-
-    const int ent = entryToIndex(entry);
-    if (ent < 0)
-        return false;
-
-    HashEntry hashEntry = mHashTable[ent];
-
-    /*
-     * Recover the start of the central directory entry from the filename
-     * pointer.  The filename is the first entry past the fixed-size data,
-     * so we can just subtract back from that.
-     */
-    const unsigned char* ptr = (const unsigned char*) hashEntry.name;
-    off64_t cdOffset = mDirectoryOffset;
-
-    ptr -= kCDELen;
-
-    int method = get2LE(ptr + kCDEMethod);
-    if (pMethod != NULL)
-        *pMethod = method;
-
-    if (pModWhen != NULL)
-        *pModWhen = get4LE(ptr + kCDEModWhen);
-    if (pCrc32 != NULL)
-        *pCrc32 = get4LE(ptr + kCDECRC);
-
-    size_t compLen = get4LE(ptr + kCDECompLen);
-    if (pCompLen != NULL)
-        *pCompLen = compLen;
-    size_t uncompLen = get4LE(ptr + kCDEUncompLen);
-    if (pUncompLen != NULL)
-        *pUncompLen = uncompLen;
-
-    /*
-     * If requested, determine the offset of the start of the data.  All we
-     * have is the offset to the Local File Header, which is variable size,
-     * so we have to read the contents of the struct to figure out where
-     * the actual data starts.
-     *
-     * We also need to make sure that the lengths are not so large that
-     * somebody trying to map the compressed or uncompressed data runs
-     * off the end of the mapped region.
-     *
-     * Note we don't verify compLen/uncompLen if they don't request the
-     * dataOffset, because dataOffset is expensive to determine.  However,
-     * if they don't have the file offset, they're not likely to be doing
-     * anything with the contents.
-     */
-    if (pOffset != NULL) {
-        long localHdrOffset = get4LE(ptr + kCDELocalOffset);
-        if (localHdrOffset + kLFHLen >= cdOffset) {
-            ALOGE("ERROR: bad local hdr offset in zip\n");
-            return false;
-        }
-
-        unsigned char lfhBuf[kLFHLen];
-
-#ifdef HAVE_PREAD
-        /*
-         * This file descriptor might be from zygote's preloaded assets,
-         * so we need to do an pread64() instead of a lseek64() + read() to
-         * guarantee atomicity across the processes with the shared file
-         * descriptors.
-         */
-        ssize_t actual =
-                TEMP_FAILURE_RETRY(pread64(mFd, lfhBuf, sizeof(lfhBuf), localHdrOffset));
-
-        if (actual != sizeof(lfhBuf)) {
-            ALOGW("failed reading lfh from offset %ld\n", localHdrOffset);
-            return false;
-        }
-
-        if (get4LE(lfhBuf) != kLFHSignature) {
-            ALOGW("didn't find signature at start of lfh; wanted: offset=%ld data=0x%08x; "
-                    "got: data=0x%08lx\n",
-                    localHdrOffset, kLFHSignature, get4LE(lfhBuf));
-            return false;
-        }
-#else /* HAVE_PREAD */
-        /*
-         * For hosts don't have pread64() we cannot guarantee atomic reads from
-         * an offset in a file. Android should never run on those platforms.
-         * File descriptors inherited from a fork() share file offsets and
-         * there would be nothing to protect from two different processes
-         * calling lseek64() concurrently.
-         */
-
-        {
-            AutoMutex _l(mFdLock);
-
-            if (lseek64(mFd, localHdrOffset, SEEK_SET) != localHdrOffset) {
-                ALOGW("failed seeking to lfh at offset %ld\n", localHdrOffset);
-                return false;
-            }
-
-            ssize_t actual =
-                    TEMP_FAILURE_RETRY(read(mFd, lfhBuf, sizeof(lfhBuf)));
-            if (actual != sizeof(lfhBuf)) {
-                ALOGW("failed reading lfh from offset %ld\n", localHdrOffset);
-                return false;
-            }
-
-            if (get4LE(lfhBuf) != kLFHSignature) {
-                off64_t actualOffset = lseek64(mFd, 0, SEEK_CUR);
-                ALOGW("didn't find signature at start of lfh; wanted: offset=%ld data=0x%08x; "
-                        "got: offset=" ZD " data=0x%08lx\n",
-                        localHdrOffset, kLFHSignature, (ZD_TYPE) actualOffset, get4LE(lfhBuf));
-                return false;
-            }
-        }
-#endif /* HAVE_PREAD */
-
-        off64_t dataOffset = localHdrOffset + kLFHLen
-            + get2LE(lfhBuf + kLFHNameLen) + get2LE(lfhBuf + kLFHExtraLen);
-        if (dataOffset >= cdOffset) {
-            ALOGW("bad data offset %ld in zip\n", (long) dataOffset);
-            return false;
-        }
-
-        /* check lengths */
-        if ((off64_t)(dataOffset + compLen) > cdOffset) {
-            ALOGW("bad compressed length in zip (%ld + " ZD " > %ld)\n",
-                (long) dataOffset, (ZD_TYPE) compLen, (long) cdOffset);
-            return false;
-        }
-
-        if (method == kCompressStored &&
-            (off64_t)(dataOffset + uncompLen) > cdOffset)
-        {
-            ALOGE("ERROR: bad uncompressed length in zip (%ld + " ZD " > %ld)\n",
-                (long) dataOffset, (ZD_TYPE) uncompLen, (long) cdOffset);
-            return false;
-        }
-
-        *pOffset = dataOffset;
-    }
-
-    return true;
-}
-
-/*
- * Copy the entry's filename to the buffer.
- */
-int ZipFileRO::getEntryFileName(ZipEntryRO entry, char* buffer, int bufLen)
-    const
-{
-    int ent = entryToIndex(entry);
-    if (ent < 0)
-        return -1;
-
-    int nameLen = mHashTable[ent].nameLen;
-    if (bufLen < nameLen+1)
-        return nameLen+1;
-
-    memcpy(buffer, mHashTable[ent].name, nameLen);
-    buffer[nameLen] = '\0';
-    return 0;
-}
-
-/*
- * Create a new FileMap object that spans the data in "entry".
- */
-FileMap* ZipFileRO::createEntryFileMap(ZipEntryRO entry) const
-{
-    /*
-     * TODO: the efficient way to do this is to modify FileMap to allow
-     * sub-regions of a file to be mapped.  A reference-counting scheme
-     * can manage the base memory mapping.  For now, we just create a brand
-     * new mapping off of the Zip archive file descriptor.
-     */
-
-    FileMap* newMap;
-    size_t compLen;
-    off64_t offset;
-
-    if (!getEntryInfo(entry, NULL, NULL, &compLen, &offset, NULL, NULL))
-        return NULL;
-
-    newMap = new FileMap();
-    if (!newMap->create(mFileName, mFd, offset, compLen, true)) {
-        newMap->release();
-        return NULL;
-    }
-
-    return newMap;
-}
-
-/*
- * Uncompress an entry, in its entirety, into the provided output buffer.
- *
- * This doesn't verify the data's CRC, which might be useful for
- * uncompressed data.  The caller should be able to manage it.
- */
-bool ZipFileRO::uncompressEntry(ZipEntryRO entry, void* buffer) const
-{
-    const size_t kSequentialMin = 32768;
-    bool result = false;
-    int ent = entryToIndex(entry);
-    if (ent < 0)
-        return -1;
-
-    int method;
-    size_t uncompLen, compLen;
-    off64_t offset;
-    const unsigned char* ptr;
-
-    getEntryInfo(entry, &method, &uncompLen, &compLen, &offset, NULL, NULL);
-
-    FileMap* file = createEntryFileMap(entry);
-    if (file == NULL) {
-        goto bail;
-    }
-
-    ptr = (const unsigned char*) file->getDataPtr();
-
-    /*
-     * Experiment with madvise hint.  When we want to uncompress a file,
-     * we pull some stuff out of the central dir entry and then hit a
-     * bunch of compressed or uncompressed data sequentially.  The CDE
-     * visit will cause a limited amount of read-ahead because it's at
-     * the end of the file.  We could end up doing lots of extra disk
-     * access if the file we're prying open is small.  Bottom line is we
-     * probably don't want to turn MADV_SEQUENTIAL on and leave it on.
-     *
-     * So, if the compressed size of the file is above a certain minimum
-     * size, temporarily boost the read-ahead in the hope that the extra
-     * pair of system calls are negated by a reduction in page faults.
-     */
-    if (compLen > kSequentialMin)
-        file->advise(FileMap::SEQUENTIAL);
-
-    if (method == kCompressStored) {
-        memcpy(buffer, ptr, uncompLen);
-    } else {
-        if (!inflateBuffer(buffer, ptr, uncompLen, compLen))
-            goto unmap;
-    }
-
-    if (compLen > kSequentialMin)
-        file->advise(FileMap::NORMAL);
-
-    result = true;
-
-unmap:
-    file->release();
-bail:
-    return result;
-}
-
-/*
- * Uncompress an entry, in its entirety, to an open file descriptor.
- *
- * This doesn't verify the data's CRC, but probably should.
- */
-bool ZipFileRO::uncompressEntry(ZipEntryRO entry, int fd) const
-{
-    bool result = false;
-    int ent = entryToIndex(entry);
-    if (ent < 0)
-        return -1;
-
-    int method;
-    size_t uncompLen, compLen;
-    off64_t offset;
-    const unsigned char* ptr;
-
-    getEntryInfo(entry, &method, &uncompLen, &compLen, &offset, NULL, NULL);
-
-    FileMap* file = createEntryFileMap(entry);
-    if (file == NULL) {
-        goto bail;
-    }
-
-    ptr = (const unsigned char*) file->getDataPtr();
-
-    if (method == kCompressStored) {
-        ssize_t actual = write(fd, ptr, uncompLen);
-        if (actual < 0) {
-            ALOGE("Write failed: %s\n", strerror(errno));
-            goto unmap;
-        } else if ((size_t) actual != uncompLen) {
-            ALOGE("Partial write during uncompress (" ZD " of " ZD ")\n",
-                (ZD_TYPE) actual, (ZD_TYPE) uncompLen);
-            goto unmap;
-        } else {
-            ALOGI("+++ successful write\n");
-        }
-    } else {
-        if (!inflateBuffer(fd, ptr, uncompLen, compLen))
-            goto unmap;
-    }
-
-    result = true;
-
-unmap:
-    file->release();
-bail:
-    return result;
-}
-
-/*
- * Uncompress "deflate" data from one buffer to another.
- */
-/*static*/ bool ZipFileRO::inflateBuffer(void* outBuf, const void* inBuf,
-    size_t uncompLen, size_t compLen)
-{
-    bool result = false;
-    z_stream zstream;
-    int zerr;
-
-    /*
-     * Initialize the zlib stream struct.
-     */
-    memset(&zstream, 0, sizeof(zstream));
-    zstream.zalloc = Z_NULL;
-    zstream.zfree = Z_NULL;
-    zstream.opaque = Z_NULL;
-    zstream.next_in = (Bytef*)inBuf;
-    zstream.avail_in = compLen;
-    zstream.next_out = (Bytef*) outBuf;
-    zstream.avail_out = uncompLen;
-    zstream.data_type = Z_UNKNOWN;
-
-    /*
-     * Use the undocumented "negative window bits" feature to tell zlib
-     * that there's no zlib header waiting for it.
-     */
-    zerr = inflateInit2(&zstream, -MAX_WBITS);
-    if (zerr != Z_OK) {
-        if (zerr == Z_VERSION_ERROR) {
-            ALOGE("Installed zlib is not compatible with linked version (%s)\n",
-                ZLIB_VERSION);
-        } else {
-            ALOGE("Call to inflateInit2 failed (zerr=%d)\n", zerr);
-        }
-        goto bail;
-    }
-
-    /*
-     * Expand data.
-     */
-    zerr = inflate(&zstream, Z_FINISH);
-    if (zerr != Z_STREAM_END) {
-        ALOGW("Zip inflate failed, zerr=%d (nIn=%p aIn=%u nOut=%p aOut=%u)\n",
-            zerr, zstream.next_in, zstream.avail_in,
-            zstream.next_out, zstream.avail_out);
-        goto z_bail;
-    }
-
-    /* paranoia */
-    if (zstream.total_out != uncompLen) {
-        ALOGW("Size mismatch on inflated file (%ld vs " ZD ")\n",
-            zstream.total_out, (ZD_TYPE) uncompLen);
-        goto z_bail;
-    }
-
-    result = true;
-
-z_bail:
-    inflateEnd(&zstream);        /* free up any allocated structures */
-
-bail:
-    return result;
-}
-
-/*
- * Uncompress "deflate" data from one buffer to an open file descriptor.
- */
-/*static*/ bool ZipFileRO::inflateBuffer(int fd, const void* inBuf,
-    size_t uncompLen, size_t compLen)
-{
-    bool result = false;
-    const size_t kWriteBufSize = 32768;
-    unsigned char writeBuf[kWriteBufSize];
-    z_stream zstream;
-    int zerr;
-
-    /*
-     * Initialize the zlib stream struct.
-     */
-    memset(&zstream, 0, sizeof(zstream));
-    zstream.zalloc = Z_NULL;
-    zstream.zfree = Z_NULL;
-    zstream.opaque = Z_NULL;
-    zstream.next_in = (Bytef*)inBuf;
-    zstream.avail_in = compLen;
-    zstream.next_out = (Bytef*) writeBuf;
-    zstream.avail_out = sizeof(writeBuf);
-    zstream.data_type = Z_UNKNOWN;
-
-    /*
-     * Use the undocumented "negative window bits" feature to tell zlib
-     * that there's no zlib header waiting for it.
-     */
-    zerr = inflateInit2(&zstream, -MAX_WBITS);
-    if (zerr != Z_OK) {
-        if (zerr == Z_VERSION_ERROR) {
-            ALOGE("Installed zlib is not compatible with linked version (%s)\n",
-                ZLIB_VERSION);
-        } else {
-            ALOGE("Call to inflateInit2 failed (zerr=%d)\n", zerr);
-        }
-        goto bail;
-    }
-
-    /*
-     * Loop while we have more to do.
-     */
-    do {
-        /*
-         * Expand data.
-         */
-        zerr = inflate(&zstream, Z_NO_FLUSH);
-        if (zerr != Z_OK && zerr != Z_STREAM_END) {
-            ALOGW("zlib inflate: zerr=%d (nIn=%p aIn=%u nOut=%p aOut=%u)\n",
-                zerr, zstream.next_in, zstream.avail_in,
-                zstream.next_out, zstream.avail_out);
-            goto z_bail;
-        }
-
-        /* write when we're full or when we're done */
-        if (zstream.avail_out == 0 ||
-            (zerr == Z_STREAM_END && zstream.avail_out != sizeof(writeBuf)))
-        {
-            long writeSize = zstream.next_out - writeBuf;
-            int cc = write(fd, writeBuf, writeSize);
-            if (cc != (int) writeSize) {
-                ALOGW("write failed in inflate (%d vs %ld)\n", cc, writeSize);
-                goto z_bail;
-            }
-
-            zstream.next_out = writeBuf;
-            zstream.avail_out = sizeof(writeBuf);
-        }
-    } while (zerr == Z_OK);
-
-    assert(zerr == Z_STREAM_END);       /* other errors should've been caught */
-
-    /* paranoia */
-    if (zstream.total_out != uncompLen) {
-        ALOGW("Size mismatch on inflated file (%ld vs " ZD ")\n",
-            zstream.total_out, (ZD_TYPE) uncompLen);
-        goto z_bail;
-    }
-
-    result = true;
-
-z_bail:
-    inflateEnd(&zstream);        /* free up any allocated structures */
-
-bail:
-    return result;
-}
diff --git a/libs/androidfw/ZipUtils.cpp b/libs/androidfw/ZipUtils.cpp
deleted file mode 100644
index db3479d..0000000
--- a/libs/androidfw/ZipUtils.cpp
+++ /dev/null
@@ -1,343 +0,0 @@
-/*
- * Copyright (C) 2007 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.
- */
-
-//
-// Misc zip/gzip utility functions.
-//
-
-#define LOG_TAG "ziputil"
-
-#include <androidfw/ZipUtils.h>
-#include <androidfw/ZipFileRO.h>
-#include <utils/Log.h>
-
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-
-#include <zlib.h>
-
-using namespace android;
-
-/*
- * Utility function that expands zip/gzip "deflate" compressed data
- * into a buffer.
- *
- * "fd" is an open file positioned at the start of the "deflate" data
- * "buf" must hold at least "uncompressedLen" bytes.
- */
-/*static*/ bool ZipUtils::inflateToBuffer(int fd, void* buf,
-    long uncompressedLen, long compressedLen)
-{
-    bool result = false;
-	const unsigned long kReadBufSize = 32768;
-	unsigned char* readBuf = NULL;
-    z_stream zstream;
-    int zerr;
-    unsigned long compRemaining;
-
-    assert(uncompressedLen >= 0);
-    assert(compressedLen >= 0);
-
-	readBuf = new unsigned char[kReadBufSize];
-	if (readBuf == NULL)
-        goto bail;
-    compRemaining = compressedLen;
-
-    /*
-     * Initialize the zlib stream.
-     */
-	memset(&zstream, 0, sizeof(zstream));
-    zstream.zalloc = Z_NULL;
-    zstream.zfree = Z_NULL;
-    zstream.opaque = Z_NULL;
-    zstream.next_in = NULL;
-    zstream.avail_in = 0;
-    zstream.next_out = (Bytef*) buf;
-    zstream.avail_out = uncompressedLen;
-    zstream.data_type = Z_UNKNOWN;
-
-	/*
-	 * Use the undocumented "negative window bits" feature to tell zlib
-	 * that there's no zlib header waiting for it.
-	 */
-    zerr = inflateInit2(&zstream, -MAX_WBITS);
-    if (zerr != Z_OK) {
-        if (zerr == Z_VERSION_ERROR) {
-            ALOGE("Installed zlib is not compatible with linked version (%s)\n",
-                ZLIB_VERSION);
-        } else {
-            ALOGE("Call to inflateInit2 failed (zerr=%d)\n", zerr);
-        }
-        goto bail;
-    }
-
-    /*
-     * Loop while we have data.
-     */
-    do {
-        unsigned long getSize;
-
-        /* read as much as we can */
-        if (zstream.avail_in == 0) {
-            getSize = (compRemaining > kReadBufSize) ?
-                        kReadBufSize : compRemaining;
-            ALOGV("+++ reading %ld bytes (%ld left)\n",
-                getSize, compRemaining);
-
-            int cc = read(fd, readBuf, getSize);
-            if (cc != (int) getSize) {
-                ALOGD("inflate read failed (%d vs %ld)\n",
-                    cc, getSize);
-                goto z_bail;
-            }
-
-            compRemaining -= getSize;
-
-            zstream.next_in = readBuf;
-            zstream.avail_in = getSize;
-        }
-
-        /* uncompress the data */
-        zerr = inflate(&zstream, Z_NO_FLUSH);
-        if (zerr != Z_OK && zerr != Z_STREAM_END) {
-            ALOGD("zlib inflate call failed (zerr=%d)\n", zerr);
-            goto z_bail;
-        }
-
-		/* output buffer holds all, so no need to write the output */
-    } while (zerr == Z_OK);
-
-    assert(zerr == Z_STREAM_END);       /* other errors should've been caught */
-
-    if ((long) zstream.total_out != uncompressedLen) {
-        ALOGW("Size mismatch on inflated file (%ld vs %ld)\n",
-            zstream.total_out, uncompressedLen);
-        goto z_bail;
-    }
-
-    // success!
-    result = true;
-
-z_bail:
-    inflateEnd(&zstream);        /* free up any allocated structures */
-
-bail:
-	delete[] readBuf;
-    return result;
-}
-
-/*
- * Utility function that expands zip/gzip "deflate" compressed data
- * into a buffer.
- *
- * (This is a clone of the previous function, but it takes a FILE* instead
- * of an fd.  We could pass fileno(fd) to the above, but we can run into
- * trouble when "fp" has a different notion of what fd's file position is.)
- *
- * "fp" is an open file positioned at the start of the "deflate" data
- * "buf" must hold at least "uncompressedLen" bytes.
- */
-/*static*/ bool ZipUtils::inflateToBuffer(FILE* fp, void* buf,
-    long uncompressedLen, long compressedLen)
-{
-    bool result = false;
-	const unsigned long kReadBufSize = 32768;
-	unsigned char* readBuf = NULL;
-    z_stream zstream;
-    int zerr;
-    unsigned long compRemaining;
-
-    assert(uncompressedLen >= 0);
-    assert(compressedLen >= 0);
-
-	readBuf = new unsigned char[kReadBufSize];
-	if (readBuf == NULL)
-        goto bail;
-    compRemaining = compressedLen;
-
-    /*
-     * Initialize the zlib stream.
-     */
-	memset(&zstream, 0, sizeof(zstream));
-    zstream.zalloc = Z_NULL;
-    zstream.zfree = Z_NULL;
-    zstream.opaque = Z_NULL;
-    zstream.next_in = NULL;
-    zstream.avail_in = 0;
-    zstream.next_out = (Bytef*) buf;
-    zstream.avail_out = uncompressedLen;
-    zstream.data_type = Z_UNKNOWN;
-
-	/*
-	 * Use the undocumented "negative window bits" feature to tell zlib
-	 * that there's no zlib header waiting for it.
-	 */
-    zerr = inflateInit2(&zstream, -MAX_WBITS);
-    if (zerr != Z_OK) {
-        if (zerr == Z_VERSION_ERROR) {
-            ALOGE("Installed zlib is not compatible with linked version (%s)\n",
-                ZLIB_VERSION);
-        } else {
-            ALOGE("Call to inflateInit2 failed (zerr=%d)\n", zerr);
-        }
-        goto bail;
-    }
-
-    /*
-     * Loop while we have data.
-     */
-    do {
-        unsigned long getSize;
-
-        /* read as much as we can */
-        if (zstream.avail_in == 0) {
-            getSize = (compRemaining > kReadBufSize) ?
-                        kReadBufSize : compRemaining;
-            ALOGV("+++ reading %ld bytes (%ld left)\n",
-                getSize, compRemaining);
-
-            int cc = fread(readBuf, 1, getSize, fp);
-            if (cc != (int) getSize) {
-                ALOGD("inflate read failed (%d vs %ld)\n",
-                    cc, getSize);
-                goto z_bail;
-            }
-
-            compRemaining -= getSize;
-
-            zstream.next_in = readBuf;
-            zstream.avail_in = getSize;
-        }
-
-        /* uncompress the data */
-        zerr = inflate(&zstream, Z_NO_FLUSH);
-        if (zerr != Z_OK && zerr != Z_STREAM_END) {
-            ALOGD("zlib inflate call failed (zerr=%d)\n", zerr);
-            goto z_bail;
-        }
-
-		/* output buffer holds all, so no need to write the output */
-    } while (zerr == Z_OK);
-
-    assert(zerr == Z_STREAM_END);       /* other errors should've been caught */
-
-    if ((long) zstream.total_out != uncompressedLen) {
-        ALOGW("Size mismatch on inflated file (%ld vs %ld)\n",
-            zstream.total_out, uncompressedLen);
-        goto z_bail;
-    }
-
-    // success!
-    result = true;
-
-z_bail:
-    inflateEnd(&zstream);        /* free up any allocated structures */
-
-bail:
-	delete[] readBuf;
-    return result;
-}
-
-/*
- * Look at the contents of a gzip archive.  We want to know where the
- * data starts, and how long it will be after it is uncompressed.
- *
- * We expect to find the CRC and length as the last 8 bytes on the file.
- * This is a pretty reasonable thing to expect for locally-compressed
- * files, but there's a small chance that some extra padding got thrown
- * on (the man page talks about compressed data written to tape).  We
- * don't currently deal with that here.  If "gzip -l" whines, we're going
- * to fail too.
- *
- * On exit, "fp" is pointing at the start of the compressed data.
- */
-/*static*/ bool ZipUtils::examineGzip(FILE* fp, int* pCompressionMethod,
-    long* pUncompressedLen, long* pCompressedLen, unsigned long* pCRC32)
-{
-    enum {  // flags
-        FTEXT       = 0x01,
-        FHCRC       = 0x02,
-        FEXTRA      = 0x04,
-        FNAME       = 0x08,
-        FCOMMENT    = 0x10,
-    };
-    int ic;
-    int method, flags;
-    int i;
-
-    ic = getc(fp);
-    if (ic != 0x1f || getc(fp) != 0x8b)
-        return false;       // not gzip
-    method = getc(fp);
-    flags = getc(fp);
-
-    /* quick sanity checks */
-    if (method == EOF || flags == EOF)
-        return false;
-    if (method != ZipFileRO::kCompressDeflated)
-        return false;
-
-    /* skip over 4 bytes of mod time, 1 byte XFL, 1 byte OS */
-    for (i = 0; i < 6; i++)
-        (void) getc(fp);
-    /* consume "extra" field, if present */
-    if ((flags & FEXTRA) != 0) {
-        int len;
-
-        len = getc(fp);
-        len |= getc(fp) << 8;
-        while (len-- && getc(fp) != EOF)
-            ;
-    }
-    /* consume filename, if present */
-    if ((flags & FNAME) != 0) {
-        do {
-            ic = getc(fp);
-        } while (ic != 0 && ic != EOF);
-    }
-    /* consume comment, if present */
-    if ((flags & FCOMMENT) != 0) {
-        do {
-            ic = getc(fp);
-        } while (ic != 0 && ic != EOF);
-    }
-    /* consume 16-bit header CRC, if present */
-    if ((flags & FHCRC) != 0) {
-        (void) getc(fp);
-        (void) getc(fp);
-    }
-
-    if (feof(fp) || ferror(fp))
-        return false;
-
-    /* seek to the end; CRC and length are in the last 8 bytes */
-    long curPosn = ftell(fp);
-    unsigned char buf[8];
-    fseek(fp, -8, SEEK_END);
-    *pCompressedLen = ftell(fp) - curPosn;
-
-    if (fread(buf, 1, 8, fp) != 8)
-        return false;
-    /* seek back to start of compressed data */
-    fseek(fp, curPosn, SEEK_SET);
-
-    *pCompressionMethod = method;
-    *pCRC32 = ZipFileRO::get4LE(&buf[0]);
-    *pUncompressedLen = ZipFileRO::get4LE(&buf[4]);
-
-    return true;
-}
diff --git a/libs/androidfw/tests/Android.mk b/libs/androidfw/tests/Android.mk
index d85009b..39009b8 100644
--- a/libs/androidfw/tests/Android.mk
+++ b/libs/androidfw/tests/Android.mk
@@ -7,8 +7,7 @@
     InputChannel_test.cpp \
     InputEvent_test.cpp \
     InputPublisherAndConsumer_test.cpp \
-    ObbFile_test.cpp \
-    ZipFileRO_test.cpp 
+    ObbFile_test.cpp
 
 shared_libraries := \
 	libandroidfw \
diff --git a/libs/androidfw/tests/ZipFileRO_test.cpp b/libs/androidfw/tests/ZipFileRO_test.cpp
deleted file mode 100644
index 344f974..0000000
--- a/libs/androidfw/tests/ZipFileRO_test.cpp
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2011 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 "ZipFileRO_test"
-#include <androidfw/ZipFileRO.h>
-#include <utils/Log.h>
-
-#include <gtest/gtest.h>
-
-#include <fcntl.h>
-#include <string.h>
-
-namespace android {
-
-class ZipFileROTest : public testing::Test {
-protected:
-    virtual void SetUp() {
-    }
-
-    virtual void TearDown() {
-    }
-};
-
-TEST_F(ZipFileROTest, ZipTimeConvertSuccess) {
-    struct tm t;
-
-    // 2011-06-29 14:40:40
-    long when = 0x3EDD7514;
-
-    ZipFileRO::zipTimeToTimespec(when, &t);
-
-    EXPECT_EQ(2011, t.tm_year + 1900)
-            << "Year was improperly converted.";
-
-    EXPECT_EQ(6, t.tm_mon)
-            << "Month was improperly converted.";
-
-    EXPECT_EQ(29, t.tm_mday)
-            << "Day was improperly converted.";
-
-    EXPECT_EQ(14, t.tm_hour)
-            << "Hour was improperly converted.";
-
-    EXPECT_EQ(40, t.tm_min)
-            << "Minute was improperly converted.";
-
-    EXPECT_EQ(40, t.tm_sec)
-            << "Second was improperly converted.";
-}
-
-}
diff --git a/libs/rs/Allocation.cpp b/libs/rs/Allocation.cpp
index d69c55f..e37d5de 100644
--- a/libs/rs/Allocation.cpp
+++ b/libs/rs/Allocation.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008-2012 The Android Open Source Project
+ * Copyright (C) 2012 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.
@@ -51,17 +51,14 @@
                    RS_ALLOCATION_USAGE_GRAPHICS_VERTEX |
                    RS_ALLOCATION_USAGE_GRAPHICS_CONSTANTS |
                    RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET |
-                   RS_ALLOCATION_USAGE_GRAPHICS_SURFACE_TEXTURE_INPUT_OPAQUE |
                    RS_ALLOCATION_USAGE_IO_INPUT |
                    RS_ALLOCATION_USAGE_IO_OUTPUT)) != 0) {
         ALOGE("Unknown usage specified.");
     }
 
-    if ((usage & (RS_ALLOCATION_USAGE_GRAPHICS_SURFACE_TEXTURE_INPUT_OPAQUE |
-                  RS_ALLOCATION_USAGE_IO_INPUT)) != 0) {
+    if ((usage & RS_ALLOCATION_USAGE_IO_INPUT) != 0) {
         mWriteAllowed = false;
-        if ((usage & ~(RS_ALLOCATION_USAGE_GRAPHICS_SURFACE_TEXTURE_INPUT_OPAQUE |
-                       RS_ALLOCATION_USAGE_IO_INPUT |
+        if ((usage & ~(RS_ALLOCATION_USAGE_IO_INPUT |
                        RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE |
                        RS_ALLOCATION_USAGE_SCRIPT)) != 0) {
             ALOGE("Invalid usage combination.");
diff --git a/libs/rs/driver/rsdAllocation.cpp b/libs/rs/driver/rsdAllocation.cpp
index fb93d82..f358f93 100644
--- a/libs/rs/driver/rsdAllocation.cpp
+++ b/libs/rs/driver/rsdAllocation.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011 The Android Open Source Project
+ * Copyright (C) 2011-2012 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.
@@ -27,6 +27,7 @@
 #include "hardware/gralloc.h"
 #include "ui/Rect.h"
 #include "ui/GraphicBufferMapper.h"
+#include "gui/SurfaceTexture.h"
 
 #include <GLES/gl.h>
 #include <GLES2/gl2.h>
@@ -139,7 +140,7 @@
 static void UploadToTexture(const Context *rsc, const Allocation *alloc) {
     DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
 
-    if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_SURFACE_TEXTURE_INPUT_OPAQUE) {
+    if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_IO_INPUT) {
         if (!drv->textureID) {
             RSD_CALL_GL(glGenTextures, 1, &drv->textureID);
         }
@@ -475,7 +476,8 @@
 }
 
 void rsdAllocationIoReceive(const Context *rsc, Allocation *alloc) {
-    ALOGE("not implemented");
+    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
+    alloc->mHal.state.surfaceTexture->updateTexImage();
 }
 
 
diff --git a/libs/rs/driver/rsdCore.cpp b/libs/rs/driver/rsdCore.cpp
index 35a5c08..6a532e9 100644
--- a/libs/rs/driver/rsdCore.cpp
+++ b/libs/rs/driver/rsdCore.cpp
@@ -227,13 +227,13 @@
 
 
     int cpu = sysconf(_SC_NPROCESSORS_ONLN);
-    ALOGV("%p Launching thread(s), CPUs %i", rsc, cpu);
     if(rsc->props.mDebugMaxThreads && (cpu > (int)rsc->props.mDebugMaxThreads)) {
         cpu = rsc->props.mDebugMaxThreads;
     }
     if (cpu < 2) {
         cpu = 0;
     }
+    ALOGV("%p Launching thread(s), CPUs %i", rsc, cpu);
 
     dc->mWorkers.mCount = (uint32_t)cpu;
     dc->mWorkers.mThreadId = (pthread_t *) calloc(dc->mWorkers.mCount, sizeof(pthread_t));
diff --git a/libs/rs/driver/rsdProgram.cpp b/libs/rs/driver/rsdProgram.cpp
index fa4cb0f..30a4c5f 100644
--- a/libs/rs/driver/rsdProgram.cpp
+++ b/libs/rs/driver/rsdProgram.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011 The Android Open Source Project
+ * Copyright (C) 2011-2012 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.
@@ -41,7 +41,7 @@
                                    textureNames, textureNamesCount, textureNamesLength);
     pv->mHal.drv = drv;
 
-    return drv->createShader();
+    return true;
 }
 
 static void SyncProgramConstants(const Context *rsc, const Program *p) {
@@ -88,7 +88,7 @@
                                    textureNames, textureNamesCount, textureNamesLength);
     pf->mHal.drv = drv;
 
-    return drv->createShader();
+    return true;
 }
 
 void rsdProgramFragmentSetActive(const Context *rsc, const ProgramFragment *pf) {
diff --git a/libs/rs/driver/rsdShader.cpp b/libs/rs/driver/rsdShader.cpp
index 1e73b95..a386735 100644
--- a/libs/rs/driver/rsdShader.cpp
+++ b/libs/rs/driver/rsdShader.cpp
@@ -39,7 +39,10 @@
     initMemberVars();
     initAttribAndUniformArray();
     init(textureNames, textureNamesCount, textureNamesLength);
-    createTexturesString(textureNames, textureNamesCount, textureNamesLength);
+
+    for(size_t i=0; i < textureNamesCount; i++) {
+        mTextureNames.push(String8(textureNames[i], textureNamesLength[i]));
+    }
 }
 
 RsdShader::~RsdShader() {
@@ -138,37 +141,42 @@
     }
 }
 
-void RsdShader::createTexturesString(const char** textureNames, size_t textureNamesCount,
-                                     const size_t *textureNamesLength) {
-    mShaderTextures.setTo("");
+void RsdShader::appendTextures() {
+
+    // TODO: this does not yet handle cases where the texture changes between IO
+    // input and local
+    bool appendUsing = true;
     for (uint32_t ct = 0; ct < mRSProgram->mHal.state.texturesCount; ct ++) {
         if (mRSProgram->mHal.state.textureTargets[ct] == RS_TEXTURE_2D) {
             Allocation *a = mRSProgram->mHal.state.textures[ct];
             if (a && a->mHal.state.surfaceTextureID) {
-                mShaderTextures.append("uniform samplerExternalOES UNI_");
+                if(appendUsing) {
+                    mShader.append("#extension GL_OES_EGL_image_external : require\n");
+                    appendUsing = false;
+                }
+                mShader.append("uniform samplerExternalOES UNI_");
+                mTextureTargets[ct] = GL_TEXTURE_EXTERNAL_OES;
             } else {
-                mShaderTextures.append("uniform sampler2D UNI_");
+                mShader.append("uniform sampler2D UNI_");
+                mTextureTargets[ct] = GL_TEXTURE_2D;
             }
-            mTextureTargets[ct] = GL_TEXTURE_2D;
         } else {
-            mShaderTextures.append("uniform samplerCube UNI_");
+            mShader.append("uniform samplerCube UNI_");
             mTextureTargets[ct] = GL_TEXTURE_CUBE_MAP;
         }
 
-        mShaderTextures.append(textureNames[ct], textureNamesLength[ct]);
-        mShaderTextures.append(";\n");
+        mShader.append(mTextureNames[ct]);
+        mShader.append(";\n");
     }
 }
 
 bool RsdShader::createShader() {
-
     if (mType == GL_FRAGMENT_SHADER) {
         mShader.append("precision mediump float;\n");
     }
     appendUserConstants();
     appendAttributes();
-    mShader.append(mShaderTextures);
-
+    appendTextures();
     mShader.append(mUserShader);
 
     return true;
@@ -178,6 +186,10 @@
     mShaderID = glCreateShader(mType);
     rsAssert(mShaderID);
 
+    if(!mShader.length()) {
+        createShader();
+    }
+
     if (rsc->props.mLogShaders) {
         ALOGV("Loading shader type %x, ID %i", mType, mShaderID);
         ALOGV("%s", mShader.string());
@@ -423,7 +435,9 @@
         }
 
         DrvAllocation *drvTex = (DrvAllocation *)mRSProgram->mHal.state.textures[ct]->mHal.drv;
-        if (drvTex->glTarget != GL_TEXTURE_2D && drvTex->glTarget != GL_TEXTURE_CUBE_MAP) {
+        if (drvTex->glTarget != GL_TEXTURE_2D &&
+            drvTex->glTarget != GL_TEXTURE_CUBE_MAP &&
+            drvTex->glTarget != GL_TEXTURE_EXTERNAL_OES) {
             ALOGE("Attempting to bind unknown texture to shader id %u, texture unit %u",
                   (uint)this, ct);
             rsc->setError(RS_ERROR_BAD_SHADER, "Non-texture allocation bound to a shader");
diff --git a/libs/rs/driver/rsdShader.h b/libs/rs/driver/rsdShader.h
index e32145f..6c0b616 100644
--- a/libs/rs/driver/rsdShader.h
+++ b/libs/rs/driver/rsdShader.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011 The Android Open Source Project
+ * Copyright (C) 2011-2012 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.
@@ -81,15 +81,12 @@
 
     void appendAttributes();
     void appendTextures();
-    void createTexturesString(const char** textureNames, size_t textureNamesCount,
-                              const size_t *textureNamesLength);
 
     void initAttribAndUniformArray();
 
     mutable bool mDirty;
     android::String8 mShader;
     android::String8 mUserShader;
-    android::String8 mShaderTextures;
     uint32_t mShaderID;
     uint32_t mType;
 
@@ -101,6 +98,8 @@
     android::String8 *mUniformNames;
     uint32_t *mUniformArraySizes;
 
+    android::Vector<android::String8> mTextureNames;
+
     int32_t mTextureUniformIndexStart;
 
     void logUniform(const android::renderscript::Element *field,
diff --git a/libs/rs/driver/rsdShaderCache.cpp b/libs/rs/driver/rsdShaderCache.cpp
index 89d3c45..50cb9f9 100644
--- a/libs/rs/driver/rsdShaderCache.cpp
+++ b/libs/rs/driver/rsdShaderCache.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011 The Android Open Source Project
+ * Copyright (C) 2011-2012 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.
@@ -119,7 +119,6 @@
     if (!vtx->getShaderID() || !frag->getShaderID()) {
         return false;
     }
-    //ALOGV("rsdShaderCache lookup  vtx %i, frag %i", vtx->getShaderID(), frag->getShaderID());
     uint32_t entryCount = mEntries.size();
     for (uint32_t ct = 0; ct < entryCount; ct ++) {
         if ((mEntries[ct]->vtx == vtx->getShaderID()) &&
@@ -134,8 +133,6 @@
         }
     }
 
-    //ALOGV("RsdShaderCache miss");
-    //ALOGE("e0 %x", glGetError());
     ProgramEntry *e = new ProgramEntry(vtx->getAttribCount(),
                                        vtx->getUniformCount(),
                                        frag->getUniformCount());
diff --git a/libs/rs/driver/rsdShaderCache.h b/libs/rs/driver/rsdShaderCache.h
index 0beecae..1192916 100644
--- a/libs/rs/driver/rsdShaderCache.h
+++ b/libs/rs/driver/rsdShaderCache.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011 The Android Open Source Project
+ * Copyright (C) 2011-2012 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.
diff --git a/libs/rs/rs.spec b/libs/rs/rs.spec
index cf4a391..b373056 100644
--- a/libs/rs/rs.spec
+++ b/libs/rs/rs.spec
@@ -69,6 +69,12 @@
     ret int32_t
 }
 
+AllocationGetSurfaceTextureID2 {
+    param RsAllocation alloc
+    param void *st
+    sync
+}
+
 AllocationSetSurface {
     param RsAllocation alloc
     param RsNativeWindow sur
diff --git a/libs/rs/rsAllocation.cpp b/libs/rs/rsAllocation.cpp
index a404c49..cdff49c 100644
--- a/libs/rs/rsAllocation.cpp
+++ b/libs/rs/rsAllocation.cpp
@@ -20,6 +20,7 @@
 #include "rs_hal.h"
 
 #include "system/window.h"
+#include "gui/SurfaceTexture.h"
 
 using namespace android;
 using namespace android::renderscript;
@@ -64,6 +65,7 @@
 
 Allocation::~Allocation() {
     freeChildrenUnlocked();
+    setSurfaceTexture(mRSC, NULL);
     mRSC->mHal.funcs.allocation.destroy(mRSC, this);
 }
 
@@ -424,6 +426,18 @@
     return id;
 }
 
+void Allocation::setSurfaceTexture(const Context *rsc, SurfaceTexture *st) {
+    if(st != mHal.state.surfaceTexture) {
+        if(mHal.state.surfaceTexture != NULL) {
+            mHal.state.surfaceTexture->decStrong(NULL);
+        }
+        mHal.state.surfaceTexture = st;
+        if(mHal.state.surfaceTexture != NULL) {
+            mHal.state.surfaceTexture->incStrong(NULL);
+        }
+    }
+}
+
 void Allocation::setSurface(const Context *rsc, RsNativeWindow sur) {
     ANativeWindow *nw = (ANativeWindow *)sur;
     ANativeWindow *old = mHal.state.wndSurface;
@@ -696,6 +710,11 @@
     return alloc->getSurfaceTextureID(rsc);
 }
 
+void rsi_AllocationGetSurfaceTextureID2(Context *rsc, RsAllocation valloc, void *vst, size_t len) {
+    Allocation *alloc = static_cast<Allocation *>(valloc);
+    alloc->setSurfaceTexture(rsc, static_cast<SurfaceTexture *>(vst));
+}
+
 void rsi_AllocationSetSurface(Context *rsc, RsAllocation valloc, RsNativeWindow sur) {
     Allocation *alloc = static_cast<Allocation *>(valloc);
     alloc->setSurface(rsc, sur);
diff --git a/libs/rs/rsAllocation.h b/libs/rs/rsAllocation.h
index 58a6fca..e2783d2 100644
--- a/libs/rs/rsAllocation.h
+++ b/libs/rs/rsAllocation.h
@@ -23,6 +23,8 @@
 
 // ---------------------------------------------------------------------------
 namespace android {
+class SurfaceTexture;
+
 namespace renderscript {
 
 class Program;
@@ -60,6 +62,7 @@
             void * usrPtr;
             int32_t surfaceTextureID;
             ANativeWindow *wndSurface;
+            SurfaceTexture *surfaceTexture;
         };
         State state;
 
@@ -130,6 +133,7 @@
     }
 
     int32_t getSurfaceTextureID(const Context *rsc);
+    void setSurfaceTexture(const Context *rsc, SurfaceTexture *st);
     void setSurface(const Context *rsc, RsNativeWindow sur);
     void ioSend(const Context *rsc);
     void ioReceive(const Context *rsc);
diff --git a/libs/rs/rsDefines.h b/libs/rs/rsDefines.h
index 990ef26..0e0cd8d 100644
--- a/libs/rs/rsDefines.h
+++ b/libs/rs/rsDefines.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2007 The Android Open Source Project
+ * Copyright (C) 2007-2012 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.
@@ -100,9 +100,8 @@
     RS_ALLOCATION_USAGE_GRAPHICS_VERTEX = 0x0004,
     RS_ALLOCATION_USAGE_GRAPHICS_CONSTANTS = 0x0008,
     RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET = 0x0010,
-    RS_ALLOCATION_USAGE_GRAPHICS_SURFACE_TEXTURE_INPUT_OPAQUE = 0x0020,
-    RS_ALLOCATION_USAGE_IO_INPUT = 0x0040,
-    RS_ALLOCATION_USAGE_IO_OUTPUT = 0x0080,
+    RS_ALLOCATION_USAGE_IO_INPUT = 0x0020,
+    RS_ALLOCATION_USAGE_IO_OUTPUT = 0x0040,
 
     RS_ALLOCATION_USAGE_ALL = 0x00FF
 };
diff --git a/libs/rs/scriptc/rs_allocation.rsh b/libs/rs/scriptc/rs_allocation.rsh
index 392a3ef..b0840a0 100644
--- a/libs/rs/scriptc/rs_allocation.rsh
+++ b/libs/rs/scriptc/rs_allocation.rsh
@@ -14,31 +14,6 @@
  * limitations under the License.
  */
 
-/*! \mainpage notitle
- *
- * Renderscript is a high-performance runtime that provides graphics rendering and
- * compute operations at the native level. Renderscript code is compiled on devices
- * at runtime to allow platform-independence as well.
- * This reference documentation describes the Renderscript runtime APIs, which you
- * can utilize to write Renderscript code in C99. The Renderscript header
- * files are automatically included for you, except for the rs_graphics.rsh header. If
- * you are doing graphics rendering, include the graphics header file like this:
- *
- * <code>#include "rs_graphics.rsh"</code>
- *
- * To use Renderscript, you need to utilize the Renderscript runtime APIs documented here
- * as well as the Android framework APIs for Renderscript.
- * For documentation on the Android framework APIs, see the <a target="_parent" href=
- * "http://developer.android.com/reference/android/renderscript/package-summary.html">
- * android.renderscript</a> package reference.
- * For more information on how to develop with Renderscript and how the runtime and
- * Android framework APIs interact, see the <a target="_parent" href=
- * "http://developer.android.com/guide/topics/renderscript/index.html">Renderscript
- * developer guide</a> and the <a target="_parent" href=
- * "http://developer.android.com/resources/samples/RenderScript/index.html">
- * Renderscript samples</a>.
- */
-
 /** @file rs_allocation.rsh
  *  \brief Allocation routines
  *
@@ -168,6 +143,8 @@
 extern const void * __attribute__((overloadable))
     rsGetElementAt(rs_allocation, uint32_t x, uint32_t y, uint32_t z);
 
+#if (defined(RS_VERSION) && (RS_VERSION >= 16))
+
 /**
  * @param a allocation to get data from
  * @return element describing allocation layout
@@ -216,26 +193,7 @@
 extern const float4 __attribute__((overloadable))
     rsSample(rs_allocation a, rs_sampler s, float2 location, float lod);
 
-/**
- * Fetch allocation in a way described by the sampler
- * @param a 3D allocation to sample from
- * @param s sampler state
- * @param location to sample from
- */
-extern const float4 __attribute__((overloadable))
-    rsSample(rs_allocation a, rs_sampler s, float3 location);
-
-/**
- * Fetch allocation in a way described by the sampler
- * @param a 3D allocation to sample from
- * @param s sampler state
- * @param location to sample from
- * @param lod mip level to sample from, for fractional values
- *            mip levels will be interpolated if
- *            RS_SAMPLER_LINEAR_MIP_LINEAR is used
- */
-extern const float4 __attribute__((overloadable))
-    rsSample(rs_allocation a, rs_sampler s, float3 location, float lod);
+#endif // (defined(RS_VERSION) && (RS_VERSION >= 16))
 
 #endif
 
diff --git a/libs/rs/scriptc/rs_core.rsh b/libs/rs/scriptc/rs_core.rsh
index 5b99976..1b0f9db 100644
--- a/libs/rs/scriptc/rs_core.rsh
+++ b/libs/rs/scriptc/rs_core.rsh
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011 The Android Open Source Project
+ * Copyright (C) 2011-2012 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.
@@ -14,6 +14,31 @@
  * limitations under the License.
  */
 
+ /*! \mainpage notitle
+  *
+  * Renderscript is a high-performance runtime that provides graphics rendering and
+  * compute operations at the native level. Renderscript code is compiled on devices
+  * at runtime to allow platform-independence as well.
+  * This reference documentation describes the Renderscript runtime APIs, which you
+  * can utilize to write Renderscript code in C99. The Renderscript header
+  * files are automatically included for you, except for the rs_graphics.rsh header. If
+  * you are doing graphics rendering, include the graphics header file like this:
+  *
+  * <code>#include "rs_graphics.rsh"</code>
+  *
+  * To use Renderscript, you need to utilize the Renderscript runtime APIs documented here
+  * as well as the Android framework APIs for Renderscript.
+  * For documentation on the Android framework APIs, see the <a target="_parent" href=
+  * "http://developer.android.com/reference/android/renderscript/package-summary.html">
+  * android.renderscript</a> package reference.
+  * For more information on how to develop with Renderscript and how the runtime and
+  * Android framework APIs interact, see the <a target="_parent" href=
+  * "http://developer.android.com/guide/topics/renderscript/index.html">Renderscript
+  * developer guide</a> and the <a target="_parent" href=
+  * "http://developer.android.com/resources/samples/RenderScript/index.html">
+  * Renderscript samples</a>.
+  */
+
 /** @file rs_core.rsh
  *  \brief todo-jsams
  *
@@ -33,16 +58,12 @@
 #include "rs_debug.rsh"
 #include "rs_element.rsh"
 #include "rs_math.rsh"
-#include "rs_mesh.rsh"
 #include "rs_matrix.rsh"
 #include "rs_object.rsh"
-#include "rs_program.rsh"
 #include "rs_quaternion.rsh"
 #include "rs_sampler.rsh"
 #include "rs_time.rsh"
 
-
-
 /**
  * Send a message back to the client.  Will not block and returns true
  * if the message was sendable and false if the fifo was full.
diff --git a/libs/rs/scriptc/rs_element.rsh b/libs/rs/scriptc/rs_element.rsh
index 72cb51c..1a4cdb75 100644
--- a/libs/rs/scriptc/rs_element.rsh
+++ b/libs/rs/scriptc/rs_element.rsh
@@ -14,31 +14,6 @@
  * limitations under the License.
  */
 
-/*! \mainpage notitle
- *
- * Renderscript is a high-performance runtime that provides graphics rendering and
- * compute operations at the native level. Renderscript code is compiled on devices
- * at runtime to allow platform-independence as well.
- * This reference documentation describes the Renderscript runtime APIs, which you
- * can utilize to write Renderscript code in C99. The Renderscript header
- * files are automatically included for you, except for the rs_graphics.rsh header. If
- * you are doing graphics rendering, include the graphics header file like this:
- *
- * <code>#include "rs_graphics.rsh"</code>
- *
- * To use Renderscript, you need to utilize the Renderscript runtime APIs documented here
- * as well as the Android framework APIs for Renderscript.
- * For documentation on the Android framework APIs, see the <a target="_parent" href=
- * "http://developer.android.com/reference/android/renderscript/package-summary.html">
- * android.renderscript</a> package reference.
- * For more information on how to develop with Renderscript and how the runtime and
- * Android framework APIs interact, see the <a target="_parent" href=
- * "http://developer.android.com/guide/topics/renderscript/index.html">Renderscript
- * developer guide</a> and the <a target="_parent" href=
- * "http://developer.android.com/resources/samples/RenderScript/index.html">
- * Renderscript samples</a>.
- */
-
 /** @file rs_element.rsh
  *  \brief Element routines
  *
@@ -48,6 +23,8 @@
 #ifndef __RS_ELEMENT_RSH__
 #define __RS_ELEMENT_RSH__
 
+#if (defined(RS_VERSION) && (RS_VERSION >= 16))
+
 /**
  * @param e element to get data from
  * @return number of sub-elements in this element
@@ -130,5 +107,7 @@
 extern uint32_t __attribute__((overloadable))
     rsElementGetVectorSize(rs_element e);
 
+#endif // (defined(RS_VERSION) && (RS_VERSION >= 16))
+
 #endif // __RS_ELEMENT_RSH__
 
diff --git a/libs/rs/scriptc/rs_graphics.rsh b/libs/rs/scriptc/rs_graphics.rsh
index 80491ee..44ee99f 100644
--- a/libs/rs/scriptc/rs_graphics.rsh
+++ b/libs/rs/scriptc/rs_graphics.rsh
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011 The Android Open Source Project
+ * Copyright (C) 2011-2012 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.
@@ -23,6 +23,9 @@
 #ifndef __RS_GRAPHICS_RSH__
 #define __RS_GRAPHICS_RSH__
 
+#include "rs_mesh.rsh"
+#include "rs_program.rsh"
+
 #if (defined(RS_VERSION) && (RS_VERSION >= 14))
 /**
  * Set the color target used for all subsequent rendering calls
diff --git a/libs/rs/scriptc/rs_mesh.rsh b/libs/rs/scriptc/rs_mesh.rsh
index 88f229b..87ffd33 100644
--- a/libs/rs/scriptc/rs_mesh.rsh
+++ b/libs/rs/scriptc/rs_mesh.rsh
@@ -14,31 +14,6 @@
  * limitations under the License.
  */
 
-/*! \mainpage notitle
- *
- * Renderscript is a high-performance runtime that provides graphics rendering and
- * compute operations at the native level. Renderscript code is compiled on devices
- * at runtime to allow platform-independence as well.
- * This reference documentation describes the Renderscript runtime APIs, which you
- * can utilize to write Renderscript code in C99. The Renderscript header
- * files are automatically included for you, except for the rs_graphics.rsh header. If
- * you are doing graphics rendering, include the graphics header file like this:
- *
- * <code>#include "rs_graphics.rsh"</code>
- *
- * To use Renderscript, you need to utilize the Renderscript runtime APIs documented here
- * as well as the Android framework APIs for Renderscript.
- * For documentation on the Android framework APIs, see the <a target="_parent" href=
- * "http://developer.android.com/reference/android/renderscript/package-summary.html">
- * android.renderscript</a> package reference.
- * For more information on how to develop with Renderscript and how the runtime and
- * Android framework APIs interact, see the <a target="_parent" href=
- * "http://developer.android.com/guide/topics/renderscript/index.html">Renderscript
- * developer guide</a> and the <a target="_parent" href=
- * "http://developer.android.com/resources/samples/RenderScript/index.html">
- * Renderscript samples</a>.
- */
-
 /** @file rs_mesh.rsh
  *  \brief Mesh routines
  *
@@ -48,13 +23,15 @@
 #ifndef __RS_MESH_RSH__
 #define __RS_MESH_RSH__
 
+#if (defined(RS_VERSION) && (RS_VERSION >= 16))
+
 /**
  * @param m mesh to get data from
  * @return number of allocations in the mesh that contain vertex
  *         data
  */
 extern uint32_t __attribute__((overloadable))
-    rsMeshGetVertexAllocationCount(rs_mesh m);
+    rsgMeshGetVertexAllocationCount(rs_mesh m);
 
 /**
  * @param m mesh to get data from
@@ -63,7 +40,7 @@
  *         containing index data
  */
 extern uint32_t __attribute__((overloadable))
-    rsMeshGetPrimitiveCount(rs_mesh m);
+    rsgMeshGetPrimitiveCount(rs_mesh m);
 
 /**
  * @param m mesh to get data from
@@ -71,7 +48,7 @@
  * @return allocation containing vertex data
  */
 extern rs_allocation __attribute__((overloadable))
-    rsMeshGetVertexAllocation(rs_mesh m, uint32_t index);
+    rsgMeshGetVertexAllocation(rs_mesh m, uint32_t index);
 
 /**
  * @param m mesh to get data from
@@ -79,7 +56,7 @@
  * @return allocation containing index data
  */
 extern rs_allocation __attribute__((overloadable))
-    rsMeshGetIndexAllocation(rs_mesh m, uint32_t index);
+    rsgMeshGetIndexAllocation(rs_mesh m, uint32_t index);
 
 /**
  * @param m mesh to get data from
@@ -87,7 +64,9 @@
  * @return primitive describing how the mesh is rendered
  */
 extern rs_primitive __attribute__((overloadable))
-    rsMeshGetPrimitive(rs_mesh m, uint32_t index);
+    rsgMeshGetPrimitive(rs_mesh m, uint32_t index);
+
+#endif // (defined(RS_VERSION) && (RS_VERSION >= 16))
 
 #endif // __RS_MESH_RSH__
 
diff --git a/libs/rs/scriptc/rs_program.rsh b/libs/rs/scriptc/rs_program.rsh
index 8c52680..6a9929e 100644
--- a/libs/rs/scriptc/rs_program.rsh
+++ b/libs/rs/scriptc/rs_program.rsh
@@ -14,31 +14,6 @@
  * limitations under the License.
  */
 
-/*! \mainpage notitle
- *
- * Renderscript is a high-performance runtime that provides graphics rendering and
- * compute operations at the native level. Renderscript code is compiled on devices
- * at runtime to allow platform-independence as well.
- * This reference documentation describes the Renderscript runtime APIs, which you
- * can utilize to write Renderscript code in C99. The Renderscript header
- * files are automatically included for you, except for the rs_graphics.rsh header. If
- * you are doing graphics rendering, include the graphics header file like this:
- *
- * <code>#include "rs_graphics.rsh"</code>
- *
- * To use Renderscript, you need to utilize the Renderscript runtime APIs documented here
- * as well as the Android framework APIs for Renderscript.
- * For documentation on the Android framework APIs, see the <a target="_parent" href=
- * "http://developer.android.com/reference/android/renderscript/package-summary.html">
- * android.renderscript</a> package reference.
- * For more information on how to develop with Renderscript and how the runtime and
- * Android framework APIs interact, see the <a target="_parent" href=
- * "http://developer.android.com/guide/topics/renderscript/index.html">Renderscript
- * developer guide</a> and the <a target="_parent" href=
- * "http://developer.android.com/resources/samples/RenderScript/index.html">
- * Renderscript samples</a>.
- */
-
 /** @file rs_program.rsh
  *  \brief Program object routines
  *
@@ -48,6 +23,8 @@
 #ifndef __RS_PROGRAM_RSH__
 #define __RS_PROGRAM_RSH__
 
+#if (defined(RS_VERSION) && (RS_VERSION >= 16))
+
 /**
  * @hide
  * Get program store depth function
@@ -55,7 +32,7 @@
  * @param ps
  */
 extern rs_depth_func __attribute__((overloadable))
-    rsProgramStoreGetDepthFunc(rs_program_store ps);
+    rsgProgramStoreGetDepthFunc(rs_program_store ps);
 
 /**
  * @hide
@@ -64,7 +41,7 @@
  * @param ps
  */
 extern bool __attribute__((overloadable))
-    rsProgramStoreGetDepthMask(rs_program_store ps);
+    rsgProgramStoreGetDepthMask(rs_program_store ps);
 /**
  * @hide
  * Get program store red component color mask
@@ -72,7 +49,7 @@
  * @param ps
  */
 extern bool __attribute__((overloadable))
-    rsProgramStoreGetColorMaskR(rs_program_store ps);
+    rsgProgramStoreGetColorMaskR(rs_program_store ps);
 
 /**
  * @hide
@@ -81,7 +58,7 @@
  * @param ps
  */
 extern bool __attribute__((overloadable))
-    rsProgramStoreGetColorMaskG(rs_program_store ps);
+    rsgProgramStoreGetColorMaskG(rs_program_store ps);
 
 /**
  * @hide
@@ -90,7 +67,7 @@
  * @param ps
  */
 extern bool __attribute__((overloadable))
-    rsProgramStoreGetColorMaskB(rs_program_store ps);
+    rsgProgramStoreGetColorMaskB(rs_program_store ps);
 
 /**
  * @hide
@@ -99,7 +76,7 @@
  * @param ps
  */
 extern bool __attribute__((overloadable))
-    rsProgramStoreGetColorMaskA(rs_program_store ps);
+    rsgProgramStoreGetColorMaskA(rs_program_store ps);
 
 /**
  * @hide
@@ -108,7 +85,7 @@
  * @param ps
  */
 extern rs_blend_src_func __attribute__((overloadable))
-        rsProgramStoreGetBlendSrcFunc(rs_program_store ps);
+        rsgProgramStoreGetBlendSrcFunc(rs_program_store ps);
 
 /**
  * @hide
@@ -117,7 +94,7 @@
  * @param ps
  */
 extern rs_blend_dst_func __attribute__((overloadable))
-    rsProgramStoreGetBlendDstFunc(rs_program_store ps);
+    rsgProgramStoreGetBlendDstFunc(rs_program_store ps);
 
 /**
  * @hide
@@ -126,7 +103,7 @@
  * @param ps
  */
 extern bool __attribute__((overloadable))
-    rsProgramStoreGetDitherEnabled(rs_program_store ps);
+    rsgProgramStoreGetDitherEnabled(rs_program_store ps);
 
 /**
  * @hide
@@ -135,7 +112,7 @@
  * @param pr
  */
 extern bool __attribute__((overloadable))
-    rsProgramRasterGetPointSpriteEnabled(rs_program_raster pr);
+    rsgProgramRasterGetPointSpriteEnabled(rs_program_raster pr);
 
 /**
  * @hide
@@ -144,9 +121,9 @@
  * @param pr
  */
 extern rs_cull_mode __attribute__((overloadable))
-    rsProgramRasterGetCullMode(rs_program_raster pr);
+    rsgProgramRasterGetCullMode(rs_program_raster pr);
 
-
+#endif // (defined(RS_VERSION) && (RS_VERSION >= 16))
 
 #endif // __RS_PROGRAM_RSH__
 
diff --git a/libs/rs/scriptc/rs_sampler.rsh b/libs/rs/scriptc/rs_sampler.rsh
index 130eca0..c8948c7 100644
--- a/libs/rs/scriptc/rs_sampler.rsh
+++ b/libs/rs/scriptc/rs_sampler.rsh
@@ -14,31 +14,6 @@
  * limitations under the License.
  */
 
-/*! \mainpage notitle
- *
- * Renderscript is a high-performance runtime that provides graphics rendering and
- * compute operations at the native level. Renderscript code is compiled on devices
- * at runtime to allow platform-independence as well.
- * This reference documentation describes the Renderscript runtime APIs, which you
- * can utilize to write Renderscript code in C99. The Renderscript header
- * files are automatically included for you, except for the rs_graphics.rsh header. If
- * you are doing graphics rendering, include the graphics header file like this:
- *
- * <code>#include "rs_graphics.rsh"</code>
- *
- * To use Renderscript, you need to utilize the Renderscript runtime APIs documented here
- * as well as the Android framework APIs for Renderscript.
- * For documentation on the Android framework APIs, see the <a target="_parent" href=
- * "http://developer.android.com/reference/android/renderscript/package-summary.html">
- * android.renderscript</a> package reference.
- * For more information on how to develop with Renderscript and how the runtime and
- * Android framework APIs interact, see the <a target="_parent" href=
- * "http://developer.android.com/guide/topics/renderscript/index.html">Renderscript
- * developer guide</a> and the <a target="_parent" href=
- * "http://developer.android.com/resources/samples/RenderScript/index.html">
- * Renderscript samples</a>.
- */
-
 /** @file rs_sampler.rsh
  *  \brief Sampler routines
  *
@@ -48,6 +23,8 @@
 #ifndef __RS_SAMPLER_RSH__
 #define __RS_SAMPLER_RSH__
 
+#if (defined(RS_VERSION) && (RS_VERSION >= 16))
+
 /**
  * @hide
  * Get sampler minification value
@@ -93,5 +70,7 @@
 extern float __attribute__((overloadable))
     rsSamplerGetAnisotropy(rs_sampler s);
 
+#endif // (defined(RS_VERSION) && (RS_VERSION >= 16))
+
 #endif // __RS_SAMPLER_RSH__
 
diff --git a/libs/rs/scriptc/rs_types.rsh b/libs/rs/scriptc/rs_types.rsh
index f8c2657..10617d8 100644
--- a/libs/rs/scriptc/rs_types.rsh
+++ b/libs/rs/scriptc/rs_types.rsh
@@ -402,6 +402,8 @@
 
 #endif //defined(RS_VERSION) && (RS_VERSION >= 14)
 
+#if (defined(RS_VERSION) && (RS_VERSION >= 16))
+
 /**
  * Describes the way mesh vertex data is interpreted when rendering
  *
@@ -552,4 +554,6 @@
     RS_SAMPLER_INVALID              = 100,
 } rs_sampler_value;
 
-#endif
+#endif // (defined(RS_VERSION) && (RS_VERSION >= 16))
+
+#endif // __RS_TYPES_RSH__
diff --git a/media/jni/mediaeditor/Android.mk b/media/jni/mediaeditor/Android.mk
index 688e180..d1cf8b5 100755
--- a/media/jni/mediaeditor/Android.mk
+++ b/media/jni/mediaeditor/Android.mk
@@ -38,12 +38,12 @@
     $(call include-path-for, corecg graphics) \
     $(TOP)/frameworks/native/include/media/editor \
     $(TOP)/frameworks/base/core/jni/mediaeditor \
-    $(TOP)/frameworks/media/libvideoeditor/vss/inc \
-    $(TOP)/frameworks/media/libvideoeditor/vss/common/inc \
-    $(TOP)/frameworks/media/libvideoeditor/vss/mcs/inc \
-    $(TOP)/frameworks/media/libvideoeditor/vss/stagefrightshells/inc \
-    $(TOP)/frameworks/media/libvideoeditor/lvpp \
-    $(TOP)/frameworks/media/libvideoeditor/osal/inc \
+    $(TOP)/frameworks/av/libvideoeditor/vss/inc \
+    $(TOP)/frameworks/av/libvideoeditor/vss/common/inc \
+    $(TOP)/frameworks/av/libvideoeditor/vss/mcs/inc \
+    $(TOP)/frameworks/av/libvideoeditor/vss/stagefrightshells/inc \
+    $(TOP)/frameworks/av/libvideoeditor/lvpp \
+    $(TOP)/frameworks/av/libvideoeditor/osal/inc \
     $(TOP)/frameworks/native/include/media/openmax
 
 LOCAL_SHARED_LIBRARIES := \
diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp
index 663f285..9385b8a 100644
--- a/media/libstagefright/MPEG4Extractor.cpp
+++ b/media/libstagefright/MPEG4Extractor.cpp
@@ -373,7 +373,8 @@
 
     if (mInitCheck == OK) {
         if (mHasVideo) {
-            mFileMetaData->setCString(kKeyMIMEType, "video/mp4");
+            mFileMetaData->setCString(
+                    kKeyMIMEType, MEDIA_MIMETYPE_CONTAINER_MPEG4);
         } else {
             mFileMetaData->setCString(kKeyMIMEType, "audio/mp4");
         }
diff --git a/media/libstagefright/MediaDefs.cpp b/media/libstagefright/MediaDefs.cpp
index 2549de6..2740d6b 100644
--- a/media/libstagefright/MediaDefs.cpp
+++ b/media/libstagefright/MediaDefs.cpp
@@ -41,7 +41,7 @@
 const char *MEDIA_MIMETYPE_AUDIO_FLAC = "audio/flac";
 const char *MEDIA_MIMETYPE_AUDIO_AAC_ADTS = "audio/aac-adts";
 
-const char *MEDIA_MIMETYPE_CONTAINER_MPEG4 = "video/mpeg4";
+const char *MEDIA_MIMETYPE_CONTAINER_MPEG4 = "video/mp4";
 const char *MEDIA_MIMETYPE_CONTAINER_WAV = "audio/wav";
 const char *MEDIA_MIMETYPE_CONTAINER_OGG = "application/ogg";
 const char *MEDIA_MIMETYPE_CONTAINER_MATROSKA = "video/x-matroska";
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
index 330a189..abf713b 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
@@ -84,6 +84,7 @@
     public DatabaseHelper(Context context) {
         super(context, DATABASE_NAME, null, DATABASE_VERSION);
         mContext = context;
+        setWriteAheadLoggingEnabled(true);
     }
 
     public static boolean isValidTable(String name) {
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index 95fd62d..1fa3695 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -260,7 +260,6 @@
         // Watch for external modifications to the database file,
         // keeping our cache in sync.
         SQLiteDatabase db = mOpenHelper.getWritableDatabase();
-        db.enableWriteAheadLogging();
         sObserverInstance = new SettingsFileObserver(db.getPath());
         sObserverInstance.startWatching();
         startAsyncCachePopulation();
diff --git a/services/java/com/android/server/BackupManagerService.java b/services/java/com/android/server/BackupManagerService.java
index a7b08f5..bd12270 100644
--- a/services/java/com/android/server/BackupManagerService.java
+++ b/services/java/com/android/server/BackupManagerService.java
@@ -1986,6 +1986,16 @@
             try {
                 mCurrentPackage = mPackageManager.getPackageInfo(request.packageName,
                         PackageManager.GET_SIGNATURES);
+                if (mCurrentPackage.applicationInfo.backupAgentName == null) {
+                    // The manifest has changed but we had a stale backup request pending.
+                    // This won't happen again because the app won't be requesting further
+                    // backups.
+                    Slog.i(TAG, "Package " + request.packageName
+                            + " no longer supports backup; skipping");
+                    addBackupTrace("skipping - no agent, completion is noop");
+                    executeNextState(BackupState.RUNNING_QUEUE);
+                    return;
+                }
 
                 IBackupAgent agent = null;
                 try {
@@ -2547,6 +2557,8 @@
                 finalizeBackup(out);
             } catch (RemoteException e) {
                 Slog.e(TAG, "App died during full backup");
+            } catch (Exception e) {
+                Slog.e(TAG, "Internal exception during full backup", e);
             } finally {
                 tearDown(pkg);
                 try {
diff --git a/services/java/com/android/server/wm/AppWindowToken.java b/services/java/com/android/server/wm/AppWindowToken.java
index 3043da2..0e110be 100644
--- a/services/java/com/android/server/wm/AppWindowToken.java
+++ b/services/java/com/android/server/wm/AppWindowToken.java
@@ -56,7 +56,8 @@
     // These are used for determining when all windows associated with
     // an activity have been drawn, so they can be made visible together
     // at the same time.
-    int lastTransactionSequence;
+    // initialize so that it doesn't match mTransactionSequence which is an int.
+    long lastTransactionSequence = Long.MIN_VALUE;
     int numInterestingWindows;
     int numDrawnWindows;
     boolean inPendingTransaction;
@@ -113,7 +114,6 @@
         appWindowToken = this;
         appToken = _token;
         mInputApplicationHandle = new InputApplicationHandle(this);
-        lastTransactionSequence = service.mTransactionSequence-1;
     }
 
     public void setAnimation(Animation anim) {
diff --git a/services/java/com/android/server/wm/WindowAnimator.java b/services/java/com/android/server/wm/WindowAnimator.java
new file mode 100644
index 0000000..b3dbee1
--- /dev/null
+++ b/services/java/com/android/server/wm/WindowAnimator.java
@@ -0,0 +1,575 @@
+// Copyright 2012 Google Inc. All Rights Reserved.
+
+package com.android.server.wm;
+
+import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
+
+import android.content.Context;
+import android.os.SystemClock;
+import android.util.Log;
+import android.util.Slog;
+import android.view.Surface;
+import android.view.WindowManager;
+import android.view.WindowManager.LayoutParams;
+import android.view.WindowManagerPolicy;
+import android.view.animation.Animation;
+import android.view.animation.AnimationUtils;
+
+import com.android.internal.policy.impl.PhoneWindowManager;
+
+/**
+ * @author cmautner@google.com (Craig Mautner)
+ * Singleton class that carries out the animations and Surface operations in a separate task
+ * on behalf of WindowManagerService.
+ */
+public class WindowAnimator {
+    private static final String TAG = "WindowAnimations";
+
+    final WindowManagerService mService;
+    final Context mContext;
+    final WindowManagerPolicy mPolicy;
+
+    boolean mAnimating;
+    boolean mUpdateRotation;
+    boolean mTokenMayBeDrawn;
+    boolean mForceHiding;
+    WindowState mWindowAnimationBackground;
+    int mWindowAnimationBackgroundColor;
+    int mAdjResult;
+
+    int mPendingLayoutChanges;
+
+    /** Overall window dimensions */
+    int mDw, mDh;
+
+    /** Interior window dimensions */
+    int mInnerDw, mInnerDh;
+
+    /** Time of current animation step. Reset on each iteration */
+    long mCurrentTime;
+
+    /** Skip repeated AppWindowTokens initialization. Note that AppWindowsToken's version of this
+     * is a long initialized to Long.MIN_VALUE so that it doesn't match this value on startup. */
+    private int mTransactionSequence;
+
+    /** The one and only screen rotation if one is happening */
+    ScreenRotationAnimation mScreenRotationAnimation = null;
+
+    WindowAnimator(final WindowManagerService service, final Context context,
+            final WindowManagerPolicy policy) {
+        mService = service;
+        mContext = context;
+        mPolicy = policy;
+    }
+
+    private void updateWindowsAppsAndRotationAnimationsLocked() {
+        int i;
+        final int NAT = mService.mAppTokens.size();
+        for (i=0; i<NAT; i++) {
+            final AppWindowToken appToken = mService.mAppTokens.get(i);
+            if (appToken.stepAnimationLocked(mCurrentTime, mInnerDw, mInnerDh)) {
+                mAnimating = true;
+            }
+        }
+
+        if (mScreenRotationAnimation != null &&
+                (mScreenRotationAnimation.isAnimating() ||
+                        mScreenRotationAnimation.mFinishAnimReady)) {
+            if (mScreenRotationAnimation.stepAnimationLocked(mCurrentTime)) {
+                mUpdateRotation = false;
+                mAnimating = true;
+            } else {
+                mUpdateRotation = true;
+                mScreenRotationAnimation.kill();
+                mScreenRotationAnimation = null;
+            }
+        }
+    }
+
+    private void updateWindowsAndWallpaperLocked() {
+        ++mTransactionSequence;
+
+        for (int i = mService.mWindows.size() - 1; i >= 0; i--) {
+            WindowState w = mService.mWindows.get(i);
+
+            final WindowManager.LayoutParams attrs = w.mAttrs;
+
+            if (w.mSurface != null) {
+                // Take care of the window being ready to display.
+                if (w.commitFinishDrawingLocked(mCurrentTime)) {
+                    if ((w.mAttrs.flags
+                            & WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER) != 0) {
+                        if (WindowManagerService.DEBUG_WALLPAPER) Slog.v(TAG,
+                                "First draw done in potential wallpaper target " + w);
+                        mService.mInnerFields.mWallpaperMayChange = true;
+                        mPendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
+                    }
+                }
+
+                // If the window has moved due to its containing
+                // content frame changing, then we'd like to animate
+                // it.  The checks here are ordered by what is least
+                // likely to be true first.
+                if (w.shouldAnimateMove()) {
+                    // Frame has moved, containing content frame
+                    // has also moved, and we're not currently animating...
+                    // let's do something.
+                    Animation a = AnimationUtils.loadAnimation(mContext,
+                            com.android.internal.R.anim.window_move_from_decor);
+                    w.setAnimation(a);
+                    w.mAnimDw = w.mLastFrame.left - w.mFrame.left;
+                    w.mAnimDh = w.mLastFrame.top - w.mFrame.top;
+                } else {
+                    w.mAnimDw = mInnerDw;
+                    w.mAnimDh = mInnerDh;
+                }
+
+                final boolean wasAnimating = w.mWasAnimating;
+                final boolean nowAnimating = w.stepAnimationLocked(mCurrentTime);
+
+                if (WindowManagerService.DEBUG_WALLPAPER) {
+                    Slog.v(TAG, w + ": wasAnimating=" + wasAnimating +
+                            ", nowAnimating=" + nowAnimating);
+                }
+
+                // If this window is animating, make a note that we have
+                // an animating window and take care of a request to run
+                // a detached wallpaper animation.
+                if (nowAnimating) {
+                    if (w.mAnimation != null) {
+                        if ((w.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0
+                                && w.mAnimation.getDetachWallpaper()) {
+                            mService.mInnerFields.mDetachedWallpaper = w;
+                        }
+                        if (w.mAnimation.getBackgroundColor() != 0) {
+                            if (mWindowAnimationBackground == null
+                                    || (w.mAnimLayer < mWindowAnimationBackground.mAnimLayer)) {
+                                mWindowAnimationBackground = w;
+                                mWindowAnimationBackgroundColor =
+                                        w.mAnimation.getBackgroundColor();
+                            }
+                        }
+                    }
+                    mAnimating = true;
+                }
+
+                // If this window's app token is running a detached wallpaper
+                // animation, make a note so we can ensure the wallpaper is
+                // displayed behind it.
+                if (w.mAppToken != null && w.mAppToken.animation != null
+                        && w.mAppToken.animating) {
+                    if ((w.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0
+                            && w.mAppToken.animation.getDetachWallpaper()) {
+                        mService.mInnerFields.mDetachedWallpaper = w;
+                    }
+                    if (w.mAppToken.animation.getBackgroundColor() != 0) {
+                        if (mWindowAnimationBackground == null
+                                || (w.mAnimLayer <
+                                        mWindowAnimationBackground.mAnimLayer)) {
+                            mWindowAnimationBackground = w;
+                            mWindowAnimationBackgroundColor =
+                                    w.mAppToken.animation.getBackgroundColor();
+                        }
+                    }
+                }
+
+                if (wasAnimating && !w.mAnimating && mService.mWallpaperTarget == w) {
+                    mService.mInnerFields.mWallpaperMayChange = true;
+                    mPendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
+                }
+
+                if (mPolicy.doesForceHide(w, attrs)) {
+                    if (!wasAnimating && nowAnimating) {
+                        if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(TAG,
+                                "Animation started that could impact force hide: "
+                                + w);
+                        mService.mInnerFields.mWallpaperForceHidingChanged = true;
+                        mPendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
+                        mService.mFocusMayChange = true;
+                    } else if (w.isReadyForDisplay() && w.mAnimation == null) {
+                        mForceHiding = true;
+                    }
+                } else if (mPolicy.canBeForceHidden(w, attrs)) {
+                    boolean changed;
+                    if (mForceHiding) {
+                        changed = w.hideLw(false, false);
+                        if (WindowManagerService.DEBUG_VISIBILITY && changed) Slog.v(TAG,
+                                "Now policy hidden: " + w);
+                    } else {
+                        changed = w.showLw(false, false);
+                        if (WindowManagerService.DEBUG_VISIBILITY && changed) Slog.v(TAG,
+                                "Now policy shown: " + w);
+                        if (changed) {
+                            if (mService.mInnerFields.mWallpaperForceHidingChanged
+                                    && w.isVisibleNow() /*w.isReadyForDisplay()*/) {
+                                // Assume we will need to animate.  If
+                                // we don't (because the wallpaper will
+                                // stay with the lock screen), then we will
+                                // clean up later.
+                                Animation a = mPolicy.createForceHideEnterAnimation();
+                                if (a != null) {
+                                    w.setAnimation(a);
+                                }
+                            }
+                            if (mCurrentFocus == null || mCurrentFocus.mLayer < w.mLayer) {
+                                // We are showing on to of the current
+                                // focus, so re-evaluate focus to make
+                                // sure it is correct.
+                                mService.mFocusMayChange = true;
+                            }
+                        }
+                    }
+                    if (changed && (attrs.flags
+                            & WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER) != 0) {
+                        mService.mInnerFields.mWallpaperMayChange = true;
+                        mPendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
+                    }
+                }
+            }
+
+            final AppWindowToken atoken = w.mAppToken;
+            if (atoken != null && (!atoken.allDrawn || atoken.freezingScreen)) {
+                if (atoken.lastTransactionSequence != mTransactionSequence) {
+                    atoken.lastTransactionSequence = mTransactionSequence;
+                    atoken.numInterestingWindows = atoken.numDrawnWindows = 0;
+                    atoken.startingDisplayed = false;
+                }
+                if ((w.isOnScreen() || w.mAttrs.type
+                        == WindowManager.LayoutParams.TYPE_BASE_APPLICATION)
+                        && !w.mExiting && !w.mDestroying) {
+                    if (WindowManagerService.DEBUG_VISIBILITY ||
+                            WindowManagerService.DEBUG_ORIENTATION) {
+                        Slog.v(TAG, "Eval win " + w + ": isDrawn="
+                                + w.isDrawnLw()
+                                + ", isAnimating=" + w.isAnimating());
+                        if (!w.isDrawnLw()) {
+                            Slog.v(TAG, "Not displayed: s=" + w.mSurface
+                                    + " pv=" + w.mPolicyVisibility
+                                    + " dp=" + w.mDrawPending
+                                    + " cdp=" + w.mCommitDrawPending
+                                    + " ah=" + w.mAttachedHidden
+                                    + " th=" + atoken.hiddenRequested
+                                    + " a=" + w.mAnimating);
+                        }
+                    }
+                    if (w != atoken.startingWindow) {
+                        if (!atoken.freezingScreen || !w.mAppFreezing) {
+                            atoken.numInterestingWindows++;
+                            if (w.isDrawnLw()) {
+                                atoken.numDrawnWindows++;
+                                if (WindowManagerService.DEBUG_VISIBILITY ||
+                                        WindowManagerService.DEBUG_ORIENTATION) Slog.v(TAG,
+                                        "tokenMayBeDrawn: " + atoken
+                                        + " freezingScreen=" + atoken.freezingScreen
+                                        + " mAppFreezing=" + w.mAppFreezing);
+                                mTokenMayBeDrawn = true;
+                            }
+                        }
+                    } else if (w.isDrawnLw()) {
+                        atoken.startingDisplayed = true;
+                    }
+                }
+            } else if (w.mReadyToShow) {
+                w.performShowLocked();
+                mPendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
+            }
+        } // end forall windows
+    }
+
+    private void testTokenMayBeDrawnLocked() {
+        // See if any windows have been drawn, so they (and others
+        // associated with them) can now be shown.
+        final int NT = mService.mAppTokens.size();
+        for (int i=0; i<NT; i++) {
+            AppWindowToken wtoken = mService.mAppTokens.get(i);
+            if (wtoken.freezingScreen) {
+                int numInteresting = wtoken.numInterestingWindows;
+                if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) {
+                    if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(TAG,
+                            "allDrawn: " + wtoken
+                            + " interesting=" + numInteresting
+                            + " drawn=" + wtoken.numDrawnWindows);
+                    wtoken.showAllWindowsLocked();
+                    mService.unsetAppFreezingScreenLocked(wtoken, false, true);
+                    if (WindowManagerService.DEBUG_ORIENTATION) Slog.i(TAG,
+                            "Setting mOrientationChangeComplete=true because wtoken "
+                            + wtoken + " numInteresting=" + numInteresting
+                            + " numDrawn=" + wtoken.numDrawnWindows);
+                    mService.mInnerFields.mOrientationChangeComplete = true;
+                }
+            } else if (!wtoken.allDrawn) {
+                int numInteresting = wtoken.numInterestingWindows;
+                if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) {
+                    if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(TAG,
+                            "allDrawn: " + wtoken
+                            + " interesting=" + numInteresting
+                            + " drawn=" + wtoken.numDrawnWindows);
+                    wtoken.allDrawn = true;
+                    mPendingLayoutChanges |= PhoneWindowManager.FINISH_LAYOUT_REDO_ANIM;
+
+                    // We can now show all of the drawn windows!
+                    if (!mService.mOpeningApps.contains(wtoken)) {
+                        mAnimating |= wtoken.showAllWindowsLocked();
+                    }
+                }
+            }
+        }
+    }
+
+    private void performAnimationsLocked() {
+        if (WindowManagerService.DEBUG_APP_TRANSITIONS) Slog.v(TAG, "*** ANIM STEP: seq="
+                + mTransactionSequence + " mAnimating="
+                + mAnimating);
+
+        mTokenMayBeDrawn = false;
+        mService.mInnerFields.mWallpaperMayChange = false;
+        mForceHiding = false;
+        mService.mInnerFields.mDetachedWallpaper = null;
+        mWindowAnimationBackground = null;
+        mWindowAnimationBackgroundColor = 0;
+
+        updateWindowsAndWallpaperLocked();
+
+        if (mTokenMayBeDrawn) {
+            testTokenMayBeDrawnLocked();
+        }
+
+        if (WindowManagerService.DEBUG_APP_TRANSITIONS) Slog.v(TAG, "*** ANIM STEP: changes=0x"
+                + Integer.toHexString(mPendingLayoutChanges));
+    }
+
+    public void prepareSurfaceLocked(final WindowState w, final boolean recoveringMemory) {
+        if (w.mSurface == null) {
+            if (w.mOrientationChanging) {
+                if (WindowManagerService.DEBUG_ORIENTATION) {
+                    Slog.v(TAG, "Orientation change skips hidden " + w);
+                }
+                w.mOrientationChanging = false;
+            }
+            return;
+        }
+
+        boolean displayed = false;
+
+        w.computeShownFrameLocked();
+
+        int width, height;
+        if ((w.mAttrs.flags & LayoutParams.FLAG_SCALED) != 0) {
+            // for a scaled surface, we just want to use
+            // the requested size.
+            width  = w.mRequestedWidth;
+            height = w.mRequestedHeight;
+        } else {
+            width = w.mCompatFrame.width();
+            height = w.mCompatFrame.height();
+        }
+
+        if (width < 1) {
+            width = 1;
+        }
+        if (height < 1) {
+            height = 1;
+        }
+        final boolean surfaceResized = w.mSurfaceW != width || w.mSurfaceH != height;
+        if (surfaceResized) {
+            w.mSurfaceW = width;
+            w.mSurfaceH = height;
+        }
+
+        if (w.mSurfaceX != w.mShownFrame.left
+                || w.mSurfaceY != w.mShownFrame.top) {
+            try {
+                if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
+                        "POS " + w.mShownFrame.left
+                        + ", " + w.mShownFrame.top, null);
+                w.mSurfaceX = w.mShownFrame.left;
+                w.mSurfaceY = w.mShownFrame.top;
+                w.mSurface.setPosition(w.mShownFrame.left, w.mShownFrame.top);
+            } catch (RuntimeException e) {
+                Slog.w(TAG, "Error positioning surface of " + w
+                        + " pos=(" + w.mShownFrame.left
+                        + "," + w.mShownFrame.top + ")", e);
+                if (!recoveringMemory) {
+                    mService.reclaimSomeSurfaceMemoryLocked(w, "position", true);
+                }
+            }
+        }
+
+        if (surfaceResized) {
+            try {
+                if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
+                        "SIZE " + width + "x" + height, null);
+                w.mSurfaceResized = true;
+                w.mSurface.setSize(width, height);
+            } catch (RuntimeException e) {
+                // If something goes wrong with the surface (such
+                // as running out of memory), don't take down the
+                // entire system.
+                Slog.e(TAG, "Error resizing surface of " + w
+                        + " size=(" + width + "x" + height + ")", e);
+                if (!recoveringMemory) {
+                    mService.reclaimSomeSurfaceMemoryLocked(w, "size", true);
+                }
+            }
+        }
+
+        if (w.mAttachedHidden || !w.isReadyForDisplay()) {
+            if (!w.mLastHidden) {
+                //dump();
+                w.mLastHidden = true;
+                if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
+                        "HIDE (performLayout)", null);
+                if (w.mSurface != null) {
+                    w.mSurfaceShown = false;
+                    try {
+                        w.mSurface.hide();
+                    } catch (RuntimeException e) {
+                        Slog.w(TAG, "Exception hiding surface in " + w);
+                    }
+                }
+            }
+            // If we are waiting for this window to handle an
+            // orientation change, well, it is hidden, so
+            // doesn't really matter.  Note that this does
+            // introduce a potential glitch if the window
+            // becomes unhidden before it has drawn for the
+            // new orientation.
+            if (w.mOrientationChanging) {
+                w.mOrientationChanging = false;
+                if (WindowManagerService.DEBUG_ORIENTATION) Slog.v(TAG,
+                        "Orientation change skips hidden " + w);
+            }
+        } else if (w.mLastLayer != w.mAnimLayer
+                || w.mLastAlpha != w.mShownAlpha
+                || w.mLastDsDx != w.mDsDx
+                || w.mLastDtDx != w.mDtDx
+                || w.mLastDsDy != w.mDsDy
+                || w.mLastDtDy != w.mDtDy
+                || w.mLastHScale != w.mHScale
+                || w.mLastVScale != w.mVScale
+                || w.mLastHidden) {
+            displayed = true;
+            w.mLastAlpha = w.mShownAlpha;
+            w.mLastLayer = w.mAnimLayer;
+            w.mLastDsDx = w.mDsDx;
+            w.mLastDtDx = w.mDtDx;
+            w.mLastDsDy = w.mDsDy;
+            w.mLastDtDy = w.mDtDy;
+            w.mLastHScale = w.mHScale;
+            w.mLastVScale = w.mVScale;
+            if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
+                    "alpha=" + w.mShownAlpha + " layer=" + w.mAnimLayer
+                    + " matrix=[" + (w.mDsDx*w.mHScale)
+                    + "," + (w.mDtDx*w.mVScale)
+                    + "][" + (w.mDsDy*w.mHScale)
+                    + "," + (w.mDtDy*w.mVScale) + "]", null);
+            if (w.mSurface != null) {
+                try {
+                    w.mSurfaceAlpha = w.mShownAlpha;
+                    w.mSurface.setAlpha(w.mShownAlpha);
+                    w.mSurfaceLayer = w.mAnimLayer;
+                    w.mSurface.setLayer(w.mAnimLayer);
+                    w.mSurface.setMatrix(
+                            w.mDsDx*w.mHScale, w.mDtDx*w.mVScale,
+                            w.mDsDy*w.mHScale, w.mDtDy*w.mVScale);
+                } catch (RuntimeException e) {
+                    Slog.w(TAG, "Error updating surface in " + w, e);
+                    if (!recoveringMemory) {
+                        mService.reclaimSomeSurfaceMemoryLocked(w, "update", true);
+                    }
+                }
+            }
+
+            if (w.mLastHidden && w.isDrawnLw()
+                    && !w.mReadyToShow) {
+                if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
+                        "SHOW (performLayout)", null);
+                if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(TAG, "Showing " + w
+                        + " during relayout");
+                if (mService.showSurfaceRobustlyLocked(w)) {
+                    w.mHasDrawn = true;
+                    w.mLastHidden = false;
+                } else {
+                    w.mOrientationChanging = false;
+                }
+            }
+            if (w.mSurface != null) {
+                w.mToken.hasVisible = true;
+            }
+        } else {
+            displayed = true;
+        }
+
+        if (displayed) {
+            if (w.mOrientationChanging) {
+                if (!w.isDrawnLw()) {
+                    mService.mInnerFields.mOrientationChangeComplete = false;
+                    if (WindowManagerService.DEBUG_ORIENTATION) Slog.v(TAG,
+                            "Orientation continue waiting for draw in " + w);
+                } else {
+                    w.mOrientationChanging = false;
+                    if (WindowManagerService.DEBUG_ORIENTATION) Slog.v(TAG,
+                            "Orientation change complete in " + w);
+                }
+            }
+            w.mToken.hasVisible = true;
+        }
+    }
+
+    void animate() {
+        mCurrentTime = SystemClock.uptimeMillis();
+
+        // Update animations of all applications, including those
+        // associated with exiting/removed apps
+        Surface.openTransaction();
+
+        try {
+            updateWindowsAppsAndRotationAnimationsLocked();
+            performAnimationsLocked();
+
+            // THIRD LOOP: Update the surfaces of all windows.
+
+            if (mScreenRotationAnimation != null) {
+                mScreenRotationAnimation.updateSurfaces();
+            }
+
+            final int N = mService.mWindows.size();
+            for (int i=N-1; i>=0; i--) {
+                WindowState w = mService.mWindows.get(i);
+                prepareSurfaceLocked(w, true);
+            }
+
+            if (mService.mDimAnimator != null && mService.mDimAnimator.mDimShown) {
+                mAnimating |= mService.mDimAnimator.updateSurface(mService.mInnerFields.mDimming,
+                            mCurrentTime, !mService.okToDisplay());
+            }
+
+            if (mService.mBlackFrame != null) {
+                if (mScreenRotationAnimation != null) {
+                    mService.mBlackFrame.setMatrix(
+                            mScreenRotationAnimation.getEnterTransformation().getMatrix());
+                } else {
+                    mService.mBlackFrame.clearMatrix();
+                }
+            }
+        } catch (RuntimeException e) {
+            Log.wtf(TAG, "Unhandled exception in Window Manager", e);
+        } finally {
+            Surface.closeTransaction();
+        }
+    }
+
+    WindowState mCurrentFocus;
+    void setCurrentFocus(WindowState currentFocus) {
+        mCurrentFocus = currentFocus;
+    }
+
+    void setDisplayDimensions(final int curWidth, final int curHeight,
+                        final int appWidth, final int appHeight) {
+        mDw = curWidth;
+        mDh = curHeight;
+        mInnerDw = appWidth;
+        mInnerDh = appHeight;
+    }
+
+}
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 31a2788..26367d2 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -408,15 +408,12 @@
     IInputMethodManager mInputMethodManager;
 
     SurfaceSession mFxSession;
-    private DimAnimator mDimAnimator = null;
+    DimAnimator mDimAnimator = null;
     Watermark mWatermark;
     StrictModeFlash mStrictModeFlash;
-    ScreenRotationAnimation mScreenRotationAnimation;
 
     BlackFrame mBlackFrame;
 
-    int mTransactionSequence = 0;
-
     final float[] mTmpFloats = new float[9];
 
     boolean mSafeMode;
@@ -575,26 +572,21 @@
 
     /** Pulled out of performLayoutAndPlaceSurfacesLockedInner in order to refactor into multiple
      * methods. */
-    private class LayoutAndSurfaceFields {
-        private boolean mAnimating = false;
-        private boolean mWallpaperForceHidingChanged = false;
-        private boolean mTokenMayBeDrawn = false;
-        private boolean mWallpaperMayChange = false;
-        private boolean mForceHiding = false;
-        private WindowState mDetachedWallpaper = null;
-        private WindowState mWindowAnimationBackground = null;
-        private int mWindowAnimationBackgroundColor = 0;
-        private boolean mOrientationChangeComplete = true;
+    class LayoutAndSurfaceFields {
+        boolean mWallpaperForceHidingChanged = false;
+        boolean mWallpaperMayChange = false;
+        WindowState mDetachedWallpaper = null;
+        boolean mOrientationChangeComplete = true;
         private int mAdjResult = 0;
         private Session mHoldScreen = null;
         private boolean mObscured = false;
-        private boolean mDimming = false;
+        boolean mDimming = false;
         private boolean mSyswin = false;
         private float mScreenBrightness = -1;
         private float mButtonBrightness = -1;
         private boolean mUpdateRotation = false;
     }
-    private LayoutAndSurfaceFields mInnerFields = new LayoutAndSurfaceFields();
+    LayoutAndSurfaceFields mInnerFields = new LayoutAndSurfaceFields();
 
     private final class AnimationRunnable implements Runnable {
         @Override
@@ -607,6 +599,8 @@
     }
     final AnimationRunnable mAnimationRunnable = new AnimationRunnable();
     boolean mAnimationScheduled;
+    
+    final WindowAnimator mAnimator;
 
     final class DragInputEventReceiver extends InputEventReceiver {
         public DragInputEventReceiver(InputChannel inputChannel, Looper looper) {
@@ -828,6 +822,7 @@
         mHoldingScreenWakeLock.setReferenceCounted(false);
 
         mInputManager = new InputManager(context, this);
+        mAnimator = new WindowAnimator(this, context, mPolicy);
 
         PolicyThread thr = new PolicyThread(mPolicy, this, context, pm);
         thr.start();
@@ -2209,7 +2204,7 @@
             if (mInTouchMode) {
                 res |= WindowManagerImpl.ADD_FLAG_IN_TOUCH_MODE;
             }
-            if (win == null || win.mAppToken == null || !win.mAppToken.clientHidden) {
+            if (win.mAppToken == null || !win.mAppToken.clientHidden) {
                 res |= WindowManagerImpl.ADD_FLAG_APP_VISIBLE;
             }
 
@@ -2276,7 +2271,7 @@
             + ", surface=" + win.mSurface);
 
         final long origId = Binder.clearCallingIdentity();
-        
+
         win.disposeInputChannel();
 
         if (DEBUG_APP_TRANSITIONS) Slog.v(
@@ -2297,7 +2292,8 @@
         if (win.mSurface != null && okToDisplay()) {
             // If we are not currently running the exit animation, we
             // need to see about starting one.
-            if (wasVisible=win.isWinVisibleLw()) {
+            wasVisible = win.isWinVisibleLw();
+            if (wasVisible) {
 
                 int transit = WindowManagerPolicy.TRANSIT_EXIT;
                 if (win.getAttrs().type == TYPE_APPLICATION_STARTING) {
@@ -5382,7 +5378,8 @@
             return false;
         }
 
-        if (mScreenRotationAnimation != null && mScreenRotationAnimation.isAnimating()) {
+        if (mAnimator.mScreenRotationAnimation != null &&
+                mAnimator.mScreenRotationAnimation.isAnimating()) {
             // Rotation updates cannot be performed while the previous rotation change
             // animation is still in progress.  Skip this update.  We will try updating
             // again after the animation is finished and the display is unfrozen.
@@ -5452,9 +5449,9 @@
         try {
             // NOTE: We disable the rotation in the emulator because
             //       it doesn't support hardware OpenGL emulation yet.
-            if (CUSTOM_SCREEN_ROTATION && mScreenRotationAnimation != null
-                    && mScreenRotationAnimation.hasScreenshot()) {
-                if (mScreenRotationAnimation.setRotation(rotation, mFxSession,
+            if (CUSTOM_SCREEN_ROTATION && mAnimator.mScreenRotationAnimation != null
+                    && mAnimator.mScreenRotationAnimation.hasScreenshot()) {
+                if (mAnimator.mScreenRotationAnimation.setRotation(rotation, mFxSession,
                         MAX_ANIMATION_DURATION, mTransitionAnimationScale,
                         mCurDisplayWidth, mCurDisplayHeight)) {
                     scheduleAnimationLocked();
@@ -6156,6 +6153,8 @@
         synchronized(mDisplaySizeLock) {
             mAppDisplayWidth = appWidth;
             mAppDisplayHeight = appHeight;
+            mAnimator.setDisplayDimensions(mCurDisplayWidth, mCurDisplayHeight,
+                    mAppDisplayWidth, mAppDisplayHeight);
         }
         if (false) {
             Slog.i(TAG, "Set app display size: " + mAppDisplayWidth
@@ -6542,6 +6541,8 @@
                 }
                 mBaseDisplayWidth = mCurDisplayWidth = mAppDisplayWidth = mInitialDisplayWidth;
                 mBaseDisplayHeight = mCurDisplayHeight = mAppDisplayHeight = mInitialDisplayHeight;
+                mAnimator.setDisplayDimensions(mCurDisplayWidth, mCurDisplayHeight,
+                        mAppDisplayWidth, mAppDisplayHeight);
             }
             mInputManager.setDisplaySize(Display.DEFAULT_DISPLAY,
                     mDisplay.getRawWidth(), mDisplay.getRawHeight(),
@@ -7622,342 +7623,6 @@
 
     /**
      * Extracted from {@link #performLayoutAndPlaceSurfacesLockedInner} to reduce size of method.
-     * Update animations of all applications, including those associated with exiting/removed apps.
-     *
-     * @param currentTime The time which animations use for calculating transitions.
-     * @param innerDw Width of app window.
-     * @param innerDh Height of app window.
-     */
-    private void updateWindowsAppsAndRotationAnimationsLocked(long currentTime,
-                                                          int innerDw, int innerDh) {
-        int i;
-        final int NAT = mAppTokens.size();
-        for (i=0; i<NAT; i++) {
-            final AppWindowToken appToken = mAppTokens.get(i);
-            if (appToken.stepAnimationLocked(currentTime, innerDw, innerDh)) {
-                mInnerFields.mAnimating = true;
-            }
-        }
-        final int NEAT = mExitingAppTokens.size();
-        for (i=0; i<NEAT; i++) {
-            final AppWindowToken appToken = mExitingAppTokens.get(i);
-            if (appToken.stepAnimationLocked(currentTime, innerDw, innerDh)) {
-                mInnerFields.mAnimating = true;
-            }
-        }
-
-        if (mScreenRotationAnimation != null &&
-                (mScreenRotationAnimation.isAnimating() ||
-                        mScreenRotationAnimation.mFinishAnimReady)) {
-            if (mScreenRotationAnimation.stepAnimationLocked(currentTime)) {
-                mInnerFields.mUpdateRotation = false;
-                mInnerFields.mAnimating = true;
-            } else {
-                mInnerFields.mUpdateRotation = true;
-                mScreenRotationAnimation.kill();
-                mScreenRotationAnimation = null;
-            }
-        }
-    }
-
-    private void animateAndUpdateSurfaces(final long currentTime, final int dw, final int dh,
-                                          final int innerDw, final int innerDh, 
-                                          final boolean recoveringMemory) {
-        // Update animations of all applications, including those
-        // associated with exiting/removed apps
-        Surface.openTransaction();
-
-        try {
-            updateWindowsAppsAndRotationAnimationsLocked(currentTime, innerDw, innerDh);
-            mPendingLayoutChanges = performAnimationsLocked(currentTime, dw, dh,
-                    innerDw, innerDh);
-        
-            // THIRD LOOP: Update the surfaces of all windows.
-            
-            if (mScreenRotationAnimation != null) {
-                mScreenRotationAnimation.updateSurfaces();
-            }
-        
-            final int N = mWindows.size();
-            for (int i=N-1; i>=0; i--) {
-                WindowState w = mWindows.get(i);
-                prepareSurfaceLocked(w, recoveringMemory);
-            }
-        
-            if (mDimAnimator != null && mDimAnimator.mDimShown) {
-                mInnerFields.mAnimating |=
-                        mDimAnimator.updateSurface(mInnerFields.mDimming, currentTime,
-                            !okToDisplay());
-            }
-        
-            if (mBlackFrame != null) {
-                if (mScreenRotationAnimation != null) {
-                    mBlackFrame.setMatrix(
-                            mScreenRotationAnimation.getEnterTransformation().getMatrix());
-                } else {
-                    mBlackFrame.clearMatrix();
-                }
-            }
-        } catch (RuntimeException e) {
-            Log.wtf(TAG, "Unhandled exception in Window Manager", e);
-        } finally {
-            Surface.closeTransaction();
-        }
-    }
-    
-    /**
-     * Extracted from {@link #performLayoutAndPlaceSurfacesLockedInner} to reduce size of method.
-     *
-     * @param currentTime The time which animations use for calculating transitions.
-     * @param dw Width of app window.
-     * @param dh Height of app window.
-     * @param innerDw Width of app window.
-     * @param innerDh Height of app window.
-     */
-    private int updateWindowsAndWallpaperLocked(final long currentTime, final int dw, final int dh,
-                                                final int innerDw, final int innerDh) {
-        ++mTransactionSequence;
-
-        int changes = 0;
-        for (int i = mWindows.size() - 1; i >= 0; i--) {
-            WindowState w = mWindows.get(i);
-
-            final WindowManager.LayoutParams attrs = w.mAttrs;
-
-            if (w.mSurface != null) {
-                // Take care of the window being ready to display.
-                if (w.commitFinishDrawingLocked(currentTime)) {
-                    if ((w.mAttrs.flags
-                            & WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER) != 0) {
-                        if (DEBUG_WALLPAPER) Slog.v(TAG,
-                                "First draw done in potential wallpaper target " + w);
-                        mInnerFields.mWallpaperMayChange = true;
-                        changes |= WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
-                    }
-                }
-
-                // If the window has moved due to its containing
-                // content frame changing, then we'd like to animate
-                // it.  The checks here are ordered by what is least
-                // likely to be true first.
-                if (w.shouldAnimateMove()) {
-                    // Frame has moved, containing content frame
-                    // has also moved, and we're not currently animating...
-                    // let's do something.
-                    Animation a = AnimationUtils.loadAnimation(mContext,
-                            com.android.internal.R.anim.window_move_from_decor);
-                    w.setAnimation(a);
-                    w.mAnimDw = w.mLastFrame.left - w.mFrame.left;
-                    w.mAnimDh = w.mLastFrame.top - w.mFrame.top;
-                } else {
-                    w.mAnimDw = innerDw;
-                    w.mAnimDh = innerDh;
-                }
-
-                final boolean wasAnimating = w.mWasAnimating;
-                final boolean nowAnimating = w.stepAnimationLocked(currentTime);
-
-                if (DEBUG_WALLPAPER) {
-                    Slog.v(TAG, w + ": wasAnimating=" + wasAnimating +
-                            ", nowAnimating=" + nowAnimating);
-                }
-
-                // If this window is animating, make a note that we have
-                // an animating window and take care of a request to run
-                // a detached wallpaper animation.
-                if (nowAnimating) {
-                    if (w.mAnimation != null) {
-                        if ((w.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0
-                                && w.mAnimation.getDetachWallpaper()) {
-                            mInnerFields.mDetachedWallpaper = w;
-                        }
-                        if (w.mAnimation.getBackgroundColor() != 0) {
-                            if (mInnerFields.mWindowAnimationBackground == null
-                                    || (w.mAnimLayer <
-                                            mInnerFields.mWindowAnimationBackground.mAnimLayer)) {
-                                mInnerFields.mWindowAnimationBackground = w;
-                                mInnerFields.mWindowAnimationBackgroundColor =
-                                        w.mAnimation.getBackgroundColor();
-                            }
-                        }
-                    }
-                    mInnerFields.mAnimating = true;
-                }
-
-                // If this window's app token is running a detached wallpaper
-                // animation, make a note so we can ensure the wallpaper is
-                // displayed behind it.
-                if (w.mAppToken != null && w.mAppToken.animation != null
-                        && w.mAppToken.animating) {
-                    if ((w.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0
-                            && w.mAppToken.animation.getDetachWallpaper()) {
-                        mInnerFields.mDetachedWallpaper = w;
-                    }
-                    if (w.mAppToken.animation.getBackgroundColor() != 0) {
-                        if (mInnerFields.mWindowAnimationBackground == null
-                                || (w.mAnimLayer <
-                                        mInnerFields.mWindowAnimationBackground.mAnimLayer)) {
-                            mInnerFields.mWindowAnimationBackground = w;
-                            mInnerFields.mWindowAnimationBackgroundColor =
-                                    w.mAppToken.animation.getBackgroundColor();
-                        }
-                    }
-                }
-
-                if (wasAnimating && !w.mAnimating && mWallpaperTarget == w) {
-                    mInnerFields.mWallpaperMayChange = true;
-                    changes |= WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
-                }
-
-                if (mPolicy.doesForceHide(w, attrs)) {
-                    if (!wasAnimating && nowAnimating) {
-                        if (DEBUG_VISIBILITY) Slog.v(TAG,
-                                "Animation started that could impact force hide: "
-                                + w);
-                        mInnerFields.mWallpaperForceHidingChanged = true;
-                        changes |= WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
-                        mFocusMayChange = true;
-                    } else if (w.isReadyForDisplay() && w.mAnimation == null) {
-                        mInnerFields.mForceHiding = true;
-                    }
-                } else if (mPolicy.canBeForceHidden(w, attrs)) {
-                    boolean changed;
-                    if (mInnerFields.mForceHiding) {
-                        changed = w.hideLw(false, false);
-                        if (DEBUG_VISIBILITY && changed) Slog.v(TAG,
-                                "Now policy hidden: " + w);
-                    } else {
-                        changed = w.showLw(false, false);
-                        if (DEBUG_VISIBILITY && changed) Slog.v(TAG,
-                                "Now policy shown: " + w);
-                        if (changed) {
-                            if (mInnerFields.mWallpaperForceHidingChanged
-                                    && w.isVisibleNow() /*w.isReadyForDisplay()*/) {
-                                // Assume we will need to animate.  If
-                                // we don't (because the wallpaper will
-                                // stay with the lock screen), then we will
-                                // clean up later.
-                                Animation a = mPolicy.createForceHideEnterAnimation();
-                                if (a != null) {
-                                    w.setAnimation(a);
-                                }
-                            }
-                            if (mCurrentFocus == null ||
-                                    mCurrentFocus.mLayer < w.mLayer) {
-                                // We are showing on to of the current
-                                // focus, so re-evaluate focus to make
-                                // sure it is correct.
-                                mFocusMayChange = true;
-                            }
-                        }
-                    }
-                    if (changed && (attrs.flags
-                            & WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER) != 0) {
-                        mInnerFields.mWallpaperMayChange = true;
-                        changes |= WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
-                    }
-                }
-            }
-
-            final AppWindowToken atoken = w.mAppToken;
-            if (atoken != null && (!atoken.allDrawn || atoken.freezingScreen)) {
-                if (atoken.lastTransactionSequence != mTransactionSequence) {
-                    atoken.lastTransactionSequence = mTransactionSequence;
-                    atoken.numInterestingWindows = atoken.numDrawnWindows = 0;
-                    atoken.startingDisplayed = false;
-                }
-                if ((w.isOnScreen() || w.mAttrs.type
-                        == WindowManager.LayoutParams.TYPE_BASE_APPLICATION)
-                        && !w.mExiting && !w.mDestroying) {
-                    if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) {
-                        Slog.v(TAG, "Eval win " + w + ": isDrawn="
-                                + w.isDrawnLw()
-                                + ", isAnimating=" + w.isAnimating());
-                        if (!w.isDrawnLw()) {
-                            Slog.v(TAG, "Not displayed: s=" + w.mSurface
-                                    + " pv=" + w.mPolicyVisibility
-                                    + " dp=" + w.mDrawPending
-                                    + " cdp=" + w.mCommitDrawPending
-                                    + " ah=" + w.mAttachedHidden
-                                    + " th=" + atoken.hiddenRequested
-                                    + " a=" + w.mAnimating);
-                        }
-                    }
-                    if (w != atoken.startingWindow) {
-                        if (!atoken.freezingScreen || !w.mAppFreezing) {
-                            atoken.numInterestingWindows++;
-                            if (w.isDrawnLw()) {
-                                atoken.numDrawnWindows++;
-                                if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) Slog.v(TAG,
-                                        "tokenMayBeDrawn: " + atoken
-                                        + " freezingScreen=" + atoken.freezingScreen
-                                        + " mAppFreezing=" + w.mAppFreezing);
-                                mInnerFields.mTokenMayBeDrawn = true;
-                            }
-                        }
-                    } else if (w.isDrawnLw()) {
-                        atoken.startingDisplayed = true;
-                    }
-                }
-            } else if (w.mReadyToShow) {
-                w.performShowLocked();
-                changes |= WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
-            }
-        } // end forall windows
-
-        return changes;
-    }
-
-    /**
-     * Extracted from {@link #performLayoutAndPlaceSurfacesLockedInner} to reduce size of method.
-     *
-     * @return bitmap indicating if another pass through layout must be made.
-     */
-    private int testTokenMayBeDrawnLocked() {
-        int changes = 0;
-        // See if any windows have been drawn, so they (and others
-        // associated with them) can now be shown.
-        final int NT = mAppTokens.size();
-        for (int i=0; i<NT; i++) {
-            AppWindowToken wtoken = mAppTokens.get(i);
-            if (wtoken.freezingScreen) {
-                int numInteresting = wtoken.numInterestingWindows;
-                if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) {
-                    if (DEBUG_VISIBILITY) Slog.v(TAG,
-                            "allDrawn: " + wtoken
-                            + " interesting=" + numInteresting
-                            + " drawn=" + wtoken.numDrawnWindows);
-                    wtoken.showAllWindowsLocked();
-                    unsetAppFreezingScreenLocked(wtoken, false, true);
-                    if (DEBUG_ORIENTATION) Slog.i(TAG,
-                            "Setting mOrientationChangeComplete=true because wtoken "
-                            + wtoken + " numInteresting=" + numInteresting
-                            + " numDrawn=" + wtoken.numDrawnWindows);
-                    mInnerFields.mOrientationChangeComplete = true;
-                }
-            } else if (!wtoken.allDrawn) {
-                int numInteresting = wtoken.numInterestingWindows;
-                if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) {
-                    if (DEBUG_VISIBILITY) Slog.v(TAG,
-                            "allDrawn: " + wtoken
-                            + " interesting=" + numInteresting
-                            + " drawn=" + wtoken.numDrawnWindows);
-                    wtoken.allDrawn = true;
-                    changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_ANIM;
-
-                    // We can now show all of the drawn windows!
-                    if (!mOpeningApps.contains(wtoken)) {
-                        mInnerFields.mAnimating |= wtoken.showAllWindowsLocked();
-                    }
-                }
-            }
-        }
-
-        return changes;
-    }
-
-    /**
-     * Extracted from {@link #performLayoutAndPlaceSurfacesLockedInner} to reduce size of method.
      *
      * @return bitmap indicating if another pass through layout must be made.
      */
@@ -8131,7 +7796,7 @@
                         transit, false);
                 wtoken.updateReportedVisibilityLocked();
                 wtoken.waitingToShow = false;
-                mInnerFields.mAnimating |= wtoken.showAllWindowsLocked();
+                mAnimator.mAnimating |= wtoken.showAllWindowsLocked();
             }
             NN = mClosingApps.size();
             for (i=0; i<NN; i++) {
@@ -8229,14 +7894,14 @@
         if (mLowerWallpaperTarget == null) {
             // Whoops, we don't need a special wallpaper animation.
             // Clear them out.
-            mInnerFields.mForceHiding = false;
+            mAnimator.mForceHiding = false;
             for (int i=mWindows.size()-1; i>=0; i--) {
                 WindowState w = mWindows.get(i);
                 if (w.mSurface != null) {
                     final WindowManager.LayoutParams attrs = w.mAttrs;
                     if (mPolicy.doesForceHide(w, attrs) && w.isVisibleLw()) {
                         if (DEBUG_FOCUS) Slog.i(TAG, "win=" + w + " force hides other windows");
-                        mInnerFields.mForceHiding = true;
+                        mAnimator.mForceHiding = true;
                     } else if (mPolicy.canBeForceHidden(w, attrs)) {
                         if (!w.mAnimating) {
                             // We set the animation above so it
@@ -8267,11 +7932,11 @@
             mInnerFields.mWallpaperMayChange = true;
         }
 
-        if (mInnerFields.mWindowAnimationBackgroundColor != 0) {
+        if (mAnimator.mWindowAnimationBackgroundColor != 0) {
             // If the window that wants black is the current wallpaper
             // target, then the black goes *below* the wallpaper so we
             // don't cause the wallpaper to suddenly disappear.
-            WindowState target = mInnerFields.mWindowAnimationBackground;
+            WindowState target = mAnimator.mWindowAnimationBackground;
             if (mWallpaperTarget == target
                     || mLowerWallpaperTarget == target
                     || mUpperWallpaperTarget == target) {
@@ -8290,7 +7955,7 @@
             final int dh = mCurDisplayHeight;
             mWindowAnimationBackgroundSurface.show(dw, dh,
                     target.mAnimLayer - LAYER_OFFSET_DIM,
-                    mInnerFields.mWindowAnimationBackgroundColor);
+                    mAnimator.mWindowAnimationBackgroundColor);
         } else if (mWindowAnimationBackgroundSurface != null) {
             mWindowAnimationBackgroundSurface.hide();
         }
@@ -8393,206 +8058,6 @@
     /**
      * Extracted from {@link #performLayoutAndPlaceSurfacesLockedInner} to reduce size of method.
      *
-     * @param w WindowState whos Surface is being prepared.
-     * @param recoveringMemory true if the caller will reclaim surface memory on error.
-     */
-    public void prepareSurfaceLocked(final WindowState w, final boolean recoveringMemory) {
-        // XXX NOTE: The logic here could be improved.  We have
-        // the decision about whether to resize a window separated
-        // from whether to hide the surface.  This can cause us to
-        // resize a surface even if we are going to hide it.  You
-        // can see this by (1) holding device in landscape mode on
-        // home screen; (2) tapping browser icon (device will rotate
-        // to landscape; (3) tap home.  The wallpaper will be resized
-        // in step 2 but then immediately hidden, causing us to
-        // have to resize and then redraw it again in step 3.  It
-        // would be nice to figure out how to avoid this, but it is
-        // difficult because we do need to resize surfaces in some
-        // cases while they are hidden such as when first showing a
-        // window.
-        
-        if (w.mSurface == null) {
-            if (w.mOrientationChanging) {
-                if (DEBUG_ORIENTATION) {
-                    Slog.v(TAG, "Orientation change skips hidden " + w);
-                }
-                w.mOrientationChanging = false;
-            }
-            return;
-        }
-        
-        boolean displayed = false;
-
-        w.computeShownFrameLocked();
-
-        int width, height;
-        if ((w.mAttrs.flags & w.mAttrs.FLAG_SCALED) != 0) {
-            // for a scaled surface, we just want to use
-            // the requested size.
-            width  = w.mRequestedWidth;
-            height = w.mRequestedHeight;
-        } else {
-            width = w.mCompatFrame.width();
-            height = w.mCompatFrame.height();
-        }
-
-        if (width < 1) {
-            width = 1;
-        }
-        if (height < 1) {
-            height = 1;
-        }
-        final boolean surfaceResized = w.mSurfaceW != width || w.mSurfaceH != height;
-        if (surfaceResized) {
-            w.mSurfaceW = width;
-            w.mSurfaceH = height;
-        }
-
-        if (w.mSurfaceX != w.mShownFrame.left
-                || w.mSurfaceY != w.mShownFrame.top) {
-            try {
-                if (SHOW_TRANSACTIONS) logSurface(w,
-                        "POS " + w.mShownFrame.left
-                        + ", " + w.mShownFrame.top, null);
-                w.mSurfaceX = w.mShownFrame.left;
-                w.mSurfaceY = w.mShownFrame.top;
-                w.mSurface.setPosition(w.mShownFrame.left, w.mShownFrame.top);
-            } catch (RuntimeException e) {
-                Slog.w(TAG, "Error positioning surface of " + w
-                        + " pos=(" + w.mShownFrame.left
-                        + "," + w.mShownFrame.top + ")", e);
-                if (!recoveringMemory) {
-                    reclaimSomeSurfaceMemoryLocked(w, "position", true);
-                }
-            }
-        }
-
-        if (surfaceResized) {
-            try {
-                if (SHOW_TRANSACTIONS) logSurface(w,
-                        "SIZE " + width + "x" + height, null);
-                w.mSurfaceResized = true;
-                w.mSurface.setSize(width, height);
-            } catch (RuntimeException e) {
-                // If something goes wrong with the surface (such
-                // as running out of memory), don't take down the
-                // entire system.
-                Slog.e(TAG, "Error resizing surface of " + w
-                        + " size=(" + width + "x" + height + ")", e);
-                if (!recoveringMemory) {
-                    reclaimSomeSurfaceMemoryLocked(w, "size", true);
-                }
-            }
-        }
-
-        updateResizingWindows(w);
-
-        if (w.mAttachedHidden || !w.isReadyForDisplay()) {
-            if (!w.mLastHidden) {
-                //dump();
-                w.mLastHidden = true;
-                if (SHOW_TRANSACTIONS) logSurface(w,
-                        "HIDE (performLayout)", null);
-                if (w.mSurface != null) {
-                    w.mSurfaceShown = false;
-                    try {
-                        w.mSurface.hide();
-                    } catch (RuntimeException e) {
-                        Slog.w(TAG, "Exception hiding surface in " + w);
-                    }
-                }
-            }
-            // If we are waiting for this window to handle an
-            // orientation change, well, it is hidden, so
-            // doesn't really matter.  Note that this does
-            // introduce a potential glitch if the window
-            // becomes unhidden before it has drawn for the
-            // new orientation.
-            if (w.mOrientationChanging) {
-                w.mOrientationChanging = false;
-                if (DEBUG_ORIENTATION) Slog.v(TAG,
-                        "Orientation change skips hidden " + w);
-            }
-        } else if (w.mLastLayer != w.mAnimLayer
-                || w.mLastAlpha != w.mShownAlpha
-                || w.mLastDsDx != w.mDsDx
-                || w.mLastDtDx != w.mDtDx
-                || w.mLastDsDy != w.mDsDy
-                || w.mLastDtDy != w.mDtDy
-                || w.mLastHScale != w.mHScale
-                || w.mLastVScale != w.mVScale
-                || w.mLastHidden) {
-            displayed = true;
-            w.mLastAlpha = w.mShownAlpha;
-            w.mLastLayer = w.mAnimLayer;
-            w.mLastDsDx = w.mDsDx;
-            w.mLastDtDx = w.mDtDx;
-            w.mLastDsDy = w.mDsDy;
-            w.mLastDtDy = w.mDtDy;
-            w.mLastHScale = w.mHScale;
-            w.mLastVScale = w.mVScale;
-            if (SHOW_TRANSACTIONS) logSurface(w,
-                    "alpha=" + w.mShownAlpha + " layer=" + w.mAnimLayer
-                    + " matrix=[" + (w.mDsDx*w.mHScale)
-                    + "," + (w.mDtDx*w.mVScale)
-                    + "][" + (w.mDsDy*w.mHScale)
-                    + "," + (w.mDtDy*w.mVScale) + "]", null);
-            if (w.mSurface != null) {
-                try {
-                    w.mSurfaceAlpha = w.mShownAlpha;
-                    w.mSurface.setAlpha(w.mShownAlpha);
-                    w.mSurfaceLayer = w.mAnimLayer;
-                    w.mSurface.setLayer(w.mAnimLayer);
-                    w.mSurface.setMatrix(
-                            w.mDsDx*w.mHScale, w.mDtDx*w.mVScale,
-                            w.mDsDy*w.mHScale, w.mDtDy*w.mVScale);
-                } catch (RuntimeException e) {
-                    Slog.w(TAG, "Error updating surface in " + w, e);
-                    if (!recoveringMemory) {
-                        reclaimSomeSurfaceMemoryLocked(w, "update", true);
-                    }
-                }
-            }
-
-            if (w.mLastHidden && w.isDrawnLw()
-                    && !w.mReadyToShow) {
-                if (SHOW_TRANSACTIONS) logSurface(w,
-                        "SHOW (performLayout)", null);
-                if (DEBUG_VISIBILITY) Slog.v(TAG, "Showing " + w
-                        + " during relayout");
-                if (showSurfaceRobustlyLocked(w)) {
-                    w.mHasDrawn = true;
-                    w.mLastHidden = false;
-                } else {
-                    w.mOrientationChanging = false;
-                }
-            }
-            if (w.mSurface != null) {
-                w.mToken.hasVisible = true;
-            }
-        } else {
-            displayed = true;
-        }
-
-        if (displayed) {
-            if (w.mOrientationChanging) {
-                if (!w.isDrawnLw()) {
-                    mInnerFields.mOrientationChangeComplete = false;
-                    if (DEBUG_ORIENTATION) Slog.v(TAG,
-                            "Orientation continue waiting for draw in " + w);
-                } else {
-                    w.mOrientationChanging = false;
-                    if (DEBUG_ORIENTATION) Slog.v(TAG,
-                            "Orientation change complete in " + w);
-                }
-            }
-            w.mToken.hasVisible = true;
-        }
-    }
-
-    /**
-     * Extracted from {@link #performLayoutAndPlaceSurfacesLockedInner} to reduce size of method.
-     *
      * @param w WindowState this method is applied to.
      * @param currentTime The time which animations use for calculating transitions.
      * @param innerDw Width of app window.
@@ -8649,65 +8114,6 @@
         }
     }
 
-    private final int performAnimationsLocked(long currentTime, int dw, int dh,
-            int innerDw, int innerDh) {
-        if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "*** ANIM STEP: seq="
-                + mTransactionSequence + " mAnimating="
-                + mInnerFields.mAnimating);
-
-        mInnerFields.mTokenMayBeDrawn = false;
-        mInnerFields.mWallpaperMayChange = false;
-        mInnerFields.mForceHiding = false;
-        mInnerFields.mDetachedWallpaper = null;
-        mInnerFields.mWindowAnimationBackground = null;
-        mInnerFields.mWindowAnimationBackgroundColor = 0;
-
-        int changes = updateWindowsAndWallpaperLocked(currentTime, dw, dh, innerDw, innerDh);
-
-        if (mInnerFields.mTokenMayBeDrawn) {
-            changes |= testTokenMayBeDrawnLocked();
-        }
-
-        // If we are ready to perform an app transition, check through
-        // all of the app tokens to be shown and see if they are ready
-        // to go.
-        if (mAppTransitionReady) {
-            changes |= handleAppTransitionReadyLocked();
-        }
-
-        mInnerFields.mAdjResult = 0;
-
-        if (!mInnerFields.mAnimating && mAppTransitionRunning) {
-            // We have finished the animation of an app transition.  To do
-            // this, we have delayed a lot of operations like showing and
-            // hiding apps, moving apps in Z-order, etc.  The app token list
-            // reflects the correct Z-order, but the window list may now
-            // be out of sync with it.  So here we will just rebuild the
-            // entire app window list.  Fun!
-            changes |= handleAnimatingStoppedAndTransitionLocked();
-        }
-
-        if (mInnerFields.mWallpaperForceHidingChanged && changes == 0 && !mAppTransitionReady) {
-            // At this point, there was a window with a wallpaper that
-            // was force hiding other windows behind it, but now it
-            // is going away.  This may be simple -- just animate
-            // away the wallpaper and its window -- or it may be
-            // hard -- the wallpaper now needs to be shown behind
-            // something that was hidden.
-            changes |= animateAwayWallpaperLocked();
-        }
-
-        changes |= testWallpaperAndBackgroundLocked();
-
-        if (mLayoutNeeded) {
-            changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
-        }
-
-        if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "*** ANIM STEP: changes=0x"
-                + Integer.toHexString(changes));
-        return changes;
-    }
-
     // "Something has changed!  Let's make it correct now."
     private final void performLayoutAndPlaceSurfacesLockedInner(
             boolean recoveringMemory) {
@@ -8745,7 +8151,7 @@
         mInnerFields.mScreenBrightness = -1;
         mInnerFields.mButtonBrightness = -1;
         boolean focusDisplayed = false;
-        mInnerFields.mAnimating = false;
+        mAnimator.mAnimating = false;
         boolean createWatermark = false;
 
         if (mFxSession == null) {
@@ -8855,9 +8261,53 @@
             Surface.closeTransaction();
         }
 
+        // If we are ready to perform an app transition, check through
+        // all of the app tokens to be shown and see if they are ready
+        // to go.
+        if (mAppTransitionReady) {
+            mPendingLayoutChanges |= handleAppTransitionReadyLocked();
+        }
+
+        mInnerFields.mAdjResult = 0;
+
+        if (!mAnimator.mAnimating && mAppTransitionRunning) {
+            // We have finished the animation of an app transition.  To do
+            // this, we have delayed a lot of operations like showing and
+            // hiding apps, moving apps in Z-order, etc.  The app token list
+            // reflects the correct Z-order, but the window list may now
+            // be out of sync with it.  So here we will just rebuild the
+            // entire app window list.  Fun!
+            mPendingLayoutChanges |= handleAnimatingStoppedAndTransitionLocked();
+        }
+
+        if (mInnerFields.mWallpaperForceHidingChanged && mPendingLayoutChanges == 0 &&
+                !mAppTransitionReady) {
+            // At this point, there was a window with a wallpaper that
+            // was force hiding other windows behind it, but now it
+            // is going away.  This may be simple -- just animate
+            // away the wallpaper and its window -- or it may be
+            // hard -- the wallpaper now needs to be shown behind
+            // something that was hidden.
+            mPendingLayoutChanges |= animateAwayWallpaperLocked();
+        }
+
+        mPendingLayoutChanges |= testWallpaperAndBackgroundLocked();
+
+        if (mLayoutNeeded) {
+            mPendingLayoutChanges |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
+        }
+
+        final int N = mWindows.size();
+        for (i=N-1; i>=0; i--) {
+            WindowState w = mWindows.get(i);
+            // TODO(cmautner): Can this move up to the loop at the end of try/catch above?
+            updateResizingWindows(w);
+        }
+
         // Update animations of all applications, including those
         // associated with exiting/removed apps
-        animateAndUpdateSurfaces(currentTime, dw, dh, innerDw, innerDh, recoveringMemory);
+        mAnimator.animate();
+        mPendingLayoutChanges |= mAnimator.mPendingLayoutChanges;
 
         if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
                 "<<< CLOSE TRANSACTION performLayoutAndPlaceSurfaces");
@@ -8961,7 +8411,7 @@
 
         boolean needRelayout = false;
 
-        if (!mInnerFields.mAnimating && mAppTransitionRunning) {
+        if (!mAnimator.mAnimating && mAppTransitionRunning) {
             // We have finished the animation of an app transition.  To do
             // this, we have delayed a lot of operations like showing and
             // hiding apps, moving apps in Z-order, etc.  The app token list
@@ -8991,7 +8441,7 @@
         }
         if (needRelayout) {
             requestTraversalLocked();
-        } else if (mInnerFields.mAnimating) {
+        } else if (mAnimator.mAnimating) {
             scheduleAnimationLocked();
         }
 
@@ -9257,6 +8707,7 @@
                 TAG, "Changing focus from " + mCurrentFocus + " to " + newFocus);
             final WindowState oldFocus = mCurrentFocus;
             mCurrentFocus = newFocus;
+            mAnimator.setCurrentFocus(mCurrentFocus);
             mLosingFocus.remove(newFocus);
             int focusChanged = mPolicy.focusChangedLw(oldFocus, newFocus);
 
@@ -9397,16 +8848,16 @@
         }
 
         if (CUSTOM_SCREEN_ROTATION) {
-            if (mScreenRotationAnimation != null) {
-                mScreenRotationAnimation.kill();
-                mScreenRotationAnimation = null;
+            if (mAnimator.mScreenRotationAnimation != null) {
+                mAnimator.mScreenRotationAnimation.kill();
+                mAnimator.mScreenRotationAnimation = null;
             }
-            if (mScreenRotationAnimation == null) {
-                mScreenRotationAnimation = new ScreenRotationAnimation(mContext,
+            if (mAnimator.mScreenRotationAnimation == null) {
+                mAnimator.mScreenRotationAnimation = new ScreenRotationAnimation(mContext,
                         mFxSession, inTransaction, mCurDisplayWidth, mCurDisplayHeight,
                         mDisplay.getRotation());
             }
-            if (!mScreenRotationAnimation.hasScreenshot()) {
+            if (!mAnimator.mScreenRotationAnimation.hasScreenshot()) {
                 Surface.freezeDisplay(0);
             }
         } else {
@@ -9431,20 +8882,20 @@
 
         boolean updateRotation = false;
         
-        if (CUSTOM_SCREEN_ROTATION && mScreenRotationAnimation != null
-                && mScreenRotationAnimation.hasScreenshot()) {
+        if (CUSTOM_SCREEN_ROTATION && mAnimator.mScreenRotationAnimation != null
+                && mAnimator.mScreenRotationAnimation.hasScreenshot()) {
             if (DEBUG_ORIENTATION) Slog.i(TAG, "**** Dismissing screen rotation animation");
-            if (mScreenRotationAnimation.dismiss(mFxSession, MAX_ANIMATION_DURATION,
+            if (mAnimator.mScreenRotationAnimation.dismiss(mFxSession, MAX_ANIMATION_DURATION,
                     mTransitionAnimationScale, mCurDisplayWidth, mCurDisplayHeight)) {
                 scheduleAnimationLocked();
             } else {
-                mScreenRotationAnimation = null;
+                mAnimator.mScreenRotationAnimation = null;
                 updateRotation = true;
             }
         } else {
-            if (mScreenRotationAnimation != null) {
-                mScreenRotationAnimation.kill();
-                mScreenRotationAnimation = null;
+            if (mAnimator.mScreenRotationAnimation != null) {
+                mAnimator.mScreenRotationAnimation.kill();
+                mAnimator.mScreenRotationAnimation = null;
             }
             updateRotation = true;
         }
@@ -9927,9 +9378,9 @@
             pw.print("  mLastWindowForcedOrientation"); pw.print(mLastWindowForcedOrientation);
                     pw.print(" mForcedAppOrientation="); pw.println(mForcedAppOrientation);
             pw.print("  mDeferredRotationPauseCount="); pw.println(mDeferredRotationPauseCount);
-            if (mScreenRotationAnimation != null) {
+            if (mAnimator.mScreenRotationAnimation != null) {
                 pw.println("  mScreenRotationAnimation:");
-                mScreenRotationAnimation.printTo("    ", pw);
+                mAnimator.mScreenRotationAnimation.printTo("    ", pw);
             }
             pw.print("  mWindowAnimationScale="); pw.print(mWindowAnimationScale);
                     pw.print(" mTransitionWindowAnimationScale="); pw.print(mTransitionAnimationScale);
diff --git a/services/java/com/android/server/wm/WindowState.java b/services/java/com/android/server/wm/WindowState.java
index d1a14df3..cf61f7f 100644
--- a/services/java/com/android/server/wm/WindowState.java
+++ b/services/java/com/android/server/wm/WindowState.java
@@ -1227,8 +1227,8 @@
             }
         }
 
-        final boolean screenAnimation = mService.mScreenRotationAnimation != null
-                && mService.mScreenRotationAnimation.isAnimating();
+        final boolean screenAnimation = mService.mAnimator.mScreenRotationAnimation != null
+                && mService.mAnimator.mScreenRotationAnimation.isAnimating();
         if (selfTransformation || attachedTransformation != null
                 || appTransformation != null || screenAnimation) {
             // cache often used attributes locally
@@ -1268,7 +1268,7 @@
             }
             if (screenAnimation) {
                 tmpMatrix.postConcat(
-                        mService.mScreenRotationAnimation.getEnterTransformation().getMatrix());
+                        mService.mAnimator.mScreenRotationAnimation.getEnterTransformation().getMatrix());
             }
 
             // "convert" it into SurfaceFlinger's format
@@ -1311,7 +1311,7 @@
                 }
                 if (screenAnimation) {
                     mShownAlpha *=
-                        mService.mScreenRotationAnimation.getEnterTransformation().getAlpha();
+                        mService.mAnimator.mScreenRotationAnimation.getEnterTransformation().getAlpha();
                 }
             } else {
                 //Slog.i(TAG, "Not applying alpha transform");
diff --git a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
index a243e4d..88ee867 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
@@ -53,6 +53,7 @@
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.Signature;
+import android.content.pm.UserInfo;
 import android.net.ConnectivityManager;
 import android.net.IConnectivityManager;
 import android.net.INetworkManagementEventObserver;
@@ -69,6 +70,7 @@
 import android.os.INetworkManagementService;
 import android.os.IPowerManager;
 import android.os.MessageQueue.IdleHandler;
+import android.os.UserId;
 import android.test.AndroidTestCase;
 import android.test.mock.MockPackageManager;
 import android.test.suitebuilder.annotation.LargeTest;
@@ -84,7 +86,9 @@
 import org.easymock.IAnswer;
 
 import java.io.File;
+import java.util.ArrayList;
 import java.util.LinkedHashSet;
+import java.util.List;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Future;
 import java.util.concurrent.TimeUnit;
@@ -126,8 +130,16 @@
     private long mStartTime;
     private long mElapsedRealtime;
 
-    private static final int UID_A = android.os.Process.FIRST_APPLICATION_UID + 800;
-    private static final int UID_B = android.os.Process.FIRST_APPLICATION_UID + 801;
+    private static final int USER_ID = 0;
+    private static final int USER_ID_GUEST = 1;
+
+    private static final int APP_ID_A = android.os.Process.FIRST_APPLICATION_UID + 800;
+    private static final int APP_ID_B = android.os.Process.FIRST_APPLICATION_UID + 801;
+
+    private static final int UID_A = UserId.getUid(USER_ID, APP_ID_A);
+    private static final int UID_B = UserId.getUid(USER_ID, APP_ID_B);
+    private static final int UID_A_GUEST = UserId.getUid(USER_ID_GUEST, APP_ID_A);
+    private static final int UID_B_GUEST = UserId.getUid(USER_ID_GUEST, APP_ID_B);
 
     private static final int PID_1 = 400;
     private static final int PID_2 = 401;
@@ -161,6 +173,14 @@
                         info.signatures = new Signature[] { signature };
                         return info;
                     }
+
+                    @Override
+                    public List<UserInfo> getUsers() {
+                        final ArrayList<UserInfo> users = new ArrayList<UserInfo>();
+                        users.add(new UserInfo(USER_ID, "Primary", UserInfo.FLAG_PRIMARY));
+                        users.add(new UserInfo(USER_ID_GUEST, "Guest", 0));
+                        return users;
+                    }
                 };
             }
 
@@ -242,13 +262,13 @@
 
     @Suppress
     public void testPolicyChangeTriggersBroadcast() throws Exception {
-        mService.setAppPolicy(UID_A, POLICY_NONE);
+        mService.setAppPolicy(APP_ID_A, POLICY_NONE);
 
         // change background policy and expect broadcast
         final Future<Intent> backgroundChanged = mServiceContext.nextBroadcastIntent(
                 ConnectivityManager.ACTION_BACKGROUND_DATA_SETTING_CHANGED);
 
-        mService.setAppPolicy(UID_A, POLICY_REJECT_METERED_BACKGROUND);
+        mService.setAppPolicy(APP_ID_A, POLICY_REJECT_METERED_BACKGROUND);
 
         backgroundChanged.get();
     }
@@ -302,6 +322,7 @@
 
     public void testScreenChangesRules() throws Exception {
         Future<Void> future;
+        Future<Void> futureGuest;
 
         expectSetUidNetworkRules(UID_A, false);
         expectSetUidForeground(UID_A, true);
@@ -314,10 +335,14 @@
         // push strict policy for foreground uid, verify ALLOW rule
         expectSetUidNetworkRules(UID_A, false);
         expectSetUidForeground(UID_A, true);
+        expectSetUidNetworkRules(UID_A_GUEST, true);
+        expectSetUidForeground(UID_A_GUEST, false);
         future = expectRulesChanged(UID_A, RULE_ALLOW_ALL);
+        futureGuest = expectRulesChanged(UID_A_GUEST, RULE_REJECT_METERED);
         replay();
-        mService.setAppPolicy(UID_A, POLICY_REJECT_METERED_BACKGROUND);
+        mService.setAppPolicy(APP_ID_A, POLICY_REJECT_METERED_BACKGROUND);
         future.get();
+        futureGuest.get();
         verifyAndReset();
 
         // now turn screen off and verify REJECT rule
@@ -343,6 +368,7 @@
 
     public void testPolicyNone() throws Exception {
         Future<Void> future;
+        Future<Void> futureGuest;
 
         expectSetUidNetworkRules(UID_A, false);
         expectSetUidForeground(UID_A, true);
@@ -355,10 +381,14 @@
         // POLICY_NONE should RULE_ALLOW in foreground
         expectSetUidNetworkRules(UID_A, false);
         expectSetUidForeground(UID_A, true);
+        expectSetUidNetworkRules(UID_A_GUEST, false);
+        expectSetUidForeground(UID_A_GUEST, false);
         future = expectRulesChanged(UID_A, RULE_ALLOW_ALL);
+        futureGuest = expectRulesChanged(UID_A_GUEST, RULE_ALLOW_ALL);
         replay();
-        mService.setAppPolicy(UID_A, POLICY_NONE);
+        mService.setAppPolicy(APP_ID_A, POLICY_NONE);
         future.get();
+        futureGuest.get();
         verifyAndReset();
 
         // POLICY_NONE should RULE_ALLOW in background
@@ -373,14 +403,19 @@
 
     public void testPolicyReject() throws Exception {
         Future<Void> future;
+        Future<Void> futureGuest;
 
         // POLICY_REJECT should RULE_ALLOW in background
         expectSetUidNetworkRules(UID_A, true);
         expectSetUidForeground(UID_A, false);
+        expectSetUidNetworkRules(UID_A_GUEST, true);
+        expectSetUidForeground(UID_A_GUEST, false);
         future = expectRulesChanged(UID_A, RULE_REJECT_METERED);
+        futureGuest = expectRulesChanged(UID_A_GUEST, RULE_REJECT_METERED);
         replay();
-        mService.setAppPolicy(UID_A, POLICY_REJECT_METERED_BACKGROUND);
+        mService.setAppPolicy(APP_ID_A, POLICY_REJECT_METERED_BACKGROUND);
         future.get();
+        futureGuest.get();
         verifyAndReset();
 
         // POLICY_REJECT should RULE_ALLOW in foreground
@@ -404,33 +439,46 @@
 
     public void testPolicyRejectAddRemove() throws Exception {
         Future<Void> future;
+        Future<Void> futureGuest;
 
         // POLICY_NONE should have RULE_ALLOW in background
         expectSetUidNetworkRules(UID_A, false);
         expectSetUidForeground(UID_A, false);
+        expectSetUidNetworkRules(UID_A_GUEST, false);
+        expectSetUidForeground(UID_A_GUEST, false);
         future = expectRulesChanged(UID_A, RULE_ALLOW_ALL);
+        futureGuest = expectRulesChanged(UID_A_GUEST, RULE_ALLOW_ALL);
         replay();
         mProcessObserver.onForegroundActivitiesChanged(PID_1, UID_A, false);
-        mService.setAppPolicy(UID_A, POLICY_NONE);
+        mService.setAppPolicy(APP_ID_A, POLICY_NONE);
         future.get();
+        futureGuest.get();
         verifyAndReset();
 
         // adding POLICY_REJECT should cause RULE_REJECT
         expectSetUidNetworkRules(UID_A, true);
         expectSetUidForeground(UID_A, false);
+        expectSetUidNetworkRules(UID_A_GUEST, true);
+        expectSetUidForeground(UID_A_GUEST, false);
         future = expectRulesChanged(UID_A, RULE_REJECT_METERED);
+        futureGuest = expectRulesChanged(UID_A_GUEST, RULE_REJECT_METERED);
         replay();
-        mService.setAppPolicy(UID_A, POLICY_REJECT_METERED_BACKGROUND);
+        mService.setAppPolicy(APP_ID_A, POLICY_REJECT_METERED_BACKGROUND);
         future.get();
+        futureGuest.get();
         verifyAndReset();
 
         // removing POLICY_REJECT should return us to RULE_ALLOW
         expectSetUidNetworkRules(UID_A, false);
         expectSetUidForeground(UID_A, false);
+        expectSetUidNetworkRules(UID_A_GUEST, false);
+        expectSetUidForeground(UID_A_GUEST, false);
         future = expectRulesChanged(UID_A, RULE_ALLOW_ALL);
+        futureGuest = expectRulesChanged(UID_A_GUEST, RULE_ALLOW_ALL);
         replay();
-        mService.setAppPolicy(UID_A, POLICY_NONE);
+        mService.setAppPolicy(APP_ID_A, POLICY_NONE);
         future.get();
+        futureGuest.get();
         verifyAndReset();
     }
 
@@ -599,25 +647,34 @@
 
     public void testUidRemovedPolicyCleared() throws Exception {
         Future<Void> future;
+        Future<Void> futureGuest;
 
         // POLICY_REJECT should RULE_REJECT in background
         expectSetUidNetworkRules(UID_A, true);
         expectSetUidForeground(UID_A, false);
+        expectSetUidNetworkRules(UID_A_GUEST, true);
+        expectSetUidForeground(UID_A_GUEST, false);
         future = expectRulesChanged(UID_A, RULE_REJECT_METERED);
+        futureGuest = expectRulesChanged(UID_A_GUEST, RULE_REJECT_METERED);
         replay();
-        mService.setAppPolicy(UID_A, POLICY_REJECT_METERED_BACKGROUND);
+        mService.setAppPolicy(APP_ID_A, POLICY_REJECT_METERED_BACKGROUND);
         future.get();
+        futureGuest.get();
         verifyAndReset();
 
         // uninstall should clear RULE_REJECT
         expectSetUidNetworkRules(UID_A, false);
         expectSetUidForeground(UID_A, false);
+        expectSetUidNetworkRules(UID_A_GUEST, false);
+        expectSetUidForeground(UID_A_GUEST, false);
         future = expectRulesChanged(UID_A, RULE_ALLOW_ALL);
+        futureGuest = expectRulesChanged(UID_A_GUEST, RULE_ALLOW_ALL);
         replay();
         final Intent intent = new Intent(ACTION_UID_REMOVED);
         intent.putExtra(EXTRA_UID, UID_A);
         mServiceContext.sendBroadcast(intent);
         future.get();
+        futureGuest.get();
         verifyAndReset();
     }
 
diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/mesh.rs b/tests/RenderScriptTests/tests/src/com/android/rs/test/mesh.rs
index 627ab99..1354897 100644
--- a/tests/RenderScriptTests/tests/src/com/android/rs/test/mesh.rs
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/mesh.rs
@@ -11,29 +11,29 @@
 static bool test_mesh_getters() {
     bool failed = false;
 
-    _RS_ASSERT(rsMeshGetVertexAllocationCount(mesh) == 2);
-    _RS_ASSERT(rsMeshGetPrimitiveCount(mesh) == 3);
+    _RS_ASSERT(rsgMeshGetVertexAllocationCount(mesh) == 2);
+    _RS_ASSERT(rsgMeshGetPrimitiveCount(mesh) == 3);
 
-    rs_allocation meshV0 = rsMeshGetVertexAllocation(mesh, 0);
-    rs_allocation meshV1 = rsMeshGetVertexAllocation(mesh, 1);
-    rs_allocation meshV2 = rsMeshGetVertexAllocation(mesh, 2);
+    rs_allocation meshV0 = rsgMeshGetVertexAllocation(mesh, 0);
+    rs_allocation meshV1 = rsgMeshGetVertexAllocation(mesh, 1);
+    rs_allocation meshV2 = rsgMeshGetVertexAllocation(mesh, 2);
     _RS_ASSERT(meshV0.p == vertexAlloc0.p);
     _RS_ASSERT(meshV1.p == vertexAlloc1.p);
     _RS_ASSERT(!rsIsObject(meshV2));
 
-    rs_allocation meshI0 = rsMeshGetIndexAllocation(mesh, 0);
-    rs_allocation meshI1 = rsMeshGetIndexAllocation(mesh, 1);
-    rs_allocation meshI2 = rsMeshGetIndexAllocation(mesh, 2);
-    rs_allocation meshI3 = rsMeshGetIndexAllocation(mesh, 3);
+    rs_allocation meshI0 = rsgMeshGetIndexAllocation(mesh, 0);
+    rs_allocation meshI1 = rsgMeshGetIndexAllocation(mesh, 1);
+    rs_allocation meshI2 = rsgMeshGetIndexAllocation(mesh, 2);
+    rs_allocation meshI3 = rsgMeshGetIndexAllocation(mesh, 3);
     _RS_ASSERT(meshI0.p == indexAlloc0.p);
     _RS_ASSERT(!rsIsObject(meshI1));
     _RS_ASSERT(meshI2.p == indexAlloc2.p);
     _RS_ASSERT(!rsIsObject(meshI3));
 
-    rs_primitive p0 = rsMeshGetPrimitive(mesh, 0);
-    rs_primitive p1 = rsMeshGetPrimitive(mesh, 1);
-    rs_primitive p2 = rsMeshGetPrimitive(mesh, 2);
-    rs_primitive p3 = rsMeshGetPrimitive(mesh, 3);
+    rs_primitive p0 = rsgMeshGetPrimitive(mesh, 0);
+    rs_primitive p1 = rsgMeshGetPrimitive(mesh, 1);
+    rs_primitive p2 = rsgMeshGetPrimitive(mesh, 2);
+    rs_primitive p3 = rsgMeshGetPrimitive(mesh, 3);
 
     _RS_ASSERT(p0 == RS_PRIMITIVE_POINT);
     _RS_ASSERT(p1 == RS_PRIMITIVE_LINE);
diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/program_raster.rs b/tests/RenderScriptTests/tests/src/com/android/rs/test/program_raster.rs
index 0eaca4a..11b8c30 100644
--- a/tests/RenderScriptTests/tests/src/com/android/rs/test/program_raster.rs
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/program_raster.rs
@@ -7,11 +7,11 @@
 static bool test_program_raster_getters() {
     bool failed = false;
 
-    _RS_ASSERT(rsProgramRasterGetPointSpriteEnabled(pointSpriteEnabled) == true);
-    _RS_ASSERT(rsProgramRasterGetCullMode(pointSpriteEnabled) == RS_CULL_BACK);
+    _RS_ASSERT(rsgProgramRasterGetPointSpriteEnabled(pointSpriteEnabled) == true);
+    _RS_ASSERT(rsgProgramRasterGetCullMode(pointSpriteEnabled) == RS_CULL_BACK);
 
-    _RS_ASSERT(rsProgramRasterGetPointSpriteEnabled(cullMode) == false);
-    _RS_ASSERT(rsProgramRasterGetCullMode(cullMode) == RS_CULL_FRONT);
+    _RS_ASSERT(rsgProgramRasterGetPointSpriteEnabled(cullMode) == false);
+    _RS_ASSERT(rsgProgramRasterGetCullMode(cullMode) == RS_CULL_FRONT);
 
     if (failed) {
         rsDebug("test_program_raster_getters FAILED", 0);
diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/program_store.rs b/tests/RenderScriptTests/tests/src/com/android/rs/test/program_store.rs
index 7b47408..3cd8a20 100644
--- a/tests/RenderScriptTests/tests/src/com/android/rs/test/program_store.rs
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/program_store.rs
@@ -14,95 +14,95 @@
 static bool test_program_store_getters() {
     bool failed = false;
 
-    _RS_ASSERT(rsProgramStoreGetDepthFunc(depthFunc) == RS_DEPTH_FUNC_GREATER);
-    _RS_ASSERT(rsProgramStoreGetDepthMask(depthFunc) == false);
-    _RS_ASSERT(rsProgramStoreGetColorMaskR(depthFunc) == false);
-    _RS_ASSERT(rsProgramStoreGetColorMaskG(depthFunc) == false);
-    _RS_ASSERT(rsProgramStoreGetColorMaskB(depthFunc) == false);
-    _RS_ASSERT(rsProgramStoreGetColorMaskA(depthFunc) == false);
-    _RS_ASSERT(rsProgramStoreGetDitherEnabled(depthFunc) == false);
-    _RS_ASSERT(rsProgramStoreGetBlendSrcFunc(depthFunc) == RS_BLEND_SRC_ZERO);
-    _RS_ASSERT(rsProgramStoreGetBlendDstFunc(depthFunc) == RS_BLEND_DST_ZERO);
+    _RS_ASSERT(rsgProgramStoreGetDepthFunc(depthFunc) == RS_DEPTH_FUNC_GREATER);
+    _RS_ASSERT(rsgProgramStoreGetDepthMask(depthFunc) == false);
+    _RS_ASSERT(rsgProgramStoreGetColorMaskR(depthFunc) == false);
+    _RS_ASSERT(rsgProgramStoreGetColorMaskG(depthFunc) == false);
+    _RS_ASSERT(rsgProgramStoreGetColorMaskB(depthFunc) == false);
+    _RS_ASSERT(rsgProgramStoreGetColorMaskA(depthFunc) == false);
+    _RS_ASSERT(rsgProgramStoreGetDitherEnabled(depthFunc) == false);
+    _RS_ASSERT(rsgProgramStoreGetBlendSrcFunc(depthFunc) == RS_BLEND_SRC_ZERO);
+    _RS_ASSERT(rsgProgramStoreGetBlendDstFunc(depthFunc) == RS_BLEND_DST_ZERO);
 
-    _RS_ASSERT(rsProgramStoreGetDepthFunc(depthWriteEnable) == RS_DEPTH_FUNC_ALWAYS);
-    _RS_ASSERT(rsProgramStoreGetDepthMask(depthWriteEnable) == true);
-    _RS_ASSERT(rsProgramStoreGetColorMaskR(depthWriteEnable) == false);
-    _RS_ASSERT(rsProgramStoreGetColorMaskG(depthWriteEnable) == false);
-    _RS_ASSERT(rsProgramStoreGetColorMaskB(depthWriteEnable) == false);
-    _RS_ASSERT(rsProgramStoreGetColorMaskA(depthWriteEnable) == false);
-    _RS_ASSERT(rsProgramStoreGetDitherEnabled(depthWriteEnable) == false);
-    _RS_ASSERT(rsProgramStoreGetBlendSrcFunc(depthWriteEnable) == RS_BLEND_SRC_ZERO);
-    _RS_ASSERT(rsProgramStoreGetBlendDstFunc(depthWriteEnable) == RS_BLEND_DST_ZERO);
+    _RS_ASSERT(rsgProgramStoreGetDepthFunc(depthWriteEnable) == RS_DEPTH_FUNC_ALWAYS);
+    _RS_ASSERT(rsgProgramStoreGetDepthMask(depthWriteEnable) == true);
+    _RS_ASSERT(rsgProgramStoreGetColorMaskR(depthWriteEnable) == false);
+    _RS_ASSERT(rsgProgramStoreGetColorMaskG(depthWriteEnable) == false);
+    _RS_ASSERT(rsgProgramStoreGetColorMaskB(depthWriteEnable) == false);
+    _RS_ASSERT(rsgProgramStoreGetColorMaskA(depthWriteEnable) == false);
+    _RS_ASSERT(rsgProgramStoreGetDitherEnabled(depthWriteEnable) == false);
+    _RS_ASSERT(rsgProgramStoreGetBlendSrcFunc(depthWriteEnable) == RS_BLEND_SRC_ZERO);
+    _RS_ASSERT(rsgProgramStoreGetBlendDstFunc(depthWriteEnable) == RS_BLEND_DST_ZERO);
 
-    _RS_ASSERT(rsProgramStoreGetDepthFunc(colorRWriteEnable) == RS_DEPTH_FUNC_ALWAYS);
-    _RS_ASSERT(rsProgramStoreGetDepthMask(colorRWriteEnable) == false);
-    _RS_ASSERT(rsProgramStoreGetColorMaskR(colorRWriteEnable) == true);
-    _RS_ASSERT(rsProgramStoreGetColorMaskG(colorRWriteEnable) == false);
-    _RS_ASSERT(rsProgramStoreGetColorMaskB(colorRWriteEnable) == false);
-    _RS_ASSERT(rsProgramStoreGetColorMaskA(colorRWriteEnable) == false);
-    _RS_ASSERT(rsProgramStoreGetDitherEnabled(colorRWriteEnable) == false);
-    _RS_ASSERT(rsProgramStoreGetBlendSrcFunc(colorRWriteEnable) == RS_BLEND_SRC_ZERO);
-    _RS_ASSERT(rsProgramStoreGetBlendDstFunc(colorRWriteEnable) == RS_BLEND_DST_ZERO);
+    _RS_ASSERT(rsgProgramStoreGetDepthFunc(colorRWriteEnable) == RS_DEPTH_FUNC_ALWAYS);
+    _RS_ASSERT(rsgProgramStoreGetDepthMask(colorRWriteEnable) == false);
+    _RS_ASSERT(rsgProgramStoreGetColorMaskR(colorRWriteEnable) == true);
+    _RS_ASSERT(rsgProgramStoreGetColorMaskG(colorRWriteEnable) == false);
+    _RS_ASSERT(rsgProgramStoreGetColorMaskB(colorRWriteEnable) == false);
+    _RS_ASSERT(rsgProgramStoreGetColorMaskA(colorRWriteEnable) == false);
+    _RS_ASSERT(rsgProgramStoreGetDitherEnabled(colorRWriteEnable) == false);
+    _RS_ASSERT(rsgProgramStoreGetBlendSrcFunc(colorRWriteEnable) == RS_BLEND_SRC_ZERO);
+    _RS_ASSERT(rsgProgramStoreGetBlendDstFunc(colorRWriteEnable) == RS_BLEND_DST_ZERO);
 
-    _RS_ASSERT(rsProgramStoreGetDepthFunc(colorGWriteEnable) == RS_DEPTH_FUNC_ALWAYS);
-    _RS_ASSERT(rsProgramStoreGetDepthMask(colorGWriteEnable) == false);
-    _RS_ASSERT(rsProgramStoreGetColorMaskR(colorGWriteEnable) == false);
-    _RS_ASSERT(rsProgramStoreGetColorMaskG(colorGWriteEnable) == true);
-    _RS_ASSERT(rsProgramStoreGetColorMaskB(colorGWriteEnable) == false);
-    _RS_ASSERT(rsProgramStoreGetColorMaskA(colorGWriteEnable) == false);
-    _RS_ASSERT(rsProgramStoreGetDitherEnabled(colorGWriteEnable) == false);
-    _RS_ASSERT(rsProgramStoreGetBlendSrcFunc(colorGWriteEnable) == RS_BLEND_SRC_ZERO);
-    _RS_ASSERT(rsProgramStoreGetBlendDstFunc(colorGWriteEnable) == RS_BLEND_DST_ZERO);
+    _RS_ASSERT(rsgProgramStoreGetDepthFunc(colorGWriteEnable) == RS_DEPTH_FUNC_ALWAYS);
+    _RS_ASSERT(rsgProgramStoreGetDepthMask(colorGWriteEnable) == false);
+    _RS_ASSERT(rsgProgramStoreGetColorMaskR(colorGWriteEnable) == false);
+    _RS_ASSERT(rsgProgramStoreGetColorMaskG(colorGWriteEnable) == true);
+    _RS_ASSERT(rsgProgramStoreGetColorMaskB(colorGWriteEnable) == false);
+    _RS_ASSERT(rsgProgramStoreGetColorMaskA(colorGWriteEnable) == false);
+    _RS_ASSERT(rsgProgramStoreGetDitherEnabled(colorGWriteEnable) == false);
+    _RS_ASSERT(rsgProgramStoreGetBlendSrcFunc(colorGWriteEnable) == RS_BLEND_SRC_ZERO);
+    _RS_ASSERT(rsgProgramStoreGetBlendDstFunc(colorGWriteEnable) == RS_BLEND_DST_ZERO);
 
-    _RS_ASSERT(rsProgramStoreGetDepthFunc(colorBWriteEnable) == RS_DEPTH_FUNC_ALWAYS);
-    _RS_ASSERT(rsProgramStoreGetDepthMask(colorBWriteEnable) == false);
-    _RS_ASSERT(rsProgramStoreGetColorMaskR(colorBWriteEnable) == false);
-    _RS_ASSERT(rsProgramStoreGetColorMaskG(colorBWriteEnable) == false);
-    _RS_ASSERT(rsProgramStoreGetColorMaskB(colorBWriteEnable) == true);
-    _RS_ASSERT(rsProgramStoreGetColorMaskA(colorBWriteEnable) == false);
-    _RS_ASSERT(rsProgramStoreGetDitherEnabled(colorBWriteEnable) == false);
-    _RS_ASSERT(rsProgramStoreGetBlendSrcFunc(colorBWriteEnable) == RS_BLEND_SRC_ZERO);
-    _RS_ASSERT(rsProgramStoreGetBlendDstFunc(colorBWriteEnable) == RS_BLEND_DST_ZERO);
+    _RS_ASSERT(rsgProgramStoreGetDepthFunc(colorBWriteEnable) == RS_DEPTH_FUNC_ALWAYS);
+    _RS_ASSERT(rsgProgramStoreGetDepthMask(colorBWriteEnable) == false);
+    _RS_ASSERT(rsgProgramStoreGetColorMaskR(colorBWriteEnable) == false);
+    _RS_ASSERT(rsgProgramStoreGetColorMaskG(colorBWriteEnable) == false);
+    _RS_ASSERT(rsgProgramStoreGetColorMaskB(colorBWriteEnable) == true);
+    _RS_ASSERT(rsgProgramStoreGetColorMaskA(colorBWriteEnable) == false);
+    _RS_ASSERT(rsgProgramStoreGetDitherEnabled(colorBWriteEnable) == false);
+    _RS_ASSERT(rsgProgramStoreGetBlendSrcFunc(colorBWriteEnable) == RS_BLEND_SRC_ZERO);
+    _RS_ASSERT(rsgProgramStoreGetBlendDstFunc(colorBWriteEnable) == RS_BLEND_DST_ZERO);
 
-    _RS_ASSERT(rsProgramStoreGetDepthFunc(colorAWriteEnable) == RS_DEPTH_FUNC_ALWAYS);
-    _RS_ASSERT(rsProgramStoreGetDepthMask(colorAWriteEnable) == false);
-    _RS_ASSERT(rsProgramStoreGetColorMaskR(colorAWriteEnable) == false);
-    _RS_ASSERT(rsProgramStoreGetColorMaskG(colorAWriteEnable) == false);
-    _RS_ASSERT(rsProgramStoreGetColorMaskB(colorAWriteEnable) == false);
-    _RS_ASSERT(rsProgramStoreGetColorMaskA(colorAWriteEnable) == true);
-    _RS_ASSERT(rsProgramStoreGetDitherEnabled(colorAWriteEnable) == false);
-    _RS_ASSERT(rsProgramStoreGetBlendSrcFunc(colorAWriteEnable) == RS_BLEND_SRC_ZERO);
-    _RS_ASSERT(rsProgramStoreGetBlendDstFunc(colorAWriteEnable) == RS_BLEND_DST_ZERO);
+    _RS_ASSERT(rsgProgramStoreGetDepthFunc(colorAWriteEnable) == RS_DEPTH_FUNC_ALWAYS);
+    _RS_ASSERT(rsgProgramStoreGetDepthMask(colorAWriteEnable) == false);
+    _RS_ASSERT(rsgProgramStoreGetColorMaskR(colorAWriteEnable) == false);
+    _RS_ASSERT(rsgProgramStoreGetColorMaskG(colorAWriteEnable) == false);
+    _RS_ASSERT(rsgProgramStoreGetColorMaskB(colorAWriteEnable) == false);
+    _RS_ASSERT(rsgProgramStoreGetColorMaskA(colorAWriteEnable) == true);
+    _RS_ASSERT(rsgProgramStoreGetDitherEnabled(colorAWriteEnable) == false);
+    _RS_ASSERT(rsgProgramStoreGetBlendSrcFunc(colorAWriteEnable) == RS_BLEND_SRC_ZERO);
+    _RS_ASSERT(rsgProgramStoreGetBlendDstFunc(colorAWriteEnable) == RS_BLEND_DST_ZERO);
 
-    _RS_ASSERT(rsProgramStoreGetDepthFunc(ditherEnable) == RS_DEPTH_FUNC_ALWAYS);
-    _RS_ASSERT(rsProgramStoreGetDepthMask(ditherEnable) == false);
-    _RS_ASSERT(rsProgramStoreGetColorMaskR(ditherEnable) == false);
-    _RS_ASSERT(rsProgramStoreGetColorMaskG(ditherEnable) == false);
-    _RS_ASSERT(rsProgramStoreGetColorMaskB(ditherEnable) == false);
-    _RS_ASSERT(rsProgramStoreGetColorMaskA(ditherEnable) == false);
-    _RS_ASSERT(rsProgramStoreGetDitherEnabled(ditherEnable) == true);
-    _RS_ASSERT(rsProgramStoreGetBlendSrcFunc(ditherEnable) == RS_BLEND_SRC_ZERO);
-    _RS_ASSERT(rsProgramStoreGetBlendDstFunc(ditherEnable) == RS_BLEND_DST_ZERO);
+    _RS_ASSERT(rsgProgramStoreGetDepthFunc(ditherEnable) == RS_DEPTH_FUNC_ALWAYS);
+    _RS_ASSERT(rsgProgramStoreGetDepthMask(ditherEnable) == false);
+    _RS_ASSERT(rsgProgramStoreGetColorMaskR(ditherEnable) == false);
+    _RS_ASSERT(rsgProgramStoreGetColorMaskG(ditherEnable) == false);
+    _RS_ASSERT(rsgProgramStoreGetColorMaskB(ditherEnable) == false);
+    _RS_ASSERT(rsgProgramStoreGetColorMaskA(ditherEnable) == false);
+    _RS_ASSERT(rsgProgramStoreGetDitherEnabled(ditherEnable) == true);
+    _RS_ASSERT(rsgProgramStoreGetBlendSrcFunc(ditherEnable) == RS_BLEND_SRC_ZERO);
+    _RS_ASSERT(rsgProgramStoreGetBlendDstFunc(ditherEnable) == RS_BLEND_DST_ZERO);
 
-    _RS_ASSERT(rsProgramStoreGetDepthFunc(blendSrc) == RS_DEPTH_FUNC_ALWAYS);
-    _RS_ASSERT(rsProgramStoreGetDepthMask(blendSrc) == false);
-    _RS_ASSERT(rsProgramStoreGetColorMaskR(blendSrc) == false);
-    _RS_ASSERT(rsProgramStoreGetColorMaskG(blendSrc) == false);
-    _RS_ASSERT(rsProgramStoreGetColorMaskB(blendSrc) == false);
-    _RS_ASSERT(rsProgramStoreGetColorMaskA(blendSrc) == false);
-    _RS_ASSERT(rsProgramStoreGetDitherEnabled(blendSrc) == false);
-    _RS_ASSERT(rsProgramStoreGetBlendSrcFunc(blendSrc) == RS_BLEND_SRC_DST_COLOR);
-    _RS_ASSERT(rsProgramStoreGetBlendDstFunc(blendSrc) == RS_BLEND_DST_ZERO);
+    _RS_ASSERT(rsgProgramStoreGetDepthFunc(blendSrc) == RS_DEPTH_FUNC_ALWAYS);
+    _RS_ASSERT(rsgProgramStoreGetDepthMask(blendSrc) == false);
+    _RS_ASSERT(rsgProgramStoreGetColorMaskR(blendSrc) == false);
+    _RS_ASSERT(rsgProgramStoreGetColorMaskG(blendSrc) == false);
+    _RS_ASSERT(rsgProgramStoreGetColorMaskB(blendSrc) == false);
+    _RS_ASSERT(rsgProgramStoreGetColorMaskA(blendSrc) == false);
+    _RS_ASSERT(rsgProgramStoreGetDitherEnabled(blendSrc) == false);
+    _RS_ASSERT(rsgProgramStoreGetBlendSrcFunc(blendSrc) == RS_BLEND_SRC_DST_COLOR);
+    _RS_ASSERT(rsgProgramStoreGetBlendDstFunc(blendSrc) == RS_BLEND_DST_ZERO);
 
-    _RS_ASSERT(rsProgramStoreGetDepthFunc(blendDst) == RS_DEPTH_FUNC_ALWAYS);
-    _RS_ASSERT(rsProgramStoreGetDepthMask(blendDst) == false);
-    _RS_ASSERT(rsProgramStoreGetColorMaskR(blendDst) == false);
-    _RS_ASSERT(rsProgramStoreGetColorMaskG(blendDst) == false);
-    _RS_ASSERT(rsProgramStoreGetColorMaskB(blendDst) == false);
-    _RS_ASSERT(rsProgramStoreGetColorMaskA(blendDst) == false);
-    _RS_ASSERT(rsProgramStoreGetDitherEnabled(blendDst) == false);
-    _RS_ASSERT(rsProgramStoreGetBlendSrcFunc(blendDst) == RS_BLEND_SRC_ZERO);
-    _RS_ASSERT(rsProgramStoreGetBlendDstFunc(blendDst) == RS_BLEND_DST_DST_ALPHA);
+    _RS_ASSERT(rsgProgramStoreGetDepthFunc(blendDst) == RS_DEPTH_FUNC_ALWAYS);
+    _RS_ASSERT(rsgProgramStoreGetDepthMask(blendDst) == false);
+    _RS_ASSERT(rsgProgramStoreGetColorMaskR(blendDst) == false);
+    _RS_ASSERT(rsgProgramStoreGetColorMaskG(blendDst) == false);
+    _RS_ASSERT(rsgProgramStoreGetColorMaskB(blendDst) == false);
+    _RS_ASSERT(rsgProgramStoreGetColorMaskA(blendDst) == false);
+    _RS_ASSERT(rsgProgramStoreGetDitherEnabled(blendDst) == false);
+    _RS_ASSERT(rsgProgramStoreGetBlendSrcFunc(blendDst) == RS_BLEND_SRC_ZERO);
+    _RS_ASSERT(rsgProgramStoreGetBlendDstFunc(blendDst) == RS_BLEND_DST_DST_ALPHA);
 
     if (failed) {
         rsDebug("test_program_store_getters FAILED", 0);
diff --git a/tools/aapt/ZipFile.cpp b/tools/aapt/ZipFile.cpp
index 8057068..3994c31 100644
--- a/tools/aapt/ZipFile.cpp
+++ b/tools/aapt/ZipFile.cpp
@@ -20,8 +20,8 @@
 
 #define LOG_TAG "zip"
 
-#include <androidfw/ZipUtils.h>
 #include <utils/Log.h>
+#include <utils/ZipUtils.h>
 
 #include "ZipFile.h"