Merge "Import translations. DO NOT MERGE"
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/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/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/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/media/libmedia/Android.mk b/media/libmedia/Android.mk
index 43008d4..21e8f29 100644
--- a/media/libmedia/Android.mk
+++ b/media/libmedia/Android.mk
@@ -3,26 +3,47 @@
 include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES:= \
+    AudioParameter.cpp
+LOCAL_MODULE:= libmedia_helper
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_STATIC_LIBRARY)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+    AudioTrack.cpp \
+    IAudioFlinger.cpp \
+    IAudioFlingerClient.cpp \
+    IAudioTrack.cpp \
+    IAudioRecord.cpp \
+    AudioRecord.cpp \
+    AudioSystem.cpp \
+    mediaplayer.cpp \
+    IMediaPlayerService.cpp \
+    IMediaPlayerClient.cpp \
+    IMediaRecorderClient.cpp \
+    IMediaPlayer.cpp \
+    IMediaRecorder.cpp \
+    IStreamSource.cpp \
+    Metadata.cpp \
+    mediarecorder.cpp \
+    IMediaMetadataRetriever.cpp \
+    mediametadataretriever.cpp \
+    ToneGenerator.cpp \
+    JetPlayer.cpp \
+    IOMX.cpp \
+    IAudioPolicyService.cpp \
+    MediaScanner.cpp \
+    MediaScannerClient.cpp \
     autodetect.cpp \
     IMediaDeathNotifier.cpp \
-    IMediaMetadataRetriever.cpp \
-    IMediaPlayerClient.cpp \
-    IMediaPlayer.cpp \
-    IMediaPlayerService.cpp \
-    IMediaRecorderClient.cpp \
-    IMediaRecorder.cpp \
-    IOMX.cpp \
-    IStreamSource.cpp \
-    JetPlayer.cpp \
-    mediametadataretriever.cpp \
-    mediaplayer.cpp \
     MediaProfiles.cpp \
-    mediarecorder.cpp \
-    MediaScannerClient.cpp \
-    MediaScanner.cpp \
-    MemoryLeakTrackUtil.cpp \
-    Metadata.cpp \
-    Visualizer.cpp
+    IEffect.cpp \
+    IEffectClient.cpp \
+    AudioEffect.cpp \
+    Visualizer.cpp \
+    MemoryLeakTrackUtil.cpp
 
 LOCAL_SHARED_LIBRARIES := \
 	libui libcutils libutils libbinder libsonivox libicuuc libexpat \
diff --git a/media/libmedia_native/Android.mk b/media/libmedia_native/Android.mk
index 07f0978..065a90f 100644
--- a/media/libmedia_native/Android.mk
+++ b/media/libmedia_native/Android.mk
@@ -1,39 +1,11 @@
-# FIXME remove "/../libmedia" at same time as rename
-LOCAL_PATH := $(call my-dir)/../libmedia
+LOCAL_PATH := $(call my-dir)
 
 include $(CLEAR_VARS)
 
-LOCAL_SRC_FILES:= \
-    AudioParameter.cpp
-LOCAL_MODULE:= libmedia_helper
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_STATIC_LIBRARY)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := \
-    AudioEffect.cpp \
-    AudioRecord.cpp \
-    AudioSystem.cpp \
-    AudioTrack.cpp \
-    IAudioFlingerClient.cpp \
-    IAudioFlinger.cpp \
-    IAudioPolicyService.cpp \
-    IAudioRecord.cpp \
-    IAudioTrack.cpp \
-    IEffectClient.cpp \
-    IEffect.cpp \
-    ToneGenerator.cpp
-
-LOCAL_SHARED_LIBRARIES := \
-    libaudioutils libbinder libcutils libutils
+LOCAL_SRC_FILES :=
 
 LOCAL_MODULE:= libmedia_native
 
-LOCAL_C_INCLUDES := \
-    $(call include-path-for, audio-utils)
-
 LOCAL_MODULE_TAGS := optional
 
 include $(BUILD_SHARED_LIBRARY)
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/audioflinger/Android.mk b/services/audioflinger/Android.mk
index 69204d3..257f62c 100644
--- a/services/audioflinger/Android.mk
+++ b/services/audioflinger/Android.mk
@@ -22,6 +22,7 @@
     libcutils \
     libutils \
     libbinder \
+    libmedia \
     libmedia_native \
     libhardware \
     libhardware_legacy \
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 {