Merge "IAudioFlingerClient::ioConfigChanged param2 const"
diff --git a/api/current.txt b/api/current.txt
index c9be4cd..4110a20 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -2722,6 +2722,7 @@
     method public int getLauncherLargeIconSize();
     method public int getMemoryClass();
     method public void getMemoryInfo(android.app.ActivityManager.MemoryInfo);
+    method public static void getMyMemoryState(android.app.ActivityManager.RunningAppProcessInfo);
     method public android.os.Debug.MemoryInfo[] getProcessMemoryInfo(int[]);
     method public java.util.List<android.app.ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState();
     method public java.util.List<android.app.ActivityManager.RecentTaskInfo> getRecentTasks(int, int) throws java.lang.SecurityException;
@@ -2804,6 +2805,7 @@
     field public int importanceReasonCode;
     field public android.content.ComponentName importanceReasonComponent;
     field public int importanceReasonPid;
+    field public int lastTrimLevel;
     field public int lru;
     field public int pid;
     field public java.lang.String[] pkgList;
@@ -4826,6 +4828,9 @@
     field public static final int TRIM_MEMORY_BACKGROUND = 40; // 0x28
     field public static final int TRIM_MEMORY_COMPLETE = 80; // 0x50
     field public static final int TRIM_MEMORY_MODERATE = 60; // 0x3c
+    field public static final int TRIM_MEMORY_RUNNING_CRITICAL = 15; // 0xf
+    field public static final int TRIM_MEMORY_RUNNING_LOW = 10; // 0xa
+    field public static final int TRIM_MEMORY_RUNNING_MODERATE = 5; // 0x5
     field public static final int TRIM_MEMORY_UI_HIDDEN = 20; // 0x14
   }
 
@@ -6904,7 +6909,7 @@
     method public boolean onMove(int, int);
   }
 
-  public abstract interface Cursor {
+  public abstract interface Cursor implements java.io.Closeable {
     method public abstract void close();
     method public abstract void copyStringToBuffer(int, android.database.CharArrayBuffer);
     method public abstract deprecated void deactivate();
@@ -6977,7 +6982,6 @@
     ctor public deprecated CursorWindow(boolean);
     method public boolean allocRow();
     method public void clear();
-    method public void close();
     method public void copyStringToBuffer(int, int, android.database.CharArrayBuffer);
     method public int describeContents();
     method public void freeLastRow();
@@ -7236,13 +7240,14 @@
     ctor public SQLiteCantOpenDatabaseException(java.lang.String);
   }
 
-  public abstract class SQLiteClosable {
+  public abstract class SQLiteClosable implements java.io.Closeable {
     ctor public SQLiteClosable();
     method public void acquireReference();
+    method public void close();
     method protected abstract void onAllReferencesReleased();
-    method protected void onAllReferencesReleasedFromContainer();
+    method protected deprecated void onAllReferencesReleasedFromContainer();
     method public void releaseReference();
-    method public void releaseReferenceFromContainer();
+    method public deprecated void releaseReferenceFromContainer();
   }
 
   public class SQLiteConstraintException extends android.database.sqlite.SQLiteException {
@@ -7272,7 +7277,6 @@
     method public void beginTransactionNonExclusive();
     method public void beginTransactionWithListener(android.database.sqlite.SQLiteTransactionListener);
     method public void beginTransactionWithListenerNonExclusive(android.database.sqlite.SQLiteTransactionListener);
-    method public void close();
     method public android.database.sqlite.SQLiteStatement compileStatement(java.lang.String) throws android.database.SQLException;
     method public static android.database.sqlite.SQLiteDatabase create(android.database.sqlite.SQLiteDatabase.CursorFactory);
     method public int delete(java.lang.String, java.lang.String, java.lang.String[]);
@@ -7415,7 +7419,6 @@
     method public void bindNull(int);
     method public void bindString(int, java.lang.String);
     method public void clearBindings();
-    method public void close();
     method public final deprecated int getUniqueId();
     method protected void onAllReferencesReleased();
   }
@@ -10777,6 +10780,17 @@
     method public abstract void onJetUserIdUpdate(android.media.JetPlayer, int, int);
   }
 
+  public class MediaActionSound {
+    ctor public MediaActionSound();
+    method public void load(int);
+    method public void play(int);
+    method public void release();
+    field public static final int FOCUS_COMPLETE = 1; // 0x1
+    field public static final int SHUTTER_CLICK = 0; // 0x0
+    field public static final int START_VIDEO_RECORDING = 2; // 0x2
+    field public static final int STOP_VIDEO_RECORDING = 3; // 0x3
+  }
+
   public class MediaMetadataRetriever {
     ctor public MediaMetadataRetriever();
     method public java.lang.String extractMetadata(int);
diff --git a/cmds/dumpstate/dumpstate.c b/cmds/dumpstate/dumpstate.c
index 13b63dc..ba79c9f 100644
--- a/cmds/dumpstate/dumpstate.c
+++ b/cmds/dumpstate/dumpstate.c
@@ -86,11 +86,6 @@
     dump_file("PAGETYPEINFO", "/proc/pagetypeinfo");
     dump_file("BUDDYINFO", "/proc/buddyinfo");
 
-    print_properties();
-
-    /* TODO: Make last_kmsg CAP_SYSLOG protected. b/5555691 */
-    dump_file("LAST KMSG", "/proc/last_kmsg");
-    do_dmesg();
 
     dump_file("KERNEL WAKELOCKS", "/proc/wakelocks");
     dump_file("KERNEL CPUFREQ", "/sys/devices/system/cpu/cpu0/cpufreq/stats/time_in_state");
@@ -99,6 +94,19 @@
     run_command("PROCESSES AND THREADS", 10, "ps", "-t", "-p", "-P", NULL);
     run_command("LIBRANK", 10, "librank", NULL);
 
+    do_dmesg();
+
+    run_command("LIST OF OPEN FILES", 10, SU_PATH, "root", "lsof", NULL);
+
+    for_each_pid(do_showmap, "SMAPS OF ALL PROCESSES");
+    for_each_pid(show_wchan, "BLOCKED PROCESS WAIT-CHANNELS");
+
+    // dump_file("EVENT LOG TAGS", "/etc/event-log-tags");
+    run_command("SYSTEM LOG", 20, "logcat", "-v", "threadtime", "-d", "*:v", NULL);
+    run_command("EVENT LOG", 20, "logcat", "-b", "events", "-v", "threadtime", "-d", "*:v", NULL);
+    run_command("RADIO LOG", 20, "logcat", "-b", "radio", "-v", "threadtime", "-d", "*:v", NULL);
+
+
     /* show the traces we collected in main(), if that was done */
     if (dump_traces_path != NULL) {
         dump_file("VM TRACES JUST NOW", dump_traces_path);
@@ -124,6 +132,11 @@
     dump_file("NETWORK ROUTES", "/proc/net/route");
     dump_file("NETWORK ROUTES IPV6", "/proc/net/ipv6_route");
 
+    /* TODO: Make last_kmsg CAP_SYSLOG protected. b/5555691 */
+    dump_file("LAST KMSG", "/proc/last_kmsg");
+    dump_file("LAST PANIC CONSOLE", "/data/dontpanic/apanic_console");
+    dump_file("LAST PANIC THREADS", "/data/dontpanic/apanic_threads");
+
     if (screenshot_path[0]) {
         ALOGI("taking screenshot\n");
         run_command(NULL, 5, SU_PATH, "root", "screenshot", screenshot_path, NULL);
@@ -134,11 +147,7 @@
             "/data/data/com.android.providers.settings/databases/settings.db",
             "pragma user_version; select * from system; select * from secure;", NULL);
 
-    // dump_file("EVENT LOG TAGS", "/etc/event-log-tags");
-    run_command("SYSTEM LOG", 20, "logcat", "-v", "threadtime", "-d", "*:v", NULL);
-    run_command("EVENT LOG", 20, "logcat", "-b", "events", "-v", "threadtime", "-d", "*:v", NULL);
-    run_command("RADIO LOG", 20, "logcat", "-b", "radio", "-v", "threadtime", "-d", "*:v", NULL);
-
+    /* The following have a tendency to get wedged when wifi drivers/fw goes belly-up. */
     run_command("NETWORK INTERFACES", 10, SU_PATH, "root", "netcfg", NULL);
     run_command("IP RULES", 10, "ip", "rule", "show", NULL);
     run_command("IP RULES v6", 10, "ip", "-6", "rule", "show", NULL);
@@ -171,40 +180,17 @@
             SU_PATH, "root", "wlutil", "counters", NULL);
 #endif
 
-    char ril_dumpstate_timeout[PROPERTY_VALUE_MAX] = {0};
-    property_get("ril.dumpstate.timeout", ril_dumpstate_timeout, "30");
-    if (strnlen(ril_dumpstate_timeout, PROPERTY_VALUE_MAX - 1) > 0) {
-        if (0 == strncmp(build_type, "user", PROPERTY_VALUE_MAX - 1)) {
-            // su does not exist on user builds, so try running without it.
-            // This way any implementations of vril-dump that do not require
-            // root can run on user builds.
-            run_command("DUMP VENDOR RIL LOGS", atoi(ril_dumpstate_timeout),
-                    "vril-dump", NULL);
-        } else {
-            run_command("DUMP VENDOR RIL LOGS", atoi(ril_dumpstate_timeout),
-                    SU_PATH, "root", "vril-dump", NULL);
-        }
-    }
+    print_properties();
 
     run_command("VOLD DUMP", 10, "vdc", "dump", NULL);
     run_command("SECURE CONTAINERS", 10, "vdc", "asec", "list", NULL);
 
-    dump_file("BINDER FAILED TRANSACTION LOG", "/sys/kernel/debug/binder/failed_transaction_log");
-    dump_file("BINDER TRANSACTION LOG", "/sys/kernel/debug/binder/transaction_log");
-    dump_file("BINDER TRANSACTIONS", "/sys/kernel/debug/binder/transactions");
-    dump_file("BINDER STATS", "/sys/kernel/debug/binder/stats");
-    dump_file("BINDER STATE", "/sys/kernel/debug/binder/state");
-
     run_command("FILESYSTEMS & FREE SPACE", 10, SU_PATH, "root", "df", NULL);
 
     dump_file("PACKAGE SETTINGS", "/data/system/packages.xml");
     dump_file("PACKAGE UID ERRORS", "/data/system/uiderrors.txt");
 
     run_command("LAST RADIO LOG", 10, "parse_radio_log", "/proc/last_radio_log", NULL);
-    dump_file("LAST PANIC CONSOLE", "/data/dontpanic/apanic_console");
-    dump_file("LAST PANIC THREADS", "/data/dontpanic/apanic_threads");
-
-    for_each_pid(show_wchan, "BLOCKED PROCESS WAIT-CHANNELS");
 
     printf("------ BACKLIGHTS ------\n");
     printf("LCD brightness=");
@@ -219,9 +205,12 @@
     dump_file(NULL, "/sys/class/leds/lcd-backlight/registers");
     printf("\n");
 
-    run_command("LIST OF OPEN FILES", 10, SU_PATH, "root", "lsof", NULL);
-
-    for_each_pid(do_showmap, "SMAPS OF ALL PROCESSES");
+    /* Binder state is expensive to look at as it uses a lot of memory. */
+    dump_file("BINDER FAILED TRANSACTION LOG", "/sys/kernel/debug/binder/failed_transaction_log");
+    dump_file("BINDER TRANSACTION LOG", "/sys/kernel/debug/binder/transaction_log");
+    dump_file("BINDER TRANSACTIONS", "/sys/kernel/debug/binder/transactions");
+    dump_file("BINDER STATS", "/sys/kernel/debug/binder/stats");
+    dump_file("BINDER STATE", "/sys/kernel/debug/binder/state");
 
 #ifdef BOARD_HAS_DUMPSTATE
     printf("========================================================\n");
@@ -232,6 +221,22 @@
     printf("\n");
 #endif
 
+    /* Migrate the ril_dumpstate to a dumpstate_board()? */
+    char ril_dumpstate_timeout[PROPERTY_VALUE_MAX] = {0};
+    property_get("ril.dumpstate.timeout", ril_dumpstate_timeout, "30");
+    if (strnlen(ril_dumpstate_timeout, PROPERTY_VALUE_MAX - 1) > 0) {
+        if (0 == strncmp(build_type, "user", PROPERTY_VALUE_MAX - 1)) {
+            // su does not exist on user builds, so try running without it.
+            // This way any implementations of vril-dump that do not require
+            // root can run on user builds.
+            run_command("DUMP VENDOR RIL LOGS", atoi(ril_dumpstate_timeout),
+                    "vril-dump", NULL);
+        } else {
+            run_command("DUMP VENDOR RIL LOGS", atoi(ril_dumpstate_timeout),
+                    SU_PATH, "root", "vril-dump", NULL);
+        }
+    }
+
     printf("========================================================\n");
     printf("== Android Framework Services\n");
     printf("========================================================\n");
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index d98d87b..59c803e 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -1145,7 +1145,14 @@
          * @hide
          */
         public int flags;
-        
+
+        /**
+         * Last memory trim level reported to the process: corresponds to
+         * the values supplied to {@link android.content.ComponentCallbacks2#onTrimMemory(int)
+         * ComponentCallbacks2.onTrimMemory(int)}.
+         */
+        public int lastTrimLevel;
+
         /**
          * Constant for {@link #importance}: this process is running the
          * foreground UI.
@@ -1212,7 +1219,7 @@
          * be maintained in the future.
          */
         public int lru;
-        
+
         /**
          * Constant for {@link #importanceReasonCode}: nothing special has
          * been specified for the reason for this level.
@@ -1282,6 +1289,7 @@
             dest.writeInt(uid);
             dest.writeStringArray(pkgList);
             dest.writeInt(this.flags);
+            dest.writeInt(lastTrimLevel);
             dest.writeInt(importance);
             dest.writeInt(lru);
             dest.writeInt(importanceReasonCode);
@@ -1296,6 +1304,7 @@
             uid = source.readInt();
             pkgList = source.readStringArray();
             flags = source.readInt();
+            lastTrimLevel = source.readInt();
             importance = source.readInt();
             lru = source.readInt();
             importanceReasonCode = source.readInt();
@@ -1349,7 +1358,25 @@
             return null;
         }
     }
-    
+
+    /**
+     * Return global memory state information for the calling process.  This
+     * does not fill in all fields of the {@link RunningAppProcessInfo}.  The
+     * only fields that will be filled in are
+     * {@link RunningAppProcessInfo#pid},
+     * {@link RunningAppProcessInfo#uid},
+     * {@link RunningAppProcessInfo#lastTrimLevel},
+     * {@link RunningAppProcessInfo#importance},
+     * {@link RunningAppProcessInfo#lru}, and
+     * {@link RunningAppProcessInfo#importanceReasonCode}.
+     */
+    static public void getMyMemoryState(RunningAppProcessInfo outState) {
+        try {
+            ActivityManagerNative.getDefault().getMyMemoryState(outState);
+        } catch (RemoteException e) {
+        }
+    }
+
     /**
      * Return information about the memory usage of one or more processes.
      * 
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index 24079a5d..b952649 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -1126,7 +1126,17 @@
             reply.writeNoException();
             return true;
         }
-        
+
+        case GET_MY_MEMORY_STATE_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            ActivityManager.RunningAppProcessInfo info =
+                    new ActivityManager.RunningAppProcessInfo();
+            getMyMemoryState(info);
+            reply.writeNoException();
+            info.writeToParcel(reply, 0);
+            return true;
+        }
+
         case GET_DEVICE_CONFIGURATION_TRANSACTION: {
             data.enforceInterface(IActivityManager.descriptor);
             ConfigurationInfo config = getDeviceConfigurationInfo();
@@ -2973,6 +2983,19 @@
         reply.recycle();
     }
     
+    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo)
+            throws RemoteException
+    {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        mRemote.transact(GET_MY_MEMORY_STATE_TRANSACTION, data, reply, 0);
+        reply.readException();
+        outInfo.readFromParcel(reply);
+        reply.recycle();
+        data.recycle();
+    }
+
     public ConfigurationInfo getDeviceConfigurationInfo() throws RemoteException
     {
         Parcel data = Parcel.obtain();
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index 53a71db..ea2545f 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -278,13 +278,16 @@
      * SIGUSR1 is delivered. All others are ignored.
      */
     public void signalPersistentProcesses(int signal) throws RemoteException;
-    // Retrieve info of applications installed on external media that are currently
-    // running.
+    // Retrieve running application processes in the system
     public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses()
             throws RemoteException;
- // Retrieve running application processes in the system
+    // Retrieve info of applications installed on external media that are currently
+    // running.
     public List<ApplicationInfo> getRunningExternalApplications()
             throws RemoteException;
+    // Get memory information about the calling process.
+    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo)
+            throws RemoteException;
     // Get device configuration
     public ConfigurationInfo getDeviceConfigurationInfo() throws RemoteException;
     
@@ -606,4 +609,5 @@
     int KILL_ALL_BACKGROUND_PROCESSES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+139;
     int GET_CONTENT_PROVIDER_EXTERNAL_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+140;
     int REMOVE_CONTENT_PROVIDER_EXTERNAL_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+141;
+    int GET_MY_MEMORY_STATE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+142;
 }
diff --git a/core/java/android/content/ComponentCallbacks2.java b/core/java/android/content/ComponentCallbacks2.java
index 8b9f97c..85294dd 100644
--- a/core/java/android/content/ComponentCallbacks2.java
+++ b/core/java/android/content/ComponentCallbacks2.java
@@ -52,15 +52,49 @@
     static final int TRIM_MEMORY_UI_HIDDEN = 20;
 
     /**
+     * Level for {@link #onTrimMemory(int)}: the process is not an expendable
+     * background process, but the device is running extremely low on memory
+     * and is about to not be able to keep any background processes running.
+     * Your running process should free up as many non-critical resources as it
+     * can to allow that memory to be used elsewhere.  The next thing that
+     * will happen after this is {@link #onLowMemory()} called to report that
+     * nothing at all can be kept in the background, a situation that can start
+     * to notably impact the user.
+     */
+    static final int TRIM_MEMORY_RUNNING_CRITICAL = 15;
+
+    /**
+     * Level for {@link #onTrimMemory(int)}: the process is not an expendable
+     * background process, but the device is running low on memory.
+     * Your running process should free up unneeded resources to allow that
+     * memory to be used elsewhere.
+     */
+    static final int TRIM_MEMORY_RUNNING_LOW = 10;
+
+
+    /**
+     * Level for {@link #onTrimMemory(int)}: the process is not an expendable
+     * background process, but the device is running moderately low on memory.
+     * Your running process may want to release some unneeded resources for
+     * use elsewhere.
+     */
+    static final int TRIM_MEMORY_RUNNING_MODERATE = 5;
+
+    /**
      * Called when the operating system has determined that it is a good
      * time for a process to trim unneeded memory from its process.  This will
      * happen for example when it goes in the background and there is not enough
-     * memory to keep as many background processes running as desired.
+     * memory to keep as many background processes running as desired.  You
+     * should never compare to exact values of the level, since new intermediate
+     * values may be added -- you will typically want to compare if the value
+     * is greater or equal to a level you are interested in.
      * 
      * @param level The context of the trim, giving a hint of the amount of
      * trimming the application may like to perform.  May be
      * {@link #TRIM_MEMORY_COMPLETE}, {@link #TRIM_MEMORY_MODERATE},
-     * {@link #TRIM_MEMORY_BACKGROUND}, or {@link #TRIM_MEMORY_UI_HIDDEN}.
+     * {@link #TRIM_MEMORY_BACKGROUND}, {@link #TRIM_MEMORY_UI_HIDDEN},
+     * {@link #TRIM_MEMORY_RUNNING_CRITICAL}, {@link #TRIM_MEMORY_RUNNING_LOW},
+     * or {@link #TRIM_MEMORY_RUNNING_MODERATE}.
      */
     void onTrimMemory(int level);
 }
diff --git a/core/java/android/database/Cursor.java b/core/java/android/database/Cursor.java
index 59ec89d..907833d 100644
--- a/core/java/android/database/Cursor.java
+++ b/core/java/android/database/Cursor.java
@@ -20,6 +20,8 @@
 import android.net.Uri;
 import android.os.Bundle;
 
+import java.io.Closeable;
+
 /**
  * This interface provides random read-write access to the result set returned
  * by a database query.
@@ -27,7 +29,7 @@
  * Cursor implementations are not required to be synchronized so code using a Cursor from multiple
  * threads should perform its own synchronization when using the Cursor.
  */
-public interface Cursor {
+public interface Cursor extends Closeable {
     /*
      * Values returned by {@link #getType(int)}.
      * These should be consistent with the corresponding types defined in CursorWindow.h
diff --git a/core/java/android/database/CursorWindow.java b/core/java/android/database/CursorWindow.java
index 85f570c1..f1f3017 100644
--- a/core/java/android/database/CursorWindow.java
+++ b/core/java/android/database/CursorWindow.java
@@ -169,14 +169,6 @@
     }
 
     /**
-     * Closes the cursor window and frees its underlying resources when all other
-     * remaining references have been released.
-     */
-    public void close() {
-        releaseReference();
-    }
-
-    /**
      * Clears out the existing contents of the window, making it safe to reuse
      * for new data.
      * <p>
@@ -703,8 +695,13 @@
     }
 
     public void writeToParcel(Parcel dest, int flags) {
-        dest.writeInt(mStartPos);
-        nativeWriteToParcel(mWindowPtr, dest);
+        acquireReference();
+        try {
+            dest.writeInt(mStartPos);
+            nativeWriteToParcel(mWindowPtr, dest);
+        } finally {
+            releaseReference();
+        }
 
         if ((flags & Parcelable.PARCELABLE_WRITE_RETURN_VALUE) != 0) {
             releaseReference();
diff --git a/core/java/android/database/DatabaseUtils.java b/core/java/android/database/DatabaseUtils.java
index 0022118..99d260e 100644
--- a/core/java/android/database/DatabaseUtils.java
+++ b/core/java/android/database/DatabaseUtils.java
@@ -269,63 +269,56 @@
         if (position < 0 || position >= cursor.getCount()) {
             return;
         }
-        window.acquireReference();
-        try {
-            final int oldPos = cursor.getPosition();
-            final int numColumns = cursor.getColumnCount();
-            window.clear();
-            window.setStartPosition(position);
-            window.setNumColumns(numColumns);
-            if (cursor.moveToPosition(position)) {
-                do {
-                    if (!window.allocRow()) {
-                        break;
-                    }
-                    for (int i = 0; i < numColumns; i++) {
-                        final int type = cursor.getType(i);
-                        final boolean success;
-                        switch (type) {
-                            case Cursor.FIELD_TYPE_NULL:
-                                success = window.putNull(position, i);
-                                break;
+        final int oldPos = cursor.getPosition();
+        final int numColumns = cursor.getColumnCount();
+        window.clear();
+        window.setStartPosition(position);
+        window.setNumColumns(numColumns);
+        if (cursor.moveToPosition(position)) {
+            do {
+                if (!window.allocRow()) {
+                    break;
+                }
+                for (int i = 0; i < numColumns; i++) {
+                    final int type = cursor.getType(i);
+                    final boolean success;
+                    switch (type) {
+                        case Cursor.FIELD_TYPE_NULL:
+                            success = window.putNull(position, i);
+                            break;
 
-                            case Cursor.FIELD_TYPE_INTEGER:
-                                success = window.putLong(cursor.getLong(i), position, i);
-                                break;
+                        case Cursor.FIELD_TYPE_INTEGER:
+                            success = window.putLong(cursor.getLong(i), position, i);
+                            break;
 
-                            case Cursor.FIELD_TYPE_FLOAT:
-                                success = window.putDouble(cursor.getDouble(i), position, i);
-                                break;
+                        case Cursor.FIELD_TYPE_FLOAT:
+                            success = window.putDouble(cursor.getDouble(i), position, i);
+                            break;
 
-                            case Cursor.FIELD_TYPE_BLOB: {
-                                final byte[] value = cursor.getBlob(i);
-                                success = value != null ? window.putBlob(value, position, i)
-                                        : window.putNull(position, i);
-                                break;
-                            }
-
-                            default: // assume value is convertible to String
-                            case Cursor.FIELD_TYPE_STRING: {
-                                final String value = cursor.getString(i);
-                                success = value != null ? window.putString(value, position, i)
-                                        : window.putNull(position, i);
-                                break;
-                            }
+                        case Cursor.FIELD_TYPE_BLOB: {
+                            final byte[] value = cursor.getBlob(i);
+                            success = value != null ? window.putBlob(value, position, i)
+                                    : window.putNull(position, i);
+                            break;
                         }
-                        if (!success) {
-                            window.freeLastRow();
+
+                        default: // assume value is convertible to String
+                        case Cursor.FIELD_TYPE_STRING: {
+                            final String value = cursor.getString(i);
+                            success = value != null ? window.putString(value, position, i)
+                                    : window.putNull(position, i);
                             break;
                         }
                     }
-                    position += 1;
-                } while (cursor.moveToNext());
-            }
-            cursor.moveToPosition(oldPos);
-        } catch (IllegalStateException e){
-            // simply ignore it
-        } finally {
-            window.releaseReference();
+                    if (!success) {
+                        window.freeLastRow();
+                        break;
+                    }
+                }
+                position += 1;
+            } while (cursor.moveToNext());
         }
+        cursor.moveToPosition(oldPos);
     }
 
     /**
diff --git a/core/java/android/database/sqlite/SQLiteClosable.java b/core/java/android/database/sqlite/SQLiteClosable.java
index 7e91a7b..adfbc6e 100644
--- a/core/java/android/database/sqlite/SQLiteClosable.java
+++ b/core/java/android/database/sqlite/SQLiteClosable.java
@@ -16,15 +16,39 @@
 
 package android.database.sqlite;
 
+import java.io.Closeable;
+
 /**
  * An object created from a SQLiteDatabase that can be closed.
+ *
+ * This class implements a primitive reference counting scheme for database objects.
  */
-public abstract class SQLiteClosable {
+public abstract class SQLiteClosable implements Closeable {
     private int mReferenceCount = 1;
 
+    /**
+     * Called when the last reference to the object was released by
+     * a call to {@link #releaseReference()} or {@link #close()}.
+     */
     protected abstract void onAllReferencesReleased();
-    protected void onAllReferencesReleasedFromContainer() {}
 
+    /**
+     * Called when the last reference to the object was released by
+     * a call to {@link #releaseReferenceFromContainer()}.
+     *
+     * @deprecated Do not use.
+     */
+    @Deprecated
+    protected void onAllReferencesReleasedFromContainer() {
+        onAllReferencesReleased();
+    }
+
+    /**
+     * Acquires a reference to the object.
+     *
+     * @throws IllegalStateException if the last reference to the object has already
+     * been released.
+     */
     public void acquireReference() {
         synchronized(this) {
             if (mReferenceCount <= 0) {
@@ -35,6 +59,12 @@
         }
     }
 
+    /**
+     * Releases a reference to the object, closing the object if the last reference
+     * was released.
+     *
+     * @see #onAllReferencesReleased()
+     */
     public void releaseReference() {
         boolean refCountIsZero = false;
         synchronized(this) {
@@ -45,6 +75,14 @@
         }
     }
 
+    /**
+     * Releases a reference to the object that was owned by the container of the object,
+     * closing the object if the last reference was released.
+     *
+     * @see #onAllReferencesReleasedFromContainer()
+     * @deprecated Do not use.
+     */
+    @Deprecated
     public void releaseReferenceFromContainer() {
         boolean refCountIsZero = false;
         synchronized(this) {
@@ -54,4 +92,17 @@
             onAllReferencesReleasedFromContainer();
         }
     }
+
+    /**
+     * Releases a reference to the object, closing the object if the last reference
+     * was released.
+     *
+     * Calling this method is equivalent to calling {@link #releaseReference}.
+     *
+     * @see #releaseReference()
+     * @see #onAllReferencesReleased()
+     */
+    public void close() {
+        releaseReference();
+    }
 }
diff --git a/core/java/android/database/sqlite/SQLiteConnection.java b/core/java/android/database/sqlite/SQLiteConnection.java
index d16f29f..0db3e4f 100644
--- a/core/java/android/database/sqlite/SQLiteConnection.java
+++ b/core/java/android/database/sqlite/SQLiteConnection.java
@@ -704,44 +704,49 @@
             throw new IllegalArgumentException("window must not be null.");
         }
 
-        int actualPos = -1;
-        int countedRows = -1;
-        int filledRows = -1;
-        final int cookie = mRecentOperations.beginOperation("executeForCursorWindow",
-                sql, bindArgs);
+        window.acquireReference();
         try {
-            final PreparedStatement statement = acquirePreparedStatement(sql);
+            int actualPos = -1;
+            int countedRows = -1;
+            int filledRows = -1;
+            final int cookie = mRecentOperations.beginOperation("executeForCursorWindow",
+                    sql, bindArgs);
             try {
-                throwIfStatementForbidden(statement);
-                bindArguments(statement, bindArgs);
-                applyBlockGuardPolicy(statement);
-                attachCancellationSignal(cancellationSignal);
+                final PreparedStatement statement = acquirePreparedStatement(sql);
                 try {
-                    final long result = nativeExecuteForCursorWindow(
-                            mConnectionPtr, statement.mStatementPtr, window.mWindowPtr,
-                            startPos, requiredPos, countAllRows);
-                    actualPos = (int)(result >> 32);
-                    countedRows = (int)result;
-                    filledRows = window.getNumRows();
-                    window.setStartPosition(actualPos);
-                    return countedRows;
+                    throwIfStatementForbidden(statement);
+                    bindArguments(statement, bindArgs);
+                    applyBlockGuardPolicy(statement);
+                    attachCancellationSignal(cancellationSignal);
+                    try {
+                        final long result = nativeExecuteForCursorWindow(
+                                mConnectionPtr, statement.mStatementPtr, window.mWindowPtr,
+                                startPos, requiredPos, countAllRows);
+                        actualPos = (int)(result >> 32);
+                        countedRows = (int)result;
+                        filledRows = window.getNumRows();
+                        window.setStartPosition(actualPos);
+                        return countedRows;
+                    } finally {
+                        detachCancellationSignal(cancellationSignal);
+                    }
                 } finally {
-                    detachCancellationSignal(cancellationSignal);
+                    releasePreparedStatement(statement);
                 }
+            } catch (RuntimeException ex) {
+                mRecentOperations.failOperation(cookie, ex);
+                throw ex;
             } finally {
-                releasePreparedStatement(statement);
+                if (mRecentOperations.endOperationDeferLog(cookie)) {
+                    mRecentOperations.logOperation(cookie, "window='" + window
+                            + "', startPos=" + startPos
+                            + ", actualPos=" + actualPos
+                            + ", filledRows=" + filledRows
+                            + ", countedRows=" + countedRows);
+                }
             }
-        } catch (RuntimeException ex) {
-            mRecentOperations.failOperation(cookie, ex);
-            throw ex;
         } finally {
-            if (mRecentOperations.endOperationDeferLog(cookie)) {
-                mRecentOperations.logOperation(cookie, "window='" + window
-                        + "', startPos=" + startPos
-                        + ", actualPos=" + actualPos
-                        + ", filledRows=" + filledRows
-                        + ", countedRows=" + countedRows);
-            }
+            window.releaseReference();
         }
     }
 
diff --git a/core/java/android/database/sqlite/SQLiteDatabase.java b/core/java/android/database/sqlite/SQLiteDatabase.java
index 604247e..d41b484 100644
--- a/core/java/android/database/sqlite/SQLiteDatabase.java
+++ b/core/java/android/database/sqlite/SQLiteDatabase.java
@@ -492,9 +492,16 @@
 
     private void beginTransaction(SQLiteTransactionListener transactionListener,
             boolean exclusive) {
-        getThreadSession().beginTransaction(exclusive ? SQLiteSession.TRANSACTION_MODE_EXCLUSIVE :
-                SQLiteSession.TRANSACTION_MODE_IMMEDIATE, transactionListener,
-                getThreadDefaultConnectionFlags(false /*readOnly*/), null);
+        acquireReference();
+        try {
+            getThreadSession().beginTransaction(
+                    exclusive ? SQLiteSession.TRANSACTION_MODE_EXCLUSIVE :
+                            SQLiteSession.TRANSACTION_MODE_IMMEDIATE,
+                    transactionListener,
+                    getThreadDefaultConnectionFlags(false /*readOnly*/), null);
+        } finally {
+            releaseReference();
+        }
     }
 
     /**
@@ -502,7 +509,12 @@
      * are committed and rolled back.
      */
     public void endTransaction() {
-        getThreadSession().endTransaction(null);
+        acquireReference();
+        try {
+            getThreadSession().endTransaction(null);
+        } finally {
+            releaseReference();
+        }
     }
 
     /**
@@ -515,7 +527,12 @@
      * transaction is already marked as successful.
      */
     public void setTransactionSuccessful() {
-        getThreadSession().setTransactionSuccessful();
+        acquireReference();
+        try {
+            getThreadSession().setTransactionSuccessful();
+        } finally {
+            releaseReference();
+        }
     }
 
     /**
@@ -524,7 +541,12 @@
      * @return True if the current thread is in a transaction.
      */
     public boolean inTransaction() {
-        return getThreadSession().hasTransaction();
+        acquireReference();
+        try {
+            return getThreadSession().hasTransaction();
+        } finally {
+            releaseReference();
+        }
     }
 
     /**
@@ -540,7 +562,12 @@
      * @return True if the current thread is holding an active connection to the database.
      */
     public boolean isDbLockedByCurrentThread() {
-        return getThreadSession().hasConnection();
+        acquireReference();
+        try {
+            return getThreadSession().hasConnection();
+        } finally {
+            releaseReference();
+        }
     }
 
     /**
@@ -599,7 +626,12 @@
     }
 
     private boolean yieldIfContendedHelper(boolean throwIfUnsafe, long sleepAfterYieldDelay) {
-        return getThreadSession().yieldTransaction(sleepAfterYieldDelay, throwIfUnsafe, null);
+        acquireReference();
+        try {
+            return getThreadSession().yieldTransaction(sleepAfterYieldDelay, throwIfUnsafe, null);
+        } finally {
+            releaseReference();
+        }
     }
 
     /**
@@ -788,13 +820,6 @@
     }
 
     /**
-     * Close the database.
-     */
-    public void close() {
-        dispose(false);
-    }
-
-    /**
      * Registers a CustomFunction callback as a function that can be called from
      * SQLite database triggers.
      *
@@ -948,8 +973,12 @@
      * {@link SQLiteStatement}s are not synchronized, see the documentation for more details.
      */
     public SQLiteStatement compileStatement(String sql) throws SQLException {
-        throwIfNotOpen(); // fail fast
-        return new SQLiteStatement(this, sql, null);
+        acquireReference();
+        try {
+            return new SQLiteStatement(this, sql, null);
+        } finally {
+            releaseReference();
+        }
     }
 
     /**
@@ -1110,12 +1139,16 @@
             boolean distinct, String table, String[] columns,
             String selection, String[] selectionArgs, String groupBy,
             String having, String orderBy, String limit, CancellationSignal cancellationSignal) {
-        throwIfNotOpen(); // fail fast
-        String sql = SQLiteQueryBuilder.buildQueryString(
-                distinct, table, columns, selection, groupBy, having, orderBy, limit);
+        acquireReference();
+        try {
+            String sql = SQLiteQueryBuilder.buildQueryString(
+                    distinct, table, columns, selection, groupBy, having, orderBy, limit);
 
-        return rawQueryWithFactory(cursorFactory, sql, selectionArgs,
-                findEditTable(table), cancellationSignal);
+            return rawQueryWithFactory(cursorFactory, sql, selectionArgs,
+                    findEditTable(table), cancellationSignal);
+        } finally {
+            releaseReference();
+        }
     }
 
     /**
@@ -1260,12 +1293,15 @@
     public Cursor rawQueryWithFactory(
             CursorFactory cursorFactory, String sql, String[] selectionArgs,
             String editTable, CancellationSignal cancellationSignal) {
-        throwIfNotOpen(); // fail fast
-
-        SQLiteCursorDriver driver = new SQLiteDirectCursorDriver(this, sql, editTable,
-                cancellationSignal);
-        return driver.query(cursorFactory != null ? cursorFactory : mCursorFactory,
-                selectionArgs);
+        acquireReference();
+        try {
+            SQLiteCursorDriver driver = new SQLiteDirectCursorDriver(this, sql, editTable,
+                    cancellationSignal);
+            return driver.query(cursorFactory != null ? cursorFactory : mCursorFactory,
+                    selectionArgs);
+        } finally {
+            releaseReference();
+        }
     }
 
     /**
@@ -1384,38 +1420,44 @@
      */
     public long insertWithOnConflict(String table, String nullColumnHack,
             ContentValues initialValues, int conflictAlgorithm) {
-        StringBuilder sql = new StringBuilder();
-        sql.append("INSERT");
-        sql.append(CONFLICT_VALUES[conflictAlgorithm]);
-        sql.append(" INTO ");
-        sql.append(table);
-        sql.append('(');
+        acquireReference();
+        try {
+            StringBuilder sql = new StringBuilder();
+            sql.append("INSERT");
+            sql.append(CONFLICT_VALUES[conflictAlgorithm]);
+            sql.append(" INTO ");
+            sql.append(table);
+            sql.append('(');
 
-        Object[] bindArgs = null;
-        int size = (initialValues != null && initialValues.size() > 0) ? initialValues.size() : 0;
-        if (size > 0) {
-            bindArgs = new Object[size];
-            int i = 0;
-            for (String colName : initialValues.keySet()) {
-                sql.append((i > 0) ? "," : "");
-                sql.append(colName);
-                bindArgs[i++] = initialValues.get(colName);
+            Object[] bindArgs = null;
+            int size = (initialValues != null && initialValues.size() > 0)
+                    ? initialValues.size() : 0;
+            if (size > 0) {
+                bindArgs = new Object[size];
+                int i = 0;
+                for (String colName : initialValues.keySet()) {
+                    sql.append((i > 0) ? "," : "");
+                    sql.append(colName);
+                    bindArgs[i++] = initialValues.get(colName);
+                }
+                sql.append(')');
+                sql.append(" VALUES (");
+                for (i = 0; i < size; i++) {
+                    sql.append((i > 0) ? ",?" : "?");
+                }
+            } else {
+                sql.append(nullColumnHack + ") VALUES (NULL");
             }
             sql.append(')');
-            sql.append(" VALUES (");
-            for (i = 0; i < size; i++) {
-                sql.append((i > 0) ? ",?" : "?");
-            }
-        } else {
-            sql.append(nullColumnHack + ") VALUES (NULL");
-        }
-        sql.append(')');
 
-        SQLiteStatement statement = new SQLiteStatement(this, sql.toString(), bindArgs);
-        try {
-            return statement.executeInsert();
+            SQLiteStatement statement = new SQLiteStatement(this, sql.toString(), bindArgs);
+            try {
+                return statement.executeInsert();
+            } finally {
+                statement.close();
+            }
         } finally {
-            statement.close();
+            releaseReference();
         }
     }
 
@@ -1430,12 +1472,17 @@
      *         whereClause.
      */
     public int delete(String table, String whereClause, String[] whereArgs) {
-        SQLiteStatement statement =  new SQLiteStatement(this, "DELETE FROM " + table +
-                (!TextUtils.isEmpty(whereClause) ? " WHERE " + whereClause : ""), whereArgs);
+        acquireReference();
         try {
-            return statement.executeUpdateDelete();
+            SQLiteStatement statement =  new SQLiteStatement(this, "DELETE FROM " + table +
+                    (!TextUtils.isEmpty(whereClause) ? " WHERE " + whereClause : ""), whereArgs);
+            try {
+                return statement.executeUpdateDelete();
+            } finally {
+                statement.close();
+            }
         } finally {
-            statement.close();
+            releaseReference();
         }
     }
 
@@ -1470,38 +1517,43 @@
             throw new IllegalArgumentException("Empty values");
         }
 
-        StringBuilder sql = new StringBuilder(120);
-        sql.append("UPDATE ");
-        sql.append(CONFLICT_VALUES[conflictAlgorithm]);
-        sql.append(table);
-        sql.append(" SET ");
-
-        // move all bind args to one array
-        int setValuesSize = values.size();
-        int bindArgsSize = (whereArgs == null) ? setValuesSize : (setValuesSize + whereArgs.length);
-        Object[] bindArgs = new Object[bindArgsSize];
-        int i = 0;
-        for (String colName : values.keySet()) {
-            sql.append((i > 0) ? "," : "");
-            sql.append(colName);
-            bindArgs[i++] = values.get(colName);
-            sql.append("=?");
-        }
-        if (whereArgs != null) {
-            for (i = setValuesSize; i < bindArgsSize; i++) {
-                bindArgs[i] = whereArgs[i - setValuesSize];
-            }
-        }
-        if (!TextUtils.isEmpty(whereClause)) {
-            sql.append(" WHERE ");
-            sql.append(whereClause);
-        }
-
-        SQLiteStatement statement = new SQLiteStatement(this, sql.toString(), bindArgs);
+        acquireReference();
         try {
-            return statement.executeUpdateDelete();
+            StringBuilder sql = new StringBuilder(120);
+            sql.append("UPDATE ");
+            sql.append(CONFLICT_VALUES[conflictAlgorithm]);
+            sql.append(table);
+            sql.append(" SET ");
+
+            // move all bind args to one array
+            int setValuesSize = values.size();
+            int bindArgsSize = (whereArgs == null) ? setValuesSize : (setValuesSize + whereArgs.length);
+            Object[] bindArgs = new Object[bindArgsSize];
+            int i = 0;
+            for (String colName : values.keySet()) {
+                sql.append((i > 0) ? "," : "");
+                sql.append(colName);
+                bindArgs[i++] = values.get(colName);
+                sql.append("=?");
+            }
+            if (whereArgs != null) {
+                for (i = setValuesSize; i < bindArgsSize; i++) {
+                    bindArgs[i] = whereArgs[i - setValuesSize];
+                }
+            }
+            if (!TextUtils.isEmpty(whereClause)) {
+                sql.append(" WHERE ");
+                sql.append(whereClause);
+            }
+
+            SQLiteStatement statement = new SQLiteStatement(this, sql.toString(), bindArgs);
+            try {
+                return statement.executeUpdateDelete();
+            } finally {
+                statement.close();
+            }
         } finally {
-            statement.close();
+            releaseReference();
         }
     }
 
@@ -1579,24 +1631,29 @@
     }
 
     private int executeSql(String sql, Object[] bindArgs) throws SQLException {
-        if (DatabaseUtils.getSqlStatementType(sql) == DatabaseUtils.STATEMENT_ATTACH) {
-            boolean disableWal = false;
-            synchronized (mLock) {
-                if (!mHasAttachedDbsLocked) {
-                    mHasAttachedDbsLocked = true;
-                    disableWal = true;
+        acquireReference();
+        try {
+            if (DatabaseUtils.getSqlStatementType(sql) == DatabaseUtils.STATEMENT_ATTACH) {
+                boolean disableWal = false;
+                synchronized (mLock) {
+                    if (!mHasAttachedDbsLocked) {
+                        mHasAttachedDbsLocked = true;
+                        disableWal = true;
+                    }
+                }
+                if (disableWal) {
+                    disableWriteAheadLogging();
                 }
             }
-            if (disableWal) {
-                disableWriteAheadLogging();
-            }
-        }
 
-        SQLiteStatement statement = new SQLiteStatement(this, sql, bindArgs);
-        try {
-            return statement.executeUpdateDelete();
+            SQLiteStatement statement = new SQLiteStatement(this, sql, bindArgs);
+            try {
+                return statement.executeUpdateDelete();
+            } finally {
+                statement.close();
+            }
         } finally {
-            statement.close();
+            releaseReference();
         }
     }
 
@@ -1881,26 +1938,32 @@
                 attachedDbs.add(new Pair<String, String>("main", mConfigurationLocked.path));
                 return attachedDbs;
             }
+
+            acquireReference();
         }
 
-        // has attached databases. query sqlite to get the list of attached databases.
-        Cursor c = null;
         try {
-            c = rawQuery("pragma database_list;", null);
-            while (c.moveToNext()) {
-                // sqlite returns a row for each database in the returned list of databases.
-                //   in each row,
-                //       1st column is the database name such as main, or the database
-                //                              name specified on the "ATTACH" command
-                //       2nd column is the database file path.
-                attachedDbs.add(new Pair<String, String>(c.getString(1), c.getString(2)));
+            // has attached databases. query sqlite to get the list of attached databases.
+            Cursor c = null;
+            try {
+                c = rawQuery("pragma database_list;", null);
+                while (c.moveToNext()) {
+                    // sqlite returns a row for each database in the returned list of databases.
+                    //   in each row,
+                    //       1st column is the database name such as main, or the database
+                    //                              name specified on the "ATTACH" command
+                    //       2nd column is the database file path.
+                    attachedDbs.add(new Pair<String, String>(c.getString(1), c.getString(2)));
+                }
+            } finally {
+                if (c != null) {
+                    c.close();
+                }
             }
+            return attachedDbs;
         } finally {
-            if (c != null) {
-                c.close();
-            }
+            releaseReference();
         }
-        return attachedDbs;
     }
 
     /**
@@ -1917,35 +1980,38 @@
      * false otherwise.
      */
     public boolean isDatabaseIntegrityOk() {
-        throwIfNotOpen(); // fail fast
-
-        List<Pair<String, String>> attachedDbs = null;
+        acquireReference();
         try {
-            attachedDbs = getAttachedDbs();
-            if (attachedDbs == null) {
-                throw new IllegalStateException("databaselist for: " + getPath() + " couldn't " +
-                        "be retrieved. probably because the database is closed");
-            }
-        } catch (SQLiteException e) {
-            // can't get attachedDb list. do integrity check on the main database
-            attachedDbs = new ArrayList<Pair<String, String>>();
-            attachedDbs.add(new Pair<String, String>("main", getPath()));
-        }
-
-        for (int i = 0; i < attachedDbs.size(); i++) {
-            Pair<String, String> p = attachedDbs.get(i);
-            SQLiteStatement prog = null;
+            List<Pair<String, String>> attachedDbs = null;
             try {
-                prog = compileStatement("PRAGMA " + p.first + ".integrity_check(1);");
-                String rslt = prog.simpleQueryForString();
-                if (!rslt.equalsIgnoreCase("ok")) {
-                    // integrity_checker failed on main or attached databases
-                    Log.e(TAG, "PRAGMA integrity_check on " + p.second + " returned: " + rslt);
-                    return false;
+                attachedDbs = getAttachedDbs();
+                if (attachedDbs == null) {
+                    throw new IllegalStateException("databaselist for: " + getPath() + " couldn't " +
+                            "be retrieved. probably because the database is closed");
                 }
-            } finally {
-                if (prog != null) prog.close();
+            } catch (SQLiteException e) {
+                // can't get attachedDb list. do integrity check on the main database
+                attachedDbs = new ArrayList<Pair<String, String>>();
+                attachedDbs.add(new Pair<String, String>("main", getPath()));
             }
+
+            for (int i = 0; i < attachedDbs.size(); i++) {
+                Pair<String, String> p = attachedDbs.get(i);
+                SQLiteStatement prog = null;
+                try {
+                    prog = compileStatement("PRAGMA " + p.first + ".integrity_check(1);");
+                    String rslt = prog.simpleQueryForString();
+                    if (!rslt.equalsIgnoreCase("ok")) {
+                        // integrity_checker failed on main or attached databases
+                        Log.e(TAG, "PRAGMA integrity_check on " + p.second + " returned: " + rslt);
+                        return false;
+                    }
+                } finally {
+                    if (prog != null) prog.close();
+                }
+            }
+        } finally {
+            releaseReference();
         }
         return true;
     }
@@ -1955,12 +2021,6 @@
         return "SQLiteDatabase: " + getPath();
     }
 
-    private void throwIfNotOpen() {
-        synchronized (mConnectionPoolLocked) {
-            throwIfNotOpenLocked();
-        }
-    }
-
     private void throwIfNotOpenLocked() {
         if (mConnectionPoolLocked == null) {
             throw new IllegalStateException("The database '" + mConfigurationLocked.label
diff --git a/core/java/android/database/sqlite/SQLiteProgram.java b/core/java/android/database/sqlite/SQLiteProgram.java
index 9f0edfb..94a23cb 100644
--- a/core/java/android/database/sqlite/SQLiteProgram.java
+++ b/core/java/android/database/sqlite/SQLiteProgram.java
@@ -190,13 +190,6 @@
     }
 
     /**
-     * Release this program's resources, making it invalid.
-     */
-    public void close() {
-        releaseReference();
-    }
-
-    /**
      * Given an array of String bindArgs, this method binds all of them in one single call.
      *
      * @param bindArgs the String array of bind args, none of which must be null.
diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java
index cca208a..573e6ea 100644
--- a/core/java/android/hardware/Camera.java
+++ b/core/java/android/hardware/Camera.java
@@ -36,7 +36,6 @@
 import java.util.List;
 import java.util.StringTokenizer;
 
-
 /**
  * The Camera class is used to set image capture settings, start/stop preview,
  * snap pictures, and retrieve frames for encoding for video.  This class is a
diff --git a/core/java/android/hardware/CameraSound.java b/core/java/android/hardware/CameraSound.java
deleted file mode 100644
index dc97ff09..0000000
--- a/core/java/android/hardware/CameraSound.java
+++ /dev/null
@@ -1,217 +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.
- */
-
-package android.hardware;
-
-import android.media.AudioManager;
-import android.media.MediaPlayer;
-import android.os.SystemProperties;
-import android.util.Log;
-
-import java.io.IOException;
-
-/**
- * <p>Use this class to play an appropriate sound when implementing a custom
- * still or video recording mechanism through the preview callbacks.</p>
- *
- * <p>There is no need to play sounds when using {@link #android.hardware.Camera#takePicture}
- * or {@link android.media.MediaRecorder} for still images or video,
- * respectively, as these play their own sounds when needed.</p>
- *
- * @hide
- */
-public class CameraSound {
-    private static final String TAG = "CameraSound";
-    /**
-     * The sound used by {@link android.hardware.Camera#takePicture} to
-     * indicate still image capture.
-     */
-    public static final int SHUTTER_CLICK         = 0;
-
-    /**
-     * A sound to indicate that focusing has completed. Because deciding
-     * when this occurs is application-dependent, this sound is not used by
-     * any methods in the Camera class.
-     */
-    public static final int FOCUS_COMPLETE        = 1;
-
-    /**
-     * The sound used by {@link android.media.MediaRecorder#start} to
-     * indicate the start of video recording.
-     */
-    public static final int START_VIDEO_RECORDING = 2;
-
-    /**
-     * The sound used by {@link android.media.MediaRecorder#stop} to
-     * indicate the end of video recording.
-     */
-    public static final int STOP_VIDEO_RECORDING  = 3;
-
-    private static final int NUM_SOUNDS           = 4;
-    private CameraSoundPlayer[] mCameraSoundPlayers;
-
-    public CameraSound() {
-    }
-
-    /**
-     * <p>Play one of the predefined platform sounds for camera actions.</p>
-     *
-     * <p>Use this method to play a platform-specific sound for various camera
-     * actions. The sound playing is done asynchronously, with the same behavior
-     * and content as the sounds played by {@link #takePicture takePicture},
-     * {@link android.media.MediaRecorder#start MediaRecorder.start}, and
-     * {@link android.media.MediaRecorder#stop MediaRecorder.stop}.</p>
-     *
-     * <p>Using this method makes it easy to match the default device sounds
-     * when recording or capturing data through the preview callbacks.</p>
-     *
-     * @param soundId The type of sound to play, selected from SHUTTER_CLICK,
-     *         FOCUS_COMPLETE, START_VIDEO_RECORDING, or STOP_VIDEO_RECORDING.
-     * @see android.hardware#takePicture
-     * @see android.media.MediaRecorder
-     * @see #SHUTTER_CLICK
-     * @see #FOCUS_COMPLETE
-     * @see #START_VIDEO_RECORDING
-     * @see #STOP_VIDEO_RECORDING
-     */
-    public void playSound(int soundId) {
-        if (mCameraSoundPlayers == null) {
-            mCameraSoundPlayers = new CameraSoundPlayer[NUM_SOUNDS];
-        }
-        if (mCameraSoundPlayers[soundId] == null) {
-            mCameraSoundPlayers[soundId] = new CameraSoundPlayer(soundId);
-        }
-        mCameraSoundPlayers[soundId].play();
-    }
-
-    public void release() {
-        if (mCameraSoundPlayers != null) {
-            for (CameraSoundPlayer csp: mCameraSoundPlayers) {
-                if (csp != null) {
-                    csp.release();
-                }
-            }
-            mCameraSoundPlayers = null;
-        }
-    }
-
-    private static class CameraSoundPlayer implements Runnable {
-        private int mSoundId;
-        private MediaPlayer mPlayer;
-        private Thread mThread;
-        private boolean mExit;
-        private int mPlayCount;
-
-        private static final String mShutterSound    =
-                "/system/media/audio/ui/camera_click.ogg";
-        private static final String mFocusSound      =
-                "/system/media/audio/ui/camera_focus.ogg";
-        private static final String mVideoStartSound =
-                "/system/media/audio/ui/VideoRecord.ogg";
-        private static final String mVideoStopSound  =
-                "/system/media/audio/ui/VideoRecord.ogg";
-
-        @Override
-        public void run() {
-            String soundFilePath;
-            switch (mSoundId) {
-                case SHUTTER_CLICK:
-                    soundFilePath = mShutterSound;
-                    break;
-                case FOCUS_COMPLETE:
-                    soundFilePath = mFocusSound;
-                    break;
-                case START_VIDEO_RECORDING:
-                    soundFilePath = mVideoStartSound;
-                    break;
-                case STOP_VIDEO_RECORDING:
-                    soundFilePath = mVideoStopSound;
-                    break;
-                default:
-                    Log.e(TAG, "Unknown sound " + mSoundId + " requested.");
-                    return;
-            }
-            mPlayer = new MediaPlayer();
-            try {
-                mPlayer.setAudioStreamType(AudioManager.STREAM_SYSTEM_ENFORCED);
-                mPlayer.setDataSource(soundFilePath);
-                mPlayer.setLooping(false);
-                mPlayer.prepare();
-            } catch(IOException e) {
-                Log.e(TAG, "Error setting up sound " + mSoundId, e);
-                return;
-            }
-
-            while(true) {
-                try {
-                    synchronized (this) {
-                        while(true) {
-                            if (mExit) {
-                                return;
-                            } else if (mPlayCount <= 0) {
-                                wait();
-                            } else {
-                                mPlayCount--;
-                                break;
-                            }
-                        }
-                    }
-                    mPlayer.start();
-                } catch (Exception e) {
-                    Log.e(TAG, "Error playing sound " + mSoundId, e);
-                }
-            }
-        }
-
-        public CameraSoundPlayer(int soundId) {
-            mSoundId = soundId;
-        }
-
-        public void play() {
-            if (mThread == null) {
-                mThread = new Thread(this);
-                mThread.start();
-            }
-            synchronized (this) {
-                mPlayCount++;
-                notifyAll();
-            }
-        }
-
-        public void release() {
-            if (mThread != null) {
-                synchronized (this) {
-                    mExit = true;
-                    notifyAll();
-                }
-                try {
-                    mThread.join();
-                } catch (InterruptedException e) {
-                }
-                mThread = null;
-            }
-            if (mPlayer != null) {
-                mPlayer.release();
-                mPlayer = null;
-            }
-        }
-
-        @Override
-        protected void finalize() {
-            release();
-        }
-    }
-}
\ No newline at end of file
diff --git a/core/java/android/view/HardwareLayer.java b/core/java/android/view/HardwareLayer.java
index 49450bd..a97167b 100644
--- a/core/java/android/view/HardwareLayer.java
+++ b/core/java/android/view/HardwareLayer.java
@@ -167,7 +167,7 @@
 
     /**
      * Specifies the display list to use to refresh the layer.
-     * 
+     *
      * @param displayList The display list containing the drawing commands to
      *                    execute in this layer
      * @param dirtyRect The dirty region of the layer that needs to be redrawn
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java
index ec95863..bf91700 100644
--- a/core/java/android/view/HardwareRenderer.java
+++ b/core/java/android/view/HardwareRenderer.java
@@ -1284,15 +1284,10 @@
                 usePbufferSurface(managedContext.getContext());
             }
 
-            switch (level) {
-                case ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN:
-                case ComponentCallbacks2.TRIM_MEMORY_BACKGROUND:
-                case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
-                    GLES20Canvas.flushCaches(GLES20Canvas.FLUSH_CACHES_MODERATE);
-                    break;
-                case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
-                    GLES20Canvas.flushCaches(GLES20Canvas.FLUSH_CACHES_FULL);
-                    break;
+            if (level >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE) {
+                GLES20Canvas.flushCaches(GLES20Canvas.FLUSH_CACHES_FULL);
+            } else if (level >= ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) {
+                GLES20Canvas.flushCaches(GLES20Canvas.FLUSH_CACHES_MODERATE);
             }
         }
 
diff --git a/core/java/android/view/TextureView.java b/core/java/android/view/TextureView.java
index c1e9946..fc02cc1 100644
--- a/core/java/android/view/TextureView.java
+++ b/core/java/android/view/TextureView.java
@@ -315,7 +315,7 @@
     }
 
     @Override
-    HardwareLayer getHardwareLayer(boolean immediateRefresh) {
+    HardwareLayer getHardwareLayer() {
         if (mLayer == null) {
             if (mAttachInfo == null || mAttachInfo.mHardwareRenderer == null) {
                 return null;
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index ecfca74..9457067 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -5247,6 +5247,7 @@
                 if (mNextFocusForwardId == View.NO_ID) return null;
                 return findViewInsideOutShouldExist(root, mNextFocusForwardId);
             case FOCUS_BACKWARD: {
+                if (mID == View.NO_ID) return null;
                 final int id = mID;
                 return root.findViewByPredicateInsideOut(this, new Predicate<View>() {
                     @Override
@@ -10220,7 +10221,7 @@
                 if (mAttachInfo.mHardwareRenderer != null &&
                         mAttachInfo.mHardwareRenderer.isEnabled() &&
                         mAttachInfo.mHardwareRenderer.validate()) {
-                    getHardwareLayer(true);
+                    getHardwareLayer();
                 }
                 break;
             case LAYER_TYPE_SOFTWARE:
@@ -10242,7 +10243,7 @@
      *
      * @return A HardwareLayer ready to render, or null if an error occurred.
      */
-    HardwareLayer getHardwareLayer(boolean immediateRefresh) {
+    HardwareLayer getHardwareLayer() {
         if (mAttachInfo == null || mAttachInfo.mHardwareRenderer == null ||
                 !mAttachInfo.mHardwareRenderer.isEnabled()) {
             return null;
@@ -10272,33 +10273,8 @@
                 return null;
             }
 
-            if (!immediateRefresh) {
-                mHardwareLayer.redraw(getDisplayList(), mLocalDirtyRect);
-                mLocalDirtyRect.setEmpty();
-            } else {
-                HardwareCanvas currentCanvas = mAttachInfo.mHardwareCanvas;
-                final HardwareCanvas canvas = mHardwareLayer.start(currentCanvas);
-    
-                // Make sure all the GPU resources have been properly allocated
-                if (canvas == null) {
-                    mHardwareLayer.end(currentCanvas);
-                    return null;
-                }
-    
-                mAttachInfo.mHardwareCanvas = canvas;
-                try {
-                    canvas.setViewport(width, height);
-                    canvas.onPreDraw(mLocalDirtyRect);
-                    mLocalDirtyRect.setEmpty();
-                    
-                    canvas.drawDisplayList(getDisplayList(), mRight - mLeft, mBottom - mTop, null,
-                            DisplayList.FLAG_CLIP_CHILDREN);
-                } finally {
-                    canvas.onPostDraw();
-                    mHardwareLayer.end(currentCanvas);
-                    mAttachInfo.mHardwareCanvas = currentCanvas;
-                }
-            }
+            mHardwareLayer.redraw(getDisplayList(), mLocalDirtyRect);
+            mLocalDirtyRect.setEmpty();
         }
 
         return mHardwareLayer;
@@ -11265,7 +11241,7 @@
         if (hasNoCache) {
             boolean layerRendered = false;
             if (layerType == LAYER_TYPE_HARDWARE) {
-                final HardwareLayer layer = getHardwareLayer(false);
+                final HardwareLayer layer = getHardwareLayer();
                 if (layer != null && layer.isValid()) {
                     mLayerPaint.setAlpha((int) (alpha * 255));
                     ((HardwareCanvas) canvas).drawHardwareLayer(layer, 0, 0, mLayerPaint);
diff --git a/core/java/android/view/WindowManagerImpl.java b/core/java/android/view/WindowManagerImpl.java
index d482b35..0e4a30f 100644
--- a/core/java/android/view/WindowManagerImpl.java
+++ b/core/java/android/view/WindowManagerImpl.java
@@ -432,29 +432,25 @@
      */
     public void trimMemory(int level) {
         if (HardwareRenderer.isAvailable()) {
-            switch (level) {
-                case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
-                case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
-                    // On low and medium end gfx devices
-                    if (!ActivityManager.isHighEndGfx(getDefaultDisplay())) {
-                        // Destroy all hardware surfaces and resources associated to
-                        // known windows
-                        synchronized (this) {
-                            if (mViews == null) return;
-                            int count = mViews.length;
-                            for (int i = 0; i < count; i++) {
-                                mRoots[i].terminateHardwareResources();
-                            }
+            // On low and medium end gfx devices
+            if (!ActivityManager.isHighEndGfx(getDefaultDisplay())) {
+                if (level >= ComponentCallbacks2.TRIM_MEMORY_MODERATE) {
+                    // Destroy all hardware surfaces and resources associated to
+                    // known windows
+                    synchronized (this) {
+                        if (mViews == null) return;
+                        int count = mViews.length;
+                        for (int i = 0; i < count; i++) {
+                            mRoots[i].terminateHardwareResources();
                         }
-                        // Force a full memory flush
-                        HardwareRenderer.trimMemory(ComponentCallbacks2.TRIM_MEMORY_COMPLETE);
-                        mNeedsEglTerminate = true;
-                        break;
                     }
-                    // high end gfx devices fall through to next case
-                default:
-                    HardwareRenderer.trimMemory(level);
+                    // Force a full memory flush
+                    HardwareRenderer.trimMemory(ComponentCallbacks2.TRIM_MEMORY_COMPLETE);
+                    mNeedsEglTerminate = true;
+                    return;
+                }
             }
+            HardwareRenderer.trimMemory(level);
         }
     }
 
diff --git a/core/java/android/webkit/WebViewClassic.java b/core/java/android/webkit/WebViewClassic.java
index c9a3ff1..4b47537 100644
--- a/core/java/android/webkit/WebViewClassic.java
+++ b/core/java/android/webkit/WebViewClassic.java
@@ -1121,7 +1121,7 @@
     static final int WEBCORE_INITIALIZED_MSG_ID         = 107;
     static final int UPDATE_TEXTFIELD_TEXT_MSG_ID       = 108;
     static final int UPDATE_ZOOM_RANGE                  = 109;
-    static final int UNHANDLED_NAV_KEY                  = 110;
+    static final int TAKE_FOCUS                         = 110;
     static final int CLEAR_TEXT_ENTRY                   = 111;
     static final int UPDATE_TEXT_SELECTION_MSG_ID       = 112;
     static final int SHOW_RECT_MSG_ID                   = 113;
@@ -4925,9 +4925,7 @@
         if (layer == 0 || isPictureAfterFirstLayout) {
             mWebViewCore.resumeWebKitDraw();
         } else if (queueFull) {
-            // temporarily disable webkit draw throttling
-            // TODO: re-enable
-            // mWebViewCore.pauseWebKitDraw();
+            mWebViewCore.pauseWebKitDraw();
         }
 
         if (mHTML5VideoViewProxy != null) {
@@ -5309,8 +5307,6 @@
         if (keyCode >= KeyEvent.KEYCODE_DPAD_UP
                 && keyCode <= KeyEvent.KEYCODE_DPAD_RIGHT) {
             switchOutDrawHistory();
-            letPageHandleNavKey(keyCode, event.getEventTime(), true, event.getMetaState());
-            return true;
         }
 
         if (isEnterActionKey(keyCode)) {
@@ -5342,7 +5338,7 @@
         }
 
         // pass the key to DOM
-        mWebViewCore.sendMessage(EventHub.KEY_DOWN, event);
+        sendKeyEvent(event);
         // return true as DOM handles the key
         return true;
     }
@@ -5405,12 +5401,6 @@
             }
         }
 
-        if (keyCode >= KeyEvent.KEYCODE_DPAD_UP
-                && keyCode <= KeyEvent.KEYCODE_DPAD_RIGHT) {
-            letPageHandleNavKey(keyCode, event.getEventTime(), false, event.getMetaState());
-            return true;
-        }
-
         if (isEnterActionKey(keyCode)) {
             // remove the long press message first
             mPrivateHandler.removeMessages(LONG_PRESS_CENTER);
@@ -5424,7 +5414,7 @@
         }
 
         // pass the key to DOM
-        mWebViewCore.sendMessage(EventHub.KEY_UP, event);
+        sendKeyEvent(event);
         // return true as DOM handles the key
         return true;
     }
@@ -5757,6 +5747,9 @@
             setFocusControllerActive(false);
             mKeysPressed.clear();
         }
+        if (!mTouchHighlightRegion.isEmpty()) {
+            mWebView.invalidate(mTouchHighlightRegion.getBounds());
+        }
     }
 
     void setGLRectViewport() {
@@ -5968,6 +5961,10 @@
             return false;
         }
 
+        if (!mWebView.isFocused()) {
+            mWebView.requestFocus();
+        }
+
         if (DebugFlags.WEB_VIEW) {
             Log.v(LOGTAG, ev + " at " + ev.getEventTime()
                 + " mTouchMode=" + mTouchMode
@@ -6357,7 +6354,6 @@
                 break;
             }
             case MotionEvent.ACTION_UP: {
-                if (!mWebView.isFocused()) mWebView.requestFocus();
                 // pass the touch events from UI thread to WebCore thread
                 if (shouldForwardTouchEvent()) {
                     TouchEventData ted = new TouchEventData();
@@ -6956,9 +6952,7 @@
             case KeyEvent.KEYCODE_DPAD_LEFT:
                 return SoundEffectConstants.NAVIGATION_LEFT;
         }
-        throw new IllegalArgumentException("keyCode must be one of " +
-                "{KEYCODE_DPAD_UP, KEYCODE_DPAD_RIGHT, KEYCODE_DPAD_DOWN, " +
-                "KEYCODE_DPAD_LEFT}.");
+        return 0;
     }
 
     private void doTrackball(long time, int metaState) {
@@ -8232,8 +8226,12 @@
                 case FORM_DID_BLUR:
                     // TODO: Figure out if this is needed for something (b/6111763)
                     break;
-                case UNHANDLED_NAV_KEY:
-                    // TODO: Support this (b/6109044)
+                case TAKE_FOCUS:
+                    int direction = msg.arg1;
+                    View focusSearch = mWebView.focusSearch(direction);
+                    if (focusSearch != null && focusSearch != mWebView) {
+                        focusSearch.requestFocus();
+                    }
                     break;
                 case CLEAR_TEXT_ENTRY:
                     hideSoftKeyboard();
@@ -8527,9 +8525,9 @@
             return false;
         }
         if (mFocusedNode.mHasFocus && !mWebView.isInTouchMode()) {
-            return !mFocusedNode.mEditable;
+            return mDrawCursorRing && !mFocusedNode.mEditable;
         }
-        if (mInitialHitTestResult.getType() == HitTestResult.UNKNOWN_TYPE) {
+        if (mFocusedNode.mHasFocus && mFocusedNode.mEditable) {
             return false;
         }
         long delay = System.currentTimeMillis() - mTouchHighlightRequested;
@@ -9129,14 +9127,10 @@
      */
     private void letPageHandleNavKey(int keyCode, long time, boolean down, int metaState) {
         int keyEventAction;
-        int eventHubAction;
         if (down) {
             keyEventAction = KeyEvent.ACTION_DOWN;
-            eventHubAction = EventHub.KEY_DOWN;
-            mWebView.playSoundEffect(keyCodeToSoundsEffect(keyCode));
         } else {
             keyEventAction = KeyEvent.ACTION_UP;
-            eventHubAction = EventHub.KEY_UP;
         }
 
         KeyEvent event = new KeyEvent(time, time, keyEventAction, keyCode,
@@ -9144,7 +9138,41 @@
                 | (metaState & KeyEvent.META_ALT_ON)
                 | (metaState & KeyEvent.META_SYM_ON)
                 , KeyCharacterMap.VIRTUAL_KEYBOARD, 0, 0);
-        mWebViewCore.sendMessage(eventHubAction, event);
+        sendKeyEvent(event);
+    }
+
+    private void sendKeyEvent(KeyEvent event) {
+        int direction = 0;
+        switch (event.getKeyCode()) {
+        case KeyEvent.KEYCODE_DPAD_DOWN:
+            direction = View.FOCUS_DOWN;
+            break;
+        case KeyEvent.KEYCODE_DPAD_UP:
+            direction = View.FOCUS_UP;
+            break;
+        case KeyEvent.KEYCODE_DPAD_LEFT:
+            direction = View.FOCUS_LEFT;
+            break;
+        case KeyEvent.KEYCODE_DPAD_RIGHT:
+            direction = View.FOCUS_RIGHT;
+            break;
+        case KeyEvent.KEYCODE_TAB:
+            direction = event.isShiftPressed() ? View.FOCUS_BACKWARD : View.FOCUS_FORWARD;
+            break;
+        }
+        if (direction != 0 && mWebView.focusSearch(direction) == null) {
+            // Can't take focus in that direction
+            direction = 0;
+        }
+        int eventHubAction = EventHub.KEY_UP;
+        if (event.getAction() == KeyEvent.ACTION_DOWN) {
+            eventHubAction = EventHub.KEY_DOWN;
+            int sound = keyCodeToSoundsEffect(event.getKeyCode());
+            if (sound != 0) {
+                mWebView.playSoundEffect(sound);
+            }
+        }
+        mWebViewCore.sendMessage(eventHubAction, direction, event);
     }
 
     /**
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index 65356f5..09aa286c 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -139,6 +139,8 @@
     private int mHighMemoryUsageThresholdMb;
     private int mHighUsageDeltaMb;
 
+    private int mChromeCanFocusDirection;
+
     // The thread name used to identify the WebCore thread and for use in
     // debugging other classes that require operation within the WebCore thread.
     /* package */ static final String THREAD_NAME = "WebViewCoreThread";
@@ -344,6 +346,58 @@
     }
 
     /**
+     * Called by JNI to advance focus to the next view.
+     */
+    private void chromeTakeFocus(int webkitDirection) {
+        if (mWebView == null) return;
+        Message m = mWebView.mPrivateHandler.obtainMessage(
+                WebViewClassic.TAKE_FOCUS);
+        m.arg1 = mapDirection(webkitDirection);
+        m.sendToTarget();
+    }
+
+    /**
+     * Called by JNI to see if we can take focus in the given direction.
+     */
+    private boolean chromeCanTakeFocus(int webkitDirection) {
+        int direction = mapDirection(webkitDirection);
+        return direction == mChromeCanFocusDirection && direction != 0;
+    }
+
+    /**
+     * Maps a Webkit focus direction to a framework one
+     */
+    private int mapDirection(int webkitDirection) {
+        /*
+         * This is WebKit's FocusDirection enum (from FocusDirection.h)
+        enum FocusDirection {
+            FocusDirectionNone = 0,
+            FocusDirectionForward,
+            FocusDirectionBackward,
+            FocusDirectionUp,
+            FocusDirectionDown,
+            FocusDirectionLeft,
+            FocusDirectionRight
+        };
+         */
+        switch (webkitDirection) {
+        case 1:
+            return View.FOCUS_FORWARD;
+        case 2:
+            return View.FOCUS_BACKWARD;
+        case 3:
+            return View.FOCUS_UP;
+        case 4:
+            return View.FOCUS_DOWN;
+        case 5:
+            return View.FOCUS_LEFT;
+        case 6:
+            return View.FOCUS_RIGHT;
+        }
+        return 0;
+    }
+
+    /**
      * Called by JNI.  Open a file chooser to upload a file.
      * @param acceptType The value of the 'accept' attribute of the
      *         input tag associated with this file picker.
@@ -1311,11 +1365,11 @@
                             break;
 
                         case KEY_DOWN:
-                            key((KeyEvent) msg.obj, true);
+                            key((KeyEvent) msg.obj, msg.arg1, true);
                             break;
 
                         case KEY_UP:
-                            key((KeyEvent) msg.obj, false);
+                            key((KeyEvent) msg.obj, msg.arg1, false);
                             break;
 
                         case KEY_PRESS:
@@ -1950,11 +2004,12 @@
         return mBrowserFrame.saveWebArchive(filename, autoname);
     }
 
-    private void key(KeyEvent evt, boolean isDown) {
+    private void key(KeyEvent evt, int canTakeFocusDirection, boolean isDown) {
         if (DebugFlags.WEB_VIEW_CORE) {
             Log.v(LOGTAG, "CORE key at " + System.currentTimeMillis() + ", "
                     + evt);
         }
+        mChromeCanFocusDirection = canTakeFocusDirection;
         int keyCode = evt.getKeyCode();
         int unicodeChar = evt.getUnicodeChar();
 
@@ -1964,18 +2019,18 @@
             unicodeChar = evt.getCharacters().codePointAt(0);
         }
 
-        if (!nativeKey(mNativeClass, keyCode, unicodeChar, evt.getRepeatCount(),
+        boolean handled = nativeKey(mNativeClass, keyCode, unicodeChar, evt.getRepeatCount(),
                 evt.isShiftPressed(), evt.isAltPressed(),
-                evt.isSymPressed(), isDown) && keyCode != KeyEvent.KEYCODE_ENTER) {
+                evt.isSymPressed(), isDown);
+        mChromeCanFocusDirection = 0;
+        if (!handled && keyCode != KeyEvent.KEYCODE_ENTER) {
             if (keyCode >= KeyEvent.KEYCODE_DPAD_UP
                     && keyCode <= KeyEvent.KEYCODE_DPAD_RIGHT) {
-                if (DebugFlags.WEB_VIEW_CORE) {
-                    Log.v(LOGTAG, "key: arrow unused by page: " + keyCode);
-                }
-                if (mWebView != null && evt.isDown()) {
-                    Message.obtain(mWebView.mPrivateHandler,
-                            WebViewClassic.UNHANDLED_NAV_KEY, keyCode,
-                            0).sendToTarget();
+                if (canTakeFocusDirection != 0 && isDown) {
+                    Message m = mWebView.mPrivateHandler.obtainMessage(
+                            WebViewClassic.TAKE_FOCUS);
+                    m.arg1 = canTakeFocusDirection;
+                    m.sendToTarget();
                 }
                 return;
             }
diff --git a/core/java/com/android/internal/view/menu/ActionMenuPresenter.java b/core/java/com/android/internal/view/menu/ActionMenuPresenter.java
index 530809b..dca45a9 100644
--- a/core/java/com/android/internal/view/menu/ActionMenuPresenter.java
+++ b/core/java/com/android/internal/view/menu/ActionMenuPresenter.java
@@ -116,9 +116,9 @@
         if (!mMaxItemsSet) {
             mMaxItems = mContext.getResources().getInteger(
                     com.android.internal.R.integer.max_action_buttons);
-            if (mMenu != null) {
-                mMenu.onItemsChanged(true);
-            }
+        }
+        if (mMenu != null) {
+            mMenu.onItemsChanged(true);
         }
     }
 
diff --git a/core/java/com/android/internal/widget/ActionBarView.java b/core/java/com/android/internal/widget/ActionBarView.java
index 2f325bf..8c05459 100644
--- a/core/java/com/android/internal/widget/ActionBarView.java
+++ b/core/java/com/android/internal/widget/ActionBarView.java
@@ -324,13 +324,31 @@
                     if (mSplitView != null) {
                         mSplitView.addView(mMenuView);
                     }
+                    mMenuView.getLayoutParams().width = LayoutParams.MATCH_PARENT;
                 } else {
                     addView(mMenuView);
+                    mMenuView.getLayoutParams().width = LayoutParams.WRAP_CONTENT;
                 }
+                mMenuView.requestLayout();
             }
             if (mSplitView != null) {
                 mSplitView.setVisibility(splitActionBar ? VISIBLE : GONE);
             }
+
+            if (mActionMenuPresenter != null) {
+                if (!splitActionBar) {
+                    mActionMenuPresenter.setExpandedActionViewsExclusive(
+                            getResources().getBoolean(
+                                    com.android.internal.R.bool.action_bar_expanded_action_views_exclusive));
+                } else {
+                    mActionMenuPresenter.setExpandedActionViewsExclusive(false);
+                    // Allow full screen width in split mode.
+                    mActionMenuPresenter.setWidthLimit(
+                            getContext().getResources().getDisplayMetrics().widthPixels, true);
+                    // No limit to the item count; use whatever will fit.
+                    mActionMenuPresenter.setItemLimit(Integer.MAX_VALUE);
+                }
+            }
             super.setSplitActionBar(splitActionBar);
         }
     }
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 4900a5d..9ac20fa 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -26,8 +26,7 @@
     <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
     <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
-    <!-- no translation found for fileSizeSuffix (9164292791500531949) -->
-    <skip />
+    <string name="fileSizeSuffix" msgid="9164292791500531949">"<xliff:g id="UNIT">%2$s</xliff:g><xliff:g id="NUMBER">%1$s</xliff:g>"</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;Titelloos&gt;"</string>
     <string name="ellipsis" msgid="7899829516048813237">"…"</string>
     <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
@@ -314,8 +313,8 @@
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"aktiveer of deaktiveer programkomponente"</string>
     <string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Laat die program toe om te verander of \'n komponent van ander program geaktiveer is of nie. Kwaadwillige programme kan dit dalk gebruik om belangrike tabletvermoëns te deaktiveer. Wees versigtig met hierdie toestemming, want dit kan programkomponente tot \'n onbruikbare, inkonsekwente of onstabiele toestand bring."</string>
     <string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Laat die program toe om te verander of \'n komponent van ander program geaktiveer is of nie. Kwaadwillige programme kan dit gebruik om belangrike foonvermoëns te deaktiveer. Wees versigtig met hierdie toestemming, want dit kan programkomponente tot \'n onbruikbare, inkonsekwente of onstabiele toestand bring."</string>
-    <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"toestemmings te verleen of te herroep"</string>
-    <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"Laat \'n program toe om spesifieke toestemmings te verleen of te herroep vir die betrokke program of ander programme. Skadelike programme kan dit gebruik om toegang te verkry tot kenmerke waarvoor jy nie toestemming verleen het nie."</string>
+    <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"verleen of herroep toestemmings"</string>
+    <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"Laat \'n program toe om spesifieke toestemmings te verleen of te herroep vir die betrokke program of ander programme. Kwaadwillige programme kan dit gebruik om toegang te verkry tot kenmerke waarvoor jy nie toestemming verleen het nie."</string>
     <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"stel voorkeurprogramme"</string>
     <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Laat die program toe om jou voorkeur-programme te verander. Kwaadwillige programme kan stilweg die programme wat loop, verander, wat jou bestaande programme bedrieg om private data oor jou in te samel."</string>
     <string name="permlab_writeSettings" msgid="1365523497395143704">"verander globale stelselinstellings"</string>
@@ -672,8 +671,7 @@
     <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Maksimum gesigontsluit-pogings oorskry"</string>
     <string name="lockscreen_plugged_in" msgid="8057762828355572315">"Laai, (<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
     <string name="lockscreen_charged" msgid="4938930459620989972">"Gehef."</string>
-    <!-- no translation found for lockscreen_battery_short (4477264849386850266) -->
-    <skip />
+    <string name="lockscreen_battery_short" msgid="4477264849386850266">"<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
     <string name="lockscreen_low_battery" msgid="1482873981919249740">"Koppel jou herlaaier."</string>
     <string name="lockscreen_missing_sim_message_short" msgid="7381499217732227295">"Geen SIM-kaart."</string>
     <string name="lockscreen_missing_sim_message" product="tablet" msgid="151659196095791474">"Geen SIM-kaart in tablet nie."</string>
@@ -722,10 +720,8 @@
     <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
     <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
     <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
-    <!-- no translation found for hour_ampm (4584338083529355982) -->
-    <skip />
-    <!-- no translation found for hour_cap_ampm (2083465992940444366) -->
-    <skip />
+    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
+    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"Fabriektoets het gefaal"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"Die FACTORY_TEST-handeling word net ondersteun vir pakkette wat in /system/app geïnstalleer is."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"Geen pakket is gevind wat die FACTORY_TEST-handeling bied nie."</string>
@@ -737,8 +733,7 @@
     <string name="double_tap_toast" msgid="4595046515400268881">"Wenk: Dubbeltik om in en uit te zoem."</string>
     <string name="autofill_this_form" msgid="4616758841157816676">"Outovul"</string>
     <string name="setup_autofill" msgid="7103495070180590814">"Stel outovul op"</string>
-    <!-- no translation found for autofill_address_name_separator (6350145154779706772) -->
-    <skip />
+    <string name="autofill_address_name_separator" msgid="6350145154779706772">" "</string>
     <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
     <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
     <string name="autofill_address_summary_format" msgid="4874459455786827344">"$1$2$3"</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index f2538c6..dc74d94 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -341,7 +341,7 @@
     <string name="permdesc_writeProfile" product="default" msgid="4637366723793045603">"ልክ እንደ አንተ ስም እና የዕውቂያ መረጃ ፣ ባንተ መሳሪያ ወስጥ የተከማቹ የግል መገለጫ መረጃ ለመለወጥ ወይም ለማከል ለመተግበሪያው ይፈቅዳሉ፡፡ይሄም ማለት ሌሎች መተግበሪያዎች ሊለዩህ ይችላሉ እና ለሌሎች የመገለጫ መረጃህን ይልካሉ፡፡"</string>
     <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"የአንተን ማህበራዊ የውይይት ክፍሎች አንብብ"</string>
     <string name="permdesc_readSocialStream" product="default" msgid="3419050808547335320">" ከአንተ ጓደኞች ማህበራዊ ዝማኔዎችን እንዲደርስባቸው እና እንዲያመሳስል ለመተግበሪያውይፈቅዳሉ፡፡ ተንኮል አዘል መተግበሪያዎች ይህን መዳረሻ ባንተና በጓደኞችህ መካከል በማህበራዊ አውታረመረቦች ያሉ የግል ተግባቦቶችን ለመዳረስ ሊጠቀሙበት ይችላሉ፡፡"</string>
-    <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"ወደ ያንተ ማህበራዊ የውይይት ክፍሎች ጻፍ"</string>
+    <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"ወደ የአንተ  ማህበራዊ የውይይት ክፍሎች ጻፍ"</string>
     <string name="permdesc_writeSocialStream" product="default" msgid="3496277176955721451">" የጓደኞችህን ማህበራዊ ዝማኔዎችን ለማሳየት ለመተግበሪያው ይፈቅዳሉ፡፡ ተንኮል አዘል መተግበሪያዎች ይህን መዳረሻ ጓደኛ መስለው ለመቅረብ እና የይለፍ ቃልና ሌላ ምስጢራዊ መረጃ እንድትሰጥ ለማድረግ ሊጠቀሙበት ይችላሉ፡፡"</string>
     <string name="permlab_readCalendar" msgid="5972727560257612398">"የቀን መቁጠሪያ ክስተቶች ተጨማሪ ሚስጥራዊ መረጃ አንብብ"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="2338414551004122687">"በጡባዊ ተኮህ ላይ የተከማቹ ሁሉንም የቀን መቁጠሪያ ክስተቶች መተግበሪያዎቹ እንዲያነቡ ይፈቅዳሉ፡፡ ያለ ባለቤቱ እውቅና ከነዚህ የቀን መቁጠሪያዎች የግል መረጃዎችን ጎጂ መተግበሪያዎች ያወጣሉ፡፡"</string>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 3daf33a..c277ee9 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -26,8 +26,7 @@
     <string name="gigabyteShort" msgid="3259882455212193214">"ГБ"</string>
     <string name="terabyteShort" msgid="231613018159186962">"ТБ"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"ПБ"</string>
-    <!-- no translation found for fileSizeSuffix (9164292791500531949) -->
-    <skip />
+    <string name="fileSizeSuffix" msgid="9164292791500531949">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;Без заглавие&gt;"</string>
     <string name="ellipsis" msgid="7899829516048813237">"…"</string>
     <string name="ellipsis_two_dots" msgid="1228078994866030736">".."</string>
@@ -672,8 +671,7 @@
     <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Максималният брой опити за отключване с лице е надвишен"</string>
     <string name="lockscreen_plugged_in" msgid="8057762828355572315">"Зарежда се, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
     <string name="lockscreen_charged" msgid="4938930459620989972">"Зареден."</string>
-    <!-- no translation found for lockscreen_battery_short (4477264849386850266) -->
-    <skip />
+    <string name="lockscreen_battery_short" msgid="4477264849386850266">"<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
     <string name="lockscreen_low_battery" msgid="1482873981919249740">"Свържете зарядното си устройство."</string>
     <string name="lockscreen_missing_sim_message_short" msgid="7381499217732227295">"Няма SIM карта."</string>
     <string name="lockscreen_missing_sim_message" product="tablet" msgid="151659196095791474">"В таблета няма SIM карта."</string>
@@ -722,10 +720,8 @@
     <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
     <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"АБВ"</string>
     <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
-    <!-- no translation found for hour_ampm (4584338083529355982) -->
-    <skip />
-    <!-- no translation found for hour_cap_ampm (2083465992940444366) -->
-    <skip />
+    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
+    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"Фабричният тест не бе успешен"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"Действието FACTORY_TEST се поддържа само за пакети, инсталирани в /system/app."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"Не бе намерен пакет, предоставящ действието FACTORY_TEST."</string>
@@ -737,8 +733,7 @@
     <string name="double_tap_toast" msgid="4595046515400268881">"Съвет: Докоснете двукратно, за да увеличите или намалите мащаба."</string>
     <string name="autofill_this_form" msgid="4616758841157816676">"Автопоп."</string>
     <string name="setup_autofill" msgid="7103495070180590814">"Автопоп.: Настройка"</string>
-    <!-- no translation found for autofill_address_name_separator (6350145154779706772) -->
-    <skip />
+    <string name="autofill_address_name_separator" msgid="6350145154779706772">" "</string>
     <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
     <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
     <string name="autofill_address_summary_format" msgid="4874459455786827344">"$1$2$3"</string>
@@ -773,10 +768,8 @@
     <string name="permdesc_serialPort" msgid="2991639985224598193">"Разрешава на притежателя достъп до серийни портове посредством приложния програмен интерфейс (API) SerialManager."</string>
     <string name="permlab_accessContentProvidersExternally" msgid="5077774297943409285">"външен достъп до доставчиците на съдърж."</string>
     <string name="permdesc_accessContentProvidersExternally" msgid="4544346486697853685">"Разрешава на притежателя достъп до доставчиците на съдържание от командния ред. Нормалните приложения би трябвало никога да не се нуждаят от това."</string>
-    <!-- no translation found for permlab_updateLock (3527558366616680889) -->
-    <skip />
-    <!-- no translation found for permdesc_updateLock (1655625832166778492) -->
-    <skip />
+    <string name="permlab_updateLock" msgid="3527558366616680889">"без авт. актуализации на устройството"</string>
+    <string name="permdesc_updateLock" msgid="1655625832166778492">"Разрешава на притежателя да предложи на системата информация за това, кога ще е възможно неинтерактивно рестартиране за надстройване на устройството."</string>
     <string name="save_password_message" msgid="767344687139195790">"Искате ли браузърът да запомни тази парола?"</string>
     <string name="save_password_notnow" msgid="6389675316706699758">"Не сега"</string>
     <string name="save_password_remember" msgid="6491879678996749466">"Запомняне"</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 8ea7711..389a672 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -768,7 +768,7 @@
     <string name="permdesc_serialPort" msgid="2991639985224598193">"Umožňuje držiteli přístup k sériovým portům pomocí rozhraní SerialManager API."</string>
     <string name="permlab_accessContentProvidersExternally" msgid="5077774297943409285">"externí přístup k poskytovatelům obsahu"</string>
     <string name="permdesc_accessContentProvidersExternally" msgid="4544346486697853685">"Umožňuje držiteli získat z příkazového řádku přístup k poskytovatelům obsahu. Běžné aplikace by toto oprávnění neměly nikdy požadovat."</string>
-    <string name="permlab_updateLock" msgid="3527558366616680889">"varování před automatickou aktualizací"</string>
+    <string name="permlab_updateLock" msgid="3527558366616680889">"varovat před automatickou aktualizací"</string>
     <string name="permdesc_updateLock" msgid="1655625832166778492">"Umožňuje držiteli navrhnout systému informace o vhodné době pro upgrade zařízení neinteraktivním restartováním."</string>
     <string name="save_password_message" msgid="767344687139195790">"Chcete, aby si prohlížeč zapamatoval toto heslo?"</string>
     <string name="save_password_notnow" msgid="6389675316706699758">"Nyní ne"</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 6fd4543..3ca0534 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -769,7 +769,7 @@
     <string name="permlab_accessContentProvidersExternally" msgid="5077774297943409285">"adgang til indholdsleverandører eksternt"</string>
     <string name="permdesc_accessContentProvidersExternally" msgid="4544346486697853685">"Giver indehaveren adgang til indholdsleverandører fra startsiden. Bør aldrig være nødvendigt for normale apps."</string>
     <string name="permlab_updateLock" msgid="3527558366616680889">"undgå automatiske enhedsopdateringer"</string>
-    <string name="permdesc_updateLock" msgid="1655625832166778492">"Giver indehaveren ret til at give systemet oplysninger om, hvornår det vil være et godt tidspunkt for en ikke-interaktiv genstart at opgradere enheden."</string>
+    <string name="permdesc_updateLock" msgid="1655625832166778492">"Giver indehaveren ret til at give systemet oplysninger om, hvornår det vil være et godt tidspunkt for en ikke-interaktiv genstart for at opgradere enheden."</string>
     <string name="save_password_message" msgid="767344687139195790">"Ønsker du, at browseren skal huske denne adgangskode?"</string>
     <string name="save_password_notnow" msgid="6389675316706699758">"Ikke nu"</string>
     <string name="save_password_remember" msgid="6491879678996749466">"Husk"</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 3b7bd0f..a4a9bff 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -768,10 +768,8 @@
     <string name="permdesc_serialPort" msgid="2991639985224598193">"به دارنده اجازه می‌دهد با استفاده از SerialManager API به درگاه‌های سریال دسترسی داشته باشد."</string>
     <string name="permlab_accessContentProvidersExternally" msgid="5077774297943409285">"دسترسی خارجی به ارائه‌دهندگان محتوا"</string>
     <string name="permdesc_accessContentProvidersExternally" msgid="4544346486697853685">"به دارنده اجازه می‌دهد تا از خارج برنامه به ارائه‌دهندگان محتوا دسترسی داشته باشد. هرگز برای برنامه‌های معمولی به آن نیازی نیست."</string>
-    <!-- no translation found for permlab_updateLock (3527558366616680889) -->
-    <skip />
-    <!-- no translation found for permdesc_updateLock (1655625832166778492) -->
-    <skip />
+    <string name="permlab_updateLock" msgid="3527558366616680889">"ترغیب به انجام ندادن به‌روزرسانی‌های خودکار دستگاه"</string>
+    <string name="permdesc_updateLock" msgid="1655625832166778492">"به دارنده اجازه می‌دهد اطلاعاتی در مورد زمان مناسب برای یک راه‌اندازی مجدد غیرتعاملی جهت ارتقای دستگاه را به سیستم ارائه دهد."</string>
     <string name="save_password_message" msgid="767344687139195790">"می خواهید مرورگر این رمز ورود را به خاطر داشته باشد؟"</string>
     <string name="save_password_notnow" msgid="6389675316706699758">"اکنون خیر"</string>
     <string name="save_password_remember" msgid="6491879678996749466">"به خاطر سپردن"</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index e59cb22..b19a7de 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -26,8 +26,7 @@
     <string name="gigabyteShort" msgid="3259882455212193214">"Go"</string>
     <string name="terabyteShort" msgid="231613018159186962">"To"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"Po"</string>
-    <!-- no translation found for fileSizeSuffix (9164292791500531949) -->
-    <skip />
+    <string name="fileSizeSuffix" msgid="9164292791500531949">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;Sans nom&gt;"</string>
     <string name="ellipsis" msgid="7899829516048813237">"…"</string>
     <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
@@ -672,8 +671,7 @@
     <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Nombre maximal autorisé de tentatives Face Unlock atteint."</string>
     <string name="lockscreen_plugged_in" msgid="8057762828355572315">"En charge (<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>)"</string>
     <string name="lockscreen_charged" msgid="4938930459620989972">"Chargé"</string>
-    <!-- no translation found for lockscreen_battery_short (4477264849386850266) -->
-    <skip />
+    <string name="lockscreen_battery_short" msgid="4477264849386850266">"<xliff:g id="NUMBER">%d</xliff:g> <xliff:g id="PERCENT">%%</xliff:g>"</string>
     <string name="lockscreen_low_battery" msgid="1482873981919249740">"Branchez votre chargeur."</string>
     <string name="lockscreen_missing_sim_message_short" msgid="7381499217732227295">"Aucune carte SIM n\'a été trouvée."</string>
     <string name="lockscreen_missing_sim_message" product="tablet" msgid="151659196095791474">"Aucune carte SIM n\'est insérée dans la tablette."</string>
@@ -722,10 +720,8 @@
     <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
     <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
     <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
-    <!-- no translation found for hour_ampm (4584338083529355982) -->
-    <skip />
-    <!-- no translation found for hour_cap_ampm (2083465992940444366) -->
-    <skip />
+    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%P</xliff:g>"</string>
+    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"Échec du test usine"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"L\'action FACTORY_TEST est uniquement prise en charge pour les paquets de données installés dans in/system/app."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"Impossible de trouver un paquet proposant l\'action FACTORY_TEST."</string>
@@ -737,8 +733,7 @@
     <string name="double_tap_toast" msgid="4595046515400268881">"Conseil : Appuyez deux fois pour faire un zoom avant ou arrière."</string>
     <string name="autofill_this_form" msgid="4616758841157816676">"Saisie auto"</string>
     <string name="setup_autofill" msgid="7103495070180590814">"Conf. saisie auto"</string>
-    <!-- no translation found for autofill_address_name_separator (6350145154779706772) -->
-    <skip />
+    <string name="autofill_address_name_separator" msgid="6350145154779706772">" "</string>
     <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
     <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
     <string name="autofill_address_summary_format" msgid="4874459455786827344">"$1$2$3"</string>
@@ -870,8 +865,8 @@
     <string name="days" msgid="4774547661021344602">"jours"</string>
     <string name="hour" msgid="2126771916426189481">"heure"</string>
     <string name="hours" msgid="894424005266852993">"heures"</string>
-    <string name="minute" msgid="9148878657703769868">"mn"</string>
-    <string name="minutes" msgid="5646001005827034509">"mn"</string>
+    <string name="minute" msgid="9148878657703769868">"min"</string>
+    <string name="minutes" msgid="5646001005827034509">"min"</string>
     <string name="second" msgid="3184235808021478">"s"</string>
     <string name="seconds" msgid="3161515347216589235">"s"</string>
     <string name="week" msgid="5617961537173061583">"semaine"</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 5343e04..fbd3a3d 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -769,7 +769,7 @@
     <string name="permlab_accessContentProvidersExternally" msgid="5077774297943409285">"pristup pružateljima sadržaja izvana"</string>
     <string name="permdesc_accessContentProvidersExternally" msgid="4544346486697853685">"Omogućuje vlasniku pristup pružateljima sadržaja iz programske ovojnice. Ne bi trebalo biti potrebno za normalne aplikacije."</string>
     <string name="permlab_updateLock" msgid="3527558366616680889">"odvratiti automatska ažuriranja uređaja"</string>
-    <string name="permdesc_updateLock" msgid="1655625832166778492">"Omogućuje vlasniku davanje informacija sustavu o pogodnom trenutku za nadogradnju uređaja putem ponovnog pokretanja bez interakcije."</string>
+    <string name="permdesc_updateLock" msgid="1655625832166778492">"Omogućuje vlasniku davanje informacija sustavu o pogodnom trenutku za nadogradnju uređaja ponovnim pokretanjem bez interakcije."</string>
     <string name="save_password_message" msgid="767344687139195790">"Želite li da preglednik zapamti ovu zaporku?"</string>
     <string name="save_password_notnow" msgid="6389675316706699758">"Ne sada"</string>
     <string name="save_password_remember" msgid="6491879678996749466">"Zapamti"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 603a7be..7d08048 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -68,7 +68,7 @@
     <string name="CLIRDefaultOffNextCallOn" msgid="6179425182856418465">"Nomor penelepon bawaan tidak dibatasi. Panggilan selanjutnya: Dibatasi"</string>
     <string name="CLIRDefaultOffNextCallOff" msgid="2567998633124408552">"Nomor penelepon bawaan tidak dibatasi. Panggilan selanjutnya: Tidak dibatasi"</string>
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"Layanan tidak diperlengkapi."</string>
-    <string name="CLIRPermanent" msgid="3377371145926835671">"Anda tidak dapat mengubah setelan nomor penelepon."</string>
+    <string name="CLIRPermanent" msgid="3377371145926835671">"Anda tidak dapat mengubah pengaturan nomor penelepon."</string>
     <string name="RestrictedChangedTitle" msgid="5592189398956187498">"Akses terbatas berubah"</string>
     <string name="RestrictedOnData" msgid="8653794784690065540">"Layanan data dicekal."</string>
     <string name="RestrictedOnEmergency" msgid="6581163779072833665">"Layanan darurat dicekal."</string>
@@ -120,15 +120,15 @@
     <string name="httpErrorUnsupportedScheme" msgid="5015730812906192208">"Protokol tidak didukung."</string>
     <string name="httpErrorFailedSslHandshake" msgid="96549606000658641">"Tidak dapat membuat sambungan aman."</string>
     <string name="httpErrorBadUrl" msgid="3636929722728881972">"Tidak dapat membuka laman karena URL tidak valid."</string>
-    <string name="httpErrorFile" msgid="2170788515052558676">"Tidak dapat mengakses berkas."</string>
-    <string name="httpErrorFileNotFound" msgid="6203856612042655084">"Tidak dapat menemukan berkas yang diminta."</string>
+    <string name="httpErrorFile" msgid="2170788515052558676">"Tidak dapat mengakses file."</string>
+    <string name="httpErrorFileNotFound" msgid="6203856612042655084">"Tidak dapat menemukan file yang diminta."</string>
     <string name="httpErrorTooManyRequests" msgid="1235396927087188253">"Terlalu banyak permintaan yang diproses. Coba lagi nanti."</string>
     <string name="notification_title" msgid="8967710025036163822">"Galat saat masuk untuk <xliff:g id="ACCOUNT">%1$s</xliff:g>"</string>
     <string name="contentServiceSync" msgid="8353523060269335667">"Sinkron"</string>
     <string name="contentServiceSyncNotificationTitle" msgid="397743349191901458">"Sinkron"</string>
     <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"Terlalu banyak <xliff:g id="CONTENT_TYPE">%s</xliff:g> penghapusan."</string>
-    <string name="low_memory" product="tablet" msgid="6494019234102154896">"Penyimpanan tablet penuh. Hapus beberapa berkas untuk mengosongkan ruang."</string>
-    <string name="low_memory" product="default" msgid="3475999286680000541">"Penyimpanan di ponsel penuh. Hapus sebagian berkas untuk mengosongkan ruang."</string>
+    <string name="low_memory" product="tablet" msgid="6494019234102154896">"Penyimpanan tablet penuh. Hapus beberapa file untuk mengosongkan ruang."</string>
+    <string name="low_memory" product="default" msgid="3475999286680000541">"Penyimpanan di ponsel penuh. Hapus sebagian file untuk mengosongkan ruang."</string>
     <string name="me" msgid="6545696007631404292">"Saya"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Opsi tablet"</string>
     <string name="power_dialog" product="default" msgid="1319919075463988638">"Opsi telepon"</string>
@@ -219,7 +219,7 @@
     <string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"Memungkinkan apl mengontrol mode kompatibilitas layar aplikasi lain. Aplikasi berbahaya dapat merusak perilaku aplikasi lain."</string>
     <string name="permlab_setDebugApp" msgid="3022107198686584052">"mengaktifkan debugging apl"</string>
     <string name="permdesc_setDebugApp" msgid="4474512416299013256">"Mengizinkan apl mengaktifkan debugging untuk apl lain. Apl berbahaya dapat menggunakan cara ini untuk menutup apl lain."</string>
-    <string name="permlab_changeConfiguration" msgid="8214475779521218295">"ubah setelan UI Anda"</string>
+    <string name="permlab_changeConfiguration" msgid="8214475779521218295">"ubah pengaturan UI Anda"</string>
     <string name="permdesc_changeConfiguration" msgid="4372223873154296076">"Mengizinkan apl mengubah konfigurasi saat ini, misalnya lokal atau ukuran fon keseluruhan."</string>
     <string name="permlab_enableCarMode" msgid="5684504058192921098">"aktifkan mode mobil"</string>
     <string name="permdesc_enableCarMode" msgid="4853187425751419467">"Mengizinkan apl mengaktifkan mode mobil."</string>
@@ -293,23 +293,23 @@
     <string name="permlab_clearAppUserData" msgid="274109191845842756">"menghapus data apl lainnya"</string>
     <string name="permdesc_clearAppUserData" msgid="4625323684125459488">"Mengizinkan apl menghapus data pengguna."</string>
     <string name="permlab_deleteCacheFiles" msgid="3128665571837408675">"menghapus tembolok apl lainnya"</string>
-    <string name="permdesc_deleteCacheFiles" msgid="3812998599006730196">"Mengizinkan apl menghapus berkas tembolok."</string>
+    <string name="permdesc_deleteCacheFiles" msgid="3812998599006730196">"Mengizinkan apl menghapus file tembolok."</string>
     <string name="permlab_getPackageSize" msgid="7472921768357981986">"mengukur ruang penyimpanan apl"</string>
     <string name="permdesc_getPackageSize" msgid="3921068154420738296">"Mengizinkan apl mengambil kode, data, dan ukuran temboloknya"</string>
     <string name="permlab_installPackages" msgid="2199128482820306924">"langsung memasang apl"</string>
     <string name="permdesc_installPackages" msgid="5628530972548071284">"Mengizinkan apl memasang paket Android yang baru atau diperbarui. Apl berbahaya dapat menggunakan ini untuk menambahkan apl baru dengan sembarang izin yang kuat."</string>
     <string name="permlab_clearAppCache" msgid="7487279391723526815">"menghapus semua data tembolok apl"</string>
-    <string name="permdesc_clearAppCache" product="tablet" msgid="3523396284474042284">"Mengizinkan apl mengosongkan penyimpanan tablet dengan menghapus berkas dalam direktori tembolok apl. Akses biasanya sangat terbatas dan hanya diberikan bagi proses sistem."</string>
-    <string name="permdesc_clearAppCache" product="default" msgid="5067988373366292186">"Mengizinkan apl mengosongkan penyimpanan ponsel dengan menghapus berkas dalam direktori tembolok apl. Akses biasanya sangat terbatas dan hanya diberikan bagi proses sistem."</string>
+    <string name="permdesc_clearAppCache" product="tablet" msgid="3523396284474042284">"Mengizinkan apl mengosongkan penyimpanan tablet dengan menghapus file dalam direktori tembolok apl. Akses biasanya sangat terbatas dan hanya diberikan bagi proses sistem."</string>
+    <string name="permdesc_clearAppCache" product="default" msgid="5067988373366292186">"Mengizinkan apl mengosongkan penyimpanan ponsel dengan menghapus file dalam direktori tembolok apl. Akses biasanya sangat terbatas dan hanya diberikan bagi proses sistem."</string>
     <string name="permlab_movePackage" msgid="3289890271645921411">"memindahkan sumber daya apl"</string>
     <string name="permdesc_movePackage" msgid="319562217778244524">"Mengizinkan apl memindahkan sumber daya apl dari media internal ke eksternal dan sebaliknya."</string>
     <string name="permlab_readLogs" msgid="6615778543198967614">"baca data log sensitif"</string>
-    <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"Mengizinkan apl membaca dari berbagai berkas log sistem. Izin ini memungkinkan apl menemukan informasi umum tentang hal-hal yang Anda lakukan dengan tablet, kemungkinan termasuk informasi pribadi."</string>
-    <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Mengizinkan apl membaca dari berbagai berkas log sistem. Izin ini memungkinkan apl menemukan informasi umum tentang hal-hal yang Anda lakukan di ponsel, kemungkinan termasuk informasi pribadi."</string>
+    <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"Mengizinkan apl membaca dari berbagai file log sistem. Izin ini memungkinkan apl menemukan informasi umum tentang hal-hal yang Anda lakukan dengan tablet, kemungkinan termasuk informasi pribadi."</string>
+    <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Mengizinkan apl membaca dari berbagai file log sistem. Izin ini memungkinkan apl menemukan informasi umum tentang hal-hal yang Anda lakukan di ponsel, kemungkinan termasuk informasi pribadi."</string>
     <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"menggunakan media pengawasandi apa pun untuk pemutaran"</string>
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Mengizinkan apl menggunakan pengawasandi media apa pun yang terpasang guna mengawasandikan media untuk diputar."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"baca/tulis ke sumber daya yang dimiliki oleh diag"</string>
-    <string name="permdesc_diagnostic" msgid="6608295692002452283">"Mengizinkan apl membaca dan menulis ke sumber daya apa pun yang dimiliki oleh grup diag; misalnya, berkas dalam /dev. Izin ini berpotensi mempengaruhi kestabilan dan keamanan sistem. Sebaiknya ini HANYA digunakan untuk diagnostik khusus perangkat keras oleh pabrikan atau operator."</string>
+    <string name="permdesc_diagnostic" msgid="6608295692002452283">"Mengizinkan apl membaca dan menulis ke sumber daya apa pun yang dimiliki oleh grup diag; misalnya, file dalam /dev. Izin ini berpotensi mempengaruhi kestabilan dan keamanan sistem. Sebaiknya ini HANYA digunakan untuk diagnostik khusus perangkat keras oleh pabrikan atau operator."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"mengaktifkan atau menonaktifkan komponen apl"</string>
     <string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Mengizinkan apl mengubah apakah komponen apl lain diaktifkan atau tidak. Apl berbahaya dapat menggunakan ini untuk menonaktifkan kemampuan tablet yang penting. Izin ini harus digunakan dengan hati-hati karena dapat menjadikan komponen apl tidak dapat digunakan, tidak konsisten, atau tidak stabil."</string>
     <string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Mengizinkan apl mengubah apakah komponen apl lain diaktifkan atau tidak. Apl berbahaya dapat menggunakan izin ini untuk menonaktifkan kemampuan ponsel yang penting. Izin ini harus digunakan dengan hati-hati, karena mungkin saja menjadikan komponen apl tidak dapat digunakan, tidak konsisten, atau tidak stabil."</string>
@@ -317,10 +317,10 @@
     <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"Memungkinkan aplikasi memberikan atau mencabut izin khusus untuk aplikasi tersebut atau aplikasi lainnya. Aplikasi berbahaya dapat menggunakannya untuk mengakses fitur yang tidak Anda beri izin."</string>
     <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"menyetel apl yang disukai"</string>
     <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Mengizinkan apl memodifikasi apl pilihan Anda. Apl berbahaya dapat diam-diam mengubah apl yang berjalan, menipu apl yang ada untuk mengumpulkan data pribadi dari Anda."</string>
-    <string name="permlab_writeSettings" msgid="1365523497395143704">"ubah setelan sistem global"</string>
-    <string name="permdesc_writeSettings" msgid="7775723441558907181">"Mengizinkan apl memodifikasi data setelan sistem. Apl berbahaya dapat merusak konfigurasi sistem anda."</string>
-    <string name="permlab_writeSecureSettings" msgid="204676251876718288">"ubah setelan sistem aman"</string>
-    <string name="permdesc_writeSecureSettings" msgid="8159535613020137391">"Mengizinkan apl memodifikasi data setelan aman sistem. Tidak untuk digunakan oleh apl normal."</string>
+    <string name="permlab_writeSettings" msgid="1365523497395143704">"ubah pengaturan sistem global"</string>
+    <string name="permdesc_writeSettings" msgid="7775723441558907181">"Mengizinkan apl memodifikasi data pengaturan sistem. Apl berbahaya dapat merusak konfigurasi sistem anda."</string>
+    <string name="permlab_writeSecureSettings" msgid="204676251876718288">"ubah pengaturan sistem aman"</string>
+    <string name="permdesc_writeSecureSettings" msgid="8159535613020137391">"Mengizinkan apl memodifikasi data pengaturan aman sistem. Tidak untuk digunakan oleh apl normal."</string>
     <string name="permlab_writeGservices" msgid="2149426664226152185">"ubah peta layanan Google"</string>
     <string name="permdesc_writeGservices" msgid="1287309437638380229">"Mengizinkan apl memodifikasi peta layanan Google. Tidak untuk digunakan oleh apl normal."</string>
     <string name="permlab_receiveBootCompleted" msgid="7776779842866993377">"mulai secara otomatis pada saat boot"</string>
@@ -364,8 +364,8 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Mengizinkan apl menggunakan fitur tingkat rendah SurfaceFlinger."</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"baca buffer frame"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Mengizinkan apl membaca konten penyangga frame."</string>
-    <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"ubah setelan audio Anda"</string>
-    <string name="permdesc_modifyAudioSettings" msgid="7343951185408396919">"Mengizinkan apl memodifikasi setelan audio global, misalnya volume dan perutean."</string>
+    <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"ubah pengaturan audio Anda"</string>
+    <string name="permdesc_modifyAudioSettings" msgid="7343951185408396919">"Mengizinkan apl memodifikasi pengaturan audio global, misalnya volume dan perutean."</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"rekam audio"</string>
     <string name="permdesc_recordAudio" msgid="2387462233976248635">"Mengizinkan apl mengakses jalur rekaman audio."</string>
     <string name="permlab_camera" msgid="3616391919559751192">"ambil gambar dan video"</string>
@@ -379,7 +379,7 @@
     <string name="permdesc_reboot" product="tablet" msgid="8172056180063700741">"Mengizinkan apl memaksa tablet melakukan reboot."</string>
     <string name="permdesc_reboot" product="default" msgid="5326008124289989969">"Mengizinkan apl memaksa ponsel melakukan reboot."</string>
     <string name="permlab_mount_unmount_filesystems" msgid="1761023272170956541">"pasang dan lepas filesystem"</string>
-    <string name="permdesc_mount_unmount_filesystems" msgid="1829290701658992347">"Mengizinkan apl memasang dan melepas sistem berkas untuk penyimpanan yang dapat dicopot."</string>
+    <string name="permdesc_mount_unmount_filesystems" msgid="1829290701658992347">"Mengizinkan apl memasang dan melepas sistem file untuk penyimpanan yang dapat dicopot."</string>
     <string name="permlab_mount_format_filesystems" msgid="5523285143576718981">"format penyimpanan eksternal"</string>
     <string name="permdesc_mount_format_filesystems" msgid="8784268246779198627">"Mengizinkan apl memformat penyimpanan yang dapat dicopot."</string>
     <string name="permlab_asec_access" msgid="3411338632002193846">"dapatkan informasi pada penyimpanan internal"</string>
@@ -434,8 +434,8 @@
     <string name="permdesc_setWallpaper" msgid="7373447920977624745">"Mengizinkan apl menyetel wallpaper sistem."</string>
     <string name="permlab_setWallpaperHints" msgid="3600721069353106851">"atur petunjuk ukuran wallpaper"</string>
     <string name="permdesc_setWallpaperHints" msgid="8235784384223730091">"Mengizinkan apl menyetel petunjuk ukuran wallpaper sistem."</string>
-    <string name="permlab_masterClear" msgid="2315750423139697397">"setel ulang sistem ke setelan bawaan pabrik"</string>
-    <string name="permdesc_masterClear" msgid="3665380492633910226">"Mengizinkan apl menyetel ulang sistem ke setelan pabrik sepenuhnya, menghapus semua data, konfigurasi, dan apl yang terpasang."</string>
+    <string name="permlab_masterClear" msgid="2315750423139697397">"setel ulang sistem ke pengaturan bawaan pabrik"</string>
+    <string name="permdesc_masterClear" msgid="3665380492633910226">"Mengizinkan apl menyetel ulang sistem ke pengaturan pabrik sepenuhnya, menghapus semua data, konfigurasi, dan apl yang terpasang."</string>
     <string name="permlab_setTime" msgid="2021614829591775646">"atur waktu"</string>
     <string name="permdesc_setTime" product="tablet" msgid="1896341438151152881">"Mengizinkan apl mengubah waktu pada jam tablet."</string>
     <string name="permdesc_setTime" product="default" msgid="1855702730738020">"Mengizinkan apl mengubah waktu pada jam ponsel."</string>
@@ -457,14 +457,14 @@
     <string name="permdesc_accessNetworkState" msgid="479772796952547198">"Mengizinkan apl melihat keadaan semua jaringan."</string>
     <string name="permlab_createNetworkSockets" msgid="9121633680349549585">"akses internet penuh"</string>
     <string name="permdesc_createNetworkSockets" msgid="5963922297444265950">"Mengizinkan apl membuat soket jaringan."</string>
-    <string name="permlab_writeApnSettings" msgid="505660159675751896">"mengubah/mencegat lalu lintas dan setelan jaringan"</string>
-    <string name="permdesc_writeApnSettings" msgid="5333798886412714193">"Mengizinkan apl mengubah setelan jaringan dan mencegat serta memeriksa semua lalu lintas jaringan, misalnya mengubah proxy dan port APN apa saja. Apl berbahaya dapat memantau, mengalihkan, atau mengubah paket jaringan tanpa sepengetahuan Anda."</string>
+    <string name="permlab_writeApnSettings" msgid="505660159675751896">"mengubah/mencegat lalu lintas dan pengaturan jaringan"</string>
+    <string name="permdesc_writeApnSettings" msgid="5333798886412714193">"Mengizinkan apl mengubah pengaturan jaringan dan mencegat serta memeriksa semua lalu lintas jaringan, misalnya mengubah proxy dan port APN apa saja. Apl berbahaya dapat memantau, mengalihkan, atau mengubah paket jaringan tanpa sepengetahuan Anda."</string>
     <string name="permlab_changeNetworkState" msgid="958884291454327309">"ubah konektivitas jaringan"</string>
     <string name="permdesc_changeNetworkState" msgid="6789123912476416214">"Mengizinkan apl mengubah keadaan konektivitas jaringan."</string>
     <string name="permlab_changeTetherState" msgid="5952584964373017960">"mengubah konektivitas yang tertambat"</string>
     <string name="permdesc_changeTetherState" msgid="1524441344412319780">"Mengizinkan apl mengubah status konektivitas jaringan yang tertambat."</string>
-    <string name="permlab_changeBackgroundDataSetting" msgid="1400666012671648741">"mengubah setelan penggunaan data latar belakang"</string>
-    <string name="permdesc_changeBackgroundDataSetting" msgid="5347729578468744379">"Mengizinkan apl mengubah setelan penggunaan data latar belakang."</string>
+    <string name="permlab_changeBackgroundDataSetting" msgid="1400666012671648741">"mengubah pengaturan penggunaan data latar belakang"</string>
+    <string name="permdesc_changeBackgroundDataSetting" msgid="5347729578468744379">"Mengizinkan apl mengubah pengaturan penggunaan data latar belakang."</string>
     <string name="permlab_accessWifiState" msgid="8100926650211034400">"lihat kondisi Wi-Fi"</string>
     <string name="permdesc_accessWifiState" msgid="7770452658226256831">"Mengizinkan apl melihat informasi tentang keadaan Wi-Fi."</string>
     <string name="permlab_changeWifiState" msgid="7280632711057112137">"ubah status Wi-Fi"</string>
@@ -485,10 +485,10 @@
     <string name="permdesc_nfc" msgid="7120611819401789907">"Mengizinkan apl berkomunikasi dengan tag, kartu, dan alat pembaca Komunikasi Nirkabel Jarak Dekat (NFC)."</string>
     <string name="permlab_disableKeyguard" msgid="4977406164311535092">"nonaktifkan kunci tombol"</string>
     <string name="permdesc_disableKeyguard" msgid="6231611286892232626">"Mengizinkan apl menonaktifkan kunci tombol dan segala keamanan sandi yang terkait. Contoh nyata dari hal ini adalah ponsel menonaktifkan kunci tombol saat menerima panggilan telepon masuk, kemudian mengaktifkan kembali kunci tombol ketika panggilan selesai."</string>
-    <string name="permlab_readSyncSettings" msgid="6201810008230503052">"baca setelan sinkron"</string>
-    <string name="permdesc_readSyncSettings" msgid="5464056785274229278">"Mengizinkan apl membaca setelan sinkronisasi, misalnya apakah sinkronisasi untuk apl Orang diaktifkan atau tidak."</string>
-    <string name="permlab_writeSyncSettings" msgid="6297138566442486462">"tuliskan setelan sinkronisasi"</string>
-    <string name="permdesc_writeSyncSettings" msgid="1466056564502117130">"Mengizinkan apl memodifikasi setelan sinkronisasi, seperti apakah sinkronisasi untuk apl Orang diaktifkan atau tidak."</string>
+    <string name="permlab_readSyncSettings" msgid="6201810008230503052">"baca pengaturan sinkron"</string>
+    <string name="permdesc_readSyncSettings" msgid="5464056785274229278">"Mengizinkan apl membaca pengaturan sinkronisasi, misalnya apakah sinkronisasi untuk apl Orang diaktifkan atau tidak."</string>
+    <string name="permlab_writeSyncSettings" msgid="6297138566442486462">"tuliskan pengaturan sinkronisasi"</string>
+    <string name="permdesc_writeSyncSettings" msgid="1466056564502117130">"Mengizinkan apl memodifikasi pengaturan sinkronisasi, seperti apakah sinkronisasi untuk apl Orang diaktifkan atau tidak."</string>
     <string name="permlab_readSyncStats" msgid="7396577451360202448">"statistika baca sinkron"</string>
     <string name="permdesc_readSyncStats" msgid="3801971839939951678">"Mengizinkan apl membaca statistik sinkronisasi; mis., riwayat sinkronisasi yang telah terjadi."</string>
     <string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"baca umpan langganan"</string>
@@ -505,8 +505,8 @@
     <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Memungkinkan apl menulis ke kartu SD."</string>
     <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"ubah/hapus konten penyimpanan media internal"</string>
     <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Mengizinkan apl memodifikasi konten penyimpanan media internal."</string>
-    <string name="permlab_cache_filesystem" msgid="5656487264819669824">"akses sistem berkas tembolok."</string>
-    <string name="permdesc_cache_filesystem" msgid="5578967642265550955">"Mengizinkan apl membaca dan menulis pada sistem berkas tembolok."</string>
+    <string name="permlab_cache_filesystem" msgid="5656487264819669824">"akses sistem file tembolok."</string>
+    <string name="permdesc_cache_filesystem" msgid="5578967642265550955">"Mengizinkan apl membaca dan menulis pada sistem file tembolok."</string>
     <string name="permlab_use_sip" msgid="5986952362795870502">"lakukan//terima panggilan internet"</string>
     <string name="permdesc_use_sip" msgid="4717632000062674294">"Mengizinkan apl menggunakan layanan SIP untuk melakukan/menerima panggilan internet."</string>
     <string name="permlab_readNetworkUsageHistory" msgid="7862593283611493232">"baca riwayat penggunaan jaringan"</string>
@@ -695,10 +695,10 @@
     <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Anda telah <xliff:g id="NUMBER_0">%d</xliff:g> kali salah mengetik PIN. "\n\n"Coba lagi dalam <xliff:g id="NUMBER_1">%d</xliff:g> detik."</string>
     <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Anda telah <xliff:g id="NUMBER_0">%d</xliff:g> kali salah menggambar pola pembuka kunci. Setelah <xliff:g id="NUMBER_1">%d</xliff:g> lagi upaya gagal, Anda akan diminta membuka kunci tablet menggunakan info masuk Google."\n\n"Coba lagi dalam <xliff:g id="NUMBER_2">%d</xliff:g> detik."</string>
     <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Anda telah <xliff:g id="NUMBER_0">%d</xliff:g> kali salah menggambar pola pembuka kunci. Setelah <xliff:g id="NUMBER_1">%d</xliff:g> lagi upaya gagal, Anda akan diminta membuka kunci ponsel menggunakan info masuk Google."\n\n"Coba lagi dalam <xliff:g id="NUMBER_2">%d</xliff:g> detik."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Anda telah gagal mencoba membuka gembok tablet sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. Setelah <xliff:g id="NUMBER_1">%d</xliff:g> upaya gagal lagi, tablet akan disetel ulang ke setelan bawaan pabrik dan semua data pengguna hilang."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Anda telah gagal mencoba membuka gembok ponsel sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. Setelah <xliff:g id="NUMBER_1">%d</xliff:g> upaya gagal lagi, ponsel akan disetel ulang ke setelan bawaan pabrik dan semua data pengguna hilang."</string>
-    <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Anda telah gagal mencoba membuka gembok tablet sebanyak <xliff:g id="NUMBER">%d</xliff:g> kali. Kini tablet akan disetel ulang ke setelan bawaan pabrik."</string>
-    <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"Anda telah gagal mencoba membuka gembok ponsel sebanyak <xliff:g id="NUMBER">%d</xliff:g> kali. Kini ponsel akan disetel ulang ke setelan bawaan pabrik."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Anda telah gagal mencoba membuka gembok tablet sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. Setelah <xliff:g id="NUMBER_1">%d</xliff:g> upaya gagal lagi, tablet akan disetel ulang ke pengaturan bawaan pabrik dan semua data pengguna hilang."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Anda telah gagal mencoba membuka gembok ponsel sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. Setelah <xliff:g id="NUMBER_1">%d</xliff:g> upaya gagal lagi, ponsel akan disetel ulang ke pengaturan bawaan pabrik dan semua data pengguna hilang."</string>
+    <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Anda telah gagal mencoba membuka gembok tablet sebanyak <xliff:g id="NUMBER">%d</xliff:g> kali. Kini tablet akan disetel ulang ke pengaturan bawaan pabrik."</string>
+    <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"Anda telah gagal mencoba membuka gembok ponsel sebanyak <xliff:g id="NUMBER">%d</xliff:g> kali. Kini ponsel akan disetel ulang ke pengaturan bawaan pabrik."</string>
     <string name="lockscreen_too_many_failed_attempts_countdown" msgid="6251480343394389665">"Coba lagi dalam <xliff:g id="NUMBER">%d</xliff:g> detik."</string>
     <string name="lockscreen_forgot_pattern_button_text" msgid="2626999449610695930">"Lupa pola?"</string>
     <string name="lockscreen_glogin_forgot_pattern" msgid="2588521501166032747">"Pembuka kunci akun"</string>
@@ -749,17 +749,17 @@
     <string name="autofill_parish" msgid="8202206105468820057">"Kampung"</string>
     <string name="autofill_area" msgid="3547409050889952423">"Area"</string>
     <string name="autofill_emirate" msgid="2893880978835698818">"Emirat"</string>
-    <string name="permlab_readHistoryBookmarks" msgid="1284843728203412135">"baca riwayat dan bookmark Peramban"</string>
-    <string name="permdesc_readHistoryBookmarks" msgid="4577476392604595921">"Mengizinkan apl membaca semua URL yang telah dikunjungi Peramban dan semua bookmark Peramban."</string>
-    <string name="permlab_writeHistoryBookmarks" msgid="9009434109836280374">"tuliskan riwayat dan bookmark Peramban"</string>
-    <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="1757103804824209530">"Mengizinkan apl memodifikasi riwayat Peramban atau bookmark yang tersimpan di tablet. Apl berbahaya dapat menggunakan izin ini untuk menghapus atau memodifikasi data Peramban Anda."</string>
-    <string name="permdesc_writeHistoryBookmarks" product="default" msgid="6693764355720719197">"Mengizinkan apl memodifikasi riwayat Peramban atau bookmark yang tersimpan di ponsel Anda. Apl berbahaya dapat menggunakannya untuk menghapus atau memodifikasi data Peramban Anda."</string>
+    <string name="permlab_readHistoryBookmarks" msgid="1284843728203412135">"baca riwayat dan bookmark Browser"</string>
+    <string name="permdesc_readHistoryBookmarks" msgid="4577476392604595921">"Mengizinkan apl membaca semua URL yang telah dikunjungi Browser dan semua bookmark Browser."</string>
+    <string name="permlab_writeHistoryBookmarks" msgid="9009434109836280374">"tuliskan riwayat dan bookmark Browser"</string>
+    <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="1757103804824209530">"Mengizinkan apl memodifikasi riwayat Browser atau bookmark yang tersimpan di tablet. Apl berbahaya dapat menggunakan izin ini untuk menghapus atau memodifikasi data Browser Anda."</string>
+    <string name="permdesc_writeHistoryBookmarks" product="default" msgid="6693764355720719197">"Mengizinkan apl memodifikasi riwayat Browser atau bookmark yang tersimpan di ponsel Anda. Apl berbahaya dapat menggunakannya untuk menghapus atau memodifikasi data Browser Anda."</string>
     <string name="permlab_setAlarm" msgid="5924401328803615165">"setel alarm di jam alarm"</string>
     <string name="permdesc_setAlarm" msgid="316392039157473848">"Mengizinkan apl menyetel alarm di apl jam alarm yang terpasang. Beberapa apl jam alarm mungkin tidak menerapkan fitur ini."</string>
     <string name="permlab_addVoicemail" msgid="5525660026090959044">"tambahkan kotak pesan"</string>
     <string name="permdesc_addVoicemail" msgid="6604508651428252437">"Mengizinkan apl menambahkan pesan ke kotak masuk untuk pesan suara Anda."</string>
-    <string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"memodifikasi izin geolokasi Peramban"</string>
-    <string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"Mengizinkan apl memodifikasi izin geolokasi Peramban. Apl berbahaya dapat menggunakan izin ini untuk memungkinkan pengiriman informasi lokasi ke sembarang situs web."</string>
+    <string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"memodifikasi izin geolokasi Browser"</string>
+    <string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"Mengizinkan apl memodifikasi izin geolokasi Browser. Apl berbahaya dapat menggunakan izin ini untuk memungkinkan pengiriman informasi lokasi ke sembarang situs web."</string>
     <string name="permlab_packageVerificationAgent" msgid="5568139100645829117">"verifikasi paket"</string>
     <string name="permdesc_packageVerificationAgent" msgid="8437590190990843381">"Mengizinkan apl memverifikasi bahwa suatu paket dapat dipasang."</string>
     <string name="permlab_bindPackageVerifier" msgid="4187786793360326654">"mengikat ke pemverifikasi paket"</string>
@@ -768,11 +768,9 @@
     <string name="permdesc_serialPort" msgid="2991639985224598193">"Memungkinkan pemegangnya mengakses port serial menggunakan API SerialManager."</string>
     <string name="permlab_accessContentProvidersExternally" msgid="5077774297943409285">"mengakses penyedia konten dari luar"</string>
     <string name="permdesc_accessContentProvidersExternally" msgid="4544346486697853685">"Memungkinkan pemegang mengakses penyedia konten dari cangkang. Tidak pernah diperlukan untuk apl normal."</string>
-    <!-- no translation found for permlab_updateLock (3527558366616680889) -->
-    <skip />
-    <!-- no translation found for permdesc_updateLock (1655625832166778492) -->
-    <skip />
-    <string name="save_password_message" msgid="767344687139195790">"Apakah Anda ingin peramban menyimpan sandi ini?"</string>
+    <string name="permlab_updateLock" msgid="3527558366616680889">"menghindari pembaruan perangkat otomatis"</string>
+    <string name="permdesc_updateLock" msgid="1655625832166778492">"Memungkinkan pemegang untuk menawarkan informasi ke sistem mengenai kapan waktu yang baik bagi pemulaian ulang non-interaktif untuk meningkatkan versi perangkat."</string>
+    <string name="save_password_message" msgid="767344687139195790">"Apakah Anda ingin browser menyimpan sandi ini?"</string>
     <string name="save_password_notnow" msgid="6389675316706699758">"Tidak sekarang"</string>
     <string name="save_password_remember" msgid="6491879678996749466">"Ingat"</string>
     <string name="save_password_never" msgid="8274330296785855105">"Jangan"</string>
@@ -912,7 +910,7 @@
     <string name="capital_off" msgid="6815870386972805832">"MATI"</string>
     <string name="whichApplication" msgid="4533185947064773386">"Tindakan lengkap menggunakan"</string>
     <string name="alwaysUse" msgid="4583018368000610438">"Gunakan secara bawaan untuk tindakan ini."</string>
-    <string name="clearDefaultHintMsg" msgid="3252584689512077257">"Menghapus bawaan di Setelan sistem &gt; Apl &gt; Terunduh."</string>
+    <string name="clearDefaultHintMsg" msgid="3252584689512077257">"Menghapus bawaan di Pengaturan sistem &gt; Apl &gt; Terunduh."</string>
     <string name="chooseActivity" msgid="7486876147751803333">"Pilih tindakan"</string>
     <string name="chooseUsbActivity" msgid="6894748416073583509">"Pilih apl untuk perangkat USB"</string>
     <string name="noApplications" msgid="2991814273936504689">"Tidak ada apl yang dapat melakukan tindakan ini."</string>
@@ -933,7 +931,7 @@
     <string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g> telah diluncurkan aslinya."</string>
     <string name="screen_compat_mode_scale" msgid="3202955667675944499">"Skala"</string>
     <string name="screen_compat_mode_show" msgid="4013878876486655892">"Selalu tampilkan"</string>
-    <string name="screen_compat_mode_hint" msgid="1064524084543304459">"Aktifkan kembali dialog ini di Setelan sistem &gt; Apl &gt; Terunduh."</string>
+    <string name="screen_compat_mode_hint" msgid="1064524084543304459">"Aktifkan kembali dialog ini di Pengaturan sistem &gt; Apl &gt; Terunduh."</string>
     <string name="smv_application" msgid="3307209192155442829">"Apl <xliff:g id="APPLICATION">%1$s</xliff:g> (proses <xliff:g id="PROCESS">%2$s</xliff:g>) telah melanggar kebijakan StrictMode yang diberlakukannya sendiri."</string>
     <string name="smv_process" msgid="5120397012047462446">"Proses <xliff:g id="PROCESS">%1$s</xliff:g> telah melanggar kebijakan StrictMode yang diberlakukan secara otomatis."</string>
     <string name="android_upgrading_title" msgid="1584192285441405746">"Android sedang meningkatkan versi..."</string>
@@ -985,7 +983,7 @@
     <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Memulai Wi-Fi Langsung. Opsi ini akan mematikan hotspot/klien Wi-Fi."</string>
     <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Tidak dapat memulai Wi-Fi Langsung."</string>
     <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"Wi-Fi Langsung aktif"</string>
-    <string name="wifi_p2p_enabled_notification_message" msgid="1638949953993894335">"Sentuh untuk setelan"</string>
+    <string name="wifi_p2p_enabled_notification_message" msgid="1638949953993894335">"Sentuh untuk pengaturan"</string>
     <string name="accept" msgid="1645267259272829559">"Terima"</string>
     <string name="decline" msgid="2112225451706137894">"Tolak"</string>
     <string name="wifi_p2p_invitation_sent_title" msgid="1318975185112070734">"Undangan terkirim"</string>
@@ -1016,13 +1014,13 @@
     <string name="perms_show_all" msgid="2671791163933091180"><b>"Tampilkan semua"</b></string>
     <string name="usb_storage_activity_title" msgid="4465055157209648641">"Penyimpanan massal USB"</string>
     <string name="usb_storage_title" msgid="5901459041398751495">"USB terhubung"</string>
-    <string name="usb_storage_message" product="nosdcard" msgid="3308538094316477839">"Anda telah tersambung ke komputer melalui USB. Sentuh tombol di bawah jika Anda ingin menyalin berkas antara komputer dan penyimpanan USB Android Anda."</string>
-    <string name="usb_storage_message" product="default" msgid="805351000446037811">"Anda telah tersambung ke komputer melalui USB. Sentuh tombol di bawah jika Anda ingin menyalin berkas antara komputer dan kartu SD Android Anda."</string>
+    <string name="usb_storage_message" product="nosdcard" msgid="3308538094316477839">"Anda telah tersambung ke komputer melalui USB. Sentuh tombol di bawah jika Anda ingin menyalin file antara komputer dan penyimpanan USB Android Anda."</string>
+    <string name="usb_storage_message" product="default" msgid="805351000446037811">"Anda telah tersambung ke komputer melalui USB. Sentuh tombol di bawah jika Anda ingin menyalin file antara komputer dan kartu SD Android Anda."</string>
     <string name="usb_storage_button_mount" msgid="1052259930369508235">"Hidupkan penyimpanan USB"</string>
     <string name="usb_storage_error_message" product="nosdcard" msgid="3017045217365540658">"Terjadi masalah saat menggunakan penyimpanan USB Anda untuk penyimpanan massal USB."</string>
     <string name="usb_storage_error_message" product="default" msgid="2876018512716970313">"Terjadi masalah saat menggunakan kartu SD Anda untuk penyimpanan massal USB."</string>
     <string name="usb_storage_notification_title" msgid="8175892554757216525">"USB terhubung"</string>
-    <string name="usb_storage_notification_message" msgid="939822783828183763">"Sentuh untuk menyalin berkas ke/dari komputer Anda."</string>
+    <string name="usb_storage_notification_message" msgid="939822783828183763">"Sentuh untuk menyalin file ke/dari komputer Anda."</string>
     <string name="usb_storage_stop_notification_title" msgid="2336058396663516017">"Matikan penyimpanan USB"</string>
     <string name="usb_storage_stop_notification_message" msgid="1656852098555623822">"Sentuh untuk mematikan penyimpanan USB."</string>
     <string name="usb_storage_stop_title" msgid="660129851708775853">"Penyimpanan USB sedang digunakan"</string>
@@ -1041,7 +1039,7 @@
     <string name="usb_notification_message" msgid="2290859399983720271">"Sentuh untuk opsi USB lainnya."</string>
     <string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"Format penyimpanan USB?"</string>
     <string name="extmedia_format_title" product="default" msgid="3648415921526526069">"Format kartu SD?"</string>
-    <string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"Semua berkas yang tersimpan dalam penyimpanan USB Anda akan dihapus. Tindakan ini tidak dapat diurungkan!"</string>
+    <string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"Semua file yang tersimpan dalam penyimpanan USB Anda akan dihapus. Tindakan ini tidak dapat diurungkan!"</string>
     <string name="extmedia_format_message" product="default" msgid="14131895027543830">"Semua data di kartu Anda akan hilang."</string>
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"Format"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Debugging USB terhubung"</string>
@@ -1057,7 +1055,7 @@
     <string name="ext_media_nofs_notification_title" product="nosdcard" msgid="7788040745686229307">"Penyimpanan USB kosong"</string>
     <string name="ext_media_nofs_notification_title" product="default" msgid="780477838241212997">"Kartu SD kosong"</string>
     <string name="ext_media_nofs_notification_message" product="nosdcard" msgid="7840121067427269500">"Penyimpanan USB kosong atau sistem berkasnya tidak didukung."</string>
-    <string name="ext_media_nofs_notification_message" product="default" msgid="8641065641786923604">"Kartu SD kosong atau memiliki sistem berkas yang tidak didukung."</string>
+    <string name="ext_media_nofs_notification_message" product="default" msgid="8641065641786923604">"Kartu SD kosong atau memiliki sistem file yang tidak didukung."</string>
     <string name="ext_media_unmountable_notification_title" product="nosdcard" msgid="2090046769532713563">"Penyimpanan USB rusak"</string>
     <string name="ext_media_unmountable_notification_title" product="default" msgid="6410723906019100189">"Kartu SD rusak"</string>
     <string name="ext_media_unmountable_notification_message" product="nosdcard" msgid="1795917578395333280">"Penyimpanan USB rusak. Coba diformat ulang."</string>
@@ -1106,8 +1104,8 @@
     <string name="vpn_title_long" msgid="6400714798049252294">"VPN diaktifkan oleh <xliff:g id="APP">%s</xliff:g>"</string>
     <string name="vpn_text" msgid="3011306607126450322">"Sentuh untuk mengelola jaringan."</string>
     <string name="vpn_text_long" msgid="6407351006249174473">"Tersambung ke <xliff:g id="SESSION">%s</xliff:g>. Sentuh untuk mengelola jaringan."</string>
-    <string name="upload_file" msgid="2897957172366730416">"Pilih berkas"</string>
-    <string name="no_file_chosen" msgid="6363648562170759465">"Tidak ada berkas yang dipilih"</string>
+    <string name="upload_file" msgid="2897957172366730416">"Pilih file"</string>
+    <string name="no_file_chosen" msgid="6363648562170759465">"Tidak ada file yang dipilih"</string>
     <string name="reset" msgid="2448168080964209908">"Setel ulang"</string>
     <string name="submit" msgid="1602335572089911941">"Kirim"</string>
     <string name="car_mode_disable_notification_title" msgid="3164768212003864316">"Mode mobil diaktifkan"</string>
@@ -1245,6 +1243,6 @@
     <string name="status_bar_device_locked" msgid="3092703448690669768">"Perangkat tergembok."</string>
     <string name="list_delimeter" msgid="3975117572185494152">", "</string>
     <string name="sending" msgid="3245653681008218030">"Mengirim..."</string>
-    <string name="launchBrowserDefault" msgid="2057951947297614725">"Luncurkan Peramban?"</string>
+    <string name="launchBrowserDefault" msgid="2057951947297614725">"Luncurkan Browser?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Terima panggilan?"</string>
 </resources>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index b28bfdd..bc9840d 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -26,8 +26,7 @@
     <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
     <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
-    <!-- no translation found for fileSizeSuffix (9164292791500531949) -->
-    <skip />
+    <string name="fileSizeSuffix" msgid="9164292791500531949">"<xliff:g id="NUMBER">%1$s</xliff:g><xliff:g id="UNIT">%2$s</xliff:g>"</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;新規&gt;"</string>
     <string name="ellipsis" msgid="7899829516048813237">"..."</string>
     <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
@@ -672,8 +671,7 @@
     <string name="faceunlock_multiple_failures" msgid="754137583022792429">"フェイスアンロックの最大試行回数を超えました"</string>
     <string name="lockscreen_plugged_in" msgid="8057762828355572315">"充電しています: <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
     <string name="lockscreen_charged" msgid="4938930459620989972">"充電完了"</string>
-    <!-- no translation found for lockscreen_battery_short (4477264849386850266) -->
-    <skip />
+    <string name="lockscreen_battery_short" msgid="4477264849386850266">"<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
     <string name="lockscreen_low_battery" msgid="1482873981919249740">"充電してください"</string>
     <string name="lockscreen_missing_sim_message_short" msgid="7381499217732227295">"SIMカードが挿入されていません"</string>
     <string name="lockscreen_missing_sim_message" product="tablet" msgid="151659196095791474">"タブレット内にSIMカードがありません。"</string>
@@ -722,10 +720,8 @@
     <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
     <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
     <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
-    <!-- no translation found for hour_ampm (4584338083529355982) -->
-    <skip />
-    <!-- no translation found for hour_cap_ampm (2083465992940444366) -->
-    <skip />
+    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
+    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"出荷時試験が失敗"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"FACTORY_TEST操作は、/system/appにインストールされたパッケージのみが対象です。"</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"FACTORY_TEST操作を行うパッケージは見つかりませんでした。"</string>
@@ -737,8 +733,7 @@
     <string name="double_tap_toast" msgid="4595046515400268881">"ヒント: ダブルタップで拡大/縮小できます。"</string>
     <string name="autofill_this_form" msgid="4616758841157816676">"自動入力"</string>
     <string name="setup_autofill" msgid="7103495070180590814">"自動入力を設定"</string>
-    <!-- no translation found for autofill_address_name_separator (6350145154779706772) -->
-    <skip />
+    <string name="autofill_address_name_separator" msgid="6350145154779706772">" "</string>
     <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$3$2$1"</string>
     <string name="autofill_address_summary_separator" msgid="7483307893170324129">"、 "</string>
     <string name="autofill_address_summary_format" msgid="4874459455786827344">"$1$2$3"</string>
@@ -773,10 +768,8 @@
     <string name="permdesc_serialPort" msgid="2991639985224598193">"SerialManager APIを使用してシリアルポートにアクセスすることを所有者に許可します。"</string>
     <string name="permlab_accessContentProvidersExternally" msgid="5077774297943409285">"コンテンツプロバイダへの外部アクセス"</string>
     <string name="permdesc_accessContentProvidersExternally" msgid="4544346486697853685">"シェルからコンテンツプロバイダにアクセスすることを権利所有者に許可します。通常のアプリでは必要ありません。"</string>
-    <!-- no translation found for permlab_updateLock (3527558366616680889) -->
-    <skip />
-    <!-- no translation found for permdesc_updateLock (1655625832166778492) -->
-    <skip />
+    <string name="permlab_updateLock" msgid="3527558366616680889">"端末の自動更新の抑制"</string>
+    <string name="permdesc_updateLock" msgid="1655625832166778492">"非対話型の再起動により端末をアップグレードするのに適したタイミングについて、システムに情報を提供することを権利所有者に許可します。"</string>
     <string name="save_password_message" msgid="767344687139195790">"このパスワードをブラウザで保存しますか?"</string>
     <string name="save_password_notnow" msgid="6389675316706699758">"今は保存しない"</string>
     <string name="save_password_remember" msgid="6491879678996749466">"保存"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 00f34ec..c9801a3 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -769,7 +769,7 @@
     <string name="permlab_accessContentProvidersExternally" msgid="5077774297943409285">"외부에서 콘텐츠 제공자에 액세스"</string>
     <string name="permdesc_accessContentProvidersExternally" msgid="4544346486697853685">"권한을 가진 프로그램이 셸에서 콘텐츠 제공자에 액세스하도록 허용합니다. 일반 앱에서는 필요하지 않습니다."</string>
     <string name="permlab_updateLock" msgid="3527558366616680889">"지금은 자동 기기 업데이트를 권장하지 않음"</string>
-    <string name="permdesc_updateLock" msgid="1655625832166778492">"기기를 스스로 다시 부팅하여 업그레이드해도 괜찮은 시간에 대한 정보를 사용자가 시스템에 제공할 수 있도록 허용합니다."</string>
+    <string name="permdesc_updateLock" msgid="1655625832166778492">"기기를 자동으로 다시 부팅하여 업그레이드해도 괜찮은 시간에 대한 정보를 사용자가 시스템에 제공할 수 있도록 허용합니다."</string>
     <string name="save_password_message" msgid="767344687139195790">"브라우저에 이 비밀번호를 저장하시겠습니까?"</string>
     <string name="save_password_notnow" msgid="6389675316706699758">"나중에"</string>
     <string name="save_password_remember" msgid="6491879678996749466">"저장"</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 13ccc2e..4424ad5 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -768,7 +768,7 @@
     <string name="permdesc_serialPort" msgid="2991639985224598193">"Leidžiama savininkui pasiekti nuosekliuosius prievadus naudojant „SerialManager“ API."</string>
     <string name="permlab_accessContentProvidersExternally" msgid="5077774297943409285">"pasiekti turinio teikėjus iš išorės"</string>
     <string name="permdesc_accessContentProvidersExternally" msgid="4544346486697853685">"Leidžiama savininkui pasiekti turinio teikėjus naudojant apvalkalą. To niekada neturėtų prireikti naudojant įprastas programas."</string>
-    <string name="permlab_updateLock" msgid="3527558366616680889">"Atsisakyti automatinių įrenginio atnaujinimų"</string>
+    <string name="permlab_updateLock" msgid="3527558366616680889">"Atsisakyti autom. įrenginio atnaujinimų"</string>
     <string name="permdesc_updateLock" msgid="1655625832166778492">"Leidžia savininkui pateikti pasiūlymą sistemai dėl tinkamo laiko iš naujo neinteraktyviai įkelti programą, kad būtų naujovinamas įrenginys."</string>
     <string name="save_password_message" msgid="767344687139195790">"Ar norite, kad naršyklė atsimintų šį slaptažodį?"</string>
     <string name="save_password_notnow" msgid="6389675316706699758">"Ne dabar"</string>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index 2c8ca30..5bb95af 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -26,8 +26,7 @@
     <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
     <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
-    <!-- no translation found for fileSizeSuffix (9164292791500531949) -->
-    <skip />
+    <string name="fileSizeSuffix" msgid="9164292791500531949">"<xliff:g id="NUMBER">%1$s</xliff:g><xliff:g id="UNIT">%2$s</xliff:g>"</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;Tidak bertajuk&gt;"</string>
     <string name="ellipsis" msgid="7899829516048813237">"..."</string>
     <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
@@ -672,8 +671,7 @@
     <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Telah melepasi had cubaan Buka Kunci Wajah"</string>
     <string name="lockscreen_plugged_in" msgid="8057762828355572315">"Mengecas, (<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>)"</string>
     <string name="lockscreen_charged" msgid="4938930459620989972">"Sudah dicas."</string>
-    <!-- no translation found for lockscreen_battery_short (4477264849386850266) -->
-    <skip />
+    <string name="lockscreen_battery_short" msgid="4477264849386850266">"<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
     <string name="lockscreen_low_battery" msgid="1482873981919249740">"Sambungkan pengecas anda."</string>
     <string name="lockscreen_missing_sim_message_short" msgid="7381499217732227295">"Tiada kad SIM."</string>
     <string name="lockscreen_missing_sim_message" product="tablet" msgid="151659196095791474">"Tiada kad SIM dalam tablet."</string>
@@ -722,10 +720,8 @@
     <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
     <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
     <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
-    <!-- no translation found for hour_ampm (4584338083529355982) -->
-    <skip />
-    <!-- no translation found for hour_cap_ampm (2083465992940444366) -->
-    <skip />
+    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
+    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"Ujian kilang gagal"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"Tindakan FACTORY_TEST hanya disokong untuk pakej yang dipasangkan dalam /system/app."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"Tiada pakej yang menyediakan tindakan FACTORY_TEST ditemui."</string>
@@ -737,8 +733,7 @@
     <string name="double_tap_toast" msgid="4595046515400268881">"Petua: Ketik dua kali untuk mengezum masuk dan keluar."</string>
     <string name="autofill_this_form" msgid="4616758841157816676">"Auto isi"</string>
     <string name="setup_autofill" msgid="7103495070180590814">"Sediakan Autoisi"</string>
-    <!-- no translation found for autofill_address_name_separator (6350145154779706772) -->
-    <skip />
+    <string name="autofill_address_name_separator" msgid="6350145154779706772">" "</string>
     <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
     <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
     <string name="autofill_address_summary_format" msgid="4874459455786827344">"$1$2$3"</string>
@@ -773,10 +768,8 @@
     <string name="permdesc_serialPort" msgid="2991639985224598193">"Membenarkan pemegang mengakses port bersiri menggunakan API SerialManager."</string>
     <string name="permlab_accessContentProvidersExternally" msgid="5077774297943409285">"akses pembekal kandungan secara luaran"</string>
     <string name="permdesc_accessContentProvidersExternally" msgid="4544346486697853685">"Membolehkan pemegang mengakses pembekal kandungan dari luar. Tidak akan sekali-kali diperlukan untuk apl biasa."</string>
-    <!-- no translation found for permlab_updateLock (3527558366616680889) -->
-    <skip />
-    <!-- no translation found for permdesc_updateLock (1655625832166778492) -->
-    <skip />
+    <string name="permlab_updateLock" msgid="3527558366616680889">"tidak menggalakkan kemas kini peranti automatik"</string>
+    <string name="permdesc_updateLock" msgid="1655625832166778492">"Membenarkan pemegang untuk menawarkan maklumat kepada sistem tentang bila akan menjadi masa yang baik untuk but semula bukan interaktif untuk menaik taraf peranti."</string>
     <string name="save_password_message" msgid="767344687139195790">"Adakah anda mahu penyemak imbas mengingati kata laluan ini?"</string>
     <string name="save_password_notnow" msgid="6389675316706699758">"Bukan sekarang"</string>
     <string name="save_password_remember" msgid="6491879678996749466">"Ingat"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 0973624..6a9f846 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -1088,7 +1088,7 @@
     <string name="ime_action_default" msgid="2840921885558045721">"Utfør"</string>
     <string name="dial_number_using" msgid="5789176425167573586">"Ring nummeret"\n"<xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="create_contact_using" msgid="4947405226788104538">"Lag kontakt"\n"med nummeret <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"Én eller flere av de følgende appene ber om tillatelse til å få tilgang til kontoen din fra nå av."</string>
+    <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"Følgende app(er) ber om tilgang til kontoen din fra nå av."</string>
     <string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"Vil du tillate dette?"</string>
     <string name="grant_permissions_header_text" msgid="6874497408201826708">"Tilgangsforespørsel"</string>
     <string name="allow" msgid="7225948811296386551">"Tillat"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index d77970d..286c32c 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -26,8 +26,7 @@
     <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
     <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
-    <!-- no translation found for fileSizeSuffix (9164292791500531949) -->
-    <skip />
+    <string name="fileSizeSuffix" msgid="9164292791500531949">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;Bez nazwy&gt;"</string>
     <string name="ellipsis" msgid="7899829516048813237">"…"</string>
     <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
@@ -672,8 +671,7 @@
     <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Przekroczono maksymalną liczbę prób odblokowania Face Unlock."</string>
     <string name="lockscreen_plugged_in" msgid="8057762828355572315">"Ładowanie (<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>)"</string>
     <string name="lockscreen_charged" msgid="4938930459620989972">"Naładowany."</string>
-    <!-- no translation found for lockscreen_battery_short (4477264849386850266) -->
-    <skip />
+    <string name="lockscreen_battery_short" msgid="4477264849386850266">"<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
     <string name="lockscreen_low_battery" msgid="1482873981919249740">"Podłącz ładowarkę."</string>
     <string name="lockscreen_missing_sim_message_short" msgid="7381499217732227295">"Brak karty SIM."</string>
     <string name="lockscreen_missing_sim_message" product="tablet" msgid="151659196095791474">"Brak karty SIM w tablecie."</string>
@@ -722,10 +720,8 @@
     <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
     <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
     <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
-    <!-- no translation found for hour_ampm (4584338083529355982) -->
-    <skip />
-    <!-- no translation found for hour_cap_ampm (2083465992940444366) -->
-    <skip />
+    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%P</xliff:g>"</string>
+    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"Nieudany test fabryczny"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"Czynność FACTORY_TEST jest obsługiwana tylko dla pakietów zainstalowanych w katalogu /system/app."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"Nie znaleziono żadnego pakietu, który zapewnia działanie FACTORY_TEST."</string>
@@ -737,8 +733,7 @@
     <string name="double_tap_toast" msgid="4595046515400268881">"Wskazówka: dotknij dwukrotnie, aby powiększyć lub pomniejszyć."</string>
     <string name="autofill_this_form" msgid="4616758841157816676">"Autouzupełnianie"</string>
     <string name="setup_autofill" msgid="7103495070180590814">"Ustaw autouzupełnianie"</string>
-    <!-- no translation found for autofill_address_name_separator (6350145154779706772) -->
-    <skip />
+    <string name="autofill_address_name_separator" msgid="6350145154779706772">" "</string>
     <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
     <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
     <string name="autofill_address_summary_format" msgid="4874459455786827344">"$1$2$3"</string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 6a084c0..cac586e 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -26,8 +26,7 @@
     <string name="gigabyteShort" msgid="3259882455212193214">"GO"</string>
     <string name="terabyteShort" msgid="231613018159186962">"TO"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"PO"</string>
-    <!-- no translation found for fileSizeSuffix (9164292791500531949) -->
-    <skip />
+    <string name="fileSizeSuffix" msgid="9164292791500531949">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;Fără titlu&gt;"</string>
     <string name="ellipsis" msgid="7899829516048813237">"…"</string>
     <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
@@ -672,8 +671,7 @@
     <string name="faceunlock_multiple_failures" msgid="754137583022792429">"S-a depăşit numărul maxim de încercări pentru Deblocare facială"</string>
     <string name="lockscreen_plugged_in" msgid="8057762828355572315">"Se încarcă, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
     <string name="lockscreen_charged" msgid="4938930459620989972">"Încărcată."</string>
-    <!-- no translation found for lockscreen_battery_short (4477264849386850266) -->
-    <skip />
+    <string name="lockscreen_battery_short" msgid="4477264849386850266">"<xliff:g id="NUMBER">%d</xliff:g> <xliff:g id="PERCENT">%%</xliff:g>"</string>
     <string name="lockscreen_low_battery" msgid="1482873981919249740">"Conectaţi încărcătorul."</string>
     <string name="lockscreen_missing_sim_message_short" msgid="7381499217732227295">"Niciun card SIM."</string>
     <string name="lockscreen_missing_sim_message" product="tablet" msgid="151659196095791474">"Nu există card SIM în computerul tablet PC."</string>
@@ -722,10 +720,8 @@
     <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
     <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
     <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
-    <!-- no translation found for hour_ampm (4584338083529355982) -->
-    <skip />
-    <!-- no translation found for hour_cap_ampm (2083465992940444366) -->
-    <skip />
+    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%P</xliff:g>"</string>
+    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"Testarea de fabrică nu a reuşit"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"Acţiunea FACTORY_TEST este acceptată doar pentru pachetele instalate în /system/app."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"Nu s-a găsit niciun pachet care să ofere acţiunea FACTORY_TEST."</string>
@@ -737,8 +733,7 @@
     <string name="double_tap_toast" msgid="4595046515400268881">"Sfat: măriţi şi micşoraţi prin dublă atingere."</string>
     <string name="autofill_this_form" msgid="4616758841157816676">"Automat"</string>
     <string name="setup_autofill" msgid="7103495070180590814">"Conf.Compl.auto."</string>
-    <!-- no translation found for autofill_address_name_separator (6350145154779706772) -->
-    <skip />
+    <string name="autofill_address_name_separator" msgid="6350145154779706772">" "</string>
     <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
     <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
     <string name="autofill_address_summary_format" msgid="4874459455786827344">"$1$2$3"</string>
@@ -773,10 +768,8 @@
     <string name="permdesc_serialPort" msgid="2991639985224598193">"Permite posesorului accesul la porturile serial utilizând API-ul SerialManager."</string>
     <string name="permlab_accessContentProvidersExternally" msgid="5077774297943409285">"accesaţi furniz. de conţin. din exterior"</string>
     <string name="permdesc_accessContentProvidersExternally" msgid="4544346486697853685">"Permite deţinătorului să acceseze furnizorii de conţinut din interfaţă. Nu ar trebui să fie necesară pentru aplicaţiile normale."</string>
-    <!-- no translation found for permlab_updateLock (3527558366616680889) -->
-    <skip />
-    <!-- no translation found for permdesc_updateLock (1655625832166778492) -->
-    <skip />
+    <string name="permlab_updateLock" msgid="3527558366616680889">"descuraj. actual. autom. ale dispozitiv."</string>
+    <string name="permdesc_updateLock" msgid="1655625832166778492">"Permite proprietarului să ofere sistemului informaţii cu privire la momentul oportun pentru o repornire noninteractivă în scopul trecerii dispozitivului la o versiune superioară."</string>
     <string name="save_password_message" msgid="767344687139195790">"Doriţi ca browserul să reţină această parolă?"</string>
     <string name="save_password_notnow" msgid="6389675316706699758">"Nu acum"</string>
     <string name="save_password_remember" msgid="6491879678996749466">"Reţineţi"</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index deb810f..3a554d6 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -26,8 +26,7 @@
     <string name="gigabyteShort" msgid="3259882455212193214">"ГБ"</string>
     <string name="terabyteShort" msgid="231613018159186962">"TБ"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"ПБ"</string>
-    <!-- no translation found for fileSizeSuffix (9164292791500531949) -->
-    <skip />
+    <string name="fileSizeSuffix" msgid="9164292791500531949">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;Без названия&gt;"</string>
     <string name="ellipsis" msgid="7899829516048813237">"…"</string>
     <string name="ellipsis_two_dots" msgid="1228078994866030736">"..."</string>
@@ -672,8 +671,7 @@
     <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Все попытки войти с помощью Фейсконтроля использованы"</string>
     <string name="lockscreen_plugged_in" msgid="8057762828355572315">"Идет зарядка (<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>)"</string>
     <string name="lockscreen_charged" msgid="4938930459620989972">"Батарея заряжена"</string>
-    <!-- no translation found for lockscreen_battery_short (4477264849386850266) -->
-    <skip />
+    <string name="lockscreen_battery_short" msgid="4477264849386850266">"<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
     <string name="lockscreen_low_battery" msgid="1482873981919249740">"Подключите зарядное устройство."</string>
     <string name="lockscreen_missing_sim_message_short" msgid="7381499217732227295">"Нет SIM-карты"</string>
     <string name="lockscreen_missing_sim_message" product="tablet" msgid="151659196095791474">"SIM-карта не установлена."</string>
@@ -722,10 +720,8 @@
     <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
     <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"АБВ"</string>
     <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
-    <!-- no translation found for hour_ampm (4584338083529355982) -->
-    <skip />
-    <!-- no translation found for hour_cap_ampm (2083465992940444366) -->
-    <skip />
+    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%P</xliff:g>"</string>
+    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"Не удалось провести стандартный тест"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"Действие FACTORY_TEST поддерживается только для пакетов, установленных в /system/app."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"Пакет, обеспечивающий действие FACTORY_TEST, не найден."</string>
@@ -737,8 +733,7 @@
     <string name="double_tap_toast" msgid="4595046515400268881">"Совет: нажмите дважды, чтобы увеличить и уменьшить масштаб."</string>
     <string name="autofill_this_form" msgid="4616758841157816676">"Автозаполнение"</string>
     <string name="setup_autofill" msgid="7103495070180590814">"Настроить автозаполнение"</string>
-    <!-- no translation found for autofill_address_name_separator (6350145154779706772) -->
-    <skip />
+    <string name="autofill_address_name_separator" msgid="6350145154779706772">" "</string>
     <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
     <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
     <string name="autofill_address_summary_format" msgid="4874459455786827344">"$1$2$3"</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 4d4c9cd..daa321d 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -26,8 +26,7 @@
     <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
     <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
-    <!-- no translation found for fileSizeSuffix (9164292791500531949) -->
-    <skip />
+    <string name="fileSizeSuffix" msgid="9164292791500531949">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;Bez mena&gt;"</string>
     <string name="ellipsis" msgid="7899829516048813237">"…"</string>
     <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
@@ -672,8 +671,7 @@
     <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Prekročili ste maximálny povolený počet pokusov o odomknutie tvárou"</string>
     <string name="lockscreen_plugged_in" msgid="8057762828355572315">"Prebieha nabíjanie, <xliff:g id="NUMBER">%d</xliff:g> <xliff:g id="PERCENT">%%</xliff:g>"</string>
     <string name="lockscreen_charged" msgid="4938930459620989972">"Nabité."</string>
-    <!-- no translation found for lockscreen_battery_short (4477264849386850266) -->
-    <skip />
+    <string name="lockscreen_battery_short" msgid="4477264849386850266">"<xliff:g id="NUMBER">%d</xliff:g> <xliff:g id="PERCENT">%%</xliff:g>"</string>
     <string name="lockscreen_low_battery" msgid="1482873981919249740">"Pripojte nabíjačku."</string>
     <string name="lockscreen_missing_sim_message_short" msgid="7381499217732227295">"Nie je vložená karta SIM."</string>
     <string name="lockscreen_missing_sim_message" product="tablet" msgid="151659196095791474">"V tablete nie je žiadna karta SIM."</string>
@@ -722,10 +720,8 @@
     <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
     <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
     <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
-    <!-- no translation found for hour_ampm (4584338083529355982) -->
-    <skip />
-    <!-- no translation found for hour_cap_ampm (2083465992940444366) -->
-    <skip />
+    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%P</xliff:g>"</string>
+    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g> <xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"Továrenský test zlyhal"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"Test FACTORY_TEST je možné uskutočniť iba pri balíčkoch nainštalovaných v priečinku /system/app."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"Nebol nájdený žiadny balíček umožňujúci test FACTORY_TEST."</string>
@@ -737,8 +733,7 @@
     <string name="double_tap_toast" msgid="4595046515400268881">"Tip: Dvojitým klepnutím môžete zobrazenie priblížiť alebo oddialiť."</string>
     <string name="autofill_this_form" msgid="4616758841157816676">"Aut.dop."</string>
     <string name="setup_autofill" msgid="7103495070180590814">"Nast. Aut. dop."</string>
-    <!-- no translation found for autofill_address_name_separator (6350145154779706772) -->
-    <skip />
+    <string name="autofill_address_name_separator" msgid="6350145154779706772">" "</string>
     <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
     <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
     <string name="autofill_address_summary_format" msgid="4874459455786827344">"$1$2$3"</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 2ed2ad6..286e6d6 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -26,8 +26,7 @@
     <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
     <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
-    <!-- no translation found for fileSizeSuffix (9164292791500531949) -->
-    <skip />
+    <string name="fileSizeSuffix" msgid="9164292791500531949">"<xliff:g id="NUMBER">%1$s</xliff:g><xliff:g id="UNIT">%2$s</xliff:g>"</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;Haina jina&gt;"</string>
     <string name="ellipsis" msgid="7899829516048813237">"…"</string>
     <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
@@ -672,8 +671,7 @@
     <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Majaribio ya Juu ya Kufungua Uso yamezidishwa"</string>
     <string name="lockscreen_plugged_in" msgid="8057762828355572315">"Inachaji <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
     <string name="lockscreen_charged" msgid="4938930459620989972">"Imechajiwa."</string>
-    <!-- no translation found for lockscreen_battery_short (4477264849386850266) -->
-    <skip />
+    <string name="lockscreen_battery_short" msgid="4477264849386850266">"<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
     <string name="lockscreen_low_battery" msgid="1482873981919249740">"Unganisha chaja yako"</string>
     <string name="lockscreen_missing_sim_message_short" msgid="7381499217732227295">"Hakuna SIM kadi."</string>
     <string name="lockscreen_missing_sim_message" product="tablet" msgid="151659196095791474">"Hakuna SIM kadi katika kompyuta ndogo."</string>
@@ -722,10 +720,8 @@
     <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
     <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
     <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
-    <!-- no translation found for hour_ampm (4584338083529355982) -->
-    <skip />
-    <!-- no translation found for hour_cap_ampm (2083465992940444366) -->
-    <skip />
+    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%P</xliff:g>"</string>
+    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="HOUR">%-l</xliff:g><xliff:g id="AMPM">%p</xliff:g>"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"Jaribio la kiwanda limeshindikana"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"Tendo la JARIBIO_LA KIWANDA  linahimiliwa tu kwa furushi zilizosakinishwa katika /system/app."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"Hakuna furushi lililopatikana ambalo linatoa tendo la JARIBIO_LA KIWANDA."</string>
@@ -737,8 +733,7 @@
     <string name="double_tap_toast" msgid="4595046515400268881">"Kidokezo: Gonga mara mbili ili kukuza ndani na nje."</string>
     <string name="autofill_this_form" msgid="4616758841157816676">"Mjazo-otomatiki"</string>
     <string name="setup_autofill" msgid="7103495070180590814">"Sanidi Mjazo-otomati"</string>
-    <!-- no translation found for autofill_address_name_separator (6350145154779706772) -->
-    <skip />
+    <string name="autofill_address_name_separator" msgid="6350145154779706772">" "</string>
     <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
     <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
     <string name="autofill_address_summary_format" msgid="4874459455786827344">"$1$2$3"</string>
@@ -773,10 +768,8 @@
     <string name="permdesc_serialPort" msgid="2991639985224598193">"Inaruhusu mmiliki kufikia vituo tambulishi kwa kutumia KisimamiziTambulishi cha API."</string>
     <string name="permlab_accessContentProvidersExternally" msgid="5077774297943409285">"fikia watoa huduma nje"</string>
     <string name="permdesc_accessContentProvidersExternally" msgid="4544346486697853685">"Inaruhusu mmiliki kufikia watoa huduma  kutoka kwa onyesho. Haifai kuhitajika kamwe kwa programu za kawaida."</string>
-    <!-- no translation found for permlab_updateLock (3527558366616680889) -->
-    <skip />
-    <!-- no translation found for permdesc_updateLock (1655625832166778492) -->
-    <skip />
+    <string name="permlab_updateLock" msgid="3527558366616680889">"katisha tamaa usasishaji kifaa kiotomatiki"</string>
+    <string name="permdesc_updateLock" msgid="1655625832166778492">"Inaruhusu mmiliki kutoa maelezo kwa mfumo kuhusu ni lini itakuwa wakati mzuri wa uwashaji upya usiotagusana ili kuboresha kifaa."</string>
     <string name="save_password_message" msgid="767344687139195790">"Unataka kuvinjari ili ukumbuke nenosiri hili?"</string>
     <string name="save_password_notnow" msgid="6389675316706699758">"Si Sasa"</string>
     <string name="save_password_remember" msgid="6491879678996749466">"Kumbuka"</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 4aba67c..24b726d 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -26,8 +26,7 @@
     <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
     <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
     <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
-    <!-- no translation found for fileSizeSuffix (9164292791500531949) -->
-    <skip />
+    <string name="fileSizeSuffix" msgid="9164292791500531949">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
     <string name="untitled" msgid="4638956954852782576">"&lt;未命名&gt;"</string>
     <string name="ellipsis" msgid="7899829516048813237">"..."</string>
     <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
@@ -672,8 +671,7 @@
     <string name="faceunlock_multiple_failures" msgid="754137583022792429">"已超过“人脸解锁”尝试次数上限"</string>
     <string name="lockscreen_plugged_in" msgid="8057762828355572315">"正在充电,<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
     <string name="lockscreen_charged" msgid="4938930459620989972">"已充满。"</string>
-    <!-- no translation found for lockscreen_battery_short (4477264849386850266) -->
-    <skip />
+    <string name="lockscreen_battery_short" msgid="4477264849386850266">"<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
     <string name="lockscreen_low_battery" msgid="1482873981919249740">"连接您的充电器。"</string>
     <string name="lockscreen_missing_sim_message_short" msgid="7381499217732227295">"没有 SIM 卡"</string>
     <string name="lockscreen_missing_sim_message" product="tablet" msgid="151659196095791474">"平板电脑中没有 SIM 卡。"</string>
@@ -722,10 +720,8 @@
     <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
     <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
     <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
-    <!-- no translation found for hour_ampm (4584338083529355982) -->
-    <skip />
-    <!-- no translation found for hour_cap_ampm (2083465992940444366) -->
-    <skip />
+    <string name="hour_ampm" msgid="4584338083529355982">"<xliff:g id="AMPM">%P</xliff:g> <xliff:g id="HOUR">%-l</xliff:g>"</string>
+    <string name="hour_cap_ampm" msgid="2083465992940444366">"<xliff:g id="AMPM">%p</xliff:g> <xliff:g id="HOUR">%-l</xliff:g>"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"出厂测试失败"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"只有在 /system/app 中安装的包支持 FACTORY_TEST 操作。"</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"未发现支持 FACTORY_TEST 操作的包。"</string>
@@ -737,8 +733,7 @@
     <string name="double_tap_toast" msgid="4595046515400268881">"提示:点按两次可放大或缩小。"</string>
     <string name="autofill_this_form" msgid="4616758841157816676">"自动填充"</string>
     <string name="setup_autofill" msgid="7103495070180590814">"设置自动填充"</string>
-    <!-- no translation found for autofill_address_name_separator (6350145154779706772) -->
-    <skip />
+    <string name="autofill_address_name_separator" msgid="6350145154779706772">" "</string>
     <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
     <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
     <string name="autofill_address_summary_format" msgid="4874459455786827344">"$1$2$3"</string>
@@ -773,10 +768,8 @@
     <string name="permdesc_serialPort" msgid="2991639985224598193">"允许持有人使用 SerialManager API 访问串行端口。"</string>
     <string name="permlab_accessContentProvidersExternally" msgid="5077774297943409285">"从外部访问内容提供程序"</string>
     <string name="permdesc_accessContentProvidersExternally" msgid="4544346486697853685">"允许持有者通过界面访问内容提供程序。普通应用绝不需要此权限。"</string>
-    <!-- no translation found for permlab_updateLock (3527558366616680889) -->
-    <skip />
-    <!-- no translation found for permdesc_updateLock (1655625832166778492) -->
-    <skip />
+    <string name="permlab_updateLock" msgid="3527558366616680889">"阻止自动设备更新"</string>
+    <string name="permdesc_updateLock" msgid="1655625832166778492">"允许持有人向系统提供相关信息,以确定什么时候适合执行非交互式重新启动来升级设备。"</string>
     <string name="save_password_message" msgid="767344687139195790">"是否希望浏览器记住此密码?"</string>
     <string name="save_password_notnow" msgid="6389675316706699758">"暂不保存"</string>
     <string name="save_password_remember" msgid="6491879678996749466">"记住"</string>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index eaf9c8c..49f2823 100755
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -18,7 +18,7 @@
 -->
 
 <!-- These resources are around just to allow their values to be customized
-     for different hardware and product builds. -->
+     for different hardware and product builds.  Do not translate. -->
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <!-- Do not translate. Defines the slots for the right-hand side icons.  That is to say, the
          icons in the status bar that are not notifications. -->
diff --git a/core/tests/benchmarks/README b/core/tests/benchmarks/README
new file mode 100644
index 0000000..0a41bcc
--- /dev/null
+++ b/core/tests/benchmarks/README
@@ -0,0 +1,8 @@
+
+These benchmarks use the Caliper benchmark framework, and can be
+run on a remote device using Vogar:
+
+http://code.google.com/p/caliper/
+http://code.google.com/p/vogar/
+
+$ vogar --benchmark path/to/Benchmark.java
diff --git a/core/tests/benchmarks/src/android/os/ParcelArrayBenchmark.java b/core/tests/benchmarks/src/android/os/ParcelArrayBenchmark.java
new file mode 100644
index 0000000..21cfb09
--- /dev/null
+++ b/core/tests/benchmarks/src/android/os/ParcelArrayBenchmark.java
@@ -0,0 +1,122 @@
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.os;
+
+import com.google.caliper.Param;
+import com.google.caliper.SimpleBenchmark;
+
+public class ParcelArrayBenchmark extends SimpleBenchmark {
+
+    @Param({ "1", "10", "100", "1000" })
+    private int mSize;
+
+    private Parcel mWriteParcel;
+
+    private byte[] mByteArray;
+    private int[] mIntArray;
+    private long[] mLongArray;
+
+    private Parcel mByteParcel;
+    private Parcel mIntParcel;
+    private Parcel mLongParcel;
+
+    @Override
+    protected void setUp() {
+        mWriteParcel = Parcel.obtain();
+
+        mByteArray = new byte[mSize];
+        mIntArray = new int[mSize];
+        mLongArray = new long[mSize];
+
+        mByteParcel = Parcel.obtain();
+        mByteParcel.writeByteArray(mByteArray);
+        mIntParcel = Parcel.obtain();
+        mIntParcel.writeIntArray(mIntArray);
+        mLongParcel = Parcel.obtain();
+        mLongParcel.writeLongArray(mLongArray);
+    }
+
+    @Override
+    protected void tearDown() {
+        mWriteParcel.recycle();
+        mWriteParcel = null;
+    }
+
+    public void timeWriteByteArray(int reps) {
+        for (int i = 0; i < reps; i++) {
+            mWriteParcel.setDataPosition(0);
+            mWriteParcel.writeByteArray(mByteArray);
+        }
+    }
+
+    public void timeCreateByteArray(int reps) {
+        for (int i = 0; i < reps; i++) {
+            mByteParcel.setDataPosition(0);
+            mByteParcel.createByteArray();
+        }
+    }
+
+    public void timeReadByteArray(int reps) {
+        for (int i = 0; i < reps; i++) {
+            mByteParcel.setDataPosition(0);
+            mByteParcel.readByteArray(mByteArray);
+        }
+    }
+
+    public void timeWriteIntArray(int reps) {
+        for (int i = 0; i < reps; i++) {
+            mWriteParcel.setDataPosition(0);
+            mWriteParcel.writeIntArray(mIntArray);
+        }
+    }
+
+    public void timeCreateIntArray(int reps) {
+        for (int i = 0; i < reps; i++) {
+            mIntParcel.setDataPosition(0);
+            mIntParcel.createIntArray();
+        }
+    }
+
+    public void timeReadIntArray(int reps) {
+        for (int i = 0; i < reps; i++) {
+            mIntParcel.setDataPosition(0);
+            mIntParcel.readIntArray(mIntArray);
+        }
+    }
+
+    public void timeWriteLongArray(int reps) {
+        for (int i = 0; i < reps; i++) {
+            mWriteParcel.setDataPosition(0);
+            mWriteParcel.writeLongArray(mLongArray);
+        }
+    }
+
+    public void timeCreateLongArray(int reps) {
+        for (int i = 0; i < reps; i++) {
+            mLongParcel.setDataPosition(0);
+            mLongParcel.createLongArray();
+        }
+    }
+
+    public void timeReadLongArray(int reps) {
+        for (int i = 0; i < reps; i++) {
+            mLongParcel.setDataPosition(0);
+            mLongParcel.readLongArray(mLongArray);
+        }
+    }
+
+}
diff --git a/core/tests/benchmarks/src/android/os/ParcelBenchmark.java b/core/tests/benchmarks/src/android/os/ParcelBenchmark.java
new file mode 100644
index 0000000..6a7b7c89
--- /dev/null
+++ b/core/tests/benchmarks/src/android/os/ParcelBenchmark.java
@@ -0,0 +1,77 @@
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.os;
+
+import com.google.caliper.SimpleBenchmark;
+
+public class ParcelBenchmark extends SimpleBenchmark {
+
+    private Parcel mParcel;
+
+    @Override
+    protected void setUp() {
+        mParcel = Parcel.obtain();
+    }
+
+    @Override
+    protected void tearDown() {
+        mParcel.recycle();
+        mParcel = null;
+    }
+
+    public void timeWriteByte(int reps) {
+        final byte val = 0xF;
+        for (int i = 0; i < reps; i++) {
+            mParcel.writeByte(val);
+        }
+    }
+
+    public void timeReadByte(int reps) {
+        mParcel.setDataCapacity(reps);
+        for (int i = 0; i < reps; i++) {
+            mParcel.readByte();
+        }
+    }
+
+    public void timeWriteInt(int reps) {
+        final int val = 0xF;
+        for (int i = 0; i < reps; i++) {
+            mParcel.writeInt(val);
+        }
+    }
+
+    public void timeReadInt(int reps) {
+        mParcel.setDataCapacity(reps << 2);
+        for (int i = 0; i < reps; i++) {
+            mParcel.readInt();
+        }
+    }
+
+    public void timeWriteLong(int reps) {
+        final long val = 0xF;
+        for (int i = 0; i < reps; i++) {
+            mParcel.writeLong(val);
+        }
+    }
+
+    public void timeReadLong(int reps) {
+        mParcel.setDataCapacity(reps << 3);
+        for (int i = 0; i < reps; i++) {
+            mParcel.readLong();
+        }
+    }
+}
diff --git a/docs/html/guide/market/expansion-files.jd b/docs/html/guide/market/expansion-files.jd
index cd9b57a..fad30e9 100644
--- a/docs/html/guide/market/expansion-files.jd
+++ b/docs/html/guide/market/expansion-files.jd
@@ -421,7 +421,7 @@
 
 <p>To use APK expansion files with your application and provide the best user experience with
 minimal effort on your behalf, we recommend you use the Downloader Library that's included in the
-Android Market APK Expansion Library package. This library downloads your expansion files in a
+Google Market Apk Expansion package. This library downloads your expansion files in a
 background service, shows a user notification with the download status, handles network
 connectivity loss, resumes the download when possible, and more.</p>
 
@@ -447,10 +447,11 @@
 download two packages from the SDK Manager and add the appropriate libraries to your
 application.</p>
 
-<p>First, open the Android SDK Manager, expand <em>Extras</em> and download:</p>
+<p>First, open the <a href="{@docRoot}sdk/adding-components.html">Android SDK Manager</a>, expand
+<em>Extras</em> and download:</p>
 <ul>
   <li><em>Google Market Licensing package</em></li>
-  <li><em>Google Market APK Expansion Library package</em></li>
+  <li><em>Google Market Apk Expansion package</em></li>
 </ul>
 
 <p>If you're using Eclipse, create a project for each library and add it to your app:</p>
@@ -498,10 +499,10 @@
 from the shared storage is a separate implementation that you should consider based on your
 application needs.</p>
 
-<p class="note"><strong>Tip:</strong> The APK Expansion Library package includes a sample
+<p class="note"><strong>Tip:</strong> The Apk Expansion package includes a sample
 application
 that shows how to use the Downloader Library in an app. The sample uses a third library
-available in the APK Expansion Library package called the APK Expansion Zip Library. If
+available in the Apk Expansion package called the APK Expansion Zip Library. If
 you plan on
 using ZIP files for your expansion files, we suggest you also add the APK Expansion Zip Library to
 your application. For more information, see the section below
@@ -686,7 +687,7 @@
 versionCode)}</li>
     <li>{@code doesFileExist(Context c, String fileName, long fileSize)}</li>
   </ul>
-    <p>For example, the sample app provided in the APK Expansion Library package calls the
+    <p>For example, the sample app provided in the Apk Expansion package calls the
 following method in the activity's {@link android.app.Activity#onCreate onCreate()} method to check
 whether the expansion files already exist on the device:</p>
 <pre>
@@ -872,7 +873,7 @@
 </dl>
 <p class="note"><strong>Tip:</strong> For examples of these callbacks that update the download
 progress UI, see the {@code SampleDownloaderActivity} in the sample app provided with the
-APK Expansion Library package.</p>
+Apk Expansion package.</p>
 
 <p>Some public methods for the {@code IDownloaderService} interface you might find useful are:</p>
 
@@ -1037,7 +1038,7 @@
 </div>
 </div>
 
-<p>The Android Market APK Expansion Library package includes a library called the APK
+<p>The Google Market Apk Expansion package includes a library called the APK
 Expansion Zip Library (located in {@code
 &lt;sdk>/extras/google/google_market_apk_expansion/zip_file/}). This is an optional library that
 helps you read your expansion
@@ -1089,7 +1090,7 @@
 provider {@link android.net.Uri} in order to provide file access for certain Android APIs that
 expect {@link android.net.Uri} access to media files.
       <p>The sample application available in the
-APK Expansion Library package demonstrates a scenario in which this class is useful
+Apk Expansion package demonstrates a scenario in which this class is useful
 to specify a video with {@link android.widget.VideoView#setVideoURI
 VideoView.setVideoURI()}. See the sample app's class {@code SampleZipfileProvider} for an
 example of how to extend this class to use in your application.</p></dd>
@@ -1226,7 +1227,7 @@
 files. Your application code must perform any necessary patches itself.</p>
 
 <p>If you use ZIP files as your expansion files, the <a href="#ZipLib">APK Expansion Zip
-Library</a> that's included with the APK Expansion Library package includes the ability to merge
+Library</a> that's included with the Apk Expansion package includes the ability to merge
 your
 patch file with the main expansion file.</p>
 
@@ -1249,7 +1250,7 @@
 previous version (and so must your application when performing manual updates).</li>
   <li>When adding a patch expansion file, the Android system does not actually patch your
 application or main expansion file. You must design your application to support the patch data.
-However, the APK Expansion Library package includes a library for using ZIP files
+However, the Apk Expansion package includes a library for using ZIP files
 as expansion files, which merges the data from the patch file into the main expansion file so
 you can easily read all the expansion file data.</li>
 </ul>
diff --git a/docs/html/resources/dashboard/platform-versions.jd b/docs/html/resources/dashboard/platform-versions.jd
index 9631059..acb8472 100644
--- a/docs/html/resources/dashboard/platform-versions.jd
+++ b/docs/html/resources/dashboard/platform-versions.jd
@@ -52,7 +52,7 @@
 <div class="dashboard-panel">
 
 <img alt="" height="250" width="470"
-src="http://chart.apis.google.com/chart?&cht=p&chs=460x250&chd=t:0.1,0.4,0.8,6.6,25.2,0.5,61.4,1.1,2.1,0.4,1.2&chl=Android%201.5|Android%201.6|Android%202.1|Android%202.2|Android%202.3|Android%202.3.3|Android%203.1|Android%203.2|Android%204.0|Android%204.0.3&chco=c4df9b,6fad0c" />
+src="http://chart.apis.google.com/chart?&cht=p&chs=460x250&chd=t:0.4,0.8,6.6,25.2,0.5,61.4,0.1,1.1,2.1,0.4,1.2&chl=Android%201.5|Android%201.6|Android%202.1|Android%202.2|Android%202.3|Android%202.3.3|Android%203.0|Android%203.1|Android%203.2|Android%204.0|Android%204.0.3&chco=c4df9b,6fad0c" />
 
 <table>
 <tr>
diff --git a/libs/gui/BufferQueue.cpp b/libs/gui/BufferQueue.cpp
index 25a4c22..cb8abdd 100644
--- a/libs/gui/BufferQueue.cpp
+++ b/libs/gui/BufferQueue.cpp
@@ -111,7 +111,7 @@
         // easy, we just have more buffers
         mBufferCount = bufferCount;
         mServerBufferCount = bufferCount;
-        mDequeueCondition.signal();
+        mDequeueCondition.broadcast();
     } else {
         // we're here because we're either
         // - reducing the number of available buffers
@@ -192,7 +192,7 @@
     mClientBufferCount = bufferCount;
     mBufferHasBeenQueued = false;
     mQueue.clear();
-    mDequeueCondition.signal();
+    mDequeueCondition.broadcast();
     return OK;
 }
 
@@ -306,6 +306,7 @@
             if (numberOfBuffersNeedsToChange) {
                 // here we're guaranteed that mQueue is empty
                 freeAllBuffersLocked();
+                // XXX: signal?
                 mBufferCount = mServerBufferCount;
                 if (mBufferCount < minBufferCountNeeded)
                     mBufferCount = minBufferCountNeeded;
@@ -370,18 +371,13 @@
                 }
             }
 
-            // we're in synchronous mode and didn't find a buffer, we need to
-            // wait for some buffers to be consumed
-            tryAgain = mSynchronousMode && (foundSync == INVALID_BUFFER_SLOT);
+            // if no buffer is found, wait for a buffer to be released
+            tryAgain = found == INVALID_BUFFER_SLOT;
             if (tryAgain) {
                 mDequeueCondition.wait(mMutex);
             }
         }
 
-        if (mSynchronousMode && found == INVALID_BUFFER_SLOT) {
-            // foundSync guaranteed to be != INVALID_BUFFER_SLOT
-            found = foundSync;
-        }
 
         if (found == INVALID_BUFFER_SLOT) {
             // This should not happen.
@@ -496,7 +492,7 @@
         // - if the client set the number of buffers, we're guaranteed that
         // we have at least 3 (because we don't allow less)
         mSynchronousMode = enabled;
-        mDequeueCondition.signal();
+        mDequeueCondition.broadcast();
     }
     return err;
 }
@@ -564,7 +560,7 @@
         mSlots[buf].mFrameNumber = mFrameCounter;
 
         mBufferHasBeenQueued = true;
-        mDequeueCondition.signal();
+        mDequeueCondition.broadcast();
 
         *outWidth = mDefaultWidth;
         *outHeight = mDefaultHeight;
@@ -601,7 +597,7 @@
     }
     mSlots[buf].mBufferState = BufferSlot::FREE;
     mSlots[buf].mFrameNumber = 0;
-    mDequeueCondition.signal();
+    mDequeueCondition.broadcast();
 }
 
 status_t BufferQueue::setCrop(const Rect& crop) {
@@ -709,7 +705,7 @@
                 mNextCrop.makeInvalid();
                 mNextScalingMode = NATIVE_WINDOW_SCALING_MODE_FREEZE;
                 mNextTransform = 0;
-                mDequeueCondition.signal();
+                mDequeueCondition.broadcast();
             } else {
                 ST_LOGE("disconnect: connected to another api (cur=%d, req=%d)",
                         mConnectedApi, api);
@@ -846,6 +842,7 @@
 
         mSlots[buf].mBufferState = BufferSlot::ACQUIRED;
         mQueue.erase(front);
+        mDequeueCondition.broadcast();
 
         ATRACE_INT(mConsumerName.string(), mQueue.size());
     }
@@ -877,7 +874,8 @@
             || mSlots[buf].mBufferState == BufferSlot::ACQUIRED) {
         mSlots[buf].mBufferState = BufferSlot::FREE;
     }
-    mDequeueCondition.signal();
+
+    mDequeueCondition.broadcast();
 
     return OK;
 }
@@ -888,7 +886,7 @@
     // is considered abandoned
     mAbandoned = true;
     freeAllBuffersLocked();
-    mDequeueCondition.signal();
+    mDequeueCondition.broadcast();
     return OK;
 }
 
diff --git a/libs/rs/driver/rsdCore.cpp b/libs/rs/driver/rsdCore.cpp
index bf2b62a..403393f 100644
--- a/libs/rs/driver/rsdCore.cpp
+++ b/libs/rs/driver/rsdCore.cpp
@@ -34,7 +34,6 @@
 #include <sys/resource.h>
 #include <sched.h>
 #include <cutils/properties.h>
-#include <cutils/sched_policy.h>
 #include <sys/syscall.h>
 #include <string.h>
 #include <bcc/bcc.h>
diff --git a/libs/rs/rsContext.cpp b/libs/rs/rsContext.cpp
index 95ac76e..0f3cea7 100644
--- a/libs/rs/rsContext.cpp
+++ b/libs/rs/rsContext.cpp
@@ -26,7 +26,6 @@
 
 #include <cutils/properties.h>
 
-#include <cutils/sched_policy.h>
 #include <sys/syscall.h>
 #include <string.h>
 
@@ -354,17 +353,7 @@
     // This is probably not what we want for something the user is actively
     // looking at.
     mThreadPriority = p;
-#if 0
-    SchedPolicy pol = SP_FOREGROUND;
-    if (p > 0) {
-        pol = SP_BACKGROUND;
-    }
-    if (!set_sched_policy(mNativeThreadId, pol)) {
-        // success; reset the priority as well
-    }
-#else
     setpriority(PRIO_PROCESS, mNativeThreadId, p);
-#endif
     mHal.funcs.setPriority(this, mThreadPriority);
 }
 
diff --git a/media/java/android/media/MediaActionSound.java b/media/java/android/media/MediaActionSound.java
new file mode 100644
index 0000000..d0e6910
--- /dev/null
+++ b/media/java/android/media/MediaActionSound.java
@@ -0,0 +1,194 @@
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media;
+
+import android.media.AudioManager;
+import android.media.SoundPool;
+import android.util.Log;
+
+/**
+ * <p>A class for producing sounds that match those produced by various actions
+ * taken by the media and camera APIs.  </p>
+ *
+ * <p>Use this class to play an appropriate camera operation sound when
+ * implementing a custom still or video recording mechanism (through the Camera
+ * preview callbacks with {@link android.hardware.Camera#setPreviewCallback
+ * Camera.setPreviewCallback}, or through GPU processing with {@link
+ * android.hardware.Camera#setPreviewTexture Camera.setPreviewTexture}, for
+ * example), or when implementing some other camera-like function in your
+ * application.</p>
+ *
+ * <p>There is no need to play sounds when using
+ * {@link android.hardware.Camera#takePicture Camera.takePicture} or
+ * {@link android.media.MediaRecorder} for still images or video, respectively,
+ * as the Android framework will play the appropriate sounds when needed for
+ * these calls.</p>
+ *
+ */
+public class MediaActionSound {
+    private static final int NUM_MEDIA_SOUND_STREAMS = 1;
+
+    private SoundPool mSoundPool;
+    private int[]     mSoundIds;
+    private int       mSoundIdToPlay;
+
+    private static final String[] SOUND_FILES = {
+        "/system/media/audio/ui/camera_click.ogg",
+        "/system/media/audio/ui/camera_focus.ogg",
+        "/system/media/audio/ui/VideoRecord.ogg",
+        "/system/media/audio/ui/VideoRecord.ogg"
+    };
+
+    private static final String TAG = "MediaActionSound";
+    /**
+     * The sound used by
+     * {@link android.hardware.Camera#takePicture Camera.takePicture} to
+     * indicate still image capture.
+     * @see #play
+     */
+    public static final int SHUTTER_CLICK         = 0;
+
+    /**
+     * A sound to indicate that focusing has completed. Because deciding
+     * when this occurs is application-dependent, this sound is not used by
+     * any methods in the media or camera APIs.
+     * @see #play
+     */
+    public static final int FOCUS_COMPLETE        = 1;
+
+    /**
+     * The sound used by
+     * {@link android.media.MediaRecorder#start MediaRecorder.start()} to
+     * indicate the start of video recording.
+     * @see #play
+     */
+    public static final int START_VIDEO_RECORDING = 2;
+
+    /**
+     * The sound used by
+     * {@link android.media.MediaRecorder#stop MediaRecorder.stop()} to
+     * indicate the end of video recording.
+     * @see #play
+     */
+    public static final int STOP_VIDEO_RECORDING  = 3;
+
+    private static final int SOUND_NOT_LOADED = -1;
+
+    /**
+     * Construct a new MediaActionSound instance. Only a single instance is
+     * needed for playing any platform media action sound; you do not need a
+     * separate instance for each sound type.
+     */
+    public MediaActionSound() {
+        mSoundPool = new SoundPool(NUM_MEDIA_SOUND_STREAMS,
+                AudioManager.STREAM_SYSTEM_ENFORCED, 0);
+        mSoundPool.setOnLoadCompleteListener(mLoadCompleteListener);
+        mSoundIds = new int[SOUND_FILES.length];
+        for (int i = 0; i < mSoundIds.length; i++) {
+            mSoundIds[i] = SOUND_NOT_LOADED;
+        }
+        mSoundIdToPlay = SOUND_NOT_LOADED;
+    }
+
+    /**
+     * Preload a predefined platform sound to minimize latency when the sound is
+     * played later by {@link #play}.
+     * @param soundName The type of sound to preload, selected from
+     *         SHUTTER_CLICK, FOCUS_COMPLETE, START_VIDEO_RECORDING, or
+     *         STOP_VIDEO_RECORDING.
+     * @see #play
+     * @see #SHUTTER_CLICK
+     * @see #FOCUS_COMPLETE
+     * @see #START_VIDEO_RECORDING
+     * @see #STOP_VIDEO_RECORDING
+     */
+    public synchronized void load(int soundName) {
+        if (soundName < 0 || soundName >= SOUND_FILES.length) {
+            throw new RuntimeException("Unknown sound requested: " + soundName);
+        }
+        if (mSoundIds[soundName] == SOUND_NOT_LOADED) {
+            mSoundIds[soundName] =
+                    mSoundPool.load(SOUND_FILES[soundName], 1);
+        }
+    }
+
+    /**
+     * <p>Play one of the predefined platform sounds for media actions.</p>
+     *
+     * <p>Use this method to play a platform-specific sound for various media
+     * actions. The sound playback is done asynchronously, with the same
+     * behavior and content as the sounds played by
+     * {@link android.hardware.Camera#takePicture Camera.takePicture},
+     * {@link android.media.MediaRecorder#start MediaRecorder.start}, and
+     * {@link android.media.MediaRecorder#stop MediaRecorder.stop}.</p>
+     *
+     * <p>Using this method makes it easy to match the default device sounds
+     * when recording or capturing data through the preview callbacks, or when
+     * implementing custom camera-like features in your
+     * application.</p>
+     *
+     * <p>If the sound has not been loaded by {@link #load} before calling play,
+     * play will load the sound at the cost of some additional latency before
+     * sound playback begins. </p>
+     *
+     * @param soundName The type of sound to play, selected from
+     *         SHUTTER_CLICK, FOCUS_COMPLETE, START_VIDEO_RECORDING, or
+     *         STOP_VIDEO_RECORDING.
+     * @see android.hardware.Camera#takePicture
+     * @see android.media.MediaRecorder
+     * @see #SHUTTER_CLICK
+     * @see #FOCUS_COMPLETE
+     * @see #START_VIDEO_RECORDING
+     * @see #STOP_VIDEO_RECORDING
+     */
+    public synchronized void play(int soundName) {
+        if (soundName < 0 || soundName >= SOUND_FILES.length) {
+            throw new RuntimeException("Unknown sound requested: " + soundName);
+        }
+        if (mSoundIds[soundName] == SOUND_NOT_LOADED) {
+            mSoundIdToPlay =
+                    mSoundPool.load(SOUND_FILES[soundName], 1);
+            mSoundIds[soundName] = mSoundIdToPlay;
+        } else {
+            mSoundPool.play(mSoundIds[soundName], 1.0f, 1.0f, 0, 0, 1.0f);
+        }
+    }
+
+    private SoundPool.OnLoadCompleteListener mLoadCompleteListener =
+            new SoundPool.OnLoadCompleteListener() {
+        public void onLoadComplete(SoundPool soundPool,
+                int sampleId, int status) {
+            if (status == 0) {
+                if (mSoundIdToPlay == sampleId) {
+                    soundPool.play(sampleId, 1.0f, 1.0f, 0, 0, 1.0f);
+                    mSoundIdToPlay = SOUND_NOT_LOADED;
+                }
+            } else {
+                Log.e(TAG, "Unable to load sound for playback (status: " +
+                        status + ")");
+            }
+        }
+    };
+
+    /**
+     * Free up all audio resources used by this MediaActionSound instance
+     */
+    public void release() {
+        mSoundPool.release();
+        mSoundPool = null;
+    }
+}
diff --git a/media/libeffects/downmix/Android.mk b/media/libeffects/downmix/Android.mk
new file mode 100644
index 0000000..0348e1e
--- /dev/null
+++ b/media/libeffects/downmix/Android.mk
@@ -0,0 +1,28 @@
+LOCAL_PATH:= $(call my-dir)
+
+# Multichannel downmix effect library
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+	EffectDownmix.c
+
+LOCAL_SHARED_LIBRARIES := \
+	libcutils
+
+LOCAL_MODULE:= libdownmix
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/soundfx
+
+ifeq ($(TARGET_OS)-$(TARGET_SIMULATOR),linux-true)
+LOCAL_LDLIBS += -ldl
+endif
+
+LOCAL_C_INCLUDES := \
+	system/media/audio_effects/include \
+	system/media/audio_utils/include
+
+LOCAL_PRELINK_MODULE := false
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/media/libeffects/downmix/EffectDownmix.c b/media/libeffects/downmix/EffectDownmix.c
new file mode 100644
index 0000000..a325172
--- /dev/null
+++ b/media/libeffects/downmix/EffectDownmix.c
@@ -0,0 +1,889 @@
+/*
+ * 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.
+ * 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 "EffectDownmix"
+#define LOG_NDEBUG 0
+#include <cutils/log.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdbool.h>
+#include "EffectDownmix.h"
+
+#define MINUS_3_DB_IN_Q19_12 2896 // -3dB = 0.707 * 2^12 = 2896
+
+// effect_handle_t interface implementation for downmix effect
+const struct effect_interface_s gDownmixInterface = {
+        Downmix_Process,
+        Downmix_Command,
+        Downmix_GetDescriptor,
+        NULL /* no process_reverse function, no reference stream needed */
+};
+
+audio_effect_library_t AUDIO_EFFECT_LIBRARY_INFO_SYM = {
+    tag : AUDIO_EFFECT_LIBRARY_TAG,
+    version : EFFECT_LIBRARY_API_VERSION,
+    name : "Downmix Library",
+    implementor : "The Android Open Source Project",
+    query_num_effects : DownmixLib_QueryNumberEffects,
+    query_effect : DownmixLib_QueryEffect,
+    create_effect : DownmixLib_Create,
+    release_effect : DownmixLib_Release,
+    get_descriptor : DownmixLib_GetDescriptor,
+};
+
+
+// AOSP insert downmix UUID: 93f04452-e4fe-41cc-91f9-e475b6d1d69f
+static const effect_descriptor_t gDownmixDescriptor = {
+        EFFECT_UIID_DOWNMIX__, //type
+        {0x93f04452, 0xe4fe, 0x41cc, 0x91f9, {0xe4, 0x75, 0xb6, 0xd1, 0xd6, 0x9f}}, // uuid
+        EFFECT_CONTROL_API_VERSION,
+        EFFECT_FLAG_TYPE_INSERT | EFFECT_FLAG_INSERT_FIRST,
+        0, //FIXME what value should be reported? // cpu load
+        0, //FIXME what value should be reported? // memory usage
+        "Multichannel Downmix To Stereo", // human readable effect name
+        "The Android Open Source Project" // human readable effect implementor name
+};
+
+// gDescriptors contains pointers to all defined effect descriptor in this library
+static const effect_descriptor_t * const gDescriptors[] = {
+        &gDownmixDescriptor
+};
+
+// number of effects in this library
+const int kNbEffects = sizeof(gDescriptors) / sizeof(const effect_descriptor_t *);
+
+
+/*----------------------------------------------------------------------------
+ * Effect API implementation
+ *--------------------------------------------------------------------------*/
+
+/*--- Effect Library Interface Implementation ---*/
+
+int32_t DownmixLib_QueryNumberEffects(uint32_t *pNumEffects) {
+    ALOGV("DownmixLib_QueryNumberEffects()");
+    *pNumEffects = kNbEffects;
+    return 0;
+}
+
+int32_t DownmixLib_QueryEffect(uint32_t index, effect_descriptor_t *pDescriptor) {
+    ALOGV("DownmixLib_QueryEffect() index=%d", index);
+    if (pDescriptor == NULL) {
+        return -EINVAL;
+    }
+    if (index >= (uint32_t)kNbEffects) {
+        return -EINVAL;
+    }
+    memcpy(pDescriptor, gDescriptors[index], sizeof(effect_descriptor_t));
+    return 0;
+}
+
+
+int32_t DownmixLib_Create(const effect_uuid_t *uuid,
+        int32_t sessionId,
+        int32_t ioId,
+        effect_handle_t *pHandle) {
+    int ret;
+    int i;
+    downmix_module_t *module;
+    const effect_descriptor_t *desc;
+
+    ALOGV("DownmixLib_Create()");
+
+    if (pHandle == NULL || uuid == NULL) {
+        return -EINVAL;
+    }
+
+    for (i = 0 ; i < kNbEffects ; i++) {
+        desc = gDescriptors[i];
+        if (memcmp(uuid, &desc->uuid, sizeof(effect_uuid_t)) == 0) {
+            break;
+        }
+    }
+
+    if (i == kNbEffects) {
+        return -ENOENT;
+    }
+
+    module = malloc(sizeof(downmix_module_t));
+
+    module->itfe = &gDownmixInterface;
+
+    module->context.state = DOWNMIX_STATE_UNINITIALIZED;
+
+    ret = Downmix_Init(module);
+    if (ret < 0) {
+        ALOGW("DownmixLib_Create() init failed");
+        free(module);
+        return ret;
+    }
+
+    *pHandle = (effect_handle_t) module;
+
+    ALOGV("DownmixLib_Create() %p , size %d", module, sizeof(downmix_module_t));
+
+    return 0;
+}
+
+
+int32_t DownmixLib_Release(effect_handle_t handle) {
+    downmix_module_t *pDwmModule = (downmix_module_t *)handle;
+
+    ALOGV("DownmixLib_Release() %p", handle);
+    if (handle == NULL) {
+        return -EINVAL;
+    }
+
+    pDwmModule->context.state = DOWNMIX_STATE_UNINITIALIZED;
+
+    free(pDwmModule);
+    return 0;
+}
+
+
+int32_t DownmixLib_GetDescriptor(const effect_uuid_t *uuid, effect_descriptor_t *pDescriptor) {
+    ALOGV("DownmixLib_GetDescriptor()");
+    int i;
+
+    if (pDescriptor == NULL || uuid == NULL){
+        ALOGE("DownmixLib_Create() called with NULL pointer");
+        return -EINVAL;
+    }
+    ALOGV("DownmixLib_GetDescriptor() nb effects=%d", kNbEffects);
+    for (i = 0; i < kNbEffects; i++) {
+        ALOGV("DownmixLib_GetDescriptor() i=%d", i);
+        if (memcmp(uuid, &gDescriptors[i]->uuid, sizeof(effect_uuid_t)) == 0) {
+            memcpy(pDescriptor, gDescriptors[i], sizeof(effect_descriptor_t));
+            ALOGV("EffectGetDescriptor - UUID matched downmix type %d, UUID = %x",
+                 i, gDescriptors[i]->uuid.timeLow);
+            return 0;
+        }
+    }
+
+    return -EINVAL;
+}
+
+
+/*--- Effect Control Interface Implementation ---*/
+
+static int Downmix_Process(effect_handle_t self,
+        audio_buffer_t *inBuffer, audio_buffer_t *outBuffer) {
+
+    downmix_object_t *pDownmixer;
+    int16_t *pSrc, *pDst;
+    downmix_module_t *pDwmModule = (downmix_module_t *)self;
+
+    if (pDwmModule == NULL) {
+        return -EINVAL;
+    }
+
+    if (inBuffer == NULL || inBuffer->raw == NULL ||
+        outBuffer == NULL || outBuffer->raw == NULL ||
+        inBuffer->frameCount != outBuffer->frameCount) {
+        return -EINVAL;
+    }
+
+    pDownmixer = (downmix_object_t*) &pDwmModule->context;
+
+    if (pDownmixer->state == DOWNMIX_STATE_UNINITIALIZED) {
+        ALOGE("Downmix_Process error: trying to use an uninitialized downmixer");
+        return -EINVAL;
+    } else if (pDownmixer->state == DOWNMIX_STATE_INITIALIZED) {
+        ALOGE("Downmix_Process error: trying to use a non-configured downmixer");
+        return -ENODATA;
+    }
+
+    pSrc = inBuffer->s16;
+    pDst = outBuffer->s16;
+    size_t numFrames = outBuffer->frameCount;
+
+    const bool accumulate =
+            (pDwmModule->config.outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE);
+
+    switch(pDownmixer->type) {
+
+      case DOWNMIX_TYPE_STRIP:
+          if (accumulate) {
+              while (numFrames) {
+                  pDst[0] = clamp16(pDst[0] + pSrc[0]);
+                  pDst[1] = clamp16(pDst[1] + pSrc[1]);
+                  pSrc += pDownmixer->input_channel_count;
+                  pDst += 2;
+                  numFrames--;
+              }
+          } else {
+              while (numFrames) {
+                  pDst[0] = pSrc[0];
+                  pDst[1] = pSrc[1];
+                  pSrc += pDownmixer->input_channel_count;
+                  pDst += 2;
+                  numFrames--;
+              }
+          }
+          break;
+
+      case DOWNMIX_TYPE_FOLD:
+        // optimize for the common formats
+        switch(pDwmModule->config.inputCfg.channels) {
+        case AUDIO_CHANNEL_OUT_QUAD:
+            Downmix_foldFromQuad(pSrc, pDst, numFrames, accumulate);
+            break;
+        case AUDIO_CHANNEL_OUT_SURROUND:
+            Downmix_foldFromSurround(pSrc, pDst, numFrames, accumulate);
+            break;
+        case AUDIO_CHANNEL_OUT_5POINT1:
+            Downmix_foldFrom5Point1(pSrc, pDst, numFrames, accumulate);
+            break;
+        case AUDIO_CHANNEL_OUT_7POINT1:
+            Downmix_foldFrom7Point1(pSrc, pDst, numFrames, accumulate);
+            break;
+        default:
+            // FIXME implement generic downmix
+            ALOGE("Multichannel configurations other than quad, 4.0, 5.1 and 7.1 are not supported");
+            break;
+        }
+        break;
+
+      default:
+        return -EINVAL;
+    }
+
+    return 0;
+}
+
+
+static int Downmix_Command(effect_handle_t self, uint32_t cmdCode, uint32_t cmdSize,
+        void *pCmdData, uint32_t *replySize, void *pReplyData) {
+
+    downmix_module_t *pDwmModule = (downmix_module_t *) self;
+    downmix_object_t *pDownmixer;
+    int retsize;
+
+    if (pDwmModule == NULL || pDwmModule->context.state == DOWNMIX_STATE_UNINITIALIZED) {
+        return -EINVAL;
+    }
+
+    pDownmixer = (downmix_object_t*) &pDwmModule->context;
+
+    ALOGV("Downmix_Command command %d cmdSize %d",cmdCode, cmdSize);
+
+    switch (cmdCode) {
+    case EFFECT_CMD_INIT:
+        if (pReplyData == NULL || *replySize != sizeof(int)) {
+            return -EINVAL;
+        }
+        *(int *) pReplyData = Downmix_Init(pDwmModule);
+        break;
+
+    case EFFECT_CMD_SET_CONFIG:
+        if (pCmdData == NULL || cmdSize != sizeof(effect_config_t)
+                || pReplyData == NULL || *replySize != sizeof(int)) {
+            return -EINVAL;
+        }
+        *(int *) pReplyData = Downmix_Configure(pDwmModule,
+                (effect_config_t *)pCmdData, false);
+        break;
+
+    case EFFECT_CMD_RESET:
+        Downmix_Reset(pDownmixer, false);
+        break;
+
+    case EFFECT_CMD_GET_PARAM:
+        ALOGV("Downmix_Command EFFECT_CMD_GET_PARAM pCmdData %p, *replySize %d, pReplyData: %p",
+                pCmdData, *replySize, pReplyData);
+        if (pCmdData == NULL || cmdSize < (int)(sizeof(effect_param_t) + sizeof(int32_t)) ||
+                pReplyData == NULL ||
+                *replySize < (int) sizeof(effect_param_t) + 2 * sizeof(int32_t)) {
+            return -EINVAL;
+        }
+        effect_param_t *rep = (effect_param_t *) pReplyData;
+        memcpy(pReplyData, pCmdData, sizeof(effect_param_t) + sizeof(int32_t));
+        ALOGV("Downmix_Command EFFECT_CMD_GET_PARAM param %d, replySize %d",
+                *(int32_t *)rep->data, rep->vsize);
+        rep->status = Downmix_getParameter(pDownmixer, *(int32_t *)rep->data, &rep->vsize,
+                rep->data + sizeof(int32_t));
+        *replySize = sizeof(effect_param_t) + sizeof(int32_t) + rep->vsize;
+        break;
+
+    case EFFECT_CMD_SET_PARAM:
+        ALOGV("Downmix_Command EFFECT_CMD_SET_PARAM cmdSize %d pCmdData %p, *replySize %d, " \
+                "pReplyData %p", cmdSize, pCmdData, *replySize, pReplyData);
+        if (pCmdData == NULL || (cmdSize < (int)(sizeof(effect_param_t) + sizeof(int32_t)))
+                || pReplyData == NULL || *replySize != (int)sizeof(int32_t)) {
+            return -EINVAL;
+        }
+        effect_param_t *cmd = (effect_param_t *) pCmdData;
+        *(int *)pReplyData = Downmix_setParameter(pDownmixer, *(int32_t *)cmd->data,
+                cmd->vsize, cmd->data + sizeof(int32_t));
+        break;
+
+    case EFFECT_CMD_SET_PARAM_DEFERRED:
+        //FIXME implement
+        ALOGW("Downmix_Command command EFFECT_CMD_SET_PARAM_DEFERRED not supported, FIXME");
+        break;
+
+    case EFFECT_CMD_SET_PARAM_COMMIT:
+        //FIXME implement
+        ALOGW("Downmix_Command command EFFECT_CMD_SET_PARAM_COMMIT not supported, FIXME");
+        break;
+
+    case EFFECT_CMD_ENABLE:
+        if (pReplyData == NULL || *replySize != sizeof(int)) {
+            return -EINVAL;
+        }
+        if (pDownmixer->state != DOWNMIX_STATE_INITIALIZED) {
+            return -ENOSYS;
+        }
+        pDownmixer->state = DOWNMIX_STATE_ACTIVE;
+        ALOGV("EFFECT_CMD_ENABLE() OK");
+        *(int *)pReplyData = 0;
+        break;
+
+    case EFFECT_CMD_DISABLE:
+        if (pReplyData == NULL || *replySize != sizeof(int)) {
+            return -EINVAL;
+        }
+        if (pDownmixer->state != DOWNMIX_STATE_ACTIVE) {
+            return -ENOSYS;
+        }
+        pDownmixer->state = DOWNMIX_STATE_INITIALIZED;
+        ALOGV("EFFECT_CMD_DISABLE() OK");
+        *(int *)pReplyData = 0;
+        break;
+
+    case EFFECT_CMD_SET_DEVICE:
+        if (pCmdData == NULL || cmdSize != (int)sizeof(uint32_t)) {
+            return -EINVAL;
+        }
+        // FIXME change type if playing on headset vs speaker
+        ALOGV("Downmix_Command EFFECT_CMD_SET_DEVICE: 0x%08x", *(uint32_t *)pCmdData);
+        break;
+
+    case EFFECT_CMD_SET_VOLUME: {
+        // audio output is always stereo => 2 channel volumes
+        if (pCmdData == NULL || cmdSize != (int)sizeof(uint32_t) * 2) {
+            return -EINVAL;
+        }
+        // FIXME change volume
+        ALOGW("Downmix_Command command EFFECT_CMD_SET_VOLUME not supported, FIXME");
+        float left = (float)(*(uint32_t *)pCmdData) / (1 << 24);
+        float right = (float)(*((uint32_t *)pCmdData + 1)) / (1 << 24);
+        ALOGV("Downmix_Command EFFECT_CMD_SET_VOLUME: left %f, right %f ", left, right);
+        break;
+    }
+
+    case EFFECT_CMD_SET_AUDIO_MODE:
+        if (pCmdData == NULL || cmdSize != (int)sizeof(uint32_t)) {
+            return -EINVAL;
+        }
+        ALOGV("Downmix_Command EFFECT_CMD_SET_AUDIO_MODE: %d", *(uint32_t *)pCmdData);
+        break;
+
+    case EFFECT_CMD_SET_CONFIG_REVERSE:
+    case EFFECT_CMD_SET_INPUT_DEVICE:
+        // these commands are ignored by a downmix effect
+        break;
+
+    default:
+        ALOGW("Downmix_Command invalid command %d",cmdCode);
+        return -EINVAL;
+    }
+
+    return 0;
+}
+
+
+int Downmix_GetDescriptor(effect_handle_t self, effect_descriptor_t *pDescriptor)
+{
+    downmix_module_t *pDwnmxModule = (downmix_module_t *) self;
+
+    if (pDwnmxModule == NULL ||
+            pDwnmxModule->context.state == DOWNMIX_STATE_UNINITIALIZED) {
+        return -EINVAL;
+    }
+
+    memcpy(pDescriptor, &gDownmixDescriptor, sizeof(effect_descriptor_t));
+
+    return 0;
+}
+
+
+/*----------------------------------------------------------------------------
+ * Downmix internal functions
+ *--------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+ * Downmix_Init()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Initialize downmix context and apply default parameters
+ *
+ * Inputs:
+ *  pDwmModule    pointer to downmix effect module
+ *
+ * Outputs:
+ *
+ * Returns:
+ *  0             indicates success
+ *
+ * Side Effects:
+ *  updates:
+ *           pDwmModule->context.type
+ *           pDwmModule->context.apply_volume_correction
+ *           pDwmModule->config.inputCfg
+ *           pDwmModule->config.outputCfg
+ *           pDwmModule->config.inputCfg.samplingRate
+ *           pDwmModule->config.outputCfg.samplingRate
+ *           pDwmModule->context.state
+ *  doesn't set:
+ *           pDwmModule->itfe
+ *
+ *----------------------------------------------------------------------------
+ */
+
+int Downmix_Init(downmix_module_t *pDwmModule) {
+
+    ALOGV("Downmix_Init module %p", pDwmModule);
+    int ret = 0;
+
+    memset(&pDwmModule->context, 0, sizeof(downmix_object_t));
+
+    pDwmModule->config.inputCfg.accessMode = EFFECT_BUFFER_ACCESS_READ;
+    pDwmModule->config.inputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
+    pDwmModule->config.inputCfg.channels = AUDIO_CHANNEL_OUT_7POINT1;
+    pDwmModule->config.inputCfg.bufferProvider.getBuffer = NULL;
+    pDwmModule->config.inputCfg.bufferProvider.releaseBuffer = NULL;
+    pDwmModule->config.inputCfg.bufferProvider.cookie = NULL;
+    pDwmModule->config.inputCfg.mask = EFFECT_CONFIG_ALL;
+
+    pDwmModule->config.inputCfg.samplingRate = 44100;
+    pDwmModule->config.outputCfg.samplingRate = pDwmModule->config.inputCfg.samplingRate;
+
+    // set a default value for the access mode, but should be overwritten by caller
+    pDwmModule->config.outputCfg.accessMode = EFFECT_BUFFER_ACCESS_ACCUMULATE;
+    pDwmModule->config.outputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
+    pDwmModule->config.outputCfg.channels = AUDIO_CHANNEL_OUT_STEREO;
+    pDwmModule->config.outputCfg.bufferProvider.getBuffer = NULL;
+    pDwmModule->config.outputCfg.bufferProvider.releaseBuffer = NULL;
+    pDwmModule->config.outputCfg.bufferProvider.cookie = NULL;
+    pDwmModule->config.outputCfg.mask = EFFECT_CONFIG_ALL;
+
+    ret = Downmix_Configure(pDwmModule, &pDwmModule->config, true);
+    if (ret != 0) {
+        ALOGV("Downmix_Init error %d on module %p", ret, pDwmModule);
+    } else {
+        pDwmModule->context.state = DOWNMIX_STATE_INITIALIZED;
+    }
+
+    return ret;
+}
+
+
+/*----------------------------------------------------------------------------
+ * Downmix_Configure()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *  Set input and output audio configuration.
+ *
+ * Inputs:
+ *  pDwmModule  pointer to downmix effect module
+ *  pConfig     pointer to effect_config_t structure containing input
+ *                  and output audio parameters configuration
+ *  init        true if called from init function
+ *
+ * Outputs:
+ *
+ * Returns:
+ *  0           indicates success
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+ */
+
+int Downmix_Configure(downmix_module_t *pDwmModule, effect_config_t *pConfig, bool init) {
+
+    downmix_object_t *pDownmixer = &pDwmModule->context;
+
+    // Check configuration compatibility with build options, and effect capabilities
+    if (pConfig->inputCfg.samplingRate != pConfig->outputCfg.samplingRate
+        || pConfig->outputCfg.channels != DOWNMIX_OUTPUT_CHANNELS
+        || pConfig->inputCfg.format != AUDIO_FORMAT_PCM_16_BIT
+        || pConfig->outputCfg.format != AUDIO_FORMAT_PCM_16_BIT) {
+        ALOGE("Downmix_Configure error: invalid config");
+        return -EINVAL;
+    }
+
+    memcpy(&pDwmModule->config, pConfig, sizeof(effect_config_t));
+
+    if (init) {
+        pDownmixer->type = DOWNMIX_TYPE_FOLD;
+        pDownmixer->apply_volume_correction = false;
+        pDownmixer->input_channel_count = 8; // matches default input of AUDIO_CHANNEL_OUT_7POINT1
+    } else {
+        // when configuring the effect, do not allow a blank channel mask
+        if (pConfig->inputCfg.channels == 0) {
+            ALOGE("Downmix_Configure error: input channel mask can't be 0");
+            return -EINVAL;
+        }
+        pDownmixer->input_channel_count = popcount(pConfig->inputCfg.channels);
+    }
+
+    Downmix_Reset(pDownmixer, init);
+
+    return 0;
+}
+
+
+/*----------------------------------------------------------------------------
+ * Downmix_Reset()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *  Reset internal states.
+ *
+ * Inputs:
+ *  pDownmixer   pointer to downmix context
+ *  init         true if called from init function
+ *
+ * Outputs:
+*
+ * Returns:
+ *  0            indicates success
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+ */
+
+int Downmix_Reset(downmix_object_t *pDownmixer, bool init) {
+    // nothing to do here
+    return 0;
+}
+
+
+/*----------------------------------------------------------------------------
+ * Downmix_setParameter()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Set a Downmix parameter
+ *
+ * Inputs:
+ *  pDownmixer    handle to instance data
+ *  param         parameter
+ *  pValue        pointer to parameter value
+ *  size          value size
+ *
+ * Outputs:
+ *
+ * Returns:
+ *  0             indicates success
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+ */
+int Downmix_setParameter(downmix_object_t *pDownmixer, int32_t param, size_t size, void *pValue) {
+
+    int16_t value16;
+    ALOGV("Downmix_setParameter, context %p, param %d, value16 %d, value32 %d",
+            pDownmixer, param, *(int16_t *)pValue, *(int32_t *)pValue);
+
+    switch (param) {
+
+      case DOWNMIX_PARAM_TYPE:
+        if (size != sizeof(downmix_type_t)) {
+            ALOGE("Downmix_setParameter(DOWNMIX_PARAM_TYPE) invalid size %d, should be %d",
+                    size, sizeof(downmix_type_t));
+            return -EINVAL;
+        }
+        value16 = *(int16_t *)pValue;
+        ALOGV("set DOWNMIX_PARAM_TYPE, type %d", value16);
+        if (!((value16 > DOWNMIX_TYPE_INVALID) && (value16 < DOWNMIX_TYPE_LAST))) {
+            ALOGE("Downmix_setParameter invalid DOWNMIX_PARAM_TYPE value %d", value16);
+            return -EINVAL;
+        } else {
+            pDownmixer->type = (downmix_type_t) value16;
+        break;
+
+      default:
+        ALOGE("Downmix_setParameter unknown parameter %d", param);
+        return -EINVAL;
+    }
+}
+
+    return 0;
+} /* end Downmix_setParameter */
+
+
+/*----------------------------------------------------------------------------
+ * Downmix_getParameter()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Get a Downmix parameter
+ *
+ * Inputs:
+ *  pDownmixer    handle to instance data
+ *  param         parameter
+ *  pValue        pointer to variable to hold retrieved value
+ *  pSize         pointer to value size: maximum size as input
+ *
+ * Outputs:
+ *  *pValue updated with parameter value
+ *  *pSize updated with actual value size
+ *
+ * Returns:
+ *  0             indicates success
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+ */
+int Downmix_getParameter(downmix_object_t *pDownmixer, int32_t param, size_t *pSize, void *pValue) {
+    int16_t *pValue16;
+
+    switch (param) {
+
+    case DOWNMIX_PARAM_TYPE:
+      if (*pSize < sizeof(int16_t)) {
+          ALOGE("Downmix_getParameter invalid parameter size %d for DOWNMIX_PARAM_TYPE", *pSize);
+          return -EINVAL;
+      }
+      pValue16 = (int16_t *)pValue;
+      *pValue16 = (int16_t) pDownmixer->type;
+      *pSize = sizeof(int16_t);
+      ALOGV("Downmix_getParameter DOWNMIX_PARAM_TYPE is %d", *pValue16);
+      break;
+
+    default:
+      ALOGE("Downmix_getParameter unknown parameter %d", param);
+      return -EINVAL;
+    }
+
+    return 0;
+} /* end Downmix_getParameter */
+
+
+/*----------------------------------------------------------------------------
+ * Downmix_foldFromQuad()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * downmix a quad signal to stereo
+ *
+ * Inputs:
+ *  pSrc       quad audio samples to downmix
+ *  numFrames  the number of quad frames to downmix
+ *
+ * Outputs:
+ *  pDst       downmixed stereo audio samples
+ *
+ *----------------------------------------------------------------------------
+ */
+void Downmix_foldFromQuad(int16_t *pSrc, int16_t*pDst, size_t numFrames, bool accumulate) {
+    // sample at index 0 is FL
+    // sample at index 1 is FR
+    // sample at index 2 is RL
+    // sample at index 3 is RR
+    if (accumulate) {
+        while (numFrames) {
+            // FL + RL
+            pDst[0] = clamp16(pDst[0] + pSrc[0] + pSrc[2]);
+            // FR + RR
+            pDst[1] = clamp16(pDst[1] + pSrc[1] + pSrc[3]);
+            pSrc += 4;
+            pDst += 2;
+            numFrames--;
+        }
+    } else { // same code as above but without adding and clamping pDst[i] to itself
+        while (numFrames) {
+            // FL + RL
+            pDst[0] = clamp16(pSrc[0] + pSrc[2]);
+            // FR + RR
+            pDst[1] = clamp16(pSrc[1] + pSrc[3]);
+            pSrc += 4;
+            pDst += 2;
+            numFrames--;
+        }
+    }
+}
+
+
+/*----------------------------------------------------------------------------
+ * Downmix_foldFromSurround()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * downmix a "surround sound" (mono rear) signal to stereo
+ *
+ * Inputs:
+ *  pSrc       surround signal to downmix
+ *  numFrames  the number of surround frames to downmix
+ *
+ * Outputs:
+ *  pDst       downmixed stereo audio samples
+ *
+ *----------------------------------------------------------------------------
+ */
+void Downmix_foldFromSurround(int16_t *pSrc, int16_t*pDst, size_t numFrames, bool accumulate) {
+    int32_t lt, rt, centerPlusRearContrib; // samples in Q19.12 format
+    // sample at index 0 is FL
+    // sample at index 1 is FR
+    // sample at index 2 is FC
+    // sample at index 3 is RC
+    if (accumulate) {
+        while (numFrames) {
+            // centerPlusRearContrib = FC(-3dB) + RC(-3dB)
+            centerPlusRearContrib = (pSrc[2] * MINUS_3_DB_IN_Q19_12) + (pSrc[3] * MINUS_3_DB_IN_Q19_12);
+            // FL + centerPlusRearContrib
+            lt = (pSrc[0] << 12) + centerPlusRearContrib;
+            // FR + centerPlusRearContrib
+            rt = (pSrc[1] << 12) + centerPlusRearContrib;
+            pDst[0] = clamp16(pDst[0] + (lt >> 12));
+            pDst[1] = clamp16(pDst[1] + (rt >> 12));
+            pSrc += 4;
+            pDst += 2;
+            numFrames--;
+        }
+    } else { // same code as above but without adding and clamping pDst[i] to itself
+        while (numFrames) {
+            // centerPlusRearContrib = FC(-3dB) + RC(-3dB)
+            centerPlusRearContrib = (pSrc[2] * MINUS_3_DB_IN_Q19_12) + (pSrc[3] * MINUS_3_DB_IN_Q19_12);
+            // FL + centerPlusRearContrib
+            lt = (pSrc[0] << 12) + centerPlusRearContrib;
+            // FR + centerPlusRearContrib
+            rt = (pSrc[1] << 12) + centerPlusRearContrib;
+            pDst[0] = clamp16(lt >> 12);
+            pDst[1] = clamp16(rt >> 12);
+            pSrc += 4;
+            pDst += 2;
+            numFrames--;
+        }
+    }
+}
+
+
+/*----------------------------------------------------------------------------
+ * Downmix_foldFrom5Point1()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * downmix a 5.1 signal to stereo
+ *
+ * Inputs:
+ *  pSrc       5.1 audio samples to downmix
+ *  numFrames  the number of 5.1 frames to downmix
+ *
+ * Outputs:
+ *  pDst       downmixed stereo audio samples
+ *
+ *----------------------------------------------------------------------------
+ */
+void Downmix_foldFrom5Point1(int16_t *pSrc, int16_t*pDst, size_t numFrames, bool accumulate) {
+    int32_t lt, rt, centerPlusLfeContrib; // samples in Q19.12 format
+    // sample at index 0 is FL
+    // sample at index 1 is FR
+    // sample at index 2 is FC
+    // sample at index 3 is LFE
+    // sample at index 4 is RL
+    // sample at index 5 is RR
+    if (accumulate) {
+        while (numFrames) {
+            // centerPlusLfeContrib = FC(-3dB) + LFE(-3dB)
+            centerPlusLfeContrib = (pSrc[2] * MINUS_3_DB_IN_Q19_12)
+                    + (pSrc[3] * MINUS_3_DB_IN_Q19_12);
+            // FL + centerPlusLfeContrib + RL
+            lt = (pSrc[0] << 12) + centerPlusLfeContrib + (pSrc[4] << 12);
+            // FR + centerPlusLfeContrib + RR
+            rt = (pSrc[1] << 12) + centerPlusLfeContrib + (pSrc[5] << 12);
+            pDst[0] = clamp16(pDst[0] + (lt >> 12));
+            pDst[1] = clamp16(pDst[1] + (rt >> 12));
+            pSrc += 6;
+            pDst += 2;
+            numFrames--;
+        }
+    } else { // same code as above but without adding and clamping pDst[i] to itself
+        while (numFrames) {
+            // centerPlusLfeContrib = FC(-3dB) + LFE(-3dB)
+            centerPlusLfeContrib = (pSrc[2] * MINUS_3_DB_IN_Q19_12)
+                    + (pSrc[3] * MINUS_3_DB_IN_Q19_12);
+            // FL + centerPlusLfeContrib + RL
+            lt = (pSrc[0] << 12) + centerPlusLfeContrib + (pSrc[4] << 12);
+            // FR + centerPlusLfeContrib + RR
+            rt = (pSrc[1] << 12) + centerPlusLfeContrib + (pSrc[5] << 12);
+            pDst[0] = clamp16(lt >> 12);
+            pDst[1] = clamp16(rt >> 12);
+            pSrc += 6;
+            pDst += 2;
+            numFrames--;
+        }
+    }
+}
+
+
+/*----------------------------------------------------------------------------
+ * Downmix_foldFrom7Point1()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * downmix a 7.1 signal to stereo
+ *
+ * Inputs:
+ *  pSrc       7.1 audio samples to downmix
+ *  numFrames  the number of 7.1 frames to downmix
+ *
+ * Outputs:
+ *  pDst       downmixed stereo audio samples
+ *
+ *----------------------------------------------------------------------------
+ */
+void Downmix_foldFrom7Point1(int16_t *pSrc, int16_t*pDst, size_t numFrames, bool accumulate) {
+    int32_t lt, rt, centerPlusLfeContrib; // samples in Q19.12 format
+    // sample at index 0 is FL
+    // sample at index 1 is FR
+    // sample at index 2 is FC
+    // sample at index 3 is LFE
+    // sample at index 4 is RL
+    // sample at index 5 is RR
+    // sample at index 6 is SL
+    // sample at index 7 is SR
+    if (accumulate) {
+        while (numFrames) {
+            // centerPlusLfeContrib = FC(-3dB) + LFE(-3dB)
+            centerPlusLfeContrib = (pSrc[2] * MINUS_3_DB_IN_Q19_12)
+                    + (pSrc[3] * MINUS_3_DB_IN_Q19_12);
+            // FL + centerPlusLfeContrib + SL + RL
+            lt = (pSrc[0] << 12) + centerPlusLfeContrib + (pSrc[6] << 12) + (pSrc[4] << 12);
+            // FR + centerPlusLfeContrib + SR + RR
+            rt = (pSrc[1] << 12) + centerPlusLfeContrib + (pSrc[7] << 12) + (pSrc[5] << 12);
+            pDst[0] = clamp16(lt >> 12);
+            pDst[1] = clamp16(rt >> 12);
+            pSrc += 8;
+            pDst += 2;
+            numFrames--;
+    }
+    } else { // same code as above but without adding and clamping pDst[i] to itself
+        while (numFrames) {
+            // centerPlusLfeContrib = FC(-3dB) + LFE(-3dB)
+            centerPlusLfeContrib = (pSrc[2] * MINUS_3_DB_IN_Q19_12)
+                    + (pSrc[3] * MINUS_3_DB_IN_Q19_12);
+            // FL + centerPlusLfeContrib + SL + RL
+            lt = (pSrc[0] << 12) + centerPlusLfeContrib + (pSrc[6] << 12) + (pSrc[4] << 12);
+            // FR + centerPlusLfeContrib + SR + RR
+            rt = (pSrc[1] << 12) + centerPlusLfeContrib + (pSrc[7] << 12) + (pSrc[5] << 12);
+            pDst[0] = clamp16(pDst[0] + (lt >> 12));
+            pDst[1] = clamp16(pDst[1] + (rt >> 12));
+            pSrc += 8;
+            pDst += 2;
+            numFrames--;
+        }
+    }
+}
+
diff --git a/media/libeffects/downmix/EffectDownmix.h b/media/libeffects/downmix/EffectDownmix.h
new file mode 100644
index 0000000..4176b5a
--- /dev/null
+++ b/media/libeffects/downmix/EffectDownmix.h
@@ -0,0 +1,96 @@
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_EFFECTDOWNMIX_H_
+#define ANDROID_EFFECTDOWNMIX_H_
+
+#include <audio_effects/effect_downmix.h>
+#include <audio_utils/primitives.h>
+#include <system/audio.h>
+
+/*------------------------------------
+ * definitions
+ *------------------------------------
+*/
+
+#define DOWNMIX_OUTPUT_CHANNELS AUDIO_CHANNEL_OUT_STEREO
+
+typedef enum {
+    DOWNMIX_STATE_UNINITIALIZED,
+    DOWNMIX_STATE_INITIALIZED,
+    DOWNMIX_STATE_ACTIVE,
+} downmix_state_t;
+
+/* parameters for each downmixer */
+typedef struct {
+    downmix_state_t state;
+    downmix_type_t type;
+    bool apply_volume_correction;
+    uint8_t input_channel_count;
+} downmix_object_t;
+
+
+typedef struct downmix_module_s {
+    const struct effect_interface_s *itfe;
+    effect_config_t config;
+    downmix_object_t context;
+} downmix_module_t;
+
+
+/*------------------------------------
+ * Effect API
+ *------------------------------------
+*/
+int32_t DownmixLib_QueryNumberEffects(uint32_t *pNumEffects);
+int32_t DownmixLib_QueryEffect(uint32_t index,
+        effect_descriptor_t *pDescriptor);
+int32_t DownmixLib_Create(const effect_uuid_t *uuid,
+        int32_t sessionId,
+        int32_t ioId,
+        effect_handle_t *pHandle);
+int32_t DownmixLib_Release(effect_handle_t handle);
+int32_t DownmixLib_GetDescriptor(const effect_uuid_t *uuid,
+        effect_descriptor_t *pDescriptor);
+
+static int Downmix_Process(effect_handle_t self,
+        audio_buffer_t *inBuffer,
+        audio_buffer_t *outBuffer);
+static int Downmix_Command(effect_handle_t self,
+        uint32_t cmdCode,
+        uint32_t cmdSize,
+        void *pCmdData,
+        uint32_t *replySize,
+        void *pReplyData);
+static int Downmix_GetDescriptor(effect_handle_t self,
+        effect_descriptor_t *pDescriptor);
+
+
+/*------------------------------------
+ * internal functions
+ *------------------------------------
+*/
+int Downmix_Init(downmix_module_t *pDwmModule);
+int Downmix_Configure(downmix_module_t *pDwmModule, effect_config_t *pConfig, bool init);
+int Downmix_Reset(downmix_object_t *pDownmixer, bool init);
+int Downmix_setParameter(downmix_object_t *pDownmixer, int32_t param, size_t size, void *pValue);
+int Downmix_getParameter(downmix_object_t *pDownmixer, int32_t param, size_t *pSize, void *pValue);
+
+void Downmix_foldFromQuad(int16_t *pSrc, int16_t*pDst, size_t numFrames, bool accumulate);
+void Downmix_foldFromSurround(int16_t *pSrc, int16_t*pDst, size_t numFrames, bool accumulate);
+void Downmix_foldFrom5Point1(int16_t *pSrc, int16_t*pDst, size_t numFrames, bool accumulate);
+void Downmix_foldFrom7Point1(int16_t *pSrc, int16_t*pDst, size_t numFrames, bool accumulate);
+
+#endif /*ANDROID_EFFECTDOWNMIX_H_*/
diff --git a/packages/SettingsProvider/res/values-in/strings.xml b/packages/SettingsProvider/res/values-in/strings.xml
index bed20eb..d5aea43 100644
--- a/packages/SettingsProvider/res/values-in/strings.xml
+++ b/packages/SettingsProvider/res/values-in/strings.xml
@@ -19,5 +19,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="4567566098528588863">"Setelan Penyimpanan"</string>
+    <string name="app_label" msgid="4567566098528588863">"Pengaturan Penyimpanan"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index a8b024d..7c1cd18 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -39,7 +39,7 @@
     <string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> tersisa"</string>
     <string name="invalid_charger" msgid="4549105996740522523">"Pengisian daya USB tidak didukung."\n"Gunakan hanya pengisi daya yang disediakan."</string>
     <string name="battery_low_why" msgid="7279169609518386372">"Penggunaan baterai"</string>
-    <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Setelan"</string>
+    <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Pengaturan"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Mode pesawat"</string>
     <string name="status_bar_settings_auto_rotation" msgid="3790482541357798421">"Putar layar secara otomatis"</string>
@@ -69,10 +69,10 @@
     <string name="screenshot_saved_text" msgid="1152839647677558815">"Sentuh untuk melihat tangkapan layar Anda."</string>
     <string name="screenshot_failed_title" msgid="705781116746922771">"Tidak dapat mengambil tangkapan layar."</string>
     <string name="screenshot_failed_text" msgid="8134011269572415402">"Tidak dapat menyimpan tangkapan layar. Penyimpanan mungkin sedang digunakan."</string>
-    <string name="usb_preference_title" msgid="6551050377388882787">"Opsi transfer berkas USB"</string>
+    <string name="usb_preference_title" msgid="6551050377388882787">"Opsi transfer file USB"</string>
     <string name="use_mtp_button_title" msgid="4333504413563023626">"Pasang sebagai pemutar media (MTP)"</string>
     <string name="use_ptp_button_title" msgid="7517127540301625751">"Pasang sebagai kamera (PTP)"</string>
-    <string name="installer_cd_button_title" msgid="2312667578562201583">"Pasang apl Transfer Berkas Android untuk Mac"</string>
+    <string name="installer_cd_button_title" msgid="2312667578562201583">"Pasang apl Transfer File Android untuk Mac"</string>
     <string name="accessibility_back" msgid="567011538994429120">"Kembali"</string>
     <string name="accessibility_home" msgid="8217216074895377641">"Utama"</string>
     <string name="accessibility_menu" msgid="316839303324695949">"Menu"</string>
@@ -118,7 +118,7 @@
     <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Penambatan bluetooth."</string>
     <string name="accessibility_airplane_mode" msgid="834748999790763092">"Mode pesawat."</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Baterai <xliff:g id="NUMBER">%d</xliff:g> persen."</string>
-    <string name="accessibility_settings_button" msgid="799583911231893380">"Setelan sistem."</string>
+    <string name="accessibility_settings_button" msgid="799583911231893380">"Pengaturan sistem."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Pemberitahuan."</string>
     <string name="accessibility_remove_notification" msgid="3603099514902182350">"Menghapus pemberitahuan."</string>
     <string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS diaktifkan."</string>
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
index c4a92f7..9a76c14 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
@@ -34,7 +34,7 @@
 import android.graphics.Matrix;
 import android.graphics.PixelFormat;
 import android.graphics.PointF;
-import android.hardware.CameraSound;
+import android.media.MediaActionSound;
 import android.net.Uri;
 import android.os.AsyncTask;
 import android.os.Environment;
@@ -256,7 +256,7 @@
     private float mBgPadding;
     private float mBgPaddingScale;
 
-    private CameraSound mCameraSound;
+    private MediaActionSound mCameraSound;
 
 
     /**
@@ -309,7 +309,8 @@
         mBgPaddingScale = mBgPadding /  mDisplayMetrics.widthPixels;
 
         // Setup the Camera shutter sound
-        mCameraSound = new CameraSound();
+        mCameraSound = new MediaActionSound();
+        mCameraSound.load(MediaActionSound.SHUTTER_CLICK);
     }
 
     /**
@@ -422,7 +423,7 @@
             @Override
             public void run() {
                 // Play the shutter sound to notify that we've taken a screenshot
-                mCameraSound.playSound(CameraSound.SHUTTER_CLICK);
+                mCameraSound.play(MediaActionSound.SHUTTER_CLICK);
 
                 mScreenshotView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
                 mScreenshotView.buildLayer();
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 97a8f8b..032406e 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -1993,12 +1993,8 @@
 
 bool AudioFlinger::PlaybackThread::threadLoop()
 {
-    // MIXER || DUPLICATING
     Vector< sp<Track> > tracksToRemove;
 
-    // DIRECT
-    sp<Track> trackToRemove;
-
     standbyTime = systemTime();
     mixBufferSize = mFrameCount * mFrameSize;
 
@@ -2078,17 +2074,7 @@
 
             }
 
-if (mType == DUPLICATING) {
-#if 0   // see earlier FIXME
-            // Now that this is a field instead of local variable,
-            // clear it so it is empty the first time through the loop,
-            // and later an assignment could combine the clear with the loop below
-            outputTracks.clear();
-#endif
-            for (size_t i = 0; i < mOutputTracks.size(); i++) {
-                outputTracks.add(mOutputTracks[i]);
-            }
-}
+            saveOutputTracks();
 
             // put audio hardware into standby after short delay
             if (CC_UNLIKELY((!mActiveTracks.size() && systemTime() > standbyTime) ||
@@ -2105,9 +2091,7 @@
                     // we're about to wait, flush the binder command buffer
                     IPCThreadState::self()->flushCommands();
 
-if (mType == DUPLICATING) {
-                    outputTracks.clear();
-}
+                    clearOutputTracks();
 
                     if (exitPending()) break;
 
@@ -2142,17 +2126,11 @@
                 }
             }
 
-// FIXME merge these
-if (mType == MIXER || mType == DUPLICATING) {
             mixerStatus = prepareTracks_l(&tracksToRemove);
-}
-if (mType == DIRECT) {
-            mixerStatus = threadLoop_prepareTracks_l(trackToRemove);
             // see FIXME in AudioFlinger.h
             if (mixerStatus == MIXER_CONTINUE) {
                 continue;
             }
-}
 
             // prevent any changes in effect chain list and in each effect chain
             // during mixing and effect process as the audio buffers could be deleted
@@ -2176,14 +2154,6 @@
 
         // only process effects if we're going to write
         if (sleepTime == 0) {
-
-            if (mixerStatus == MIXER_TRACKS_READY) {
-
-                // Non-trivial for DIRECT only
-                applyVolume();
-
-            }
-
             for (size_t i = 0; i < effectChains.size(); i ++) {
                 effectChains[i]->process_l();
             }
@@ -2224,19 +2194,16 @@
         // finally let go of removed track(s), without the lock held
         // since we can't guarantee the destructors won't acquire that
         // same lock.
+        tracksToRemove.clear();
 
 // FIXME merge these
-if (mType == MIXER) {
-        tracksToRemove.clear();
-}
 if (mType == DIRECT) {
-        trackToRemove.clear();
         activeTrack.clear();
 }
-if (mType == DUPLICATING) {
-        tracksToRemove.clear();
-        outputTracks.clear();
-}
+        // FIXME I don't understand the need for this here;
+        //       it was in the original code but maybe the
+        //       assignment in saveOutputTracks() makes this unnecessary?
+        clearOutputTracks();
 
         // Effect chains will be actually deleted here if they were removed from
         // mEffectChains list during mixing or effects processing
@@ -2852,10 +2819,12 @@
     mRightVolShort = rightVol;
 }
 
-AudioFlinger::PlaybackThread::mixer_state AudioFlinger::DirectOutputThread::threadLoop_prepareTracks_l(
-    sp<Track>& trackToRemove
+AudioFlinger::PlaybackThread::mixer_state AudioFlinger::DirectOutputThread::prepareTracks_l(
+    Vector< sp<Track> > *tracksToRemove
 )
 {
+    sp<Track> trackToRemove;
+
     // FIXME Temporarily renamed to avoid confusion with the member "mixerStatus"
     mixer_state mixerStatus_ = MIXER_IDLE;
 
@@ -2973,8 +2942,10 @@
         }
     }
 
+    // FIXME merge this with similar code for removing multiple tracks
     // remove all the tracks that need to be...
     if (CC_UNLIKELY(trackToRemove != 0)) {
+        tracksToRemove->add(trackToRemove);
         mActiveTracks.remove(trackToRemove);
         if (!mEffectChains.isEmpty()) {
             ALOGV("stopping track on chain %p for session Id: %d", effectChains[0].get(),
@@ -3009,6 +2980,7 @@
     }
     sleepTime = 0;
     standbyTime = systemTime() + standbyDelay;
+    applyVolume();
 }
 
 void AudioFlinger::DirectOutputThread::threadLoop_sleepTime()
@@ -3185,6 +3157,16 @@
     }
 }
 
+void AudioFlinger::DuplicatingThread::saveOutputTracks()
+{
+    outputTracks = mOutputTracks;
+}
+
+void AudioFlinger::DuplicatingThread::clearOutputTracks()
+{
+    outputTracks.clear();
+}
+
 void AudioFlinger::DuplicatingThread::addOutputTrack(MixerThread *thread)
 {
     Mutex::Autolock _l(mLock);
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 7fc6cc2..e26466f 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -534,7 +534,10 @@
         friend class RecordTrack;
 
                     const type_t            mType;
+
+                    // Used by parameters, config events, addTrack_l, exit
                     Condition               mWaitWorkCV;
+
                     const sp<AudioFlinger>  mAudioFlinger;
                     uint32_t                mSampleRate;
                     size_t                  mFrameCount;
@@ -542,9 +545,30 @@
                     uint16_t                mChannelCount;
                     size_t                  mFrameSize;
                     audio_format_t          mFormat;
+
+                    // Parameter sequence by client: binder thread calling setParameters():
+                    //  1. Lock mLock
+                    //  2. Append to mNewParameters
+                    //  3. mWaitWorkCV.signal
+                    //  4. mParamCond.waitRelative with timeout
+                    //  5. read mParamStatus
+                    //  6. mWaitWorkCV.signal
+                    //  7. Unlock
+                    //
+                    // Parameter sequence by server: threadLoop calling checkForNewParameters_l():
+                    // 1. Lock mLock
+                    // 2. If there is an entry in mNewParameters proceed ...
+                    // 2. Read first entry in mNewParameters
+                    // 3. Process
+                    // 4. Remove first entry from mNewParameters
+                    // 5. Set mParamStatus
+                    // 6. mParamCond.signal
+                    // 7. mWaitWorkCV.wait with timeout (this is to avoid overwriting mParamStatus)
+                    // 8. Unlock
                     Condition               mParamCond;
                     Vector<String8>         mNewParameters;
                     status_t                mParamStatus;
+
                     Vector<ConfigEvent>     mConfigEvents;
                     bool                    mStandby;
                     const audio_io_handle_t mId;
@@ -584,7 +608,7 @@
             // standby mode does not have an enum value
             // suspend by audio policy manager is orthogonal to mixer state
 #if 1
-            // FIXME remove these hacks for threadLoop_prepareTracks_l
+            // FIXME remove this hack for prepareTracks_l()
             , MIXER_CONTINUE        // "continue;"
 #endif
         };
@@ -817,12 +841,11 @@
         // Non-trivial for DIRECT only
         virtual     void        applyVolume() { }
 
-        // FIXME merge these
-        // Non-trivial for MIXER and DUPLICATING only
-        virtual     mixer_state prepareTracks_l(Vector< sp<Track> > *tracksToRemove) { return MIXER_IDLE; }
-        // Non-trivial for DIRECT only
-        virtual     mixer_state threadLoop_prepareTracks_l(sp<Track>& trackToRemove)
-                                                                { return MIXER_IDLE; }
+                    // prepareTracks_l reads and writes mActiveTracks, and also returns the
+                    // pending set of tracks to remove via Vector 'tracksToRemove'.  The caller is
+                    // responsible for clearing or destroying this Vector later on, when it
+                    // is safe to do so. That will drop the final ref count and destroy the tracks.
+        virtual     mixer_state prepareTracks_l(Vector< sp<Track> > *tracksToRemove) = 0;
 
 public:
 
@@ -897,6 +920,10 @@
         // Code snippets that are temporarily lifted up out of threadLoop() until the merge
                     void        checkSilentMode_l();
 
+        // Non-trivial for DUPLICATING only
+        virtual     void        saveOutputTracks() { }
+        virtual     void        clearOutputTracks() { }
+
     private:
 
         friend class AudioFlinger;
@@ -949,9 +976,7 @@
         // activeTrack was local to the while !exitingPending loop
         sp<Track>                       activeTrack;
         // DUPLICATING only
-        SortedVector < sp<OutputTrack> >  outputTracks;
         uint32_t                        writeFrames;
-        SortedVector < sp<OutputTrack> >  mOutputTracks;
     };
 
     class MixerThread : public PlaybackThread {
@@ -970,10 +995,6 @@
         virtual     status_t    dumpInternals(int fd, const Vector<String16>& args);
 
     protected:
-                    // prepareTracks_l reads and writes mActiveTracks, and also returns the
-                    // pending set of tracks to remove via Vector 'tracksToRemove'.  The caller is
-                    // responsible for clearing or destroying this Vector later on, when it
-                    // is safe to do so. That will drop the final ref count and destroy the tracks.
         virtual     mixer_state prepareTracks_l(Vector< sp<Track> > *tracksToRemove);
         virtual     int         getTrackName_l();
         virtual     void        deleteTrackName_l(int name);
@@ -1006,10 +1027,9 @@
         virtual     uint32_t    suspendSleepTimeUs();
 
         // threadLoop snippets
-        virtual     mixer_state threadLoop_prepareTracks_l(sp<Track>& trackToRemove);
+        virtual     mixer_state prepareTracks_l(Vector< sp<Track> > *tracksToRemove);
         virtual     void        threadLoop_mix();
         virtual     void        threadLoop_sleepTime();
-        virtual     void        applyVolume();
 
         // volumes last sent to audio HAL with stream->set_volume()
         // FIXME use standard representation and names
@@ -1023,6 +1043,9 @@
         bool rampVolume;
         uint16_t leftVol;
         uint16_t rightVol;
+
+private:
+                    void        applyVolume();  // FIXME inline into threadLoop_mix()
     };
 
     class DuplicatingThread : public MixerThread {
@@ -1049,9 +1072,13 @@
 
         // called from threadLoop, addOutputTrack, removeOutputTrack
         virtual     void        updateWaitTime_l();
+        virtual     void        saveOutputTracks();
+        virtual     void        clearOutputTracks();
     private:
 
                     uint32_t    mWaitTimeMs;
+        SortedVector < sp<OutputTrack> >  outputTracks;
+        SortedVector < sp<OutputTrack> >  mOutputTracks;
     };
 
               PlaybackThread *checkPlaybackThread_l(audio_io_handle_t output) const;
diff --git a/services/java/com/android/server/PowerManagerService.java b/services/java/com/android/server/PowerManagerService.java
index d9d3f4e..63418db 100644
--- a/services/java/com/android/server/PowerManagerService.java
+++ b/services/java/com/android/server/PowerManagerService.java
@@ -2234,14 +2234,18 @@
                 }
 
                 if (target != currentValue) {
+                    final boolean doScreenAnim = (mask & (SCREEN_BRIGHT_BIT | SCREEN_ON_BIT)) != 0;
                     final boolean turningOff = endValue == Power.BRIGHTNESS_OFF;
-                    if (turningOff && ((mask & (SCREEN_ON_BIT | SCREEN_BRIGHT_BIT)) != 0)) {
+                    if (turningOff && doScreenAnim) {
                         // Cancel all pending animations since we're turning off
                         mScreenBrightnessHandler.removeCallbacksAndMessages(null);
                         screenOffFinishedAnimatingLocked(mScreenOffReason);
                         duration = 200; // TODO: how long should this be?
                     }
-                    animateInternal(mask, turningOff, 0);
+                    if (doScreenAnim) {
+                        animateInternal(mask, turningOff, 0);
+                    }
+                    // TODO: Handle keyboard light animation when we have devices that support it
                 }
             }
         }
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 3ac446c..4ea2f04 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -7952,6 +7952,22 @@
         }
     }
 
+    private void fillInProcMemInfo(ProcessRecord app,
+            ActivityManager.RunningAppProcessInfo outInfo) {
+        outInfo.pid = app.pid;
+        outInfo.uid = app.info.uid;
+        if (mHeavyWeightProcess == app) {
+            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
+        }
+        if (app.persistent) {
+            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
+        }
+        outInfo.lastTrimLevel = app.trimMemoryLevel;
+        int adj = app.curAdj;
+        outInfo.importance = oomAdjToImportance(adj, outInfo);
+        outInfo.importanceReasonCode = app.adjTypeCode;
+    }
+
     public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
         enforceNotIsolatedCaller("getRunningAppProcesses");
         // Lazy instantiation of list
@@ -7965,16 +7981,7 @@
                     ActivityManager.RunningAppProcessInfo currApp = 
                         new ActivityManager.RunningAppProcessInfo(app.processName,
                                 app.pid, app.getPackageList());
-                    currApp.uid = app.info.uid;
-                    if (mHeavyWeightProcess == app) {
-                        currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
-                    }
-                    if (app.persistent) {
-                        currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
-                    }
-                    int adj = app.curAdj;
-                    currApp.importance = oomAdjToImportance(adj, currApp);
-                    currApp.importanceReasonCode = app.adjTypeCode;
+                    fillInProcMemInfo(app, currApp);
                     if (app.adjSource instanceof ProcessRecord) {
                         currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
                         currApp.importanceReasonImportance = oomAdjToImportance(
@@ -8026,6 +8033,18 @@
     }
 
     @Override
+    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
+        enforceNotIsolatedCaller("getMyMemoryState");
+        synchronized (this) {
+            ProcessRecord proc;
+            synchronized (mPidsSelfLocked) {
+                proc = mPidsSelfLocked.get(Binder.getCallingPid());
+            }
+            fillInProcMemInfo(proc, outInfo);
+        }
+    }
+
+    @Override
     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         if (checkCallingPermission(android.Manifest.permission.DUMP)
                 != PackageManager.PERMISSION_GRANTED) {
@@ -8479,8 +8498,8 @@
                     pw.print("    Process "); pw.print(pname);
                             pw.print(" uid "); pw.print(puid);
                             pw.print(": last crashed ");
-                            pw.print((now-uids.valueAt(i)));
-                            pw.println(" ms ago");
+                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
+                            pw.println(" ago");
                 }
             }
         }
@@ -13982,6 +14001,14 @@
             if (mPreviousProcess != null) minFactor++;
             if (factor < minFactor) factor = minFactor;
             step = 0;
+            int fgTrimLevel;
+            if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/5)) {
+                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
+            } else if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/3)) {
+                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
+            } else {
+                fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
+            }
             int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
             for (i=0; i<N; i++) {
                 ProcessRecord app = mLruProcesses.get(i);
@@ -14008,6 +14035,7 @@
                     app.trimMemoryLevel = curLevel;
                     step++;
                     if (step >= factor) {
+                        step = 0;
                         switch (curLevel) {
                             case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
@@ -14027,20 +14055,28 @@
                         }
                     }
                     app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
-                } else if ((app.curAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
-                        && app.pendingUiClean) {
-                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
-                            && app.thread != null) {
+                } else {
+                    if ((app.curAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
+                            && app.pendingUiClean) {
+                        // If this application is now in the background and it
+                        // had done UI, then give it the special trim level to
+                        // have it free UI resources.
+                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
+                        if (app.trimMemoryLevel < level && app.thread != null) {
+                            try {
+                                app.thread.scheduleTrimMemory(level);
+                            } catch (RemoteException e) {
+                            }
+                        }
+                        app.pendingUiClean = false;
+                    }
+                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
                         try {
-                            app.thread.scheduleTrimMemory(
-                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
+                            app.thread.scheduleTrimMemory(fgTrimLevel);
                         } catch (RemoteException e) {
                         }
                     }
-                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
-                    app.pendingUiClean = false;
-                } else {
-                    app.trimMemoryLevel = 0;
+                    app.trimMemoryLevel = fgTrimLevel;
                 }
             }
         } else {
@@ -14057,11 +14093,9 @@
                         } catch (RemoteException e) {
                         }
                     }
-                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
                     app.pendingUiClean = false;
-                } else {
-                    app.trimMemoryLevel = 0;
                 }
+                app.trimMemoryLevel = 0;
             }
         }
 
diff --git a/services/java/com/android/server/net/NetworkStatsService.java b/services/java/com/android/server/net/NetworkStatsService.java
index 13c0640..fd8d411 100644
--- a/services/java/com/android/server/net/NetworkStatsService.java
+++ b/services/java/com/android/server/net/NetworkStatsService.java
@@ -212,6 +212,8 @@
     private final HandlerThread mHandlerThread;
     private final Handler mHandler;
 
+    private boolean mSystemReady;
+
     public NetworkStatsService(
             Context context, INetworkManagementService networkManager, IAlarmManager alarmManager) {
         this(context, networkManager, alarmManager, NtpTrustedTime.getInstance(context),
@@ -250,6 +252,8 @@
     }
 
     public void systemReady() {
+        mSystemReady = true;
+
         if (!isBandwidthControlEnabled()) {
             Slog.w(TAG, "bandwidth controls disabled, unable to track stats");
             return;
@@ -336,6 +340,8 @@
         mUidTagRecorder = null;
 
         mDevStatsCached = null;
+
+        mSystemReady = false;
     }
 
     private void maybeUpgradeLegacyStatsLocked() {
@@ -649,6 +655,7 @@
      * {@link NetworkIdentitySet}.
      */
     private void updateIfacesLocked() {
+        if (!mSystemReady) return;
         if (LOGV) Slog.v(TAG, "updateIfacesLocked()");
 
         // take one last stats snapshot before updating iface mapping. this
@@ -737,7 +744,9 @@
      * {@link NetworkStatsHistory}.
      */
     private void performPollLocked(int flags) {
+        if (!mSystemReady) return;
         if (LOGV) Slog.v(TAG, "performPollLocked(flags=0x" + Integer.toHexString(flags) + ")");
+
         final long startRealtime = SystemClock.elapsedRealtime();
 
         final boolean persistNetwork = (flags & FLAG_PERSIST_NETWORK) != 0;
diff --git a/telephony/java/com/android/internal/telephony/IccCard.java b/telephony/java/com/android/internal/telephony/IccCard.java
index 530a8dc..fe80fdf 100644
--- a/telephony/java/com/android/internal/telephony/IccCard.java
+++ b/telephony/java/com/android/internal/telephony/IccCard.java
@@ -35,8 +35,15 @@
 
 import com.android.internal.telephony.PhoneBase;
 import com.android.internal.telephony.CommandsInterface.RadioState;
+import com.android.internal.telephony.gsm.SIMFileHandler;
 import com.android.internal.telephony.gsm.SIMRecords;
+import com.android.internal.telephony.cdma.CDMALTEPhone;
+import com.android.internal.telephony.cdma.CdmaLteUiccFileHandler;
+import com.android.internal.telephony.cdma.CdmaLteUiccRecords;
 import com.android.internal.telephony.cdma.CdmaSubscriptionSourceManager;
+import com.android.internal.telephony.cdma.RuimFileHandler;
+import com.android.internal.telephony.cdma.RuimRecords;
+
 import android.os.SystemProperties;
 
 import com.android.internal.R;
@@ -56,6 +63,8 @@
     protected boolean isSubscriptionFromIccCard = true;
     protected CdmaSubscriptionSourceManager mCdmaSSM = null;
     protected PhoneBase mPhone;
+    private IccRecords mIccRecords;
+    private IccFileHandler mIccFileHandler;
     private RegistrantList mAbsentRegistrants = new RegistrantList();
     private RegistrantList mPinLockedRegistrants = new RegistrantList();
     private RegistrantList mNetworkLockedRegistrants = new RegistrantList();
@@ -167,26 +176,46 @@
     }
 
     public IccCard(PhoneBase phone, String logTag, Boolean is3gpp, Boolean dbg) {
+        mLogTag = logTag;
+        mDbg = dbg;
+        if (mDbg) log("[IccCard] Creating card type " + (is3gpp ? "3gpp" : "3gpp2"));
         mPhone = phone;
         this.is3gpp = is3gpp;
         mCdmaSSM = CdmaSubscriptionSourceManager.getInstance(mPhone.getContext(),
                 mPhone.mCM, mHandler, EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED, null);
+        if (phone.mCM.getLteOnCdmaMode() == Phone.LTE_ON_CDMA_TRUE
+                && phone instanceof CDMALTEPhone) {
+            mIccRecords = new CdmaLteUiccRecords(phone);
+            mIccFileHandler = new CdmaLteUiccFileHandler((CDMALTEPhone)phone);
+        } else {
+            mIccRecords = is3gpp ? new SIMRecords(phone) : new RuimRecords(phone);
+            mIccFileHandler = is3gpp ? new SIMFileHandler(phone) : new RuimFileHandler(phone);
+        }
         mPhone.mCM.registerForOffOrNotAvailable(mHandler, EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null);
         mPhone.mCM.registerForOn(mHandler, EVENT_RADIO_ON, null);
         mPhone.mCM.registerForIccStatusChanged(mHandler, EVENT_ICC_STATUS_CHANGED, null);
-        mLogTag = logTag;
-        mDbg = dbg;
     }
 
     public void dispose() {
+        if (mDbg) log("[IccCard] Disposing card type " + (is3gpp ? "3gpp" : "3gpp2"));
         mPhone.mCM.unregisterForIccStatusChanged(mHandler);
         mPhone.mCM.unregisterForOffOrNotAvailable(mHandler);
         mPhone.mCM.unregisterForOn(mHandler);
         mCdmaSSM.dispose(mHandler);
+        mIccRecords.dispose();
+        mIccFileHandler.dispose();
     }
 
     protected void finalize() {
-        if(mDbg) Log.d(mLogTag, "IccCard finalized");
+        if (mDbg) log("[IccCard] Finalized card type " + (is3gpp ? "3gpp" : "3gpp2"));
+    }
+
+    public IccRecords getIccRecords() {
+        return mIccRecords;
+    }
+
+    public IccFileHandler getIccFileHandler() {
+        return mIccFileHandler;
     }
 
     /**
@@ -541,6 +570,10 @@
         } else if (isIccCardAdded) {
             mHandler.sendMessage(mHandler.obtainMessage(EVENT_CARD_ADDED, null));
         }
+
+        if (oldState != State.READY && newState == State.READY) {
+            mIccRecords.onReady();
+        }
     }
 
     private void onIccSwap(boolean isAdded) {
@@ -932,6 +965,10 @@
 
     public String getAid() {
         String aid = "";
+        if (mIccCardStatus == null) {
+            return aid;
+        }
+
         int appIndex = getCurrentApplicationIndex();
 
         if (appIndex >= 0 && appIndex < IccCardStatus.CARD_MAX_APPS) {
diff --git a/telephony/java/com/android/internal/telephony/IccRecords.java b/telephony/java/com/android/internal/telephony/IccRecords.java
index fc011c0..6e82903 100644
--- a/telephony/java/com/android/internal/telephony/IccRecords.java
+++ b/telephony/java/com/android/internal/telephony/IccRecords.java
@@ -102,6 +102,7 @@
     public abstract void dispose();
 
     protected abstract void onRadioOffOrNotAvailable();
+    public abstract void onReady();
 
     //***** Public Methods
     public AdnRecordCache getAdnCache() {
diff --git a/telephony/java/com/android/internal/telephony/cdma/CDMALTEPhone.java b/telephony/java/com/android/internal/telephony/cdma/CDMALTEPhone.java
index 3084c14..14a4b46 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CDMALTEPhone.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CDMALTEPhone.java
@@ -36,6 +36,7 @@
 import com.android.internal.telephony.SMSDispatcher;
 import com.android.internal.telephony.gsm.GsmSMSDispatcher;
 import com.android.internal.telephony.ims.IsimRecords;
+import com.android.internal.telephony.uicc.UiccController;
 
 public class CDMALTEPhone extends CDMAPhone {
     static final String LOG_TAG = "CDMA";
@@ -79,9 +80,9 @@
 
     @Override
     protected void initSstIcc() {
-        mIccCard = new IccCard(this, LOG_TAG, IccCard.CARD_IS_3GPP, DBG);
-        mIccRecords = new CdmaLteUiccRecords(this);
-        mIccFileHandler = new CdmaLteUiccFileHandler(this);
+        mIccCard = UiccController.getInstance(this).getIccCard();
+        mIccRecords = mIccCard.getIccRecords();
+        mIccFileHandler = mIccCard.getIccFileHandler();
         // CdmaLteServiceStateTracker registers with IccCard to know
         // when the card is ready. So create mIccCard before the ServiceStateTracker
         mSST = new CdmaLteServiceStateTracker(this);
@@ -164,7 +165,7 @@
         // look for our wrapper within the asyncresult, skip the rest if it
         // is null.
         if (!(ar.userObj instanceof NetworkSelectMessage)) {
-            if (DBG) Log.d(LOG_TAG, "unexpected result from user object.");
+            Log.e(LOG_TAG, "unexpected result from user object.");
             return;
         }
 
@@ -173,7 +174,7 @@
         // found the object, now we send off the message we had originally
         // attached to the request.
         if (nsm.message != null) {
-            if (DBG) Log.d(LOG_TAG, "sending original message to recipient");
+            if (DBG) log("sending original message to recipient");
             AsyncResult.forMessage(nsm.message, ar.result, ar.exception);
             nsm.message.sendToTarget();
         }
@@ -200,14 +201,15 @@
                 ContentValues map = new ContentValues();
                 String operatorNumeric = mIccRecords.getOperatorNumeric();
                 map.put(Telephony.Carriers.NUMERIC, operatorNumeric);
-                log("updateCurrentCarrierInProvider from UICC: numeric=" + operatorNumeric);
+                if (DBG) log("updateCurrentCarrierInProvider from UICC: numeric=" +
+                        operatorNumeric);
                 mContext.getContentResolver().insert(uri, map);
                 return true;
             } catch (SQLException e) {
                 Log.e(LOG_TAG, "[CDMALTEPhone] Can't store current operator ret false", e);
             }
         } else {
-            log("updateCurrentCarrierInProvider mIccRecords == null ret false");
+            if (DBG) log("updateCurrentCarrierInProvider mIccRecords == null ret false");
         }
         return false;
     }
@@ -259,7 +261,6 @@
 
     @Override
     protected void log(String s) {
-        if (DBG)
             Log.d(LOG_TAG, "[CDMALTEPhone] " + s);
     }
 }
diff --git a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java b/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
index b5dca65..e86e441 100755
--- a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
@@ -64,6 +64,7 @@
 import com.android.internal.telephony.TelephonyProperties;
 import com.android.internal.telephony.UUSInfo;
 import com.android.internal.telephony.cat.CatService;
+import com.android.internal.telephony.uicc.UiccController;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -149,9 +150,9 @@
     }
 
     protected void initSstIcc() {
-        mIccCard = new IccCard(this, LOG_TAG, IccCard.CARD_IS_NOT_3GPP, DBG);
-        mIccRecords = new RuimRecords(this);
-        mIccFileHandler = new RuimFileHandler(this);
+        mIccCard = UiccController.getInstance(this).getIccCard();
+        mIccRecords = mIccCard.getIccRecords();
+        mIccFileHandler = mIccCard.getIccFileHandler();
         // CdmaServiceStateTracker registers with IccCard to know
         // when the Ruim card is ready. So create mIccCard before the ServiceStateTracker
         mSST = new CdmaServiceStateTracker(this);
@@ -242,7 +243,6 @@
             mSMS.dispose();
             mIccFileHandler.dispose(); // instance of RuimFileHandler
             mIccRecords.dispose();
-            mIccCard.dispose();
             mRuimPhoneBookInterfaceManager.dispose();
             mRuimSmsInterfaceManager.dispose();
             mSubInfo.dispose();
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaLteUiccFileHandler.java b/telephony/java/com/android/internal/telephony/cdma/CdmaLteUiccFileHandler.java
index 8375fd0..e195ff2 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaLteUiccFileHandler.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaLteUiccFileHandler.java
@@ -27,7 +27,7 @@
 public final class CdmaLteUiccFileHandler extends IccFileHandler {
     static final String LOG_TAG = "CDMA";
 
-    CdmaLteUiccFileHandler(CDMALTEPhone phone) {
+    public CdmaLteUiccFileHandler(CDMALTEPhone phone) {
         super(phone);
     }
 
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaLteUiccRecords.java b/telephony/java/com/android/internal/telephony/cdma/CdmaLteUiccRecords.java
index 0a285b9..ca1e96d 100755
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaLteUiccRecords.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaLteUiccRecords.java
@@ -436,6 +436,10 @@
             return true;
         }
 
+        if (phone == null || phone.mIccCard == null) {
+            return false;
+        }
+
         if (phone.mIccCard.isApplicationOnIcc(AppType.APPTYPE_CSIM) &&
             ((mMdn == null) || (mMin == null))) {
             return false;
diff --git a/telephony/java/com/android/internal/telephony/cdma/RuimFileHandler.java b/telephony/java/com/android/internal/telephony/cdma/RuimFileHandler.java
index 375cc07..e854d7f 100644
--- a/telephony/java/com/android/internal/telephony/cdma/RuimFileHandler.java
+++ b/telephony/java/com/android/internal/telephony/cdma/RuimFileHandler.java
@@ -25,6 +25,7 @@
 import com.android.internal.telephony.IccFileTypeMismatch;
 import com.android.internal.telephony.IccIoResult;
 import com.android.internal.telephony.IccUtils;
+import com.android.internal.telephony.PhoneBase;
 import com.android.internal.telephony.PhoneProxy;
 
 import java.util.ArrayList;
@@ -38,7 +39,7 @@
     //***** Instance Variables
 
     //***** Constructor
-    RuimFileHandler(CDMAPhone phone) {
+    public RuimFileHandler(PhoneBase phone) {
         super(phone);
     }
 
diff --git a/telephony/java/com/android/internal/telephony/cdma/RuimRecords.java b/telephony/java/com/android/internal/telephony/cdma/RuimRecords.java
index e518c4c..265dff7 100755
--- a/telephony/java/com/android/internal/telephony/cdma/RuimRecords.java
+++ b/telephony/java/com/android/internal/telephony/cdma/RuimRecords.java
@@ -31,6 +31,7 @@
 import com.android.internal.telephony.CommandsInterface;
 import com.android.internal.telephony.IccRefreshResponse;
 import com.android.internal.telephony.IccCard;
+import com.android.internal.telephony.PhoneBase;
 import com.android.internal.telephony.TelephonyProperties;
 import com.android.internal.telephony.MccTable;
 
@@ -61,7 +62,6 @@
 
     // ***** Event Constants
 
-    private static final int EVENT_RUIM_READY = 1;
     private static final int EVENT_RADIO_OFF_OR_NOT_AVAILABLE = 2;
     private static final int EVENT_GET_IMSI_DONE = 3;
     private static final int EVENT_GET_DEVICE_IDENTITY_DONE = 4;
@@ -78,7 +78,7 @@
     private static final int EVENT_RUIM_REFRESH = 31;
 
 
-    RuimRecords(CDMAPhone p) {
+    public RuimRecords(PhoneBase p) {
         super(p);
 
         adnCache = new AdnRecordCache(phone);
@@ -88,8 +88,6 @@
         // recordsToLoad is set to 0 because no requests are made yet
         recordsToLoad = 0;
 
-
-        p.mIccCard.registerForRuimReady(this, EVENT_RUIM_READY, null);
         p.mCM.registerForOffOrNotAvailable(this, EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null);
         // NOTE the EVENT_SMS_ON_RUIM is not registered
         p.mCM.registerForIccRefresh(this, EVENT_RUIM_REFRESH, null);
@@ -102,7 +100,6 @@
     @Override
     public void dispose() {
         //Unregister for all events
-        phone.mIccCard.unregisterForRuimReady(this);
         phone.mCM.unregisterForOffOrNotAvailable( this);
         phone.mCM.unregisterForIccRefresh(this);
     }
@@ -206,10 +203,6 @@
         }
 
         try { switch (msg.what) {
-            case EVENT_RUIM_READY:
-                onRuimReady();
-            break;
-
             case EVENT_RADIO_OFF_OR_NOT_AVAILABLE:
                 onRadioOffOrNotAvailable();
             break;
@@ -349,7 +342,8 @@
                 IccCard.INTENT_VALUE_ICC_LOADED, null);
     }
 
-    private void onRuimReady() {
+    @Override
+    public void onReady() {
         /* broadcast intent ICC_READY here so that we can make sure
           READY is sent before IMSI ready
         */
diff --git a/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java b/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java
index 4c846f1..5e9a4f2 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java
@@ -70,6 +70,7 @@
 import com.android.internal.telephony.TelephonyProperties;
 import com.android.internal.telephony.UUSInfo;
 import com.android.internal.telephony.test.SimulatedRadioControl;
+import com.android.internal.telephony.uicc.UiccController;
 import com.android.internal.telephony.IccVmNotSupportedException;
 import com.android.internal.telephony.ServiceStateTracker;
 
@@ -136,12 +137,12 @@
         }
 
         mCM.setPhoneType(Phone.PHONE_TYPE_GSM);
-        mIccCard = new IccCard(this, LOG_TAG, IccCard.CARD_IS_3GPP, true);
+        mIccCard = UiccController.getInstance(this).getIccCard();
         mCT = new GsmCallTracker(this);
         mSST = new GsmServiceStateTracker (this);
         mSMS = new GsmSMSDispatcher(this, mSmsStorageMonitor, mSmsUsageMonitor);
-        mIccFileHandler = new SIMFileHandler(this);
-        mIccRecords = new SIMRecords(this);
+        mIccFileHandler = mIccCard.getIccFileHandler();
+        mIccRecords = mIccCard.getIccRecords();
         mDataConnectionTracker = new GsmDataConnectionTracker (this);
         if (!unitTestMode) {
             mSimPhoneBookIntManager = new SimPhoneBookInterfaceManager(this);
@@ -220,7 +221,6 @@
             mSST.dispose();
             mIccFileHandler.dispose(); // instance of SimFileHandler
             mIccRecords.dispose();
-            mIccCard.dispose();
             mSimPhoneBookIntManager.dispose();
             mSimSmsIntManager.dispose();
             mSubInfo.dispose();
diff --git a/telephony/java/com/android/internal/telephony/gsm/SIMFileHandler.java b/telephony/java/com/android/internal/telephony/gsm/SIMFileHandler.java
index e8d10f9..8c3bc0e 100644
--- a/telephony/java/com/android/internal/telephony/gsm/SIMFileHandler.java
+++ b/telephony/java/com/android/internal/telephony/gsm/SIMFileHandler.java
@@ -23,22 +23,20 @@
 import com.android.internal.telephony.IccCardApplication;
 import com.android.internal.telephony.IccConstants;
 import com.android.internal.telephony.IccFileHandler;
-import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneBase;
 
 /**
  * {@hide}
  */
 public final class SIMFileHandler extends IccFileHandler implements IccConstants {
     static final String LOG_TAG = "GSM";
-    private Phone mPhone;
 
     //***** Instance Variables
 
     //***** Constructor
 
-    SIMFileHandler(GSMPhone phone) {
+    public SIMFileHandler(PhoneBase phone) {
         super(phone);
-        mPhone = phone;
     }
 
     public void dispose() {
diff --git a/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java b/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java
index 1fb99e3..68d3b2a 100755
--- a/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java
+++ b/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java
@@ -123,7 +123,6 @@
 
     // ***** Event Constants
 
-    private static final int EVENT_SIM_READY = 1;
     private static final int EVENT_RADIO_OFF_OR_NOT_AVAILABLE = 2;
     protected static final int EVENT_GET_IMSI_DONE = 3;
     protected static final int EVENT_GET_ICCID_DONE = 4;
@@ -188,7 +187,6 @@
         // recordsToLoad is set to 0 because no requests are made yet
         recordsToLoad = 0;
 
-        p.mIccCard.registerForReady(this, EVENT_SIM_READY, null);
         p.mCM.registerForOffOrNotAvailable(
                         this, EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null);
         p.mCM.setOnSmsOnSim(this, EVENT_SMS_ON_SIM, null);
@@ -202,7 +200,6 @@
     @Override
     public void dispose() {
         //Unregister for all events
-        phone.mIccCard.unregisterForReady(this);
         phone.mCM.unregisterForOffOrNotAvailable( this);
         phone.mCM.unregisterForIccRefresh(this);
     }
@@ -526,10 +523,6 @@
         }
 
         try { switch (msg.what) {
-            case EVENT_SIM_READY:
-                onSimReady();
-            break;
-
             case EVENT_RADIO_OFF_OR_NOT_AVAILABLE:
                 onRadioOffOrNotAvailable();
             break;
@@ -1296,7 +1289,8 @@
         }
     }
 
-    public void onSimReady() {
+    @Override
+    public void onReady() {
         /* broadcast intent SIM_READY here so that we can make sure
           READY is sent before IMSI ready
         */
diff --git a/telephony/java/com/android/internal/telephony/uicc/UiccController.java b/telephony/java/com/android/internal/telephony/uicc/UiccController.java
new file mode 100644
index 0000000..5961efd
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/uicc/UiccController.java
@@ -0,0 +1,93 @@
+/*
+ * 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.
+ */
+
+package com.android.internal.telephony.uicc;
+
+import com.android.internal.telephony.IccCard;
+import com.android.internal.telephony.PhoneBase;
+import com.android.internal.telephony.cdma.CDMALTEPhone;
+import com.android.internal.telephony.cdma.CDMAPhone;
+import com.android.internal.telephony.gsm.GSMPhone;
+
+import android.util.Log;
+
+/* This class is responsible for keeping all knowledge about
+ * ICCs in the system. It is also used as API to get appropriate
+ * applications to pass them to phone and service trackers.
+ */
+public class UiccController {
+    private static final boolean DBG = true;
+    private static final String LOG_TAG = "RIL_UiccController";
+
+    private static UiccController mInstance;
+
+    private PhoneBase mCurrentPhone;
+    private boolean mIsCurrentCard3gpp;
+    private IccCard mIccCard;
+
+    public static synchronized UiccController getInstance(PhoneBase phone) {
+        if (mInstance == null) {
+            mInstance = new UiccController(phone);
+        } else {
+            mInstance.setNewPhone(phone);
+        }
+        return mInstance;
+    }
+
+    public IccCard getIccCard() {
+        return mIccCard;
+    }
+
+    private UiccController(PhoneBase phone) {
+        if (DBG) log("Creating UiccController");
+        setNewPhone(phone);
+    }
+
+    private void setNewPhone(PhoneBase phone) {
+        mCurrentPhone = phone;
+        if (phone instanceof GSMPhone) {
+            if (DBG) log("New phone is GSMPhone");
+            updateCurrentCard(IccCard.CARD_IS_3GPP);
+        } else if (phone instanceof CDMALTEPhone){
+            if (DBG) log("New phone type is CDMALTEPhone");
+            updateCurrentCard(IccCard.CARD_IS_3GPP);
+        } else if (phone instanceof CDMAPhone){
+            if (DBG) log("New phone type is CDMAPhone");
+            updateCurrentCard(IccCard.CARD_IS_NOT_3GPP);
+        } else {
+            Log.e(LOG_TAG, "Unhandled phone type. Critical error!");
+        }
+    }
+
+    private void updateCurrentCard(boolean isNewCard3gpp) {
+        if (mIsCurrentCard3gpp == isNewCard3gpp && mIccCard != null) {
+            return;
+        }
+
+        if (mIccCard != null) {
+            mIccCard.dispose();
+            mIccCard = null;
+        }
+
+        mIsCurrentCard3gpp = isNewCard3gpp;
+        mIccCard = new IccCard(mCurrentPhone, mCurrentPhone.getPhoneName(),
+                isNewCard3gpp, DBG);
+    }
+
+    private void log(String string) {
+        Log.d(LOG_TAG, string);
+    }
+}
\ No newline at end of file
diff --git a/tests/RenderScriptTests/SampleTest/res/layout/rs.xml b/tests/RenderScriptTests/SampleTest/res/layout/rs.xml
index 61c339a..f2a356f 100644
--- a/tests/RenderScriptTests/SampleTest/res/layout/rs.xml
+++ b/tests/RenderScriptTests/SampleTest/res/layout/rs.xml
@@ -26,10 +26,42 @@
                 android:orientation="vertical"
                 android:layout_width="fill_parent"
                 android:layout_height="fill_parent">
+            <TextView
+                        android:layout_width="match_parent"
+                        android:layout_height="wrap_content"
+                        android:textSize="8pt"
+                        android:text="@string/wraplinear"/>
             <TextureView
                 android:id="@+id/display"
                 android:layout_width="256sp"
                 android:layout_height="256sp" />
+            <TextView
+                        android:layout_width="match_parent"
+                        android:layout_height="wrap_content"
+                        android:textSize="8pt"
+                        android:text="@string/clamplinear"/>
+            <TextureView
+                android:id="@+id/display2"
+                android:layout_width="256sp"
+                android:layout_height="256sp" />
+            <TextView
+                        android:layout_width="match_parent"
+                        android:layout_height="wrap_content"
+                        android:textSize="8pt"
+                        android:text="@string/wrapnearest"/>
+            <TextureView
+                android:id="@+id/display3"
+                android:layout_width="256sp"
+                android:layout_height="256sp" />
+            <TextView
+                        android:layout_width="match_parent"
+                        android:layout_height="wrap_content"
+                        android:textSize="8pt"
+                        android:text="@string/clampnearest"/>
+            <TextureView
+                android:id="@+id/display4"
+                android:layout_width="256sp"
+                android:layout_height="256sp" />
             <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
                 android:orientation="horizontal"
                 android:layout_width="fill_parent"
diff --git a/tests/RenderScriptTests/SampleTest/res/values/strings.xml b/tests/RenderScriptTests/SampleTest/res/values/strings.xml
index a92eac0..a0a2499 100644
--- a/tests/RenderScriptTests/SampleTest/res/values/strings.xml
+++ b/tests/RenderScriptTests/SampleTest/res/values/strings.xml
@@ -21,4 +21,8 @@
     <!-- General -->
     <skip />
     <string name="benchmark">Benchmark</string>
+    <string name="wraplinear">Wrap Linear</string>
+    <string name="clamplinear">Clamp Linear</string>
+    <string name="wrapnearest">Wrap Nearest</string>
+    <string name="clampnearest">Clamp Nearest</string>
 </resources>
diff --git a/tests/RenderScriptTests/SampleTest/src/com/android/rs/sample/SampleRSActivity.java b/tests/RenderScriptTests/SampleTest/src/com/android/rs/sample/SampleRSActivity.java
index 91e3c4c..cd5d53f 100644
--- a/tests/RenderScriptTests/SampleTest/src/com/android/rs/sample/SampleRSActivity.java
+++ b/tests/RenderScriptTests/SampleTest/src/com/android/rs/sample/SampleRSActivity.java
@@ -31,14 +31,40 @@
 import android.renderscript.Type.Builder;
 import android.util.Log;
 import android.view.TextureView;
+import android.view.TextureView.SurfaceTextureListener;
 import android.view.View;
 import android.widget.ImageView;
 import android.widget.SeekBar;
 import android.widget.TextView;
 
-public class SampleRSActivity extends Activity
-                              implements TextureView.SurfaceTextureListener
-{
+public class SampleRSActivity extends Activity {
+    class TextureViewUpdater implements TextureView.SurfaceTextureListener {
+        private Allocation mOutPixelsAllocation;
+        private Sampler mSampler;
+
+        TextureViewUpdater(Allocation outAlloc, Sampler sampler) {
+            mOutPixelsAllocation = outAlloc;
+            mSampler = sampler;
+        }
+
+        public void onSurfaceTextureUpdated(SurfaceTexture surface) {
+        }
+
+        public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
+            mOutPixelsAllocation.setSurfaceTexture(surface);
+        }
+
+        public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
+            mOutPixelsAllocation.setSurfaceTexture(surface);
+            filterAlloc(mOutPixelsAllocation, mSampler);
+        }
+
+        public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
+            mOutPixelsAllocation.setSurfaceTexture(null);
+            return true;
+        }
+    }
+
     private final String TAG = "Img";
     private Bitmap mBitmapIn;
     private TextureView mDisplayView;
@@ -47,7 +73,6 @@
 
     private RenderScript mRS;
     private Allocation mInPixelsAllocation;
-    private Allocation mOutPixelsAllocation;
     private ScriptC_sample mScript;
 
     public void onStartTrackingTouch(SeekBar seekBar) {
@@ -74,17 +99,36 @@
 
         Type.Builder b = new Type.Builder(mRS, Element.RGBA_8888(mRS));
 
-        mOutPixelsAllocation = Allocation.createTyped(mRS, b.setX(32).setY(32).create(),
-                                                      Allocation.USAGE_SCRIPT |
-                                                      Allocation.USAGE_IO_OUTPUT);
-        mDisplayView.setSurfaceTextureListener(this);
+        int usage = Allocation.USAGE_SCRIPT | Allocation.USAGE_IO_OUTPUT;
+
+        int outX = 32;
+        int outY = 32;
+
+        // Wrap Linear
+        Allocation outAlloc = Allocation.createTyped(mRS, b.setX(outX).setY(outY).create(), usage);
+        TextureViewUpdater updater = new TextureViewUpdater(outAlloc, Sampler.WRAP_LINEAR(mRS));
+        TextureView displayView = (TextureView) findViewById(R.id.display);
+        displayView.setSurfaceTextureListener(updater);
+
+        // Clamp Linear
+        outAlloc = Allocation.createTyped(mRS, b.setX(outX).setY(outY).create(), usage);
+        updater = new TextureViewUpdater(outAlloc, Sampler.CLAMP_LINEAR(mRS));
+        displayView = (TextureView) findViewById(R.id.display2);
+        displayView.setSurfaceTextureListener(updater);
+
+        // Wrap Nearest
+        outAlloc = Allocation.createTyped(mRS, b.setX(outX).setY(outY).create(), usage);
+        updater = new TextureViewUpdater(outAlloc, Sampler.WRAP_NEAREST(mRS));
+        displayView = (TextureView) findViewById(R.id.display3);
+        displayView.setSurfaceTextureListener(updater);
+
+        // Clamp Nearest
+        outAlloc = Allocation.createTyped(mRS, b.setX(outX).setY(outY).create(), usage);
+        updater = new TextureViewUpdater(outAlloc, Sampler.CLAMP_NEAREST(mRS));
+        displayView = (TextureView) findViewById(R.id.display4);
+        displayView.setSurfaceTextureListener(updater);
 
         mScript = new ScriptC_sample(mRS, getResources(), R.raw.sample);
-
-        mScript.set_sourceAlloc(mInPixelsAllocation);
-        mScript.set_destAlloc(mOutPixelsAllocation);
-        mScript.set_wrapUV(Sampler.WRAP_LINEAR(mRS));
-        mScript.set_clampUV(Sampler.CLAMP_LINEAR(mRS));
     }
 
     private Bitmap loadBitmap(int resource) {
@@ -98,43 +142,22 @@
         return b2;
     }
 
-    private void filter() {
+    private synchronized void filterAlloc(Allocation alloc, Sampler sampler) {
         long t = java.lang.System.currentTimeMillis();
-        mScript.forEach_root(mOutPixelsAllocation);
-        mOutPixelsAllocation.ioSendOutput();
+        mScript.invoke_setSampleData(alloc, mInPixelsAllocation, sampler);
+        mScript.forEach_root(alloc);
+        alloc.ioSendOutput();
         mRS.finish();
         t = java.lang.System.currentTimeMillis() - t;
         Log.i(TAG, "Filter time is: " + t + " ms");
     }
 
     public void benchmark(View v) {
-        filter();
+        /*filterAlloc();
         long t = java.lang.System.currentTimeMillis();
-        filter();
+        filterAlloc();
         t = java.lang.System.currentTimeMillis() - t;
         mDisplayView.invalidate();
-        mBenchmarkResult.setText("Result: " + t + " ms");
-    }
-
-
-    @Override
-    public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
-        mOutPixelsAllocation.setSurfaceTexture(surface);
-        filter();
-    }
-
-    @Override
-    public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
-        mOutPixelsAllocation.setSurfaceTexture(surface);
-    }
-
-    @Override
-    public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
-        mOutPixelsAllocation.setSurfaceTexture(null);
-        return true;
-    }
-
-    @Override
-    public void onSurfaceTextureUpdated(SurfaceTexture surface) {
+        mBenchmarkResult.setText("Result: " + t + " ms");*/
     }
 }
diff --git a/tests/RenderScriptTests/SampleTest/src/com/android/rs/sample/sample.rs b/tests/RenderScriptTests/SampleTest/src/com/android/rs/sample/sample.rs
index 8f09be0..8a027b2 100644
--- a/tests/RenderScriptTests/SampleTest/src/com/android/rs/sample/sample.rs
+++ b/tests/RenderScriptTests/SampleTest/src/com/android/rs/sample/sample.rs
@@ -18,16 +18,24 @@
 #pragma rs java_package_name(com.android.rs.sample)
 #include "rs_graphics.rsh"
 
-rs_sampler wrapUV;
-rs_sampler clampUV;
-rs_allocation sourceAlloc;
-rs_allocation destAlloc;
+static rs_allocation sourceAlloc;
+static rs_allocation destAlloc;
+static rs_sampler allocSampler;
 
-static uint32_t wrapI(rs_sampler_value wrap, uint32_t coord, uint32_t size) {
+void setSampleData(rs_allocation dest, rs_allocation source, rs_sampler sampler) {
+    destAlloc = dest;
+    sourceAlloc = source;
+    allocSampler = sampler;
+}
+
+static int32_t wrapI(rs_sampler_value wrap, int32_t coord, int32_t size) {
     if (wrap == RS_SAMPLER_WRAP) {
-        return coord % (size + 1);
+        coord = coord % size;
+        if (coord < 0) {
+            coord += size;
+        }
     }
-    return min(coord, size);
+    return max(0, min(coord, size - 1));
 }
 
 static float2 wrap(rs_sampler_value wrapS, rs_sampler_value wrapT, float2 coord) {
@@ -39,8 +47,11 @@
         if (wrappedCoord.x == 0.0f && coord.x != 0.0f) {
             wrappedCoord.x = 1.0f;
         }
+        if (wrappedCoord.x < 0.0f) {
+            wrappedCoord.x += 1.0f;
+        }
     } else {
-        wrappedCoord.x = min(coord.x, 1.0f);
+        wrappedCoord.x = max(0.0f, min(coord.x, 1.0f));
     }
 
     if (wrapT == RS_SAMPLER_WRAP) {
@@ -49,14 +60,18 @@
         if (wrappedCoord.y == 0.0f && coord.y != 0.0f) {
             wrappedCoord.y = 1.0f;
         }
+        if (wrappedCoord.y < 0.0f) {
+            wrappedCoord.y += 1.0f;
+        }
     } else {
-        wrappedCoord.y = min(coord.y, 1.0f);
+        wrappedCoord.y = max(0.0f, min(coord.y, 1.0f));
     }
     return wrappedCoord;
 }
 
 // Naive implementation of texture filtering for prototyping purposes
 static float4 sample(rs_allocation a, rs_sampler s, float2 uv) {
+    //rsDebug("*****************************************", 0);
     rs_sampler_value wrapS = rsgSamplerGetWrapS(s);
     rs_sampler_value wrapT = rsgSamplerGetWrapT(s);
 
@@ -65,26 +80,57 @@
 
     uv = wrap(wrapS, wrapT, uv);
 
-    uint32_t sourceW = rsAllocationGetDimX(a) - 1;
-    uint32_t sourceH = rsAllocationGetDimY(a) - 1;
+    int32_t sourceW = rsAllocationGetDimX(a);
+    int32_t sourceH = rsAllocationGetDimY(a);
+
+    /*rsDebug("uv", uv);
+    rsDebug("sourceW", sourceW);
+    rsDebug("sourceH", sourceH);*/
 
     float2 dimF;
     dimF.x = (float)(sourceW);
     dimF.y = (float)(sourceH);
     float2 pixelUV = uv * dimF;
-    uint2 iPixel = convert_uint2(pixelUV);
+    int2 iPixel = convert_int2(pixelUV);
+    /*rsDebug("iPixelX initial", iPixel.x);
+    rsDebug("iPixelY initial", iPixel.y);*/
 
     if (sampleMin == RS_SAMPLER_NEAREST ||
         sampleMag == RS_SAMPLER_NEAREST) {
+        iPixel.x = wrapI(wrapS, iPixel.x, sourceW);
+        iPixel.y = wrapI(wrapT, iPixel.y, sourceH);
         uchar4 *nearestSample = (uchar4*)rsGetElementAt(a, iPixel.x, iPixel.y);
         return convert_float4(*nearestSample);
     }
 
     float2 frac = pixelUV - convert_float2(iPixel);
+
+    if (frac.x < 0.5f) {
+        iPixel.x -= 1;
+        frac.x += 0.5f;
+    } else {
+        frac.x -= 0.5f;
+    }
+    if (frac.y < 0.5f) {
+        iPixel.y -= 1;
+        frac.y += 0.5f;
+    } else {
+        frac.y -= 0.5f;
+    }
     float2 oneMinusFrac = 1.0f - frac;
 
+    float4 weights;
+    weights.x = oneMinusFrac.x * oneMinusFrac.y;
+    weights.y = frac.x * oneMinusFrac.y;
+    weights.z = oneMinusFrac.x * frac.y;
+    weights.w = frac.x * frac.y;
+
     uint32_t nextX = wrapI(wrapS, iPixel.x + 1, sourceW);
     uint32_t nextY = wrapI(wrapT, iPixel.y + 1, sourceH);
+    iPixel.x = wrapI(wrapS, iPixel.x, sourceW);
+    iPixel.y = wrapI(wrapT, iPixel.y, sourceH);
+    /*rsDebug("iPixelX wrapped", iPixel.x);
+    rsDebug("iPixelY wrapped", iPixel.y);*/
 
     uchar4 *p0c = (uchar4*)rsGetElementAt(a, iPixel.x, iPixel.y);
     uchar4 *p1c = (uchar4*)rsGetElementAt(a, nextX, iPixel.y);
@@ -96,24 +142,9 @@
     float4 p2 = convert_float4(*p2c);
     float4 p3 = convert_float4(*p3c);
 
-    float4 weights;
-    weights.x = oneMinusFrac.x * oneMinusFrac.y;
-    weights.y = frac.x * oneMinusFrac.y;
-    weights.z = oneMinusFrac.x * frac.y;
-    weights.w = frac.x * frac.y;
-
     float4 result = p0 * weights.x + p1 * weights.y + p2 * weights.z + p3 * weights.w;
 
-    /*rsDebug("*****************************************", 0);
-    rsDebug("u", uv.x);
-    rsDebug("v", uv.y);
-    rsDebug("sourceW", sourceW);
-    rsDebug("sourceH", sourceH);
-    rsDebug("iPixelX", iPixel.x);
-    rsDebug("iPixelY", iPixel.y);
-    rsDebug("fiPixel", (float2)iPixel);
-    rsDebug("whole", wholeUV);
-    rsDebug("pixelUV", pixelUV);
+    /*rsDebug("pixelUV", pixelUV);
     rsDebug("frac", frac);
     rsDebug("oneMinusFrac", oneMinusFrac);
     rsDebug("p0", p0);
@@ -131,15 +162,11 @@
     float destX = (float)rsAllocationGetDimX(destAlloc) - 1.0f;
     float destY = (float)rsAllocationGetDimY(destAlloc) - 1.0f;
 
-    /*rsDebug("*****************************************", 0);
-    rsDebug("x", x);
-    rsDebug("y", y);*/
-
     float2 uv;
     uv.x = (float)x / destX;
     uv.y = (float)y / destY;
 
-    out->xyz = convert_uchar3(sample(sourceAlloc, wrapUV, uv*2.0f).xyz);
+    out->xyz = convert_uchar3(sample(sourceAlloc, allocSampler, uv*2.0f).xyz);
     out->w = 0xff;
 }