Merge "Change RSSI notification levels to 5 in framework"
diff --git a/Android.mk b/Android.mk
index 4cd85ec..80e681c 100644
--- a/Android.mk
+++ b/Android.mk
@@ -478,6 +478,8 @@
 		            resources/samples/TicTacToeLib "TicTacToeLib" \
 		-samplecode $(sample_dir)/TicTacToeMain \
 		            resources/samples/TicTacToeMain "TicTacToeMain" \
+		-samplecode $(sample_dir)/ToyVpn \
+		            resources/samples/ToyVpn "Toy VPN Client" \
 		-samplecode $(sample_dir)/USB \
 		            resources/samples/USB "USB" \
 		-samplecode $(sample_dir)/WeatherListWidget \
diff --git a/api/current.txt b/api/current.txt
index 4cf23eb..9610853 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -5334,6 +5334,7 @@
     method public java.util.ArrayList<T> getParcelableArrayListExtra(java.lang.String);
     method public T getParcelableExtra(java.lang.String);
     method public java.lang.String getScheme();
+    method public android.content.Intent getSelector();
     method public java.io.Serializable getSerializableExtra(java.lang.String);
     method public short[] getShortArrayExtra(java.lang.String);
     method public short getShortExtra(java.lang.String, short);
@@ -5346,6 +5347,7 @@
     method public boolean hasExtra(java.lang.String);
     method public boolean hasFileDescriptors();
     method public static android.content.Intent makeMainActivity(android.content.ComponentName);
+    method public static android.content.Intent makeMainSelectorActivity(java.lang.String, java.lang.String);
     method public static android.content.Intent makeRestartActivityTask(android.content.ComponentName);
     method public static android.content.Intent parseIntent(android.content.res.Resources, org.xmlpull.v1.XmlPullParser, android.util.AttributeSet) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
     method public static android.content.Intent parseUri(java.lang.String, int) throws java.net.URISyntaxException;
@@ -5399,6 +5401,7 @@
     method public void setExtrasClassLoader(java.lang.ClassLoader);
     method public android.content.Intent setFlags(int);
     method public android.content.Intent setPackage(java.lang.String);
+    method public void setSelector(android.content.Intent);
     method public void setSourceBounds(android.graphics.Rect);
     method public android.content.Intent setType(java.lang.String);
     method public deprecated java.lang.String toURI();
@@ -5502,7 +5505,16 @@
     field public static final java.lang.String ACTION_WALLPAPER_CHANGED = "android.intent.action.WALLPAPER_CHANGED";
     field public static final java.lang.String ACTION_WEB_SEARCH = "android.intent.action.WEB_SEARCH";
     field public static final java.lang.String CATEGORY_ALTERNATIVE = "android.intent.category.ALTERNATIVE";
+    field public static final java.lang.String CATEGORY_APP_BROWSER = "android.intent.category.APP_BROWSER";
+    field public static final java.lang.String CATEGORY_APP_CALCULATOR = "android.intent.category.APP_CALCULATOR";
+    field public static final java.lang.String CATEGORY_APP_CALENDAR = "android.intent.category.APP_CALENDAR";
+    field public static final java.lang.String CATEGORY_APP_CONTACTS = "android.intent.category.APP_CONTACTS";
+    field public static final java.lang.String CATEGORY_APP_EMAIL = "android.intent.category.APP_EMAIL";
+    field public static final java.lang.String CATEGORY_APP_GALLERY = "android.intent.category.APP_GALLERY";
+    field public static final java.lang.String CATEGORY_APP_MAPS = "android.intent.category.APP_MAPS";
     field public static final java.lang.String CATEGORY_APP_MARKET = "android.intent.category.APP_MARKET";
+    field public static final java.lang.String CATEGORY_APP_MESSAGING = "android.intent.category.APP_MESSAGING";
+    field public static final java.lang.String CATEGORY_APP_MUSIC = "android.intent.category.APP_MUSIC";
     field public static final java.lang.String CATEGORY_BROWSABLE = "android.intent.category.BROWSABLE";
     field public static final java.lang.String CATEGORY_CAR_DOCK = "android.intent.category.CAR_DOCK";
     field public static final java.lang.String CATEGORY_CAR_MODE = "android.intent.category.CAR_MODE";
@@ -5568,6 +5580,7 @@
     field public static final int FILL_IN_COMPONENT = 8; // 0x8
     field public static final int FILL_IN_DATA = 2; // 0x2
     field public static final int FILL_IN_PACKAGE = 16; // 0x10
+    field public static final int FILL_IN_SELECTOR = 64; // 0x40
     field public static final int FILL_IN_SOURCE_BOUNDS = 32; // 0x20
     field public static final int FLAG_ACTIVITY_BROUGHT_TO_FRONT = 4194304; // 0x400000
     field public static final int FLAG_ACTIVITY_CLEAR_TASK = 32768; // 0x8000
@@ -14779,6 +14792,7 @@
     field public static final int FLAG_ONEWAY = 1; // 0x1
     field public static final int INTERFACE_TRANSACTION = 1598968902; // 0x5f4e5446
     field public static final int LAST_CALL_TRANSACTION = 16777215; // 0xffffff
+    field public static final int LIKE_TRANSACTION = 1598835019; // 0x5f4c494b
     field public static final int PING_TRANSACTION = 1599098439; // 0x5f504e47
     field public static final int TWEET_TRANSACTION = 1599362900; // 0x5f545754
   }
@@ -17057,7 +17071,7 @@
     field public static final java.lang.String EXTRA_VIDEO_QUALITY = "android.intent.extra.videoQuality";
     field public static final java.lang.String INTENT_ACTION_MEDIA_PLAY_FROM_SEARCH = "android.media.action.MEDIA_PLAY_FROM_SEARCH";
     field public static final java.lang.String INTENT_ACTION_MEDIA_SEARCH = "android.intent.action.MEDIA_SEARCH";
-    field public static final java.lang.String INTENT_ACTION_MUSIC_PLAYER = "android.intent.action.MUSIC_PLAYER";
+    field public static final deprecated java.lang.String INTENT_ACTION_MUSIC_PLAYER = "android.intent.action.MUSIC_PLAYER";
     field public static final java.lang.String INTENT_ACTION_STILL_IMAGE_CAMERA = "android.media.action.STILL_IMAGE_CAMERA";
     field public static final java.lang.String INTENT_ACTION_VIDEO_CAMERA = "android.media.action.VIDEO_CAMERA";
     field public static final java.lang.String MEDIA_IGNORE_FILENAME = ".nomedia";
@@ -17421,6 +17435,7 @@
     method public static boolean putString(android.content.ContentResolver, java.lang.String, java.lang.String);
     method public static final void setLocationProviderEnabled(android.content.ContentResolver, java.lang.String, boolean);
     field public static final java.lang.String ACCESSIBILITY_ENABLED = "accessibility_enabled";
+    field public static final java.lang.String ACCESSIBILITY_SPEAK_PASSWORD = "speak_password";
     field public static final java.lang.String ADB_ENABLED = "adb_enabled";
     field public static final java.lang.String ALLOWED_GEOLOCATION_ORIGINS = "allowed_geolocation_origins";
     field public static final java.lang.String ALLOW_MOCK_LOCATION = "mock_location";
@@ -22217,6 +22232,8 @@
     field public static final int KEYCODE_BUTTON_Y = 100; // 0x64
     field public static final int KEYCODE_BUTTON_Z = 101; // 0x65
     field public static final int KEYCODE_C = 31; // 0x1f
+    field public static final int KEYCODE_CALCULATOR = 210; // 0xd2
+    field public static final int KEYCODE_CALENDAR = 208; // 0xd0
     field public static final int KEYCODE_CALL = 5; // 0x5
     field public static final int KEYCODE_CAMERA = 27; // 0x1b
     field public static final int KEYCODE_CAPS_LOCK = 115; // 0x73
@@ -22225,6 +22242,7 @@
     field public static final int KEYCODE_CHANNEL_UP = 166; // 0xa6
     field public static final int KEYCODE_CLEAR = 28; // 0x1c
     field public static final int KEYCODE_COMMA = 55; // 0x37
+    field public static final int KEYCODE_CONTACTS = 207; // 0xcf
     field public static final int KEYCODE_CTRL_LEFT = 113; // 0x71
     field public static final int KEYCODE_CTRL_RIGHT = 114; // 0x72
     field public static final int KEYCODE_D = 32; // 0x20
@@ -22292,6 +22310,7 @@
     field public static final int KEYCODE_MINUS = 69; // 0x45
     field public static final int KEYCODE_MOVE_END = 123; // 0x7b
     field public static final int KEYCODE_MOVE_HOME = 122; // 0x7a
+    field public static final int KEYCODE_MUSIC = 209; // 0xd1
     field public static final int KEYCODE_MUTE = 91; // 0x5b
     field public static final int KEYCODE_N = 42; // 0x2a
     field public static final int KEYCODE_NOTIFICATION = 83; // 0x53
diff --git a/cmds/am/src/com/android/commands/am/Am.java b/cmds/am/src/com/android/commands/am/Am.java
index 140222e..fddb429 100644
--- a/cmds/am/src/com/android/commands/am/Am.java
+++ b/cmds/am/src/com/android/commands/am/Am.java
@@ -131,6 +131,10 @@
             runScreenCompat();
         } else if (op.equals("display-size")) {
             runDisplaySize();
+        } else if (op.equals("to-uri")) {
+            runToUri(false);
+        } else if (op.equals("to-intent-uri")) {
+            runToUri(true);
         } else {
             throw new IllegalArgumentException("Unknown command: " + op);
         }
@@ -138,6 +142,7 @@
 
     private Intent makeIntent() throws URISyntaxException {
         Intent intent = new Intent();
+        Intent baseIntent = intent;
         boolean hasIntentInfo = false;
 
         mDebugOption = false;
@@ -152,35 +157,39 @@
         while ((opt=nextOption()) != null) {
             if (opt.equals("-a")) {
                 intent.setAction(nextArgRequired());
-                hasIntentInfo = true;
+                if (intent == baseIntent) {
+                    hasIntentInfo = true;
+                }
             } else if (opt.equals("-d")) {
                 data = Uri.parse(nextArgRequired());
-                hasIntentInfo = true;
+                if (intent == baseIntent) {
+                    hasIntentInfo = true;
+                }
             } else if (opt.equals("-t")) {
                 type = nextArgRequired();
-                hasIntentInfo = true;
+                if (intent == baseIntent) {
+                    hasIntentInfo = true;
+                }
             } else if (opt.equals("-c")) {
                 intent.addCategory(nextArgRequired());
-                hasIntentInfo = true;
+                if (intent == baseIntent) {
+                    hasIntentInfo = true;
+                }
             } else if (opt.equals("-e") || opt.equals("--es")) {
                 String key = nextArgRequired();
                 String value = nextArgRequired();
                 intent.putExtra(key, value);
-                hasIntentInfo = true;
             } else if (opt.equals("--esn")) {
                 String key = nextArgRequired();
                 intent.putExtra(key, (String) null);
-                hasIntentInfo = true;
             } else if (opt.equals("--ei")) {
                 String key = nextArgRequired();
                 String value = nextArgRequired();
                 intent.putExtra(key, Integer.valueOf(value));
-                hasIntentInfo = true;
             } else if (opt.equals("--eu")) {
                 String key = nextArgRequired();
                 String value = nextArgRequired();
                 intent.putExtra(key, Uri.parse(value));
-                hasIntentInfo = true;
             } else if (opt.equals("--eia")) {
                 String key = nextArgRequired();
                 String value = nextArgRequired();
@@ -190,12 +199,10 @@
                     list[i] = Integer.valueOf(strings[i]);
                 }
                 intent.putExtra(key, list);
-                hasIntentInfo = true;
             } else if (opt.equals("--el")) {
                 String key = nextArgRequired();
                 String value = nextArgRequired();
                 intent.putExtra(key, Long.valueOf(value));
-                hasIntentInfo = true;
             } else if (opt.equals("--ela")) {
                 String key = nextArgRequired();
                 String value = nextArgRequired();
@@ -205,18 +212,18 @@
                     list[i] = Long.valueOf(strings[i]);
                 }
                 intent.putExtra(key, list);
-                hasIntentInfo = true;
             } else if (opt.equals("--ez")) {
                 String key = nextArgRequired();
                 String value = nextArgRequired();
                 intent.putExtra(key, Boolean.valueOf(value));
-                hasIntentInfo = true;
             } else if (opt.equals("-n")) {
                 String str = nextArgRequired();
                 ComponentName cn = ComponentName.unflattenFromString(str);
                 if (cn == null) throw new IllegalArgumentException("Bad component name: " + str);
                 intent.setComponent(cn);
-                hasIntentInfo = true;
+                if (intent == baseIntent) {
+                    hasIntentInfo = true;
+                }
             } else if (opt.equals("-f")) {
                 String str = nextArgRequired();
                 intent.setFlags(Integer.decode(str).intValue());
@@ -264,6 +271,9 @@
                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
             } else if (opt.equals("--receiver-replace-pending")) {
                 intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
+            } else if (opt.equals("--selector")) {
+                intent.setDataAndType(data, type);
+                intent = new Intent();
             } else if (opt.equals("-D")) {
                 mDebugOption = true;
             } else if (opt.equals("-W")) {
@@ -286,25 +296,42 @@
         }
         intent.setDataAndType(data, type);
 
+        final boolean hasSelector = intent != baseIntent;
+        if (hasSelector) {
+            // A selector was specified; fix up.
+            baseIntent.setSelector(intent);
+            intent = baseIntent;
+        }
+
         String arg = nextArg();
-        if (arg != null) {
-            Intent baseIntent;
-            if (arg.indexOf(':') >= 0) {
-                // The argument is a URI.  Fully parse it, and use that result
-                // to fill in any data not specified so far.
-                baseIntent = Intent.parseUri(arg, Intent.URI_INTENT_SCHEME);
-            } else if (arg.indexOf('/') >= 0) {
-                // The argument is a component name.  Build an Intent to launch
-                // it.
+        baseIntent = null;
+        if (arg == null) {
+            if (hasSelector) {
+                // If a selector has been specified, and no arguments
+                // have been supplied for the main Intent, then we can
+                // assume it is ACTION_MAIN CATEGORY_LAUNCHER; we don't
+                // need to have a component name specified yet, the
+                // selector will take care of that.
                 baseIntent = new Intent(Intent.ACTION_MAIN);
                 baseIntent.addCategory(Intent.CATEGORY_LAUNCHER);
-                baseIntent.setComponent(ComponentName.unflattenFromString(arg));
-            } else {
-                // Assume the argument is a package name.
-                baseIntent = new Intent(Intent.ACTION_MAIN);
-                baseIntent.addCategory(Intent.CATEGORY_LAUNCHER);
-                baseIntent.setPackage(arg);
             }
+        } else if (arg.indexOf(':') >= 0) {
+            // The argument is a URI.  Fully parse it, and use that result
+            // to fill in any data not specified so far.
+            baseIntent = Intent.parseUri(arg, Intent.URI_INTENT_SCHEME);
+        } else if (arg.indexOf('/') >= 0) {
+            // The argument is a component name.  Build an Intent to launch
+            // it.
+            baseIntent = new Intent(Intent.ACTION_MAIN);
+            baseIntent.addCategory(Intent.CATEGORY_LAUNCHER);
+            baseIntent.setComponent(ComponentName.unflattenFromString(arg));
+        } else {
+            // Assume the argument is a package name.
+            baseIntent = new Intent(Intent.ACTION_MAIN);
+            baseIntent.addCategory(Intent.CATEGORY_LAUNCHER);
+            baseIntent.setPackage(arg);
+        }
+        if (baseIntent != null) {
             Bundle extras = intent.getExtras();
             intent.replaceExtras((Bundle)null);
             Bundle uriExtras = baseIntent.getExtras();
@@ -315,7 +342,7 @@
                     baseIntent.removeCategory(c);
                 }
             }
-            intent.fillIn(baseIntent, Intent.FILL_IN_COMPONENT);
+            intent.fillIn(baseIntent, Intent.FILL_IN_COMPONENT | Intent.FILL_IN_SELECTOR);
             if (extras == null) {
                 extras = uriExtras;
             } else if (uriExtras != null) {
@@ -1064,6 +1091,11 @@
         }
     }
 
+    private void runToUri(boolean intentScheme) throws Exception {
+        Intent intent = makeIntent();
+        System.out.println(intent.toUri(intentScheme ? Intent.URI_INTENT_SCHEME : 0));
+    }
+
     private class IntentReceiver extends IIntentReceiver.Stub {
         private boolean mFinished = false;
 
@@ -1233,6 +1265,8 @@
                 "       am monitor [--gdb <port>]\n" +
                 "       am screen-compat [on|off] <PACKAGE>\n" +
                 "       am display-size [reset|MxN]\n" +
+                "       am to-uri [INTENT]\n" +
+                "       am to-intent-uri [INTENT]\n" +
                 "\n" +
                 "am start: start an Activity.  Options are:\n" +
                 "    -D: enable debugging\n" +
@@ -1284,6 +1318,10 @@
                 "\n" +
                 "am display-size: override display size.\n" +
                 "\n" +
+                "am to-uri: print the given Intent specification as a URI.\n" +
+                "\n" +
+                "am to-intent-uri: print the given Intent specification as an intent: URI.\n" +
+                "\n" +
                 "<INTENT> specifications include these flags and arguments:\n" +
                 "    [-a <ACTION>] [-d <DATA_URI>] [-t <MIME_TYPE>]\n" +
                 "    [-c <CATEGORY> [-c <CATEGORY>] ...]\n" +
@@ -1308,6 +1346,7 @@
                 "    [--activity-single-top] [--activity-clear-task]\n" +
                 "    [--activity-task-on-home]\n" +
                 "    [--receiver-registered-only] [--receiver-replace-pending]\n" +
+                "    [--selector]\n" +
                 "    [<URI> | <PACKAGE> | <COMPONENT>]\n"
                 );
     }
diff --git a/cmds/dumpstate/dumpstate.c b/cmds/dumpstate/dumpstate.c
index 52465a0..d5d65c1 100644
--- a/cmds/dumpstate/dumpstate.c
+++ b/cmds/dumpstate/dumpstate.c
@@ -25,6 +25,8 @@
 #include <sys/time.h>
 #include <sys/wait.h>
 #include <unistd.h>
+#include <linux/capability.h>
+#include <linux/prctl.h>
 
 #include <cutils/properties.h>
 
@@ -121,6 +123,12 @@
 
     dump_file("NETWORK ROUTES", "/proc/net/route");
     dump_file("NETWORK ROUTES IPV6", "/proc/net/ipv6_route");
+    run_command("IP RULES", 10, "ip", "rule", "show", NULL);
+    run_command("IP RULES v6", 10, "ip", "-6", "rule", "show", NULL);
+    run_command("ROUTE TABLE 60", 10, "ip", "route", "show", "table", "60", NULL);
+    run_command("ROUTE TABLE 61 v6", 10, "ip", "-6", "route", "show", "table", "60", NULL);
+    run_command("ROUTE TABLE 61", 10, "ip", "route", "show", "table", "61", NULL);
+    run_command("ROUTE TABLE 61 v6", 10, "ip", "-6", "route", "show", "table", "61", NULL);
     dump_file("ARP CACHE", "/proc/net/arp");
     run_command("IPTABLES", 10, "su", "root", "iptables", "-L", "-nvx", NULL);
     run_command("IP6TABLES", 10, "su", "root", "ip6tables", "-L", "-nvx", NULL);
@@ -163,7 +171,7 @@
 
     print_properties();
 
-    run_command("KERNEL LOG", 20, "dmesg", NULL);
+    do_dmesg();
 
     dump_file("KERNEL WAKELOCKS", "/proc/wakelocks");
     dump_file("KERNEL CPUFREQ", "/sys/devices/system/cpu/cpu0/cpufreq/stats/time_in_state");
@@ -186,6 +194,7 @@
     dump_file("PACKAGE SETTINGS", "/data/system/packages.xml");
     dump_file("PACKAGE UID ERRORS", "/data/system/uiderrors.txt");
 
+    /* TODO: Make last_kmsg CAP_SYSLOG protected. b/5555691 */
     dump_file("LAST KMSG", "/proc/last_kmsg");
     run_command("LAST RADIO LOG", 10, "parse_radio_log", "/proc/last_radio_log", NULL);
     dump_file("LAST PANIC CONSOLE", "/data/dontpanic/apanic_console");
@@ -309,6 +318,11 @@
     }
 
     if (getuid() == 0) {
+        if (prctl(PR_SET_KEEPCAPS, 1) < 0) {
+            LOGE("prctl(PR_SET_KEEPCAPS) failed: %s\n", strerror(errno));
+            return -1;
+        }
+
         /* switch to non-root user and group */
         gid_t groups[] = { AID_LOG, AID_SDCARD_RW, AID_MOUNT, AID_INET };
         if (setgroups(sizeof(groups)/sizeof(groups[0]), groups) != 0) {
@@ -323,6 +337,23 @@
             LOGE("Unable to setuid, aborting: %s\n", strerror(errno));
             return -1;
         }
+
+        struct __user_cap_header_struct capheader;
+        struct __user_cap_data_struct capdata[2];
+        memset(&capheader, 0, sizeof(capheader));
+        memset(&capdata, 0, sizeof(capdata));
+        capheader.version = _LINUX_CAPABILITY_VERSION_3;
+        capheader.pid = 0;
+
+        capdata[CAP_TO_INDEX(CAP_SYSLOG)].permitted = CAP_TO_MASK(CAP_SYSLOG);
+        capdata[CAP_TO_INDEX(CAP_SYSLOG)].effective = CAP_TO_MASK(CAP_SYSLOG);
+        capdata[0].inheritable = 0;
+        capdata[1].inheritable = 0;
+
+        if (capset(&capheader, &capdata[0]) < 0) {
+            LOGE("capset failed: %s\n", strerror(errno));
+            return -1;
+        }
     }
 
     char path[PATH_MAX], tmp_path[PATH_MAX];
diff --git a/cmds/dumpstate/dumpstate.h b/cmds/dumpstate/dumpstate.h
index 6d66b1b..b02db0b 100644
--- a/cmds/dumpstate/dumpstate.h
+++ b/cmds/dumpstate/dumpstate.h
@@ -48,6 +48,9 @@
 /* Runs "showmap" for a process */
 void do_showmap(int pid, const char *name);
 
+/* Gets the dmesg output for the kernel */
+void do_dmesg();
+
 /* Play a sound via Stagefright */
 void play_sound(const char* path);
 
diff --git a/cmds/dumpstate/utils.c b/cmds/dumpstate/utils.c
index 14984ec..21526f9 100644
--- a/cmds/dumpstate/utils.c
+++ b/cmds/dumpstate/utils.c
@@ -28,6 +28,7 @@
 #include <sys/stat.h>
 #include <sys/time.h>
 #include <sys/wait.h>
+#include <sys/klog.h>
 #include <time.h>
 #include <unistd.h>
 
@@ -96,6 +97,30 @@
     return;
 }
 
+void do_dmesg() {
+    printf("------ KERNEL LOG (dmesg) ------\n");
+    int size = klogctl(10, NULL, 0); /* Get size of kernel buffer */
+    if (size <= 0) {
+        printf("Unexpected klogctl return value: %d\n\n", size);
+        return;
+    }
+    char *buf = (char *) malloc(size + 1);
+    if (buf == NULL) {
+        printf("memory allocation failed\n\n");
+        return;
+    }
+    int retval = klogctl(KLOG_READ_ALL, buf, size);
+    if (retval < 0) {
+        printf("klogctl failure\n\n");
+        free(buf);
+        return;
+    }
+    buf[retval] = '\0';
+    printf("%s\n\n", buf);
+    free(buf);
+    return;
+}
+
 void do_showmap(int pid, const char *name) {
     char title[255];
     char arg[255];
diff --git a/cmds/input/src/com/android/commands/input/Input.java b/cmds/input/src/com/android/commands/input/Input.java
index df1d0bf..c4c3b8a 100755
--- a/cmds/input/src/com/android/commands/input/Input.java
+++ b/cmds/input/src/com/android/commands/input/Input.java
@@ -23,6 +23,7 @@
 import android.view.IWindowManager;
 import android.view.KeyCharacterMap;
 import android.view.KeyEvent;
+import android.view.MotionEvent;
 
 /**
  * Command that sends key events to the device, either by their keycode, or by
@@ -30,6 +31,9 @@
  */
 
 public class Input {
+    private static final String TAG = "Input";
+
+    private IWindowManager mWindowManager;
 
     /**
      * Command-line entry point.
@@ -40,6 +44,13 @@
         (new Input()).run(args);
     }
 
+    private IWindowManager getWindowManager() {
+        if (mWindowManager == null) {
+            mWindowManager = (IWindowManager.Stub.asInterface(ServiceManager.getService("window")));
+        }
+        return mWindowManager;
+    }
+
     private void run(String[] args) {
         if (args.length < 1) {
             showUsage();
@@ -48,19 +59,37 @@
 
         String command = args[0];
 
-        if (command.equals("text")) {
-            sendText(args[1]);
-        } else if (command.equals("keyevent")) {
-            sendKeyEvent(args[1]);
-        } else if (command.equals("motionevent")) {
-            System.err.println("Error: motionevent not yet supported.");
-            return;
+        try {
+            if (command.equals("text")) {
+                if (args.length == 2) {
+                    sendText(args[1]);
+                    return;
+                }
+            } else if (command.equals("keyevent")) {
+                if (args.length == 2) {
+                    sendKeyEvent(Integer.parseInt(args[1]));
+                    return;
+                }
+            } else if (command.equals("tap")) {
+                if (args.length == 3) {
+                    sendTap(Float.parseFloat(args[1]), Float.parseFloat(args[2]));
+                    return;
+                }
+            } else if (command.equals("swipe")) {
+                if (args.length == 5) {
+                    sendSwipe(Float.parseFloat(args[1]), Float.parseFloat(args[2]),
+                            Float.parseFloat(args[3]), Float.parseFloat(args[4]));
+                    return;
+                }
+            } else {
+                System.err.println("Error: Unknown command: " + command);
+                showUsage();
+                return;
+            }
+        } catch (NumberFormatException ex) {
         }
-        else {
-            System.err.println("Error: Unknown command: " + command);
-            showUsage();
-            return;
-        }
+        System.err.println("Error: Invalid arguments for command: " + command);
+        showUsage();
     }
 
     /**
@@ -69,7 +98,6 @@
      *
      * @param text is a string of characters you want to input to the device.
      */
-
     private void sendText(String text) {
 
         StringBuffer buff = new StringBuffer(text);
@@ -90,55 +118,66 @@
 
         char[] chars = buff.toString().toCharArray();
 
-        KeyCharacterMap mKeyCharacterMap = KeyCharacterMap.
-            load(KeyCharacterMap.VIRTUAL_KEYBOARD);
-
-        KeyEvent[] events = mKeyCharacterMap.getEvents(chars);
-
+        KeyCharacterMap kcm = KeyCharacterMap.load(KeyCharacterMap.VIRTUAL_KEYBOARD);
+        KeyEvent[] events = kcm.getEvents(chars);
         for(int i = 0; i < events.length; i++) {
-            KeyEvent event = events[i];
-            Log.i("SendKeyEvent", Integer.toString(event.getKeyCode()));
-            try {
-                (IWindowManager.Stub
-                    .asInterface(ServiceManager.getService("window")))
-                    .injectKeyEvent(event, true);
-            } catch (RemoteException e) {
-                Log.i("Input", "DeadOjbectException");
-            }
+            injectKeyEvent(events[i]);
         }
     }
 
-    /**
-     * Send a single key event.
-     *
-     * @param event is a string representing the keycode of the key event you
-     * want to execute.
-     */
-    private void sendKeyEvent(String event) {
-        int eventCode = Integer.parseInt(event);
+    private void sendKeyEvent(int keyCode) {
         long now = SystemClock.uptimeMillis();
-        Log.i("SendKeyEvent", event);
+        injectKeyEvent(new KeyEvent(now, now, KeyEvent.ACTION_DOWN, keyCode, 0));
+        injectKeyEvent(new KeyEvent(now, now, KeyEvent.ACTION_UP, keyCode, 0));
+    }
+
+    private void sendTap(float x, float y) {
+        long now = SystemClock.uptimeMillis();
+        injectPointerEvent(MotionEvent.obtain(now, now, MotionEvent.ACTION_DOWN, x, y, 0));
+        injectPointerEvent(MotionEvent.obtain(now, now, MotionEvent.ACTION_UP, x, y, 0));
+    }
+
+    private void sendSwipe(float x1, float y1, float x2, float y2) {
+        final int NUM_STEPS = 11;
+        long now = SystemClock.uptimeMillis();
+        injectPointerEvent(MotionEvent.obtain(now, now, MotionEvent.ACTION_DOWN, x1, y1, 0));
+        for (int i = 1; i < NUM_STEPS; i++) {
+            float alpha = (float)i / NUM_STEPS;
+            injectPointerEvent(MotionEvent.obtain(now, now, MotionEvent.ACTION_MOVE,
+                    lerp(x1, x2, alpha), lerp(y1, y2, alpha), 0));
+        }
+        injectPointerEvent(MotionEvent.obtain(now, now, MotionEvent.ACTION_UP, x2, y2, 0));
+    }
+
+    private void injectKeyEvent(KeyEvent event) {
         try {
-            KeyEvent down = new KeyEvent(now, now, KeyEvent.ACTION_DOWN, eventCode, 0);
-            KeyEvent up = new KeyEvent(now, now, KeyEvent.ACTION_UP, eventCode, 0);
-            (IWindowManager.Stub
-                .asInterface(ServiceManager.getService("window")))
-                .injectKeyEvent(down, true);
-            (IWindowManager.Stub
-                .asInterface(ServiceManager.getService("window")))
-                .injectKeyEvent(up, true);
-        } catch (RemoteException e) {
-            Log.i("Input", "DeadOjbectException");
+            Log.i(TAG, "InjectKeyEvent: " + event);
+            getWindowManager().injectKeyEvent(event, true);
+        } catch (RemoteException ex) {
+            Log.i(TAG, "RemoteException", ex);
         }
     }
 
-    private void sendMotionEvent(long downTime, int action, float x, float y, 
-            float pressure, float size) {
+    private void injectPointerEvent(MotionEvent event) {
+        try {
+            Log.i("Input", "InjectPointerEvent: " + event);
+            getWindowManager().injectPointerEvent(event, true);
+        } catch (RemoteException ex) {
+            Log.i(TAG, "RemoteException", ex);
+        } finally {
+            event.recycle();
+        }
+    }
+
+    private static final float lerp(float a, float b, float alpha) {
+        return (b - a) * alpha + a;
     }
 
     private void showUsage() {
         System.err.println("usage: input [text|keyevent]");
         System.err.println("       input text <string>");
-        System.err.println("       input keyevent <event_code>");
+        System.err.println("       input keyevent <key code>");
+        System.err.println("       input tap <x> <y>");
+        System.err.println("       input swipe <x1> <y1> <x2> <y2>");
     }
 }
diff --git a/cmds/installd/commands.c b/cmds/installd/commands.c
index 34c0c2a..db72585 100644
--- a/cmds/installd/commands.c
+++ b/cmds/installd/commands.c
@@ -184,6 +184,7 @@
     DIR *d;
     struct dirent *de;
     int64_t avail;
+    char datadir[PKG_PATH_MAX];
 
     avail = disk_free();
     if (avail < 0) return -1;
@@ -191,9 +192,14 @@
     LOGI("free_cache(%" PRId64 ") avail %" PRId64 "\n", free_size, avail);
     if (avail >= free_size) return 0;
 
-    d = opendir(android_data_dir.path);
+    if (create_persona_path(datadir, 0)) {
+        LOGE("couldn't get directory for persona 0");
+        return -1;
+    }
+
+    d = opendir(datadir);
     if (d == NULL) {
-        LOGE("cannot open %s: %s\n", android_data_dir.path, strerror(errno));
+        LOGE("cannot open %s: %s\n", datadir, strerror(errno));
         return -1;
     }
     dfd = dirfd(d);
@@ -578,19 +584,6 @@
     return -1;
 }
 
-int create_move_path(char path[PKG_PATH_MAX],
-    const char* pkgname,
-    const char* leaf,
-    uid_t persona)
-{
-    if ((android_data_dir.len + strlen(pkgname) + strlen(leaf) + 1) >= PKG_PATH_MAX) {
-        return -1;
-    }
-    
-    sprintf(path, "%s%s%s/%s", android_data_dir.path, PRIMARY_USER_PREFIX, pkgname, leaf);
-    return 0;
-}
-
 void mkinnerdirs(char* path, int basepos, mode_t mode, int uid, int gid,
         struct stat* statbuf)
 {
diff --git a/cmds/installd/installd.h b/cmds/installd/installd.h
index c5872b8..173cabf 100644
--- a/cmds/installd/installd.h
+++ b/cmds/installd/installd.h
@@ -105,6 +105,11 @@
 int create_persona_path(char path[PKG_PATH_MAX],
                     uid_t persona);
 
+int create_move_path(char path[PKG_PATH_MAX],
+                     const char* pkgname,
+                     const char* leaf,
+                     uid_t persona);
+
 int is_valid_package_name(const char* pkgname);
 
 int create_cache_path(char path[PKG_PATH_MAX], const char *src);
diff --git a/cmds/installd/tests/installd_utils_test.cpp b/cmds/installd/tests/installd_utils_test.cpp
index 1128fce..7cb9b37 100644
--- a/cmds/installd/tests/installd_utils_test.cpp
+++ b/cmds/installd/tests/installd_utils_test.cpp
@@ -34,6 +34,16 @@
 #define TEST_SYSTEM_DIR1 "/system/app/"
 #define TEST_SYSTEM_DIR2 "/vendor/app/"
 
+#define REALLY_LONG_APP_NAME "com.example." \
+        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa." \
+        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa." \
+        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+
+#define REALLY_LONG_LEAF_NAME "shared_prefs_shared_prefs_shared_prefs_shared_prefs_shared_prefs_" \
+        "shared_prefs_shared_prefs_shared_prefs_shared_prefs_shared_prefs_shared_prefs_" \
+        "shared_prefs_shared_prefs_shared_prefs_shared_prefs_shared_prefs_shared_prefs_" \
+        "shared_prefs_shared_prefs_shared_prefs_shared_prefs_shared_prefs_shared_prefs_"
+
 namespace android {
 
 class UtilsTest : public testing::Test {
@@ -210,7 +220,7 @@
 
 TEST_F(UtilsTest, GetPathFromString_NullPathFail) {
     dir_rec_t test1;
-    EXPECT_EQ(-1, get_path_from_string(&test1, NULL))
+    EXPECT_EQ(-1, get_path_from_string(&test1, (const char *) NULL))
             << "Should not allow NULL as a path.";
 }
 
@@ -327,6 +337,50 @@
             << "Package path should be in /data/app-private/";
 }
 
+TEST_F(UtilsTest, CreatePersonaPath_Primary) {
+    char path[PKG_PATH_MAX];
+
+    EXPECT_EQ(0, create_persona_path(path, 0))
+            << "Should successfully build primary user path.";
+
+    EXPECT_STREQ("/data/data/", path)
+            << "Primary user should have correct path";
+}
+
+TEST_F(UtilsTest, CreatePersonaPath_Secondary) {
+    char path[PKG_PATH_MAX];
+
+    EXPECT_EQ(0, create_persona_path(path, 1))
+            << "Should successfully build primary user path.";
+
+    EXPECT_STREQ("/data/user/1/", path)
+            << "Primary user should have correct path";
+}
+
+TEST_F(UtilsTest, CreateMovePath_Primary) {
+    char path[PKG_PATH_MAX];
+
+    EXPECT_EQ(0, create_move_path(path, "com.android.test", "shared_prefs", 0))
+            << "Should be able to create move path for primary user";
+
+    EXPECT_STREQ("/data/data/com.android.test/shared_prefs", path)
+            << "Primary user package directory should be created correctly";
+}
+
+TEST_F(UtilsTest, CreateMovePath_Fail_AppTooLong) {
+    char path[PKG_PATH_MAX];
+
+    EXPECT_EQ(-1, create_move_path(path, REALLY_LONG_APP_NAME, "shared_prefs", 0))
+            << "Should fail to create move path for primary user";
+}
+
+TEST_F(UtilsTest, CreateMovePath_Fail_LeafTooLong) {
+    char path[PKG_PATH_MAX];
+
+    EXPECT_EQ(-1, create_move_path(path, "com.android.test", REALLY_LONG_LEAF_NAME, 0))
+            << "Should fail to create move path for primary user";
+}
+
 TEST_F(UtilsTest, CopyAndAppend_Normal) {
     //int copy_and_append(dir_rec_t* dst, dir_rec_t* src, char* suffix)
     dir_rec_t dst;
diff --git a/cmds/installd/utils.c b/cmds/installd/utils.c
index 3099b83..a53a93c 100644
--- a/cmds/installd/utils.c
+++ b/cmds/installd/utils.c
@@ -109,7 +109,7 @@
         uid_len = 0;
     } else {
         persona_prefix = SECONDARY_USER_PREFIX;
-        uid_len = snprintf(NULL, 0, "%d", persona);
+        uid_len = snprintf(NULL, 0, "%d/", persona);
     }
 
     char *dst = path;
@@ -126,7 +126,7 @@
             LOGE("Error building user path");
             return -1;
         }
-        int ret = snprintf(dst, dst_size, "%d", persona);
+        int ret = snprintf(dst, dst_size, "%d/", persona);
         if (ret < 0 || (size_t) ret != uid_len) {
             LOGE("Error appending persona id to path");
             return -1;
@@ -135,6 +135,20 @@
     return 0;
 }
 
+int create_move_path(char path[PKG_PATH_MAX],
+    const char* pkgname,
+    const char* leaf,
+    uid_t persona)
+{
+    if ((android_data_dir.len + strlen(PRIMARY_USER_PREFIX) + strlen(pkgname) + strlen(leaf) + 1)
+            >= PKG_PATH_MAX) {
+        return -1;
+    }
+
+    sprintf(path, "%s%s%s/%s", android_data_dir.path, PRIMARY_USER_PREFIX, pkgname, leaf);
+    return 0;
+}
+
 /**
  * Checks whether the package name is valid. Returns -1 on error and
  * 0 on success.
diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java
index 64a2755..211be52 100644
--- a/core/java/android/accessibilityservice/AccessibilityService.java
+++ b/core/java/android/accessibilityservice/AccessibilityService.java
@@ -16,8 +16,6 @@
 
 package android.accessibilityservice;
 
-import com.android.internal.os.HandlerCaller;
-
 import android.app.Service;
 import android.content.Intent;
 import android.os.IBinder;
@@ -25,8 +23,11 @@
 import android.os.RemoteException;
 import android.util.Log;
 import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityInteractionClient;
 import android.view.accessibility.AccessibilityNodeInfo;
 
+import com.android.internal.os.HandlerCaller;
+
 /**
  * An accessibility service runs in the background and receives callbacks by the system
  * when {@link AccessibilityEvent}s are fired. Such events denote some state transition
@@ -219,7 +220,7 @@
 
     private AccessibilityServiceInfo mInfo;
 
-    IAccessibilityServiceConnection mConnection;
+    private int mConnectionId;
 
     /**
      * Callback for {@link android.view.accessibility.AccessibilityEvent}s.
@@ -264,9 +265,11 @@
      * AccessibilityManagerService.
      */
     private void sendServiceInfo() {
-        if (mInfo != null && mConnection != null) {
+        IAccessibilityServiceConnection connection =
+            AccessibilityInteractionClient.getInstance().getConnection(mConnectionId);
+        if (mInfo != null && connection != null) {
             try {
-                mConnection.setServiceInfo(mInfo);
+                connection.setServiceInfo(mInfo);
             } catch (RemoteException re) {
                 Log.w(LOG_TAG, "Error while setting AccessibilityServiceInfo", re);
             }
@@ -302,8 +305,9 @@
             mCaller = new HandlerCaller(context, this);
         }
 
-        public void setConnection(IAccessibilityServiceConnection connection) {
-            Message message = mCaller.obtainMessageO(DO_SET_SET_CONNECTION, connection);
+        public void setConnection(IAccessibilityServiceConnection connection, int connectionId) {
+            Message message = mCaller.obtainMessageIO(DO_SET_SET_CONNECTION, connectionId,
+                    connection);
             mCaller.sendMessage(message);
         }
 
@@ -330,8 +334,19 @@
                     mTarget.onInterrupt();
                     return;
                 case DO_SET_SET_CONNECTION :
-                    mConnection = ((IAccessibilityServiceConnection) message.obj);
-                    mTarget.onServiceConnected();
+                    final int connectionId = message.arg1;
+                    IAccessibilityServiceConnection connection =
+                        (IAccessibilityServiceConnection) message.obj;
+                    if (connection != null) {
+                        AccessibilityInteractionClient.getInstance().addConnection(connectionId,
+                                connection);
+                        mConnectionId = connectionId;
+                        mTarget.onServiceConnected();
+                    } else {
+                        AccessibilityInteractionClient.getInstance().removeConnection(connectionId);
+                        mConnectionId = AccessibilityInteractionClient.NO_ID;
+                        // TODO: Do we need a onServiceDisconnected callback?
+                    }
                     return;
                 default :
                     Log.w(LOG_TAG, "Unknown message type " + message.what);
diff --git a/core/java/android/accessibilityservice/IEventListener.aidl b/core/java/android/accessibilityservice/IEventListener.aidl
index 5b849f1..5536b3c 100644
--- a/core/java/android/accessibilityservice/IEventListener.aidl
+++ b/core/java/android/accessibilityservice/IEventListener.aidl
@@ -26,7 +26,7 @@
  */
  oneway interface IEventListener {
 
-    void setConnection(in IAccessibilityServiceConnection connection);
+    void setConnection(in IAccessibilityServiceConnection connection, int connectionId);
 
     void onAccessibilityEvent(in AccessibilityEvent event);
 
diff --git a/core/java/android/animation/ValueAnimator.java b/core/java/android/animation/ValueAnimator.java
index edd0fa3..9bf1634 100755
--- a/core/java/android/animation/ValueAnimator.java
+++ b/core/java/android/animation/ValueAnimator.java
@@ -20,6 +20,7 @@
 import android.os.Looper;
 import android.os.Message;
 import android.util.AndroidRuntimeException;
+import android.view.Choreographer;
 import android.view.animation.AccelerateDecelerateInterpolator;
 import android.view.animation.AnimationUtils;
 import android.view.animation.LinearInterpolator;
@@ -45,17 +46,10 @@
      * Internal constants
      */
 
-    /*
-     * The default amount of time in ms between animation frames
-     */
-    private static final long DEFAULT_FRAME_DELAY = 10;
-
     /**
-     * Messages sent to timing handler: START is sent when an animation first begins, FRAME is sent
-     * by the handler to itself to process the next animation frame
+     * Messages sent to timing handler: START is sent when an animation first begins.
      */
     static final int ANIMATION_START = 0;
-    static final int ANIMATION_FRAME = 1;
 
     /**
      * Values used with internal variable mPlayingState to indicate the current state of an
@@ -83,70 +77,15 @@
      */
     long mSeekTime = -1;
 
-    // TODO: We access the following ThreadLocal variables often, some of them on every update.
-    // If ThreadLocal access is significantly expensive, we may want to put all of these
-    // fields into a structure sot hat we just access ThreadLocal once to get the reference
-    // to that structure, then access the structure directly for each field.
-
     // The static sAnimationHandler processes the internal timing loop on which all animations
     // are based
     private static ThreadLocal<AnimationHandler> sAnimationHandler =
             new ThreadLocal<AnimationHandler>();
 
-    // The per-thread list of all active animations
-    private static final ThreadLocal<ArrayList<ValueAnimator>> sAnimations =
-            new ThreadLocal<ArrayList<ValueAnimator>>() {
-                @Override
-                protected ArrayList<ValueAnimator> initialValue() {
-                    return new ArrayList<ValueAnimator>();
-                }
-            };
-
-    // The per-thread set of animations to be started on the next animation frame
-    private static final ThreadLocal<ArrayList<ValueAnimator>> sPendingAnimations =
-            new ThreadLocal<ArrayList<ValueAnimator>>() {
-                @Override
-                protected ArrayList<ValueAnimator> initialValue() {
-                    return new ArrayList<ValueAnimator>();
-                }
-            };
-
-    /**
-     * Internal per-thread collections used to avoid set collisions as animations start and end
-     * while being processed.
-     */
-    private static final ThreadLocal<ArrayList<ValueAnimator>> sDelayedAnims =
-            new ThreadLocal<ArrayList<ValueAnimator>>() {
-                @Override
-                protected ArrayList<ValueAnimator> initialValue() {
-                    return new ArrayList<ValueAnimator>();
-                }
-            };
-
-    private static final ThreadLocal<ArrayList<ValueAnimator>> sEndingAnims =
-            new ThreadLocal<ArrayList<ValueAnimator>>() {
-                @Override
-                protected ArrayList<ValueAnimator> initialValue() {
-                    return new ArrayList<ValueAnimator>();
-                }
-            };
-
-    private static final ThreadLocal<ArrayList<ValueAnimator>> sReadyAnims =
-            new ThreadLocal<ArrayList<ValueAnimator>>() {
-                @Override
-                protected ArrayList<ValueAnimator> initialValue() {
-                    return new ArrayList<ValueAnimator>();
-                }
-            };
-
     // The time interpolator to be used if none is set on the animation
     private static final TimeInterpolator sDefaultInterpolator =
             new AccelerateDecelerateInterpolator();
 
-    // type evaluators for the primitive types handled by this implementation
-    private static final TypeEvaluator sIntEvaluator = new IntEvaluator();
-    private static final TypeEvaluator sFloatEvaluator = new FloatEvaluator();
-
     /**
      * Used to indicate whether the animation is currently playing in reverse. This causes the
      * elapsed fraction to be inverted to calculate the appropriate values.
@@ -217,9 +156,6 @@
     // The amount of time in ms to delay starting the animation after start() is called
     private long mStartDelay = 0;
 
-    // The number of milliseconds between animation frames
-    private static long sFrameDelay = DEFAULT_FRAME_DELAY;
-
     // The number of times the animation will repeat. The default is 0, which means the animation
     // will play only once
     private int mRepeatCount = 0;
@@ -566,119 +502,146 @@
      * animations possible.
      *
      */
-    private static class AnimationHandler extends Handler {
+    private static class AnimationHandler extends Handler
+            implements Choreographer.OnAnimateListener {
+        // The per-thread list of all active animations
+        private final ArrayList<ValueAnimator> mAnimations = new ArrayList<ValueAnimator>();
+
+        // The per-thread set of animations to be started on the next animation frame
+        private final ArrayList<ValueAnimator> mPendingAnimations = new ArrayList<ValueAnimator>();
+
         /**
-         * There are only two messages that we care about: ANIMATION_START and
-         * ANIMATION_FRAME. The START message is sent when an animation's start()
-         * method is called. It cannot start synchronously when start() is called
+         * Internal per-thread collections used to avoid set collisions as animations start and end
+         * while being processed.
+         */
+        private final ArrayList<ValueAnimator> mDelayedAnims = new ArrayList<ValueAnimator>();
+        private final ArrayList<ValueAnimator> mEndingAnims = new ArrayList<ValueAnimator>();
+        private final ArrayList<ValueAnimator> mReadyAnims = new ArrayList<ValueAnimator>();
+
+        private final Choreographer mChoreographer;
+        private boolean mIsChoreographed;
+
+        private AnimationHandler() {
+            mChoreographer = Choreographer.getInstance();
+        }
+
+        /**
+         * The START message is sent when an animation's start()  method is called.
+         * It cannot start synchronously when start() is called
          * because the call may be on the wrong thread, and it would also not be
          * synchronized with other animations because it would not start on a common
          * timing pulse. So each animation sends a START message to the handler, which
          * causes the handler to place the animation on the active animations queue and
          * start processing frames for that animation.
-         * The FRAME message is the one that is sent over and over while there are any
-         * active animations to process.
          */
         @Override
         public void handleMessage(Message msg) {
-            boolean callAgain = true;
-            ArrayList<ValueAnimator> animations = sAnimations.get();
-            ArrayList<ValueAnimator> delayedAnims = sDelayedAnims.get();
             switch (msg.what) {
-                // TODO: should we avoid sending frame message when starting if we
-                // were already running?
                 case ANIMATION_START:
-                    ArrayList<ValueAnimator> pendingAnimations = sPendingAnimations.get();
-                    if (animations.size() > 0 || delayedAnims.size() > 0) {
-                        callAgain = false;
-                    }
-                    // pendingAnims holds any animations that have requested to be started
-                    // We're going to clear sPendingAnimations, but starting animation may
-                    // cause more to be added to the pending list (for example, if one animation
-                    // starting triggers another starting). So we loop until sPendingAnimations
-                    // is empty.
-                    while (pendingAnimations.size() > 0) {
-                        ArrayList<ValueAnimator> pendingCopy =
-                                (ArrayList<ValueAnimator>) pendingAnimations.clone();
-                        pendingAnimations.clear();
-                        int count = pendingCopy.size();
-                        for (int i = 0; i < count; ++i) {
-                            ValueAnimator anim = pendingCopy.get(i);
-                            // If the animation has a startDelay, place it on the delayed list
-                            if (anim.mStartDelay == 0) {
-                                anim.startAnimation();
-                            } else {
-                                delayedAnims.add(anim);
-                            }
-                        }
-                    }
-                    // fall through to process first frame of new animations
-                case ANIMATION_FRAME:
-                    // currentTime holds the common time for all animations processed
-                    // during this frame
-                    long currentTime = AnimationUtils.currentAnimationTimeMillis();
-                    ArrayList<ValueAnimator> readyAnims = sReadyAnims.get();
-                    ArrayList<ValueAnimator> endingAnims = sEndingAnims.get();
-
-                    // First, process animations currently sitting on the delayed queue, adding
-                    // them to the active animations if they are ready
-                    int numDelayedAnims = delayedAnims.size();
-                    for (int i = 0; i < numDelayedAnims; ++i) {
-                        ValueAnimator anim = delayedAnims.get(i);
-                        if (anim.delayedAnimationFrame(currentTime)) {
-                            readyAnims.add(anim);
-                        }
-                    }
-                    int numReadyAnims = readyAnims.size();
-                    if (numReadyAnims > 0) {
-                        for (int i = 0; i < numReadyAnims; ++i) {
-                            ValueAnimator anim = readyAnims.get(i);
-                            anim.startAnimation();
-                            anim.mRunning = true;
-                            delayedAnims.remove(anim);
-                        }
-                        readyAnims.clear();
-                    }
-
-                    // Now process all active animations. The return value from animationFrame()
-                    // tells the handler whether it should now be ended
-                    int numAnims = animations.size();
-                    int i = 0;
-                    while (i < numAnims) {
-                        ValueAnimator anim = animations.get(i);
-                        if (anim.animationFrame(currentTime)) {
-                            endingAnims.add(anim);
-                        }
-                        if (animations.size() == numAnims) {
-                            ++i;
-                        } else {
-                            // An animation might be canceled or ended by client code
-                            // during the animation frame. Check to see if this happened by
-                            // seeing whether the current index is the same as it was before
-                            // calling animationFrame(). Another approach would be to copy
-                            // animations to a temporary list and process that list instead,
-                            // but that entails garbage and processing overhead that would
-                            // be nice to avoid.
-                            --numAnims;
-                            endingAnims.remove(anim);
-                        }
-                    }
-                    if (endingAnims.size() > 0) {
-                        for (i = 0; i < endingAnims.size(); ++i) {
-                            endingAnims.get(i).endAnimation();
-                        }
-                        endingAnims.clear();
-                    }
-
-                    // If there are still active or delayed animations, call the handler again
-                    // after the frameDelay
-                    if (callAgain && (!animations.isEmpty() || !delayedAnims.isEmpty())) {
-                        sendEmptyMessageDelayed(ANIMATION_FRAME, Math.max(0, sFrameDelay -
-                            (AnimationUtils.currentAnimationTimeMillis() - currentTime)));
-                    }
+                    doAnimationStart();
                     break;
             }
         }
+
+        private void doAnimationStart() {
+            // mPendingAnimations holds any animations that have requested to be started
+            // We're going to clear mPendingAnimations, but starting animation may
+            // cause more to be added to the pending list (for example, if one animation
+            // starting triggers another starting). So we loop until mPendingAnimations
+            // is empty.
+            while (mPendingAnimations.size() > 0) {
+                ArrayList<ValueAnimator> pendingCopy =
+                        (ArrayList<ValueAnimator>) mPendingAnimations.clone();
+                mPendingAnimations.clear();
+                int count = pendingCopy.size();
+                for (int i = 0; i < count; ++i) {
+                    ValueAnimator anim = pendingCopy.get(i);
+                    // If the animation has a startDelay, place it on the delayed list
+                    if (anim.mStartDelay == 0) {
+                        anim.startAnimation(this);
+                    } else {
+                        mDelayedAnims.add(anim);
+                    }
+                }
+            }
+            doAnimationFrame();
+        }
+
+        private void doAnimationFrame() {
+            // currentTime holds the common time for all animations processed
+            // during this frame
+            long currentTime = AnimationUtils.currentAnimationTimeMillis();
+
+            // First, process animations currently sitting on the delayed queue, adding
+            // them to the active animations if they are ready
+            int numDelayedAnims = mDelayedAnims.size();
+            for (int i = 0; i < numDelayedAnims; ++i) {
+                ValueAnimator anim = mDelayedAnims.get(i);
+                if (anim.delayedAnimationFrame(currentTime)) {
+                    mReadyAnims.add(anim);
+                }
+            }
+            int numReadyAnims = mReadyAnims.size();
+            if (numReadyAnims > 0) {
+                for (int i = 0; i < numReadyAnims; ++i) {
+                    ValueAnimator anim = mReadyAnims.get(i);
+                    anim.startAnimation(this);
+                    anim.mRunning = true;
+                    mDelayedAnims.remove(anim);
+                }
+                mReadyAnims.clear();
+            }
+
+            // Now process all active animations. The return value from animationFrame()
+            // tells the handler whether it should now be ended
+            int numAnims = mAnimations.size();
+            int i = 0;
+            while (i < numAnims) {
+                ValueAnimator anim = mAnimations.get(i);
+                if (anim.animationFrame(currentTime)) {
+                    mEndingAnims.add(anim);
+                }
+                if (mAnimations.size() == numAnims) {
+                    ++i;
+                } else {
+                    // An animation might be canceled or ended by client code
+                    // during the animation frame. Check to see if this happened by
+                    // seeing whether the current index is the same as it was before
+                    // calling animationFrame(). Another approach would be to copy
+                    // animations to a temporary list and process that list instead,
+                    // but that entails garbage and processing overhead that would
+                    // be nice to avoid.
+                    --numAnims;
+                    mEndingAnims.remove(anim);
+                }
+            }
+            if (mEndingAnims.size() > 0) {
+                for (i = 0; i < mEndingAnims.size(); ++i) {
+                    mEndingAnims.get(i).endAnimation(this);
+                }
+                mEndingAnims.clear();
+            }
+
+            // If there are still active or delayed animations, schedule a future call to
+            // onAnimate to process the next frame of the animations.
+            if (!mAnimations.isEmpty() || !mDelayedAnims.isEmpty()) {
+                if (!mIsChoreographed) {
+                    mIsChoreographed = true;
+                    mChoreographer.addOnAnimateListener(this);
+                }
+                mChoreographer.scheduleAnimation();
+            } else {
+                if (mIsChoreographed) {
+                    mIsChoreographed = false;
+                    mChoreographer.removeOnAnimateListener(this);
+                }
+            }
+        }
+
+        @Override
+        public void onAnimate() {
+            doAnimationFrame();
+        }
     }
 
     /**
@@ -708,10 +671,13 @@
      * function because the same delay will be applied to all animations, since they are all
      * run off of a single timing loop.
      *
+     * The frame delay may be ignored when the animation system uses an external timing
+     * source, such as the display refresh rate (vsync), to govern animations.
+     *
      * @return the requested time between frames, in milliseconds
      */
     public static long getFrameDelay() {
-        return sFrameDelay;
+        return Choreographer.getFrameDelay();
     }
 
     /**
@@ -721,10 +687,13 @@
      * function because the same delay will be applied to all animations, since they are all
      * run off of a single timing loop.
      *
+     * The frame delay may be ignored when the animation system uses an external timing
+     * source, such as the display refresh rate (vsync), to govern animations.
+     *
      * @param frameDelay the requested time between frames, in milliseconds
      */
     public static void setFrameDelay(long frameDelay) {
-        sFrameDelay = frameDelay;
+        Choreographer.setFrameDelay(frameDelay);
     }
 
     /**
@@ -921,7 +890,8 @@
         mPlayingState = STOPPED;
         mStarted = true;
         mStartedDelay = false;
-        sPendingAnimations.get().add(this);
+        AnimationHandler animationHandler = getOrCreateAnimationHandler();
+        animationHandler.mPendingAnimations.add(this);
         if (mStartDelay == 0) {
             // This sets the initial value of the animation, prior to actually starting it running
             setCurrentPlayTime(getCurrentPlayTime());
@@ -937,11 +907,6 @@
                 }
             }
         }
-        AnimationHandler animationHandler = sAnimationHandler.get();
-        if (animationHandler == null) {
-            animationHandler = new AnimationHandler();
-            sAnimationHandler.set(animationHandler);
-        }
         animationHandler.sendEmptyMessage(ANIMATION_START);
     }
 
@@ -954,8 +919,10 @@
     public void cancel() {
         // Only cancel if the animation is actually running or has been started and is about
         // to run
-        if (mPlayingState != STOPPED || sPendingAnimations.get().contains(this) ||
-                sDelayedAnims.get().contains(this)) {
+        AnimationHandler handler = getOrCreateAnimationHandler();
+        if (mPlayingState != STOPPED
+                || handler.mPendingAnimations.contains(this)
+                || handler.mDelayedAnims.contains(this)) {
             // Only notify listeners if the animator has actually started
             if (mRunning && mListeners != null) {
                 ArrayList<AnimatorListener> tmpListeners =
@@ -964,16 +931,17 @@
                     listener.onAnimationCancel(this);
                 }
             }
-            endAnimation();
+            endAnimation(handler);
         }
     }
 
     @Override
     public void end() {
-        if (!sAnimations.get().contains(this) && !sPendingAnimations.get().contains(this)) {
+        AnimationHandler handler = getOrCreateAnimationHandler();
+        if (!handler.mAnimations.contains(this) && !handler.mPendingAnimations.contains(this)) {
             // Special case if the animation has not yet started; get it ready for ending
             mStartedDelay = false;
-            startAnimation();
+            startAnimation(handler);
         } else if (!mInitialized) {
             initAnimation();
         }
@@ -984,7 +952,7 @@
         } else {
             animateValue(1f);
         }
-        endAnimation();
+        endAnimation(handler);
     }
 
     @Override
@@ -1020,10 +988,10 @@
      * Called internally to end an animation by removing it from the animations list. Must be
      * called on the UI thread.
      */
-    private void endAnimation() {
-        sAnimations.get().remove(this);
-        sPendingAnimations.get().remove(this);
-        sDelayedAnims.get().remove(this);
+    private void endAnimation(AnimationHandler handler) {
+        handler.mAnimations.remove(this);
+        handler.mPendingAnimations.remove(this);
+        handler.mDelayedAnims.remove(this);
         mPlayingState = STOPPED;
         if (mRunning && mListeners != null) {
             ArrayList<AnimatorListener> tmpListeners =
@@ -1041,9 +1009,9 @@
      * Called internally to start an animation by adding it to the active animations list. Must be
      * called on the UI thread.
      */
-    private void startAnimation() {
+    private void startAnimation(AnimationHandler handler) {
         initAnimation();
-        sAnimations.get().add(this);
+        handler.mAnimations.add(this);
         if (mStartDelay > 0 && mListeners != null) {
             // Listeners were already notified in start() if startDelay is 0; this is
             // just for delayed animations
@@ -1229,13 +1197,14 @@
     /**
      * Return the number of animations currently running.
      *
-     * Used by StrictMode internally to annotate violations.  Only
-     * called on the main thread.
+     * Used by StrictMode internally to annotate violations.
+     * May be called on arbitrary threads!
      *
      * @hide
      */
     public static int getCurrentAnimationsCount() {
-        return sAnimations.get().size();
+        AnimationHandler handler = sAnimationHandler.get();
+        return handler != null ? handler.mAnimations.size() : 0;
     }
 
     /**
@@ -1245,9 +1214,21 @@
      * @hide
      */
     public static void clearAllAnimations() {
-        sAnimations.get().clear();
-        sPendingAnimations.get().clear();
-        sDelayedAnims.get().clear();
+        AnimationHandler handler = sAnimationHandler.get();
+        if (handler != null) {
+            handler.mAnimations.clear();
+            handler.mPendingAnimations.clear();
+            handler.mDelayedAnims.clear();
+        }
+    }
+
+    private AnimationHandler getOrCreateAnimationHandler() {
+        AnimationHandler handler = sAnimationHandler.get();
+        if (handler == null) {
+            handler = new AnimationHandler();
+            sAnimationHandler.set(handler);
+        }
+        return handler;
     }
 
     @Override
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 303f81b..0c761fc 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -175,11 +175,11 @@
     // These can be accessed by multiple threads; mPackages is the lock.
     // XXX For now we keep around information about all packages we have
     // seen, not removing entries from this map.
-    // NOTE: The activity manager in its process needs to call in to
+    // NOTE: The activity and window managers need to call in to
     // ActivityThread to do things like update resource configurations,
-    // which means this lock gets held while the activity manager holds its
-    // own lock.  Thus you MUST NEVER call back into the activity manager
-    // or anything that depends on it while holding this lock.
+    // which means this lock gets held while the activity and window managers
+    // holds their own lock.  Thus you MUST NEVER call back into the activity manager
+    // or window manager or anything that depends on them while holding this lock.
     final HashMap<String, WeakReference<LoadedApk>> mPackages
             = new HashMap<String, WeakReference<LoadedApk>>();
     final HashMap<String, WeakReference<LoadedApk>> mResourcePackages
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 8ed7481..180a442 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -625,7 +625,7 @@
             return info.activityInfo.loadIcon(this);
         }
 
-        throw new NameNotFoundException(intent.toURI());
+        throw new NameNotFoundException(intent.toUri(0));
     }
 
     @Override public Drawable getDefaultActivityIcon() {
@@ -728,15 +728,22 @@
 
     private Drawable getCachedIcon(ResourceName name) {
         synchronized (sSync) {
-            WeakReference<Drawable> wr = sIconCache.get(name);
+            WeakReference<Drawable.ConstantState> wr = sIconCache.get(name);
             if (DEBUG_ICONS) Log.v(TAG, "Get cached weak drawable ref for "
                                    + name + ": " + wr);
             if (wr != null) {   // we have the activity
-                Drawable dr = wr.get();
-                if (dr != null) {
-                    if (DEBUG_ICONS) Log.v(TAG, "Get cached drawable for "
-                                           + name + ": " + dr);
-                    return dr;
+                Drawable.ConstantState state = wr.get();
+                if (state != null) {
+                    if (DEBUG_ICONS) {
+                        Log.v(TAG, "Get cached drawable state for " + name + ": " + state);
+                    }
+                    // Note: It's okay here to not use the newDrawable(Resources) variant
+                    //       of the API. The ConstantState comes from a drawable that was
+                    //       originally created by passing the proper app Resources instance
+                    //       which means the state should already contain the proper
+                    //       resources specific information (like density.) See
+                    //       BitmapDrawable.BitmapState for instance.
+                    return state.newDrawable();
                 }
                 // our entry has been purged
                 sIconCache.remove(name);
@@ -747,14 +754,12 @@
 
     private void putCachedIcon(ResourceName name, Drawable dr) {
         synchronized (sSync) {
-            sIconCache.put(name, new WeakReference<Drawable>(dr));
-            if (DEBUG_ICONS) Log.v(TAG, "Added cached drawable for "
-                                   + name + ": " + dr);
+            sIconCache.put(name, new WeakReference<Drawable.ConstantState>(dr.getConstantState()));
+            if (DEBUG_ICONS) Log.v(TAG, "Added cached drawable state for " + name + ": " + dr);
         }
     }
 
-    static final void handlePackageBroadcast(int cmd, String[] pkgList,
-                                             boolean hasPkgInfo) {
+    static void handlePackageBroadcast(int cmd, String[] pkgList, boolean hasPkgInfo) {
         boolean immediateGc = false;
         if (cmd == IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE) {
             immediateGc = true;
@@ -1226,8 +1231,8 @@
     private final IPackageManager mPM;
 
     private static final Object sSync = new Object();
-    private static HashMap<ResourceName, WeakReference<Drawable> > sIconCache
-            = new HashMap<ResourceName, WeakReference<Drawable> >();
-    private static HashMap<ResourceName, WeakReference<CharSequence> > sStringCache
-            = new HashMap<ResourceName, WeakReference<CharSequence> >();
+    private static HashMap<ResourceName, WeakReference<Drawable.ConstantState>> sIconCache
+            = new HashMap<ResourceName, WeakReference<Drawable.ConstantState>>();
+    private static HashMap<ResourceName, WeakReference<CharSequence>> sStringCache
+            = new HashMap<ResourceName, WeakReference<CharSequence>>();
 }
diff --git a/core/java/android/app/DatePickerDialog.java b/core/java/android/app/DatePickerDialog.java
index 8b70370..bf8fde0 100644
--- a/core/java/android/app/DatePickerDialog.java
+++ b/core/java/android/app/DatePickerDialog.java
@@ -91,13 +91,14 @@
 
         mCallBack = callBack;
 
-        setButton(BUTTON_POSITIVE, context.getText(R.string.date_time_set), this);
-        setButton(BUTTON_NEGATIVE, context.getText(R.string.cancel), (OnClickListener) null);
+        Context themeContext = getContext();
+        setButton(BUTTON_POSITIVE, themeContext.getText(R.string.date_time_set), this);
+        setButton(BUTTON_NEGATIVE, themeContext.getText(R.string.cancel), (OnClickListener) null);
         setIcon(0);
         setTitle(R.string.date_picker_dialog_title);
 
         LayoutInflater inflater =
-                (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+                (LayoutInflater) themeContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
         View view = inflater.inflate(R.layout.date_picker_dialog, null);
         setView(view);
         mDatePicker = (DatePicker) view.findViewById(R.id.datePicker);
diff --git a/core/java/android/app/StatusBarManager.java b/core/java/android/app/StatusBarManager.java
index 5b8addf..dd9f337 100644
--- a/core/java/android/app/StatusBarManager.java
+++ b/core/java/android/app/StatusBarManager.java
@@ -56,6 +56,11 @@
             | DISABLE_NOTIFICATION_ALERTS | DISABLE_NOTIFICATION_TICKER
             | DISABLE_SYSTEM_INFO | DISABLE_RECENT | DISABLE_HOME | DISABLE_BACK | DISABLE_CLOCK;
 
+    public static final int NAVIGATION_HINT_BACK_NOP      = 1 << 0;
+    public static final int NAVIGATION_HINT_HOME_NOP      = 1 << 1;
+    public static final int NAVIGATION_HINT_RECENT_NOP    = 1 << 2;
+    public static final int NAVIGATION_HINT_BACK_ALT      = 1 << 3;
+
     private Context mContext;
     private IStatusBarService mService;
     private IBinder mToken = new Binder();
diff --git a/core/java/android/app/TimePickerDialog.java b/core/java/android/app/TimePickerDialog.java
index a990ee9..353b415 100644
--- a/core/java/android/app/TimePickerDialog.java
+++ b/core/java/android/app/TimePickerDialog.java
@@ -92,16 +92,16 @@
         mInitialMinute = minute;
         mIs24HourView = is24HourView;
 
-        setCanceledOnTouchOutside(false);
         setIcon(0);
         setTitle(R.string.time_picker_dialog_title);
 
-        setButton(BUTTON_POSITIVE, context.getText(R.string.date_time_set), this);
-        setButton(BUTTON_NEGATIVE, context.getText(R.string.cancel),
+        Context themeContext = getContext();
+        setButton(BUTTON_POSITIVE, themeContext.getText(R.string.date_time_set), this);
+        setButton(BUTTON_NEGATIVE, themeContext.getText(R.string.cancel),
                 (OnClickListener) null);
 
         LayoutInflater inflater =
-                (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+                (LayoutInflater) themeContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
         View view = inflater.inflate(R.layout.time_picker_dialog, null);
         setView(view);
         mTimePicker = (TimePicker) view.findViewById(R.id.timePicker);
diff --git a/core/java/android/bluetooth/BluetoothA2dp.java b/core/java/android/bluetooth/BluetoothA2dp.java
index 96f3290..7300107 100644
--- a/core/java/android/bluetooth/BluetoothA2dp.java
+++ b/core/java/android/bluetooth/BluetoothA2dp.java
@@ -129,6 +129,10 @@
         }
     }
 
+    /*package*/ void close() {
+        mServiceListener = null;
+    }
+
     /**
      * Initiate connection to a profile of the remote bluetooth device.
      *
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index d971652..5f5ba50 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -1180,11 +1180,29 @@
      * @param proxy Profile proxy object
      */
     public void closeProfileProxy(int profile, BluetoothProfile proxy) {
-        if (profile == BluetoothProfile.HEADSET) {
-            BluetoothHeadset headset = (BluetoothHeadset)proxy;
-            if (headset != null) {
+        if (proxy == null) return;
+
+        switch (profile) {
+            case BluetoothProfile.HEADSET:
+                BluetoothHeadset headset = (BluetoothHeadset)proxy;
                 headset.close();
-            }
+                break;
+            case BluetoothProfile.A2DP:
+                BluetoothA2dp a2dp = (BluetoothA2dp)proxy;
+                a2dp.close();
+                break;
+            case BluetoothProfile.INPUT_DEVICE:
+                BluetoothInputDevice iDev = (BluetoothInputDevice)proxy;
+                iDev.close();
+                break;
+            case BluetoothProfile.PAN:
+                BluetoothPan pan = (BluetoothPan)proxy;
+                pan.close();
+                break;
+            case BluetoothProfile.HEALTH:
+                BluetoothHealth health = (BluetoothHealth)proxy;
+                health.close();
+                break;
         }
     }
 
diff --git a/core/java/android/bluetooth/BluetoothDeviceProfileState.java b/core/java/android/bluetooth/BluetoothDeviceProfileState.java
index b1d0070..c9603bf 100644
--- a/core/java/android/bluetooth/BluetoothDeviceProfileState.java
+++ b/core/java/android/bluetooth/BluetoothDeviceProfileState.java
@@ -109,6 +109,8 @@
     private BluetoothA2dpService mA2dpService;
     private BluetoothHeadset  mHeadsetService;
     private BluetoothPbap     mPbapService;
+    private PbapServiceListener mPbap;
+    private BluetoothAdapter mAdapter;
     private boolean mPbapServiceConnected;
     private boolean mAutoConnectionPending;
     private static final String BLUETOOTH_ADMIN_PERM = android.Manifest.permission.BLUETOOTH_ADMIN;
@@ -249,11 +251,11 @@
 
         mContext.registerReceiver(mBroadcastReceiver, filter);
 
-        BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
-        adapter.getProfileProxy(mContext, mBluetoothProfileServiceListener,
+        mAdapter = BluetoothAdapter.getDefaultAdapter();
+        mAdapter.getProfileProxy(mContext, mBluetoothProfileServiceListener,
                                 BluetoothProfile.HEADSET);
         // TODO(): Convert PBAP to the new Profile APIs.
-        PbapServiceListener p = new PbapServiceListener();
+        mPbap = new PbapServiceListener();
 
         mIncomingConnections = mService.getIncomingState(address);
         mIncomingRejectTimer = readTimerValue();
@@ -414,6 +416,26 @@
                 case TRANSITION_TO_STABLE:
                     // ignore.
                     break;
+                case SM_QUIT_CMD:
+                    mContext.unregisterReceiver(mBroadcastReceiver);
+                    mBroadcastReceiver = null;
+                    mAdapter.closeProfileProxy(BluetoothProfile.HEADSET, mHeadsetService);
+                    mBluetoothProfileServiceListener = null;
+                    mOutgoingHandsfree = null;
+                    mPbap = null;
+                    mPbapService.close();
+                    mPbapService = null;
+                    mIncomingHid = null;
+                    mOutgoingHid = null;
+                    mIncomingHandsfree = null;
+                    mOutgoingHandsfree = null;
+                    mIncomingA2dp = null;
+                    mOutgoingA2dp = null;
+                    mBondedDevice = null;
+                    // There is a problem in the State Machine code
+                    // where things are not cleaned up properly, when quit message
+                    // is handled so return NOT_HANDLED as a workaround.
+                    return NOT_HANDLED;
                 default:
                     return NOT_HANDLED;
             }
diff --git a/core/java/android/bluetooth/BluetoothHeadset.java b/core/java/android/bluetooth/BluetoothHeadset.java
index 8f2b3d8..2bbf008 100644
--- a/core/java/android/bluetooth/BluetoothHeadset.java
+++ b/core/java/android/bluetooth/BluetoothHeadset.java
@@ -245,6 +245,7 @@
             mContext.unbindService(mConnection);
             mConnection = null;
         }
+        mServiceListener = null;
     }
 
     /**
diff --git a/core/java/android/bluetooth/BluetoothHealth.java b/core/java/android/bluetooth/BluetoothHealth.java
index 9b2b8ca..f850c02 100644
--- a/core/java/android/bluetooth/BluetoothHealth.java
+++ b/core/java/android/bluetooth/BluetoothHealth.java
@@ -452,6 +452,10 @@
         }
     }
 
+    /*package*/ void close() {
+        mServiceListener = null;
+    }
+
     private boolean isEnabled() {
         BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
 
diff --git a/core/java/android/bluetooth/BluetoothInputDevice.java b/core/java/android/bluetooth/BluetoothInputDevice.java
index 282b70a..1a9e011 100644
--- a/core/java/android/bluetooth/BluetoothInputDevice.java
+++ b/core/java/android/bluetooth/BluetoothInputDevice.java
@@ -118,6 +118,10 @@
         }
     }
 
+    /*package*/ void close() {
+        mServiceListener = null;
+    }
+
     /**
      * Initiate connection to a profile of the remote bluetooth device.
      *
diff --git a/core/java/android/bluetooth/BluetoothPan.java b/core/java/android/bluetooth/BluetoothPan.java
index 7490f9e..5d9d8be 100644
--- a/core/java/android/bluetooth/BluetoothPan.java
+++ b/core/java/android/bluetooth/BluetoothPan.java
@@ -139,6 +139,10 @@
         }
     }
 
+    /*package*/ void close() {
+        mServiceListener = null;
+    }
+
     /**
      * Initiate connection to a profile of the remote bluetooth device.
      *
@@ -299,4 +303,4 @@
     private static void log(String msg) {
       Log.d(TAG, msg);
     }
-}
\ No newline at end of file
+}
diff --git a/core/java/android/bluetooth/BluetoothPbap.java b/core/java/android/bluetooth/BluetoothPbap.java
index 4be077c..2683bef 100644
--- a/core/java/android/bluetooth/BluetoothPbap.java
+++ b/core/java/android/bluetooth/BluetoothPbap.java
@@ -69,7 +69,7 @@
 
     private IBluetoothPbap mService;
     private final Context mContext;
-    private final ServiceListener mServiceListener;
+    private ServiceListener mServiceListener;
 
     /** There was an error trying to obtain the state */
     public static final int STATE_ERROR        = -1;
@@ -138,6 +138,7 @@
             mContext.unbindService(mConnection);
             mConnection = null;
         }
+        mServiceListener = null;
     }
 
     /**
diff --git a/core/java/android/content/ContentUris.java b/core/java/android/content/ContentUris.java
index aa7603470b..dbe8a7c 100644
--- a/core/java/android/content/ContentUris.java
+++ b/core/java/android/content/ContentUris.java
@@ -19,9 +19,54 @@
 import android.net.Uri;
 
 /**
- * Utility methods useful for working with content {@link android.net.Uri}s,
- * those with a "content" scheme.
- */
+* Utility methods useful for working with {@link android.net.Uri} objects
+* that use the &quot;content&quot; (content://) scheme.
+*
+*<p>
+*   Content URIs have the syntax
+*</p>
+*<p>
+*   <code>content://<em>authority</em>/<em>path</em>/<em>id</em></code>
+*</p>
+*<dl>
+*   <dt>
+*       <code>content:</code>
+*   </dt>
+*   <dd>
+*       The scheme portion of the URI. This is always set to {@link
+*       android.content.ContentResolver#SCHEME_CONTENT ContentResolver.SCHEME_CONTENT} (value
+*       <code>content://</code>).
+*   </dd>
+*   <dt>
+*       <em>authority</em>
+*   </dt>
+*   <dd>
+*       A string that identifies the entire content provider. All the content URIs for the provider
+*       start with this string. To guarantee a unique authority, providers should consider
+*       using an authority that is the same as the provider class' package identifier.
+*   </dd>
+*   <dt>
+*       <em>path</em>
+*   </dt>
+*   <dd>
+*       Zero or more segments, separated by a forward slash (<code>/</code>), that identify
+*       some subset of the provider's data. Most providers use the path part to identify
+*       individual tables. Individual segments in the path are often called
+*       &quot;directories&quot; although they do not refer to file directories. The right-most
+*       segment in a path is often called a &quot;twig&quot;
+*   </dd>
+*   <dt>
+*       <em>id</em>
+*   </dt>
+*   <dd>
+*       A unique numeric identifier for a single row in the subset of data identified by the
+*       preceding path part. Most providers recognize content URIs that contain an id part
+*       and give them special handling. A table that contains a column named <code>_ID</code>
+*       often expects the id part to be a particular value for that column.
+*   </dd>
+*</dl>
+*
+*/
 public class ContentUris {
 
     /**
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 45a42e4..4e5598b 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -2310,6 +2310,120 @@
 
     // ---------------------------------------------------------------------
     // ---------------------------------------------------------------------
+    // Application launch intent categories (see addCategory()).
+
+    /**
+     * Used with {@link #ACTION_MAIN} to launch the browser application.
+     * The activity should be able to browse the Internet.
+     * <p>NOTE: This should not be used as the primary key of an Intent,
+     * since it will not result in the app launching with the correct
+     * action and category.  Instead, use this with
+     * {@link #makeMainSelectorActivity(String, String) to generate a main
+     * Intent with this category in the selector.</p>
+     */
+    @SdkConstant(SdkConstantType.INTENT_CATEGORY)
+    public static final String CATEGORY_APP_BROWSER = "android.intent.category.APP_BROWSER";
+
+    /**
+     * Used with {@link #ACTION_MAIN} to launch the calculator application.
+     * The activity should be able to perform standard arithmetic operations.
+     * <p>NOTE: This should not be used as the primary key of an Intent,
+     * since it will not result in the app launching with the correct
+     * action and category.  Instead, use this with
+     * {@link #makeMainSelectorActivity(String, String) to generate a main
+     * Intent with this category in the selector.</p>
+     */
+    @SdkConstant(SdkConstantType.INTENT_CATEGORY)
+    public static final String CATEGORY_APP_CALCULATOR = "android.intent.category.APP_CALCULATOR";
+
+    /**
+     * Used with {@link #ACTION_MAIN} to launch the calendar application.
+     * The activity should be able to view and manipulate calendar entries.
+     * <p>NOTE: This should not be used as the primary key of an Intent,
+     * since it will not result in the app launching with the correct
+     * action and category.  Instead, use this with
+     * {@link #makeMainSelectorActivity(String, String) to generate a main
+     * Intent with this category in the selector.</p>
+     */
+    @SdkConstant(SdkConstantType.INTENT_CATEGORY)
+    public static final String CATEGORY_APP_CALENDAR = "android.intent.category.APP_CALENDAR";
+
+    /**
+     * Used with {@link #ACTION_MAIN} to launch the contacts application.
+     * The activity should be able to view and manipulate address book entries.
+     * <p>NOTE: This should not be used as the primary key of an Intent,
+     * since it will not result in the app launching with the correct
+     * action and category.  Instead, use this with
+     * {@link #makeMainSelectorActivity(String, String) to generate a main
+     * Intent with this category in the selector.</p>
+     */
+    @SdkConstant(SdkConstantType.INTENT_CATEGORY)
+    public static final String CATEGORY_APP_CONTACTS = "android.intent.category.APP_CONTACTS";
+
+    /**
+     * Used with {@link #ACTION_MAIN} to launch the email application.
+     * The activity should be able to send and receive email.
+     * <p>NOTE: This should not be used as the primary key of an Intent,
+     * since it will not result in the app launching with the correct
+     * action and category.  Instead, use this with
+     * {@link #makeMainSelectorActivity(String, String) to generate a main
+     * Intent with this category in the selector.</p>
+     */
+    @SdkConstant(SdkConstantType.INTENT_CATEGORY)
+    public static final String CATEGORY_APP_EMAIL = "android.intent.category.APP_EMAIL";
+
+    /**
+     * Used with {@link #ACTION_MAIN} to launch the gallery application.
+     * The activity should be able to view and manipulate image and video files
+     * stored on the device.
+     * <p>NOTE: This should not be used as the primary key of an Intent,
+     * since it will not result in the app launching with the correct
+     * action and category.  Instead, use this with
+     * {@link #makeMainSelectorActivity(String, String) to generate a main
+     * Intent with this category in the selector.</p>
+     */
+    @SdkConstant(SdkConstantType.INTENT_CATEGORY)
+    public static final String CATEGORY_APP_GALLERY = "android.intent.category.APP_GALLERY";
+
+    /**
+     * Used with {@link #ACTION_MAIN} to launch the maps application.
+     * The activity should be able to show the user's current location and surroundings.
+     * <p>NOTE: This should not be used as the primary key of an Intent,
+     * since it will not result in the app launching with the correct
+     * action and category.  Instead, use this with
+     * {@link #makeMainSelectorActivity(String, String) to generate a main
+     * Intent with this category in the selector.</p>
+     */
+    @SdkConstant(SdkConstantType.INTENT_CATEGORY)
+    public static final String CATEGORY_APP_MAPS = "android.intent.category.APP_MAPS";
+
+    /**
+     * Used with {@link #ACTION_MAIN} to launch the messaging application.
+     * The activity should be able to send and receive text messages.
+     * <p>NOTE: This should not be used as the primary key of an Intent,
+     * since it will not result in the app launching with the correct
+     * action and category.  Instead, use this with
+     * {@link #makeMainSelectorActivity(String, String) to generate a main
+     * Intent with this category in the selector.</p>
+     */
+    @SdkConstant(SdkConstantType.INTENT_CATEGORY)
+    public static final String CATEGORY_APP_MESSAGING = "android.intent.category.APP_MESSAGING";
+
+    /**
+     * Used with {@link #ACTION_MAIN} to launch the music application.
+     * The activity should be able to play, browse, or manipulate music files
+     * stored on the device.
+     * <p>NOTE: This should not be used as the primary key of an Intent,
+     * since it will not result in the app launching with the correct
+     * action and category.  Instead, use this with
+     * {@link #makeMainSelectorActivity(String, String) to generate a main
+     * Intent with this category in the selector.</p>
+     */
+    @SdkConstant(SdkConstantType.INTENT_CATEGORY)
+    public static final String CATEGORY_APP_MUSIC = "android.intent.category.APP_MUSIC";
+
+    // ---------------------------------------------------------------------
+    // ---------------------------------------------------------------------
     // Standard extra data keys.
 
     /**
@@ -2895,6 +3009,7 @@
     private HashSet<String> mCategories;
     private Bundle mExtras;
     private Rect mSourceBounds;
+    private Intent mSelector;
 
     // ---------------------------------------------------------------------
 
@@ -2923,6 +3038,9 @@
         if (o.mSourceBounds != null) {
             this.mSourceBounds = new Rect(o.mSourceBounds);
         }
+        if (o.mSelector != null) {
+            this.mSelector = new Intent(o.mSelector);
+        }
     }
 
     @Override
@@ -3063,6 +3181,39 @@
     }
 
     /**
+     * Make an Intent for the main activity of an application, without
+     * specifying a specific activity to run but giving a selector to find
+     * the activity.  This results in a final Intent that is structured
+     * the same as when the application is launched from
+     * Home.  For anything else that wants to launch an application in the
+     * same way, it is important that they use an Intent structured the same
+     * way, and can use this function to ensure this is the case.
+     *
+     * <p>The returned Intent has {@link #ACTION_MAIN} as its action, and includes the
+     * category {@link #CATEGORY_LAUNCHER}.  This does <em>not</em> have
+     * {@link #FLAG_ACTIVITY_NEW_TASK} set, though typically you will want
+     * to do that through {@link #addFlags(int)} on the returned Intent.
+     *
+     * @param selectorAction The action name of the Intent's selector.
+     * @param selectorCategory The name of a category to add to the Intent's
+     * selector.
+     * @return Returns a newly created Intent that can be used to launch the
+     * activity as a main application entry.
+     *
+     * @see #setSelector(Intent)
+     */
+    public static Intent makeMainSelectorActivity(String selectorAction,
+            String selectorCategory) {
+        Intent intent = new Intent(ACTION_MAIN);
+        intent.addCategory(CATEGORY_LAUNCHER);
+        Intent selector = new Intent();
+        selector.setAction(selectorAction);
+        selector.addCategory(selectorCategory);
+        intent.setSelector(selector);
+        return intent;
+    }
+
+    /**
      * Make an Intent that can be used to re-launch an application's task
      * in its base state.  This is like {@link #makeMainActivity(ComponentName)},
      * but also sets the flags {@link #FLAG_ACTIVITY_NEW_TASK} and
@@ -3137,6 +3288,7 @@
 
             // new format
             Intent intent = new Intent(ACTION_VIEW);
+            Intent baseIntent = intent;
 
             // fetch data part, if present
             String data = i >= 0 ? uri.substring(0, i) : null;
@@ -3146,8 +3298,9 @@
             // loop over contents of Intent, all name=value;
             while (!uri.startsWith("end", i)) {
                 int eq = uri.indexOf('=', i);
-                int semi = uri.indexOf(';', eq);
-                String value = Uri.decode(uri.substring(eq + 1, semi));
+                if (eq < 0) eq = i-1;
+                int semi = uri.indexOf(';', i);
+                String value = eq < semi ? Uri.decode(uri.substring(eq + 1, semi)) : "";
 
                 // action
                 if (uri.startsWith("action=", i)) {
@@ -3189,6 +3342,11 @@
                     intent.mSourceBounds = Rect.unflattenFromString(value);
                 }
 
+                // selector
+                else if (semi == (i+3) && uri.startsWith("SEL", i)) {
+                    intent = new Intent();
+                }
+
                 // extra
                 else {
                     String key = Uri.decode(uri.substring(i + 2, eq));
@@ -3212,6 +3370,12 @@
                 i = semi + 1;
             }
 
+            if (intent != baseIntent) {
+                // The Intent had a selector; fix it up.
+                baseIntent.setSelector(intent);
+                intent = baseIntent;
+            }
+
             if (data != null) {
                 if (data.startsWith("intent:")) {
                     data = data.substring(7);
@@ -3537,7 +3701,7 @@
      * Return the set of all categories in the intent.  If there are no categories,
      * returns NULL.
      *
-     * @return Set The set of categories you can examine.  Do not modify!
+     * @return The set of categories you can examine.  Do not modify!
      *
      * @see #hasCategory
      * @see #addCategory
@@ -3547,6 +3711,16 @@
     }
 
     /**
+     * Return the specific selector associated with this Intent.  If there is
+     * none, returns null.  See {@link #setSelector} for more information.
+     *
+     * @see #setSelector
+     */
+    public Intent getSelector() {
+        return mSelector;
+    }
+
+    /**
      * Sets the ClassLoader that will be used when unmarshalling
      * any Parcelable values from the extras of this Intent.
      *
@@ -4365,6 +4539,49 @@
     }
 
     /**
+     * Set a selector for this Intent.  This is a modification to the kinds of
+     * things the Intent will match.  If the selector is set, it will be used
+     * when trying to find entities that can handle the Intent, instead of the
+     * main contents of the Intent.  This allows you build an Intent containing
+     * a generic protocol while targeting it more specifically.
+     *
+     * <p>An example of where this may be used is with things like
+     * {@link #CATEGORY_APP_BROWSER}.  This category allows you to build an
+     * Intent that will launch the Browser application.  However, the correct
+     * main entry point of an application is actually {@link #ACTION_MAIN}
+     * {@link #CATEGORY_LAUNCHER} with {@link #setComponent(ComponentName)}
+     * used to specify the actual Activity to launch.  If you launch the browser
+     * with something different, undesired behavior may happen if the user has
+     * previously or later launches it the normal way, since they do not match.
+     * Instead, you can build an Intent with the MAIN action (but no ComponentName
+     * yet specified) and set a selector with {@link #ACTION_MAIN} and
+     * {@link #CATEGORY_APP_BROWSER} to point it specifically to the browser activity.
+     *
+     * <p>Setting a selector does not impact the behavior of
+     * {@link #filterEquals(Intent)} and {@link #filterHashCode()}.  This is part of the
+     * desired behavior of a selector -- it does not impact the base meaning
+     * of the Intent, just what kinds of things will be matched against it
+     * when determining who can handle it.</p>
+     *
+     * <p>You can not use both a selector and {@link #setPackage(String)} on
+     * the same base Intent.</p>
+     *
+     * @param selector The desired selector Intent; set to null to not use
+     * a special selector.
+     */
+    public void setSelector(Intent selector) {
+        if (selector == this) {
+            throw new IllegalArgumentException(
+                    "Intent being set as a selector of itself");
+        }
+        if (selector != null && mPackage != null) {
+            throw new IllegalArgumentException(
+                    "Can't set selector when package name is already set");
+        }
+        mSelector = selector;
+    }
+
+    /**
      * Add extended data to the intent.  The name must include a package
      * prefix, for example the app com.android.contacts would use names
      * like "com.android.contacts.ShowAll".
@@ -5191,6 +5408,10 @@
      * @see #resolveActivity
      */
     public Intent setPackage(String packageName) {
+        if (packageName != null && mSelector != null) {
+            throw new IllegalArgumentException(
+                    "Can't set package name when selector is already set");
+        }
         mPackage = packageName;
         return this;
     }
@@ -5326,12 +5547,18 @@
     public static final int FILL_IN_PACKAGE = 1<<4;
 
     /**
-     * Use with {@link #fillIn} to allow the current package value to be
+     * Use with {@link #fillIn} to allow the current bounds rectangle to be
      * overwritten, even if it is already set.
      */
     public static final int FILL_IN_SOURCE_BOUNDS = 1<<5;
 
     /**
+     * Use with {@link #fillIn} to allow the current selector to be
+     * overwritten, even if it is already set.
+     */
+    public static final int FILL_IN_SELECTOR = 1<<6;
+
+    /**
      * Copy the contents of <var>other</var> in to this object, but only
      * where fields are not defined by this object.  For purposes of a field
      * being defined, the following pieces of data in the Intent are
@@ -5351,11 +5578,13 @@
      *
      * <p>In addition, you can use the {@link #FILL_IN_ACTION},
      * {@link #FILL_IN_DATA}, {@link #FILL_IN_CATEGORIES}, {@link #FILL_IN_PACKAGE},
-     * and {@link #FILL_IN_COMPONENT} to override the restriction where the
+     * {@link #FILL_IN_COMPONENT}, {@link #FILL_IN_SOURCE_BOUNDS}, and
+     * {@link #FILL_IN_SELECTOR} to override the restriction where the
      * corresponding field will not be replaced if it is already set.
      *
      * <p>Note: The component field will only be copied if {@link #FILL_IN_COMPONENT} is explicitly
-     * specified.
+     * specified.  The selector will only be copied if {@link #FILL_IN_SELECTOR} is
+     * explicitly specified.
      *
      * <p>For example, consider Intent A with {data="foo", categories="bar"}
      * and Intent B with {action="gotit", data-type="some/thing",
@@ -5371,7 +5600,8 @@
      *
      * @return Returns a bit mask of {@link #FILL_IN_ACTION},
      * {@link #FILL_IN_DATA}, {@link #FILL_IN_CATEGORIES}, {@link #FILL_IN_PACKAGE},
-     * and {@link #FILL_IN_COMPONENT} indicating which fields were changed.
+     * {@link #FILL_IN_COMPONENT}, {@link #FILL_IN_SOURCE_BOUNDS}, and
+     * {@link #FILL_IN_SELECTOR} indicating which fields were changed.
      */
     public int fillIn(Intent other, int flags) {
         int changes = 0;
@@ -5396,8 +5626,20 @@
         }
         if (other.mPackage != null
                 && (mPackage == null || (flags&FILL_IN_PACKAGE) != 0)) {
-            mPackage = other.mPackage;
-            changes |= FILL_IN_PACKAGE;
+            // Only do this if mSelector is not set.
+            if (mSelector == null) {
+                mPackage = other.mPackage;
+                changes |= FILL_IN_PACKAGE;
+            }
+        }
+        // Selector is special: it can only be set if explicitly allowed,
+        // for the same reason as the component name.
+        if (other.mSelector != null && (flags&FILL_IN_SELECTOR) != 0) {
+            if (mPackage == null) {
+                mSelector = new Intent(other.mSelector);
+                mPackage = null;
+                changes |= FILL_IN_SELECTOR;
+            }
         }
         // Component is special: it can -only- be set if explicitly allowed,
         // since otherwise the sender could force the intent somewhere the
@@ -5695,6 +5937,11 @@
             first = false;
             b.append("(has extras)");
         }
+        if (mSelector != null) {
+            b.append(" sel={");
+            mSelector.toShortString(b, secure, comp, extras);
+            b.append("}");
+        }
     }
 
     /**
@@ -5755,6 +6002,21 @@
 
         uri.append("#Intent;");
 
+        toUriInner(uri, scheme, flags);
+        if (mSelector != null) {
+            uri.append("SEL;");
+            // Note that for now we are not going to try to handle the
+            // data part; not clear how to represent this as a URI, and
+            // not much utility in it.
+            mSelector.toUriInner(uri, null, flags);
+        }
+
+        uri.append("end");
+
+        return uri.toString();
+    }
+
+    private void toUriInner(StringBuilder uri, String scheme, int flags) {
         if (scheme != null) {
             uri.append("scheme=").append(scheme).append(';');
         }
@@ -5809,10 +6071,6 @@
                 }
             }
         }
-
-        uri.append("end");
-
-        return uri.toString();
     }
 
     public int describeContents() {
@@ -5843,6 +6101,13 @@
             out.writeInt(0);
         }
 
+        if (mSelector != null) {
+            out.writeInt(1);
+            mSelector.writeToParcel(out, flags);
+        } else {
+            out.writeInt(0);
+        }
+
         out.writeBundle(mExtras);
     }
 
@@ -5884,6 +6149,10 @@
             mCategories = null;
         }
 
+        if (in.readInt() != 0) {
+            mSelector = new Intent(in);
+        }
+
         mExtras = in.readBundle();
     }
 
diff --git a/core/java/android/content/SyncManager.java b/core/java/android/content/SyncManager.java
index b2909b3..3c4e545 100644
--- a/core/java/android/content/SyncManager.java
+++ b/core/java/android/content/SyncManager.java
@@ -24,6 +24,7 @@
 import android.accounts.Account;
 import android.accounts.AccountManager;
 import android.accounts.OnAccountsUpdateListener;
+import android.app.ActivityManager;
 import android.app.AlarmManager;
 import android.app.Notification;
 import android.app.NotificationManager;
@@ -86,8 +87,13 @@
     private static final long MAX_TIME_PER_SYNC;
 
     static {
-        MAX_SIMULTANEOUS_INITIALIZATION_SYNCS = SystemProperties.getInt("sync.max_init_syncs", 5);
-        MAX_SIMULTANEOUS_REGULAR_SYNCS = SystemProperties.getInt("sync.max_regular_syncs", 2);
+        final boolean isLargeRAM = ActivityManager.isLargeRAM();
+        int defaultMaxInitSyncs = isLargeRAM ? 5 : 2;
+        int defaultMaxRegularSyncs = isLargeRAM ? 2 : 1;
+        MAX_SIMULTANEOUS_INITIALIZATION_SYNCS =
+                SystemProperties.getInt("sync.max_init_syncs", defaultMaxInitSyncs);
+        MAX_SIMULTANEOUS_REGULAR_SYNCS =
+                SystemProperties.getInt("sync.max_regular_syncs", defaultMaxRegularSyncs);
         LOCAL_SYNC_DELAY =
                 SystemProperties.getLong("sync.local_sync_delay", 30 * 1000 /* 30 seconds */);
         MAX_TIME_PER_SYNC =
diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java
index 7ca6155..cca208a 100644
--- a/core/java/android/hardware/Camera.java
+++ b/core/java/android/hardware/Camera.java
@@ -138,7 +138,7 @@
     private static final int CAMERA_MSG_COMPRESSED_IMAGE = 0x100;
     private static final int CAMERA_MSG_RAW_IMAGE_NOTIFY = 0x200;
     private static final int CAMERA_MSG_PREVIEW_METADATA = 0x400;
-    private static final int CAMERA_MSG_ALL_MSGS         = 0x4FF;
+    private static final int CAMERA_MSG_FOCUS_MOVE       = 0x800;
 
     private int mNativeContext; // accessed by native methods
     private EventHandler mEventHandler;
@@ -148,6 +148,7 @@
     private PreviewCallback mPreviewCallback;
     private PictureCallback mPostviewCallback;
     private AutoFocusCallback mAutoFocusCallback;
+    private AutoFocusMoveCallback mAutoFocusMoveCallback;
     private OnZoomChangeListener mZoomListener;
     private FaceDetectionListener mFaceListener;
     private ErrorCallback mErrorCallback;
@@ -302,6 +303,12 @@
         native_setup(new WeakReference<Camera>(this), cameraId);
     }
 
+    /**
+     * An empty Camera for testing purpose.
+     */
+    Camera() {
+    }
+
     protected void finalize() {
         release();
     }
@@ -492,6 +499,7 @@
         mPostviewCallback = null;
         mJpegCallback = null;
         mAutoFocusCallback = null;
+        mAutoFocusMoveCallback = null;
     }
 
     private native final void _stopPreview();
@@ -737,6 +745,12 @@
                 }
                 return;
 
+            case CAMERA_MSG_FOCUS_MOVE:
+                if (mAutoFocusMoveCallback != null) {
+                    mAutoFocusMoveCallback.onAutoFocusMoving(msg.arg1 == 0 ? false : true, mCamera);
+                }
+                return;
+
             default:
                 Log.e(TAG, "Unknown message type " + msg.what);
                 return;
@@ -849,6 +863,39 @@
     private native final void native_cancelAutoFocus();
 
     /**
+     * Callback interface used to notify on auto focus start and stop.
+     *
+     * <p>This is useful for continuous autofocus -- {@link Parameters#FOCUS_MODE_CONTINUOUS_VIDEO}
+     * and {@link Parameters#FOCUS_MODE_CONTINUOUS_PICTURE}. Applications can
+     * show autofocus animation.</p>
+     *
+     * @hide
+     */
+    public interface AutoFocusMoveCallback
+    {
+        /**
+         * Called when the camera auto focus starts or stops.
+         *
+         * @param start true if focus starts to move, false if focus stops to move
+         * @param camera  the Camera service object
+         */
+        void onAutoFocusMoving(boolean start, Camera camera);
+    }
+
+    /**
+     * Sets camera auto-focus move callback.
+     *
+     * @param cb the callback to run
+     * @hide
+     */
+    public void setAutoFocusMoveCallback(AutoFocusMoveCallback cb) {
+        mAutoFocusMoveCallback = cb;
+        enableFocusMoveCallback((mAutoFocusMoveCallback != null) ? 1 : 0);
+    }
+
+    private native void enableFocusMoveCallback(int enable);
+
+    /**
      * Callback interface used to signal the moment of actual image capture.
      *
      * @see #takePicture(ShutterCallback, PictureCallback, PictureCallback, PictureCallback)
@@ -1310,6 +1357,18 @@
     }
 
     /**
+     * Returns an empty {@link Parameters} for testing purpose.
+     *
+     * @return an Parameter object.
+     *
+     * @hide
+     */
+    public static Parameters getEmptyParameters() {
+        Camera camera = new Camera();
+        return camera.new Parameters();
+    }
+
+    /**
      * Image size (width and height dimensions).
      */
     public class Size {
diff --git a/core/java/android/inputmethodservice/ExtractEditText.java b/core/java/android/inputmethodservice/ExtractEditText.java
index 4fc63ed..72431f3 100644
--- a/core/java/android/inputmethodservice/ExtractEditText.java
+++ b/core/java/android/inputmethodservice/ExtractEditText.java
@@ -156,4 +156,27 @@
             mIME.onViewClicked(false);
         }
     }
+
+    /**
+     * Delete the range of text, supposedly valid
+     * @hide
+     */
+    @Override
+    protected void deleteText_internal(int start, int end) {
+        // Do not call the super method. This will change the source TextView instead, which
+        // will update the ExtractTextView.
+        mIME.onExtractedDeleteText(start, end);
+    }
+
+    /**
+     * Replaces the range of text [start, end[ by replacement text
+     * @hide
+     */
+    @Override
+    protected void replaceText_internal(int start, int end, CharSequence text) {
+        // Do not call the super method. This will change the source TextView instead, which
+        // will update the ExtractTextView.
+        mIME.onExtractedReplaceText(start, end, text);
+    }
+
 }
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index 60188ea..02839db 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -1982,7 +1982,29 @@
             conn.setSelection(start, end);
         }
     }
-    
+
+    /**
+     * @hide
+     */
+    public void onExtractedDeleteText(int start, int end) {
+        InputConnection conn = getCurrentInputConnection();
+        if (conn != null) {
+            conn.setSelection(start, start);
+            conn.deleteSurroundingText(0, end-start);
+        }
+    }
+
+    /**
+     * @hide
+     */
+    public void onExtractedReplaceText(int start, int end, CharSequence text) {
+        InputConnection conn = getCurrentInputConnection();
+        if (conn != null) {
+            conn.setComposingRegion(start, end);
+            conn.commitText(text, 1);
+        }
+    }
+
     /**
      * This is called when the user has clicked on the extracted text view,
      * when running in fullscreen mode.  The default implementation hides
@@ -1998,7 +2020,7 @@
             setCandidatesViewShown(false);
         }
     }
-    
+
     /**
      * This is called when the user has performed a cursor movement in the
      * extracted text view, when it is running in fullscreen mode.  The default
diff --git a/core/java/android/inputmethodservice/KeyboardView.java b/core/java/android/inputmethodservice/KeyboardView.java
index 5143f7f..7257521 100644
--- a/core/java/android/inputmethodservice/KeyboardView.java
+++ b/core/java/android/inputmethodservice/KeyboardView.java
@@ -31,6 +31,7 @@
 import android.media.AudioManager;
 import android.os.Handler;
 import android.os.Message;
+import android.provider.Settings;
 import android.util.AttributeSet;
 import android.util.TypedValue;
 import android.view.GestureDetector;
@@ -967,8 +968,13 @@
             AccessibilityEvent event = AccessibilityEvent.obtain(eventType);
             onInitializeAccessibilityEvent(event);
             String text = null;
-            // Add text only if headset is used to avoid leaking passwords.
-            if (mAudioManager.isBluetoothA2dpOn() || mAudioManager.isWiredHeadsetOn()) {
+            // This is very efficient since the properties are cached.
+            final boolean speakPassword = Settings.Secure.getInt(mContext.getContentResolver(),
+                    Settings.Secure.ACCESSIBILITY_SPEAK_PASSWORD, 0) != 0;
+            // Add text only if password announcement is enabled or if headset is
+            // used to avoid leaking passwords.
+            if (speakPassword || mAudioManager.isBluetoothA2dpOn()
+                    || mAudioManager.isWiredHeadsetOn()) {
                 switch (code) {
                     case Keyboard.KEYCODE_ALT:
                         text = mContext.getString(R.string.keyboardview_keycode_alt);
diff --git a/core/java/android/net/InterfaceConfiguration.java b/core/java/android/net/InterfaceConfiguration.java
index 89b5915..8cdd153 100644
--- a/core/java/android/net/InterfaceConfiguration.java
+++ b/core/java/android/net/InterfaceConfiguration.java
@@ -16,34 +16,84 @@
 
 package android.net;
 
-import android.os.Parcelable;
 import android.os.Parcel;
+import android.os.Parcelable;
 
-import java.net.InetAddress;
-import java.net.UnknownHostException;
+import com.google.android.collect.Sets;
+
+import java.util.HashSet;
 
 /**
- * A simple object for retrieving / setting an interfaces configuration
+ * Configuration details for a network interface.
+ *
  * @hide
  */
 public class InterfaceConfiguration implements Parcelable {
-    public String hwAddr;
-    public LinkAddress addr;
-    public String interfaceFlags;
+    private String mHwAddr;
+    private LinkAddress mAddr;
+    private HashSet<String> mFlags = Sets.newHashSet();
 
-    public InterfaceConfiguration() {
-        super();
+    private static final String FLAG_UP = "up";
+    private static final String FLAG_DOWN = "down";
+
+    @Override
+    public String toString() {
+        final StringBuilder builder = new StringBuilder();
+        builder.append("mHwAddr=").append(mHwAddr);
+        builder.append(" mAddr=").append(String.valueOf(mAddr));
+        builder.append(" mFlags=").append(getFlags());
+        return builder.toString();
     }
 
-    public String toString() {
-        StringBuffer str = new StringBuffer();
+    public Iterable<String> getFlags() {
+        return mFlags;
+    }
 
-        str.append("ipddress ");
-        str.append((addr != null) ? addr.toString() : "NULL");
-        str.append(" flags ").append(interfaceFlags);
-        str.append(" hwaddr ").append(hwAddr);
+    public boolean hasFlag(String flag) {
+        validateFlag(flag);
+        return mFlags.contains(flag);
+    }
 
-        return str.toString();
+    public void clearFlag(String flag) {
+        validateFlag(flag);
+        mFlags.remove(flag);
+    }
+
+    public void setFlag(String flag) {
+        validateFlag(flag);
+        mFlags.add(flag);
+    }
+
+    /**
+     * Set flags to mark interface as up.
+     */
+    public void setInterfaceUp() {
+        mFlags.remove(FLAG_DOWN);
+        mFlags.add(FLAG_UP);
+    }
+
+    /**
+     * Set flags to mark interface as down.
+     */
+    public void setInterfaceDown() {
+        mFlags.remove(FLAG_UP);
+        mFlags.add(FLAG_DOWN);
+    }
+
+    public LinkAddress getLinkAddress() {
+        return mAddr;
+    }
+
+    public void setLinkAddress(LinkAddress addr) {
+        mAddr = addr;
+    }
+
+    public String getHardwareAddress() {
+        return mHwAddr;
+    }
+
+    public void setHardwareAddress(String hwAddr) {
+        mHwAddr = hwAddr;
     }
 
     /**
@@ -55,8 +105,8 @@
      */
     public boolean isActive() {
         try {
-            if(interfaceFlags.contains("up")) {
-                for (byte b : addr.getAddress().getAddress()) {
+            if (hasFlag(FLAG_UP)) {
+                for (byte b : mAddr.getAddress().getAddress()) {
                     if (b != 0) return true;
                 }
             }
@@ -66,38 +116,49 @@
         return false;
     }
 
-    /** Implement the Parcelable interface {@hide} */
+    /** {@inheritDoc} */
     public int describeContents() {
         return 0;
     }
 
-    /** Implement the Parcelable interface {@hide} */
+    /** {@inheritDoc} */
     public void writeToParcel(Parcel dest, int flags) {
-        dest.writeString(hwAddr);
-        if (addr != null) {
+        dest.writeString(mHwAddr);
+        if (mAddr != null) {
             dest.writeByte((byte)1);
-            dest.writeParcelable(addr, flags);
+            dest.writeParcelable(mAddr, flags);
         } else {
             dest.writeByte((byte)0);
         }
-        dest.writeString(interfaceFlags);
+        dest.writeInt(mFlags.size());
+        for (String flag : mFlags) {
+            dest.writeString(flag);
+        }
     }
 
-    /** Implement the Parcelable interface {@hide} */
-    public static final Creator<InterfaceConfiguration> CREATOR =
-        new Creator<InterfaceConfiguration>() {
-            public InterfaceConfiguration createFromParcel(Parcel in) {
-                InterfaceConfiguration info = new InterfaceConfiguration();
-                info.hwAddr = in.readString();
-                if (in.readByte() == 1) {
-                    info.addr = in.readParcelable(null);
-                }
-                info.interfaceFlags = in.readString();
-                return info;
+    public static final Creator<InterfaceConfiguration> CREATOR = new Creator<
+            InterfaceConfiguration>() {
+        public InterfaceConfiguration createFromParcel(Parcel in) {
+            InterfaceConfiguration info = new InterfaceConfiguration();
+            info.mHwAddr = in.readString();
+            if (in.readByte() == 1) {
+                info.mAddr = in.readParcelable(null);
             }
+            final int size = in.readInt();
+            for (int i = 0; i < size; i++) {
+                info.mFlags.add(in.readString());
+            }
+            return info;
+        }
 
-            public InterfaceConfiguration[] newArray(int size) {
-                return new InterfaceConfiguration[size];
-            }
-        };
+        public InterfaceConfiguration[] newArray(int size) {
+            return new InterfaceConfiguration[size];
+        }
+    };
+
+    private static void validateFlag(String flag) {
+        if (flag.indexOf(' ') >= 0) {
+            throw new IllegalArgumentException("flag contains space: " + flag);
+        }
+    }
 }
diff --git a/core/java/android/net/NetworkUtils.java b/core/java/android/net/NetworkUtils.java
index e289fc1..d39e741 100644
--- a/core/java/android/net/NetworkUtils.java
+++ b/core/java/android/net/NetworkUtils.java
@@ -250,4 +250,32 @@
         }
         return result;
     }
+
+    /**
+     * Trim leading zeros from IPv4 address strings
+     * Our base libraries will interpret that as octel..
+     * Must leave non v4 addresses and host names alone.
+     * For example, 192.168.000.010 -> 192.168.0.10
+     * TODO - fix base libraries and remove this function
+     * @param addr a string representing an ip addr
+     * @return a string propertly trimmed
+     */
+    public static String trimV4AddrZeros(String addr) {
+        if (addr == null) return null;
+        String[] octets = addr.split("\\.");
+        if (octets.length != 4) return addr;
+        StringBuilder builder = new StringBuilder(16);
+        String result = null;
+        for (int i = 0; i < 4; i++) {
+            try {
+                if (octets[i].length() > 3) return addr;
+                builder.append(Integer.parseInt(octets[i]));
+            } catch (NumberFormatException e) {
+                return addr;
+            }
+            if (i < 3) builder.append('.');
+        }
+        result = builder.toString();
+        return result;
+    }
 }
diff --git a/core/java/android/os/AsyncTask.java b/core/java/android/os/AsyncTask.java
index 9dea4c4..5e9abb7 100644
--- a/core/java/android/os/AsyncTask.java
+++ b/core/java/android/os/AsyncTask.java
@@ -195,6 +195,7 @@
 
     private volatile Status mStatus = Status.PENDING;
     
+    private final AtomicBoolean mCancelled = new AtomicBoolean();
     private final AtomicBoolean mTaskInvoked = new AtomicBoolean();
 
     private static class SerialExecutor implements Executor {
@@ -261,6 +262,7 @@
                 mTaskInvoked.set(true);
 
                 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
+                //noinspection unchecked
                 return postResult(doInBackground(mParams));
             }
         };
@@ -269,9 +271,7 @@
             @Override
             protected void done() {
                 try {
-                    final Result result = get();
-
-                    postResultIfNotInvoked(result);
+                    postResultIfNotInvoked(get());
                 } catch (InterruptedException e) {
                     android.util.Log.w(LOG_TAG, e);
                 } catch (ExecutionException e) {
@@ -295,6 +295,7 @@
     }
 
     private Result postResult(Result result) {
+        @SuppressWarnings("unchecked")
         Message message = sHandler.obtainMessage(MESSAGE_POST_RESULT,
                 new AsyncTaskResult<Result>(this, result));
         message.sendToTarget();
@@ -411,7 +412,7 @@
      * @see #cancel(boolean)
      */
     public final boolean isCancelled() {
-        return mFuture.isCancelled();
+        return mCancelled.get();
     }
 
     /**
@@ -444,6 +445,7 @@
      * @see #onCancelled(Object)
      */
     public final boolean cancel(boolean mayInterruptIfRunning) {
+        mCancelled.set(true);
         return mFuture.cancel(mayInterruptIfRunning);
     }
 
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index 7d034940..88fea91 100644
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -311,7 +311,7 @@
         public static final int ICE_CREAM_SANDWICH = 14;
 
         /**
-         * Android 4.1.
+         * Android 4.0.3.
          */
         public static final int ICE_CREAM_SANDWICH_MR1 = 15;
     }
diff --git a/core/java/android/os/IBinder.java b/core/java/android/os/IBinder.java
index 81defd6..0586d9e 100644
--- a/core/java/android/os/IBinder.java
+++ b/core/java/android/os/IBinder.java
@@ -128,6 +128,19 @@
     int TWEET_TRANSACTION   = ('_'<<24)|('T'<<16)|('W'<<8)|'T';
 
     /**
+     * IBinder protocol transaction code: tell an app asynchronously that the
+     * caller likes it.  The app is responsible for incrementing and maintaining
+     * its own like counter, and may display this value to the user to indicate the
+     * quality of the app.  This is an optional command that applications do not
+     * need to handle, so the default implementation is to do nothing.
+     * 
+     * <p>There is no response returned and nothing about the
+     * system will be functionally affected by it, but it will improve the
+     * app's self-esteem.
+     */
+    int LIKE_TRANSACTION   = ('_'<<24)|('L'<<16)|('I'<<8)|'K';
+
+    /**
      * Flag to {@link #transact}: this is a one-way call, meaning that the
      * caller returns immediately, without waiting for a result from the
      * callee. Applies only if the caller and callee are in different
diff --git a/core/java/android/os/storage/package.html b/core/java/android/os/storage/package.html
new file mode 100644
index 0000000..a5f1e1c
--- /dev/null
+++ b/core/java/android/os/storage/package.html
@@ -0,0 +1,8 @@
+<HTML>
+<BODY>
+<p>
+Contains classes for the system storage service, which manages binary asset filesystems
+known as Opaque Binary Blobs (OBBs).
+</p>
+</BODY>
+</HTML>
diff --git a/core/java/android/provider/MediaStore.java b/core/java/android/provider/MediaStore.java
index 5f111eb..4e01672 100644
--- a/core/java/android/provider/MediaStore.java
+++ b/core/java/android/provider/MediaStore.java
@@ -40,8 +40,6 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
-import java.io.UnsupportedEncodingException;
-import java.text.Collator;
 
 /**
  * The Media provider contains meta data for all available media on both internal
@@ -66,7 +64,10 @@
     /**
      * Activity Action: Launch a music player.
      * The activity should be able to play, browse, or manipulate music files stored on the device.
+     *
+     * @deprecated Use {@link android.content.Intent#CATEGORY_APP_MUSIC} instead.
      */
+    @Deprecated
     @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
     public static final String INTENT_ACTION_MUSIC_PLAYER = "android.intent.action.MUSIC_PLAYER";
 
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 1b5d73e..c44f23b 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -2774,10 +2774,15 @@
             "enabled_accessibility_services";
 
         /**
-         * If injection of accessibility enhancing JavaScript scripts
+         * Whether to speak passwords while in accessibility mode.
+         */
+        public static final String ACCESSIBILITY_SPEAK_PASSWORD = "speak_password";
+
+        /**
+         * If injection of accessibility enhancing JavaScript screen-reader
          * is enabled.
          * <p>
-         *   Note: Accessibility injecting scripts are served by the
+         *   Note: The JavaScript based screen-reader is served by the
          *   Google infrastructure and enable users with disabilities to
          *   efficiantly navigate in and explore web content.
          * </p>
@@ -2790,6 +2795,22 @@
             "accessibility_script_injection";
 
         /**
+         * The URL for the injected JavaScript based screen-reader used
+         * for providing accessiblity of content in WebView.
+         * <p>
+         *   Note: The JavaScript based screen-reader is served by the
+         *   Google infrastructure and enable users with disabilities to
+         *   efficiently navigate in and explore web content.
+         * </p>
+         * <p>
+         *   This property represents a string value.
+         * </p>
+         * @hide
+         */
+        public static final String ACCESSIBILITY_SCREEN_READER_URL =
+            "accessibility_script_injection_url";
+
+        /**
          * Key bindings for navigation in built-in accessibility support for web content.
          * <p>
          *   Note: These key bindings are for the built-in accessibility navigation for
@@ -3127,6 +3148,14 @@
                 "wifi_watchdog_blacklist_followup_interval_ms";
 
         /**
+         * Setting to turn off poor network avoidance on Wi-Fi. Feature is disabled by default and
+         * the setting needs to be set to 1 to enable it.
+         * @hide
+         */
+        public static final String WIFI_WATCHDOG_POOR_NETWORK_TEST_ENABLED =
+                "wifi_watchdog_poor_network_test_enabled";
+
+        /**
          * Setting to turn off walled garden test on Wi-Fi. Feature is enabled by default and
          * the setting needs to be set to 0 to disable it.
          * @hide
@@ -4121,6 +4150,7 @@
             ENABLED_ACCESSIBILITY_SERVICES,
             TOUCH_EXPLORATION_ENABLED,
             ACCESSIBILITY_ENABLED,
+            ACCESSIBILITY_SPEAK_PASSWORD,
             TTS_USE_DEFAULTS,
             TTS_DEFAULT_RATE,
             TTS_DEFAULT_PITCH,
diff --git a/core/java/android/server/BluetoothAdapterStateMachine.java b/core/java/android/server/BluetoothAdapterStateMachine.java
index c59a05a..f4a390e 100644
--- a/core/java/android/server/BluetoothAdapterStateMachine.java
+++ b/core/java/android/server/BluetoothAdapterStateMachine.java
@@ -186,8 +186,8 @@
             switch(message.what) {
                 case USER_TURN_ON:
                     // starts turning on BT module, broadcast this out
-                    transitionTo(mWarmUp);
                     broadcastState(BluetoothAdapter.STATE_TURNING_ON);
+                    transitionTo(mWarmUp);
                     if (prepareBluetooth()) {
                         // this is user request, save the setting
                         if ((Boolean) message.obj) {
@@ -209,8 +209,8 @@
                 case AIRPLANE_MODE_OFF:
                     if (getBluetoothPersistedSetting()) {
                         // starts turning on BT module, broadcast this out
-                        transitionTo(mWarmUp);
                         broadcastState(BluetoothAdapter.STATE_TURNING_ON);
+                        transitionTo(mWarmUp);
                         if (prepareBluetooth()) {
                             // We will continue turn the BT on all the way to the BluetoothOn state
                             deferMessage(obtainMessage(TURN_ON_CONTINUE));
@@ -366,9 +366,9 @@
                     // let it fall to TURN_ON_CONTINUE:
                     //$FALL-THROUGH$
                 case TURN_ON_CONTINUE:
+                    broadcastState(BluetoothAdapter.STATE_TURNING_ON);
                     mBluetoothService.switchConnectable(true);
                     transitionTo(mSwitching);
-                    broadcastState(BluetoothAdapter.STATE_TURNING_ON);
                     break;
                 case AIRPLANE_MODE_ON:
                 case TURN_COLD:
@@ -378,9 +378,9 @@
                     break;
                 case AIRPLANE_MODE_OFF:
                     if (getBluetoothPersistedSetting()) {
+                        broadcastState(BluetoothAdapter.STATE_TURNING_ON);
                         transitionTo(mSwitching);
                         mBluetoothService.switchConnectable(true);
-                        broadcastState(BluetoothAdapter.STATE_TURNING_ON);
                     }
                     break;
                 case PER_PROCESS_TURN_ON:
@@ -526,8 +526,8 @@
                     }
                     //$FALL-THROUGH$ to AIRPLANE_MODE_ON
                 case AIRPLANE_MODE_ON:
-                    transitionTo(mSwitching);
                     broadcastState(BluetoothAdapter.STATE_TURNING_OFF);
+                    transitionTo(mSwitching);
                     if (mBluetoothService.getAdapterConnectionState() !=
                         BluetoothAdapter.STATE_DISCONNECTED) {
                         mBluetoothService.disconnectDevices();
diff --git a/core/java/android/server/BluetoothPanProfileHandler.java b/core/java/android/server/BluetoothPanProfileHandler.java
index bfad747..41bb87f 100644
--- a/core/java/android/server/BluetoothPanProfileHandler.java
+++ b/core/java/android/server/BluetoothPanProfileHandler.java
@@ -377,16 +377,16 @@
         try {
             ifcg = service.getInterfaceConfig(iface);
             if (ifcg != null) {
+                final LinkAddress linkAddr = ifcg.getLinkAddress();
                 InetAddress addr = null;
-                if (ifcg.addr == null || (addr = ifcg.addr.getAddress()) == null ||
+                if (linkAddr == null || (addr = linkAddr.getAddress()) == null ||
                         addr.equals(NetworkUtils.numericToInetAddress("0.0.0.0")) ||
                         addr.equals(NetworkUtils.numericToInetAddress("::0"))) {
                     addr = NetworkUtils.numericToInetAddress(address);
                 }
-                ifcg.interfaceFlags = ifcg.interfaceFlags.replace("down", "up");
-                ifcg.addr = new LinkAddress(addr, BLUETOOTH_PREFIX_LENGTH);
-                ifcg.interfaceFlags = ifcg.interfaceFlags.replace("running", "");
-                ifcg.interfaceFlags = ifcg.interfaceFlags.replace("  "," ");
+                ifcg.setInterfaceUp();
+                ifcg.clearFlag("running");
+                ifcg.setLinkAddress(new LinkAddress(addr, BLUETOOTH_PREFIX_LENGTH));
                 service.setInterfaceConfig(iface, ifcg);
                 if (cm.tether(iface) != ConnectivityManager.TETHER_ERROR_NO_ERROR) {
                     Log.e(TAG, "Error tethering "+iface);
diff --git a/core/java/android/server/BluetoothService.java b/core/java/android/server/BluetoothService.java
index 28e231e..94fbbc8 100755
--- a/core/java/android/server/BluetoothService.java
+++ b/core/java/android/server/BluetoothService.java
@@ -145,7 +145,12 @@
     private final ArrayList<String> mUuidIntentTracker;
     private final HashMap<RemoteService, IBluetoothCallback> mUuidCallbackTracker;
 
-    private final HashMap<Integer, Pair<Integer, IBinder>> mServiceRecordToPid;
+    private static class ServiceRecordClient {
+        int pid;
+        IBinder binder;
+        IBinder.DeathRecipient death;
+    }
+    private final HashMap<Integer, ServiceRecordClient> mServiceRecordToPid;
 
     private final HashMap<String, BluetoothDeviceProfileState> mDeviceProfileState;
     private final BluetoothProfileState mA2dpProfileState;
@@ -221,7 +226,7 @@
         mDeviceOobData = new HashMap<String, Pair<byte[], byte[]>>();
         mUuidIntentTracker = new ArrayList<String>();
         mUuidCallbackTracker = new HashMap<RemoteService, IBluetoothCallback>();
-        mServiceRecordToPid = new HashMap<Integer, Pair<Integer, IBinder>>();
+        mServiceRecordToPid = new HashMap<Integer, ServiceRecordClient>();
         mDeviceProfileState = new HashMap<String, BluetoothDeviceProfileState>();
         mA2dpProfileState = new BluetoothProfileState(mContext, BluetoothProfileState.A2DP);
         mHfpProfileState = new BluetoothProfileState(mContext, BluetoothProfileState.HFP);
@@ -1528,11 +1533,17 @@
             return -1;
         }
 
-        int pid = Binder.getCallingPid();
-        mServiceRecordToPid.put(new Integer(handle), new Pair<Integer, IBinder>(pid, b));
+        ServiceRecordClient client = new ServiceRecordClient();
+        client.pid = Binder.getCallingPid();
+        client.binder = b;
+        client.death = new Reaper(handle, client.pid, RFCOMM_RECORD_REAPER);
+        mServiceRecordToPid.put(new Integer(handle), client);
         try {
-            b.linkToDeath(new Reaper(handle, pid, RFCOMM_RECORD_REAPER), 0);
-        } catch (RemoteException e) {Log.e(TAG, "", e);}
+            b.linkToDeath(client.death, 0);
+        } catch (RemoteException e) {
+            Log.e(TAG, "", e);
+            client.death = null;
+        }
         return handle;
     }
 
@@ -1547,10 +1558,15 @@
     }
 
     private synchronized void checkAndRemoveRecord(int handle, int pid) {
-        Pair<Integer, IBinder> pidPair = mServiceRecordToPid.get(handle);
-        if (pidPair != null && pid == pidPair.first) {
+        ServiceRecordClient client = mServiceRecordToPid.get(handle);
+        if (client != null && pid == client.pid) {
             if (DBG) Log.d(TAG, "Removing service record " +
                 Integer.toHexString(handle) + " for pid " + pid);
+
+            if (client.death != null) {
+                client.binder.unlinkToDeath(client.death, 0);
+            }
+
             mServiceRecordToPid.remove(handle);
             removeServiceRecordNative(handle);
         }
@@ -1880,7 +1896,7 @@
     private void dumpApplicationServiceRecords(PrintWriter pw) {
         pw.println("\n--Application Service Records--");
         for (Integer handle : mServiceRecordToPid.keySet()) {
-            Integer pid = mServiceRecordToPid.get(handle).first;
+            Integer pid = mServiceRecordToPid.get(handle).pid;
             pw.println("\tpid " + pid + " handle " + Integer.toHexString(handle));
         }
     }
@@ -2374,16 +2390,18 @@
     }
 
     BluetoothDeviceProfileState addProfileState(String address, boolean setTrust) {
-        BluetoothDeviceProfileState state = mDeviceProfileState.get(address);
-        if (state != null) return state;
-
-        state = new BluetoothDeviceProfileState(mContext, address, this, mA2dpService, setTrust);
+        BluetoothDeviceProfileState state =
+            new BluetoothDeviceProfileState(mContext, address, this, mA2dpService, setTrust);
         mDeviceProfileState.put(address, state);
         state.start();
         return state;
     }
 
     void removeProfileState(String address) {
+        BluetoothDeviceProfileState state = mDeviceProfileState.get(address);
+        if (state == null) return;
+
+        state.quit();
         mDeviceProfileState.remove(address);
     }
 
diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java
index a9a628a..7ce96c0 100644
--- a/core/java/android/service/wallpaper/WallpaperService.java
+++ b/core/java/android/service/wallpaper/WallpaperService.java
@@ -18,7 +18,6 @@
 
 import com.android.internal.os.HandlerCaller;
 import com.android.internal.view.BaseIWindow;
-import com.android.internal.view.BaseInputHandler;
 import com.android.internal.view.BaseSurfaceHolder;
 
 import android.annotation.SdkConstant;
@@ -45,8 +44,8 @@
 import android.view.IWindowSession;
 import android.view.InputChannel;
 import android.view.InputDevice;
-import android.view.InputHandler;
-import android.view.InputQueue;
+import android.view.InputEvent;
+import android.view.InputEventReceiver;
 import android.view.MotionEvent;
 import android.view.SurfaceHolder;
 import android.view.View;
@@ -228,24 +227,29 @@
             }
             
         };
-        
-        final InputHandler mInputHandler = new BaseInputHandler() {
+
+        final class WallpaperInputEventReceiver extends InputEventReceiver {
+            public WallpaperInputEventReceiver(InputChannel inputChannel, Looper looper) {
+                super(inputChannel, looper);
+            }
+
             @Override
-            public void handleMotion(MotionEvent event,
-                    InputQueue.FinishedCallback finishedCallback) {
+            public void onInputEvent(InputEvent event) {
                 boolean handled = false;
                 try {
-                    int source = event.getSource();
-                    if ((source & InputDevice.SOURCE_CLASS_POINTER) != 0) {
-                        dispatchPointer(event);
+                    if (event instanceof MotionEvent
+                            && (event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) {
+                        MotionEvent dup = MotionEvent.obtainNoHistory((MotionEvent)event);
+                        dispatchPointer(dup);
                         handled = true;
                     }
                 } finally {
-                    finishedCallback.finished(handled);
+                    finishInputEvent(event, handled);
                 }
             }
-        };
-        
+        }
+        WallpaperInputEventReceiver mInputEventReceiver;
+
         final BaseIWindow mWindow = new BaseIWindow() {
             @Override
             public void resized(int w, int h, Rect coveredInsets,
@@ -534,6 +538,8 @@
                 }
                 Message msg = mCaller.obtainMessageO(MSG_TOUCH_EVENT, event);
                 mCaller.sendMessage(msg);
+            } else {
+                event.recycle();
             }
         }
 
@@ -599,8 +605,8 @@
                         }
                         mCreated = true;
 
-                        InputQueue.registerInputChannel(mInputChannel, mInputHandler,
-                                Looper.myQueue());
+                        mInputEventReceiver = new WallpaperInputEventReceiver(
+                                mInputChannel, Looper.myLooper());
                     }
                     
                     mSurfaceHolder.mSurfaceLock.lock();
@@ -608,7 +614,7 @@
 
                     final int relayoutResult = mSession.relayout(
                         mWindow, mWindow.mSeq, mLayout, mWidth, mHeight,
-                            View.VISIBLE, false, mWinFrame, mContentInsets,
+                            View.VISIBLE, 0, mWinFrame, mContentInsets,
                             mVisibleInsets, mConfiguration, mSurfaceHolder.mSurface);
 
                     if (DEBUG) Log.v(TAG, "New surface: " + mSurfaceHolder.mSurface
@@ -654,7 +660,7 @@
                         }
 
                         redrawNeeded |= creating
-                                || (relayoutResult&WindowManagerImpl.RELAYOUT_FIRST_TIME) != 0;
+                                || (relayoutResult&WindowManagerImpl.RELAYOUT_RES_FIRST_TIME) != 0;
 
                         if (forceReport || creating || surfaceCreating
                                 || formatChanged || sizeChanged) {
@@ -902,8 +908,9 @@
                     if (DEBUG) Log.v(TAG, "Removing window and destroying surface "
                             + mSurfaceHolder.getSurface() + " of: " + this);
                     
-                    if (mInputChannel != null) {
-                        InputQueue.unregisterInputChannel(mInputChannel);
+                    if (mInputEventReceiver != null) {
+                        mInputEventReceiver.dispose();
+                        mInputEventReceiver = null;
                     }
                     
                     mSession.remove(mWindow);
@@ -970,6 +977,8 @@
         public void dispatchPointer(MotionEvent event) {
             if (mEngine != null) {
                 mEngine.dispatchPointer(event);
+            } else {
+                event.recycle();
             }
         }
 
diff --git a/core/java/android/speech/tts/AudioMessageParams.java b/core/java/android/speech/tts/AudioMessageParams.java
deleted file mode 100644
index 29b4367..0000000
--- a/core/java/android/speech/tts/AudioMessageParams.java
+++ /dev/null
@@ -1,38 +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.speech.tts;
-
-import android.speech.tts.TextToSpeechService.UtteranceProgressDispatcher;
-
-class AudioMessageParams extends MessageParams {
-    private final BlockingMediaPlayer mPlayer;
-
-    AudioMessageParams(UtteranceProgressDispatcher dispatcher,
-            String callingApp, BlockingMediaPlayer player) {
-        super(dispatcher, callingApp);
-        mPlayer = player;
-    }
-
-    BlockingMediaPlayer getPlayer() {
-        return mPlayer;
-    }
-
-    @Override
-    int getType() {
-        return TYPE_AUDIO;
-    }
-
-}
diff --git a/core/java/android/speech/tts/AudioPlaybackHandler.java b/core/java/android/speech/tts/AudioPlaybackHandler.java
index 0194240..d63f605 100644
--- a/core/java/android/speech/tts/AudioPlaybackHandler.java
+++ b/core/java/android/speech/tts/AudioPlaybackHandler.java
@@ -15,44 +15,20 @@
  */
 package android.speech.tts;
 
-import android.media.AudioFormat;
-import android.media.AudioTrack;
-import android.text.TextUtils;
 import android.util.Log;
 
 import java.util.Iterator;
-import java.util.concurrent.PriorityBlockingQueue;
-import java.util.concurrent.atomic.AtomicLong;
+import java.util.concurrent.LinkedBlockingQueue;
 
 class AudioPlaybackHandler {
     private static final String TAG = "TTS.AudioPlaybackHandler";
-    private static final boolean DBG_THREADING = false;
     private static final boolean DBG = false;
 
-    private static final int MIN_AUDIO_BUFFER_SIZE = 8192;
-
-    private static final int SYNTHESIS_START = 1;
-    private static final int SYNTHESIS_DATA_AVAILABLE = 2;
-    private static final int SYNTHESIS_DONE = 3;
-
-    private static final int PLAY_AUDIO = 5;
-    private static final int PLAY_SILENCE = 6;
-
-    private static final int SHUTDOWN = -1;
-
-    private static final int DEFAULT_PRIORITY = 1;
-    private static final int HIGH_PRIORITY = 0;
-
-    private final PriorityBlockingQueue<ListEntry> mQueue =
-            new PriorityBlockingQueue<ListEntry>();
+    private final LinkedBlockingQueue<PlaybackQueueItem> mQueue =
+            new LinkedBlockingQueue<PlaybackQueueItem>();
     private final Thread mHandlerThread;
 
-    private volatile MessageParams mCurrentParams = null;
-    // Used only for book keeping and error detection.
-    private volatile SynthesisMessageParams mLastSynthesisRequest = null;
-    // Used to order incoming messages in our priority queue.
-    private final AtomicLong mSequenceIdCtr = new AtomicLong(0);
-
+    private volatile PlaybackQueueItem mCurrentWorkItem = null;
 
     AudioPlaybackHandler() {
         mHandlerThread = new Thread(new MessageLoop(), "TTS.AudioPlaybackThread");
@@ -62,68 +38,38 @@
         mHandlerThread.start();
     }
 
-    /**
-     * Stops all synthesis for a given {@code token}. If the current token
-     * is currently being processed, an effort will be made to stop it but
-     * that is not guaranteed.
-     *
-     * NOTE: This assumes that all other messages in the queue with {@code token}
-     * have been removed already.
-     *
-     * NOTE: Must be called synchronized on {@code AudioPlaybackHandler.this}.
-     */
-    private void stop(MessageParams token) {
-        if (token == null) {
+    private void stop(PlaybackQueueItem item) {
+        if (item == null) {
             return;
         }
 
-        if (DBG) Log.d(TAG, "Stopping token : " + token);
+        item.stop(false);
+    }
 
-        if (token.getType() == MessageParams.TYPE_SYNTHESIS) {
-            AudioTrack current = ((SynthesisMessageParams) token).getAudioTrack();
-            if (current != null) {
-                // Stop the current audio track if it's still playing.
-                // The audio track is thread safe in this regard. The current
-                // handleSynthesisDataAvailable call will return soon after this
-                // call.
-                current.stop();
-            }
-            // This is safe because PlaybackSynthesisCallback#stop would have
-            // been called before this method, and will no longer enqueue any
-            // audio for this token.
-            //
-            // (Even if it did, all it would result in is a warning message).
-            mQueue.add(new ListEntry(SYNTHESIS_DONE, token, HIGH_PRIORITY));
-        } else if (token.getType() == MessageParams.TYPE_AUDIO) {
-            ((AudioMessageParams) token).getPlayer().stop();
-            // No cleanup required for audio messages.
-        } else if (token.getType() == MessageParams.TYPE_SILENCE) {
-            ((SilenceMessageParams) token).getConditionVariable().open();
-            // No cleanup required for silence messages.
+    public void enqueue(PlaybackQueueItem item) {
+        try {
+            mQueue.put(item);
+        } catch (InterruptedException ie) {
+            // This exception will never be thrown, since we allow our queue
+            // to be have an unbounded size. put() will therefore never block.
         }
     }
 
-    // -----------------------------------------------------
-    // Methods that add and remove elements from the queue. These do not
-    // need to be synchronized strictly speaking, but they make the behaviour
-    // a lot more predictable. (though it would still be correct without
-    // synchronization).
-    // -----------------------------------------------------
+    public void stopForApp(Object callerIdentity) {
+        if (DBG) Log.d(TAG, "Removing all callback items for : " + callerIdentity);
+        removeWorkItemsFor(callerIdentity);
 
-    synchronized public void removePlaybackItems(String callingApp) {
-        if (DBG_THREADING) Log.d(TAG, "Removing all callback items for : " + callingApp);
-        removeMessages(callingApp);
-
-        final MessageParams current = getCurrentParams();
-        if (current != null && TextUtils.equals(callingApp, current.getCallingApp())) {
+        final PlaybackQueueItem current = mCurrentWorkItem;
+        if (current != null && (current.getCallerIdentity() == callerIdentity)) {
             stop(current);
         }
     }
 
-    synchronized public void removeAllItems() {
-        if (DBG_THREADING) Log.d(TAG, "Removing all items");
+    public void stop() {
+        if (DBG) Log.d(TAG, "Stopping all items");
         removeAllMessages();
-        stop(getCurrentParams());
+
+        stop(mCurrentWorkItem);
     }
 
     /**
@@ -131,51 +77,39 @@
      *        being handled, true otherwise.
      */
     public boolean isSpeaking() {
-        return (mQueue.peek() != null) || (mCurrentParams != null);
+        return (mQueue.peek() != null) || (mCurrentWorkItem != null);
     }
 
     /**
      * Shut down the audio playback thread.
      */
-    synchronized public void quit() {
+    public void quit() {
         removeAllMessages();
-        stop(getCurrentParams());
-        mQueue.add(new ListEntry(SHUTDOWN, null, HIGH_PRIORITY));
+        stop(mCurrentWorkItem);
+        mHandlerThread.interrupt();
     }
 
-    synchronized void enqueueSynthesisStart(SynthesisMessageParams token) {
-        if (DBG_THREADING) Log.d(TAG, "Enqueuing synthesis start : " + token);
-        mQueue.add(new ListEntry(SYNTHESIS_START, token));
+    /*
+     * Atomically clear the queue of all messages.
+     */
+    private void removeAllMessages() {
+        mQueue.clear();
     }
 
-    synchronized void enqueueSynthesisDataAvailable(SynthesisMessageParams token) {
-        if (DBG_THREADING) Log.d(TAG, "Enqueuing synthesis data available : " + token);
-        mQueue.add(new ListEntry(SYNTHESIS_DATA_AVAILABLE, token));
+    /*
+     * Remove all messages that originate from a given calling app.
+     */
+    private void removeWorkItemsFor(Object callerIdentity) {
+        Iterator<PlaybackQueueItem> it = mQueue.iterator();
+
+        while (it.hasNext()) {
+            final PlaybackQueueItem item = it.next();
+            if (item.getCallerIdentity() == callerIdentity) {
+                it.remove();
+            }
+        }
     }
 
-    synchronized void enqueueSynthesisDone(SynthesisMessageParams token) {
-        if (DBG_THREADING) Log.d(TAG, "Enqueuing synthesis done : " + token);
-        mQueue.add(new ListEntry(SYNTHESIS_DONE, token));
-    }
-
-    synchronized void enqueueAudio(AudioMessageParams token) {
-        if (DBG_THREADING) Log.d(TAG, "Enqueuing audio : " + token);
-        mQueue.add(new ListEntry(PLAY_AUDIO, token));
-    }
-
-    synchronized void enqueueSilence(SilenceMessageParams token) {
-        if (DBG_THREADING) Log.d(TAG, "Enqueuing silence : " + token);
-        mQueue.add(new ListEntry(PLAY_SILENCE, token));
-    }
-
-    // -----------------------------------------
-    // End of public API methods.
-    // -----------------------------------------
-
-    // -----------------------------------------
-    // Methods for managing the message queue.
-    // -----------------------------------------
-
     /*
      * The MessageLoop is a handler like implementation that
      * processes messages from a priority queue.
@@ -184,431 +118,23 @@
         @Override
         public void run() {
             while (true) {
-                ListEntry entry = null;
+                PlaybackQueueItem item = null;
                 try {
-                    entry = mQueue.take();
+                    item = mQueue.take();
                 } catch (InterruptedException ie) {
+                    if (DBG) Log.d(TAG, "MessageLoop : Shutting down (interrupted)");
                     return;
                 }
 
-                if (entry.mWhat == SHUTDOWN) {
-                    if (DBG) Log.d(TAG, "MessageLoop : Shutting down");
-                    return;
-                }
+                // If stop() or stopForApp() are called between mQueue.take()
+                // returning and mCurrentWorkItem being set, the current work item
+                // will be run anyway.
 
-                if (DBG) {
-                    Log.d(TAG, "MessageLoop : Handling message :" + entry.mWhat
-                            + " ,seqId : " + entry.mSequenceId);
-                }
-
-                setCurrentParams(entry.mMessage);
-                handleMessage(entry);
-                setCurrentParams(null);
+                mCurrentWorkItem = item;
+                item.run();
+                mCurrentWorkItem = null;
             }
         }
     }
 
-    /*
-     * Atomically clear the queue of all messages.
-     */
-    synchronized private void removeAllMessages() {
-        mQueue.clear();
-    }
-
-    /*
-     * Remove all messages that originate from a given calling app.
-     */
-    synchronized private void removeMessages(String callingApp) {
-        Iterator<ListEntry> it = mQueue.iterator();
-
-        while (it.hasNext()) {
-            final ListEntry current = it.next();
-            // The null check is to prevent us from removing control messages,
-            // such as a shutdown message.
-            if (current.mMessage != null &&
-                    callingApp.equals(current.mMessage.getCallingApp())) {
-                it.remove();
-            }
-        }
-    }
-
-    /*
-     * An element of our priority queue of messages. Each message has a priority,
-     * and a sequence id (defined by the order of enqueue calls). Among messages
-     * with the same priority, messages that were received earlier win out.
-     */
-    private final class ListEntry implements Comparable<ListEntry> {
-        final int mWhat;
-        final MessageParams mMessage;
-        final int mPriority;
-        final long mSequenceId;
-
-        private ListEntry(int what, MessageParams message) {
-            this(what, message, DEFAULT_PRIORITY);
-        }
-
-        private ListEntry(int what, MessageParams message, int priority) {
-            mWhat = what;
-            mMessage = message;
-            mPriority = priority;
-            mSequenceId = mSequenceIdCtr.incrementAndGet();
-        }
-
-        @Override
-        public int compareTo(ListEntry that) {
-            if (that == this) {
-                return 0;
-            }
-
-            // Note that this is always 0, 1 or -1.
-            int priorityDiff = mPriority - that.mPriority;
-            if (priorityDiff == 0) {
-                // The == case cannot occur.
-                return (mSequenceId < that.mSequenceId) ? -1 : 1;
-            }
-
-            return priorityDiff;
-        }
-    }
-
-    private void setCurrentParams(MessageParams p) {
-        if (DBG_THREADING) {
-            if (p != null) {
-                Log.d(TAG, "Started handling :" + p);
-            } else {
-                Log.d(TAG, "End handling : " + mCurrentParams);
-            }
-        }
-        mCurrentParams = p;
-    }
-
-    private MessageParams getCurrentParams() {
-        return mCurrentParams;
-    }
-
-    // -----------------------------------------
-    // Methods for dealing with individual messages, the methods
-    // below do the actual work.
-    // -----------------------------------------
-
-    private void handleMessage(ListEntry entry) {
-        final MessageParams msg = entry.mMessage;
-        if (entry.mWhat == SYNTHESIS_START) {
-            handleSynthesisStart(msg);
-        } else if (entry.mWhat == SYNTHESIS_DATA_AVAILABLE) {
-            handleSynthesisDataAvailable(msg);
-        } else if (entry.mWhat == SYNTHESIS_DONE) {
-            handleSynthesisDone(msg);
-        } else if (entry.mWhat == PLAY_AUDIO) {
-            handleAudio(msg);
-        } else if (entry.mWhat == PLAY_SILENCE) {
-            handleSilence(msg);
-        }
-    }
-
-    // Currently implemented as blocking the audio playback thread for the
-    // specified duration. If a call to stop() is made, the thread
-    // unblocks.
-    private void handleSilence(MessageParams msg) {
-        if (DBG) Log.d(TAG, "handleSilence()");
-        SilenceMessageParams params = (SilenceMessageParams) msg;
-        params.getDispatcher().dispatchOnStart();
-        if (params.getSilenceDurationMs() > 0) {
-            params.getConditionVariable().block(params.getSilenceDurationMs());
-        }
-        params.getDispatcher().dispatchOnDone();
-        if (DBG) Log.d(TAG, "handleSilence() done.");
-    }
-
-    // Plays back audio from a given URI. No TTS engine involvement here.
-    private void handleAudio(MessageParams msg) {
-        if (DBG) Log.d(TAG, "handleAudio()");
-        AudioMessageParams params = (AudioMessageParams) msg;
-        params.getDispatcher().dispatchOnStart();
-        // Note that the BlockingMediaPlayer spawns a separate thread.
-        //
-        // TODO: This can be avoided.
-        params.getPlayer().startAndWait();
-        params.getDispatcher().dispatchOnDone();
-        if (DBG) Log.d(TAG, "handleAudio() done.");
-    }
-
-    // Denotes the start of a new synthesis request. We create a new
-    // audio track, and prepare it for incoming data.
-    //
-    // Note that since all TTS synthesis happens on a single thread, we
-    // should ALWAYS see the following order :
-    //
-    // handleSynthesisStart -> handleSynthesisDataAvailable(*) -> handleSynthesisDone
-    // OR
-    // handleSynthesisCompleteDataAvailable.
-    private void handleSynthesisStart(MessageParams msg) {
-        if (DBG) Log.d(TAG, "handleSynthesisStart()");
-        final SynthesisMessageParams param = (SynthesisMessageParams) msg;
-
-        // Oops, looks like the engine forgot to call done(). We go through
-        // extra trouble to clean the data to prevent the AudioTrack resources
-        // from being leaked.
-        if (mLastSynthesisRequest != null) {
-            Log.w(TAG, "Error : Missing call to done() for request : " +
-                    mLastSynthesisRequest);
-            handleSynthesisDone(mLastSynthesisRequest);
-        }
-
-        mLastSynthesisRequest = param;
-
-        // Create the audio track.
-        final AudioTrack audioTrack = createStreamingAudioTrack(param);
-
-        if (DBG) Log.d(TAG, "Created audio track [" + audioTrack.hashCode() + "]");
-
-        param.setAudioTrack(audioTrack);
-        msg.getDispatcher().dispatchOnStart();
-    }
-
-    // More data available to be flushed to the audio track.
-    private void handleSynthesisDataAvailable(MessageParams msg) {
-        final SynthesisMessageParams param = (SynthesisMessageParams) msg;
-        if (param.getAudioTrack() == null) {
-            Log.w(TAG, "Error : null audio track in handleDataAvailable : " + param);
-            return;
-        }
-
-        if (param != mLastSynthesisRequest) {
-            Log.e(TAG, "Call to dataAvailable without done() / start()");
-            return;
-        }
-
-        final AudioTrack audioTrack = param.getAudioTrack();
-        final SynthesisMessageParams.ListEntry bufferCopy = param.getNextBuffer();
-
-        if (bufferCopy == null) {
-            Log.e(TAG, "No buffers available to play.");
-            return;
-        }
-
-        int playState = audioTrack.getPlayState();
-        if (playState == AudioTrack.PLAYSTATE_STOPPED) {
-            if (DBG) Log.d(TAG, "AudioTrack stopped, restarting : " + audioTrack.hashCode());
-            audioTrack.play();
-        }
-        int count = 0;
-        while (count < bufferCopy.mBytes.length) {
-            // Note that we don't take bufferCopy.mOffset into account because
-            // it is guaranteed to be 0.
-            int written = audioTrack.write(bufferCopy.mBytes, count, bufferCopy.mBytes.length);
-            if (written <= 0) {
-                break;
-            }
-            count += written;
-        }
-        param.mBytesWritten += count;
-        param.mLogger.onPlaybackStart();
-    }
-
-    // Wait for the audio track to stop playing, and then release its resources.
-    private void handleSynthesisDone(MessageParams msg) {
-        final SynthesisMessageParams params = (SynthesisMessageParams) msg;
-
-        if (DBG) Log.d(TAG, "handleSynthesisDone()");
-        final AudioTrack audioTrack = params.getAudioTrack();
-
-        if (audioTrack == null) {
-            params.getDispatcher().dispatchOnError();
-            return;
-        }
-
-        if (params.mBytesWritten < params.mAudioBufferSize) {
-            if (DBG) Log.d(TAG, "Stopping audio track to flush audio, state was : " +
-                    audioTrack.getPlayState());
-            params.mIsShortUtterance = true;
-            audioTrack.stop();
-        }
-
-        if (DBG) Log.d(TAG, "Waiting for audio track to complete : " +
-                audioTrack.hashCode());
-        blockUntilDone(params);
-        if (DBG) Log.d(TAG, "Releasing audio track [" + audioTrack.hashCode() + "]");
-
-        // The last call to AudioTrack.write( ) will return only after
-        // all data from the audioTrack has been sent to the mixer, so
-        // it's safe to release at this point. Make sure release() and the call
-        // that set the audio track to null are performed atomically.
-        synchronized (this) {
-            // Never allow the audioTrack to be observed in a state where
-            // it is released but non null. The only case this might happen
-            // is in the various stopFoo methods that call AudioTrack#stop from
-            // different threads, but they are synchronized on AudioPlayBackHandler#this
-            // too.
-            audioTrack.release();
-            params.setAudioTrack(null);
-        }
-        params.getDispatcher().dispatchOnDone();
-        mLastSynthesisRequest = null;
-        params.mLogger.onWriteData();
-    }
-
-    /**
-     * The minimum increment of time to wait for an audiotrack to finish
-     * playing.
-     */
-    private static final long MIN_SLEEP_TIME_MS = 20;
-
-    /**
-     * The maximum increment of time to sleep while waiting for an audiotrack
-     * to finish playing.
-     */
-    private static final long MAX_SLEEP_TIME_MS = 2500;
-
-    /**
-     * The maximum amount of time to wait for an audio track to make progress while
-     * it remains in PLAYSTATE_PLAYING. This should never happen in normal usage, but
-     * could happen in exceptional circumstances like a media_server crash.
-     */
-    private static final long MAX_PROGRESS_WAIT_MS = MAX_SLEEP_TIME_MS;
-
-    private static void blockUntilDone(SynthesisMessageParams params) {
-        if (params.mAudioTrack == null || params.mBytesWritten <= 0) {
-            return;
-        }
-
-        if (params.mIsShortUtterance) {
-            // In this case we would have called AudioTrack#stop() to flush
-            // buffers to the mixer. This makes the playback head position
-            // unobservable and notification markers do not work reliably. We
-            // have no option but to wait until we think the track would finish
-            // playing and release it after.
-            //
-            // This isn't as bad as it looks because (a) We won't end up waiting
-            // for much longer than we should because even at 4khz mono, a short
-            // utterance weighs in at about 2 seconds, and (b) such short utterances
-            // are expected to be relatively infrequent and in a stream of utterances
-            // this shows up as a slightly longer pause.
-            blockUntilEstimatedCompletion(params);
-        } else {
-            blockUntilCompletion(params);
-        }
-    }
-
-    private static void blockUntilEstimatedCompletion(SynthesisMessageParams params) {
-        final int lengthInFrames = params.mBytesWritten / params.mBytesPerFrame;
-        final long estimatedTimeMs = (lengthInFrames * 1000 / params.mSampleRateInHz);
-
-        if (DBG) Log.d(TAG, "About to sleep for: " + estimatedTimeMs + "ms for a short utterance");
-
-        try {
-            Thread.sleep(estimatedTimeMs);
-        } catch (InterruptedException ie) {
-            // Do nothing.
-        }
-    }
-
-    private static void blockUntilCompletion(SynthesisMessageParams params) {
-        final AudioTrack audioTrack = params.mAudioTrack;
-        final int lengthInFrames = params.mBytesWritten / params.mBytesPerFrame;
-
-        int previousPosition = -1;
-        int currentPosition = 0;
-        long blockedTimeMs = 0;
-
-        while ((currentPosition = audioTrack.getPlaybackHeadPosition()) < lengthInFrames &&
-                audioTrack.getPlayState() == AudioTrack.PLAYSTATE_PLAYING) {
-
-            final long estimatedTimeMs = ((lengthInFrames - currentPosition) * 1000) /
-                    audioTrack.getSampleRate();
-            final long sleepTimeMs = clip(estimatedTimeMs, MIN_SLEEP_TIME_MS, MAX_SLEEP_TIME_MS);
-
-            // Check if the audio track has made progress since the last loop
-            // iteration. We should then add in the amount of time that was
-            // spent sleeping in the last iteration.
-            if (currentPosition == previousPosition) {
-                // This works only because the sleep time that would have been calculated
-                // would be the same in the previous iteration too.
-                blockedTimeMs += sleepTimeMs;
-                // If we've taken too long to make progress, bail.
-                if (blockedTimeMs > MAX_PROGRESS_WAIT_MS) {
-                    Log.w(TAG, "Waited unsuccessfully for " + MAX_PROGRESS_WAIT_MS + "ms " +
-                            "for AudioTrack to make progress, Aborting");
-                    break;
-                }
-            } else {
-                blockedTimeMs = 0;
-            }
-            previousPosition = currentPosition;
-
-            if (DBG) Log.d(TAG, "About to sleep for : " + sleepTimeMs + " ms," +
-                    " Playback position : " + currentPosition + ", Length in frames : "
-                    + lengthInFrames);
-            try {
-                Thread.sleep(sleepTimeMs);
-            } catch (InterruptedException ie) {
-                break;
-            }
-        }
-    }
-
-    private static final long clip(long value, long min, long max) {
-        if (value < min) {
-            return min;
-        }
-
-        if (value > max) {
-            return max;
-        }
-
-        return value;
-    }
-
-    private static AudioTrack createStreamingAudioTrack(SynthesisMessageParams params) {
-        final int channelConfig = getChannelConfig(params.mChannelCount);
-        final int sampleRateInHz = params.mSampleRateInHz;
-        final int audioFormat = params.mAudioFormat;
-
-        int minBufferSizeInBytes
-                = AudioTrack.getMinBufferSize(sampleRateInHz, channelConfig, audioFormat);
-        int bufferSizeInBytes = Math.max(MIN_AUDIO_BUFFER_SIZE, minBufferSizeInBytes);
-
-        AudioTrack audioTrack = new AudioTrack(params.mStreamType, sampleRateInHz, channelConfig,
-                audioFormat, bufferSizeInBytes, AudioTrack.MODE_STREAM);
-        if (audioTrack.getState() != AudioTrack.STATE_INITIALIZED) {
-            Log.w(TAG, "Unable to create audio track.");
-            audioTrack.release();
-            return null;
-        }
-        params.mAudioBufferSize = bufferSizeInBytes;
-
-        setupVolume(audioTrack, params.mVolume, params.mPan);
-        return audioTrack;
-    }
-
-    static int getChannelConfig(int channelCount) {
-        if (channelCount == 1) {
-            return AudioFormat.CHANNEL_OUT_MONO;
-        } else if (channelCount == 2){
-            return AudioFormat.CHANNEL_OUT_STEREO;
-        }
-
-        return 0;
-    }
-
-    private static void setupVolume(AudioTrack audioTrack, float volume, float pan) {
-        float vol = clip(volume, 0.0f, 1.0f);
-        float panning = clip(pan, -1.0f, 1.0f);
-        float volLeft = vol;
-        float volRight = vol;
-        if (panning > 0.0f) {
-            volLeft *= (1.0f - panning);
-        } else if (panning < 0.0f) {
-            volRight *= (1.0f + panning);
-        }
-        if (DBG) Log.d(TAG, "volLeft=" + volLeft + ",volRight=" + volRight);
-        if (audioTrack.setStereoVolume(volLeft, volRight) != AudioTrack.SUCCESS) {
-            Log.e(TAG, "Failed to set volume");
-        }
-    }
-
-    private static float clip(float value, float min, float max) {
-        return value > max ? max : (value < min ? min : value);
-    }
-
 }
diff --git a/core/java/android/speech/tts/AudioPlaybackQueueItem.java b/core/java/android/speech/tts/AudioPlaybackQueueItem.java
new file mode 100644
index 0000000..1a1fda81
--- /dev/null
+++ b/core/java/android/speech/tts/AudioPlaybackQueueItem.java
@@ -0,0 +1,105 @@
+/*
+ * 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.speech.tts;
+
+import android.content.Context;
+import android.media.MediaPlayer;
+import android.net.Uri;
+import android.os.ConditionVariable;
+import android.speech.tts.TextToSpeechService.UtteranceProgressDispatcher;
+import android.util.Log;
+
+class AudioPlaybackQueueItem extends PlaybackQueueItem {
+    private static final String TAG = "TTS.AudioQueueItem";
+
+    private final Context mContext;
+    private final Uri mUri;
+    private final int mStreamType;
+
+    private final ConditionVariable mDone;
+    private MediaPlayer mPlayer;
+    private volatile boolean mFinished;
+
+    AudioPlaybackQueueItem(UtteranceProgressDispatcher dispatcher,
+            Object callerIdentity,
+            Context context, Uri uri, int streamType) {
+        super(dispatcher, callerIdentity);
+
+        mContext = context;
+        mUri = uri;
+        mStreamType = streamType;
+
+        mDone = new ConditionVariable();
+        mPlayer = null;
+        mFinished = false;
+    }
+    @Override
+    public void run() {
+        final UtteranceProgressDispatcher dispatcher = getDispatcher();
+
+        dispatcher.dispatchOnStart();
+        mPlayer = MediaPlayer.create(mContext, mUri);
+        if (mPlayer == null) {
+            dispatcher.dispatchOnError();
+            return;
+        }
+
+        try {
+            mPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
+                @Override
+                public boolean onError(MediaPlayer mp, int what, int extra) {
+                    Log.w(TAG, "Audio playback error: " + what + ", " + extra);
+                    mDone.open();
+                    return true;
+                }
+            });
+            mPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
+                @Override
+                public void onCompletion(MediaPlayer mp) {
+                    mFinished = true;
+                    mDone.open();
+                }
+            });
+            mPlayer.setAudioStreamType(mStreamType);
+            mPlayer.start();
+            mDone.block();
+            finish();
+        } catch (IllegalArgumentException ex) {
+            Log.w(TAG, "MediaPlayer failed", ex);
+            mDone.open();
+        }
+
+        if (mFinished) {
+            dispatcher.dispatchOnDone();
+        } else {
+            dispatcher.dispatchOnError();
+        }
+    }
+
+    private void finish() {
+        try {
+            mPlayer.stop();
+        } catch (IllegalStateException ex) {
+            // Do nothing, the player is already stopped
+        }
+        mPlayer.release();
+    }
+
+    @Override
+    void stop(boolean isError) {
+        mDone.open();
+    }
+}
diff --git a/core/java/android/speech/tts/BlockingAudioTrack.java b/core/java/android/speech/tts/BlockingAudioTrack.java
new file mode 100644
index 0000000..fcadad7
--- /dev/null
+++ b/core/java/android/speech/tts/BlockingAudioTrack.java
@@ -0,0 +1,338 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+
+package android.speech.tts;
+
+import android.media.AudioFormat;
+import android.media.AudioTrack;
+import android.util.Log;
+
+/**
+ * Exposes parts of the {@link AudioTrack} API by delegating calls to an
+ * underlying {@link AudioTrack}. Additionally, provides methods like
+ * {@link #waitAndRelease()} that will block until all audiotrack
+ * data has been flushed to the mixer, and is estimated to have completed
+ * playback.
+ */
+class BlockingAudioTrack {
+    private static final String TAG = "TTS.BlockingAudioTrack";
+    private static final boolean DBG = false;
+
+
+    /**
+     * The minimum increment of time to wait for an AudioTrack to finish
+     * playing.
+     */
+    private static final long MIN_SLEEP_TIME_MS = 20;
+
+    /**
+     * The maximum increment of time to sleep while waiting for an AudioTrack
+     * to finish playing.
+     */
+    private static final long MAX_SLEEP_TIME_MS = 2500;
+
+    /**
+     * The maximum amount of time to wait for an audio track to make progress while
+     * it remains in PLAYSTATE_PLAYING. This should never happen in normal usage, but
+     * could happen in exceptional circumstances like a media_server crash.
+     */
+    private static final long MAX_PROGRESS_WAIT_MS = MAX_SLEEP_TIME_MS;
+
+    /**
+     * Minimum size of the buffer of the underlying {@link android.media.AudioTrack}
+     * we create.
+     */
+    private static final int MIN_AUDIO_BUFFER_SIZE = 8192;
+
+
+    private final int mStreamType;
+    private final int mSampleRateInHz;
+    private final int mAudioFormat;
+    private final int mChannelCount;
+    private final float mVolume;
+    private final float mPan;
+
+    private final int mBytesPerFrame;
+    /**
+     * A "short utterance" is one that uses less bytes than the audio
+     * track buffer size (mAudioBufferSize). In this case, we need to call
+     * {@link AudioTrack#stop()} to send pending buffers to the mixer, and slightly
+     * different logic is required to wait for the track to finish.
+     *
+     * Not volatile, accessed only from the audio playback thread.
+     */
+    private boolean mIsShortUtterance;
+    /**
+     * Will be valid after a call to {@link #init()}.
+     */
+    private int mAudioBufferSize;
+    private int mBytesWritten = 0;
+
+    private AudioTrack mAudioTrack;
+    private volatile boolean mStopped;
+    // Locks the initialization / uninitialization of the audio track.
+    // This is required because stop() will throw an illegal state exception
+    // if called before init() or after mAudioTrack.release().
+    private final Object mAudioTrackLock = new Object();
+
+    BlockingAudioTrack(int streamType, int sampleRate,
+            int audioFormat, int channelCount,
+            float volume, float pan) {
+        mStreamType = streamType;
+        mSampleRateInHz = sampleRate;
+        mAudioFormat = audioFormat;
+        mChannelCount = channelCount;
+        mVolume = volume;
+        mPan = pan;
+
+        mBytesPerFrame = getBytesPerFrame(mAudioFormat) * mChannelCount;
+        mIsShortUtterance = false;
+        mAudioBufferSize = 0;
+        mBytesWritten = 0;
+
+        mAudioTrack = null;
+        mStopped = false;
+    }
+
+    public void init() {
+        AudioTrack track = createStreamingAudioTrack();
+
+        synchronized (mAudioTrackLock) {
+            mAudioTrack = track;
+        }
+    }
+
+    public void stop() {
+        synchronized (mAudioTrackLock) {
+            if (mAudioTrack != null) {
+                mAudioTrack.stop();
+            }
+        }
+        mStopped = true;
+    }
+
+    public int write(byte[] data) {
+        if (mAudioTrack == null || mStopped) {
+            return -1;
+        }
+        final int bytesWritten = writeToAudioTrack(mAudioTrack, data);
+        mBytesWritten += bytesWritten;
+        return bytesWritten;
+    }
+
+    public void waitAndRelease() {
+        // For "small" audio tracks, we have to stop() them to make them mixable,
+        // else the audio subsystem will wait indefinitely for us to fill the buffer
+        // before rendering the track mixable.
+        //
+        // If mStopped is true, the track would already have been stopped, so not
+        // much point not doing that again.
+        if (mBytesWritten < mAudioBufferSize && !mStopped) {
+            if (DBG) {
+                Log.d(TAG, "Stopping audio track to flush audio, state was : " +
+                        mAudioTrack.getPlayState() + ",stopped= " + mStopped);
+            }
+
+            mIsShortUtterance = true;
+            mAudioTrack.stop();
+        }
+
+        // Block until the audio track is done only if we haven't stopped yet.
+        if (!mStopped) {
+            if (DBG) Log.d(TAG, "Waiting for audio track to complete : " + mAudioTrack.hashCode());
+            blockUntilDone(mAudioTrack);
+        }
+
+        // The last call to AudioTrack.write( ) will return only after
+        // all data from the audioTrack has been sent to the mixer, so
+        // it's safe to release at this point.
+        if (DBG) Log.d(TAG, "Releasing audio track [" + mAudioTrack.hashCode() + "]");
+        synchronized (mAudioTrackLock) {
+            mAudioTrack.release();
+            mAudioTrack = null;
+        }
+    }
+
+
+    static int getChannelConfig(int channelCount) {
+        if (channelCount == 1) {
+            return AudioFormat.CHANNEL_OUT_MONO;
+        } else if (channelCount == 2){
+            return AudioFormat.CHANNEL_OUT_STEREO;
+        }
+
+        return 0;
+    }
+
+    long getAudioLengthMs(int numBytes) {
+        final int unconsumedFrames = numBytes / mBytesPerFrame;
+        final long estimatedTimeMs = unconsumedFrames * 1000 / mSampleRateInHz;
+
+        return estimatedTimeMs;
+    }
+
+    private static int writeToAudioTrack(AudioTrack audioTrack, byte[] bytes) {
+        if (audioTrack.getPlayState() != AudioTrack.PLAYSTATE_PLAYING) {
+            if (DBG) Log.d(TAG, "AudioTrack not playing, restarting : " + audioTrack.hashCode());
+            audioTrack.play();
+        }
+
+        int count = 0;
+        while (count < bytes.length) {
+            // Note that we don't take bufferCopy.mOffset into account because
+            // it is guaranteed to be 0.
+            int written = audioTrack.write(bytes, count, bytes.length);
+            if (written <= 0) {
+                break;
+            }
+            count += written;
+        }
+        return count;
+    }
+
+    private AudioTrack createStreamingAudioTrack() {
+        final int channelConfig = getChannelConfig(mChannelCount);
+
+        int minBufferSizeInBytes
+                = AudioTrack.getMinBufferSize(mSampleRateInHz, channelConfig, mAudioFormat);
+        int bufferSizeInBytes = Math.max(MIN_AUDIO_BUFFER_SIZE, minBufferSizeInBytes);
+
+        AudioTrack audioTrack = new AudioTrack(mStreamType, mSampleRateInHz, channelConfig,
+                mAudioFormat, bufferSizeInBytes, AudioTrack.MODE_STREAM);
+        if (audioTrack.getState() != AudioTrack.STATE_INITIALIZED) {
+            Log.w(TAG, "Unable to create audio track.");
+            audioTrack.release();
+            return null;
+        }
+
+        mAudioBufferSize = bufferSizeInBytes;
+
+        setupVolume(audioTrack, mVolume, mPan);
+        return audioTrack;
+    }
+
+    private static int getBytesPerFrame(int audioFormat) {
+        if (audioFormat == AudioFormat.ENCODING_PCM_8BIT) {
+            return 1;
+        } else if (audioFormat == AudioFormat.ENCODING_PCM_16BIT) {
+            return 2;
+        }
+
+        return -1;
+    }
+
+
+    private void blockUntilDone(AudioTrack audioTrack) {
+        if (mBytesWritten <= 0) {
+            return;
+        }
+
+        if (mIsShortUtterance) {
+            // In this case we would have called AudioTrack#stop() to flush
+            // buffers to the mixer. This makes the playback head position
+            // unobservable and notification markers do not work reliably. We
+            // have no option but to wait until we think the track would finish
+            // playing and release it after.
+            //
+            // This isn't as bad as it looks because (a) We won't end up waiting
+            // for much longer than we should because even at 4khz mono, a short
+            // utterance weighs in at about 2 seconds, and (b) such short utterances
+            // are expected to be relatively infrequent and in a stream of utterances
+            // this shows up as a slightly longer pause.
+            blockUntilEstimatedCompletion();
+        } else {
+            blockUntilCompletion(audioTrack);
+        }
+    }
+
+    private void blockUntilEstimatedCompletion() {
+        final int lengthInFrames = mBytesWritten / mBytesPerFrame;
+        final long estimatedTimeMs = (lengthInFrames * 1000 / mSampleRateInHz);
+
+        if (DBG) Log.d(TAG, "About to sleep for: " + estimatedTimeMs + "ms for a short utterance");
+
+        try {
+            Thread.sleep(estimatedTimeMs);
+        } catch (InterruptedException ie) {
+            // Do nothing.
+        }
+    }
+
+    private void blockUntilCompletion(AudioTrack audioTrack) {
+        final int lengthInFrames = mBytesWritten / mBytesPerFrame;
+
+        int previousPosition = -1;
+        int currentPosition = 0;
+        long blockedTimeMs = 0;
+
+        while ((currentPosition = audioTrack.getPlaybackHeadPosition()) < lengthInFrames &&
+                audioTrack.getPlayState() == AudioTrack.PLAYSTATE_PLAYING && !mStopped) {
+
+            final long estimatedTimeMs = ((lengthInFrames - currentPosition) * 1000) /
+                    audioTrack.getSampleRate();
+            final long sleepTimeMs = clip(estimatedTimeMs, MIN_SLEEP_TIME_MS, MAX_SLEEP_TIME_MS);
+
+            // Check if the audio track has made progress since the last loop
+            // iteration. We should then add in the amount of time that was
+            // spent sleeping in the last iteration.
+            if (currentPosition == previousPosition) {
+                // This works only because the sleep time that would have been calculated
+                // would be the same in the previous iteration too.
+                blockedTimeMs += sleepTimeMs;
+                // If we've taken too long to make progress, bail.
+                if (blockedTimeMs > MAX_PROGRESS_WAIT_MS) {
+                    Log.w(TAG, "Waited unsuccessfully for " + MAX_PROGRESS_WAIT_MS + "ms " +
+                            "for AudioTrack to make progress, Aborting");
+                    break;
+                }
+            } else {
+                blockedTimeMs = 0;
+            }
+            previousPosition = currentPosition;
+
+            if (DBG) {
+                Log.d(TAG, "About to sleep for : " + sleepTimeMs + " ms," +
+                        " Playback position : " + currentPosition + ", Length in frames : "
+                        + lengthInFrames);
+            }
+            try {
+                Thread.sleep(sleepTimeMs);
+            } catch (InterruptedException ie) {
+                break;
+            }
+        }
+    }
+
+    private static void setupVolume(AudioTrack audioTrack, float volume, float pan) {
+        final float vol = clip(volume, 0.0f, 1.0f);
+        final float panning = clip(pan, -1.0f, 1.0f);
+
+        float volLeft = vol;
+        float volRight = vol;
+        if (panning > 0.0f) {
+            volLeft *= (1.0f - panning);
+        } else if (panning < 0.0f) {
+            volRight *= (1.0f + panning);
+        }
+        if (DBG) Log.d(TAG, "volLeft=" + volLeft + ",volRight=" + volRight);
+        if (audioTrack.setStereoVolume(volLeft, volRight) != AudioTrack.SUCCESS) {
+            Log.e(TAG, "Failed to set volume");
+        }
+    }
+
+    private static final long clip(long value, long min, long max) {
+        if (value < min) {
+            return min;
+        }
+
+        if (value > max) {
+            return max;
+        }
+
+        return value;
+    }
+
+    private static float clip(float value, float min, float max) {
+        return value > max ? max : (value < min ? min : value);
+    }
+
+}
diff --git a/core/java/android/speech/tts/BlockingMediaPlayer.java b/core/java/android/speech/tts/BlockingMediaPlayer.java
deleted file mode 100644
index 3cf60dd..0000000
--- a/core/java/android/speech/tts/BlockingMediaPlayer.java
+++ /dev/null
@@ -1,146 +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.speech.tts;
-
-import android.content.Context;
-import android.media.MediaPlayer;
-import android.net.Uri;
-import android.os.ConditionVariable;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.Looper;
-import android.util.Log;
-
-/**
- * A media player that allows blocking to wait for it to finish.
- */
-class BlockingMediaPlayer {
-
-    private static final String TAG = "BlockMediaPlayer";
-
-    private static final String MEDIA_PLAYER_THREAD_NAME = "TTS-MediaPlayer";
-
-    private final Context mContext;
-    private final Uri mUri;
-    private final int mStreamType;
-    private final ConditionVariable mDone;
-    // Only accessed on the Handler thread
-    private MediaPlayer mPlayer;
-    private volatile boolean mFinished;
-
-    /**
-     * Creates a new blocking media player.
-     * Creating a blocking media player is a cheap operation.
-     *
-     * @param context
-     * @param uri
-     * @param streamType
-     */
-    public BlockingMediaPlayer(Context context, Uri uri, int streamType) {
-        mContext = context;
-        mUri = uri;
-        mStreamType = streamType;
-        mDone = new ConditionVariable();
-
-    }
-
-    /**
-     * Starts playback and waits for it to finish.
-     * Can be called from any thread.
-     *
-     * @return {@code true} if the playback finished normally, {@code false} if the playback
-     *         failed or {@link #stop} was called before the playback finished.
-     */
-    public boolean startAndWait() {
-        HandlerThread thread = new HandlerThread(MEDIA_PLAYER_THREAD_NAME);
-        thread.start();
-        Handler handler = new Handler(thread.getLooper());
-        mFinished = false;
-        handler.post(new Runnable() {
-            @Override
-            public void run() {
-                startPlaying();
-            }
-        });
-        mDone.block();
-        handler.post(new Runnable() {
-            @Override
-            public void run() {
-                finish();
-                // No new messages should get posted to the handler thread after this
-                Looper.myLooper().quit();
-            }
-        });
-        return mFinished;
-    }
-
-    /**
-     * Stops playback. Can be called multiple times.
-     * Can be called from any thread.
-     */
-    public void stop() {
-        mDone.open();
-    }
-
-    /**
-     * Starts playback.
-     * Called on the handler thread.
-     */
-    private void startPlaying() {
-        mPlayer = MediaPlayer.create(mContext, mUri);
-        if (mPlayer == null) {
-            Log.w(TAG, "Failed to play " + mUri);
-            mDone.open();
-            return;
-        }
-        try {
-            mPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
-                @Override
-                public boolean onError(MediaPlayer mp, int what, int extra) {
-                    Log.w(TAG, "Audio playback error: " + what + ", " + extra);
-                    mDone.open();
-                    return true;
-                }
-            });
-            mPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
-                @Override
-                public void onCompletion(MediaPlayer mp) {
-                    mFinished = true;
-                    mDone.open();
-                }
-            });
-            mPlayer.setAudioStreamType(mStreamType);
-            mPlayer.start();
-        } catch (IllegalArgumentException ex) {
-            Log.w(TAG, "MediaPlayer failed", ex);
-            mDone.open();
-        }
-    }
-
-    /**
-     * Stops playback and release the media player.
-     * Called on the handler thread.
-     */
-    private void finish() {
-        try {
-            mPlayer.stop();
-        } catch (IllegalStateException ex) {
-            // Do nothing, the player is already stopped
-        }
-        mPlayer.release();
-    }
-
-}
\ No newline at end of file
diff --git a/core/java/android/speech/tts/EventLogTags.logtags b/core/java/android/speech/tts/EventLogTags.logtags
index 1a9f5fe..f8654ad 100644
--- a/core/java/android/speech/tts/EventLogTags.logtags
+++ b/core/java/android/speech/tts/EventLogTags.logtags
@@ -2,5 +2,5 @@
 
 option java_package android.speech.tts;
 
-76001 tts_speak_success (engine|3),(caller|3),(length|1),(locale|3),(rate|1),(pitch|1),(engine_latency|2|3),(engine_total|2|3),(audio_latency|2|3)
-76002 tts_speak_failure (engine|3),(caller|3),(length|1),(locale|3),(rate|1),(pitch|1)
+76001 tts_speak_success (engine|3),(caller_uid|1),(caller_pid|1),(length|1),(locale|3),(rate|1),(pitch|1),(engine_latency|2|3),(engine_total|2|3),(audio_latency|2|3)
+76002 tts_speak_failure (engine|3),(caller_uid|1),(caller_pid|1),(length|1),(locale|3),(rate|1),(pitch|1)
diff --git a/core/java/android/speech/tts/EventLogger.java b/core/java/android/speech/tts/EventLogger.java
index 63b954b..82ed4dd 100644
--- a/core/java/android/speech/tts/EventLogger.java
+++ b/core/java/android/speech/tts/EventLogger.java
@@ -17,6 +17,7 @@
 
 import android.os.SystemClock;
 import android.text.TextUtils;
+import android.util.Log;
 
 /**
  * Writes data about a given speech synthesis request to the event logs.
@@ -24,14 +25,15 @@
  * speech rate / pitch and the latency and overall time taken.
  *
  * Note that {@link EventLogger#onStopped()} and {@link EventLogger#onError()}
- * might be called from any thread, but on {@link EventLogger#onPlaybackStart()} and
+ * might be called from any thread, but on {@link EventLogger#onAudioDataWritten()} and
  * {@link EventLogger#onComplete()} must be called from a single thread
  * (usually the audio playback thread}
  */
 class EventLogger {
     private final SynthesisRequest mRequest;
-    private final String mCallingApp;
     private final String mServiceApp;
+    private final int mCallerUid;
+    private final int mCallerPid;
     private final long mReceivedTime;
     private long mPlaybackStartTime = -1;
     private volatile long mRequestProcessingStartTime = -1;
@@ -42,10 +44,10 @@
     private volatile boolean mStopped = false;
     private boolean mLogWritten = false;
 
-    EventLogger(SynthesisRequest request, String callingApp,
-            String serviceApp) {
+    EventLogger(SynthesisRequest request, int callerUid, int callerPid, String serviceApp) {
         mRequest = request;
-        mCallingApp = callingApp;
+        mCallerUid = callerUid;
+        mCallerPid = callerPid;
         mServiceApp = serviceApp;
         mReceivedTime = SystemClock.elapsedRealtime();
     }
@@ -80,10 +82,10 @@
     /**
      * Notifies the logger that audio playback has started for some section
      * of the synthesis. This is normally some amount of time after the engine
-     * has synthesized data and varides depending on utterances and
+     * has synthesized data and varies depending on utterances and
      * other audio currently in the queue.
      */
-    public void onPlaybackStart() {
+    public void onAudioDataWritten() {
         // For now, keep track of only the first chunk of audio
         // that was played.
         if (mPlaybackStartTime == -1) {
@@ -119,10 +121,10 @@
         }
 
         long completionTime = SystemClock.elapsedRealtime();
-        // onPlaybackStart() should normally always be called if an
+        // onAudioDataWritten() should normally always be called if an
         // error does not occur.
         if (mError || mPlaybackStartTime == -1 || mEngineCompleteTime == -1) {
-            EventLogTags.writeTtsSpeakFailure(mServiceApp, mCallingApp,
+            EventLogTags.writeTtsSpeakFailure(mServiceApp, mCallerUid, mCallerPid,
                     getUtteranceLength(), getLocaleString(),
                     mRequest.getSpeechRate(), mRequest.getPitch());
             return;
@@ -138,7 +140,8 @@
         final long audioLatency = mPlaybackStartTime - mReceivedTime;
         final long engineLatency = mEngineStartTime - mRequestProcessingStartTime;
         final long engineTotal = mEngineCompleteTime - mRequestProcessingStartTime;
-        EventLogTags.writeTtsSpeakSuccess(mServiceApp, mCallingApp,
+
+        EventLogTags.writeTtsSpeakSuccess(mServiceApp, mCallerUid, mCallerPid,
                 getUtteranceLength(), getLocaleString(),
                 mRequest.getSpeechRate(), mRequest.getPitch(),
                 engineLatency, engineTotal, audioLatency);
diff --git a/core/java/android/speech/tts/ITextToSpeechService.aidl b/core/java/android/speech/tts/ITextToSpeechService.aidl
index 1a8c1fb..ab63187 100644
--- a/core/java/android/speech/tts/ITextToSpeechService.aidl
+++ b/core/java/android/speech/tts/ITextToSpeechService.aidl
@@ -30,47 +30,47 @@
     /**
      * Tells the engine to synthesize some speech and play it back.
      *
-     * @param callingApp The package name of the calling app. Used to connect requests
-     *         callbacks and to clear requests when the calling app is stopping.
+     * @param callingInstance a binder representing the identity of the calling
+     *        TextToSpeech object.
      * @param text The text to synthesize.
      * @param queueMode Determines what to do to requests already in the queue.
      * @param param Request parameters.
      */
-    int speak(in String callingApp, in String text, in int queueMode, in Bundle params);
+    int speak(in IBinder callingInstance, in String text, in int queueMode, in Bundle params);
 
     /**
      * Tells the engine to synthesize some speech and write it to a file.
      *
-     * @param callingApp The package name of the calling app. Used to connect requests
-     *         callbacks and to clear requests when the calling app is stopping.
+     * @param callingInstance a binder representing the identity of the calling
+     *        TextToSpeech object.
      * @param text The text to synthesize.
      * @param filename The file to write the synthesized audio to.
      * @param param Request parameters.
      */
-    int synthesizeToFile(in String callingApp, in String text,
+    int synthesizeToFile(in IBinder callingInstance, in String text,
         in String filename, in Bundle params);
 
     /**
      * Plays an existing audio resource.
      *
-     * @param callingApp The package name of the calling app. Used to connect requests
-     *         callbacks and to clear requests when the calling app is stopping.
+     * @param callingInstance a binder representing the identity of the calling
+     *        TextToSpeech object.
      * @param audioUri URI for the audio resource (a file or android.resource URI)
      * @param queueMode Determines what to do to requests already in the queue.
      * @param param Request parameters.
      */
-    int playAudio(in String callingApp, in Uri audioUri, in int queueMode, in Bundle params);
+    int playAudio(in IBinder callingInstance, in Uri audioUri, in int queueMode, in Bundle params);
 
     /**
      * Plays silence.
      *
-     * @param callingApp The package name of the calling app. Used to connect requests
-     *         callbacks and to clear requests when the calling app is stopping.
+     * @param callingInstance a binder representing the identity of the calling
+     *        TextToSpeech object.
      * @param duration Number of milliseconds of silence to play.
      * @param queueMode Determines what to do to requests already in the queue.
      * @param param Request parameters.
      */
-    int playSilence(in String callingApp, in long duration, in int queueMode, in Bundle params);
+    int playSilence(in IBinder callingInstance, in long duration, in int queueMode, in Bundle params);
 
     /**
      * Checks whether the service is currently playing some audio.
@@ -81,10 +81,10 @@
      * Interrupts the current utterance (if from the given app) and removes any utterances
      * in the queue that are from the given app.
      *
-     * @param callingApp Package name of the app whose utterances
-     *        should be interrupted and cleared.
+     * @param callingInstance a binder representing the identity of the calling
+     *        TextToSpeech object.
      */
-    int stop(in String callingApp);
+    int stop(in IBinder callingInstance);
 
     /**
      * Returns the language, country and variant currently being used by the TTS engine.
@@ -150,6 +150,6 @@
      * @param callingApp Package name for the app whose utterance the callback will handle.
      * @param cb The callback.
      */
-    void setCallback(in String callingApp, ITextToSpeechCallback cb);
+    void setCallback(in IBinder caller, ITextToSpeechCallback cb);
 
 }
diff --git a/core/java/android/speech/tts/MessageParams.java b/core/java/android/speech/tts/MessageParams.java
deleted file mode 100644
index de9cc07..0000000
--- a/core/java/android/speech/tts/MessageParams.java
+++ /dev/null
@@ -1,47 +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.speech.tts;
-
-import android.speech.tts.TextToSpeechService.UtteranceProgressDispatcher;
-
-abstract class MessageParams {
-    static final int TYPE_SYNTHESIS = 1;
-    static final int TYPE_AUDIO = 2;
-    static final int TYPE_SILENCE = 3;
-
-    private final UtteranceProgressDispatcher mDispatcher;
-    private final String mCallingApp;
-
-    MessageParams(UtteranceProgressDispatcher dispatcher, String callingApp) {
-        mDispatcher = dispatcher;
-        mCallingApp = callingApp;
-    }
-
-    UtteranceProgressDispatcher getDispatcher() {
-        return mDispatcher;
-    }
-
-    String getCallingApp() {
-        return mCallingApp;
-    }
-
-    @Override
-    public String toString() {
-        return "MessageParams[" + hashCode() + "]";
-    }
-
-    abstract int getType();
-}
diff --git a/core/java/android/speech/tts/PlaybackQueueItem.java b/core/java/android/speech/tts/PlaybackQueueItem.java
new file mode 100644
index 0000000..d0957ff
--- /dev/null
+++ b/core/java/android/speech/tts/PlaybackQueueItem.java
@@ -0,0 +1,27 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+
+package android.speech.tts;
+
+import android.speech.tts.TextToSpeechService.UtteranceProgressDispatcher;
+
+abstract class PlaybackQueueItem implements Runnable {
+    private final UtteranceProgressDispatcher mDispatcher;
+    private final Object mCallerIdentity;
+
+    PlaybackQueueItem(TextToSpeechService.UtteranceProgressDispatcher dispatcher,
+            Object callerIdentity) {
+        mDispatcher = dispatcher;
+        mCallerIdentity = callerIdentity;
+    }
+
+    Object getCallerIdentity() {
+        return mCallerIdentity;
+    }
+
+    protected UtteranceProgressDispatcher getDispatcher() {
+        return mDispatcher;
+    }
+
+    public abstract void run();
+    abstract void stop(boolean isError);
+}
diff --git a/core/java/android/speech/tts/PlaybackSynthesisCallback.java b/core/java/android/speech/tts/PlaybackSynthesisCallback.java
index ce3522b..c99f201 100644
--- a/core/java/android/speech/tts/PlaybackSynthesisCallback.java
+++ b/core/java/android/speech/tts/PlaybackSynthesisCallback.java
@@ -47,69 +47,77 @@
     private final float mPan;
 
     /**
-     * Guards {@link #mAudioTrackHandler}, {@link #mToken} and {@link #mStopped}.
+     * Guards {@link #mAudioTrackHandler}, {@link #mItem} and {@link #mStopped}.
      */
     private final Object mStateLock = new Object();
 
     // Handler associated with a thread that plays back audio requests.
     private final AudioPlaybackHandler mAudioTrackHandler;
     // A request "token", which will be non null after start() has been called.
-    private SynthesisMessageParams mToken = null;
+    private SynthesisPlaybackQueueItem mItem = null;
     // Whether this request has been stopped. This is useful for keeping
     // track whether stop() has been called before start(). In all other cases,
-    // a non-null value of mToken will provide the same information.
+    // a non-null value of mItem will provide the same information.
     private boolean mStopped = false;
 
     private volatile boolean mDone = false;
 
     private final UtteranceProgressDispatcher mDispatcher;
-    private final String mCallingApp;
+    private final Object mCallerIdentity;
     private final EventLogger mLogger;
 
     PlaybackSynthesisCallback(int streamType, float volume, float pan,
             AudioPlaybackHandler audioTrackHandler, UtteranceProgressDispatcher dispatcher,
-            String callingApp, EventLogger logger) {
+            Object callerIdentity, EventLogger logger) {
         mStreamType = streamType;
         mVolume = volume;
         mPan = pan;
         mAudioTrackHandler = audioTrackHandler;
         mDispatcher = dispatcher;
-        mCallingApp = callingApp;
+        mCallerIdentity = callerIdentity;
         mLogger = logger;
     }
 
     @Override
     void stop() {
+        stopImpl(false);
+    }
+
+    void stopImpl(boolean wasError) {
         if (DBG) Log.d(TAG, "stop()");
 
         // Note that mLogger.mError might be true too at this point.
         mLogger.onStopped();
 
-        SynthesisMessageParams token = null;
+        SynthesisPlaybackQueueItem item;
         synchronized (mStateLock) {
             if (mStopped) {
                 Log.w(TAG, "stop() called twice");
                 return;
             }
 
-            // mToken will be null if the engine encounters
-            // an error before it called start().
-            if (mToken == null) {
-                // In all other cases, mAudioTrackHandler.stop() will
-                // result in onComplete being called.
-                mLogger.onWriteData();
-            } else {
-                token = mToken;
-            }
+            item = mItem;
             mStopped = true;
         }
 
-        if (token != null) {
+        if (item != null) {
             // This might result in the synthesis thread being woken up, at which
-            // point it will write an additional buffer to the token - but we
+            // point it will write an additional buffer to the item - but we
             // won't worry about that because the audio playback queue will be cleared
             // soon after (see SynthHandler#stop(String).
-            token.clearBuffers();
+            item.stop(wasError);
+        } else {
+            // This happens when stop() or error() were called before start() was.
+
+            // In all other cases, mAudioTrackHandler.stop() will
+            // result in onSynthesisDone being called, and we will
+            // write data there.
+            mLogger.onWriteData();
+
+            if (wasError) {
+                // We have to dispatch the error ourselves.
+                mDispatcher.dispatchOnError();
+            }
         }
     }
 
@@ -132,7 +140,7 @@
                     + "," + channelCount + ")");
         }
 
-        int channelConfig = AudioPlaybackHandler.getChannelConfig(channelCount);
+        int channelConfig = BlockingAudioTrack.getChannelConfig(channelCount);
         if (channelConfig == 0) {
             Log.e(TAG, "Unsupported number of channels :" + channelCount);
             return TextToSpeech.ERROR;
@@ -143,12 +151,11 @@
                 if (DBG) Log.d(TAG, "stop() called before start(), returning.");
                 return TextToSpeech.ERROR;
             }
-            SynthesisMessageParams params = new SynthesisMessageParams(
+            SynthesisPlaybackQueueItem item = new SynthesisPlaybackQueueItem(
                     mStreamType, sampleRateInHz, audioFormat, channelCount, mVolume, mPan,
-                    mDispatcher, mCallingApp, mLogger);
-            mAudioTrackHandler.enqueueSynthesisStart(params);
-
-            mToken = params;
+                    mDispatcher, mCallerIdentity, mLogger);
+            mAudioTrackHandler.enqueue(item);
+            mItem = item;
         }
 
         return TextToSpeech.SUCCESS;
@@ -166,21 +173,25 @@
                     + length + " bytes)");
         }
 
-        SynthesisMessageParams token = null;
+        SynthesisPlaybackQueueItem item = null;
         synchronized (mStateLock) {
-            if (mToken == null || mStopped) {
+            if (mItem == null || mStopped) {
                 return TextToSpeech.ERROR;
             }
-            token = mToken;
+            item = mItem;
         }
 
         // Sigh, another copy.
         final byte[] bufferCopy = new byte[length];
         System.arraycopy(buffer, offset, bufferCopy, 0, length);
-        // Might block on mToken.this, if there are too many buffers waiting to
+
+        // Might block on mItem.this, if there are too many buffers waiting to
         // be consumed.
-        token.addBuffer(bufferCopy);
-        mAudioTrackHandler.enqueueSynthesisDataAvailable(token);
+        try {
+            item.put(bufferCopy);
+        } catch (InterruptedException ie) {
+            return TextToSpeech.ERROR;
+        }
 
         mLogger.onEngineDataReceived();
 
@@ -191,7 +202,7 @@
     public int done() {
         if (DBG) Log.d(TAG, "done()");
 
-        SynthesisMessageParams token = null;
+        SynthesisPlaybackQueueItem item = null;
         synchronized (mStateLock) {
             if (mDone) {
                 Log.w(TAG, "Duplicate call to done()");
@@ -200,14 +211,14 @@
 
             mDone = true;
 
-            if (mToken == null) {
+            if (mItem == null) {
                 return TextToSpeech.ERROR;
             }
 
-            token = mToken;
+            item = mItem;
         }
 
-        mAudioTrackHandler.enqueueSynthesisDone(token);
+        item.done();
         mLogger.onEngineComplete();
 
         return TextToSpeech.SUCCESS;
@@ -219,7 +230,7 @@
         // Currently, this call will not be logged if error( ) is called
         // before start.
         mLogger.onError();
-        stop();
+        stopImpl(true);
     }
 
 }
diff --git a/core/java/android/speech/tts/SilenceMessageParams.java b/core/java/android/speech/tts/SilencePlaybackQueueItem.java
similarity index 64%
rename from core/java/android/speech/tts/SilenceMessageParams.java
rename to core/java/android/speech/tts/SilencePlaybackQueueItem.java
index 9909126..a5e47ae 100644
--- a/core/java/android/speech/tts/SilenceMessageParams.java
+++ b/core/java/android/speech/tts/SilencePlaybackQueueItem.java
@@ -17,28 +17,29 @@
 
 import android.os.ConditionVariable;
 import android.speech.tts.TextToSpeechService.UtteranceProgressDispatcher;
+import android.util.Log;
 
-class SilenceMessageParams extends MessageParams {
+class SilencePlaybackQueueItem extends PlaybackQueueItem {
     private final ConditionVariable mCondVar = new ConditionVariable();
     private final long mSilenceDurationMs;
 
-    SilenceMessageParams(UtteranceProgressDispatcher dispatcher,
-            String callingApp, long silenceDurationMs) {
-        super(dispatcher, callingApp);
+    SilencePlaybackQueueItem(UtteranceProgressDispatcher dispatcher,
+            Object callerIdentity, long silenceDurationMs) {
+        super(dispatcher, callerIdentity);
         mSilenceDurationMs = silenceDurationMs;
     }
 
-    long getSilenceDurationMs() {
-        return mSilenceDurationMs;
+    @Override
+    public void run() {
+        getDispatcher().dispatchOnStart();
+        if (mSilenceDurationMs > 0) {
+            mCondVar.block(mSilenceDurationMs);
+        }
+        getDispatcher().dispatchOnDone();
     }
 
     @Override
-    int getType() {
-        return TYPE_SILENCE;
+    void stop(boolean isError) {
+        mCondVar.open();
     }
-
-    ConditionVariable getConditionVariable() {
-        return mCondVar;
-    }
-
 }
diff --git a/core/java/android/speech/tts/SynthesisMessageParams.java b/core/java/android/speech/tts/SynthesisMessageParams.java
deleted file mode 100644
index 0c0f033..0000000
--- a/core/java/android/speech/tts/SynthesisMessageParams.java
+++ /dev/null
@@ -1,149 +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.speech.tts;
-
-import android.media.AudioFormat;
-import android.media.AudioTrack;
-import android.speech.tts.TextToSpeechService.UtteranceProgressDispatcher;
-
-import java.util.LinkedList;
-
-/**
- * Params required to play back a synthesis request.
- */
-final class SynthesisMessageParams extends MessageParams {
-    private static final long MAX_UNCONSUMED_AUDIO_MS = 500;
-
-    final int mStreamType;
-    final int mSampleRateInHz;
-    final int mAudioFormat;
-    final int mChannelCount;
-    final float mVolume;
-    final float mPan;
-    final EventLogger mLogger;
-
-    final int mBytesPerFrame;
-
-    volatile AudioTrack mAudioTrack;
-    // Written by the synthesis thread, but read on the audio playback
-    // thread.
-    volatile int mBytesWritten;
-    // A "short utterance" is one that uses less bytes than the audio
-    // track buffer size (mAudioBufferSize). In this case, we need to call
-    // AudioTrack#stop() to send pending buffers to the mixer, and slightly
-    // different logic is required to wait for the track to finish.
-    //
-    // Not volatile, accessed only from the audio playback thread.
-    boolean mIsShortUtterance;
-    int mAudioBufferSize;
-    // Always synchronized on "this".
-    int mUnconsumedBytes;
-
-    private final LinkedList<ListEntry> mDataBufferList = new LinkedList<ListEntry>();
-
-    SynthesisMessageParams(int streamType, int sampleRate,
-            int audioFormat, int channelCount,
-            float volume, float pan, UtteranceProgressDispatcher dispatcher,
-            String callingApp, EventLogger logger) {
-        super(dispatcher, callingApp);
-
-        mStreamType = streamType;
-        mSampleRateInHz = sampleRate;
-        mAudioFormat = audioFormat;
-        mChannelCount = channelCount;
-        mVolume = volume;
-        mPan = pan;
-        mLogger = logger;
-
-        mBytesPerFrame = getBytesPerFrame(mAudioFormat) * mChannelCount;
-
-        // initially null.
-        mAudioTrack = null;
-        mBytesWritten = 0;
-        mAudioBufferSize = 0;
-    }
-
-    @Override
-    int getType() {
-        return TYPE_SYNTHESIS;
-    }
-
-    synchronized void addBuffer(byte[] buffer) {
-        long unconsumedAudioMs = 0;
-
-        while ((unconsumedAudioMs = getUnconsumedAudioLengthMs()) > MAX_UNCONSUMED_AUDIO_MS) {
-            try {
-                wait();
-            } catch (InterruptedException ie) {
-                return;
-            }
-        }
-
-        mDataBufferList.add(new ListEntry(buffer));
-        mUnconsumedBytes += buffer.length;
-    }
-
-    synchronized void clearBuffers() {
-        mDataBufferList.clear();
-        mUnconsumedBytes = 0;
-        notifyAll();
-    }
-
-    synchronized ListEntry getNextBuffer() {
-        ListEntry entry = mDataBufferList.poll();
-        if (entry != null) {
-            mUnconsumedBytes -= entry.mBytes.length;
-            notifyAll();
-        }
-
-        return entry;
-    }
-
-    void setAudioTrack(AudioTrack audioTrack) {
-        mAudioTrack = audioTrack;
-    }
-
-    AudioTrack getAudioTrack() {
-        return mAudioTrack;
-    }
-
-    // Must be called synchronized on this.
-    private long getUnconsumedAudioLengthMs() {
-        final int unconsumedFrames = mUnconsumedBytes / mBytesPerFrame;
-        final long estimatedTimeMs = unconsumedFrames * 1000 / mSampleRateInHz;
-
-        return estimatedTimeMs;
-    }
-
-    private static int getBytesPerFrame(int audioFormat) {
-        if (audioFormat == AudioFormat.ENCODING_PCM_8BIT) {
-            return 1;
-        } else if (audioFormat == AudioFormat.ENCODING_PCM_16BIT) {
-            return 2;
-        }
-
-        return -1;
-    }
-
-    static final class ListEntry {
-        final byte[] mBytes;
-
-        ListEntry(byte[] bytes) {
-            mBytes = bytes;
-        }
-    }
-}
-
diff --git a/core/java/android/speech/tts/SynthesisPlaybackQueueItem.java b/core/java/android/speech/tts/SynthesisPlaybackQueueItem.java
new file mode 100644
index 0000000..d299d70
--- /dev/null
+++ b/core/java/android/speech/tts/SynthesisPlaybackQueueItem.java
@@ -0,0 +1,245 @@
+/*
+ * 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.speech.tts;
+
+import android.speech.tts.TextToSpeechService.UtteranceProgressDispatcher;
+import android.util.Log;
+
+import java.util.LinkedList;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+/**
+ * Manages the playback of a list of byte arrays representing audio data
+ * that are queued by the engine to an audio track.
+ */
+final class SynthesisPlaybackQueueItem extends PlaybackQueueItem {
+    private static final String TAG = "TTS.SynthQueueItem";
+    private static final boolean DBG = false;
+
+    /**
+     * Maximum length of audio we leave unconsumed by the audio track.
+     * Calls to {@link #put(byte[])} will block until we have less than
+     * this amount of audio left to play back.
+     */
+    private static final long MAX_UNCONSUMED_AUDIO_MS = 500;
+
+    /**
+     * Guards accesses to mDataBufferList and mUnconsumedBytes.
+     */
+    private final Lock mListLock = new ReentrantLock();
+    private final Condition mReadReady = mListLock.newCondition();
+    private final Condition mNotFull = mListLock.newCondition();
+
+    // Guarded by mListLock.
+    private final LinkedList<ListEntry> mDataBufferList = new LinkedList<ListEntry>();
+    // Guarded by mListLock.
+    private int mUnconsumedBytes;
+
+    /*
+     * While mStopped and mIsError can be written from any thread, mDone is written
+     * only from the synthesis thread. All three variables are read from the
+     * audio playback thread.
+     */
+    private volatile boolean mStopped;
+    private volatile boolean mDone;
+    private volatile boolean mIsError;
+
+    private final BlockingAudioTrack mAudioTrack;
+    private final EventLogger mLogger;
+
+
+    SynthesisPlaybackQueueItem(int streamType, int sampleRate,
+            int audioFormat, int channelCount,
+            float volume, float pan, UtteranceProgressDispatcher dispatcher,
+            Object callerIdentity, EventLogger logger) {
+        super(dispatcher, callerIdentity);
+
+        mUnconsumedBytes = 0;
+
+        mStopped = false;
+        mDone = false;
+        mIsError = false;
+
+        mAudioTrack = new BlockingAudioTrack(streamType, sampleRate, audioFormat,
+                channelCount, volume, pan);
+        mLogger = logger;
+    }
+
+
+    @Override
+    public void run() {
+        final UtteranceProgressDispatcher dispatcher = getDispatcher();
+        dispatcher.dispatchOnStart();
+
+
+        mAudioTrack.init();
+
+        try {
+            byte[] buffer = null;
+
+            // take() will block until:
+            //
+            // (a) there is a buffer available to tread. In which case
+            // a non null value is returned.
+            // OR (b) stop() is called in which case it will return null.
+            // OR (c) done() is called in which case it will return null.
+            while ((buffer = take()) != null) {
+                mAudioTrack.write(buffer);
+                mLogger.onAudioDataWritten();
+            }
+
+        } catch (InterruptedException ie) {
+            if (DBG) Log.d(TAG, "Interrupted waiting for buffers, cleaning up.");
+        }
+
+        mAudioTrack.waitAndRelease();
+
+        if (mIsError) {
+            dispatcher.dispatchOnError();
+        } else {
+            dispatcher.dispatchOnDone();
+        }
+
+        mLogger.onWriteData();
+    }
+
+    @Override
+    void stop(boolean isError) {
+        try {
+            mListLock.lock();
+
+            // Update our internal state.
+            mStopped = true;
+            mIsError = isError;
+
+            // Wake up the audio playback thread if it was waiting on take().
+            // take() will return null since mStopped was true, and will then
+            // break out of the data write loop.
+            mReadReady.signal();
+
+            // Wake up the synthesis thread if it was waiting on put(). Its
+            // buffers will no longer be copied since mStopped is true. The
+            // PlaybackSynthesisCallback that this synthesis corresponds to
+            // would also have been stopped, and so all calls to
+            // Callback.onDataAvailable( ) will return errors too.
+            mNotFull.signal();
+        } finally {
+            mListLock.unlock();
+        }
+
+        // Stop the underlying audio track. This will stop sending
+        // data to the mixer and discard any pending buffers that the
+        // track holds.
+        mAudioTrack.stop();
+    }
+
+    void done() {
+        try {
+            mListLock.lock();
+
+            // Update state.
+            mDone = true;
+
+            // Unblocks the audio playback thread if it was waiting on take()
+            // after having consumed all available buffers. It will then return
+            // null and leave the write loop.
+            mReadReady.signal();
+
+            // Just so that engines that try to queue buffers after
+            // calling done() don't block the synthesis thread forever. Ideally
+            // this should be called from the same thread as put() is, and hence
+            // this call should be pointless.
+            mNotFull.signal();
+        } finally {
+            mListLock.unlock();
+        }
+    }
+
+
+    void put(byte[] buffer) throws InterruptedException {
+        try {
+            mListLock.lock();
+            long unconsumedAudioMs = 0;
+
+            while ((unconsumedAudioMs = mAudioTrack.getAudioLengthMs(mUnconsumedBytes)) >
+                    MAX_UNCONSUMED_AUDIO_MS && !mStopped) {
+                mNotFull.await();
+            }
+
+            // Don't bother queueing the buffer if we've stopped. The playback thread
+            // would have woken up when stop() is called (if it was blocked) and will
+            // proceed to leave the write loop since take() will return null when
+            // stopped.
+            if (mStopped) {
+                return;
+            }
+
+            mDataBufferList.add(new ListEntry(buffer));
+            mUnconsumedBytes += buffer.length;
+            mReadReady.signal();
+        } finally {
+            mListLock.unlock();
+        }
+    }
+
+    private byte[] take() throws InterruptedException {
+        try {
+            mListLock.lock();
+
+            // Block if there are no available buffers, and stop() has not
+            // been called and done() has not been called.
+            while (mDataBufferList.size() == 0 && !mStopped && !mDone) {
+                mReadReady.await();
+            }
+
+            // If stopped, return null so that we can exit the playback loop
+            // as soon as possible.
+            if (mStopped) {
+                return null;
+            }
+
+            // Remove the first entry from the queue.
+            ListEntry entry = mDataBufferList.poll();
+
+            // This is the normal playback loop exit case, when done() was
+            // called. (mDone will be true at this point).
+            if (entry == null) {
+                return null;
+            }
+
+            mUnconsumedBytes -= entry.mBytes.length;
+            // Unblock the waiting writer. We use signal() and not signalAll()
+            // because there will only be one thread waiting on this (the
+            // Synthesis thread).
+            mNotFull.signal();
+
+            return entry.mBytes;
+        } finally {
+            mListLock.unlock();
+        }
+    }
+
+    static final class ListEntry {
+        final byte[] mBytes;
+
+        ListEntry(byte[] bytes) {
+            mBytes = bytes;
+        }
+    }
+}
+
diff --git a/core/java/android/speech/tts/TextToSpeech.java b/core/java/android/speech/tts/TextToSpeech.java
index 38699ea..cd065ec 100755
--- a/core/java/android/speech/tts/TextToSpeech.java
+++ b/core/java/android/speech/tts/TextToSpeech.java
@@ -490,6 +490,7 @@
     private final Map<String, Uri> mUtterances;
     private final Bundle mParams = new Bundle();
     private final TtsEngines mEnginesHelper;
+    private final String mPackageName;
     private volatile String mCurrentEngine = null;
 
     /**
@@ -518,21 +519,34 @@
      * @param engine Package name of the TTS engine to use.
      */
     public TextToSpeech(Context context, OnInitListener listener, String engine) {
+        this(context, listener, engine, null);
+    }
+
+    /**
+     * Used by the framework to instantiate TextToSpeech objects with a supplied
+     * package name, instead of using {@link android.content.Context#getPackageName()}
+     *
+     * @hide
+     */
+    public TextToSpeech(Context context, OnInitListener listener, String engine,
+            String packageName) {
         mContext = context;
         mInitListener = listener;
         mRequestedEngine = engine;
 
         mEarcons = new HashMap<String, Uri>();
         mUtterances = new HashMap<String, Uri>();
+        mUtteranceProgressListener = null;
 
         mEnginesHelper = new TtsEngines(mContext);
+        if (packageName != null) {
+            mPackageName = packageName;
+        } else {
+            mPackageName = mContext.getPackageName();
+        }
         initTts();
     }
 
-    private String getPackageName() {
-        return mContext.getPackageName();
-    }
-
     private <R> R runActionNoReconnect(Action<R> action, R errorResult, String method) {
         return runAction(action, errorResult, method, false);
     }
@@ -612,6 +626,10 @@
         }
     }
 
+    private IBinder getCallerIdentity() {
+        return mServiceConnection.getCallerIdentity();
+    }
+
     /**
      * Releases the resources used by the TextToSpeech engine.
      * It is good practice for instance to call this method in the onDestroy() method of an Activity
@@ -621,8 +639,8 @@
         runActionNoReconnect(new Action<Void>() {
             @Override
             public Void run(ITextToSpeechService service) throws RemoteException {
-                service.setCallback(getPackageName(), null);
-                service.stop(getPackageName());
+                service.setCallback(getCallerIdentity(), null);
+                service.stop(getCallerIdentity());
                 mServiceConnection.disconnect();
                 // Context#unbindService does not result in a call to
                 // ServiceConnection#onServiceDisconnected. As a result, the
@@ -782,10 +800,10 @@
             public Integer run(ITextToSpeechService service) throws RemoteException {
                 Uri utteranceUri = mUtterances.get(text);
                 if (utteranceUri != null) {
-                    return service.playAudio(getPackageName(), utteranceUri, queueMode,
+                    return service.playAudio(getCallerIdentity(), utteranceUri, queueMode,
                             getParams(params));
                 } else {
-                    return service.speak(getPackageName(), text, queueMode, getParams(params));
+                    return service.speak(getCallerIdentity(), text, queueMode, getParams(params));
                 }
             }
         }, ERROR, "speak");
@@ -818,7 +836,7 @@
                 if (earconUri == null) {
                     return ERROR;
                 }
-                return service.playAudio(getPackageName(), earconUri, queueMode,
+                return service.playAudio(getCallerIdentity(), earconUri, queueMode,
                         getParams(params));
             }
         }, ERROR, "playEarcon");
@@ -845,7 +863,7 @@
         return runAction(new Action<Integer>() {
             @Override
             public Integer run(ITextToSpeechService service) throws RemoteException {
-                return service.playSilence(getPackageName(), durationInMs, queueMode,
+                return service.playSilence(getCallerIdentity(), durationInMs, queueMode,
                         getParams(params));
             }
         }, ERROR, "playSilence");
@@ -908,7 +926,7 @@
         return runAction(new Action<Integer>() {
             @Override
             public Integer run(ITextToSpeechService service) throws RemoteException {
-                return service.stop(getPackageName());
+                return service.stop(getCallerIdentity());
             }
         }, ERROR, "stop");
     }
@@ -1073,7 +1091,7 @@
         return runAction(new Action<Integer>() {
             @Override
             public Integer run(ITextToSpeechService service) throws RemoteException {
-                return service.synthesizeToFile(getPackageName(), text, filename,
+                return service.synthesizeToFile(getCallerIdentity(), text, filename,
                         getParams(params));
             }
         }, ERROR, "synthesizeToFile");
@@ -1257,7 +1275,7 @@
                 mServiceConnection = this;
                 mService = ITextToSpeechService.Stub.asInterface(service);
                 try {
-                    mService.setCallback(getPackageName(), mCallback);
+                    mService.setCallback(getCallerIdentity(), mCallback);
                     dispatchOnInit(SUCCESS);
                 } catch (RemoteException re) {
                     Log.e(TAG, "Error connecting to service, setCallback() failed");
@@ -1266,6 +1284,10 @@
             }
         }
 
+        public IBinder getCallerIdentity() {
+            return mCallback;
+        }
+
         public void onServiceDisconnected(ComponentName name) {
             synchronized(mStartLock) {
                 mService = null;
diff --git a/core/java/android/speech/tts/TextToSpeechService.java b/core/java/android/speech/tts/TextToSpeechService.java
index 39922da..4c1a0af 100644
--- a/core/java/android/speech/tts/TextToSpeechService.java
+++ b/core/java/android/speech/tts/TextToSpeechService.java
@@ -18,6 +18,7 @@
 import android.app.Service;
 import android.content.Intent;
 import android.net.Uri;
+import android.os.Binder;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.HandlerThread;
@@ -272,9 +273,9 @@
             return old;
         }
 
-        private synchronized SpeechItem maybeRemoveCurrentSpeechItem(String callingApp) {
+        private synchronized SpeechItem maybeRemoveCurrentSpeechItem(Object callerIdentity) {
             if (mCurrentSpeechItem != null &&
-                    TextUtils.equals(mCurrentSpeechItem.getCallingApp(), callingApp)) {
+                    mCurrentSpeechItem.getCallerIdentity() == callerIdentity) {
                 SpeechItem current = mCurrentSpeechItem;
                 mCurrentSpeechItem = null;
                 return current;
@@ -311,7 +312,7 @@
             }
 
             if (queueMode == TextToSpeech.QUEUE_FLUSH) {
-                stopForApp(speechItem.getCallingApp());
+                stopForApp(speechItem.getCallerIdentity());
             } else if (queueMode == TextToSpeech.QUEUE_DESTROY) {
                 stopAll();
             }
@@ -328,7 +329,7 @@
             // stopForApp(String).
             //
             // Note that this string is interned, so the == comparison works.
-            msg.obj = speechItem.getCallingApp();
+            msg.obj = speechItem.getCallerIdentity();
             if (sendMessage(msg)) {
                 return TextToSpeech.SUCCESS;
             } else {
@@ -344,12 +345,12 @@
          *
          * Called on a service binder thread.
          */
-        public int stopForApp(String callingApp) {
-            if (TextUtils.isEmpty(callingApp)) {
+        public int stopForApp(Object callerIdentity) {
+            if (callerIdentity == null) {
                 return TextToSpeech.ERROR;
             }
 
-            removeCallbacksAndMessages(callingApp);
+            removeCallbacksAndMessages(callerIdentity);
             // This stops writing data to the file / or publishing
             // items to the audio playback handler.
             //
@@ -357,13 +358,13 @@
             // belongs to the callingApp, else the item will be "orphaned" and
             // not stopped correctly if a stop request comes along for the item
             // from the app it belongs to.
-            SpeechItem current = maybeRemoveCurrentSpeechItem(callingApp);
+            SpeechItem current = maybeRemoveCurrentSpeechItem(callerIdentity);
             if (current != null) {
                 current.stop();
             }
 
             // Remove any enqueued audio too.
-            mAudioPlaybackHandler.removePlaybackItems(callingApp);
+            mAudioPlaybackHandler.stopForApp(callerIdentity);
 
             return TextToSpeech.SUCCESS;
         }
@@ -377,7 +378,7 @@
             // Remove all other items from the queue.
             removeCallbacksAndMessages(null);
             // Remove all pending playback as well.
-            mAudioPlaybackHandler.removeAllItems();
+            mAudioPlaybackHandler.stop();
 
             return TextToSpeech.SUCCESS;
         }
@@ -393,18 +394,22 @@
      * An item in the synth thread queue.
      */
     private abstract class SpeechItem implements UtteranceProgressDispatcher {
-        private final String mCallingApp;
+        private final Object mCallerIdentity;
         protected final Bundle mParams;
+        private final int mCallerUid;
+        private final int mCallerPid;
         private boolean mStarted = false;
         private boolean mStopped = false;
 
-        public SpeechItem(String callingApp, Bundle params) {
-            mCallingApp = callingApp;
+        public SpeechItem(Object caller, int callerUid, int callerPid, Bundle params) {
+            mCallerIdentity = caller;
             mParams = params;
+            mCallerUid = callerUid;
+            mCallerPid = callerPid;
         }
 
-        public String getCallingApp() {
-            return mCallingApp;
+        public Object getCallerIdentity() {
+            return mCallerIdentity;
         }
 
         /**
@@ -450,27 +455,35 @@
         @Override
         public void dispatchOnDone() {
             final String utteranceId = getUtteranceId();
-            if (!TextUtils.isEmpty(utteranceId)) {
-                mCallbacks.dispatchOnDone(getCallingApp(), utteranceId);
+            if (utteranceId != null) {
+                mCallbacks.dispatchOnDone(getCallerIdentity(), utteranceId);
             }
         }
 
         @Override
         public void dispatchOnStart() {
             final String utteranceId = getUtteranceId();
-            if (!TextUtils.isEmpty(utteranceId)) {
-                mCallbacks.dispatchOnStart(getCallingApp(), utteranceId);
+            if (utteranceId != null) {
+                mCallbacks.dispatchOnStart(getCallerIdentity(), utteranceId);
             }
         }
 
         @Override
         public void dispatchOnError() {
             final String utteranceId = getUtteranceId();
-            if (!TextUtils.isEmpty(utteranceId)) {
-                mCallbacks.dispatchOnError(getCallingApp(), utteranceId);
+            if (utteranceId != null) {
+                mCallbacks.dispatchOnError(getCallerIdentity(), utteranceId);
             }
         }
 
+        public int getCallerUid() {
+            return mCallerUid;
+        }
+
+        public int getCallerPid() {
+            return mCallerPid;
+        }
+
         protected synchronized boolean isStopped() {
              return mStopped;
         }
@@ -509,6 +522,7 @@
     }
 
     class SynthesisSpeechItem extends SpeechItem {
+        // Never null.
         private final String mText;
         private final SynthesisRequest mSynthesisRequest;
         private final String[] mDefaultLocale;
@@ -517,13 +531,15 @@
         private AbstractSynthesisCallback mSynthesisCallback;
         private final EventLogger mEventLogger;
 
-        public SynthesisSpeechItem(String callingApp, Bundle params, String text) {
-            super(callingApp, params);
+        public SynthesisSpeechItem(Object callerIdentity, int callerUid, int callerPid,
+                Bundle params, String text) {
+            super(callerIdentity, callerUid, callerPid, params);
             mText = text;
             mSynthesisRequest = new SynthesisRequest(mText, mParams);
             mDefaultLocale = getSettingsLocale();
             setRequestParams(mSynthesisRequest);
-            mEventLogger = new EventLogger(mSynthesisRequest, getCallingApp(), mPackageName);
+            mEventLogger = new EventLogger(mSynthesisRequest, callerUid, callerPid,
+                    mPackageName);
         }
 
         public String getText() {
@@ -532,8 +548,8 @@
 
         @Override
         public boolean isValid() {
-            if (TextUtils.isEmpty(mText)) {
-                Log.w(TAG, "Got empty text");
+            if (mText == null) {
+                Log.wtf(TAG, "Got null text");
                 return false;
             }
             if (mText.length() >= MAX_SPEECH_ITEM_CHAR_LENGTH) {
@@ -562,7 +578,7 @@
 
         protected AbstractSynthesisCallback createSynthesisCallback() {
             return new PlaybackSynthesisCallback(getStreamType(), getVolume(), getPan(),
-                    mAudioPlaybackHandler, this, getCallingApp(), mEventLogger);
+                    mAudioPlaybackHandler, this, getCallerIdentity(), mEventLogger);
         }
 
         private void setRequestParams(SynthesisRequest request) {
@@ -617,9 +633,10 @@
     private class SynthesisToFileSpeechItem extends SynthesisSpeechItem {
         private final File mFile;
 
-        public SynthesisToFileSpeechItem(String callingApp, Bundle params, String text,
+        public SynthesisToFileSpeechItem(Object callerIdentity, int callerUid, int callerPid,
+                Bundle params, String text,
                 File file) {
-            super(callingApp, params, text);
+            super(callerIdentity, callerUid, callerPid, params, text);
             mFile = file;
         }
 
@@ -677,13 +694,12 @@
     }
 
     private class AudioSpeechItem extends SpeechItem {
-
-        private final BlockingMediaPlayer mPlayer;
-        private AudioMessageParams mToken;
-
-        public AudioSpeechItem(String callingApp, Bundle params, Uri uri) {
-            super(callingApp, params);
-            mPlayer = new BlockingMediaPlayer(TextToSpeechService.this, uri, getStreamType());
+        private final AudioPlaybackQueueItem mItem;
+        public AudioSpeechItem(Object callerIdentity, int callerUid, int callerPid,
+                Bundle params, Uri uri) {
+            super(callerIdentity, callerUid, callerPid, params);
+            mItem = new AudioPlaybackQueueItem(this, getCallerIdentity(),
+                    TextToSpeechService.this, uri, getStreamType());
         }
 
         @Override
@@ -693,8 +709,7 @@
 
         @Override
         protected int playImpl() {
-            mToken = new AudioMessageParams(this, getCallingApp(), mPlayer);
-            mAudioPlaybackHandler.enqueueAudio(mToken);
+            mAudioPlaybackHandler.enqueue(mItem);
             return TextToSpeech.SUCCESS;
         }
 
@@ -706,10 +721,10 @@
 
     private class SilenceSpeechItem extends SpeechItem {
         private final long mDuration;
-        private SilenceMessageParams mToken;
 
-        public SilenceSpeechItem(String callingApp, Bundle params, long duration) {
-            super(callingApp, params);
+        public SilenceSpeechItem(Object callerIdentity, int callerUid, int callerPid,
+                Bundle params, long duration) {
+            super(callerIdentity, callerUid, callerPid, params);
             mDuration = duration;
         }
 
@@ -720,14 +735,14 @@
 
         @Override
         protected int playImpl() {
-            mToken = new SilenceMessageParams(this, getCallingApp(), mDuration);
-            mAudioPlaybackHandler.enqueueSilence(mToken);
+            mAudioPlaybackHandler.enqueue(new SilencePlaybackQueueItem(
+                    this, getCallerIdentity(), mDuration));
             return TextToSpeech.SUCCESS;
         }
 
         @Override
         protected void stopImpl() {
-            // Do nothing.
+            // Do nothing, handled by AudioPlaybackHandler#stopForApp
         }
     }
 
@@ -746,58 +761,67 @@
     // NOTE: All calls that are passed in a calling app are interned so that
     // they can be used as message objects (which are tested for equality using ==).
     private final ITextToSpeechService.Stub mBinder = new ITextToSpeechService.Stub() {
-
-        public int speak(String callingApp, String text, int queueMode, Bundle params) {
-            if (!checkNonNull(callingApp, text, params)) {
+        @Override
+        public int speak(IBinder caller, String text, int queueMode, Bundle params) {
+            if (!checkNonNull(caller, text, params)) {
                 return TextToSpeech.ERROR;
             }
 
-            SpeechItem item = new SynthesisSpeechItem(intern(callingApp), params, text);
+            SpeechItem item = new SynthesisSpeechItem(caller,
+                    Binder.getCallingUid(), Binder.getCallingPid(), params, text);
             return mSynthHandler.enqueueSpeechItem(queueMode, item);
         }
 
-        public int synthesizeToFile(String callingApp, String text, String filename,
+        @Override
+        public int synthesizeToFile(IBinder caller, String text, String filename,
                 Bundle params) {
-            if (!checkNonNull(callingApp, text, filename, params)) {
+            if (!checkNonNull(caller, text, filename, params)) {
                 return TextToSpeech.ERROR;
             }
 
             File file = new File(filename);
-            SpeechItem item = new SynthesisToFileSpeechItem(intern(callingApp),
-                    params, text, file);
+            SpeechItem item = new SynthesisToFileSpeechItem(caller, Binder.getCallingUid(),
+                    Binder.getCallingPid(), params, text, file);
             return mSynthHandler.enqueueSpeechItem(TextToSpeech.QUEUE_ADD, item);
         }
 
-        public int playAudio(String callingApp, Uri audioUri, int queueMode, Bundle params) {
-            if (!checkNonNull(callingApp, audioUri, params)) {
+        @Override
+        public int playAudio(IBinder caller, Uri audioUri, int queueMode, Bundle params) {
+            if (!checkNonNull(caller, audioUri, params)) {
                 return TextToSpeech.ERROR;
             }
 
-            SpeechItem item = new AudioSpeechItem(intern(callingApp), params, audioUri);
+            SpeechItem item = new AudioSpeechItem(caller,
+                    Binder.getCallingUid(), Binder.getCallingPid(), params, audioUri);
             return mSynthHandler.enqueueSpeechItem(queueMode, item);
         }
 
-        public int playSilence(String callingApp, long duration, int queueMode, Bundle params) {
-            if (!checkNonNull(callingApp, params)) {
+        @Override
+        public int playSilence(IBinder caller, long duration, int queueMode, Bundle params) {
+            if (!checkNonNull(caller, params)) {
                 return TextToSpeech.ERROR;
             }
 
-            SpeechItem item = new SilenceSpeechItem(intern(callingApp), params, duration);
+            SpeechItem item = new SilenceSpeechItem(caller,
+                    Binder.getCallingUid(), Binder.getCallingPid(), params, duration);
             return mSynthHandler.enqueueSpeechItem(queueMode, item);
         }
 
+        @Override
         public boolean isSpeaking() {
             return mSynthHandler.isSpeaking() || mAudioPlaybackHandler.isSpeaking();
         }
 
-        public int stop(String callingApp) {
-            if (!checkNonNull(callingApp)) {
+        @Override
+        public int stop(IBinder caller) {
+            if (!checkNonNull(caller)) {
                 return TextToSpeech.ERROR;
             }
 
-            return mSynthHandler.stopForApp(intern(callingApp));
+            return mSynthHandler.stopForApp(caller);
         }
 
+        @Override
         public String[] getLanguage() {
             return onGetLanguage();
         }
@@ -806,6 +830,7 @@
          * If defaults are enforced, then no language is "available" except
          * perhaps the default language selected by the user.
          */
+        @Override
         public int isLanguageAvailable(String lang, String country, String variant) {
             if (!checkNonNull(lang)) {
                 return TextToSpeech.ERROR;
@@ -814,6 +839,7 @@
             return onIsLanguageAvailable(lang, country, variant);
         }
 
+        @Override
         public String[] getFeaturesForLanguage(String lang, String country, String variant) {
             Set<String> features = onGetFeaturesForLanguage(lang, country, variant);
             String[] featuresArray = null;
@@ -830,6 +856,7 @@
          * There is no point loading a non default language if defaults
          * are enforced.
          */
+        @Override
         public int loadLanguage(String lang, String country, String variant) {
             if (!checkNonNull(lang)) {
                 return TextToSpeech.ERROR;
@@ -838,13 +865,14 @@
             return onLoadLanguage(lang, country, variant);
         }
 
-        public void setCallback(String packageName, ITextToSpeechCallback cb) {
+        @Override
+        public void setCallback(IBinder caller, ITextToSpeechCallback cb) {
             // Note that passing in a null callback is a valid use case.
-            if (!checkNonNull(packageName)) {
+            if (!checkNonNull(caller)) {
                 return;
             }
 
-            mCallbacks.setCallback(packageName, cb);
+            mCallbacks.setCallback(caller, cb);
         }
 
         private String intern(String in) {
@@ -861,18 +889,17 @@
     };
 
     private class CallbackMap extends RemoteCallbackList<ITextToSpeechCallback> {
+        private final HashMap<IBinder, ITextToSpeechCallback> mCallerToCallback
+                = new HashMap<IBinder, ITextToSpeechCallback>();
 
-        private final HashMap<String, ITextToSpeechCallback> mAppToCallback
-                = new HashMap<String, ITextToSpeechCallback>();
-
-        public void setCallback(String packageName, ITextToSpeechCallback cb) {
-            synchronized (mAppToCallback) {
+        public void setCallback(IBinder caller, ITextToSpeechCallback cb) {
+            synchronized (mCallerToCallback) {
                 ITextToSpeechCallback old;
                 if (cb != null) {
-                    register(cb, packageName);
-                    old = mAppToCallback.put(packageName, cb);
+                    register(cb, caller);
+                    old = mCallerToCallback.put(caller, cb);
                 } else {
-                    old = mAppToCallback.remove(packageName);
+                    old = mCallerToCallback.remove(caller);
                 }
                 if (old != null && old != cb) {
                     unregister(old);
@@ -880,8 +907,8 @@
             }
         }
 
-        public void dispatchOnDone(String packageName, String utteranceId) {
-            ITextToSpeechCallback cb = getCallbackFor(packageName);
+        public void dispatchOnDone(Object callerIdentity, String utteranceId) {
+            ITextToSpeechCallback cb = getCallbackFor(callerIdentity);
             if (cb == null) return;
             try {
                 cb.onDone(utteranceId);
@@ -890,8 +917,8 @@
             }
         }
 
-        public void dispatchOnStart(String packageName, String utteranceId) {
-            ITextToSpeechCallback cb = getCallbackFor(packageName);
+        public void dispatchOnStart(Object callerIdentity, String utteranceId) {
+            ITextToSpeechCallback cb = getCallbackFor(callerIdentity);
             if (cb == null) return;
             try {
                 cb.onStart(utteranceId);
@@ -901,8 +928,8 @@
 
         }
 
-        public void dispatchOnError(String packageName, String utteranceId) {
-            ITextToSpeechCallback cb = getCallbackFor(packageName);
+        public void dispatchOnError(Object callerIdentity, String utteranceId) {
+            ITextToSpeechCallback cb = getCallbackFor(callerIdentity);
             if (cb == null) return;
             try {
                 cb.onError(utteranceId);
@@ -913,25 +940,26 @@
 
         @Override
         public void onCallbackDied(ITextToSpeechCallback callback, Object cookie) {
-            String packageName = (String) cookie;
-            synchronized (mAppToCallback) {
-                mAppToCallback.remove(packageName);
+            IBinder caller = (IBinder) cookie;
+            synchronized (mCallerToCallback) {
+                mCallerToCallback.remove(caller);
             }
-            mSynthHandler.stopForApp(packageName);
+            mSynthHandler.stopForApp(caller);
         }
 
         @Override
         public void kill() {
-            synchronized (mAppToCallback) {
-                mAppToCallback.clear();
+            synchronized (mCallerToCallback) {
+                mCallerToCallback.clear();
                 super.kill();
             }
         }
 
-        private ITextToSpeechCallback getCallbackFor(String packageName) {
+        private ITextToSpeechCallback getCallbackFor(Object caller) {
             ITextToSpeechCallback cb;
-            synchronized (mAppToCallback) {
-                cb = mAppToCallback.get(packageName);
+            IBinder asBinder = (IBinder) caller;
+            synchronized (mCallerToCallback) {
+                cb = mCallerToCallback.get(asBinder);
             }
 
             return cb;
diff --git a/core/java/android/speech/tts/UtteranceProgressListener.java b/core/java/android/speech/tts/UtteranceProgressListener.java
index a04458a..cf0d22c 100644
--- a/core/java/android/speech/tts/UtteranceProgressListener.java
+++ b/core/java/android/speech/tts/UtteranceProgressListener.java
@@ -57,12 +57,16 @@
                 listener.onUtteranceCompleted(utteranceId);
             }
 
-            // The following methods are left unimplemented.
             @Override
-            public void onStart(String utteranceId) { }
+            public void onError(String utteranceId) {
+                listener.onUtteranceCompleted(utteranceId);
+            }
 
             @Override
-            public void onError(String utteranceId) { }
+            public void onStart(String utteranceId) {
+                // Left unimplemented, has no equivalent in the old
+                // API.
+            }
         };
     }
 }
diff --git a/core/java/android/text/format/DateUtils.java b/core/java/android/text/format/DateUtils.java
index 22a7528..da10311 100644
--- a/core/java/android/text/format/DateUtils.java
+++ b/core/java/android/text/format/DateUtils.java
@@ -1412,7 +1412,7 @@
             }
         }
 
-        if (noMonthDay && startMonthNum == endMonthNum) {
+        if (noMonthDay && startMonthNum == endMonthNum && startYear == endYear) {
             // Example: "January, 2008"
             return formatter.format("%s", startDate.format(defaultDateFormat));
         }
diff --git a/core/java/android/util/SparseArray.java b/core/java/android/util/SparseArray.java
index 7cf4579..366abd3 100644
--- a/core/java/android/util/SparseArray.java
+++ b/core/java/android/util/SparseArray.java
@@ -134,6 +134,7 @@
                 if (i != o) {
                     keys[o] = keys[i];
                     values[o] = val;
+                    values[i] = null;
                 }
 
                 o++;
diff --git a/core/java/android/view/Choreographer.java b/core/java/android/view/Choreographer.java
new file mode 100644
index 0000000..63de128
--- /dev/null
+++ b/core/java/android/view/Choreographer.java
@@ -0,0 +1,382 @@
+/*
+ * 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.view;
+
+import com.android.internal.util.ArrayUtils;
+
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.os.SystemClock;
+import android.os.SystemProperties;
+import android.util.Log;
+
+/**
+ * Coodinates animations and drawing for UI on a particular thread.
+ * @hide
+ */
+public final class Choreographer extends Handler {
+    private static final String TAG = "Choreographer";
+    private static final boolean DEBUG = false;
+
+    // The default amount of time in ms between animation frames.
+    // When vsync is not enabled, we want to have some idea of how long we should
+    // wait before posting the next animation message.  It is important that the
+    // default value be less than the true inter-frame delay on all devices to avoid
+    // situations where we might skip frames by waiting too long (we must compensate
+    // for jitter and hardware variations).  Regardless of this value, the animation
+    // and display loop is ultimately rate-limited by how fast new graphics buffers can
+    // be dequeued.
+    private static final long DEFAULT_FRAME_DELAY = 10;
+
+    // The number of milliseconds between animation frames.
+    private static long sFrameDelay = DEFAULT_FRAME_DELAY;
+
+    // Thread local storage for the choreographer.
+    private static final ThreadLocal<Choreographer> sThreadInstance =
+            new ThreadLocal<Choreographer>() {
+        @Override
+        protected Choreographer initialValue() {
+            Looper looper = Looper.myLooper();
+            if (looper == null) {
+                throw new IllegalStateException("The current thread must have a looper!");
+            }
+            return new Choreographer(looper);
+        }
+    };
+
+    // System property to enable/disable vsync for animations and drawing.
+    // Enabled by default.
+    private static final boolean USE_VSYNC = SystemProperties.getBoolean(
+            "debug.choreographer.vsync", true);
+
+    // System property to enable/disable the use of the vsync / animation timer
+    // for drawing rather than drawing immediately.
+    // Temporarily disabled by default because postponing performTraversals() violates
+    // assumptions about traversals happening in-order relative to other posted messages.
+    // Bug: 5721047
+    private static final boolean USE_ANIMATION_TIMER_FOR_DRAW = SystemProperties.getBoolean(
+            "debug.choreographer.animdraw", false);
+
+    private static final int MSG_DO_ANIMATION = 0;
+    private static final int MSG_DO_DRAW = 1;
+
+    private final Looper mLooper;
+
+    private OnAnimateListener[] mOnAnimateListeners;
+    private OnDrawListener[] mOnDrawListeners;
+
+    private boolean mAnimationScheduled;
+    private boolean mDrawScheduled;
+    private FrameDisplayEventReceiver mFrameDisplayEventReceiver;
+    private long mLastAnimationTime;
+    private long mLastDrawTime;
+
+    private Choreographer(Looper looper) {
+        super(looper);
+        mLooper = looper;
+        mLastAnimationTime = Long.MIN_VALUE;
+        mLastDrawTime = Long.MIN_VALUE;
+    }
+
+    /**
+     * Gets the choreographer for this thread.
+     * Must be called on the UI thread.
+     *
+     * @return The choreographer for this thread.
+     * @throws IllegalStateException if the thread does not have a looper.
+     */
+    public static Choreographer getInstance() {
+        return sThreadInstance.get();
+    }
+
+    /**
+     * The amount of time, in milliseconds, between each frame of the animation. This is a
+     * requested time that the animation will attempt to honor, but the actual delay between
+     * frames may be different, depending on system load and capabilities. This is a static
+     * function because the same delay will be applied to all animations, since they are all
+     * run off of a single timing loop.
+     *
+     * The frame delay may be ignored when the animation system uses an external timing
+     * source, such as the display refresh rate (vsync), to govern animations.
+     *
+     * @return the requested time between frames, in milliseconds
+     */
+    public static long getFrameDelay() {
+        return sFrameDelay;
+    }
+
+    /**
+     * The amount of time, in milliseconds, between each frame of the animation. This is a
+     * requested time that the animation will attempt to honor, but the actual delay between
+     * frames may be different, depending on system load and capabilities. This is a static
+     * function because the same delay will be applied to all animations, since they are all
+     * run off of a single timing loop.
+     *
+     * The frame delay may be ignored when the animation system uses an external timing
+     * source, such as the display refresh rate (vsync), to govern animations.
+     *
+     * @param frameDelay the requested time between frames, in milliseconds
+     */
+    public static void setFrameDelay(long frameDelay) {
+        sFrameDelay = frameDelay;
+    }
+
+    /**
+     * Schedules animation (and drawing) to occur on the next frame synchronization boundary.
+     * Must be called on the UI thread.
+     */
+    public void scheduleAnimation() {
+        if (!mAnimationScheduled) {
+            mAnimationScheduled = true;
+            if (USE_VSYNC) {
+                if (DEBUG) {
+                    Log.d(TAG, "Scheduling vsync for animation.");
+                }
+                if (mFrameDisplayEventReceiver == null) {
+                    mFrameDisplayEventReceiver = new FrameDisplayEventReceiver(mLooper);
+                }
+                mFrameDisplayEventReceiver.scheduleVsync();
+            } else {
+                final long now = SystemClock.uptimeMillis();
+                final long nextAnimationTime = Math.max(mLastAnimationTime + sFrameDelay, now);
+                if (DEBUG) {
+                    Log.d(TAG, "Scheduling animation in " + (nextAnimationTime - now) + " ms.");
+                }
+                sendEmptyMessageAtTime(MSG_DO_ANIMATION, nextAnimationTime);
+            }
+        }
+    }
+
+    /**
+     * Schedules drawing to occur on the next frame synchronization boundary.
+     * Must be called on the UI thread.
+     */
+    public void scheduleDraw() {
+        if (!mDrawScheduled) {
+            mDrawScheduled = true;
+            if (USE_ANIMATION_TIMER_FOR_DRAW) {
+                scheduleAnimation();
+            } else {
+                if (DEBUG) {
+                    Log.d(TAG, "Scheduling draw immediately.");
+                }
+                sendEmptyMessage(MSG_DO_DRAW);
+            }
+        }
+    }
+
+    @Override
+    public void handleMessage(Message msg) {
+        switch (msg.what) {
+            case MSG_DO_ANIMATION:
+                doAnimation();
+                break;
+            case MSG_DO_DRAW:
+                doDraw();
+                break;
+        }
+    }
+
+    private void doAnimation() {
+        if (mAnimationScheduled) {
+            mAnimationScheduled = false;
+
+            final long start = SystemClock.uptimeMillis();
+            if (DEBUG) {
+                Log.d(TAG, "Performing animation: " + Math.max(0, start - mLastAnimationTime)
+                        + " ms have elapsed since previous animation.");
+            }
+            mLastAnimationTime = start;
+
+            final OnAnimateListener[] listeners = mOnAnimateListeners;
+            if (listeners != null) {
+                for (int i = 0; i < listeners.length; i++) {
+                    listeners[i].onAnimate();
+                }
+            }
+
+            if (DEBUG) {
+                Log.d(TAG, "Animation took " + (SystemClock.uptimeMillis() - start) + " ms.");
+            }
+        }
+
+        if (USE_ANIMATION_TIMER_FOR_DRAW) {
+            doDraw();
+        }
+    }
+
+    private void doDraw() {
+        if (mDrawScheduled) {
+            mDrawScheduled = false;
+
+            final long start = SystemClock.uptimeMillis();
+            if (DEBUG) {
+                Log.d(TAG, "Performing draw: " + Math.max(0, start - mLastDrawTime)
+                        + " ms have elapsed since previous draw.");
+            }
+            mLastDrawTime = start;
+
+            final OnDrawListener[] listeners = mOnDrawListeners;
+            if (listeners != null) {
+                for (int i = 0; i < listeners.length; i++) {
+                    listeners[i].onDraw();
+                }
+            }
+
+            if (DEBUG) {
+                Log.d(TAG, "Draw took " + (SystemClock.uptimeMillis() - start) + " ms.");
+            }
+        }
+    }
+
+    /**
+     * Adds an animation listener.
+     * Must be called on the UI thread.
+     *
+     * @param listener The listener to add.
+     */
+    public void addOnAnimateListener(OnAnimateListener listener) {
+        if (listener == null) {
+            throw new IllegalArgumentException("listener must not be null");
+        }
+
+        if (DEBUG) {
+            Log.d(TAG, "Adding onAnimate listener: " + listener);
+        }
+
+        mOnAnimateListeners = ArrayUtils.appendElement(OnAnimateListener.class,
+                mOnAnimateListeners, listener);
+    }
+
+    /**
+     * Removes an animation listener.
+     * Must be called on the UI thread.
+     *
+     * @param listener The listener to remove.
+     */
+    public void removeOnAnimateListener(OnAnimateListener listener) {
+        if (listener == null) {
+            throw new IllegalArgumentException("listener must not be null");
+        }
+
+        if (DEBUG) {
+            Log.d(TAG, "Removing onAnimate listener: " + listener);
+        }
+
+        mOnAnimateListeners = ArrayUtils.removeElement(OnAnimateListener.class,
+                mOnAnimateListeners, listener);
+        stopTimingLoopIfNoListeners();
+    }
+
+    /**
+     * Adds a draw listener.
+     * Must be called on the UI thread.
+     *
+     * @param listener The listener to add.
+     */
+    public void addOnDrawListener(OnDrawListener listener) {
+        if (listener == null) {
+            throw new IllegalArgumentException("listener must not be null");
+        }
+
+        if (DEBUG) {
+            Log.d(TAG, "Adding onDraw listener: " + listener);
+        }
+
+        mOnDrawListeners = ArrayUtils.appendElement(OnDrawListener.class,
+                mOnDrawListeners, listener);
+    }
+
+    /**
+     * Removes a draw listener.
+     * Must be called on the UI thread.
+     *
+     * @param listener The listener to remove.
+     */
+    public void removeOnDrawListener(OnDrawListener listener) {
+        if (listener == null) {
+            throw new IllegalArgumentException("listener must not be null");
+        }
+
+        if (DEBUG) {
+            Log.d(TAG, "Removing onDraw listener: " + listener);
+        }
+
+        mOnDrawListeners = ArrayUtils.removeElement(OnDrawListener.class,
+                mOnDrawListeners, listener);
+        stopTimingLoopIfNoListeners();
+    }
+
+    private void stopTimingLoopIfNoListeners() {
+        if (mOnDrawListeners == null && mOnAnimateListeners == null) {
+            if (DEBUG) {
+                Log.d(TAG, "Stopping timing loop.");
+            }
+
+            if (mAnimationScheduled) {
+                mAnimationScheduled = false;
+                if (!USE_VSYNC) {
+                    removeMessages(MSG_DO_ANIMATION);
+                }
+            }
+
+            if (mDrawScheduled) {
+                mDrawScheduled = false;
+                if (!USE_ANIMATION_TIMER_FOR_DRAW) {
+                    removeMessages(MSG_DO_DRAW);
+                }
+            }
+
+            if (mFrameDisplayEventReceiver != null) {
+                mFrameDisplayEventReceiver.dispose();
+                mFrameDisplayEventReceiver = null;
+            }
+        }
+    }
+
+    /**
+     * Listens for animation frame timing events.
+     */
+    public static interface OnAnimateListener {
+        /**
+         * Called to animate properties before drawing the frame.
+         */
+        public void onAnimate();
+    }
+
+    /**
+     * Listens for draw frame timing events.
+     */
+    public static interface OnDrawListener {
+        /**
+         * Called to draw the frame.
+         */
+        public void onDraw();
+    }
+
+    private final class FrameDisplayEventReceiver extends DisplayEventReceiver {
+        public FrameDisplayEventReceiver(Looper looper) {
+            super(looper);
+        }
+
+        @Override
+        public void onVsync(long timestampNanos, int frame) {
+            doAnimation();
+        }
+    }
+}
diff --git a/core/java/android/view/DisplayEventReceiver.java b/core/java/android/view/DisplayEventReceiver.java
new file mode 100644
index 0000000..d6711ee
--- /dev/null
+++ b/core/java/android/view/DisplayEventReceiver.java
@@ -0,0 +1,115 @@
+/*
+ * 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.view;
+
+import dalvik.system.CloseGuard;
+
+import android.os.Looper;
+import android.os.MessageQueue;
+import android.util.Log;
+
+/**
+ * Provides a low-level mechanism for an application to receive display events
+ * such as vertical sync.
+ * @hide
+ */
+public abstract class DisplayEventReceiver {
+    private static final String TAG = "DisplayEventReceiver";
+
+    private final CloseGuard mCloseGuard = CloseGuard.get();
+
+    private int mReceiverPtr;
+
+    // We keep a reference message queue object here so that it is not
+    // GC'd while the native peer of the receiver is using them.
+    private MessageQueue mMessageQueue;
+
+    private static native int nativeInit(DisplayEventReceiver receiver,
+            MessageQueue messageQueue);
+    private static native void nativeDispose(int receiverPtr);
+    private static native void nativeScheduleVsync(int receiverPtr);
+
+    /**
+     * Creates a display event receiver.
+     *
+     * @param looper The looper to use when invoking callbacks.
+     */
+    public DisplayEventReceiver(Looper looper) {
+        if (looper == null) {
+            throw new IllegalArgumentException("looper must not be null");
+        }
+
+        mMessageQueue = looper.getQueue();
+        mReceiverPtr = nativeInit(this, mMessageQueue);
+
+        mCloseGuard.open("dispose");
+    }
+
+    @Override
+    protected void finalize() throws Throwable {
+        try {
+            dispose();
+        } finally {
+            super.finalize();
+        }
+    }
+
+    /**
+     * Disposes the receiver.
+     */
+    public void dispose() {
+        if (mCloseGuard != null) {
+            mCloseGuard.close();
+        }
+        if (mReceiverPtr != 0) {
+            nativeDispose(mReceiverPtr);
+            mReceiverPtr = 0;
+        }
+        mMessageQueue = null;
+    }
+
+    /**
+     * Called when a vertical sync pulse is received.
+     * The recipient should render a frame and then call {@link #scheduleVsync}
+     * to schedule the next vertical sync pulse.
+     *
+     * @param timestampNanos The timestamp of the pulse, in the {@link System#nanoTime()}
+     * timebase.
+     * @param frame The frame number.  Increases by one for each vertical sync interval.
+     */
+    public void onVsync(long timestampNanos, int frame) {
+    }
+
+    /**
+     * Schedules a single vertical sync pulse to be delivered when the next
+     * display frame begins.
+     */
+    public void scheduleVsync() {
+        if (mReceiverPtr == 0) {
+            Log.w(TAG, "Attempted to schedule a vertical sync pulse but the display event "
+                    + "receiver has already been disposed.");
+        } else {
+            nativeScheduleVsync(mReceiverPtr);
+        }
+    }
+
+    // Called from native code.
+    @SuppressWarnings("unused")
+    private void dispatchVsync(long timestampNanos, int frame) {
+        onVsync(timestampNanos, frame);
+    }
+}
diff --git a/core/java/android/view/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java
index 67d9033..43a451d 100644
--- a/core/java/android/view/GLES20Canvas.java
+++ b/core/java/android/view/GLES20Canvas.java
@@ -154,6 +154,7 @@
     static native void nSetTextureLayerTransform(int layerId, int matrix);
     static native void nDestroyLayer(int layerId);
     static native void nDestroyLayerDeferred(int layerId);
+    static native void nFlushLayer(int layerId);
     static native boolean nCopyLayer(int layerId, int bitmap);
 
     ///////////////////////////////////////////////////////////////////////////
@@ -737,8 +738,21 @@
         // Shaders are ignored when drawing bitmaps
         int modifiers = paint != null ? setupModifiers(bitmap, paint) : MODIFIER_NONE;
         final int nativePaint = paint == null ? 0 : paint.mNativePaint;
-        nDrawBitmap(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, src.left, src.top, src.right,
-                src.bottom, dst.left, dst.top, dst.right, dst.bottom, nativePaint);
+
+        float left, top, right, bottom;
+        if (src == null) {
+            left = top = 0;
+            right = bitmap.getWidth();
+            bottom = bitmap.getHeight();
+        } else {
+            left = src.left;
+            right = src.right;
+            top = src.top;
+            bottom = src.bottom;
+        }
+
+        nDrawBitmap(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, left, top, right, bottom,
+                dst.left, dst.top, dst.right, dst.bottom, nativePaint);
         if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
     }
 
diff --git a/core/java/android/view/GLES20Layer.java b/core/java/android/view/GLES20Layer.java
index fd3b9e5..4f25792 100644
--- a/core/java/android/view/GLES20Layer.java
+++ b/core/java/android/view/GLES20Layer.java
@@ -60,6 +60,13 @@
         }
         mLayer = 0;
     }
+    
+    @Override
+    void flush() {
+        if (mLayer != 0) {
+            GLES20Canvas.nFlushLayer(mLayer);
+        }
+    }
 
     static class Finalizer {
         private int mLayerId;
diff --git a/core/java/android/view/HardwareLayer.java b/core/java/android/view/HardwareLayer.java
index 28389ab..d5666f3 100644
--- a/core/java/android/view/HardwareLayer.java
+++ b/core/java/android/view/HardwareLayer.java
@@ -116,6 +116,11 @@
     abstract void destroy();
 
     /**
+     * Flush the render queue associated with this layer.
+     */
+    abstract void flush();
+
+    /**
      * This must be invoked before drawing onto this layer.
      * @param currentCanvas
      */
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java
index f77cf7e..3f793bb 100644
--- a/core/java/android/view/HardwareRenderer.java
+++ b/core/java/android/view/HardwareRenderer.java
@@ -219,6 +219,13 @@
     abstract int getHeight();
 
     /**
+     * Gets the current canvas associated with this HardwareRenderer.
+     *
+     * @return the current HardwareCanvas
+     */
+    abstract HardwareCanvas getCanvas();
+
+    /**
      * Sets the directory to use as a persistent storage for hardware rendering
      * resources.
      * 
@@ -434,6 +441,8 @@
         }
 
         boolean mDirtyRegionsEnabled;
+        boolean mUpdateDirtyRegions;
+
         final boolean mVsyncDisabled;
 
         final int mGlVersion;
@@ -668,6 +677,12 @@
             
             initCaches();
 
+            enableDirtyRegions();
+
+            return mEglContext.getGL();
+        }
+
+        private void enableDirtyRegions() {
             // If mDirtyRegions is set, this means we have an EGL configuration
             // with EGL_SWAP_BEHAVIOR_PRESERVED_BIT set
             if (sDirtyRegions) {
@@ -683,8 +698,6 @@
                 // configuration (see RENDER_DIRTY_REGIONS)
                 mDirtyRegionsEnabled = GLES20Canvas.isBackBufferPreserved();
             }
-
-            return mEglContext.getGL();
         }
 
         abstract void initCaches();
@@ -738,6 +751,9 @@
                 if (!createSurface(holder)) {
                     return;
                 }
+
+                mUpdateDirtyRegions = true;
+
                 if (mCanvas != null) {
                     setEnabled(true);
                 }
@@ -783,6 +799,11 @@
             return mHeight;
         }
 
+        @Override
+        HardwareCanvas getCanvas() {
+            return mCanvas;
+        }
+
         boolean canDraw() {
             return mGl != null && mCanvas != null;
         }        
@@ -825,10 +846,37 @@
                                 (view.mPrivateFlags & View.INVALIDATED) == View.INVALIDATED;
                         view.mPrivateFlags &= ~View.INVALIDATED;
 
+                        final long getDisplayListStartTime;
+                        if (ViewDebug.DEBUG_LATENCY) {
+                            getDisplayListStartTime = System.nanoTime();
+                        }
+
                         DisplayList displayList = view.getDisplayList();
+
+                        if (ViewDebug.DEBUG_LATENCY) {
+                            long now = System.nanoTime();
+                            Log.d(ViewDebug.DEBUG_LATENCY_TAG, "- getDisplayList() took "
+                                    + ((now - getDisplayListStartTime) * 0.000001f) + "ms");
+                        }
+
                         if (displayList != null) {
-                            if (canvas.drawDisplayList(displayList, view.getWidth(),
-                                    view.getHeight(), mRedrawClip)) {
+                            final long drawDisplayListStartTime;
+                            if (ViewDebug.DEBUG_LATENCY) {
+                                drawDisplayListStartTime = System.nanoTime();
+                            }
+
+                            boolean invalidateNeeded = canvas.drawDisplayList(
+                                    displayList, view.getWidth(),
+                                    view.getHeight(), mRedrawClip);
+
+                            if (ViewDebug.DEBUG_LATENCY) {
+                                long now = System.nanoTime();
+                                Log.d(ViewDebug.DEBUG_LATENCY_TAG, "- drawDisplayList() took "
+                                        + ((now - drawDisplayListStartTime) * 0.000001f)
+                                        + "ms, invalidateNeeded=" + invalidateNeeded + ".");
+                            }
+
+                            if (invalidateNeeded) {
                                 if (mRedrawClip.isEmpty() || view.getParent() == null) {
                                     view.invalidate();
                                 } else {
@@ -860,7 +908,19 @@
 
                     attachInfo.mIgnoreDirtyState = false;
 
+                    final long eglSwapBuffersStartTime;
+                    if (ViewDebug.DEBUG_LATENCY) {
+                        eglSwapBuffersStartTime = System.nanoTime();
+                    }
+
                     sEgl.eglSwapBuffers(sEglDisplay, mEglSurface);
+
+                    if (ViewDebug.DEBUG_LATENCY) {
+                        long now = System.nanoTime();
+                        Log.d(ViewDebug.DEBUG_LATENCY_TAG, "- eglSwapBuffers() took "
+                                + ((now - eglSwapBuffersStartTime) * 0.000001f) + "ms");
+                    }
+
                     checkEglErrors();
 
                     return dirty == null;
@@ -892,6 +952,10 @@
                     fallback(true);
                     return SURFACE_STATE_ERROR;
                 } else {
+                    if (mUpdateDirtyRegions) {
+                        enableDirtyRegions();
+                        mUpdateDirtyRegions = false;
+                    }
                     return SURFACE_STATE_UPDATED;
                 }
             }
diff --git a/core/java/android/view/IWindowSession.aidl b/core/java/android/view/IWindowSession.aidl
index 282d7be..53d6e1f 100644
--- a/core/java/android/view/IWindowSession.aidl
+++ b/core/java/android/view/IWindowSession.aidl
@@ -54,9 +54,8 @@
      * @param requestedWidth The width the window wants to be.
      * @param requestedHeight The height the window wants to be.
      * @param viewVisibility Window root view's visibility.
-     * @param insetsPending Set to true if the client will be later giving
-     * internal insets; as a result, the window will not impact other window
-     * layouts until the insets are given.
+     * @param flags Request flags: {@link WindowManagerImpl#RELAYOUT_INSETS_PENDING},
+     * {@link WindowManagerImpl#RELAYOUT_DEFER_SURFACE_DESTROY}.
      * @param outFrame Rect in which is placed the new position/size on
      * screen.
      * @param outContentInsets Rect in which is placed the offsets from
@@ -80,11 +79,17 @@
      */
     int relayout(IWindow window, int seq, in WindowManager.LayoutParams attrs,
             int requestedWidth, int requestedHeight, int viewVisibility,
-            boolean insetsPending, out Rect outFrame, out Rect outContentInsets,
+            int flags, out Rect outFrame, out Rect outContentInsets,
             out Rect outVisibleInsets, out Configuration outConfig,
             out Surface outSurface);
 
     /**
+     * If a call to relayout() asked to have the surface destroy deferred,
+     * it must call this once it is okay to destroy that surface.
+     */
+    void performDeferredDestroy(IWindow window);
+
+    /**
      * Called by a client to report that it ran out of graphics memory.
      */
     boolean outOfMemory(IWindow window);
diff --git a/core/java/android/view/InputEvent.java b/core/java/android/view/InputEvent.java
index 01ddcc9..5602436 100755
--- a/core/java/android/view/InputEvent.java
+++ b/core/java/android/view/InputEvent.java
@@ -19,6 +19,8 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 
+import java.util.concurrent.atomic.AtomicInteger;
+
 /**
  * Common base class for input events.
  */
@@ -27,8 +29,21 @@
     protected static final int PARCEL_TOKEN_MOTION_EVENT = 1;
     /** @hide */
     protected static final int PARCEL_TOKEN_KEY_EVENT = 2;
-    
+
+    // Next sequence number.
+    private static final AtomicInteger mNextSeq = new AtomicInteger();
+
+    /** @hide */
+    protected int mSeq;
+
+    /** @hide */
+    protected boolean mRecycled;
+
+    private static final boolean TRACK_RECYCLED_LOCATION = false;
+    private RuntimeException mRecycledLocation;
+
     /*package*/ InputEvent() {
+        mSeq = mNextSeq.getAndIncrement();
     }
 
     /**
@@ -82,7 +97,44 @@
      * objects are fine.  See {@link KeyEvent#recycle()} for details.
      * @hide
      */
-    public abstract void recycle();
+    public void recycle() {
+        if (TRACK_RECYCLED_LOCATION) {
+            if (mRecycledLocation != null) {
+                throw new RuntimeException(toString() + " recycled twice!", mRecycledLocation);
+            }
+            mRecycledLocation = new RuntimeException("Last recycled here");
+        } else {
+            if (mRecycled) {
+                throw new RuntimeException(toString() + " recycled twice!");
+            }
+            mRecycled = true;
+        }
+    }
+
+    /**
+     * Conditionally recycled the event if it is appropriate to do so after
+     * dispatching the event to an application.
+     *
+     * If the event is a {@link MotionEvent} then it is recycled.
+     *
+     * If the event is a {@link KeyEvent} then it is NOT recycled, because applications
+     * expect key events to be immutable so once the event has been dispatched to
+     * the application we can no longer recycle it.
+     * @hide
+     */
+    public void recycleIfNeededAfterDispatch() {
+        recycle();
+    }
+
+    /**
+     * Reinitializes the event on reuse (after recycling).
+     * @hide
+     */
+    protected void prepareForReuse() {
+        mRecycled = false;
+        mRecycledLocation = null;
+        mSeq = mNextSeq.getAndIncrement();
+    }
 
     /**
      * Gets a private flag that indicates when the system has detected that this input event
@@ -113,6 +165,22 @@
      */
     public abstract long getEventTimeNano();
 
+    /**
+     * Gets the unique sequence number of this event.
+     * Every input event that is created or received by a process has a
+     * unique sequence number.  Moreover, a new sequence number is obtained
+     * each time an event object is recycled.
+     *
+     * Sequence numbers are only guaranteed to be locally unique within a process.
+     * Sequence numbers are not preserved when events are parceled.
+     *
+     * @return The unique sequence number of this event.
+     * @hide
+     */
+    public int getSequenceNumber() {
+        return mSeq;
+    }
+
     public int describeContents() {
         return 0;
     }
diff --git a/core/java/android/view/InputEventConsistencyVerifier.java b/core/java/android/view/InputEventConsistencyVerifier.java
index 9b081b2..fafe416 100644
--- a/core/java/android/view/InputEventConsistencyVerifier.java
+++ b/core/java/android/view/InputEventConsistencyVerifier.java
@@ -58,7 +58,7 @@
     // so that the verifier can detect when it has been asked to verify the same event twice.
     // It does not make sense to examine the contents of the last event since it may have
     // been recycled.
-    private InputEvent mLastEvent;
+    private int mLastEventSeq;
     private String mLastEventType;
     private int mLastNestingLevel;
 
@@ -140,7 +140,7 @@
      * Resets the state of the input event consistency verifier.
      */
     public void reset() {
-        mLastEvent = null;
+        mLastEventSeq = -1;
         mLastNestingLevel = 0;
         mTrackballDown = false;
         mTrackballUnhandled = false;
@@ -573,17 +573,18 @@
 
     private boolean startEvent(InputEvent event, int nestingLevel, String eventType) {
         // Ignore the event if we already checked it at a higher nesting level.
-        if (event == mLastEvent && nestingLevel < mLastNestingLevel
+        final int seq = event.getSequenceNumber();
+        if (seq == mLastEventSeq && nestingLevel < mLastNestingLevel
                 && eventType == mLastEventType) {
             return false;
         }
 
         if (nestingLevel > 0) {
-            mLastEvent = event;
+            mLastEventSeq = seq;
             mLastEventType = eventType;
             mLastNestingLevel = nestingLevel;
         } else {
-            mLastEvent = null;
+            mLastEventSeq = -1;
             mLastEventType = null;
             mLastNestingLevel = 0;
         }
diff --git a/core/java/android/view/InputEventReceiver.java b/core/java/android/view/InputEventReceiver.java
new file mode 100644
index 0000000..764d8dc
--- /dev/null
+++ b/core/java/android/view/InputEventReceiver.java
@@ -0,0 +1,141 @@
+/*
+ * 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.view;
+
+import dalvik.system.CloseGuard;
+
+import android.os.Looper;
+import android.os.MessageQueue;
+import android.util.Log;
+
+/**
+ * Provides a low-level mechanism for an application to receive input events.
+ * @hide
+ */
+public abstract class InputEventReceiver {
+    private static final String TAG = "InputEventReceiver";
+
+    private final CloseGuard mCloseGuard = CloseGuard.get();
+
+    private int mReceiverPtr;
+
+    // We keep references to the input channel and message queue objects here so that
+    // they are not GC'd while the native peer of the receiver is using them.
+    private InputChannel mInputChannel;
+    private MessageQueue mMessageQueue;
+
+    // The sequence number of the event that is in progress.
+    private int mEventSequenceNumberInProgress = -1;
+
+    private static native int nativeInit(InputEventReceiver receiver,
+            InputChannel inputChannel, MessageQueue messageQueue);
+    private static native void nativeDispose(int receiverPtr);
+    private static native void nativeFinishInputEvent(int receiverPtr, boolean handled);
+
+    /**
+     * Creates an input event receiver bound to the specified input channel.
+     *
+     * @param inputChannel The input channel.
+     * @param looper The looper to use when invoking callbacks.
+     */
+    public InputEventReceiver(InputChannel inputChannel, Looper looper) {
+        if (inputChannel == null) {
+            throw new IllegalArgumentException("inputChannel must not be null");
+        }
+        if (looper == null) {
+            throw new IllegalArgumentException("looper must not be null");
+        }
+
+        mInputChannel = inputChannel;
+        mMessageQueue = looper.getQueue();
+        mReceiverPtr = nativeInit(this, inputChannel, mMessageQueue);
+
+        mCloseGuard.open("dispose");
+    }
+
+    @Override
+    protected void finalize() throws Throwable {
+        try {
+            dispose();
+        } finally {
+            super.finalize();
+        }
+    }
+
+    /**
+     * Disposes the receiver.
+     */
+    public void dispose() {
+        if (mCloseGuard != null) {
+            mCloseGuard.close();
+        }
+        if (mReceiverPtr != 0) {
+            nativeDispose(mReceiverPtr);
+            mReceiverPtr = 0;
+        }
+        mInputChannel = null;
+        mMessageQueue = null;
+    }
+
+    /**
+     * Called when an input event is received.
+     * The recipient should process the input event and then call {@link #finishInputEvent}
+     * to indicate whether the event was handled.  No new input events will be received
+     * until {@link #finishInputEvent} is called.
+     *
+     * @param event The input event that was received.
+     */
+    public void onInputEvent(InputEvent event) {
+        finishInputEvent(event, false);
+    }
+
+    /**
+     * Finishes an input event and indicates whether it was handled.
+     *
+     * @param event The input event that was finished.
+     * @param handled True if the event was handled.
+     */
+    public void finishInputEvent(InputEvent event, boolean handled) {
+        if (event == null) {
+            throw new IllegalArgumentException("event must not be null");
+        }
+        if (mReceiverPtr == 0) {
+            Log.w(TAG, "Attempted to finish an input event but the input event "
+                    + "receiver has already been disposed.");
+        } else {
+            if (event.getSequenceNumber() != mEventSequenceNumberInProgress) {
+                Log.w(TAG, "Attempted to finish an input event that is not in progress.");
+            } else {
+                mEventSequenceNumberInProgress = -1;
+                nativeFinishInputEvent(mReceiverPtr, handled);
+            }
+        }
+        event.recycleIfNeededAfterDispatch();
+    }
+
+    // Called from native code.
+    @SuppressWarnings("unused")
+    private void dispatchInputEvent(InputEvent event) {
+        mEventSequenceNumberInProgress = event.getSequenceNumber();
+        onInputEvent(event);
+    }
+
+    public static interface Factory {
+        public InputEventReceiver createInputEventReceiver(
+                InputChannel inputChannel, Looper looper);
+    }
+}
diff --git a/core/java/android/view/InputHandler.java b/core/java/android/view/InputHandler.java
deleted file mode 100644
index 14ce14c..0000000
--- a/core/java/android/view/InputHandler.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2010 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.view;
-
-/**
- * Handles input messages that arrive on an input channel.
- * @hide
- */
-public interface InputHandler {
-    /**
-     * Handle a key event.
-     * It is the responsibility of the callee to ensure that the finished callback is
-     * eventually invoked when the event processing is finished and the input system
-     * can send the next event.
-     * @param event The key event data.
-     * @param finishedCallback The callback to invoke when event processing is finished.
-     */
-    public void handleKey(KeyEvent event, InputQueue.FinishedCallback finishedCallback);
-    
-    /**
-     * Handle a motion event.
-     * It is the responsibility of the callee to ensure that the finished callback is
-     * eventually invoked when the event processing is finished and the input system
-     * can send the next event.
-     * @param event The motion event data.
-     * @param finishedCallback The callback to invoke when event processing is finished.
-     */
-    public void handleMotion(MotionEvent event, InputQueue.FinishedCallback finishedCallback);
-}
diff --git a/core/java/android/view/InputQueue.java b/core/java/android/view/InputQueue.java
index 5735b63..909a3b2 100644
--- a/core/java/android/view/InputQueue.java
+++ b/core/java/android/view/InputQueue.java
@@ -16,18 +16,11 @@
 
 package android.view;
 
-import android.os.MessageQueue;
-import android.util.Slog;
-
 /**
  * An input queue provides a mechanism for an application to receive incoming
  * input events.  Currently only usable from native code.
  */
 public final class InputQueue {
-    private static final String TAG = "InputQueue";
-    
-    private static final boolean DEBUG = false;
-    
     /**
      * Interface to receive notification of when an InputQueue is associated
      * and dissociated with a thread.
@@ -48,13 +41,6 @@
 
     final InputChannel mChannel;
     
-    private static final Object sLock = new Object();
-    
-    private static native void nativeRegisterInputChannel(InputChannel inputChannel,
-            InputHandler inputHandler, MessageQueue messageQueue);
-    private static native void nativeUnregisterInputChannel(InputChannel inputChannel);
-    private static native void nativeFinished(long finishedToken, boolean handled);
-    
     /** @hide */
     public InputQueue(InputChannel channel) {
         mChannel = channel;
@@ -64,121 +50,4 @@
     public InputChannel getInputChannel() {
         return mChannel;
     }
-    
-    /**
-     * Registers an input channel and handler.
-     * @param inputChannel The input channel to register.
-     * @param inputHandler The input handler to input events send to the target.
-     * @param messageQueue The message queue on whose thread the handler should be invoked.
-     * @hide
-     */
-    public static void registerInputChannel(InputChannel inputChannel, InputHandler inputHandler,
-            MessageQueue messageQueue) {
-        if (inputChannel == null) {
-            throw new IllegalArgumentException("inputChannel must not be null");
-        }
-        if (inputHandler == null) {
-            throw new IllegalArgumentException("inputHandler must not be null");
-        }
-        if (messageQueue == null) {
-            throw new IllegalArgumentException("messageQueue must not be null");
-        }
-        
-        synchronized (sLock) {
-            if (DEBUG) {
-                Slog.d(TAG, "Registering input channel '" + inputChannel + "'");
-            }
-            
-            nativeRegisterInputChannel(inputChannel, inputHandler, messageQueue);
-        }
-    }
-    
-    /**
-     * Unregisters an input channel.
-     * Does nothing if the channel is not currently registered.
-     * @param inputChannel The input channel to unregister.
-     * @hide
-     */
-    public static void unregisterInputChannel(InputChannel inputChannel) {
-        if (inputChannel == null) {
-            throw new IllegalArgumentException("inputChannel must not be null");
-        }
-
-        synchronized (sLock) {
-            if (DEBUG) {
-                Slog.d(TAG, "Unregistering input channel '" + inputChannel + "'");
-            }
-            
-            nativeUnregisterInputChannel(inputChannel);
-        }
-    }
-    
-    @SuppressWarnings("unused")
-    private static void dispatchKeyEvent(InputHandler inputHandler,
-            KeyEvent event, long finishedToken) {
-        FinishedCallback finishedCallback = FinishedCallback.obtain(finishedToken);
-        inputHandler.handleKey(event, finishedCallback);
-    }
-
-    @SuppressWarnings("unused")
-    private static void dispatchMotionEvent(InputHandler inputHandler,
-            MotionEvent event, long finishedToken) {
-        FinishedCallback finishedCallback = FinishedCallback.obtain(finishedToken);
-        inputHandler.handleMotion(event, finishedCallback);
-    }
-    
-    /**
-     * A callback that must be invoked to when finished processing an event.
-     * @hide
-     */
-    public static final class FinishedCallback {
-        private static final boolean DEBUG_RECYCLING = false;
-        
-        private static final int RECYCLE_MAX_COUNT = 4;
-        
-        private static FinishedCallback sRecycleHead;
-        private static int sRecycleCount;
-        
-        private FinishedCallback mRecycleNext;
-        private long mFinishedToken;
-        
-        private FinishedCallback() {
-        }
-        
-        public static FinishedCallback obtain(long finishedToken) {
-            synchronized (sLock) {
-                FinishedCallback callback = sRecycleHead;
-                if (callback != null) {
-                    sRecycleHead = callback.mRecycleNext;
-                    sRecycleCount -= 1;
-                    callback.mRecycleNext = null;
-                } else {
-                    callback = new FinishedCallback();
-                }
-                callback.mFinishedToken = finishedToken;
-                return callback;
-            }
-        }
-        
-        public void finished(boolean handled) {
-            synchronized (sLock) {
-                if (mFinishedToken == -1) {
-                    throw new IllegalStateException("Event finished callback already invoked.");
-                }
-                
-                nativeFinished(mFinishedToken, handled);
-                mFinishedToken = -1;
-
-                if (sRecycleCount < RECYCLE_MAX_COUNT) {
-                    mRecycleNext = sRecycleHead;
-                    sRecycleHead = this;
-                    sRecycleCount += 1;
-                    
-                    if (DEBUG_RECYCLING) {
-                        Slog.d(TAG, "Recycled finished callbacks: " + sRecycleCount);
-                    }
-                }
-            }
-        }
-    }
 }
diff --git a/core/java/android/view/KeyEvent.java b/core/java/android/view/KeyEvent.java
index 6c3d387..104ed6a 100755
--- a/core/java/android/view/KeyEvent.java
+++ b/core/java/android/view/KeyEvent.java
@@ -579,8 +579,20 @@
     /** Key code constant: 3D Mode key.
      * Toggles the display between 2D and 3D mode. */
     public static final int KEYCODE_3D_MODE         = 206;
+    /** Key code constant: Contacts special function key.
+     * Used to launch an address book application. */
+    public static final int KEYCODE_CONTACTS        = 207;
+    /** Key code constant: Calendar special function key.
+     * Used to launch a calendar application. */
+    public static final int KEYCODE_CALENDAR        = 208;
+    /** Key code constant: Music special function key.
+     * Used to launch a music player application. */
+    public static final int KEYCODE_MUSIC           = 209;
+    /** Key code constant: Calculator special function key.
+     * Used to launch a calculator application. */
+    public static final int KEYCODE_CALCULATOR      = 210;
 
-    private static final int LAST_KEYCODE           = KEYCODE_BUTTON_16;
+    private static final int LAST_KEYCODE           = KEYCODE_CALCULATOR;
 
     // NOTE: If you add a new keycode here you must also add it to:
     //  isSystem()
@@ -589,6 +601,8 @@
     //  external/webkit/WebKit/android/plugins/ANPKeyCodes.h
     //  frameworks/base/core/res/res/values/attrs.xml
     //  emulator?
+    //  LAST_KEYCODE
+    //  KEYCODE_SYMBOLIC_NAMES
     //
     //  Also Android currently does not reserve code ranges for vendor-
     //  specific key codes.  If you have new key codes to have, you
@@ -807,6 +821,10 @@
         names.append(KEYCODE_LANGUAGE_SWITCH, "KEYCODE_LANGUAGE_SWITCH");
         names.append(KEYCODE_MANNER_MODE, "KEYCODE_MANNER_MODE");
         names.append(KEYCODE_3D_MODE, "KEYCODE_3D_MODE");
+        names.append(KEYCODE_CONTACTS, "KEYCODE_CONTACTS");
+        names.append(KEYCODE_CALENDAR, "KEYCODE_CALENDAR");
+        names.append(KEYCODE_MUSIC, "KEYCODE_MUSIC");
+        names.append(KEYCODE_CALCULATOR, "KEYCODE_CALCULATOR");
     };
 
     // Symbolic names of all metakeys in bit order from least significant to most significant.
@@ -1207,7 +1225,6 @@
     private static KeyEvent gRecyclerTop;
 
     private KeyEvent mNext;
-    private boolean mRecycled;
 
     private int mDeviceId;
     private int mSource;
@@ -1517,8 +1534,8 @@
             gRecyclerTop = ev.mNext;
             gRecyclerUsed -= 1;
         }
-        ev.mRecycled = false;
         ev.mNext = null;
+        ev.prepareForReuse();
         return ev;
     }
 
@@ -1579,11 +1596,9 @@
      *
      * @hide
      */
+    @Override
     public final void recycle() {
-        if (mRecycled) {
-            throw new RuntimeException(toString() + " recycled twice!");
-        }
-        mRecycled = true;
+        super.recycle();
         mCharacters = null;
 
         synchronized (gRecyclerLock) {
@@ -1595,6 +1610,12 @@
         }
     }
 
+    /** @hide */
+    @Override
+    public final void recycleIfNeededAfterDispatch() {
+        // Do nothing.
+    }
+
     /**
      * Create a new key event that is the same as the given one, but whose
      * event time and repeat count are replaced with the given value.
diff --git a/core/java/android/view/MotionEvent.java b/core/java/android/view/MotionEvent.java
index 8e0ab1a..92e8f4e 100644
--- a/core/java/android/view/MotionEvent.java
+++ b/core/java/android/view/MotionEvent.java
@@ -167,7 +167,6 @@
  */
 public final class MotionEvent extends InputEvent implements Parcelable {
     private static final long NS_PER_MS = 1000000;
-    private static final boolean TRACK_RECYCLED_LOCATION = false;
 
     /**
      * An invalid pointer id.
@@ -1315,8 +1314,6 @@
     private int mNativePtr;
 
     private MotionEvent mNext;
-    private RuntimeException mRecycledLocation;
-    private boolean mRecycled;
 
     private static native int nativeInitialize(int nativePtr,
             int deviceId, int source, int action, int flags, int edgeFlags,
@@ -1397,9 +1394,8 @@
             gRecyclerTop = ev.mNext;
             gRecyclerUsed -= 1;
         }
-        ev.mRecycledLocation = null;
-        ev.mRecycled = false;
         ev.mNext = null;
+        ev.prepareForReuse();
         return ev;
     }
 
@@ -1646,20 +1642,9 @@
      * Recycle the MotionEvent, to be re-used by a later caller.  After calling
      * this function you must not ever touch the event again.
      */
+    @Override
     public final void recycle() {
-        // Ensure recycle is only called once!
-        if (TRACK_RECYCLED_LOCATION) {
-            if (mRecycledLocation != null) {
-                throw new RuntimeException(toString() + " recycled twice!", mRecycledLocation);
-            }
-            mRecycledLocation = new RuntimeException("Last recycled here");
-            //Log.w("MotionEvent", "Recycling event " + this, mRecycledLocation);
-        } else {
-            if (mRecycled) {
-                throw new RuntimeException(toString() + " recycled twice!");
-            }
-            mRecycled = true;
-        }
+        super.recycle();
 
         synchronized (gRecyclerLock) {
             if (gRecyclerUsed < MAX_RECYCLED) {
diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java
index 2b254af..edaa262 100644
--- a/core/java/android/view/Surface.java
+++ b/core/java/android/view/Surface.java
@@ -282,10 +282,24 @@
     /**
      * Copy another surface to this one.  This surface now holds a reference
      * to the same data as the original surface, and is -not- the owner.
+     * This is for use by the window manager when returning a window surface
+     * back from a client, converting it from the representation being managed
+     * by the window manager to the representation the client uses to draw
+     * in to it.
      * @hide
      */
     public native void copyFrom(Surface o);
-    
+
+    /**
+     * Transfer the native state from 'o' to this surface, releasing it
+     * from 'o'.  This is for use in the client side for drawing into a
+     * surface; not guaranteed to work on the window manager side.
+     * This is for use by the client to move the underlying surface from
+     * one Surface object to another, in particular in SurfaceFlinger.
+     * @hide.
+     */
+    public native void transferFrom(Surface o);
+
     /** @hide */
     public int getGenerationId() {
         return mSurfaceGenerationId;
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index 9a57ea0..6726c56e 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -16,7 +16,6 @@
 
 package android.view;
 
-import android.util.DisplayMetrics;
 import com.android.internal.view.BaseIWindow;
 
 import android.content.Context;
@@ -82,7 +81,6 @@
 public class SurfaceView extends View {
     static private final String TAG = "SurfaceView";
     static private final boolean DEBUG = false;
-    static private final boolean localLOGV = DEBUG ? true : false;
 
     final ArrayList<SurfaceHolder.Callback> mCallbacks
             = new ArrayList<SurfaceHolder.Callback>();
@@ -90,7 +88,8 @@
     final int[] mLocation = new int[2];
     
     final ReentrantLock mSurfaceLock = new ReentrantLock();
-    final Surface mSurface = new Surface();
+    final Surface mSurface = new Surface();       // Current surface in use
+    final Surface mNewSurface = new Surface();    // New surface we are switching to
     boolean mDrawingStopped = true;
 
     final WindowManager.LayoutParams mLayout
@@ -145,8 +144,7 @@
     int mRequestedFormat = PixelFormat.RGB_565;
 
     boolean mHaveFrame = false;
-    boolean mDestroyReportNeeded = false;
-    boolean mNewSurfaceNeeded = false;
+    boolean mSurfaceCreated = false;
     long mLastLockTime = 0;
     
     boolean mVisible = false;
@@ -236,46 +234,6 @@
         updateWindow(false, false);
     }
 
-    /**
-     * This method is not intended for general use. It was created
-     * temporarily to improve performance of 3D layers in Launcher
-     * and should be removed and fixed properly.
-     * 
-     * Do not call this method. Ever.
-     * 
-     * @hide
-     */
-    protected void showSurface() {
-        if (mSession != null) {
-            updateWindow(true, false);
-        }
-    }
-
-    /**
-     * This method is not intended for general use. It was created
-     * temporarily to improve performance of 3D layers in Launcher
-     * and should be removed and fixed properly.
-     * 
-     * Do not call this method. Ever.
-     * 
-     * @hide
-     */
-    protected void hideSurface() {
-        if (mSession != null && mWindow != null) {
-            mSurfaceLock.lock();
-            try {
-                DisplayMetrics metrics = getResources().getDisplayMetrics();
-                mLayout.x = metrics.widthPixels * 3;
-                mSession.relayout(mWindow, mWindow.mSeq, mLayout, mWidth, mHeight, VISIBLE, false,
-                        mWinFrame, mContentInsets, mVisibleInsets, mConfiguration, mSurface);
-            } catch (RemoteException e) {
-                // Ignore
-            } finally {
-                mSurfaceLock.unlock();
-            }
-        }
-    }
-    
     @Override
     protected void onDetachedFromWindow() {
         if (mGlobalListenersAdded) {
@@ -444,14 +402,13 @@
         final boolean creating = mWindow == null;
         final boolean formatChanged = mFormat != mRequestedFormat;
         final boolean sizeChanged = mWidth != myWidth || mHeight != myHeight;
-        final boolean visibleChanged = mVisible != mRequestedVisible
-                || mNewSurfaceNeeded;
+        final boolean visibleChanged = mVisible != mRequestedVisible;
 
         if (force || creating || formatChanged || sizeChanged || visibleChanged
             || mLeft != mLocation[0] || mTop != mLocation[1]
             || mUpdateWindowNeeded || mReportDrawNeeded || redrawNeeded) {
 
-            if (localLOGV) Log.i(TAG, "Changes: creating=" + creating
+            if (DEBUG) Log.i(TAG, "Changes: creating=" + creating
                     + " format=" + formatChanged + " size=" + sizeChanged
                     + " visible=" + visibleChanged
                     + " left=" + (mLeft != mLocation[0])
@@ -496,15 +453,11 @@
                             mVisible ? VISIBLE : GONE, mContentInsets);
                 }
                 
-                if (visibleChanged && (!visible || mNewSurfaceNeeded)) {
-                    reportSurfaceDestroyed();
-                }
-
-                mNewSurfaceNeeded = false;
-                
                 boolean realSizeChanged;
                 boolean reportDrawNeeded;
-                
+
+                int relayoutResult;
+
                 mSurfaceLock.lock();
                 try {
                     mUpdateWindowNeeded = false;
@@ -512,17 +465,21 @@
                     mReportDrawNeeded = false;
                     mDrawingStopped = !visible;
     
-                    final int relayoutResult = mSession.relayout(
+                    if (DEBUG) Log.i(TAG, "Cur surface: " + mSurface);
+
+                    relayoutResult = mSession.relayout(
                         mWindow, mWindow.mSeq, mLayout, mWidth, mHeight,
-                            visible ? VISIBLE : GONE, false, mWinFrame, mContentInsets,
-                            mVisibleInsets, mConfiguration, mSurface);
-                    if ((relayoutResult&WindowManagerImpl.RELAYOUT_FIRST_TIME) != 0) {
+                            visible ? VISIBLE : GONE,
+                            WindowManagerImpl.RELAYOUT_DEFER_SURFACE_DESTROY,
+                            mWinFrame, mContentInsets,
+                            mVisibleInsets, mConfiguration, mNewSurface);
+                    if ((relayoutResult&WindowManagerImpl.RELAYOUT_RES_FIRST_TIME) != 0) {
                         mReportDrawNeeded = true;
                     }
-                    
-                    if (localLOGV) Log.i(TAG, "New surface: " + mSurface
+
+                    if (DEBUG) Log.i(TAG, "New surface: " + mNewSurface
                             + ", vis=" + visible + ", frame=" + mWinFrame);
-                    
+
                     mSurfaceFrame.left = 0;
                     mSurfaceFrame.top = 0;
                     if (mTranslator == null) {
@@ -547,28 +504,51 @@
                 try {
                     redrawNeeded |= creating | reportDrawNeeded;
 
-                    if (visible) {
-                        mDestroyReportNeeded = true;
+                    SurfaceHolder.Callback callbacks[] = null;
 
-                        SurfaceHolder.Callback callbacks[];
-                        synchronized (mCallbacks) {
-                            callbacks = new SurfaceHolder.Callback[mCallbacks.size()];
-                            mCallbacks.toArray(callbacks);
+                    final boolean surfaceChanged =
+                            (relayoutResult&WindowManagerImpl.RELAYOUT_RES_SURFACE_CHANGED) != 0;
+                    if (mSurfaceCreated && (surfaceChanged || (!visible && visibleChanged))) {
+                        mSurfaceCreated = false;
+                        if (mSurface.isValid()) {
+                            if (DEBUG) Log.i(TAG, "visibleChanged -- surfaceDestroyed");
+                            callbacks = getSurfaceCallbacks();
+                            for (SurfaceHolder.Callback c : callbacks) {
+                                c.surfaceDestroyed(mSurfaceHolder);
+                            }
                         }
+                    }
 
-                        if (visibleChanged) {
+                    mSurface.transferFrom(mNewSurface);
+
+                    if (visible) {
+                        if (!mSurfaceCreated && (surfaceChanged || visibleChanged)) {
+                            mSurfaceCreated = true;
                             mIsCreating = true;
+                            if (DEBUG) Log.i(TAG, "visibleChanged -- surfaceCreated");
+                            if (callbacks == null) {
+                                callbacks = getSurfaceCallbacks();
+                            }
                             for (SurfaceHolder.Callback c : callbacks) {
                                 c.surfaceCreated(mSurfaceHolder);
                             }
                         }
                         if (creating || formatChanged || sizeChanged
                                 || visibleChanged || realSizeChanged) {
+                            if (DEBUG) Log.i(TAG, "surfaceChanged -- format=" + mFormat
+                                    + " w=" + myWidth + " h=" + myHeight);
+                            if (callbacks == null) {
+                                callbacks = getSurfaceCallbacks();
+                            }
                             for (SurfaceHolder.Callback c : callbacks) {
                                 c.surfaceChanged(mSurfaceHolder, mFormat, myWidth, myHeight);
                             }
                         }
                         if (redrawNeeded) {
+                            if (DEBUG) Log.i(TAG, "surfaceRedrawNeeded");
+                            if (callbacks == null) {
+                                callbacks = getSurfaceCallbacks();
+                            }
                             for (SurfaceHolder.Callback c : callbacks) {
                                 if (c instanceof SurfaceHolder.Callback2) {
                                     ((SurfaceHolder.Callback2)c).surfaceRedrawNeeded(
@@ -576,41 +556,34 @@
                                 }
                             }
                         }
-                    } else {
-                        mSurface.release();
                     }
                 } finally {
                     mIsCreating = false;
                     if (redrawNeeded) {
+                        if (DEBUG) Log.i(TAG, "finishedDrawing");
                         mSession.finishDrawing(mWindow);
                     }
+                    mSession.performDeferredDestroy(mWindow);
                 }
             } catch (RemoteException ex) {
             }
-            if (localLOGV) Log.v(
+            if (DEBUG) Log.v(
                 TAG, "Layout: x=" + mLayout.x + " y=" + mLayout.y +
                 " w=" + mLayout.width + " h=" + mLayout.height +
                 ", frame=" + mSurfaceFrame);
         }
     }
 
-    private void reportSurfaceDestroyed() {
-        if (mDestroyReportNeeded) {
-            mDestroyReportNeeded = false;
-            SurfaceHolder.Callback callbacks[];
-            synchronized (mCallbacks) {
-                callbacks = new SurfaceHolder.Callback[mCallbacks.size()];
-                mCallbacks.toArray(callbacks);
-            }            
-            for (SurfaceHolder.Callback c : callbacks) {
-                c.surfaceDestroyed(mSurfaceHolder);
-            }
+    private SurfaceHolder.Callback[] getSurfaceCallbacks() {
+        SurfaceHolder.Callback callbacks[];
+        synchronized (mCallbacks) {
+            callbacks = new SurfaceHolder.Callback[mCallbacks.size()];
+            mCallbacks.toArray(callbacks);
         }
-        super.onDetachedFromWindow();
+        return callbacks;
     }
 
     void handleGetNewSurface() {
-        mNewSurfaceNeeded = true;
         updateWindow(false, false);
     }
 
@@ -636,7 +609,7 @@
                 Rect visibleInsets, boolean reportDraw, Configuration newConfig) {
             SurfaceView surfaceView = mSurfaceView.get();
             if (surfaceView != null) {
-                if (localLOGV) Log.v(
+                if (DEBUG) Log.v(
                         "SurfaceView", surfaceView + " got resized: w=" +
                                 w + " h=" + h + ", cur w=" + mCurWidth + " h=" + mCurHeight);
                 surfaceView.mSurfaceLock.lock();
@@ -754,7 +727,7 @@
         private final Canvas internalLockCanvas(Rect dirty) {
             mSurfaceLock.lock();
 
-            if (localLOGV) Log.i(TAG, "Locking canvas... stopped="
+            if (DEBUG) Log.i(TAG, "Locking canvas... stopped="
                     + mDrawingStopped + ", win=" + mWindow);
 
             Canvas c = null;
@@ -774,7 +747,7 @@
                 }
             }
 
-            if (localLOGV) Log.i(TAG, "Returned canvas: " + c);
+            if (DEBUG) Log.i(TAG, "Returned canvas: " + c);
             if (c != null) {
                 mLastLockTime = SystemClock.uptimeMillis();
                 return c;
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 42b9b3a..5c93a42 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -8115,9 +8115,9 @@
     /**
      * If some part of this view is not clipped by any of its parents, then
      * return that area in r in global (root) coordinates. To convert r to local
-     * coordinates, offset it by -globalOffset (e.g. r.offset(-globalOffset.x,
-     * -globalOffset.y)) If the view is completely clipped or translated out,
-     * return false.
+     * coordinates (without taking possible View rotations into account), offset
+     * it by -globalOffset (e.g. r.offset(-globalOffset.x, -globalOffset.y)).
+     * If the view is completely clipped or translated out, return false.
      *
      * @param r If true is returned, r holds the global coordinates of the
      *        visible portion of this view.
@@ -10196,13 +10196,24 @@
 
         switch (mLayerType) {
             case LAYER_TYPE_HARDWARE:
-                getHardwareLayer();
+                if (mAttachInfo.mHardwareRenderer != null &&
+                        mAttachInfo.mHardwareRenderer.isEnabled() &&
+                        mAttachInfo.mHardwareRenderer.validate()) {
+                    getHardwareLayer();
+                }
                 break;
             case LAYER_TYPE_SOFTWARE:
                 buildDrawingCache(true);
                 break;
         }
     }
+    
+    // Make sure the HardwareRenderer.validate() was invoked before calling this method
+    void flushLayer() {
+        if (mLayerType == LAYER_TYPE_HARDWARE && mHardwareLayer != null) {
+            mHardwareLayer.flush();
+        }
+    }
 
     /**
      * <p>Returns a hardware layer that can be used to draw this view again
@@ -10215,6 +10226,8 @@
                 !mAttachInfo.mHardwareRenderer.isEnabled()) {
             return null;
         }
+        
+        if (!mAttachInfo.mHardwareRenderer.validate()) return null;
 
         final int width = mRight - mLeft;
         final int height = mBottom - mTop;
@@ -10289,12 +10302,15 @@
      */
     boolean destroyLayer() {
         if (mHardwareLayer != null) {
-            mHardwareLayer.destroy();
-            mHardwareLayer = null;
+            AttachInfo info = mAttachInfo;
+            if (info != null && info.mHardwareRenderer != null &&
+                    info.mHardwareRenderer.isEnabled() && info.mHardwareRenderer.validate()) {
+                mHardwareLayer.destroy();
+                mHardwareLayer = null;
 
-            invalidate(true);
-            invalidateParentCaches();
-
+                invalidate(true);
+                invalidateParentCaches();
+            }
             return true;
         }
         return false;
@@ -12205,34 +12221,50 @@
      */
     public void getLocationInWindow(int[] location) {
         if (location == null || location.length < 2) {
-            throw new IllegalArgumentException("location must be an array of "
-                    + "two integers");
+            throw new IllegalArgumentException("location must be an array of two integers");
         }
 
-        location[0] = mLeft;
-        location[1] = mTop;
-        if (mTransformationInfo != null) {
-            location[0] += (int) (mTransformationInfo.mTranslationX + 0.5f);
-            location[1] += (int) (mTransformationInfo.mTranslationY + 0.5f);
+        if (mAttachInfo == null) {
+            // When the view is not attached to a window, this method does not make sense
+            location[0] = location[1] = 0;
+            return;
         }
 
+        float[] position = mAttachInfo.mTmpTransformLocation;
+        position[0] = position[1] = 0.0f;
+
+        if (!hasIdentityMatrix()) {
+            getMatrix().mapPoints(position);
+        }
+
+        position[0] += mLeft;
+        position[1] += mTop;
+
         ViewParent viewParent = mParent;
         while (viewParent instanceof View) {
-            final View view = (View)viewParent;
-            location[0] += view.mLeft - view.mScrollX;
-            location[1] += view.mTop - view.mScrollY;
-            if (view.mTransformationInfo != null) {
-                location[0] += (int) (view.mTransformationInfo.mTranslationX + 0.5f);
-                location[1] += (int) (view.mTransformationInfo.mTranslationY + 0.5f);
+            final View view = (View) viewParent;
+
+            position[0] -= view.mScrollX;
+            position[1] -= view.mScrollY;
+
+            if (!view.hasIdentityMatrix()) {
+                view.getMatrix().mapPoints(position);
             }
+
+            position[0] += view.mLeft;
+            position[1] += view.mTop;
+
             viewParent = view.mParent;
         }
 
         if (viewParent instanceof ViewRootImpl) {
             // *cough*
-            final ViewRootImpl vr = (ViewRootImpl)viewParent;
-            location[1] -= vr.mCurScrollY;
+            final ViewRootImpl vr = (ViewRootImpl) viewParent;
+            position[1] -= vr.mCurScrollY;
         }
+
+        location[0] = (int) (position[0] + 0.5f);
+        location[1] = (int) (position[1] + 0.5f);
     }
 
     /**
diff --git a/core/java/android/view/ViewConfiguration.java b/core/java/android/view/ViewConfiguration.java
index d824e36..b455ad5 100644
--- a/core/java/android/view/ViewConfiguration.java
+++ b/core/java/android/view/ViewConfiguration.java
@@ -139,9 +139,17 @@
     private static final int EDGE_SLOP = 12;
     
     /**
-     * Distance a touch can wander before we think the user is scrolling in dips
+     * Distance a touch can wander before we think the user is scrolling in dips.
+     * Note that this value defined here is only used as a fallback by legacy/misbehaving
+     * applications that do not provide a Context for determining density/configuration-dependent
+     * values.
+     *
+     * To alter this value, see the configuration resource config_viewConfigurationTouchSlop
+     * in frameworks/base/core/res/res/values/config.xml or the appropriate device resource overlay.
+     * It may be appropriate to tweak this on a device-specific basis in an overlay based on
+     * the characteristics of the touch panel and firmware.
      */
-    private static final int TOUCH_SLOP = 16;
+    private static final int TOUCH_SLOP = 8;
     
     /**
      * Distance the first touch can wander before we stop considering this event a double tap
@@ -152,6 +160,14 @@
     /**
      * Distance a touch can wander before we think the user is attempting a paged scroll
      * (in dips)
+     *
+     * Note that this value defined here is only used as a fallback by legacy/misbehaving
+     * applications that do not provide a Context for determining density/configuration-dependent
+     * values.
+     *
+     * See the note above on {@link #TOUCH_SLOP} regarding the dimen resource
+     * config_viewConfigurationTouchSlop. ViewConfiguration will report a paging touch slop of
+     * config_viewConfigurationTouchSlop * 2 when provided with a Context.
      */
     private static final int PAGING_TOUCH_SLOP = TOUCH_SLOP * 2;
     
@@ -285,9 +301,6 @@
         mMinimumFlingVelocity = (int) (density * MINIMUM_FLING_VELOCITY + 0.5f);
         mMaximumFlingVelocity = (int) (density * MAXIMUM_FLING_VELOCITY + 0.5f);
         mScrollbarSize = (int) (density * SCROLL_BAR_SIZE + 0.5f);
-        mTouchSlop = (int) (sizeAndDensity * TOUCH_SLOP + 0.5f);
-        mDoubleTapTouchSlop = (int) (sizeAndDensity * DOUBLE_TAP_TOUCH_SLOP + 0.5f);
-        mPagingTouchSlop = (int) (sizeAndDensity * PAGING_TOUCH_SLOP + 0.5f);
         mDoubleTapSlop = (int) (sizeAndDensity * DOUBLE_TAP_SLOP + 0.5f);
         mScaledTouchExplorationTapSlop = (int) (density * TOUCH_EXPLORATION_TAP_SLOP + 0.5f);
         mWindowTouchSlop = (int) (sizeAndDensity * WINDOW_TOUCH_SLOP + 0.5f);
@@ -310,6 +323,11 @@
 
         mFadingMarqueeEnabled = res.getBoolean(
                 com.android.internal.R.bool.config_ui_enableFadingMarquee);
+        mTouchSlop = res.getDimensionPixelSize(
+                com.android.internal.R.dimen.config_viewConfigurationTouchSlop);
+        mPagingTouchSlop = mTouchSlop * 2;
+
+        mDoubleTapTouchSlop = mTouchSlop;
     }
 
     /**
diff --git a/core/java/android/view/ViewDebug.java b/core/java/android/view/ViewDebug.java
index 65e72c9..c1db572 100644
--- a/core/java/android/view/ViewDebug.java
+++ b/core/java/android/view/ViewDebug.java
@@ -127,16 +127,19 @@
      * Logs the relative difference between the time an event was created and the time it
      * was delivered.
      *
-     * Logs the time spent waiting for Surface.lockCanvas() or eglSwapBuffers().
-     * This is time that the event loop spends blocked and unresponsive.  Ideally, drawing
-     * and animations should be perfectly synchronized with VSYNC so that swap buffers
-     * is instantaneous.
+     * Logs the time spent waiting for Surface.lockCanvas(), Surface.unlockCanvasAndPost()
+     * or eglSwapBuffers().  This is time that the event loop spends blocked and unresponsive.
+     * Ideally, drawing and animations should be perfectly synchronized with VSYNC so that
+     * dequeuing and queueing buffers is instantaneous.
      *
-     * Logs the time spent in ViewRoot.performTraversals() or ViewRoot.draw().
+     * Logs the time spent in ViewRoot.performTraversals() and ViewRoot.performDraw().
      * @hide
      */
     public static final boolean DEBUG_LATENCY = false;
 
+    /** @hide */
+    public static final String DEBUG_LATENCY_TAG = "ViewLatency";
+
     /**
      * <p>Enables or disables views consistency check. Even when this property is enabled,
      * view consistency checks happen only if {@link false} is set
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index e366e72..1102a47 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -79,7 +79,7 @@
 public abstract class ViewGroup extends View implements ViewParent, ViewManager {
 
     private static final boolean DBG = false;
-    
+
     /**
      * Views which have been hidden or removed which need to be animated on
      * their way out.
@@ -2719,13 +2719,6 @@
             return more;
         }
 
-        float alpha = child.getAlpha();
-        // Bail out early if the view does not need to be drawn
-        if (alpha <= ViewConfiguration.ALPHA_THRESHOLD && (child.mPrivateFlags & ALPHA_SET) == 0 &&
-                !(child instanceof SurfaceView)) {
-            return more;
-        }
-
         if (hardwareAccelerated) {
             // Clear INVALIDATED flag to allow invalidation to occur during rendering, but
             // retain the flag's value temporarily in the mRecreateDisplayList flag
@@ -2779,6 +2772,7 @@
             }
         }
 
+        float alpha = child.getAlpha();
         if (transformToApply != null || alpha < 1.0f || !child.hasIdentityMatrix()) {
             if (transformToApply != null || !childHasIdentityMatrix) {
                 int transX = 0;
@@ -2958,6 +2952,17 @@
             mDrawLayers = enabled;
             invalidate(true);
 
+            boolean flushLayers = !enabled;
+            AttachInfo info = mAttachInfo;
+            if (info != null && info.mHardwareRenderer != null &&
+                    info.mHardwareRenderer.isEnabled()) {
+                if (!info.mHardwareRenderer.validate()) {
+                    flushLayers = false;
+                }
+            } else {
+                flushLayers = false;
+            }
+
             // We need to invalidate any child with a layer. For instance,
             // if a child is backed by a hardware layer and we disable layers
             // the child is marked as not dirty (flags cleared the last time
@@ -2968,6 +2973,7 @@
             for (int i = 0; i < mChildrenCount; i++) {
                 View child = mChildren[i];
                 if (child.mLayerType != LAYER_TYPE_NONE) {
+                    if (flushLayers) child.flushLayer();
                     child.invalidate(true);
                 }
             }
@@ -3949,8 +3955,11 @@
                 } while (parent != null);
             } else {
                 // Check whether the child that requests the invalidate is fully opaque
+                // Views being animated or transformed are not considered opaque because we may
+                // be invalidating their old position and need the parent to paint behind them.
+                Matrix childMatrix = child.getMatrix();
                 final boolean isOpaque = child.isOpaque() && !drawAnimation &&
-                        child.getAnimation() == null;
+                        child.getAnimation() == null && childMatrix.isIdentity();
                 // Mark the child as dirty, using the appropriate flag
                 // Make sure we do not set both flags at the same time
                 int opaqueFlag = isOpaque ? DIRTY_OPAQUE : DIRTY;
@@ -3964,7 +3973,6 @@
                 final int[] location = attachInfo.mInvalidateChildLocation;
                 location[CHILD_LEFT_INDEX] = child.mLeft;
                 location[CHILD_TOP_INDEX] = child.mTop;
-                Matrix childMatrix = child.getMatrix();
                 if (!childMatrix.isIdentity()) {
                     RectF boundingRect = attachInfo.mTmpTransformRect;
                     boundingRect.set(dirty);
@@ -4182,15 +4190,42 @@
      * {@inheritDoc}
      */
     public boolean getChildVisibleRect(View child, Rect r, android.graphics.Point offset) {
+        // The View is not attached to a window, 'visible' does not make sense, return false
+        if (mAttachInfo == null) return false;
+
+        final RectF rect = mAttachInfo.mTmpTransformRect;
+        rect.set(r);
+
+        if (!child.hasIdentityMatrix()) {
+           child.getMatrix().mapRect(rect);
+        }
+
         int dx = child.mLeft - mScrollX;
         int dy = child.mTop - mScrollY;
+
+        rect.offset(dx, dy);
+
         if (offset != null) {
+            if (!child.hasIdentityMatrix()) {
+                float[] position = mAttachInfo.mTmpTransformLocation;
+                position[0] = offset.x;
+                position[1] = offset.y;
+                child.getMatrix().mapPoints(position);
+                offset.x = (int) (position[0] + 0.5f);
+                offset.y = (int) (position[1] + 0.5f);
+            }
             offset.x += dx;
             offset.y += dy;
         }
-        r.offset(dx, dy);
-        return r.intersect(0, 0, mRight - mLeft, mBottom - mTop) &&
-               (mParent == null || mParent.getChildVisibleRect(this, r, offset));
+
+        if (rect.intersect(0, 0, mRight - mLeft, mBottom - mTop)) {
+            if (mParent == null) return true;
+            r.set((int) (rect.left + 0.5f), (int) (rect.top + 0.5f),
+                    (int) (rect.right + 0.5f), (int) (rect.bottom + 0.5f));
+            return mParent.getChildVisibleRect(this, r, offset);
+        }
+
+        return false;
     }
 
     /**
diff --git a/core/java/android/view/ViewParent.java b/core/java/android/view/ViewParent.java
index 655df39..873d4bb 100644
--- a/core/java/android/view/ViewParent.java
+++ b/core/java/android/view/ViewParent.java
@@ -63,16 +63,16 @@
     /**
      * All or part of a child is dirty and needs to be redrawn.
      *
-     * The location array is an array of two int values which respectively
-     * define the left and the top position of the dirty child.
+     * <p>The location array is an array of two int values which respectively
+     * define the left and the top position of the dirty child.</p>
      *
-     * This method must return the parent of this ViewParent if the specified
+     * <p>This method must return the parent of this ViewParent if the specified
      * rectangle must be invalidated in the parent. If the specified rectangle
      * does not require invalidation in the parent or if the parent does not
-     * exist, this method must return null.
+     * exist, this method must return null.</p>
      *
-     * When this method returns a non-null value, the location array must
-     * have been updated with the left and top coordinates of this ViewParent.
+     * <p>When this method returns a non-null value, the location array must
+     * have been updated with the left and top coordinates of this ViewParent.</p>
      *
      * @param location An array of 2 ints containing the left and top
      *        coordinates of the child to invalidate
@@ -115,6 +115,26 @@
      */
     public void clearChildFocus(View child);
 
+    /**
+     * Compute the visible part of a rectangular region defined in terms of a child view's
+     * coordinates.
+     *
+     * <p>Returns the clipped visible part of the rectangle <code>r</code>, defined in the
+     * <code>child</code>'s local coordinate system. <code>r</code> is modified by this method to
+     * contain the result, expressed in the global (root) coordinate system.</p>
+     *
+     * <p>The resulting rectangle is always axis aligned. If a rotation is applied to a node in the
+     * View hierarchy, the result is the axis-aligned bounding box of the visible rectangle.</p>
+     *
+     * @param child A child View, whose rectangular visible region we want to compute
+     * @param r The input rectangle, defined in the child coordinate system. Will be overwritten to
+     * contain the resulting visible rectangle, expressed in global (root) coordinates
+     * @param offset The input coordinates of a point, defined in the child coordinate system.
+     * As with the <code>r</code> parameter, this will be overwritten to contain the global (root)
+     * coordinates of that point.
+     * A <code>null</code> value is valid (in case you are not interested in this result)
+     * @return true if the resulting rectangle is not empty, false otherwise
+     */
     public boolean getChildVisibleRect(View child, Rect r, android.graphics.Point offset);
 
     /**
@@ -143,11 +163,11 @@
 
     /**
      * Bring up a context menu for the specified view or its ancestors.
-     * <p>
-     * In most cases, a subclass does not need to override this.  However, if
+     *
+     * <p>In most cases, a subclass does not need to override this.  However, if
      * the subclass is added directly to the window manager (for example,
      * {@link ViewManager#addView(View, android.view.ViewGroup.LayoutParams)})
-     * then it should override this and show the context menu.
+     * then it should override this and show the context menu.</p>
      * 
      * @param originalView The source view where the context menu was first invoked
      * @return true if a context menu was displayed
@@ -164,11 +184,11 @@
 
     /**
      * Start an action mode for the specified view.
-     * <p>
-     * In most cases, a subclass does not need to override this. However, if the
+     *
+     * <p>In most cases, a subclass does not need to override this. However, if the
      * subclass is added directly to the window manager (for example,
      * {@link ViewManager#addView(View, android.view.ViewGroup.LayoutParams)})
-     * then it should override this and start the action mode.
+     * then it should override this and start the action mode.</p>
      *
      * @param originalView The source view where the action mode was first invoked
      * @param callback The callback that will handle lifecycle events for the action mode
@@ -188,10 +208,10 @@
      * Called when a child does not want this parent and its ancestors to
      * intercept touch events with
      * {@link ViewGroup#onInterceptTouchEvent(MotionEvent)}.
-     * <p>
-     * This parent should pass this call onto its parents. This parent must obey
+     *
+     * <p>This parent should pass this call onto its parents. This parent must obey
      * this request for the duration of the touch (that is, only clear the flag
-     * after this parent has received an up or a cancel.
+     * after this parent has received an up or a cancel.</p>
      * 
      * @param disallowIntercept True if the child does not want the parent to
      *            intercept touch events.
@@ -234,7 +254,7 @@
      *       the sending. The parent can optionally add a record for itself before
      *       dispatching the request to its parent. A parent can also choose not to
      *       respect the request for sending the event. The accessibility event is sent
-     *       by the topmost view in the view tree.
+     *       by the topmost view in the view tree.</p>
      *
      * @param child The child which requests sending the event.
      * @param event The event to be sent.
diff --git a/core/java/android/view/ViewPropertyAnimator.java b/core/java/android/view/ViewPropertyAnimator.java
index 84dc7d8..89a1ef2 100644
--- a/core/java/android/view/ViewPropertyAnimator.java
+++ b/core/java/android/view/ViewPropertyAnimator.java
@@ -837,6 +837,11 @@
          */
         @Override
         public void onAnimationUpdate(ValueAnimator animation) {
+            PropertyBundle propertyBundle = mAnimatorMap.get(animation);
+            if (propertyBundle == null) {
+                // Shouldn't happen, but just to play it safe
+                return;
+            }
             // alpha requires slightly different treatment than the other (transform) properties.
             // The logic in setAlpha() is not simply setting mAlpha, plus the invalidation
             // logic is dependent on how the view handles an internal call to onSetAlpha().
@@ -845,7 +850,6 @@
             boolean alphaHandled = false;
             mView.invalidateParentCaches();
             float fraction = animation.getAnimatedFraction();
-            PropertyBundle propertyBundle = mAnimatorMap.get(animation);
             int propertyMask = propertyBundle.mPropertyMask;
             if ((propertyMask & TRANSFORM_MASK) != 0) {
                 mView.invalidate(false);
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 18d5c40..7a9d82c 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -96,7 +96,8 @@
  */
 @SuppressWarnings({"EmptyCatchBlock", "PointlessBooleanExpression"})
 public final class ViewRootImpl extends Handler implements ViewParent,
-        View.AttachInfo.Callbacks, HardwareRenderer.HardwareDrawCallbacks {
+        View.AttachInfo.Callbacks, HardwareRenderer.HardwareDrawCallbacks,
+        Choreographer.OnDrawListener {
     private static final String TAG = "ViewRootImpl";
     private static final boolean DBG = false;
     private static final boolean LOCAL_LOGV = false;
@@ -110,7 +111,6 @@
     private static final boolean DEBUG_IMF = false || LOCAL_LOGV;
     private static final boolean DEBUG_CONFIGURATION = false || LOCAL_LOGV;
     private static final boolean DEBUG_FPS = false;
-    private static final boolean WATCH_POINTER = false;
 
     /**
      * Set this system property to true to force the view hierarchy to render
@@ -154,9 +154,6 @@
     final TypedValue mTmpValue = new TypedValue();
     
     final InputMethodCallback mInputMethodCallback;
-    final SparseArray<Object> mPendingEvents = new SparseArray<Object>();
-    int mPendingEventSeq = 0;
-
     final Thread mThread;
 
     final WindowLeaked mLocation;
@@ -204,13 +201,14 @@
     InputQueue.Callback mInputQueueCallback;
     InputQueue mInputQueue;
     FallbackEventHandler mFallbackEventHandler;
+    Choreographer mChoreographer;
     
     final Rect mTempRect; // used in the transaction to not thrash the heap.
     final Rect mVisRect; // used to retrieve visible rect of focused view.
 
     boolean mTraversalScheduled;
     long mLastTraversalFinishedTimeNanos;
-    long mLastDrawDurationNanos;
+    long mLastDrawFinishedTimeNanos;
     boolean mWillDrawSoon;
     boolean mLayoutRequested;
     boolean mFirst;
@@ -219,7 +217,16 @@
     boolean mNewSurfaceNeeded;
     boolean mHasHadWindowFocus;
     boolean mLastWasImTarget;
-    InputEventMessage mPendingInputEvents = null;
+
+    // Pool of queued input events.
+    private static final int MAX_QUEUED_INPUT_EVENT_POOL_SIZE = 10;
+    private QueuedInputEvent mQueuedInputEventPool;
+    private int mQueuedInputEventPoolSize;
+
+    // Input event queue.
+    QueuedInputEvent mFirstPendingInputEvent;
+    QueuedInputEvent mCurrentInputEvent;
+    boolean mProcessInputEventsScheduled;
 
     boolean mWindowAttributesChanged = false;
     int mWindowAttributesChangesFlag = 0;
@@ -368,6 +375,7 @@
         mFallbackEventHandler = PolicyManager.makeNewFallbackEventHandler(context);
         mProfileRendering = Boolean.parseBoolean(
                 SystemProperties.get(PROPERTY_PROFILE_RENDERING, "false"));
+        mChoreographer = Choreographer.getInstance();
     }
 
     public static void addFirstDrawHandler(Runnable callback) {
@@ -419,6 +427,8 @@
     public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {
         synchronized (this) {
             if (mView == null) {
+                mChoreographer.addOnDrawListener(this);
+
                 mView = view;
                 mFallbackEventHandler.setView(view);
                 mWindowAttributes.copyFrom(attrs);
@@ -552,8 +562,8 @@
                         mInputQueue = new InputQueue(mInputChannel);
                         mInputQueueCallback.onInputQueueCreated(mInputQueue);
                     } else {
-                        InputQueue.registerInputChannel(mInputChannel, mInputHandler,
-                                Looper.myQueue());
+                        mInputEventReceiver = new WindowInputEventReceiver(mInputChannel,
+                                Looper.myLooper());
                     }
                 }
 
@@ -788,23 +798,19 @@
     public void scheduleTraversals() {
         if (!mTraversalScheduled) {
             mTraversalScheduled = true;
-
-            //noinspection ConstantConditions
-            if (ViewDebug.DEBUG_LATENCY && mLastTraversalFinishedTimeNanos != 0) {
-                final long now = System.nanoTime();
-                Log.d(TAG, "Latency: Scheduled traversal, it has been "
-                        + ((now - mLastTraversalFinishedTimeNanos) * 0.000001f)
-                        + "ms since the last traversal finished.");
-            }
-
-            sendEmptyMessage(DO_TRAVERSAL);
+            mChoreographer.scheduleDraw();
         }
     }
 
     public void unscheduleTraversals() {
+        mTraversalScheduled = false;
+    }
+
+    @Override
+    public void onDraw() {
         if (mTraversalScheduled) {
             mTraversalScheduled = false;
-            removeMessages(DO_TRAVERSAL);
+            doTraversal();
         }
     }
 
@@ -841,24 +847,45 @@
         }
     }
 
-    private void processInputEvents(boolean outOfOrder) {
-        while (mPendingInputEvents != null) {
-            handleMessage(mPendingInputEvents.mMessage);
-            InputEventMessage tmpMessage = mPendingInputEvents;
-            mPendingInputEvents = mPendingInputEvents.mNext;
-            tmpMessage.recycle();
-            if (outOfOrder) {
-                removeMessages(PROCESS_INPUT_EVENTS);
+    private void doTraversal() {
+        doProcessInputEvents();
+
+        if (mProfile) {
+            Debug.startMethodTracing("ViewAncestor");
+        }
+
+        final long traversalStartTime;
+        if (ViewDebug.DEBUG_LATENCY) {
+            traversalStartTime = System.nanoTime();
+            if (mLastTraversalFinishedTimeNanos != 0) {
+                Log.d(ViewDebug.DEBUG_LATENCY_TAG, "Starting performTraversals(); it has been "
+                        + ((traversalStartTime - mLastTraversalFinishedTimeNanos) * 0.000001f)
+                        + "ms since the last traversals finished.");
+            } else {
+                Log.d(ViewDebug.DEBUG_LATENCY_TAG, "Starting performTraversals().");
             }
         }
+
+        performTraversals();
+
+        if (ViewDebug.DEBUG_LATENCY) {
+            long now = System.nanoTime();
+            Log.d(ViewDebug.DEBUG_LATENCY_TAG, "performTraversals() took "
+                    + ((now - traversalStartTime) * 0.000001f)
+                    + "ms.");
+            mLastTraversalFinishedTimeNanos = now;
+        }
+
+        if (mProfile) {
+            Debug.stopMethodTracing();
+            mProfile = false;
+        }
     }
 
     private void performTraversals() {
         // cache mView since it is used so much below...
         final View host = mView;
 
-        processInputEvents(true);
-
         if (DBG) {
             System.out.println("======================================");
             System.out.println("performTraversals");
@@ -868,10 +895,8 @@
         if (host == null || !mAdded)
             return;
 
-        mTraversalScheduled = false;
         mWillDrawSoon = true;
         boolean windowSizeMayChange = false;
-        boolean fullRedrawNeeded = mFullRedrawNeeded;
         boolean newSurface = false;
         boolean surfaceChanged = false;
         WindowManager.LayoutParams lp = mWindowAttributes;
@@ -896,7 +921,7 @@
         CompatibilityInfo compatibilityInfo = mCompatibilityInfo.get();
         if (compatibilityInfo.supportsScreen() == mLastInCompatMode) {
             params = lp;
-            fullRedrawNeeded = true;
+            mFullRedrawNeeded = true;
             mLayoutRequested = true;
             if (mLastInCompatMode) {
                 params.flags &= ~WindowManager.LayoutParams.FLAG_COMPATIBLE_WINDOW;
@@ -911,7 +936,7 @@
         
         Rect frame = mWinFrame;
         if (mFirst) {
-            fullRedrawNeeded = true;
+            mFullRedrawNeeded = true;
             mLayoutRequested = true;
 
             if (lp.type == WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL) {
@@ -955,7 +980,7 @@
             if (desiredWindowWidth != mWidth || desiredWindowHeight != mHeight) {
                 if (DEBUG_ORIENTATION) Log.v(TAG,
                         "View " + host + " resized to: " + frame);
-                fullRedrawNeeded = true;
+                mFullRedrawNeeded = true;
                 mLayoutRequested = true;
                 windowSizeMayChange = true;
             }
@@ -1217,7 +1242,8 @@
                         disposeResizeBuffer();
 
                         boolean completed = false;
-                        HardwareCanvas canvas = null;
+                        HardwareCanvas hwRendererCanvas = mAttachInfo.mHardwareRenderer.getCanvas();
+                        HardwareCanvas layerCanvas = null;
                         try {
                             if (mResizeBuffer == null) {
                                 mResizeBuffer = mAttachInfo.mHardwareRenderer.createHardwareLayer(
@@ -1226,12 +1252,12 @@
                                     mResizeBuffer.getHeight() != mHeight) {
                                 mResizeBuffer.resize(mWidth, mHeight);
                             }
-                            canvas = mResizeBuffer.start(mAttachInfo.mHardwareCanvas);
-                            canvas.setViewport(mWidth, mHeight);
-                            canvas.onPreDraw(null);
-                            final int restoreCount = canvas.save();
+                            layerCanvas = mResizeBuffer.start(hwRendererCanvas);
+                            layerCanvas.setViewport(mWidth, mHeight);
+                            layerCanvas.onPreDraw(null);
+                            final int restoreCount = layerCanvas.save();
                             
-                            canvas.drawColor(0xff000000, PorterDuff.Mode.SRC);
+                            layerCanvas.drawColor(0xff000000, PorterDuff.Mode.SRC);
 
                             int yoff;
                             final boolean scrolling = mScroller != null
@@ -1243,27 +1269,27 @@
                                 yoff = mScrollY;
                             }
 
-                            canvas.translate(0, -yoff);
+                            layerCanvas.translate(0, -yoff);
                             if (mTranslator != null) {
-                                mTranslator.translateCanvas(canvas);
+                                mTranslator.translateCanvas(layerCanvas);
                             }
 
-                            mView.draw(canvas);
+                            mView.draw(layerCanvas);
 
                             mResizeBufferStartTime = SystemClock.uptimeMillis();
                             mResizeBufferDuration = mView.getResources().getInteger(
                                     com.android.internal.R.integer.config_mediumAnimTime);
                             completed = true;
 
-                            canvas.restoreToCount(restoreCount);
+                            layerCanvas.restoreToCount(restoreCount);
                         } catch (OutOfMemoryError e) {
                             Log.w(TAG, "Not enough memory for content change anim buffer", e);
                         } finally {
-                            if (canvas != null) {
-                                canvas.onPostDraw();
+                            if (layerCanvas != null) {
+                                layerCanvas.onPostDraw();
                             }
                             if (mResizeBuffer != null) {
-                                mResizeBuffer.end(mAttachInfo.mHardwareCanvas);
+                                mResizeBuffer.end(hwRendererCanvas);
                                 if (!completed) {
                                     mResizeBuffer.destroy();
                                     mResizeBuffer = null;
@@ -1292,7 +1318,7 @@
                         // before actually drawing them, so it can display then
                         // all at once.
                         newSurface = true;
-                        fullRedrawNeeded = true;
+                        mFullRedrawNeeded = true;
                         mPreviousTransparentRegion.setEmpty();
 
                         if (mAttachInfo.mHardwareRenderer != null) {
@@ -1328,7 +1354,7 @@
                     }
                 } else if (surfaceGenerationId != mSurface.getGenerationId() &&
                         mSurfaceHolder == null && mAttachInfo.mHardwareRenderer != null) {
-                    fullRedrawNeeded = true;
+                    mFullRedrawNeeded = true;
                     try {
                         mAttachInfo.mHardwareRenderer.updateSurface(mHolder);
                     } catch (Surface.OutOfResourcesException e) {
@@ -1426,7 +1452,7 @@
 
             if (!mStopped) {
                 boolean focusChangedDueToTouchMode = ensureTouchModeLocally(
-                        (relayoutResult&WindowManagerImpl.RELAYOUT_IN_TOUCH_MODE) != 0);
+                        (relayoutResult&WindowManagerImpl.RELAYOUT_RES_IN_TOUCH_MODE) != 0);
                 if (focusChangedDueToTouchMode || mWidth != host.getMeasuredWidth()
                         || mHeight != host.getMeasuredHeight() || contentInsetsChanged) {
                     childWidthMeasureSpec = getRootMeasureSpec(mWidth, lp.width);
@@ -1614,6 +1640,11 @@
             }
         }
 
+        // Remember if we must report the next draw.
+        if ((relayoutResult & WindowManagerImpl.RELAYOUT_RES_FIRST_TIME) != 0) {
+            mReportNextDraw = true;
+        }
+
         boolean cancelDraw = attachInfo.mTreeObserver.dispatchOnPreDraw() ||
                 viewVisibility != View.VISIBLE;
 
@@ -1624,42 +1655,8 @@
                 }
                 mPendingTransitions.clear();
             }
-            mFullRedrawNeeded = false;
 
-            final long drawStartTime;
-            if (ViewDebug.DEBUG_LATENCY) {
-                drawStartTime = System.nanoTime();
-            }
-
-            draw(fullRedrawNeeded);
-
-            if (ViewDebug.DEBUG_LATENCY) {
-                mLastDrawDurationNanos = System.nanoTime() - drawStartTime;
-            }
-
-            if ((relayoutResult&WindowManagerImpl.RELAYOUT_FIRST_TIME) != 0
-                    || mReportNextDraw) {
-                if (LOCAL_LOGV) {
-                    Log.v(TAG, "FINISHED DRAWING: " + mWindowAttributes.getTitle());
-                }
-                mReportNextDraw = false;
-                if (mSurfaceHolder != null && mSurface.isValid()) {
-                    mSurfaceHolderCallback.surfaceRedrawNeeded(mSurfaceHolder);
-                    SurfaceHolder.Callback callbacks[] = mSurfaceHolder.getCallbacks();
-                    if (callbacks != null) {
-                        for (SurfaceHolder.Callback c : callbacks) {
-                            if (c instanceof SurfaceHolder.Callback2) {
-                                ((SurfaceHolder.Callback2)c).surfaceRedrawNeeded(
-                                        mSurfaceHolder);
-                            }
-                        }
-                    }
-                }
-                try {
-                    sWindowSession.finishDrawing(mWindow);
-                } catch (RemoteException e) {
-                }
-            }
+            performDraw();
         } else {
             // End any pending transitions on this non-visible window
             if (mPendingTransitions != null && mPendingTransitions.size() > 0) {
@@ -1668,14 +1665,6 @@
                 }
                 mPendingTransitions.clear();
             }
-            // We were supposed to report when we are done drawing. Since we canceled the
-            // draw, remember it here.
-            if ((relayoutResult&WindowManagerImpl.RELAYOUT_FIRST_TIME) != 0) {
-                mReportNextDraw = true;
-            }
-            if (fullRedrawNeeded) {
-                mFullRedrawNeeded = true;
-            }
 
             if (viewVisibility == View.VISIBLE) {
                 // Try again
@@ -1819,6 +1808,56 @@
         }
     }
 
+    private void performDraw() {
+        final long drawStartTime;
+        if (ViewDebug.DEBUG_LATENCY) {
+            drawStartTime = System.nanoTime();
+            if (mLastDrawFinishedTimeNanos != 0) {
+                Log.d(ViewDebug.DEBUG_LATENCY_TAG, "Starting draw(); it has been "
+                        + ((drawStartTime - mLastDrawFinishedTimeNanos) * 0.000001f)
+                        + "ms since the last draw finished.");
+            } else {
+                Log.d(ViewDebug.DEBUG_LATENCY_TAG, "Starting draw().");
+            }
+        }
+
+        final boolean fullRedrawNeeded = mFullRedrawNeeded;
+        mFullRedrawNeeded = false;
+        draw(fullRedrawNeeded);
+
+        if (ViewDebug.DEBUG_LATENCY) {
+            long now = System.nanoTime();
+            Log.d(ViewDebug.DEBUG_LATENCY_TAG, "performDraw() took "
+                    + ((now - drawStartTime) * 0.000001f)
+                    + "ms.");
+            mLastDrawFinishedTimeNanos = now;
+        }
+
+        if (mReportNextDraw) {
+            mReportNextDraw = false;
+
+            if (LOCAL_LOGV) {
+                Log.v(TAG, "FINISHED DRAWING: " + mWindowAttributes.getTitle());
+            }
+            if (mSurfaceHolder != null && mSurface.isValid()) {
+                mSurfaceHolderCallback.surfaceRedrawNeeded(mSurfaceHolder);
+                SurfaceHolder.Callback callbacks[] = mSurfaceHolder.getCallbacks();
+                if (callbacks != null) {
+                    for (SurfaceHolder.Callback c : callbacks) {
+                        if (c instanceof SurfaceHolder.Callback2) {
+                            ((SurfaceHolder.Callback2)c).surfaceRedrawNeeded(
+                                    mSurfaceHolder);
+                        }
+                    }
+                }
+            }
+            try {
+                sWindowSession.finishDrawing(mWindow);
+            } catch (RemoteException e) {
+            }
+        }
+    }
+
     private void draw(boolean fullRedrawNeeded) {
         Surface surface = mSurface;
         if (surface == null || !surface.isValid()) {
@@ -1857,8 +1896,9 @@
             mCurScrollY = yoff;
             fullRedrawNeeded = true;
         }
-        float appScale = mAttachInfo.mApplicationScale;
-        boolean scalingRequired = mAttachInfo.mScalingRequired;
+
+        final float appScale = mAttachInfo.mApplicationScale;
+        final boolean scalingRequired = mAttachInfo.mScalingRequired;
 
         int resizeAlpha = 0;
         if (mResizeBuffer != null) {
@@ -1873,7 +1913,7 @@
             }
         }
 
-        Rect dirty = mDirty;
+        final Rect dirty = mDirty;
         if (mSurfaceHolder != null) {
             // The app owns the surface, we won't draw.
             dirty.setEmpty();
@@ -1891,35 +1931,6 @@
             dirty.set(0, 0, (int) (mWidth * appScale + 0.5f), (int) (mHeight * appScale + 0.5f));
         }
 
-        if (mAttachInfo.mHardwareRenderer != null && mAttachInfo.mHardwareRenderer.isEnabled()) {
-            if (!dirty.isEmpty() || mIsAnimating) {
-                mIsAnimating = false;
-                mHardwareYOffset = yoff;
-                mResizeAlpha = resizeAlpha;
-
-                mCurrentDirty.set(dirty);
-                mCurrentDirty.union(mPreviousDirty);
-                mPreviousDirty.set(dirty);
-                dirty.setEmpty();
-
-                Rect currentDirty = mCurrentDirty;
-                if (animating) {
-                    currentDirty = null;
-                }
-
-                if (mAttachInfo.mHardwareRenderer.draw(mView, mAttachInfo, this, currentDirty)) {
-                    mPreviousDirty.set(0, 0, mWidth, mHeight);
-                }
-            }
-
-            if (animating) {
-                mFullRedrawNeeded = true;
-                scheduleTraversals();
-            }
-
-            return;
-        }
-
         if (DEBUG_ORIENTATION || DEBUG_DRAW) {
             Log.v(TAG, "Draw " + mView + "/"
                     + mWindowAttributes.getTitle()
@@ -1930,64 +1941,79 @@
         }
 
         if (!dirty.isEmpty() || mIsAnimating) {
-            Canvas canvas;
-            try {
-                int left = dirty.left;
-                int top = dirty.top;
-                int right = dirty.right;
-                int bottom = dirty.bottom;
+            if (mAttachInfo.mHardwareRenderer != null
+                    && mAttachInfo.mHardwareRenderer.isEnabled()) {
+                // Draw with hardware renderer.
+                mIsAnimating = false;
+                mHardwareYOffset = yoff;
+                mResizeAlpha = resizeAlpha;
 
-                final long lockCanvasStartTime;
-                if (ViewDebug.DEBUG_LATENCY) {
-                    lockCanvasStartTime = System.nanoTime();
+                mCurrentDirty.set(dirty);
+                mCurrentDirty.union(mPreviousDirty);
+                mPreviousDirty.set(dirty);
+                dirty.setEmpty();
+
+                if (mAttachInfo.mHardwareRenderer.draw(mView, mAttachInfo, this,
+                        animating ? null : mCurrentDirty)) {
+                    mPreviousDirty.set(0, 0, mWidth, mHeight);
                 }
-
-                canvas = surface.lockCanvas(dirty);
-
-                if (ViewDebug.DEBUG_LATENCY) {
-                    long now = System.nanoTime();
-                    Log.d(TAG, "Latency: Spent "
-                            + ((now - lockCanvasStartTime) * 0.000001f)
-                            + "ms waiting for surface.lockCanvas()");
-                }
-
-                if (left != dirty.left || top != dirty.top || right != dirty.right ||
-                        bottom != dirty.bottom) {
-                    mAttachInfo.mIgnoreDirtyState = true;
-                }
-
-                // TODO: Do this in native
-                canvas.setDensity(mDensity);
-            } catch (Surface.OutOfResourcesException e) {
-                Log.e(TAG, "OutOfResourcesException locking surface", e);
+            } else {
+                // Draw with software renderer.
+                Canvas canvas;
                 try {
-                    if (!sWindowSession.outOfMemory(mWindow)) {
-                        Slog.w(TAG, "No processes killed for memory; killing self");
-                        Process.killProcess(Process.myPid());
+                    int left = dirty.left;
+                    int top = dirty.top;
+                    int right = dirty.right;
+                    int bottom = dirty.bottom;
+
+                    final long lockCanvasStartTime;
+                    if (ViewDebug.DEBUG_LATENCY) {
+                        lockCanvasStartTime = System.nanoTime();
                     }
-                } catch (RemoteException ex) {
+
+                    canvas = mSurface.lockCanvas(dirty);
+
+                    if (ViewDebug.DEBUG_LATENCY) {
+                        long now = System.nanoTime();
+                        Log.d(ViewDebug.DEBUG_LATENCY_TAG, "- lockCanvas() took "
+                                + ((now - lockCanvasStartTime) * 0.000001f) + "ms");
+                    }
+
+                    if (left != dirty.left || top != dirty.top || right != dirty.right ||
+                            bottom != dirty.bottom) {
+                        mAttachInfo.mIgnoreDirtyState = true;
+                    }
+
+                    // TODO: Do this in native
+                    canvas.setDensity(mDensity);
+                } catch (Surface.OutOfResourcesException e) {
+                    Log.e(TAG, "OutOfResourcesException locking surface", e);
+                    try {
+                        if (!sWindowSession.outOfMemory(mWindow)) {
+                            Slog.w(TAG, "No processes killed for memory; killing self");
+                            Process.killProcess(Process.myPid());
+                        }
+                    } catch (RemoteException ex) {
+                    }
+                    mLayoutRequested = true;    // ask wm for a new surface next time.
+                    return;
+                } catch (IllegalArgumentException e) {
+                    Log.e(TAG, "IllegalArgumentException locking surface", e);
+                    // Don't assume this is due to out of memory, it could be
+                    // something else, and if it is something else then we could
+                    // kill stuff (or ourself) for no reason.
+                    mLayoutRequested = true;    // ask wm for a new surface next time.
+                    return;
                 }
-                mLayoutRequested = true;    // ask wm for a new surface next time.
-                return;
-            } catch (IllegalArgumentException e) {
-                Log.e(TAG, "IllegalArgumentException locking surface", e);
-                // Don't assume this is due to out of memory, it could be
-                // something else, and if it is something else then we could
-                // kill stuff (or ourself) for no reason.
-                mLayoutRequested = true;    // ask wm for a new surface next time.
-                return;
-            }
 
-            try {
-                if (!dirty.isEmpty() || mIsAnimating) {
-                    long startTime = 0L;
-
+                try {
                     if (DEBUG_ORIENTATION || DEBUG_DRAW) {
                         Log.v(TAG, "Surface " + surface + " drawing to bitmap w="
                                 + canvas.getWidth() + ", h=" + canvas.getHeight());
                         //canvas.drawARGB(255, 255, 0, 0);
                     }
 
+                    long startTime = 0L;
                     if (ViewDebug.DEBUG_PROFILE_DRAWING) {
                         startTime = SystemClock.elapsedRealtime();
                     }
@@ -2023,7 +2049,19 @@
                         canvas.setScreenDensity(scalingRequired
                                 ? DisplayMetrics.DENSITY_DEVICE : 0);
                         mAttachInfo.mSetIgnoreDirtyState = false;
+
+                        final long drawStartTime;
+                        if (ViewDebug.DEBUG_LATENCY) {
+                            drawStartTime = System.nanoTime();
+                        }
+
                         mView.draw(canvas);
+
+                        if (ViewDebug.DEBUG_LATENCY) {
+                            long now = System.nanoTime();
+                            Log.d(ViewDebug.DEBUG_LATENCY_TAG, "- draw() took "
+                                    + ((now - drawStartTime) * 0.000001f) + "ms");
+                        }
                     } finally {
                         if (!mAttachInfo.mSetIgnoreDirtyState) {
                             // Only clear the flag if it was not set during the mView.draw() call
@@ -2038,17 +2076,27 @@
                     if (ViewDebug.DEBUG_PROFILE_DRAWING) {
                         EventLog.writeEvent(60000, SystemClock.elapsedRealtime() - startTime);
                     }
+                } finally {
+                    final long unlockCanvasAndPostStartTime;
+                    if (ViewDebug.DEBUG_LATENCY) {
+                        unlockCanvasAndPostStartTime = System.nanoTime();
+                    }
+
+                    surface.unlockCanvasAndPost(canvas);
+
+                    if (ViewDebug.DEBUG_LATENCY) {
+                        long now = System.nanoTime();
+                        Log.d(ViewDebug.DEBUG_LATENCY_TAG, "- unlockCanvasAndPost() took "
+                                + ((now - unlockCanvasAndPostStartTime) * 0.000001f) + "ms");
+                    }
+
+                    if (LOCAL_LOGV) {
+                        Log.v(TAG, "Surface " + surface + " unlockCanvasAndPost");
+                    }
                 }
-
-            } finally {
-                surface.unlockCanvasAndPost(canvas);
             }
         }
 
-        if (LOCAL_LOGV) {
-            Log.v(TAG, "Surface " + surface + " unlockCanvasAndPost");
-        }
-
         if (animating) {
             mFullRedrawNeeded = true;
             scheduleTraversals();
@@ -2265,8 +2313,9 @@
             mInputQueueCallback.onInputQueueDestroyed(mInputQueue);
             mInputQueueCallback = null;
             mInputQueue = null;
-        } else if (mInputChannel != null) {
-            InputQueue.unregisterInputChannel(mInputChannel);
+        } else if (mInputEventReceiver != null) {
+            mInputEventReceiver.dispose();
+            mInputEventReceiver = null;
         }
         try {
             sWindowSession.remove(mWindow);
@@ -2279,6 +2328,8 @@
             mInputChannel.dispose();
             mInputChannel = null;
         }
+
+        mChoreographer.removeOnDrawListener(this);
     }
 
     void updateConfiguration(Configuration config, boolean force) {
@@ -2333,17 +2384,14 @@
         }
     }
 
-    public final static int DO_TRAVERSAL = 1000;
     public final static int DIE = 1001;
     public final static int RESIZED = 1002;
     public final static int RESIZED_REPORT = 1003;
     public final static int WINDOW_FOCUS_CHANGED = 1004;
     public final static int DISPATCH_KEY = 1005;
-    public final static int DISPATCH_POINTER = 1006;
-    public final static int DISPATCH_TRACKBALL = 1007;
     public final static int DISPATCH_APP_VISIBILITY = 1008;
     public final static int DISPATCH_GET_NEW_SURFACE = 1009;
-    public final static int FINISHED_EVENT = 1010;
+    public final static int IME_FINISHED_EVENT = 1010;
     public final static int DISPATCH_KEY_FROM_IME = 1011;
     public final static int FINISH_INPUT_CONNECTION = 1012;
     public final static int CHECK_FOCUS = 1013;
@@ -2357,13 +2405,11 @@
     public final static int DO_FIND_ACCESSIBLITY_NODE_INFO_BY_ACCESSIBILITY_ID = 1021;
     public final static int DO_FIND_ACCESSIBLITY_NODE_INFO_BY_VIEW_ID = 1022;
     public final static int DO_FIND_ACCESSIBLITY_NODE_INFO_BY_TEXT = 1023;
-    public final static int PROCESS_INPUT_EVENTS = 1024;
+    public final static int DO_PROCESS_INPUT_EVENTS = 1024;
 
     @Override
     public String getMessageName(Message message) {
         switch (message.what) {
-            case DO_TRAVERSAL:
-                return "DO_TRAVERSAL";
             case DIE:
                 return "DIE";
             case RESIZED:
@@ -2374,16 +2420,12 @@
                 return "WINDOW_FOCUS_CHANGED";
             case DISPATCH_KEY:
                 return "DISPATCH_KEY";
-            case DISPATCH_POINTER:
-                return "DISPATCH_POINTER";
-            case DISPATCH_TRACKBALL:
-                return "DISPATCH_TRACKBALL";
             case DISPATCH_APP_VISIBILITY:
                 return "DISPATCH_APP_VISIBILITY";
             case DISPATCH_GET_NEW_SURFACE:
                 return "DISPATCH_GET_NEW_SURFACE";
-            case FINISHED_EVENT:
-                return "FINISHED_EVENT";
+            case IME_FINISHED_EVENT:
+                return "IME_FINISHED_EVENT";
             case DISPATCH_KEY_FROM_IME:
                 return "DISPATCH_KEY_FROM_IME";
             case FINISH_INPUT_CONNECTION:
@@ -2410,8 +2452,8 @@
                 return "DO_FIND_ACCESSIBLITY_NODE_INFO_BY_VIEW_ID";
             case DO_FIND_ACCESSIBLITY_NODE_INFO_BY_TEXT:
                 return "DO_FIND_ACCESSIBLITY_NODE_INFO_BY_TEXT";
-            case PROCESS_INPUT_EVENTS:
-                return "PROCESS_INPUT_EVENTS";
+            case DO_PROCESS_INPUT_EVENTS:
+                return "DO_PROCESS_INPUT_EVENTS";
         }
         return super.getMessageName(message);
     }
@@ -2427,51 +2469,12 @@
             info.target.invalidate(info.left, info.top, info.right, info.bottom);
             info.release();
             break;
-        case DO_TRAVERSAL:
-            if (mProfile) {
-                Debug.startMethodTracing("ViewAncestor");
-            }
-
-            final long traversalStartTime;
-            if (ViewDebug.DEBUG_LATENCY) {
-                traversalStartTime = System.nanoTime();
-                mLastDrawDurationNanos = 0;
-            }
-
-            performTraversals();
-
-            if (ViewDebug.DEBUG_LATENCY) {
-                long now = System.nanoTime();
-                Log.d(TAG, "Latency: Spent "
-                        + ((now - traversalStartTime) * 0.000001f)
-                        + "ms in performTraversals(), with "
-                        + (mLastDrawDurationNanos * 0.000001f)
-                        + "ms of that time in draw()");
-                mLastTraversalFinishedTimeNanos = now;
-            }
-
-            if (mProfile) {
-                Debug.stopMethodTracing();
-                mProfile = false;
-            }
+        case IME_FINISHED_EVENT:
+            handleImeFinishedEvent(msg.arg1, msg.arg2 != 0);
             break;
-        case FINISHED_EVENT:
-            handleFinishedEvent(msg.arg1, msg.arg2 != 0);
-            break;
-        case DISPATCH_KEY:
-            deliverKeyEvent((KeyEvent)msg.obj, msg.arg1 != 0);
-            break;
-        case DISPATCH_POINTER:
-            deliverPointerEvent((MotionEvent) msg.obj, msg.arg1 != 0);
-            break;
-        case DISPATCH_TRACKBALL:
-            deliverTrackballEvent((MotionEvent) msg.obj, msg.arg1 != 0);
-            break;
-        case DISPATCH_GENERIC_MOTION:
-            deliverGenericMotionEvent((MotionEvent) msg.obj, msg.arg1 != 0);
-            break;
-        case PROCESS_INPUT_EVENTS:
-            processInputEvents(false);
+        case DO_PROCESS_INPUT_EVENTS:
+            mProcessInputEventsScheduled = false;
+            doProcessInputEvents();
             break;
         case DISPATCH_APP_VISIBILITY:
             handleAppVisibility(msg.arg1 != 0);
@@ -2582,6 +2585,10 @@
         case DIE:
             doDie();
             break;
+        case DISPATCH_KEY: {
+            KeyEvent event = (KeyEvent)msg.obj;
+            enqueueInputEvent(event, null, 0);
+        } break;
         case DISPATCH_KEY_FROM_IME: {
             if (LOCAL_LOGV) Log.v(
                 TAG, "Dispatching key "
@@ -2593,7 +2600,7 @@
                 //noinspection UnusedAssignment
                 event = KeyEvent.changeFlags(event, event.getFlags() & ~KeyEvent.FLAG_FROM_SYSTEM);
             }
-            deliverKeyEventPostIme((KeyEvent)msg.obj, false);
+            enqueueInputEvent(event, null, QueuedInputEvent.FLAG_DELIVER_POST_IME);
         } break;
         case FINISH_INPUT_CONNECTION: {
             InputMethodManager imm = InputMethodManager.peekInstance();
@@ -2655,70 +2662,6 @@
         }
     }
 
-    private void startInputEvent(InputQueue.FinishedCallback finishedCallback) {
-        if (mFinishedCallback != null) {
-            Slog.w(TAG, "Received a new input event from the input queue but there is "
-                    + "already an unfinished input event in progress.");
-        }
-
-        if (ViewDebug.DEBUG_LATENCY) {
-            mInputEventReceiveTimeNanos = System.nanoTime();
-            mInputEventDeliverTimeNanos = 0;
-            mInputEventDeliverPostImeTimeNanos = 0;
-        }
-
-        mFinishedCallback = finishedCallback;
-    }
-
-    private void finishInputEvent(InputEvent event, boolean handled) {
-        if (LOCAL_LOGV) Log.v(TAG, "Telling window manager input event is finished");
-
-        if (mFinishedCallback == null) {
-            Slog.w(TAG, "Attempted to tell the input queue that the current input event "
-                    + "is finished but there is no input event actually in progress.");
-            return;
-        }
-
-        if (ViewDebug.DEBUG_LATENCY) {
-            final long now = System.nanoTime();
-            final long eventTime = event.getEventTimeNano();
-            final StringBuilder msg = new StringBuilder();
-            msg.append("Latency: Spent ");
-            msg.append((now - mInputEventReceiveTimeNanos) * 0.000001f);
-            msg.append("ms processing ");
-            if (event instanceof KeyEvent) {
-                final KeyEvent  keyEvent = (KeyEvent)event;
-                msg.append("key event, action=");
-                msg.append(KeyEvent.actionToString(keyEvent.getAction()));
-            } else {
-                final MotionEvent motionEvent = (MotionEvent)event;
-                msg.append("motion event, action=");
-                msg.append(MotionEvent.actionToString(motionEvent.getAction()));
-                msg.append(", historySize=");
-                msg.append(motionEvent.getHistorySize());
-            }
-            msg.append(", handled=");
-            msg.append(handled);
-            msg.append(", received at +");
-            msg.append((mInputEventReceiveTimeNanos - eventTime) * 0.000001f);
-            if (mInputEventDeliverTimeNanos != 0) {
-                msg.append("ms, delivered at +");
-                msg.append((mInputEventDeliverTimeNanos - eventTime) * 0.000001f);
-            }
-            if (mInputEventDeliverPostImeTimeNanos != 0) {
-                msg.append("ms, delivered post IME at +");
-                msg.append((mInputEventDeliverPostImeTimeNanos - eventTime) * 0.000001f);
-            }
-            msg.append("ms, finished at +");
-            msg.append((now - eventTime) * 0.000001f);
-            msg.append("ms.");
-            Log.d(TAG, msg.toString());
-        }
-
-        mFinishedCallback.finished(handled);
-        mFinishedCallback = null;
-    }
-    
     /**
      * Something in the current window tells us we need to change the touch mode.  For
      * example, we are not in touch mode, and the user touches the screen.
@@ -2840,11 +2783,27 @@
         return false;
     }
 
-    private void deliverPointerEvent(MotionEvent event, boolean sendDone) {
+    private void deliverInputEvent(QueuedInputEvent q) {
         if (ViewDebug.DEBUG_LATENCY) {
-            mInputEventDeliverTimeNanos = System.nanoTime();
+            q.mDeliverTimeNanos = System.nanoTime();
         }
 
+        if (q.mEvent instanceof KeyEvent) {
+            deliverKeyEvent(q);
+        } else {
+            final int source = q.mEvent.getSource();
+            if ((source & InputDevice.SOURCE_CLASS_POINTER) != 0) {
+                deliverPointerEvent(q);
+            } else if ((source & InputDevice.SOURCE_CLASS_TRACKBALL) != 0) {
+                deliverTrackballEvent(q);
+            } else {
+                deliverGenericMotionEvent(q);
+            }
+        }
+    }
+
+    private void deliverPointerEvent(QueuedInputEvent q) {
+        final MotionEvent event = (MotionEvent)q.mEvent;
         final boolean isTouchEvent = event.isTouchEvent();
         if (mInputEventConsistencyVerifier != null) {
             if (isTouchEvent) {
@@ -2856,7 +2815,7 @@
 
         // If there is no view, then the event will not be handled.
         if (mView == null || !mAdded) {
-            finishMotionEvent(event, sendDone, false);
+            finishInputEvent(q, false);
             return;
         }
 
@@ -2891,41 +2850,23 @@
             lt.sample("B Dispatched PointerEvents ", System.nanoTime() - event.getEventTimeNano());
         }
         if (handled) {
-            finishMotionEvent(event, sendDone, true);
+            finishInputEvent(q, true);
             return;
         }
 
         // Pointer event was unhandled.
-        finishMotionEvent(event, sendDone, false);
+        finishInputEvent(q, false);
     }
 
-    private void finishMotionEvent(MotionEvent event, boolean sendDone, boolean handled) {
-        event.recycle();
-        if (sendDone) {
-            finishInputEvent(event, handled);
-        }
-        //noinspection ConstantConditions
-        if (LOCAL_LOGV || WATCH_POINTER) {
-            if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) {
-                Log.i(TAG, "Done dispatching!");
-            }
-        }
-    }
-
-    private void deliverTrackballEvent(MotionEvent event, boolean sendDone) {
-        if (ViewDebug.DEBUG_LATENCY) {
-            mInputEventDeliverTimeNanos = System.nanoTime();
-        }
-
-        if (DEBUG_TRACKBALL) Log.v(TAG, "Motion event:" + event);
-
+    private void deliverTrackballEvent(QueuedInputEvent q) {
+        final MotionEvent event = (MotionEvent)q.mEvent;
         if (mInputEventConsistencyVerifier != null) {
             mInputEventConsistencyVerifier.onTrackballEvent(event, 0);
         }
 
         // If there is no view, then the event will not be handled.
         if (mView == null || !mAdded) {
-            finishMotionEvent(event, sendDone, false);
+            finishInputEvent(q, false);
             return;
         }
 
@@ -2937,7 +2878,7 @@
             // touch mode here.
             ensureTouchMode(false);
 
-            finishMotionEvent(event, sendDone, true);
+            finishInputEvent(q, true);
             mLastTrackballTime = Integer.MIN_VALUE;
             return;
         }
@@ -2961,18 +2902,18 @@
             case MotionEvent.ACTION_DOWN:
                 x.reset(2);
                 y.reset(2);
-                deliverKeyEvent(new KeyEvent(curTime, curTime,
+                dispatchKey(new KeyEvent(curTime, curTime,
                         KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_CENTER, 0, metaState,
                         KeyCharacterMap.VIRTUAL_KEYBOARD, 0, KeyEvent.FLAG_FALLBACK,
-                        InputDevice.SOURCE_KEYBOARD), false);
+                        InputDevice.SOURCE_KEYBOARD));
                 break;
             case MotionEvent.ACTION_UP:
                 x.reset(2);
                 y.reset(2);
-                deliverKeyEvent(new KeyEvent(curTime, curTime,
+                dispatchKey(new KeyEvent(curTime, curTime,
                         KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DPAD_CENTER, 0, metaState,
                         KeyCharacterMap.VIRTUAL_KEYBOARD, 0, KeyEvent.FLAG_FALLBACK,
-                        InputDevice.SOURCE_KEYBOARD), false);
+                        InputDevice.SOURCE_KEYBOARD));
                 break;
         }
 
@@ -3023,38 +2964,35 @@
                         + keycode);
                 movement--;
                 int repeatCount = accelMovement - movement;
-                deliverKeyEvent(new KeyEvent(curTime, curTime,
+                dispatchKey(new KeyEvent(curTime, curTime,
                         KeyEvent.ACTION_MULTIPLE, keycode, repeatCount, metaState,
                         KeyCharacterMap.VIRTUAL_KEYBOARD, 0, KeyEvent.FLAG_FALLBACK,
-                        InputDevice.SOURCE_KEYBOARD), false);
+                        InputDevice.SOURCE_KEYBOARD));
             }
             while (movement > 0) {
                 if (DEBUG_TRACKBALL) Log.v("foo", "Delivering fake DPAD: "
                         + keycode);
                 movement--;
                 curTime = SystemClock.uptimeMillis();
-                deliverKeyEvent(new KeyEvent(curTime, curTime,
+                dispatchKey(new KeyEvent(curTime, curTime,
                         KeyEvent.ACTION_DOWN, keycode, 0, metaState,
                         KeyCharacterMap.VIRTUAL_KEYBOARD, 0, KeyEvent.FLAG_FALLBACK,
-                        InputDevice.SOURCE_KEYBOARD), false);
-                deliverKeyEvent(new KeyEvent(curTime, curTime,
+                        InputDevice.SOURCE_KEYBOARD));
+                dispatchKey(new KeyEvent(curTime, curTime,
                         KeyEvent.ACTION_UP, keycode, 0, metaState,
                         KeyCharacterMap.VIRTUAL_KEYBOARD, 0, KeyEvent.FLAG_FALLBACK,
-                        InputDevice.SOURCE_KEYBOARD), false);
-                }
+                        InputDevice.SOURCE_KEYBOARD));
+            }
             mLastTrackballTime = curTime;
         }
 
         // Unfortunately we can't tell whether the application consumed the keys, so
         // we always consider the trackball event handled.
-        finishMotionEvent(event, sendDone, true);
+        finishInputEvent(q, true);
     }
 
-    private void deliverGenericMotionEvent(MotionEvent event, boolean sendDone) {
-        if (ViewDebug.DEBUG_LATENCY) {
-            mInputEventDeliverTimeNanos = System.nanoTime();
-        }
-
+    private void deliverGenericMotionEvent(QueuedInputEvent q) {
+        final MotionEvent event = (MotionEvent)q.mEvent;
         if (mInputEventConsistencyVerifier != null) {
             mInputEventConsistencyVerifier.onGenericMotionEvent(event, 0);
         }
@@ -3067,7 +3005,7 @@
             if (isJoystick) {
                 updateJoystickDirection(event, false);
             }
-            finishMotionEvent(event, sendDone, false);
+            finishInputEvent(q, false);
             return;
         }
 
@@ -3076,16 +3014,16 @@
             if (isJoystick) {
                 updateJoystickDirection(event, false);
             }
-            finishMotionEvent(event, sendDone, true);
+            finishInputEvent(q, true);
             return;
         }
 
         if (isJoystick) {
             // Translate the joystick event into DPAD keys and try to deliver those.
             updateJoystickDirection(event, true);
-            finishMotionEvent(event, sendDone, true);
+            finishInputEvent(q, true);
         } else {
-            finishMotionEvent(event, sendDone, false);
+            finishInputEvent(q, false);
         }
     }
 
@@ -3107,9 +3045,9 @@
 
         if (xDirection != mLastJoystickXDirection) {
             if (mLastJoystickXKeyCode != 0) {
-                deliverKeyEvent(new KeyEvent(time, time,
+                dispatchKey(new KeyEvent(time, time,
                         KeyEvent.ACTION_UP, mLastJoystickXKeyCode, 0, metaState,
-                        deviceId, 0, KeyEvent.FLAG_FALLBACK, source), false);
+                        deviceId, 0, KeyEvent.FLAG_FALLBACK, source));
                 mLastJoystickXKeyCode = 0;
             }
 
@@ -3118,17 +3056,17 @@
             if (xDirection != 0 && synthesizeNewKeys) {
                 mLastJoystickXKeyCode = xDirection > 0
                         ? KeyEvent.KEYCODE_DPAD_RIGHT : KeyEvent.KEYCODE_DPAD_LEFT;
-                deliverKeyEvent(new KeyEvent(time, time,
+                dispatchKey(new KeyEvent(time, time,
                         KeyEvent.ACTION_DOWN, mLastJoystickXKeyCode, 0, metaState,
-                        deviceId, 0, KeyEvent.FLAG_FALLBACK, source), false);
+                        deviceId, 0, KeyEvent.FLAG_FALLBACK, source));
             }
         }
 
         if (yDirection != mLastJoystickYDirection) {
             if (mLastJoystickYKeyCode != 0) {
-                deliverKeyEvent(new KeyEvent(time, time,
+                dispatchKey(new KeyEvent(time, time,
                         KeyEvent.ACTION_UP, mLastJoystickYKeyCode, 0, metaState,
-                        deviceId, 0, KeyEvent.FLAG_FALLBACK, source), false);
+                        deviceId, 0, KeyEvent.FLAG_FALLBACK, source));
                 mLastJoystickYKeyCode = 0;
             }
 
@@ -3137,9 +3075,9 @@
             if (yDirection != 0 && synthesizeNewKeys) {
                 mLastJoystickYKeyCode = yDirection > 0
                         ? KeyEvent.KEYCODE_DPAD_DOWN : KeyEvent.KEYCODE_DPAD_UP;
-                deliverKeyEvent(new KeyEvent(time, time,
+                dispatchKey(new KeyEvent(time, time,
                         KeyEvent.ACTION_DOWN, mLastJoystickYKeyCode, 0, metaState,
-                        deviceId, 0, KeyEvent.FLAG_FALLBACK, source), false);
+                        deviceId, 0, KeyEvent.FLAG_FALLBACK, source));
             }
         }
     }
@@ -3230,91 +3168,81 @@
         return false;
     }
 
-    int enqueuePendingEvent(Object event, boolean sendDone) {
-        int seq = mPendingEventSeq+1;
-        if (seq < 0) seq = 0;
-        mPendingEventSeq = seq;
-        mPendingEvents.put(seq, event);
-        return sendDone ? seq : -seq;
-    }
-
-    Object retrievePendingEvent(int seq) {
-        if (seq < 0) seq = -seq;
-        Object event = mPendingEvents.get(seq);
-        if (event != null) {
-            mPendingEvents.remove(seq);
-        }
-        return event;
-    }
-
-    private void deliverKeyEvent(KeyEvent event, boolean sendDone) {
-        if (ViewDebug.DEBUG_LATENCY) {
-            mInputEventDeliverTimeNanos = System.nanoTime();
-        }
-
+    private void deliverKeyEvent(QueuedInputEvent q) {
+        final KeyEvent event = (KeyEvent)q.mEvent;
         if (mInputEventConsistencyVerifier != null) {
             mInputEventConsistencyVerifier.onKeyEvent(event, 0);
         }
 
-        // If there is no view, then the event will not be handled.
-        if (mView == null || !mAdded) {
-            finishKeyEvent(event, sendDone, false);
-            return;
-        }
-
-        if (LOCAL_LOGV) Log.v(TAG, "Dispatching key " + event + " to " + mView);
-
-        // Perform predispatching before the IME.
-        if (mView.dispatchKeyEventPreIme(event)) {
-            finishKeyEvent(event, sendDone, true);
-            return;
-        }
-
-        // Dispatch to the IME before propagating down the view hierarchy.
-        // The IME will eventually call back into handleFinishedEvent.
-        if (mLastWasImTarget) {
-            InputMethodManager imm = InputMethodManager.peekInstance();
-            if (imm != null) {
-                int seq = enqueuePendingEvent(event, sendDone);
-                if (DEBUG_IMF) Log.v(TAG, "Sending key event to IME: seq="
-                        + seq + " event=" + event);
-                imm.dispatchKeyEvent(mView.getContext(), seq, event, mInputMethodCallback);
+        if ((q.mFlags & QueuedInputEvent.FLAG_DELIVER_POST_IME) == 0) {
+            // If there is no view, then the event will not be handled.
+            if (mView == null || !mAdded) {
+                finishInputEvent(q, false);
                 return;
             }
+
+            if (LOCAL_LOGV) Log.v(TAG, "Dispatching key " + event + " to " + mView);
+
+            // Perform predispatching before the IME.
+            if (mView.dispatchKeyEventPreIme(event)) {
+                finishInputEvent(q, true);
+                return;
+            }
+
+            // Dispatch to the IME before propagating down the view hierarchy.
+            // The IME will eventually call back into handleImeFinishedEvent.
+            if (mLastWasImTarget) {
+                InputMethodManager imm = InputMethodManager.peekInstance();
+                if (imm != null) {
+                    final int seq = event.getSequenceNumber();
+                    if (DEBUG_IMF) Log.v(TAG, "Sending key event to IME: seq="
+                            + seq + " event=" + event);
+                    imm.dispatchKeyEvent(mView.getContext(), seq, event, mInputMethodCallback);
+                    return;
+                }
+            }
         }
 
         // Not dispatching to IME, continue with post IME actions.
-        deliverKeyEventPostIme(event, sendDone);
+        deliverKeyEventPostIme(q);
     }
 
-    private void handleFinishedEvent(int seq, boolean handled) {
-        final KeyEvent event = (KeyEvent)retrievePendingEvent(seq);
-        if (DEBUG_IMF) Log.v(TAG, "IME finished event: seq=" + seq
-                + " handled=" + handled + " event=" + event);
-        if (event != null) {
-            final boolean sendDone = seq >= 0;
+    void handleImeFinishedEvent(int seq, boolean handled) {
+        final QueuedInputEvent q = mCurrentInputEvent;
+        if (q != null && q.mEvent.getSequenceNumber() == seq) {
+            final KeyEvent event = (KeyEvent)q.mEvent;
+            if (DEBUG_IMF) {
+                Log.v(TAG, "IME finished event: seq=" + seq
+                        + " handled=" + handled + " event=" + event);
+            }
             if (handled) {
-                finishKeyEvent(event, sendDone, true);
+                finishInputEvent(q, true);
             } else {
-                deliverKeyEventPostIme(event, sendDone);
+                deliverKeyEventPostIme(q);
+            }
+        } else {
+            if (DEBUG_IMF) {
+                Log.v(TAG, "IME finished event: seq=" + seq
+                        + " handled=" + handled + ", event not found!");
             }
         }
     }
 
-    private void deliverKeyEventPostIme(KeyEvent event, boolean sendDone) {
+    private void deliverKeyEventPostIme(QueuedInputEvent q) {
+        final KeyEvent event = (KeyEvent)q.mEvent;
         if (ViewDebug.DEBUG_LATENCY) {
-            mInputEventDeliverPostImeTimeNanos = System.nanoTime();
+            q.mDeliverPostImeTimeNanos = System.nanoTime();
         }
 
         // If the view went away, then the event will not be handled.
         if (mView == null || !mAdded) {
-            finishKeyEvent(event, sendDone, false);
+            finishInputEvent(q, false);
             return;
         }
 
         // If the key's purpose is to exit touch mode then we consume it and consider it handled.
         if (checkForLeavingTouchModeAndConsume(event)) {
-            finishKeyEvent(event, sendDone, true);
+            finishInputEvent(q, true);
             return;
         }
 
@@ -3324,7 +3252,7 @@
 
         // Deliver the key to the view hierarchy.
         if (mView.dispatchKeyEvent(event)) {
-            finishKeyEvent(event, sendDone, true);
+            finishInputEvent(q, true);
             return;
         }
 
@@ -3333,14 +3261,14 @@
                 && event.isCtrlPressed()
                 && !KeyEvent.isModifierKey(event.getKeyCode())) {
             if (mView.dispatchKeyShortcutEvent(event)) {
-                finishKeyEvent(event, sendDone, true);
+                finishInputEvent(q, true);
                 return;
             }
         }
 
         // Apply the fallback event policy.
         if (mFallbackEventHandler.dispatchKeyEvent(event)) {
-            finishKeyEvent(event, sendDone, true);
+            finishInputEvent(q, true);
             return;
         }
 
@@ -3395,14 +3323,14 @@
                         if (v.requestFocus(direction, mTempRect)) {
                             playSoundEffect(
                                     SoundEffectConstants.getContantForFocusDirection(direction));
-                            finishKeyEvent(event, sendDone, true);
+                            finishInputEvent(q, true);
                             return;
                         }
                     }
 
                     // Give the focused view a last chance to handle the dpad key.
                     if (mView.dispatchUnhandledMove(focused, direction)) {
-                        finishKeyEvent(event, sendDone, true);
+                        finishInputEvent(q, true);
                         return;
                     }
                 }
@@ -3410,13 +3338,7 @@
         }
 
         // Key was unhandled.
-        finishKeyEvent(event, sendDone, false);
-    }
-
-    private void finishKeyEvent(KeyEvent event, boolean sendDone, boolean handled) {
-        if (sendDone) {
-            finishInputEvent(event, handled);
-        }
+        finishInputEvent(q, false);
     }
 
     /* drag/drop */
@@ -3585,8 +3507,8 @@
                 mWindow, mSeq, params,
                 (int) (mView.getMeasuredWidth() * appScale + 0.5f),
                 (int) (mView.getMeasuredHeight() * appScale + 0.5f),
-                viewVisibility, insetsPending, mWinFrame,
-                mPendingContentInsets, mPendingVisibleInsets,
+                viewVisibility, insetsPending ? WindowManagerImpl.RELAYOUT_INSETS_PENDING : 0,
+                mWinFrame, mPendingContentInsets, mPendingVisibleInsets,
                 mPendingConfiguration, mSurface);
         //Log.d(TAG, "<<<<<< BACK FROM relayout");
         if (restore) {
@@ -3716,7 +3638,7 @@
                     // animation info.
                     try {
                         if ((relayoutWindow(mWindowAttributes, viewVisibility, false)
-                                & WindowManagerImpl.RELAYOUT_FIRST_TIME) != 0) {
+                                & WindowManagerImpl.RELAYOUT_RES_FIRST_TIME) != 0) {
                             sWindowSession.finishDrawing(mWindow);
                         }
                     } catch (RemoteException e) {
@@ -3741,8 +3663,8 @@
         }
     }
 
-    public void dispatchFinishedEvent(int seq, boolean handled) {
-        Message msg = obtainMessage(FINISHED_EVENT);
+    void dispatchImeFinishedEvent(int seq, boolean handled) {
+        Message msg = obtainMessage(IME_FINISHED_EVENT);
         msg.arg1 = seq;
         msg.arg2 = handled ? 1 : 0;
         sendMessage(msg);
@@ -3771,152 +3693,182 @@
         sendMessage(msg);
     }
 
-    private long mInputEventReceiveTimeNanos;
-    private long mInputEventDeliverTimeNanos;
-    private long mInputEventDeliverPostImeTimeNanos;
-    private InputQueue.FinishedCallback mFinishedCallback;
-    
-    private final InputHandler mInputHandler = new InputHandler() {
-        public void handleKey(KeyEvent event, InputQueue.FinishedCallback finishedCallback) {
-            startInputEvent(finishedCallback);
-            dispatchKey(event, true);
-        }
-
-        public void handleMotion(MotionEvent event, InputQueue.FinishedCallback finishedCallback) {
-            startInputEvent(finishedCallback);
-            dispatchMotion(event, true);
-        }
-    };
-
     /**
-     * Utility class used to queue up input events which are then handled during
-     * performTraversals(). Doing it this way allows us to ensure that we are up to date with
-     * all input events just prior to drawing, instead of placing those events on the regular
-     * handler queue, potentially behind a drawing event.
+     * Represents a pending input event that is waiting in a queue.
+     *
+     * Input events are processed in serial order by the timestamp specified by
+     * {@link InputEvent#getEventTime()}.  In general, the input dispatcher delivers
+     * one input event to the application at a time and waits for the application
+     * to finish handling it before delivering the next one.
+     *
+     * However, because the application or IME can synthesize and inject multiple
+     * key events at a time without going through the input dispatcher, we end up
+     * needing a queue on the application's side.
      */
-    static class InputEventMessage {
-        Message mMessage;
-        InputEventMessage mNext;
+    private static final class QueuedInputEvent {
+        public static final int FLAG_DELIVER_POST_IME = 1 << 0;
 
-        private static final Object sPoolSync = new Object();
-        private static InputEventMessage sPool;
-        private static int sPoolSize = 0;
+        public QueuedInputEvent mNext;
 
-        private static final int MAX_POOL_SIZE = 10;
+        public InputEvent mEvent;
+        public InputEventReceiver mReceiver;
+        public int mFlags;
 
-        private InputEventMessage(Message m) {
-            mMessage = m;
-            mNext = null;
-        }
-
-        /**
-         * Return a new Message instance from the global pool. Allows us to
-         * avoid allocating new objects in many cases.
-         */
-        public static InputEventMessage obtain(Message msg) {
-            synchronized (sPoolSync) {
-                if (sPool != null) {
-                    InputEventMessage m = sPool;
-                    sPool = m.mNext;
-                    m.mNext = null;
-                    sPoolSize--;
-                    m.mMessage = msg;
-                    return m;
-                }
-            }
-            return new InputEventMessage(msg);
-        }
-
-        /**
-         * Return the message to the pool.
-         */
-        public void recycle() {
-            mMessage.recycle();
-            synchronized (sPoolSync) {
-                if (sPoolSize < MAX_POOL_SIZE) {
-                    mNext = sPool;
-                    sPool = this;
-                    sPoolSize++;
-                }
-            }
-
-        }
+        // Used for latency calculations.
+        public long mReceiveTimeNanos;
+        public long mDeliverTimeNanos;
+        public long mDeliverPostImeTimeNanos;
     }
 
-    /**
-     * Place the input event message at the end of the current pending list
-     */
-    private void enqueueInputEvent(Message msg, long when) {
-        InputEventMessage inputMessage = InputEventMessage.obtain(msg);
-        if (mPendingInputEvents == null) {
-            mPendingInputEvents = inputMessage;
+    private QueuedInputEvent obtainQueuedInputEvent(InputEvent event,
+            InputEventReceiver receiver, int flags) {
+        QueuedInputEvent q = mQueuedInputEventPool;
+        if (q != null) {
+            mQueuedInputEventPoolSize -= 1;
+            mQueuedInputEventPool = q.mNext;
+            q.mNext = null;
         } else {
-            InputEventMessage currMessage = mPendingInputEvents;
-            while (currMessage.mNext != null) {
-                currMessage = currMessage.mNext;
-            }
-            currMessage.mNext = inputMessage;
+            q = new QueuedInputEvent();
         }
-        sendEmptyMessageAtTime(PROCESS_INPUT_EVENTS, when);
+
+        q.mEvent = event;
+        q.mReceiver = receiver;
+        q.mFlags = flags;
+        return q;
     }
 
+    private void recycleQueuedInputEvent(QueuedInputEvent q) {
+        q.mEvent = null;
+        q.mReceiver = null;
+
+        if (mQueuedInputEventPoolSize < MAX_QUEUED_INPUT_EVENT_POOL_SIZE) {
+            mQueuedInputEventPoolSize += 1;
+            q.mNext = mQueuedInputEventPool;
+            mQueuedInputEventPool = q;
+        }
+    }
+
+    void enqueueInputEvent(InputEvent event,
+            InputEventReceiver receiver, int flags) {
+        QueuedInputEvent q = obtainQueuedInputEvent(event, receiver, flags);
+
+        if (ViewDebug.DEBUG_LATENCY) {
+            q.mReceiveTimeNanos = System.nanoTime();
+            q.mDeliverTimeNanos = 0;
+            q.mDeliverPostImeTimeNanos = 0;
+        }
+
+        // Always enqueue the input event in order, regardless of its time stamp.
+        // We do this because the application or the IME may inject key events
+        // in response to touch events and we want to ensure that the injected keys
+        // are processed in the order they were received and we cannot trust that
+        // the time stamp of injected events are monotonic.
+        QueuedInputEvent last = mFirstPendingInputEvent;
+        if (last == null) {
+            mFirstPendingInputEvent = q;
+        } else {
+            while (last.mNext != null) {
+                last = last.mNext;
+            }
+            last.mNext = q;
+        }
+
+        scheduleProcessInputEvents();
+    }
+
+    private void scheduleProcessInputEvents() {
+        if (!mProcessInputEventsScheduled) {
+            mProcessInputEventsScheduled = true;
+            sendEmptyMessage(DO_PROCESS_INPUT_EVENTS);
+        }
+    }
+
+    private void doProcessInputEvents() {
+        while (mCurrentInputEvent == null && mFirstPendingInputEvent != null) {
+            QueuedInputEvent q = mFirstPendingInputEvent;
+            mFirstPendingInputEvent = q.mNext;
+            q.mNext = null;
+            mCurrentInputEvent = q;
+            deliverInputEvent(q);
+        }
+
+        // We are done processing all input events that we can process right now
+        // so we can clear the pending flag immediately.
+        if (mProcessInputEventsScheduled) {
+            mProcessInputEventsScheduled = false;
+            removeMessages(DO_PROCESS_INPUT_EVENTS);
+        }
+    }
+
+    private void finishInputEvent(QueuedInputEvent q, boolean handled) {
+        if (q != mCurrentInputEvent) {
+            throw new IllegalStateException("finished input event out of order");
+        }
+
+        if (ViewDebug.DEBUG_LATENCY) {
+            final long now = System.nanoTime();
+            final long eventTime = q.mEvent.getEventTimeNano();
+            final StringBuilder msg = new StringBuilder();
+            msg.append("Spent ");
+            msg.append((now - q.mReceiveTimeNanos) * 0.000001f);
+            msg.append("ms processing ");
+            if (q.mEvent instanceof KeyEvent) {
+                final KeyEvent  keyEvent = (KeyEvent)q.mEvent;
+                msg.append("key event, action=");
+                msg.append(KeyEvent.actionToString(keyEvent.getAction()));
+            } else {
+                final MotionEvent motionEvent = (MotionEvent)q.mEvent;
+                msg.append("motion event, action=");
+                msg.append(MotionEvent.actionToString(motionEvent.getAction()));
+                msg.append(", historySize=");
+                msg.append(motionEvent.getHistorySize());
+            }
+            msg.append(", handled=");
+            msg.append(handled);
+            msg.append(", received at +");
+            msg.append((q.mReceiveTimeNanos - eventTime) * 0.000001f);
+            if (q.mDeliverTimeNanos != 0) {
+                msg.append("ms, delivered at +");
+                msg.append((q.mDeliverTimeNanos - eventTime) * 0.000001f);
+            }
+            if (q.mDeliverPostImeTimeNanos != 0) {
+                msg.append("ms, delivered post IME at +");
+                msg.append((q.mDeliverPostImeTimeNanos - eventTime) * 0.000001f);
+            }
+            msg.append("ms, finished at +");
+            msg.append((now - eventTime) * 0.000001f);
+            msg.append("ms.");
+            Log.d(ViewDebug.DEBUG_LATENCY_TAG, msg.toString());
+        }
+
+        if (q.mReceiver != null) {
+            q.mReceiver.finishInputEvent(q.mEvent, handled);
+        } else {
+            q.mEvent.recycleIfNeededAfterDispatch();
+        }
+
+        recycleQueuedInputEvent(q);
+
+        mCurrentInputEvent = null;
+        if (mFirstPendingInputEvent != null) {
+            scheduleProcessInputEvents();
+        }
+    }
+
+    final class WindowInputEventReceiver extends InputEventReceiver {
+        public WindowInputEventReceiver(InputChannel inputChannel, Looper looper) {
+            super(inputChannel, looper);
+        }
+
+        @Override
+        public void onInputEvent(InputEvent event) {
+            enqueueInputEvent(event, this, 0);
+        }
+    }
+    WindowInputEventReceiver mInputEventReceiver;
+
     public void dispatchKey(KeyEvent event) {
-        dispatchKey(event, false);
-    }
-
-    private void dispatchKey(KeyEvent event, boolean sendDone) {
-        //noinspection ConstantConditions
-        if (false && event.getAction() == KeyEvent.ACTION_DOWN) {
-            if (event.getKeyCode() == KeyEvent.KEYCODE_CAMERA) {
-                if (DBG) Log.d("keydisp", "===================================================");
-                if (DBG) Log.d("keydisp", "Focused view Hierarchy is:");
-
-                debug();
-
-                if (DBG) Log.d("keydisp", "===================================================");
-            }
-        }
-
-        Message msg = obtainMessage(DISPATCH_KEY);
-        msg.obj = event;
-        msg.arg1 = sendDone ? 1 : 0;
-
-        if (LOCAL_LOGV) Log.v(
-            TAG, "sending key " + event + " to " + mView);
-
-        enqueueInputEvent(msg, event.getEventTime());
-    }
-    
-    private void dispatchMotion(MotionEvent event, boolean sendDone) {
-        int source = event.getSource();
-        if ((source & InputDevice.SOURCE_CLASS_POINTER) != 0) {
-            dispatchPointer(event, sendDone);
-        } else if ((source & InputDevice.SOURCE_CLASS_TRACKBALL) != 0) {
-            dispatchTrackball(event, sendDone);
-        } else {
-            dispatchGenericMotion(event, sendDone);
-        }
-    }
-
-    private void dispatchPointer(MotionEvent event, boolean sendDone) {
-        Message msg = obtainMessage(DISPATCH_POINTER);
-        msg.obj = event;
-        msg.arg1 = sendDone ? 1 : 0;
-        enqueueInputEvent(msg, event.getEventTime());
-    }
-
-    private void dispatchTrackball(MotionEvent event, boolean sendDone) {
-        Message msg = obtainMessage(DISPATCH_TRACKBALL);
-        msg.obj = event;
-        msg.arg1 = sendDone ? 1 : 0;
-        enqueueInputEvent(msg, event.getEventTime());
-    }
-
-    private void dispatchGenericMotion(MotionEvent event, boolean sendDone) {
-        Message msg = obtainMessage(DISPATCH_GENERIC_MOTION);
-        msg.obj = event;
-        msg.arg1 = sendDone ? 1 : 0;
-        enqueueInputEvent(msg, event.getEventTime());
+        enqueueInputEvent(event, null, 0);
     }
 
     public void dispatchAppVisibility(boolean visible) {
@@ -4098,7 +4050,7 @@
         public void finishedEvent(int seq, boolean handled) {
             final ViewRootImpl viewAncestor = mViewAncestor.get();
             if (viewAncestor != null) {
-                viewAncestor.dispatchFinishedEvent(seq, handled);
+                viewAncestor.dispatchImeFinishedEvent(seq, handled);
             }
         }
 
diff --git a/core/java/android/view/VolumePanel.java b/core/java/android/view/VolumePanel.java
index b657204..48fe0df 100644
--- a/core/java/android/view/VolumePanel.java
+++ b/core/java/android/view/VolumePanel.java
@@ -278,10 +278,6 @@
     }
 
     private void createSliders() {
-        final int silentableStreams = System.getInt(mContext.getContentResolver(),
-                System.MODE_RINGER_STREAMS_AFFECTED,
-                ((1 << AudioSystem.STREAM_NOTIFICATION) | (1 << AudioSystem.STREAM_RING)));
-
         LayoutInflater inflater = (LayoutInflater) mContext
                 .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
         mStreamControls = new HashMap<Integer, StreamControl>(STREAMS.length);
@@ -297,9 +293,6 @@
             sc.group = (ViewGroup) inflater.inflate(R.layout.volume_adjust_item, null);
             sc.group.setTag(sc);
             sc.icon = (ImageView) sc.group.findViewById(R.id.stream_icon);
-            if ((silentableStreams & (1 << sc.streamType)) != 0) {
-                sc.icon.setOnClickListener(this);
-            }
             sc.icon.setTag(sc);
             sc.icon.setContentDescription(res.getString(streamRes.descRes));
             sc.iconRes = streamRes.iconRes;
@@ -356,7 +349,6 @@
                 && mAudioManager.shouldVibrate(AudioManager.VIBRATE_TYPE_RINGER)) {
             sc.icon.setImageResource(R.drawable.ic_audio_ring_notif_vibrate);
         }
-        sc.seekbarView.setEnabled(!muted);
     }
 
     private boolean isExpanded() {
@@ -436,8 +428,6 @@
                 mAudioService.getLastAudibleStreamVolume(streamType)
                 : mAudioService.getStreamVolume(streamType);
 
-//        int message = UNKNOWN_VOLUME_TEXT;
-//        int additionalMessage = 0;
         mRingIsSilent = false;
 
         if (LOGD) {
@@ -697,18 +687,6 @@
     public void onClick(View v) {
         if (v == mMoreButton) {
             expand();
-        } else if (v.getTag() instanceof StreamControl) {
-            StreamControl sc = (StreamControl) v.getTag();
-            boolean vibeInSilent = Settings.System.getInt(mContext.getContentResolver(),
-                    System.VIBRATE_IN_SILENT, 1) == 1;
-            int newMode = mAudioManager.isSilentMode()
-                    ? AudioManager.RINGER_MODE_NORMAL
-                    : (vibeInSilent
-                            ? AudioManager.RINGER_MODE_VIBRATE 
-                            : AudioManager.RINGER_MODE_SILENT);
-            mAudioManager.setRingerMode(newMode);
-            // Expand the dialog if it hasn't been expanded yet.
-            if (mShowCombinedVolumes && !isExpanded()) expand();
         }
         resetTimeout();
     }
diff --git a/core/java/android/view/WindowManagerImpl.java b/core/java/android/view/WindowManagerImpl.java
index dfd1d55..d7113374 100644
--- a/core/java/android/view/WindowManagerImpl.java
+++ b/core/java/android/view/WindowManagerImpl.java
@@ -63,15 +63,34 @@
      * The user is navigating with keys (not the touch screen), so
      * navigational focus should be shown.
      */
-    public static final int RELAYOUT_IN_TOUCH_MODE = 0x1;
+    public static final int RELAYOUT_RES_IN_TOUCH_MODE = 0x1;
     /**
      * This is the first time the window is being drawn,
      * so the client must call drawingFinished() when done
      */
-    public static final int RELAYOUT_FIRST_TIME = 0x2;
-    
+    public static final int RELAYOUT_RES_FIRST_TIME = 0x2;
+    /**
+     * The window manager has changed the surface from the last call.
+     */
+    public static final int RELAYOUT_RES_SURFACE_CHANGED = 0x4;
+
+    /**
+     * Flag for relayout: the client will be later giving
+     * internal insets; as a result, the window will not impact other window
+     * layouts until the insets are given.
+     */
+    public static final int RELAYOUT_INSETS_PENDING = 0x1;
+
+    /**
+     * Flag for relayout: the client may be currently using the current surface,
+     * so if it is to be destroyed as a part of the relayout the destroy must
+     * be deferred until later.  The client will call performDeferredDestroy()
+     * when it is okay.
+     */
+    public static final int RELAYOUT_DEFER_SURFACE_DESTROY = 0x2;
+
     public static final int ADD_FLAG_APP_VISIBLE = 0x2;
-    public static final int ADD_FLAG_IN_TOUCH_MODE = RELAYOUT_IN_TOUCH_MODE;
+    public static final int ADD_FLAG_IN_TOUCH_MODE = RELAYOUT_RES_IN_TOUCH_MODE;
     
     public static final int ADD_OKAY = 0;
     public static final int ADD_BAD_APP_TOKEN = -1;
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index 2e19bf6..7d729c6 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -340,7 +340,8 @@
          * Add a fake window to the window manager.  This window sits
          * at the top of the other windows and consumes events.
          */
-        public FakeWindow addFakeWindow(Looper looper, InputHandler inputHandler,
+        public FakeWindow addFakeWindow(Looper looper,
+                InputEventReceiver.Factory inputEventReceiverFactory,
                 String name, int windowType, int layoutParamsFlags, boolean canReceiveKeys,
                 boolean hasFocus, boolean touchFullscreen);
     }
diff --git a/core/java/android/view/accessibility/AccessibilityEvent.java b/core/java/android/view/accessibility/AccessibilityEvent.java
index 34b4dcc..75b875a 100644
--- a/core/java/android/view/accessibility/AccessibilityEvent.java
+++ b/core/java/android/view/accessibility/AccessibilityEvent.java
@@ -16,7 +16,6 @@
 
 package android.view.accessibility;
 
-import android.accessibilityservice.IAccessibilityServiceConnection;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.text.TextUtils;
@@ -590,24 +589,6 @@
     }
 
     /**
-     * Sets the connection for interacting with the AccessibilityManagerService.
-     *
-     * @param connection The connection.
-     *
-     * @hide
-     */
-    @Override
-    public void setConnection(IAccessibilityServiceConnection connection) {
-        super.setConnection(connection);
-        List<AccessibilityRecord> records = mRecords;
-        final int recordCount = records.size();
-        for (int i = 0; i < recordCount; i++) {
-            AccessibilityRecord record = records.get(i);
-            record.setConnection(connection);
-        }
-    }
-
-    /**
      * Sets if this instance is sealed.
      *
      * @param sealed Whether is sealed.
@@ -821,23 +802,19 @@
      * @param parcel A parcel containing the state of a {@link AccessibilityEvent}.
      */
     public void initFromParcel(Parcel parcel) {
-        if (parcel.readInt() == 1) {
-            mConnection = IAccessibilityServiceConnection.Stub.asInterface(
-                    parcel.readStrongBinder());
-        }
-        setSealed(parcel.readInt() == 1);
+        mSealed = (parcel.readInt() == 1);
         mEventType = parcel.readInt();
         mPackageName = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel);
         mEventTime = parcel.readLong();
+        mConnectionId = parcel.readInt();
         readAccessibilityRecordFromParcel(this, parcel);
 
         // Read the records.
         final int recordCount = parcel.readInt();
         for (int i = 0; i < recordCount; i++) {
             AccessibilityRecord record = AccessibilityRecord.obtain();
-            // Do this to write the connection only once.
-            record.setConnection(mConnection);
             readAccessibilityRecordFromParcel(record, parcel);
+            record.mConnectionId = mConnectionId;
             mRecords.add(record);
         }
     }
@@ -875,16 +852,11 @@
      * {@inheritDoc}
      */
     public void writeToParcel(Parcel parcel, int flags) {
-        if (mConnection == null) {
-            parcel.writeInt(0);
-        } else {
-            parcel.writeInt(1);
-            parcel.writeStrongBinder(mConnection.asBinder());
-        }
         parcel.writeInt(isSealed() ? 1 : 0);
         parcel.writeInt(mEventType);
         TextUtils.writeToParcel(mPackageName, parcel, 0);
         parcel.writeLong(mEventTime);
+        parcel.writeInt(mConnectionId);
         writeAccessibilityRecordToParcel(this, parcel, flags);
 
         // Write the records.
diff --git a/core/java/android/view/accessibility/AccessibilityInteractionClient.java b/core/java/android/view/accessibility/AccessibilityInteractionClient.java
index 5f2990a..95c070c 100644
--- a/core/java/android/view/accessibility/AccessibilityInteractionClient.java
+++ b/core/java/android/view/accessibility/AccessibilityInteractionClient.java
@@ -21,7 +21,9 @@
 import android.os.Message;
 import android.os.RemoteException;
 import android.os.SystemClock;
+import android.util.Log;
 import android.util.LongSparseArray;
+import android.util.SparseArray;
 
 import java.util.Collections;
 import java.util.List;
@@ -62,6 +64,12 @@
 public final class AccessibilityInteractionClient
         extends IAccessibilityInteractionConnectionCallback.Stub {
 
+    public static final int NO_ID = -1;
+
+    private static final String LOG_TAG = "AccessibilityInteractionClient";
+
+    private static final boolean DEBUG = false;
+
     private static final long TIMEOUT_INTERACTION_MILLIS = 5000;
 
     private static final Object sStaticLock = new Object();
@@ -85,6 +93,10 @@
 
     private final Rect mTempBounds = new Rect();
 
+    // The connection cache is shared between all interrogating threads.
+    private static final SparseArray<IAccessibilityServiceConnection> sConnectionCache =
+        new SparseArray<IAccessibilityServiceConnection>();
+
     /**
      * @return The client for the current thread.
      */
@@ -132,29 +144,38 @@
     /**
      * Finds an {@link AccessibilityNodeInfo} by accessibility id.
      *
-     * @param connection A connection for interacting with the system.
+     * @param connectionId The id of a connection for interacting with the system.
      * @param accessibilityWindowId A unique window id.
      * @param accessibilityNodeId A unique node accessibility id
      *     (accessibility view and virtual descendant id).
      * @return An {@link AccessibilityNodeInfo} if found, null otherwise.
      */
-    public AccessibilityNodeInfo findAccessibilityNodeInfoByAccessibilityId(
-            IAccessibilityServiceConnection connection, int accessibilityWindowId,
-            long accessibilityNodeId) {
+    public AccessibilityNodeInfo findAccessibilityNodeInfoByAccessibilityId(int connectionId,
+            int accessibilityWindowId, long accessibilityNodeId) {
         try {
-            final int interactionId = mInteractionIdCounter.getAndIncrement();
-            final float windowScale = connection.findAccessibilityNodeInfoByAccessibilityId(
-                    accessibilityWindowId, accessibilityNodeId, interactionId, this,
-                    Thread.currentThread().getId());
-            // If the scale is zero the call has failed.
-            if (windowScale > 0) {
-                AccessibilityNodeInfo info = getFindAccessibilityNodeInfoResultAndClear(
-                        interactionId);
-                finalizeAccessibilityNodeInfo(info, connection, windowScale);
-                return info;
+            IAccessibilityServiceConnection connection = getConnection(connectionId);
+            if (connection != null) {
+                final int interactionId = mInteractionIdCounter.getAndIncrement();
+                final float windowScale = connection.findAccessibilityNodeInfoByAccessibilityId(
+                        accessibilityWindowId, accessibilityNodeId, interactionId, this,
+                        Thread.currentThread().getId());
+                // If the scale is zero the call has failed.
+                if (windowScale > 0) {
+                    AccessibilityNodeInfo info = getFindAccessibilityNodeInfoResultAndClear(
+                            interactionId);
+                    finalizeAccessibilityNodeInfo(info, connectionId, windowScale);
+                    return info;
+                }
+            } else {
+                if (DEBUG) {
+                    Log.w(LOG_TAG, "No connection for connection id: " + connectionId);
+                }
             }
         } catch (RemoteException re) {
-            /* ignore */
+            if (DEBUG) {
+                Log.w(LOG_TAG, "Error while calling remote"
+                        + " findAccessibilityNodeInfoByAccessibilityId", re);
+            }
         }
         return null;
     }
@@ -163,25 +184,36 @@
      * Finds an {@link AccessibilityNodeInfo} by View id. The search is performed
      * in the currently active window and starts from the root View in the window.
      *
-     * @param connection A connection for interacting with the system.
+     * @param connectionId The id of a connection for interacting with the system.
      * @param viewId The id of the view.
      * @return An {@link AccessibilityNodeInfo} if found, null otherwise.
      */
-    public AccessibilityNodeInfo findAccessibilityNodeInfoByViewIdInActiveWindow(
-            IAccessibilityServiceConnection connection, int viewId) {
+    public AccessibilityNodeInfo findAccessibilityNodeInfoByViewIdInActiveWindow(int connectionId,
+            int viewId) {
         try {
-            final int interactionId = mInteractionIdCounter.getAndIncrement();
-            final float windowScale = connection.findAccessibilityNodeInfoByViewIdInActiveWindow(
-                    viewId, interactionId, this, Thread.currentThread().getId());
-            // If the scale is zero the call has failed.
-            if (windowScale > 0) {
-                AccessibilityNodeInfo info = getFindAccessibilityNodeInfoResultAndClear(
-                        interactionId);
-                finalizeAccessibilityNodeInfo(info, connection, windowScale);
-                return info;
+            IAccessibilityServiceConnection connection = getConnection(connectionId);
+            if (connection != null) {
+                final int interactionId = mInteractionIdCounter.getAndIncrement();
+                final float windowScale =
+                    connection.findAccessibilityNodeInfoByViewIdInActiveWindow(viewId,
+                            interactionId, this, Thread.currentThread().getId());
+                // If the scale is zero the call has failed.
+                if (windowScale > 0) {
+                    AccessibilityNodeInfo info = getFindAccessibilityNodeInfoResultAndClear(
+                            interactionId);
+                    finalizeAccessibilityNodeInfo(info, connectionId, windowScale);
+                    return info;
+                }
+            } else {
+                if (DEBUG) {
+                    Log.w(LOG_TAG, "No connection for connection id: " + connectionId);
+                }
             }
         } catch (RemoteException re) {
-            /* ignore */
+            if (DEBUG) {
+                Log.w(LOG_TAG, "Error while calling remote"
+                        + " findAccessibilityNodeInfoByViewIdInActiveWindow", re);
+            }
         }
         return null;
     }
@@ -191,28 +223,36 @@
      * insensitive containment. The search is performed in the currently
      * active window and starts from the root View in the window.
      *
-     * @param connection A connection for interacting with the system.
+     * @param connectionId The id of a connection for interacting with the system.
      * @param text The searched text.
      * @return A list of found {@link AccessibilityNodeInfo}s.
      */
     public List<AccessibilityNodeInfo> findAccessibilityNodeInfosByTextInActiveWindow(
-            IAccessibilityServiceConnection connection, String text) {
+            int connectionId, String text) {
         try {
-            final int interactionId = mInteractionIdCounter.getAndIncrement();
-            final float windowScale = connection.findAccessibilityNodeInfosByTextInActiveWindow(
-                    text, interactionId, this, Thread.currentThread().getId());
-            // If the scale is zero the call has failed.
-            if (windowScale > 0) {
-                List<AccessibilityNodeInfo> infos = getFindAccessibilityNodeInfosResultAndClear(
-                        interactionId);
-                if (infos == null) {
-                    return Collections.emptyList();
+            IAccessibilityServiceConnection connection = getConnection(connectionId);
+            if (connection != null) {
+                final int interactionId = mInteractionIdCounter.getAndIncrement();
+                final float windowScale =
+                    connection.findAccessibilityNodeInfosByTextInActiveWindow(text,
+                            interactionId, this, Thread.currentThread().getId());
+                // If the scale is zero the call has failed.
+                if (windowScale > 0) {
+                    List<AccessibilityNodeInfo> infos = getFindAccessibilityNodeInfosResultAndClear(
+                            interactionId);
+                    finalizeAccessibilityNodeInfos(infos, connectionId, windowScale);
+                    return infos;
                 }
-                finalizeAccessibilityNodeInfos(infos, connection, windowScale);
-                return infos;
+            } else {
+                if (DEBUG) {
+                    Log.w(LOG_TAG, "No connection for connection id: " + connectionId);
+                }
             }
         } catch (RemoteException re) {
-            /* ignore */
+            if (DEBUG) {
+                Log.w(LOG_TAG, "Error while calling remote"
+                        + " findAccessibilityNodeInfosByViewTextInActiveWindow", re);
+            }
         }
         return null;
     }
@@ -223,30 +263,39 @@
      * id is specified and starts from the View whose accessibility id is
      * specified.
      *
-     * @param connection A connection for interacting with the system.
+     * @param connectionId The id of a connection for interacting with the system.
      * @param text The searched text.
      * @param accessibilityWindowId A unique window id.
      * @param accessibilityNodeId A unique node id (accessibility and virtual descendant id) from
      *        where to start the search. Use {@link android.view.View#NO_ID} to start from the root.
      * @return A list of found {@link AccessibilityNodeInfo}s.
      */
-    public List<AccessibilityNodeInfo> findAccessibilityNodeInfosByText(
-            IAccessibilityServiceConnection connection, String text, int accessibilityWindowId,
-            long accessibilityNodeId) {
+    public List<AccessibilityNodeInfo> findAccessibilityNodeInfosByText(int connectionId,
+            String text, int accessibilityWindowId, long accessibilityNodeId) {
         try {
-            final int interactionId = mInteractionIdCounter.getAndIncrement();
-            final float windowScale = connection.findAccessibilityNodeInfosByText(text,
-                    accessibilityWindowId, accessibilityNodeId, interactionId, this,
-                    Thread.currentThread().getId());
-            // If the scale is zero the call has failed.
-            if (windowScale > 0) {
-                List<AccessibilityNodeInfo> infos = getFindAccessibilityNodeInfosResultAndClear(
-                        interactionId);
-                finalizeAccessibilityNodeInfos(infos, connection, windowScale);
-                return infos;
+            IAccessibilityServiceConnection connection = getConnection(connectionId);
+            if (connection != null) {
+                final int interactionId = mInteractionIdCounter.getAndIncrement();
+                final float windowScale = connection.findAccessibilityNodeInfosByText(text,
+                        accessibilityWindowId, accessibilityNodeId, interactionId, this,
+                        Thread.currentThread().getId());
+                // If the scale is zero the call has failed.
+                if (windowScale > 0) {
+                    List<AccessibilityNodeInfo> infos = getFindAccessibilityNodeInfosResultAndClear(
+                            interactionId);
+                    finalizeAccessibilityNodeInfos(infos, connectionId, windowScale);
+                    return infos;
+                }
+            } else {
+                if (DEBUG) {
+                    Log.w(LOG_TAG, "No connection for connection id: " + connectionId);
+                }
             }
         } catch (RemoteException re) {
-            /* ignore */
+            if (DEBUG) {
+                Log.w(LOG_TAG, "Error while calling remote"
+                        + " findAccessibilityNodeInfosByViewText", re);
+            }
         }
         return Collections.emptyList();
     }
@@ -254,24 +303,33 @@
     /**
      * Performs an accessibility action on an {@link AccessibilityNodeInfo}.
      *
-     * @param connection A connection for interacting with the system.
+     * @param connectionId The id of a connection for interacting with the system.
      * @param accessibilityWindowId The id of the window.
      * @param accessibilityNodeId A unique node id (accessibility and virtual descendant id).
      * @param action The action to perform.
      * @return Whether the action was performed.
      */
-    public boolean performAccessibilityAction(IAccessibilityServiceConnection connection,
-            int accessibilityWindowId, long accessibilityNodeId, int action) {
+    public boolean performAccessibilityAction(int connectionId, int accessibilityWindowId,
+            long accessibilityNodeId, int action) {
         try {
-            final int interactionId = mInteractionIdCounter.getAndIncrement();
-            final boolean success = connection.performAccessibilityAction(
-                    accessibilityWindowId, accessibilityNodeId, action, interactionId, this,
-                    Thread.currentThread().getId());
-            if (success) {
-                return getPerformAccessibilityActionResult(interactionId);
+            IAccessibilityServiceConnection connection = getConnection(connectionId);
+            if (connection != null) {
+                final int interactionId = mInteractionIdCounter.getAndIncrement();
+                final boolean success = connection.performAccessibilityAction(
+                        accessibilityWindowId, accessibilityNodeId, action, interactionId, this,
+                        Thread.currentThread().getId());
+                if (success) {
+                    return getPerformAccessibilityActionResult(interactionId);
+                }
+            } else {
+                if (DEBUG) {
+                    Log.w(LOG_TAG, "No connection for connection id: " + connectionId);
+                }
             }
         } catch (RemoteException re) {
-            /* ignore */
+            if (DEBUG) {
+                Log.w(LOG_TAG, "Error while calling remote performAccessibilityAction", re);
+            }
         }
         return false;
     }
@@ -431,14 +489,14 @@
      * Finalize an {@link AccessibilityNodeInfo} before passing it to the client.
      *
      * @param info The info.
-     * @param connection The current connection to the system.
+     * @param connectionId The id of the connection to the system.
      * @param windowScale The source window compatibility scale.
      */
-    private void finalizeAccessibilityNodeInfo(AccessibilityNodeInfo info,
-            IAccessibilityServiceConnection connection, float windowScale) {
+    private void finalizeAccessibilityNodeInfo(AccessibilityNodeInfo info, int connectionId,
+            float windowScale) {
         if (info != null) {
             applyCompatibilityScaleIfNeeded(info, windowScale);
-            info.setConnection(connection);
+            info.setConnectionId(connectionId);
             info.setSealed(true);
         }
     }
@@ -447,16 +505,16 @@
      * Finalize {@link AccessibilityNodeInfo}s before passing them to the client.
      *
      * @param infos The {@link AccessibilityNodeInfo}s.
-     * @param connection The current connection to the system.
+     * @param connectionId The id of the connection to the system.
      * @param windowScale The source window compatibility scale.
      */
     private void finalizeAccessibilityNodeInfos(List<AccessibilityNodeInfo> infos,
-            IAccessibilityServiceConnection connection, float windowScale) {
+            int connectionId, float windowScale) {
         if (infos != null) {
             final int infosCount = infos.size();
             for (int i = 0; i < infosCount; i++) {
                 AccessibilityNodeInfo info = infos.get(i);
-                finalizeAccessibilityNodeInfo(info, connection, windowScale);
+                finalizeAccessibilityNodeInfo(info, connectionId, windowScale);
             }
         }
     }
@@ -474,4 +532,39 @@
             return result;
         }
     }
+
+    /**
+     * Gets a cached accessibility service connection.
+     *
+     * @param connectionId The connection id.
+     * @return The cached connection if such.
+     */
+    public IAccessibilityServiceConnection getConnection(int connectionId) {
+        synchronized (sConnectionCache) {
+            return sConnectionCache.get(connectionId);
+        }
+    }
+
+    /**
+     * Adds a cached accessibility service connection.
+     *
+     * @param connectionId The connection id.
+     * @param connection The connection.
+     */
+    public void addConnection(int connectionId, IAccessibilityServiceConnection connection) {
+        synchronized (sConnectionCache) {
+            sConnectionCache.put(connectionId, connection);
+        }
+    }
+
+    /**
+     * Removes a cached accessibility service connection.
+     *
+     * @param connectionId The connection id.
+     */
+    public void removeConnection(int connectionId) {
+        synchronized (sConnectionCache) {
+            sConnectionCache.remove(connectionId);
+        }
+    }
 }
diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
index d65c0a7..6939c2c 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
@@ -16,7 +16,6 @@
 
 package android.view.accessibility;
 
-import android.accessibilityservice.IAccessibilityServiceConnection;
 import android.graphics.Rect;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -53,6 +52,8 @@
 
     private static final boolean DEBUG = false;
 
+    private static final int UNDEFINED = -1;
+
     // Actions.
 
     /**
@@ -160,9 +161,10 @@
     private boolean mSealed;
 
     // Data.
-    private long mSourceNodeId = makeNodeId(View.NO_ID, View.NO_ID);
-    private int mWindowId = View.NO_ID;
-    private long mParentNodeId = makeNodeId(View.NO_ID, View.NO_ID);
+    private int mWindowId = UNDEFINED;
+    private long mSourceNodeId = makeNodeId(UNDEFINED, UNDEFINED);
+    private long mParentNodeId = makeNodeId(UNDEFINED, UNDEFINED);
+
     private int mBooleanProperties;
     private final Rect mBoundsInParent = new Rect();
     private final Rect mBoundsInScreen = new Rect();
@@ -175,7 +177,7 @@
     private SparseLongArray mChildIds = new SparseLongArray();
     private int mActions;
 
-    private IAccessibilityServiceConnection mConnection;
+    private int mConnectionId = UNDEFINED;
 
     /**
      * Hide constructor from clients.
@@ -195,7 +197,7 @@
      * @param source The info source.
      */
     public void setSource(View source) {
-        setSource(source, View.NO_ID);
+        setSource(source, UNDEFINED);
     }
 
     /**
@@ -219,9 +221,9 @@
      */
     public void setSource(View root, int virtualDescendantId) {
         enforceNotSealed();
-        mWindowId = (root != null) ? root.getAccessibilityWindowId() : View.NO_ID;
+        mWindowId = (root != null) ? root.getAccessibilityWindowId() : UNDEFINED;
         final int rootAccessibilityViewId =
-            (root != null) ? root.getAccessibilityViewId() : View.NO_ID;
+            (root != null) ? root.getAccessibilityViewId() : UNDEFINED;
         mSourceNodeId = makeNodeId(rootAccessibilityViewId, virtualDescendantId);
     }
 
@@ -264,7 +266,7 @@
         }
         final long childId = mChildIds.get(index);
         AccessibilityInteractionClient client = AccessibilityInteractionClient.getInstance();
-        return client.findAccessibilityNodeInfoByAccessibilityId(mConnection, mWindowId, childId);
+        return client.findAccessibilityNodeInfoByAccessibilityId(mConnectionId, mWindowId, childId);
     }
 
     /**
@@ -280,7 +282,7 @@
      * @throws IllegalStateException If called from an AccessibilityService.
      */
     public void addChild(View child) {
-        addChild(child, View.NO_ID);
+        addChild(child, UNDEFINED);
     }
 
     /**
@@ -301,7 +303,7 @@
         enforceNotSealed();
         final int index = mChildIds.size();
         final int rootAccessibilityViewId =
-            (root != null) ? root.getAccessibilityViewId() : View.NO_ID;
+            (root != null) ? root.getAccessibilityViewId() : UNDEFINED;
         final long childNodeId = makeNodeId(rootAccessibilityViewId, virtualDescendantId);
         mChildIds.put(index, childNodeId);
     }
@@ -355,7 +357,7 @@
             return false;
         }
         AccessibilityInteractionClient client = AccessibilityInteractionClient.getInstance();
-        return client.performAccessibilityAction(mConnection, mWindowId, mSourceNodeId, action);
+        return client.performAccessibilityAction(mConnectionId, mWindowId, mSourceNodeId, action);
     }
 
     /**
@@ -378,7 +380,8 @@
             return Collections.emptyList();
         }
         AccessibilityInteractionClient client = AccessibilityInteractionClient.getInstance();
-        return client.findAccessibilityNodeInfosByText(mConnection, text, mWindowId, mSourceNodeId);
+        return client.findAccessibilityNodeInfosByText(mConnectionId, text, mWindowId,
+                mSourceNodeId);
     }
 
     /**
@@ -397,7 +400,7 @@
             return null;
         }
         AccessibilityInteractionClient client = AccessibilityInteractionClient.getInstance();
-        return client.findAccessibilityNodeInfoByAccessibilityId(mConnection,
+        return client.findAccessibilityNodeInfoByAccessibilityId(mConnectionId,
                 mWindowId, mParentNodeId);
     }
 
@@ -414,7 +417,7 @@
      * @throws IllegalStateException If called from an AccessibilityService.
      */
     public void setParent(View parent) {
-        setParent(parent, View.NO_ID);
+        setParent(parent, UNDEFINED);
     }
 
     /**
@@ -439,7 +442,7 @@
     public void setParent(View root, int virtualDescendantId) {
         enforceNotSealed();
         final int rootAccessibilityViewId =
-            (root != null) ? root.getAccessibilityViewId() : View.NO_ID;
+            (root != null) ? root.getAccessibilityViewId() : UNDEFINED;
         mParentNodeId = makeNodeId(rootAccessibilityViewId, virtualDescendantId);
     }
 
@@ -880,15 +883,16 @@
     }
 
     /**
-     * Sets the connection for interacting with the system.
+     * Sets the unique id of the IAccessibilityServiceConnection over which
+     * this instance can send requests to the system.
      *
-     * @param connection The client token.
+     * @param connectionId The connection id.
      *
      * @hide
      */
-    public final void setConnection(IAccessibilityServiceConnection connection) {
+    public void setConnectionId(int connectionId) {
         enforceNotSealed();
-        mConnection = connection;
+        mConnectionId = connectionId;
     }
 
     /**
@@ -1042,16 +1046,11 @@
      * </p>
      */
     public void writeToParcel(Parcel parcel, int flags) {
-        if (mConnection == null) {
-            parcel.writeInt(0);
-        } else {
-            parcel.writeInt(1);
-            parcel.writeStrongBinder(mConnection.asBinder());
-        }
         parcel.writeInt(isSealed() ? 1 : 0);
         parcel.writeLong(mSourceNodeId);
         parcel.writeInt(mWindowId);
         parcel.writeLong(mParentNodeId);
+        parcel.writeInt(mConnectionId);
 
         SparseLongArray childIds = mChildIds;
         final int childIdsSize = childIds.size();
@@ -1091,10 +1090,10 @@
      */
     private void init(AccessibilityNodeInfo other) {
         mSealed = other.mSealed;
-        mConnection = other.mConnection;
         mSourceNodeId = other.mSourceNodeId;
         mParentNodeId = other.mParentNodeId;
         mWindowId = other.mWindowId;
+        mConnectionId = other.mConnectionId;
         mBoundsInParent.set(other.mBoundsInParent);
         mBoundsInScreen.set(other.mBoundsInScreen);
         mPackageName = other.mPackageName;
@@ -1112,14 +1111,11 @@
      * @param parcel A parcel containing the state of a {@link AccessibilityNodeInfo}.
      */
     private void initFromParcel(Parcel parcel) {
-        if (parcel.readInt() == 1) {
-            mConnection = IAccessibilityServiceConnection.Stub.asInterface(
-                    parcel.readStrongBinder());
-        }
         mSealed = (parcel.readInt()  == 1);
         mSourceNodeId = parcel.readLong();
         mWindowId = parcel.readInt();
         mParentNodeId = parcel.readLong();
+        mConnectionId = parcel.readInt();
 
         SparseLongArray childIds = mChildIds;
         final int childrenSize = parcel.readInt();
@@ -1153,10 +1149,10 @@
      */
     private void clear() {
         mSealed = false;
-        mConnection = null;
-        mSourceNodeId = makeNodeId(View.NO_ID, View.NO_ID);
-        mParentNodeId = makeNodeId(View.NO_ID, View.NO_ID);
-        mWindowId = View.NO_ID;
+        mSourceNodeId = makeNodeId(UNDEFINED, UNDEFINED);
+        mParentNodeId = makeNodeId(UNDEFINED, UNDEFINED);
+        mWindowId = UNDEFINED;
+        mConnectionId = UNDEFINED;
         mChildIds.clear();
         mBoundsInParent.set(0, 0, 0, 0);
         mBoundsInScreen.set(0, 0, 0, 0);
@@ -1190,9 +1186,9 @@
     }
 
     private boolean canPerformRequestOverConnection(long accessibilityNodeId) {
-        return (mWindowId != View.NO_ID
-                && getAccessibilityViewId(accessibilityNodeId) != View.NO_ID
-                && mConnection != null);
+        return (mWindowId != UNDEFINED
+                && getAccessibilityViewId(accessibilityNodeId) != UNDEFINED
+                && mConnectionId != UNDEFINED);
     }
 
     @Override
diff --git a/core/java/android/view/accessibility/AccessibilityRecord.java b/core/java/android/view/accessibility/AccessibilityRecord.java
index f3ca0d5..07aeb9a 100644
--- a/core/java/android/view/accessibility/AccessibilityRecord.java
+++ b/core/java/android/view/accessibility/AccessibilityRecord.java
@@ -16,7 +16,6 @@
 
 package android.view.accessibility;
 
-import android.accessibilityservice.IAccessibilityServiceConnection;
 import android.os.Parcelable;
 import android.view.View;
 
@@ -78,8 +77,8 @@
 
     int mAddedCount= UNDEFINED;
     int mRemovedCount = UNDEFINED;
-    long mSourceNodeId = AccessibilityNodeInfo.makeNodeId(View.NO_ID, View.NO_ID);
-    int mSourceWindowId = View.NO_ID;
+    long mSourceNodeId = AccessibilityNodeInfo.makeNodeId(UNDEFINED, UNDEFINED);
+    int mSourceWindowId = UNDEFINED;
 
     CharSequence mClassName;
     CharSequence mContentDescription;
@@ -87,7 +86,8 @@
     Parcelable mParcelableData;
 
     final List<CharSequence> mText = new ArrayList<CharSequence>();
-    IAccessibilityServiceConnection mConnection;
+
+    int mConnectionId = UNDEFINED;
 
     /*
      * Hide constructor.
@@ -103,7 +103,7 @@
      * @throws IllegalStateException If called from an AccessibilityService.
      */
     public void setSource(View source) {
-        setSource(source, View.NO_ID);
+        setSource(source, UNDEFINED);
     }
 
     /**
@@ -122,8 +122,8 @@
      */
     public void setSource(View root, int virtualDescendantId) {
         enforceNotSealed();
-        mSourceWindowId = (root != null) ? root.getAccessibilityWindowId() : View.NO_ID;
-        final int rootViewId = (root != null) ? root.getAccessibilityViewId() : View.NO_ID;
+        mSourceWindowId = (root != null) ? root.getAccessibilityWindowId() : UNDEFINED;
+        final int rootViewId = (root != null) ? root.getAccessibilityViewId() : UNDEFINED;
         mSourceNodeId = AccessibilityNodeInfo.makeNodeId(rootViewId, virtualDescendantId);
     }
 
@@ -133,34 +133,21 @@
      *   <strong>Note:</strong> It is a client responsibility to recycle the received info
      *   by calling {@link AccessibilityNodeInfo#recycle() AccessibilityNodeInfo#recycle()}
      *   to avoid creating of multiple instances.
-     *
      * </p>
      * @return The info of the source.
      */
     public AccessibilityNodeInfo getSource() {
         enforceSealed();
-        if (mConnection == null || mSourceWindowId == View.NO_ID
-                || AccessibilityNodeInfo.getAccessibilityViewId(mSourceNodeId) == View.NO_ID) {
+        if (mConnectionId == UNDEFINED || mSourceWindowId == UNDEFINED
+                || AccessibilityNodeInfo.getAccessibilityViewId(mSourceNodeId) == UNDEFINED) {
             return null;
         }
         AccessibilityInteractionClient client = AccessibilityInteractionClient.getInstance();
-        return client.findAccessibilityNodeInfoByAccessibilityId(mConnection, mSourceWindowId,
+        return client.findAccessibilityNodeInfoByAccessibilityId(mConnectionId, mSourceWindowId,
                 mSourceNodeId);
     }
 
     /**
-     * Sets the connection for interacting with the AccessibilityManagerService.
-     *
-     * @param connection The connection.
-     *
-     * @hide
-     */
-    public void setConnection(IAccessibilityServiceConnection connection) {
-        enforceNotSealed();
-        mConnection = connection;
-    }
-
-    /**
      * Gets the id of the window from which the event comes from.
      *
      * @return The window id.
@@ -577,6 +564,19 @@
     }
 
     /**
+     * Sets the unique id of the IAccessibilityServiceConnection over which
+     * this instance can send requests to the system.
+     *
+     * @param connectionId The connection id.
+     *
+     * @hide
+     */
+    public void setConnectionId(int connectionId) {
+        enforceNotSealed();
+        mConnectionId = connectionId;
+    }
+
+    /**
      * Sets if this instance is sealed.
      *
      * @param sealed Whether is sealed.
@@ -724,7 +724,7 @@
         mText.addAll(record.mText);
         mSourceWindowId = record.mSourceWindowId;
         mSourceNodeId = record.mSourceNodeId;
-        mConnection = record.mConnection;
+        mConnectionId = record.mConnectionId;
     }
 
     /**
@@ -748,8 +748,9 @@
         mBeforeText = null;
         mParcelableData = null;
         mText.clear();
-        mSourceNodeId = AccessibilityNodeInfo.makeNodeId(View.NO_ID, View.NO_ID);
-        mSourceWindowId = View.NO_ID;
+        mSourceNodeId = AccessibilityNodeInfo.makeNodeId(UNDEFINED, UNDEFINED);
+        mSourceWindowId = UNDEFINED;
+        mConnectionId = UNDEFINED;
     }
 
     @Override
diff --git a/core/java/android/view/accessibility/IAccessibilityManager.aidl b/core/java/android/view/accessibility/IAccessibilityManager.aidl
index c621ff6..c3794be 100644
--- a/core/java/android/view/accessibility/IAccessibilityManager.aidl
+++ b/core/java/android/view/accessibility/IAccessibilityManager.aidl
@@ -49,5 +49,5 @@
 
     void removeAccessibilityInteractionConnection(IWindow windowToken);
 
-    IAccessibilityServiceConnection registerEventListener(IEventListener client);
+    void registerEventListener(IEventListener client);
 }
diff --git a/core/java/android/webkit/CookieManager.java b/core/java/android/webkit/CookieManager.java
index d6e36bb..9fa5593 100644
--- a/core/java/android/webkit/CookieManager.java
+++ b/core/java/android/webkit/CookieManager.java
@@ -345,6 +345,11 @@
      * a system private class.
      */
     public synchronized void setCookie(WebAddress uri, String value) {
+        if (JniUtil.useChromiumHttpStack()) {
+            nativeSetCookie(uri.toString(), value, false);
+            return;
+        }
+
         if (value != null && value.length() > MAX_COOKIE_LENGTH) {
             return;
         }
@@ -500,6 +505,10 @@
      * is a system private class.
      */
     public synchronized String getCookie(WebAddress uri) {
+        if (JniUtil.useChromiumHttpStack()) {
+            return nativeGetCookie(uri.toString(), false);
+        }
+
         if (!mAcceptCookie || uri == null) {
             return null;
         }
@@ -573,6 +582,8 @@
      * {@hide}  Too late to release publically.
      */
     public void waitForCookieOperationsToComplete() {
+        // Note that this function is applicable for both the java
+        // and native http stacks, and works correctly with either.
         synchronized (this) {
             while (pendingCookieOperations > 0) {
                 try {
diff --git a/core/java/android/webkit/GeolocationPermissions.java b/core/java/android/webkit/GeolocationPermissions.java
index 5d54180..d7b6adb 100755
--- a/core/java/android/webkit/GeolocationPermissions.java
+++ b/core/java/android/webkit/GeolocationPermissions.java
@@ -27,30 +27,47 @@
 
 
 /**
- * This class is used to get Geolocation permissions from, and set them on the
- * WebView. For example, it could be used to allow a user to manage Geolocation
- * permissions from a browser's UI.
+ * This class is used to manage permissions for the WebView's Geolocation
+ * JavaScript API.
  *
- * Permissions are managed on a per-origin basis, as required by the
- * Geolocation spec - http://dev.w3.org/geo/api/spec-source.html. An origin
- * specifies the scheme, host and port of particular frame. An origin is
- * represented here as a string, using the output of
- * WebCore::SecurityOrigin::toString.
+ * Geolocation permissions are applied to an origin, which consists of the
+ * host, scheme and port of a URI. In order for web content to use the
+ * Geolocation API, permission must be granted for that content's origin.
  *
- * This class is the Java counterpart of the WebKit C++ GeolocationPermissions
- * class. It simply marshalls calls from the UI thread to the WebKit thread.
+ * This class stores Geolocation permissions. An origin's permission state can
+ * be either allowed or denied. This class uses Strings to represent
+ * an origin.
  *
- * Within WebKit, Geolocation permissions may be applied either temporarily
- * (for the duration of the page) or permanently. This class deals only with
- * permanent permissions.
+ * When an origin attempts to use the Geolocation API, but no permission state
+ * is currently set for that origin,
+ * {@link WebChromeClient#onGeolocationPermissionsShowPrompt(String,GeolocationPermissions.Callback) WebChromeClient.onGeolocationPermissionsShowPrompt()}
+ * is called. This allows the permission state to be set for that origin.
+ *
+ * The methods of this class can be used to modify and interrogate the stored
+ * Geolocation permissions at any time.
  */
+// This class is the Java counterpart of the WebKit C++ GeolocationPermissions
+// class. It simply marshalls calls from the UI thread to the WebKit thread.
+//
+// Within WebKit, Geolocation permissions may be applied either temporarily
+// (for the duration of the page) or permanently. This class deals only with
+// permanent permissions.
 public final class GeolocationPermissions {
     /**
-     * Callback interface used by the browser to report a Geolocation permission
-     * state set by the user in response to a permissions prompt.
+     * A callback interface used by the host application to set the Geolocation
+     * permission state for an origin.
      */
     public interface Callback {
-        public void invoke(String origin, boolean allow, boolean remember);
+        /**
+         * Set the Geolocation permission state for the supplied origin.
+         * @param origin The origin for which permissions are set.
+         * @param allow Whether or not the origin should be allowed to use the
+         *              Geolocation API.
+         * @param retain Whether the permission should be retained beyond the
+         *               lifetime of a page currently being displayed by a
+         *               WebView.
+         */
+        public void invoke(String origin, boolean allow, boolean retain);
     };
 
     // Log tag
@@ -82,7 +99,8 @@
     private static final String ALLOWED = "allowed";
 
     /**
-     * Gets the singleton instance of the class.
+     * Get the singleton instance of this class.
+     * @return The singleton {@link GeolocationPermissions} instance.
      */
     public static GeolocationPermissions getInstance() {
       if (sInstance == null) {
@@ -196,15 +214,18 @@
     }
 
     /**
-     * Gets the set of origins for which Geolocation permissions are stored.
-     * Note that we represent the origins as strings. These are created using
-     * WebCore::SecurityOrigin::toString(). As long as all 'HTML 5 modules'
-     * (Database, Geolocation etc) do so, it's safe to match up origins based
-     * on this string.
-     *
-     * Callback is a ValueCallback object whose onReceiveValue method will be
-     * called asynchronously with the set of origins.
+     * Get the set of origins for which Geolocation permissions are stored.
+     * @param callback A {@link ValueCallback} to receive the result of this
+     *                 request. This object's
+     *                 {@link ValueCallback#onReceiveValue(T) onReceiveValue()}
+     *                 method will be invoked asynchronously with a set of
+     *                 Strings containing the origins for which Geolocation
+     *                 permissions are stored.
      */
+    // Note that we represent the origins as strings. These are created using
+    // WebCore::SecurityOrigin::toString(). As long as all 'HTML 5 modules'
+    // (Database, Geolocation etc) do so, it's safe to match up origins based
+    // on this string.
     public void getOrigins(ValueCallback<Set<String> > callback) {
         if (callback != null) {
             if (WebViewCore.THREAD_NAME.equals(Thread.currentThread().getName())) {
@@ -217,10 +238,14 @@
     }
 
     /**
-     * Gets the permission state for the specified origin.
-     *
-     * Callback is a ValueCallback object whose onReceiveValue method will be
-     * called asynchronously with the permission state for the origin.
+     * Get the Geolocation permission state for the specified origin.
+     * @param origin The origin for which Geolocation permission is requested.
+     * @param callback A {@link ValueCallback} to receive the result of this
+     *                 request. This object's
+     *                 {@link ValueCallback#onReceiveValue(T) onReceiveValue()}
+     *                 method will be invoked asynchronously with a boolean
+     *                 indicating whether or not the origin can use the
+     *                 Geolocation API.
      */
     public void getAllowed(String origin, ValueCallback<Boolean> callback) {
         if (callback == null) {
@@ -242,27 +267,31 @@
     }
 
     /**
-     * Clears the permission state for the specified origin. This method may be
-     * called before the WebKit thread has intialized the message handler.
-     * Messages will be queued until this time.
+     * Clear the Geolocation permission state for the specified origin.
+     * @param origin The origin for which Geolocation permissions are cleared.
      */
+    // This method may be called before the WebKit
+    // thread has intialized the message handler. Messages will be queued until
+    // this time.
     public void clear(String origin) {
         // Called on the UI thread.
         postMessage(Message.obtain(null, CLEAR, origin));
     }
 
     /**
-     * Allows the specified origin. This method may be called before the WebKit
-     * thread has intialized the message handler. Messages will be queued until
-     * this time.
+     * Allow the specified origin to use the Geolocation API.
+     * @param origin The origin for which Geolocation API use is allowed.
      */
+    // This method may be called before the WebKit
+    // thread has intialized the message handler. Messages will be queued until
+    // this time.
     public void allow(String origin) {
         // Called on the UI thread.
         postMessage(Message.obtain(null, ALLOW, origin));
     }
 
     /**
-     * Clears the permission state for all origins.
+     * Clear the Geolocation permission state for all origins.
      */
     public void clearAll() {
         // Called on the UI thread.
diff --git a/core/java/android/webkit/HTML5VideoFullScreen.java b/core/java/android/webkit/HTML5VideoFullScreen.java
index cb555ea..e1eff58 100644
--- a/core/java/android/webkit/HTML5VideoFullScreen.java
+++ b/core/java/android/webkit/HTML5VideoFullScreen.java
@@ -4,15 +4,12 @@
 import android.content.Context;
 import android.media.MediaPlayer;
 import android.media.Metadata;
-import android.util.Log;
 import android.view.Gravity;
 import android.view.MotionEvent;
 import android.view.SurfaceHolder;
 import android.view.SurfaceView;
 import android.view.View;
 import android.view.ViewGroup;
-import android.webkit.HTML5VideoView;
-import android.webkit.HTML5VideoViewProxy;
 import android.widget.FrameLayout;
 import android.widget.MediaController;
 import android.widget.MediaController.MediaPlayerControl;
@@ -150,7 +147,7 @@
     private void prepareForFullScreen() {
         // So in full screen, we reset the MediaPlayer
         mPlayer.reset();
-        MediaController mc = new MediaController(mProxy.getContext());
+        MediaController mc = new FullScreenMediaController(mProxy.getContext(), mLayout);
         mc.setSystemUiVisibility(mLayout.getSystemUiVisibility());
         setMediaController(mc);
         mPlayer.setScreenOnWhilePlaying(true);
@@ -261,9 +258,6 @@
         mLayout.addView(getSurfaceView(), layoutParams);
 
         mLayout.setVisibility(View.VISIBLE);
-        mLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE
-                | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
-
         WebChromeClient client = webView.getWebChromeClient();
         if (client != null) {
             client.onShowCustomView(mLayout, mCallback);
@@ -340,4 +334,33 @@
         }
         return;
     }
+
+    static class FullScreenMediaController extends MediaController {
+
+        View mVideoView;
+
+        public FullScreenMediaController(Context context, View video) {
+            super(context);
+            mVideoView = video;
+        }
+
+        @Override
+        public void show() {
+            super.show();
+            if (mVideoView != null) {
+                mVideoView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);
+            }
+        }
+
+        @Override
+        public void hide() {
+            if (mVideoView != null) {
+                mVideoView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE
+                        | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
+            }
+            super.hide();
+        }
+
+    }
+
 }
diff --git a/core/java/android/webkit/ValueCallback.java b/core/java/android/webkit/ValueCallback.java
index 1a167e8..5c7d97f 100644
--- a/core/java/android/webkit/ValueCallback.java
+++ b/core/java/android/webkit/ValueCallback.java
@@ -17,11 +17,12 @@
 package android.webkit;
 
 /**
- * A callback interface used to returns values asynchronously
+ * A callback interface used to provide values asynchronously.
  */
 public interface ValueCallback<T> {
     /**
-     * Invoked when we have the result
+     * Invoked when the value is available.
+     * @param value The value.
      */
     public void onReceiveValue(T value);
 };
diff --git a/core/java/android/webkit/WebChromeClient.java b/core/java/android/webkit/WebChromeClient.java
index 3d129f7..a6ef0ce 100644
--- a/core/java/android/webkit/WebChromeClient.java
+++ b/core/java/android/webkit/WebChromeClient.java
@@ -250,14 +250,24 @@
     }
 
     /**
-     * Instructs the client to show a prompt to ask the user to set the
-     * Geolocation permission state for the specified origin.
+     * Notify the host application that web content from the specified origin
+     * is attempting to use the Geolocation API, but no permission state is
+     * currently set for that origin. The host application should invoke the
+     * specified callback with the desired permission state. See
+     * {@link GeolocationPermissions} for details.
+     * @param origin The origin of the web content attempting to use the
+     *               Geolocation API.
+     * @param callback The callback to use to set the permission state for the
+     *                 origin.
      */
     public void onGeolocationPermissionsShowPrompt(String origin,
             GeolocationPermissions.Callback callback) {}
 
     /**
-     * Instructs the client to hide the Geolocation permissions prompt.
+     * Notify the host application that a request for Geolocation permissions,
+     * made with a previous call to
+     * {@link #onGeolocationPermissionsShowPrompt(String,GeolocationPermissions.Callback) onGeolocationPermissionsShowPrompt()}
+     * has been canceled. Any related UI should therefore be hidden.
      */
     public void onGeolocationPermissionsHidePrompt() {}
 
diff --git a/core/java/android/webkit/WebTextView.java b/core/java/android/webkit/WebTextView.java
index f18a396..2b59b80 100644
--- a/core/java/android/webkit/WebTextView.java
+++ b/core/java/android/webkit/WebTextView.java
@@ -19,10 +19,13 @@
 import android.content.Context;
 import android.graphics.Canvas;
 import android.graphics.Color;
+import android.graphics.ColorFilter;
 import android.graphics.Paint;
 import android.graphics.Paint.Style;
+import android.graphics.PixelFormat;
 import android.graphics.Rect;
 import android.graphics.drawable.ColorDrawable;
+import android.graphics.drawable.Drawable;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Message;
@@ -51,7 +54,6 @@
 import android.view.inputmethod.EditorInfo;
 import android.view.inputmethod.InputConnection;
 import android.view.inputmethod.InputMethodManager;
-import android.widget.AbsoluteLayout;
 import android.widget.AbsoluteLayout.LayoutParams;
 import android.widget.AdapterView;
 import android.widget.ArrayAdapter;
@@ -74,7 +76,6 @@
 
     static final String LOGTAG = "webtextview";
 
-    private Paint mRingPaint;
     private int mRingInset;
 
     private WebView         mWebView;
@@ -207,13 +208,51 @@
                 }
             }
         };
-        float ringWidth = 4f * context.getResources().getDisplayMetrics().density;
         mReceiver = new MyResultReceiver(mHandler);
-        mRingPaint = new Paint();
-        mRingPaint.setColor(0x6633b5e5);
-        mRingPaint.setStrokeWidth(ringWidth);
-        mRingPaint.setStyle(Style.FILL);
+        float ringWidth = 2f * context.getResources().getDisplayMetrics().density;
         mRingInset = (int) ringWidth;
+        setBackgroundDrawable(new BackgroundDrawable(mRingInset));
+        setPadding(getPaddingLeft(), getPaddingTop(), getPaddingRight(),
+                getPaddingBottom());
+    }
+
+    private static class BackgroundDrawable extends Drawable {
+
+        private Paint mPaint = new Paint();
+        private int mBorderWidth;
+        private Rect mInsetRect = new Rect();
+
+        public BackgroundDrawable(int width) {
+            mPaint = new Paint();
+            mPaint.setStrokeWidth(width);
+            mBorderWidth = width;
+        }
+
+        @Override
+        public void draw(Canvas canvas) {
+            mPaint.setColor(0x6633b5e5);
+            canvas.drawRect(getBounds(), mPaint);
+            mInsetRect.left = getBounds().left + mBorderWidth;
+            mInsetRect.top = getBounds().top + mBorderWidth;
+            mInsetRect.right = getBounds().right - mBorderWidth;
+            mInsetRect.bottom = getBounds().bottom - mBorderWidth;
+            mPaint.setColor(Color.WHITE);
+            canvas.drawRect(mInsetRect, mPaint);
+        }
+
+        @Override
+        public void setAlpha(int alpha) {
+        }
+
+        @Override
+        public void setColorFilter(ColorFilter cf) {
+        }
+
+        @Override
+        public int getOpacity() {
+            return PixelFormat.TRANSLUCENT;
+        }
+
     }
 
     public void setAutoFillable(int queryId) {
@@ -223,37 +262,9 @@
     }
 
     @Override
-    protected void onDraw(Canvas canvas) {
-        super.onDraw(canvas);
-        if (isFocused()) {
-            final int ib = getHeight() - mRingInset;
-            canvas.drawRect(0, 0, getWidth(), mRingInset, mRingPaint);
-            canvas.drawRect(0, ib, getWidth(), getHeight(), mRingPaint);
-            canvas.drawRect(0, mRingInset, mRingInset, ib, mRingPaint);
-            canvas.drawRect(getWidth() - mRingInset, mRingInset, getWidth(), ib, mRingPaint);
-        }
-    }
-
-    private void growOrShrink(boolean grow) {
-        AbsoluteLayout.LayoutParams lp = (AbsoluteLayout.LayoutParams) getLayoutParams();
-        if (grow) {
-            Log.i("webtextview", "grow");
-            lp.x -= mRingInset;
-            lp.y -= mRingInset;
-            lp.width += 2 * mRingInset;
-            lp.height += 2 * mRingInset;
-            setPadding(getPaddingLeft() + mRingInset, getPaddingTop() + mRingInset,
-                    getPaddingRight() + mRingInset, getPaddingBottom() + mRingInset);
-        } else {
-            Log.i("webtextview", "shrink");
-            lp.x += mRingInset;
-            lp.y += mRingInset;
-            lp.width -= 2 * mRingInset;
-            lp.height -= 2 * mRingInset;
-            setPadding(getPaddingLeft() - mRingInset, getPaddingTop() - mRingInset,
-                    getPaddingRight() - mRingInset, getPaddingBottom() - mRingInset);
-        }
-        setLayoutParams(lp);
+    public void setPadding(int left, int top, int right, int bottom) {
+        super.setPadding(left + mRingInset, top + mRingInset,
+                right + mRingInset, bottom + mRingInset);
     }
 
     @Override
@@ -557,7 +568,6 @@
         } else if (!mInsideRemove) {
             mWebView.setActive(false);
         }
-        growOrShrink(focused);
         mFromFocusChange = false;
     }
 
@@ -968,6 +978,10 @@
      */
     /* package */ void setRect(int x, int y, int width, int height) {
         LayoutParams lp = (LayoutParams) getLayoutParams();
+        x -= mRingInset;
+        y -= mRingInset;
+        width += 2 * mRingInset;
+        height += 2 * mRingInset;
         boolean needsUpdate = false;
         if (null == lp) {
             lp = new LayoutParams(width, height, x, y);
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 7bbad78..a284a17 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -59,6 +59,7 @@
 import android.os.StrictMode;
 import android.provider.Settings;
 import android.speech.tts.TextToSpeech;
+import android.text.TextUtils;
 import android.util.AttributeSet;
 import android.util.EventLog;
 import android.util.Log;
@@ -507,7 +508,7 @@
     private float mLastVelY;
 
     // The id of the native layer being scrolled.
-    private int mScrollingLayer;
+    private int mCurrentScrollingLayerId;
     private Rect mScrollingLayerRect = new Rect();
 
     // only trigger accelerated fling if the new velocity is at least
@@ -849,13 +850,12 @@
     // the alias via which accessibility JavaScript interface is exposed
     private static final String ALIAS_ACCESSIBILITY_JS_INTERFACE = "accessibility";
 
-    // JavaScript to inject the script chooser which will
-    // pick the right script for the current URL
-    private static final String ACCESSIBILITY_SCRIPT_CHOOSER_JAVASCRIPT =
+    // Template for JavaScript that injects a screen-reader.
+    private static final String ACCESSIBILITY_SCREEN_READER_JAVASCRIPT_TEMPLATE =
         "javascript:(function() {" +
         "    var chooser = document.createElement('script');" +
         "    chooser.type = 'text/javascript';" +
-        "    chooser.src = 'https://ssl.gstatic.com/accessibility/javascript/android/AndroidScriptChooser.user.js';" +
+        "    chooser.src = '%1s';" +
         "    document.getElementsByTagName('head')[0].appendChild(chooser);" +
         "  })();";
 
@@ -1306,8 +1306,15 @@
         if (AccessibilityManager.getInstance(mContext).isEnabled()
                 && getSettings().getJavaScriptEnabled()) {
             // exposing the TTS for now ...
-            mTextToSpeech = new TextToSpeech(getContext(), null);
-            addJavascriptInterface(mTextToSpeech, ALIAS_ACCESSIBILITY_JS_INTERFACE);
+            final Context ctx = getContext();
+            if (ctx != null) {
+                final String packageName = ctx.getPackageName();
+                if (packageName != null) {
+                    mTextToSpeech = new TextToSpeech(getContext(), null, null,
+                            packageName + ".**webview**");
+                    addJavascriptInterface(mTextToSpeech, ALIAS_ACCESSIBILITY_JS_INTERFACE);
+                }
+            }
         }
     }
 
@@ -1628,6 +1635,14 @@
         clearTextEntry();
         clearActionModes();
         dismissFullScreenMode();
+        cancelSelectDialog();
+    }
+
+    private void cancelSelectDialog() {
+        if (mListBoxDialog != null) {
+            mListBoxDialog.cancel();
+            mListBoxDialog = null;
+        }
     }
 
     /**
@@ -2481,11 +2496,12 @@
     }
 
     /**
-     * Return the reading level scale of the WebView
+     * Compute the reading level scale of the WebView
+     * @param scale The current scale.
      * @return The reading level scale.
      */
-    /*package*/ float getReadingLevelScale() {
-        return mZoomManager.getReadingLevelScale();
+    /*package*/ float computeReadingLevelScale(float scale) {
+        return mZoomManager.computeReadingLevelScale(scale);
     }
 
     /**
@@ -3279,6 +3295,8 @@
             if (mNativeClass != 0) {
                 nativeSetPauseDrawing(mNativeClass, true);
             }
+
+            cancelSelectDialog();
         }
     }
 
@@ -3648,7 +3666,7 @@
         if (x == mScrollingLayerRect.left && y == mScrollingLayerRect.top) {
             return;
         }
-        nativeScrollLayer(mScrollingLayer, x, y);
+        nativeScrollLayer(mCurrentScrollingLayerId, x, y);
         mScrollingLayerRect.left = x;
         mScrollingLayerRect.top = y;
         onScrollChanged(mScrollX, mScrollY, mScrollX, mScrollY);
@@ -3801,7 +3819,7 @@
             if (onDeviceScriptInjectionEnabled) {
                 ensureAccessibilityScriptInjectorInstance(false);
                 // neither script injected nor script injection opted out => we inject
-                loadUrl(ACCESSIBILITY_SCRIPT_CHOOSER_JAVASCRIPT);
+                loadUrl(getScreenReaderInjectingJs());
                 // TODO: Set this flag after successfull script injection. Maybe upon injection
                 // the chooser should update the meta tag and we check it to declare success
                 mAccessibilityScriptInjected = true;
@@ -3815,7 +3833,7 @@
         } else if (axsParameterValue == ACCESSIBILITY_SCRIPT_INJECTION_PROVIDED) {
             ensureAccessibilityScriptInjectorInstance(false);
             // the URL provides accessibility but we still need to add our generic script
-            loadUrl(ACCESSIBILITY_SCRIPT_CHOOSER_JAVASCRIPT);
+            loadUrl(getScreenReaderInjectingJs());
         } else {
             Log.e(LOGTAG, "Unknown URL value for the \"axs\" URL parameter: " + axsParameterValue);
         }
@@ -3837,6 +3855,17 @@
     }
 
     /**
+     * Gets JavaScript that injects a screen-reader.
+     *
+     * @return The JavaScript snippet.
+     */
+    private String getScreenReaderInjectingJs() {
+        String screenReaderUrl = Settings.Secure.getString(mContext.getContentResolver(),
+                Settings.Secure.ACCESSIBILITY_SCREEN_READER_URL);
+        return String.format(ACCESSIBILITY_SCREEN_READER_JAVASCRIPT_TEMPLATE, screenReaderUrl);
+    }
+
+    /**
      * Gets the "axs" URL parameter value.
      *
      * @param url A url to fetch the paramter from.
@@ -4233,6 +4262,9 @@
 
     @Override
     protected void onDraw(Canvas canvas) {
+        if (inFullScreenMode()) {
+            return; // no need to draw anything if we aren't visible.
+        }
         // if mNativeClass is 0, the WebView is either destroyed or not
         // initialized. In either case, just draw the background color and return
         if (mNativeClass == 0) {
@@ -4458,6 +4490,7 @@
         Rect vBox = contentToViewRect(contentBounds);
         Rect visibleRect = new Rect();
         calcOurVisibleRect(visibleRect);
+        offsetByLayerScrollPosition(vBox);
         // If the textfield is on screen, place the WebTextView in
         // its new place, accounting for our new scroll/zoom values,
         // and adjust its textsize.
@@ -4493,6 +4526,14 @@
         }
     }
 
+    private void offsetByLayerScrollPosition(Rect box) {
+        if ((mCurrentScrollingLayerId != 0)
+                && (mCurrentScrollingLayerId == nativeFocusCandidateLayerId())) {
+            box.offsetTo(box.left - mScrollingLayerRect.left,
+                    box.top - mScrollingLayerRect.top);
+        }
+    }
+
     void setBaseLayer(int layer, Region invalRegion, boolean showVisualIndicator,
             boolean isPictureAfterFirstLayout, boolean registerPageSwapCallback) {
         if (mNativeClass == 0)
@@ -4592,14 +4633,15 @@
         boolean UIAnimationsRunning = false;
         // Currently for each draw we compute the animation values;
         // We may in the future decide to do that independently.
-        if (mNativeClass != 0 && nativeEvaluateLayersAnimations(mNativeClass)) {
+        if (mNativeClass != 0 && !canvas.isHardwareAccelerated()
+                && nativeEvaluateLayersAnimations(mNativeClass)) {
             UIAnimationsRunning = true;
             // If we have unfinished (or unstarted) animations,
             // we ask for a repaint. We only need to do this in software
             // rendering (with hardware rendering we already have a different
             // method of requesting a repaint)
-            if (!canvas.isHardwareAccelerated())
-                invalidate();
+            mWebViewCore.sendMessage(EventHub.NOTIFY_ANIMATION_STARTED);
+            invalidate();
         }
 
         // decide which adornments to draw
@@ -4910,6 +4952,7 @@
         // should be in content coordinates.
         Rect bounds = nativeFocusCandidateNodeBounds();
         Rect vBox = contentToViewRect(bounds);
+        offsetByLayerScrollPosition(vBox);
         mWebTextView.setRect(vBox.left, vBox.top, vBox.width(), vBox.height());
         if (!Rect.intersects(bounds, visibleRect)) {
             revealSelection();
@@ -5487,10 +5530,10 @@
         mMaxAutoScrollX = getViewWidth();
         mMinAutoScrollY = 0;
         mMaxAutoScrollY = getViewHeightWithTitle();
-        mScrollingLayer = nativeScrollableLayer(viewToContentX(mSelectX),
+        mCurrentScrollingLayerId = nativeScrollableLayer(viewToContentX(mSelectX),
                 viewToContentY(mSelectY), mScrollingLayerRect,
                 mScrollingLayerBounds);
-        if (mScrollingLayer != 0) {
+        if (mCurrentScrollingLayerId != 0) {
             if (mScrollingLayerRect.left != mScrollingLayerRect.right) {
                 mMinAutoScrollX = Math.max(mMinAutoScrollX,
                         contentToViewX(mScrollingLayerBounds.left));
@@ -5805,7 +5848,8 @@
         }
         calcOurContentVisibleRectF(mVisibleContentRect);
         nativeUpdateDrawGLFunction(mGLViewportEmpty ? null : mGLRectViewport,
-                mGLViewportEmpty ? null : mViewRectViewport, mVisibleContentRect);
+                mGLViewportEmpty ? null : mViewRectViewport,
+                mVisibleContentRect);
     }
 
     /**
@@ -5952,6 +5996,7 @@
         if (inFullScreenMode()) {
             mFullScreenHolder.hide();
             mFullScreenHolder = null;
+            invalidate();
         }
     }
 
@@ -5976,9 +6021,9 @@
     private void startScrollingLayer(float x, float y) {
         int contentX = viewToContentX((int) x + mScrollX);
         int contentY = viewToContentY((int) y + mScrollY);
-        mScrollingLayer = nativeScrollableLayer(contentX, contentY,
+        mCurrentScrollingLayerId = nativeScrollableLayer(contentX, contentY,
                 mScrollingLayerRect, mScrollingLayerBounds);
-        if (mScrollingLayer != 0) {
+        if (mCurrentScrollingLayerId != 0) {
             mTouchMode = TOUCH_DRAG_LAYER_MODE;
         }
     }
@@ -6209,7 +6254,7 @@
                     ted.mPointsInView[0] = new Point(x, y);
                     ted.mMetaState = ev.getMetaState();
                     ted.mReprocess = mDeferTouchProcess;
-                    ted.mNativeLayer = mScrollingLayer;
+                    ted.mNativeLayer = mCurrentScrollingLayerId;
                     ted.mNativeLayerRect.set(mScrollingLayerRect);
                     ted.mSequence = mTouchEventQueue.nextTouchSequence();
                     mTouchEventQueue.preQueueTouchEventData(ted);
@@ -6400,7 +6445,7 @@
                     ted.mPointsInView[0] = new Point(x, y);
                     ted.mMetaState = ev.getMetaState();
                     ted.mReprocess = mDeferTouchProcess;
-                    ted.mNativeLayer = mScrollingLayer;
+                    ted.mNativeLayer = mCurrentScrollingLayerId;
                     ted.mNativeLayerRect.set(mScrollingLayerRect);
                     ted.mSequence = mTouchEventQueue.nextTouchSequence();
                     mTouchEventQueue.preQueueTouchEventData(ted);
@@ -6709,7 +6754,7 @@
             // directions.  mTouchMode might be TOUCH_DRAG_MODE if we have
             // reached the edge of a layer but mScrollingLayer will be non-zero
             // if we initiated the drag on a layer.
-            if (mScrollingLayer != 0) {
+            if (mCurrentScrollingLayerId != 0) {
                 final int contentX = viewToContentDimension(deltaX);
                 final int contentY = viewToContentDimension(deltaY);
 
@@ -7231,7 +7276,7 @@
                     + " vx=" + vx + " vy=" + vy
                     + " maxX=" + maxX + " maxY=" + maxY
                     + " scrollX=" + scrollX + " scrollY=" + scrollY
-                    + " layer=" + mScrollingLayer);
+                    + " layer=" + mCurrentScrollingLayerId);
         }
 
         // Allow sloppy flings without overscrolling at the edges.
@@ -8340,7 +8385,7 @@
                         mSentAutoScrollMessage = false;
                         break;
                     }
-                    if (mScrollingLayer == 0) {
+                    if (mCurrentScrollingLayerId == 0) {
                         pinScrollBy(mAutoScrollX, mAutoScrollY, true, 0);
                     } else {
                         scrollLayerTo(mScrollingLayerRect.left + mAutoScrollX,
@@ -8627,6 +8672,7 @@
                     mFullScreenHolder = new PluginFullScreenHolder(WebView.this, orientation, npp);
                     mFullScreenHolder.setContentView(view);
                     mFullScreenHolder.show();
+                    invalidate();
 
                     break;
                 }
@@ -8770,10 +8816,13 @@
 
     /** @hide Called by JNI when pages are swapped (only occurs with hardware
      * acceleration) */
-    protected void pageSwapCallback() {
+    protected void pageSwapCallback(boolean notifyAnimationStarted) {
         if (inEditingMode()) {
             didUpdateWebTextViewDimensions(ANYWHERE);
         }
+        if (notifyAnimationStarted) {
+            mWebViewCore.sendMessage(EventHub.NOTIFY_ANIMATION_STARTED);
+        }
     }
 
     void setNewPicture(final WebViewCore.DrawData draw, boolean updateBaseLayer) {
@@ -9551,6 +9600,7 @@
      * See WebTextView.setType()
      */
     private native int      nativeFocusCandidateType();
+    private native int      nativeFocusCandidateLayerId();
     private native boolean  nativeFocusIsPlugin();
     private native Rect     nativeFocusNodeBounds();
     /* package */ native int nativeFocusNodePointer();
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index 42b9eab..14da23e 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -519,7 +519,12 @@
     /**
      * Update the layers' content
      */
-    private native boolean nativeUpdateLayers(int baseLayer);
+    private native boolean nativeUpdateLayers(int nativeClass, int baseLayer);
+
+    /**
+     * Notify webkit that animations have begun (on the hardware accelerated content)
+     */
+    private native void nativeNotifyAnimationStarted(int nativeClass);
 
     private native boolean nativeFocusBoundsChanged();
 
@@ -1032,6 +1037,8 @@
 
         static final int PLUGIN_SURFACE_READY = 195;
 
+        static final int NOTIFY_ANIMATION_STARTED = 196;
+
         // private message ids
         private static final int DESTROY =     200;
 
@@ -1587,6 +1594,10 @@
                             nativePluginSurfaceReady();
                             break;
 
+                        case NOTIFY_ANIMATION_STARTED:
+                            nativeNotifyAnimationStarted(mNativeClass);
+                            break;
+
                         case ADD_PACKAGE_NAMES:
                             if (BrowserFrame.sJavaBridge == null) {
                                 throw new IllegalStateException("No WebView " +
@@ -2008,7 +2019,7 @@
             return;
         }
         // Directly update the layers we last passed to the UI side
-        if (nativeUpdateLayers(mLastDrawData.mBaseLayer)) {
+        if (nativeUpdateLayers(mNativeClass, mLastDrawData.mBaseLayer)) {
             // If anything more complex than position has been touched, let's do a full draw
             webkitDraw();
         }
@@ -2503,7 +2514,7 @@
                     if (mSettings.isNarrowColumnLayout()) {
                         // In case of automatic text reflow in fixed view port mode.
                         mInitialViewState.mTextWrapScale =
-                                mWebView.getReadingLevelScale();
+                                mWebView.computeReadingLevelScale(data.mScale);
                     }
                 } else {
                     // Scale is given such as when page is restored, use it.
diff --git a/core/java/android/webkit/ZoomManager.java b/core/java/android/webkit/ZoomManager.java
index 84d00c9..8ffba64 100644
--- a/core/java/android/webkit/ZoomManager.java
+++ b/core/java/android/webkit/ZoomManager.java
@@ -316,7 +316,12 @@
      * Returns the zoom scale used for reading text on a double-tap.
      */
     public final float getReadingLevelScale() {
-        return mDisplayDensity * mDoubleTapZoomFactor;
+        return computeScaleWithLimits(computeReadingLevelScale(getZoomOverviewScale()));
+    }
+
+    /* package */ final float computeReadingLevelScale(float scale) {
+        return Math.max(mDisplayDensity * mDoubleTapZoomFactor,
+                scale + MIN_DOUBLE_TAP_SCALE_INCREMENT);
     }
 
     public final float getInvDefaultScale() {
@@ -493,11 +498,19 @@
 
         if (mHardwareAccelerated) {
             mWebView.updateScrollCoordinates(mWebView.getScrollX() - tx, mWebView.getScrollY() - ty);
+            // By adding webView matrix, we need to offset the canvas a bit
+            // to make the animation smooth.
+            canvas.translate(tx, ty);
             setZoomScale(zoomScale, false);
 
             if (mZoomScale == 0) {
                 // We've reached the end of the zoom animation.
                 mInHWAcceleratedZoom = false;
+
+                // Ensure that the zoom level is pushed to WebCore. This has not
+                // yet occurred because we prevent it from happening while
+                // mInHWAcceleratedZoom is true.
+                mWebView.sendViewSizeZoom(false);
             }
         } else {
             canvas.translate(tx, ty);
@@ -514,11 +527,12 @@
     }
 
     public void updateDoubleTapZoom(int doubleTapZoom) {
-        if (mInZoomOverview) {
-            mDoubleTapZoomFactor = doubleTapZoom / 100.0f;
-            mTextWrapScale = getReadingLevelScale();
-            refreshZoomScale(true);
-        }
+        boolean zoomIn = (mTextWrapScale - mActualScale) < .1f;
+        mDoubleTapZoomFactor = doubleTapZoom / 100.0f;
+        mTextWrapScale = getReadingLevelScale();
+        float newScale = zoomIn ? mTextWrapScale
+                : Math.min(mTextWrapScale, mActualScale);
+        setZoomScale(newScale, true, true);
     }
 
     public void refreshZoomScale(boolean reflowText) {
@@ -669,7 +683,7 @@
             }
             zoomToOverview();
         } else {
-            zoomToReadingLevelOrMore();
+            zoomToReadingLevel();
         }
     }
 
@@ -700,9 +714,8 @@
             !mWebView.getSettings().getUseFixedViewport());
     }
 
-    private void zoomToReadingLevelOrMore() {
-        final float zoomScale = Math.max(getReadingLevelScale(),
-                mActualScale + MIN_DOUBLE_TAP_SCALE_INCREMENT);
+    private void zoomToReadingLevel() {
+        final float readingScale = getReadingLevelScale();
 
         int left = mWebView.nativeGetBlockLeftEdge(mAnchorX, mAnchorY, mActualScale);
         if (left != WebView.NO_LEFTEDGE) {
@@ -712,13 +725,13 @@
             // Re-calculate the zoom center so that the new scroll x will be
             // on the left edge.
             if (viewLeft > 0) {
-                mZoomCenterX = viewLeft * zoomScale / (zoomScale - mActualScale);
+                mZoomCenterX = viewLeft * readingScale / (readingScale - mActualScale);
             } else {
                 mWebView.scrollBy(viewLeft, 0);
                 mZoomCenterX = 0;
             }
         }
-        startZoomAnimation(zoomScale,
+        startZoomAnimation(readingScale,
             !mWebView.getSettings().getUseFixedViewport());
     }
 
diff --git a/core/java/android/widget/NumberPicker.java b/core/java/android/widget/NumberPicker.java
index 3360e9c..9d541e0 100644
--- a/core/java/android/widget/NumberPicker.java
+++ b/core/java/android/widget/NumberPicker.java
@@ -165,6 +165,11 @@
     };
 
     /**
+     * Constant for unspecified size.
+     */
+    private static final int SIZE_UNSPECIFIED = -1;
+
+    /**
      * Use a custom NumberPicker formatting callback to use two-digit minutes
      * strings like "01". Keeping a static formatter etc. is the most efficient
      * way to do this; it avoids creating temporary objects on every call to
@@ -542,16 +547,20 @@
                 getResources().getDisplayMetrics());
         mSelectionDividerHeight = attributesArray.getDimensionPixelSize(
                 R.styleable.NumberPicker_selectionDividerHeight, defSelectionDividerHeight);
-        mMinHeight = attributesArray.getDimensionPixelSize(R.styleable.NumberPicker_minHeight, 0);
+        mMinHeight = attributesArray.getDimensionPixelSize(R.styleable.NumberPicker_minHeight,
+                SIZE_UNSPECIFIED);
         mMaxHeight = attributesArray.getDimensionPixelSize(R.styleable.NumberPicker_maxHeight,
-                Integer.MAX_VALUE);
-        if (mMinHeight > mMaxHeight) {
+                SIZE_UNSPECIFIED);
+        if (mMinHeight != SIZE_UNSPECIFIED && mMaxHeight != SIZE_UNSPECIFIED
+                && mMinHeight > mMaxHeight) {
             throw new IllegalArgumentException("minHeight > maxHeight");
         }
-        mMinWidth = attributesArray.getDimensionPixelSize(R.styleable.NumberPicker_minWidth, 0);
+        mMinWidth = attributesArray.getDimensionPixelSize(R.styleable.NumberPicker_minWidth,
+                SIZE_UNSPECIFIED);
         mMaxWidth = attributesArray.getDimensionPixelSize(R.styleable.NumberPicker_maxWidth,
-                Integer.MAX_VALUE);
-        if (mMinWidth > mMaxWidth) {
+                SIZE_UNSPECIFIED);
+        if (mMinWidth != SIZE_UNSPECIFIED && mMaxWidth != SIZE_UNSPECIFIED
+                && mMinWidth > mMaxWidth) {
             throw new IllegalArgumentException("minWidth > maxWidth");
         }
         mComputeMaxWidth = (mMaxWidth == Integer.MAX_VALUE);
@@ -744,10 +753,10 @@
         final int newHeightMeasureSpec = makeMeasureSpec(heightMeasureSpec, mMaxHeight);
         super.onMeasure(newWidthMeasureSpec, newHeightMeasureSpec);
         // Flag if we are measured with width or height less than the respective min.
-        final int desiredWidth = Math.max(mMinWidth, getMeasuredWidth());
-        final int desiredHeight = Math.max(mMinHeight, getMeasuredHeight());
-        final int widthSize = resolveSizeAndState(desiredWidth, newWidthMeasureSpec, 0);
-        final int heightSize = resolveSizeAndState(desiredHeight, newHeightMeasureSpec, 0);
+        final int widthSize = resolveSizeAndStateRespectingMinSize(mMinWidth, getMeasuredWidth(),
+                widthMeasureSpec);
+        final int heightSize = resolveSizeAndStateRespectingMinSize(mMinHeight, getMeasuredHeight(),
+                heightMeasureSpec);
         setMeasuredDimension(widthSize, heightSize);
     }
 
@@ -1254,6 +1263,7 @@
         }
         updateInputTextView();
         initializeSelectorWheelIndices();
+        tryComputeMaxWidth();
     }
 
     @Override
@@ -1379,6 +1389,9 @@
      * @return A measure spec greedily imposing the max size.
      */
     private int makeMeasureSpec(int measureSpec, int maxSize) {
+        if (maxSize == SIZE_UNSPECIFIED) {
+            return measureSpec;
+        }
         final int size = MeasureSpec.getSize(measureSpec);
         final int mode = MeasureSpec.getMode(measureSpec);
         switch (mode) {
@@ -1394,6 +1407,26 @@
     }
 
     /**
+     * Utility to reconcile a desired size and state, with constraints imposed by
+     * a MeasureSpec. Tries to respect the min size, unless a different size is
+     * imposed by the constraints.
+     *
+     * @param minSize The minimal desired size.
+     * @param measuredSize The currently measured size.
+     * @param measureSpec The current measure spec.
+     * @return The resolved size and state.
+     */
+    private int resolveSizeAndStateRespectingMinSize(int minSize, int measuredSize,
+            int measureSpec) {
+        if (minSize != SIZE_UNSPECIFIED) {
+            final int desiredWidth = Math.max(minSize, measuredSize);
+            return resolveSizeAndState(desiredWidth, measureSpec, 0);
+        } else {
+            return measuredSize;
+        }
+    }
+
+    /**
      * Resets the selector indices and clear the cached
      * string representation of these indices.
      */
diff --git a/core/java/android/widget/RemoteViewsService.java b/core/java/android/widget/RemoteViewsService.java
index 7ba4777..07bd918 100644
--- a/core/java/android/widget/RemoteViewsService.java
+++ b/core/java/android/widget/RemoteViewsService.java
@@ -145,6 +145,9 @@
                 Thread.getDefaultUncaughtExceptionHandler().uncaughtException(t, ex);
             }
         }
+        public synchronized void onDataSetChangedAsync() {
+            onDataSetChanged();
+        }
         public synchronized int getCount() {
             int count = 0;
             try {
diff --git a/core/java/android/widget/SpellChecker.java b/core/java/android/widget/SpellChecker.java
index d03db10..4bd7165 100644
--- a/core/java/android/widget/SpellChecker.java
+++ b/core/java/android/widget/SpellChecker.java
@@ -272,9 +272,11 @@
                             ((attributes & SuggestionsInfo.RESULT_ATTR_LOOKS_LIKE_TYPO) > 0);
 
                     SpellCheckSpan spellCheckSpan = mSpellCheckSpans[j];
+
                     if (!isInDictionary && looksLikeTypo) {
                         createMisspelledSuggestionSpan(editable, suggestionsInfo, spellCheckSpan);
                     }
+
                     editable.removeSpan(spellCheckSpan);
                     break;
                 }
@@ -295,20 +297,21 @@
         }, SPELL_PAUSE_DURATION);
     }
 
-    private void createMisspelledSuggestionSpan(Editable editable,
-            SuggestionsInfo suggestionsInfo, SpellCheckSpan spellCheckSpan) {
+    private void createMisspelledSuggestionSpan(Editable editable, SuggestionsInfo suggestionsInfo,
+            SpellCheckSpan spellCheckSpan) {
         final int start = editable.getSpanStart(spellCheckSpan);
         final int end = editable.getSpanEnd(spellCheckSpan);
-        if (start < 0 || end < 0) return; // span was removed in the meantime
+        if (start < 0 || end <= start) return; // span was removed in the meantime
 
         // Other suggestion spans may exist on that region, with identical suggestions, filter
-        // them out to avoid duplicates. First, filter suggestion spans on that exact region.
+        // them out to avoid duplicates.
         SuggestionSpan[] suggestionSpans = editable.getSpans(start, end, SuggestionSpan.class);
         final int length = suggestionSpans.length;
         for (int i = 0; i < length; i++) {
             final int spanStart = editable.getSpanStart(suggestionSpans[i]);
             final int spanEnd = editable.getSpanEnd(suggestionSpans[i]);
             if (spanStart != start || spanEnd != end) {
+                // Nulled (to avoid new array allocation) if not on that exact same region
                 suggestionSpans[i] = null;
             }
         }
@@ -355,6 +358,8 @@
         SuggestionSpan suggestionSpan = new SuggestionSpan(mTextView.getContext(), suggestions,
                 SuggestionSpan.FLAG_EASY_CORRECT | SuggestionSpan.FLAG_MISSPELLED);
         editable.setSpan(suggestionSpan, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+
+        mTextView.invalidateRegion(start, end);
     }
 
     private class SpellParser {
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index ee5fa64..babd8e7 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -3830,7 +3830,6 @@
                 if (imm != null && imm.isActive(this)) {
                     imm.hideSoftInputFromWindow(getWindowToken(), 0);
                 }
-                clearFocus();
                 return;
             }
         }
@@ -3852,7 +3851,7 @@
                     | KeyEvent.FLAG_EDITOR_ACTION)));
         }
     }
-    
+
     /**
      * Set the private content type of the text, which is the
      * {@link EditorInfo#privateImeOptions EditorInfo.privateImeOptions}
@@ -4327,15 +4326,24 @@
     }
 
     private void invalidateCursor(int a, int b, int c) {
+        if (a >= 0 || b >= 0 || c >= 0) {
+            int start = Math.min(Math.min(a, b), c);
+            int end = Math.max(Math.max(a, b), c);
+            invalidateRegion(start, end);
+        }
+    }
+
+    /**
+     * Invalidates the region of text enclosed between the start and end text offsets.
+     *
+     * @hide
+     */
+    void invalidateRegion(int start, int end) {
         if (mLayout == null) {
             invalidate();
         } else {
-            if (a >= 0 || b >= 0 || c >= 0) {
-                int first = Math.min(Math.min(a, b), c);
-                int last = Math.max(Math.max(a, b), c);
-
-                int line = mLayout.getLineForOffset(first);
-                int top = mLayout.getLineTop(line);
+                int lineStart = mLayout.getLineForOffset(start);
+                int top = mLayout.getLineTop(lineStart);
 
                 // This is ridiculous, but the descent from the line above
                 // can hang down into the line we really want to redraw,
@@ -4343,36 +4351,36 @@
                 // sure everything that needs to be redrawn really is.
                 // (But not the whole line above, because that would cause
                 // the same problem with the descenders on the line above it!)
-                if (line > 0) {
-                    top -= mLayout.getLineDescent(line - 1);
+                if (lineStart > 0) {
+                    top -= mLayout.getLineDescent(lineStart - 1);
                 }
 
-                int line2;
+                int lineEnd;
 
-                if (first == last)
-                    line2 = line;
+                if (start == end)
+                    lineEnd = lineStart;
                 else
-                    line2 = mLayout.getLineForOffset(last);
+                    lineEnd = mLayout.getLineForOffset(end);
 
-                int bottom = mLayout.getLineTop(line2 + 1);
+                int bottom = mLayout.getLineBottom(lineEnd);
 
-                final int horizontalPadding = getCompoundPaddingLeft();
+                final int compoundPaddingLeft = getCompoundPaddingLeft();
                 final int verticalPadding = getExtendedPaddingTop() + getVerticalOffset(true);
-                
-                // If used, the cursor drawables can have an arbitrary dimension that can go beyond
-                // the invalidated lines specified above.
-                for (int i = 0; i < mCursorCount; i++) {
-                    Rect bounds = mCursorDrawable[i].getBounds();
-                    top = Math.min(top, bounds.top);
-                    bottom = Math.max(bottom, bounds.bottom);
-                    // Horizontal bounds are already full width, no need to update
+
+                int left, right;
+                if (lineStart == lineEnd) {
+                    left = (int) mLayout.getPrimaryHorizontal(start);
+                    right = (int) (mLayout.getPrimaryHorizontal(end) + 1.0);
+                    left += compoundPaddingLeft;
+                    right += compoundPaddingLeft;
+                } else {
+                    // Rectangle bounding box when the region spans several lines
+                    left = compoundPaddingLeft;
+                    right = getWidth() - getCompoundPaddingRight();
                 }
 
-                invalidate(horizontalPadding + mScrollX, top + verticalPadding,
-                        horizontalPadding + mScrollX + getWidth() -
-                        getCompoundPaddingLeft() - getCompoundPaddingRight(),
-                        bottom + verticalPadding);
-            }
+                invalidate(mScrollX + left, verticalPadding + top,
+                        mScrollX + right, verticalPadding + bottom);
         }
     }
 
@@ -5608,8 +5616,6 @@
                 outAttrs.extras = mInputContentType.extras;
             } else {
                 outAttrs.imeOptions = EditorInfo.IME_NULL;
-                // May not be defined otherwise and needed by onEditorAction
-                mInputContentType = new InputContentType();
             }
             if (focusSearch(FOCUS_DOWN) != null) {
                 outAttrs.imeOptions |= EditorInfo.IME_FLAG_NAVIGATE_NEXT;
@@ -5907,10 +5913,10 @@
                 if (cursorOffsetVertical != 0) {
                     canvas.translate(0, -cursorOffsetVertical);
                 }
-                invalidate(true);
+                invalidate(true); // TODO invalidate cursor region only
             } else {
                 stopAnimation();
-                invalidate(false);
+                invalidate(false); // TODO invalidate cursor region only
             }
         }
 
@@ -7629,6 +7635,13 @@
                 list.get(i).onTextChanged(text, start, before, after);
             }
         }
+
+        updateSpellCheckSpans(start, start + after);
+
+        // Hide the controllers as soon as text is modified (typing, procedural...)
+        // We do not hide the span controllers, since they can be added when a new text is
+        // inserted into the text view (voice IME).
+        hideCursorControllers();
     }
 
     /**
@@ -7668,15 +7681,6 @@
 
         sendOnTextChanged(buffer, start, before, after);
         onTextChanged(buffer, start, before, after);
-
-        updateSpellCheckSpans(start, start + after);
-
-        // Hide the controllers if the amount of content changed
-        if (before != after) {
-            // We do not hide the span controllers, as they can be added when a new text is
-            // inserted into the text view
-            hideCursorControllers();
-        }
     }
     
     /**
@@ -7734,10 +7738,8 @@
                 onSelectionChanged(newSelStart, newSelEnd);
             }
         }
-        
-        if (what instanceof UpdateAppearance || what instanceof ParagraphStyle
-                || (what instanceof SuggestionSpan && (((SuggestionSpan)what).getFlags()
-                        & SuggestionSpan.FLAG_AUTO_CORRECTION) != 0)) {
+
+        if (what instanceof UpdateAppearance || what instanceof ParagraphStyle) {
             if (ims == null || ims.mBatchEditNesting == 0) {
                 invalidate();
                 mHighlightPathBogus = true;
@@ -7979,16 +7981,12 @@
         @Override
         public void onClick(View view) {
             if (view == mDeleteTextView) {
-                deleteText();
-            }
-        }
-
-        private void deleteText() {
-            Editable editable = (Editable) mText;
-            int start = editable.getSpanStart(mEasyEditSpan);
-            int end = editable.getSpanEnd(mEasyEditSpan);
-            if (start >= 0 && end >= 0) {
-                editable.delete(start, end);
+                Editable editable = (Editable) mText;
+                int start = editable.getSpanStart(mEasyEditSpan);
+                int end = editable.getSpanEnd(mEasyEditSpan);
+                if (start >= 0 && end >= 0) {
+                    deleteText_internal(start, end);
+                }
             }
         }
 
@@ -9113,7 +9111,7 @@
 
             case ID_CUT:
                 setPrimaryClip(ClipData.newPlainText(null, getTransformedText(min, max)));
-                ((Editable) mText).delete(min, max);
+                deleteText_internal(min, max);
                 stopSelectionActionMode();
                 return true;
 
@@ -9144,7 +9142,7 @@
                 if (Character.isSpaceChar(charBefore) && Character.isSpaceChar(charAfter)) {
                     // Two spaces at beginning of paste: remove one
                     final int originalLength = mText.length();
-                    ((Editable) mText).delete(min - 1, min);
+                    deleteText_internal(min - 1, min);
                     // Due to filters, there is no guarantee that exactly one character was
                     // removed: count instead.
                     final int delta = mText.length() - originalLength;
@@ -9154,7 +9152,7 @@
                         !Character.isSpaceChar(charAfter) && charAfter != '\n') {
                     // No space at beginning of paste: add one
                     final int originalLength = mText.length();
-                    ((Editable) mText).replace(min, min, " ");
+                    replaceText_internal(min, min, " ");
                     // Taking possible filters into account as above.
                     final int delta = mText.length() - originalLength;
                     min += delta;
@@ -9168,11 +9166,11 @@
 
                 if (Character.isSpaceChar(charBefore) && Character.isSpaceChar(charAfter)) {
                     // Two spaces at end of paste: remove one
-                    ((Editable) mText).delete(max, max + 1);
+                    deleteText_internal(max, max + 1);
                 } else if (!Character.isSpaceChar(charBefore) && charBefore != '\n' &&
                         !Character.isSpaceChar(charAfter) && charAfter != '\n') {
                     // No space at end of paste: add one
-                    ((Editable) mText).replace(max, max, " ");
+                    replaceText_internal(max, max, " ");
                 }
             }
         }
@@ -9393,42 +9391,59 @@
             mPositionY = mTempCoords[1];
         }
 
-        public boolean isVisible(int positionX, int positionY) {
-            final TextView textView = TextView.this;
-
-            if (mTempRect == null) mTempRect = new Rect();
-            final Rect clip = mTempRect;
-            clip.left = getCompoundPaddingLeft();
-            clip.top = getExtendedPaddingTop();
-            clip.right = textView.getWidth() - getCompoundPaddingRight();
-            clip.bottom = textView.getHeight() - getExtendedPaddingBottom();
-
-            final ViewParent parent = textView.getParent();
-            if (parent == null || !parent.getChildVisibleRect(textView, clip, null)) {
-                return false;
-            }
-
-            int posX = mPositionX + positionX;
-            int posY = mPositionY + positionY;
-
-            // Offset by 1 to take into account 0.5 and int rounding around getPrimaryHorizontal.
-            return posX >= clip.left - 1 && posX <= clip.right + 1 &&
-                    posY >= clip.top && posY <= clip.bottom;
-        }
-
-        public boolean isOffsetVisible(int offset) {
-            final int line = mLayout.getLineForOffset(offset);
-            final int lineBottom = mLayout.getLineBottom(line);
-            final int primaryHorizontal = (int) mLayout.getPrimaryHorizontal(offset);
-            return isVisible(primaryHorizontal + viewportToContentHorizontalOffset(),
-                    lineBottom + viewportToContentVerticalOffset());
-        }
-
         public void onScrollChanged() {
             mScrollHasChanged = true;
         }
     }
 
+    private boolean isPositionVisible(int positionX, int positionY) {
+        synchronized (sTmpPosition) {
+            final float[] position = sTmpPosition;
+            position[0] = positionX;
+            position[1] = positionY;
+            View view = this;
+
+            while (view != null) {
+                if (view != this) {
+                    // Local scroll is already taken into account in positionX/Y
+                    position[0] -= view.getScrollX();
+                    position[1] -= view.getScrollY();
+                }
+
+                if (position[0] < 0 || position[1] < 0 ||
+                        position[0] > view.getWidth() || position[1] > view.getHeight()) {
+                    return false;
+                }
+
+                if (!view.getMatrix().isIdentity()) {
+                    view.getMatrix().mapPoints(position);
+                }
+
+                position[0] += view.getLeft();
+                position[1] += view.getTop();
+
+                final ViewParent parent = view.getParent();
+                if (parent instanceof View) {
+                    view = (View) parent;
+                } else {
+                    // We've reached the ViewRoot, stop iterating
+                    view = null;
+                }
+            }
+        }
+
+        // We've been able to walk up the view hierarchy and the position was never clipped
+        return true;
+    }
+
+    private boolean isOffsetVisible(int offset) {
+        final int line = mLayout.getLineForOffset(offset);
+        final int lineBottom = mLayout.getLineBottom(line);
+        final int primaryHorizontal = (int) mLayout.getPrimaryHorizontal(offset);
+        return isPositionVisible(primaryHorizontal + viewportToContentHorizontalOffset(),
+                lineBottom + viewportToContentVerticalOffset());
+    }
+
     @Override
     protected void onScrollChanged(int horiz, int vert, int oldHoriz, int oldVert) {
         super.onScrollChanged(horiz, vert, oldHoriz, oldVert);
@@ -9527,7 +9542,7 @@
         public void updatePosition(int parentPositionX, int parentPositionY,
                 boolean parentPositionChanged, boolean parentScrolled) {
             // Either parentPositionChanged or parentScrolled is true, check if still visible
-            if (isShowing() && getPositionListener().isOffsetVisible(getTextOffset())) {
+            if (isShowing() && isOffsetVisible(getTextOffset())) {
                 if (parentScrolled) computeLocalPosition();
                 updatePosition(parentPositionX, parentPositionY);
             } else {
@@ -9884,9 +9899,7 @@
 
         @Override
         public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
-            TextView textView = (TextView) view;
             Editable editable = (Editable) mText;
-
             SuggestionInfo suggestionInfo = mSuggestionInfos[position];
 
             if (suggestionInfo.suggestionIndex == DELETE_TEXT) {
@@ -9900,7 +9913,7 @@
                             Character.isSpaceChar(editable.charAt(spanUnionStart - 1)))) {
                         spanUnionEnd = spanUnionEnd + 1;
                     }
-                    editable.replace(spanUnionStart, spanUnionEnd, "");
+                    deleteText_internal(spanUnionStart, spanUnionEnd);
                 }
                 hide();
                 return;
@@ -9918,9 +9931,11 @@
             if (suggestionInfo.suggestionIndex == ADD_TO_DICTIONARY) {
                 Intent intent = new Intent(Settings.ACTION_USER_DICTIONARY_INSERT);
                 intent.putExtra("word", originalText);
+                intent.putExtra("locale", getTextServicesLocale().toString());
                 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
                 getContext().startActivity(intent);
                 // There is no way to know if the word was indeed added. Re-check.
+                // TODO The ExtractEditText should remove the span in the original text instead
                 editable.removeSpan(suggestionInfo.suggestionSpan);
                 updateSpellCheckSpans(spanStart, spanEnd);
             } else {
@@ -9948,9 +9963,9 @@
 
                 final int suggestionStart = suggestionInfo.suggestionStart;
                 final int suggestionEnd = suggestionInfo.suggestionEnd;
-                final String suggestion = textView.getText().subSequence(
+                final String suggestion = suggestionInfo.text.subSequence(
                         suggestionStart, suggestionEnd).toString();
-                editable.replace(spanStart, spanEnd, suggestion);
+                replaceText_internal(spanStart, spanEnd, suggestion);
 
                 // Notify source IME of the suggestion pick. Do this before swaping texts.
                 if (!TextUtils.isEmpty(
@@ -9974,6 +9989,7 @@
                     // way to assign them a valid range after replacement
                     if (suggestionSpansStarts[i] <= spanStart &&
                             suggestionSpansEnds[i] >= spanEnd) {
+                        // TODO The ExtractEditText should restore these spans in the original text
                         editable.setSpan(suggestionSpans[i], suggestionSpansStarts[i],
                                 suggestionSpansEnds[i] + lengthDifference, suggestionSpansFlags[i]);
                     }
@@ -10551,7 +10567,7 @@
                 return false;
             }
 
-            return getPositionListener().isVisible(mPositionX + mHotspotX, mPositionY);
+            return TextView.this.isPositionVisible(mPositionX + mHotspotX, mPositionY);
         }
 
         public abstract int getCurrentCursorOffset();
@@ -10840,7 +10856,7 @@
 
             // Handles can not cross and selection is at least one character
             final int selectionEnd = getSelectionEnd();
-            if (offset >= selectionEnd) offset = selectionEnd - 1;
+            if (offset >= selectionEnd) offset = Math.max(0, selectionEnd - 1);
 
             positionAtCursorOffset(offset, false);
         }
@@ -10882,7 +10898,7 @@
 
             // Handles can not cross and selection is at least one character
             final int selectionStart = getSelectionStart();
-            if (offset <= selectionStart) offset = selectionStart + 1;
+            if (offset <= selectionStart) offset = Math.min(selectionStart + 1, mText.length());
 
             positionAtCursorOffset(offset, false);
         }
@@ -11254,7 +11270,7 @@
         int max = extractRangeEndFromLong(minMax);
 
         Selection.setSelection((Spannable) mText, max);
-        ((Editable) mText).replace(min, max, content);
+        replaceText_internal(min, max, content);
 
         if (dragDropIntoItself) {
             int dragSourceStart = dragLocalState.start;
@@ -11267,7 +11283,7 @@
             }
 
             // Delete original selection
-            ((Editable) mText).delete(dragSourceStart, dragSourceEnd);
+            deleteText_internal(dragSourceStart, dragSourceEnd);
 
             // Make sure we do not leave two adjacent spaces.
             if ((dragSourceStart == 0 ||
@@ -11276,7 +11292,7 @@
                     Character.isSpaceChar(mTransformed.charAt(dragSourceStart)))) {
                 final int pos = dragSourceStart == mText.length() ?
                         dragSourceStart - 1 : dragSourceStart;
-                ((Editable) mText).delete(pos, pos + 1);
+                deleteText_internal(pos, pos + 1);
             }
         }
     }
@@ -11437,6 +11453,22 @@
         }
     }
 
+    /**
+     * Deletes the range of text [start, end[.
+     * @hide
+     */
+    protected void deleteText_internal(int start, int end) {
+        ((Editable) mText).delete(start, end);
+    }
+
+    /**
+     * Replaces the range of text [start, end[ by replacement text
+     * @hide
+     */
+    protected void replaceText_internal(int start, int end, CharSequence text) {
+        ((Editable) mText).replace(start, end, text);
+    }
+
     @ViewDebug.ExportedProperty(category = "text")
     private CharSequence            mText;
     private CharSequence            mTransformed;
@@ -11460,13 +11492,7 @@
     private boolean                 mUserSetTextScaleX;
     private final Paint             mHighlightPaint;
     private int                     mHighlightColor = 0x6633B5E5;
-    /**
-     * This is temporarily visible to fix bug 3085564 in webView. Do not rely on
-     * this field being protected. Will be restored as private when lineHeight
-     * feature request 3215097 is implemented
-     * @hide
-     */
-    protected Layout                mLayout;
+    private Layout                  mLayout;
 
     private long                    mShowCursor;
     private Blink                   mBlink;
@@ -11517,6 +11543,7 @@
     private Path                    mHighlightPath;
     private boolean                 mHighlightPathBogus = true;
     private static final RectF      sTempRect = new RectF();
+    private static final float[]    sTmpPosition = new float[2];
 
     // XXX should be much larger
     private static final int        VERY_WIDE = 1024*1024;
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 3e96c81..fec4cbc 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -1275,7 +1275,7 @@
             // record changes to the battery level.
             if (mHistoryLastWritten.batteryLevel == mHistoryCur.batteryLevel &&
                     (dataSize >= MAX_MAX_HISTORY_BUFFER
-                            || ((mHistoryEnd.states^mHistoryCur.states)
+                            || ((mHistoryLastWritten.states^mHistoryCur.states)
                                     & HistoryItem.MOST_INTERESTING_STATES) == 0)) {
                 return;
             }
diff --git a/core/java/com/android/internal/util/ArrayUtils.java b/core/java/com/android/internal/util/ArrayUtils.java
index 3d22929..edeb2a8 100644
--- a/core/java/com/android/internal/util/ArrayUtils.java
+++ b/core/java/com/android/internal/util/ArrayUtils.java
@@ -17,7 +17,6 @@
 package com.android.internal.util;
 
 import java.lang.reflect.Array;
-import java.util.Collection;
 
 // XXX these should be changed to reflect the actual memory allocator we use.
 // it looks like right now objects want to be powers of 2 minus 8
@@ -142,4 +141,56 @@
         }
         return false;
     }
+
+    /**
+     * Appends an element to a copy of the array and returns the copy.
+     * @param array The original array, or null to represent an empty array.
+     * @param element The element to add.
+     * @return A new array that contains all of the elements of the original array
+     * with the specified element added at the end.
+     */
+    @SuppressWarnings("unchecked")
+    public static <T> T[] appendElement(Class<T> kind, T[] array, T element) {
+        final T[] result;
+        final int end;
+        if (array != null) {
+            end = array.length;
+            result = (T[])Array.newInstance(kind, end + 1);
+            System.arraycopy(array, 0, result, 0, end);
+        } else {
+            end = 0;
+            result = (T[])Array.newInstance(kind, 1);
+        }
+        result[end] = element;
+        return result;
+    }
+
+    /**
+     * Removes an element from a copy of the array and returns the copy.
+     * If the element is not present, then the original array is returned unmodified.
+     * @param array The original array, or null to represent an empty array.
+     * @param element The element to remove.
+     * @return A new array that contains all of the elements of the original array
+     * except the first copy of the specified element removed.  If the specified element
+     * was not present, then returns the original array.  Returns null if the result
+     * would be an empty array.
+     */
+    @SuppressWarnings("unchecked")
+    public static <T> T[] removeElement(Class<T> kind, T[] array, T element) {
+        if (array != null) {
+            final int length = array.length;
+            for (int i = 0; i < length; i++) {
+                if (array[i] == element) {
+                    if (length == 1) {
+                        return null;
+                    }
+                    T[] result = (T[])Array.newInstance(kind, length - 1);
+                    System.arraycopy(array, 0, result, 0, i);
+                    System.arraycopy(array, i + 1, result, i, length - i - 1);
+                    return result;
+                }
+            }
+        }
+        return array;
+    }
 }
diff --git a/core/java/com/android/internal/util/StateMachine.java b/core/java/com/android/internal/util/StateMachine.java
index 36f0246..61c0c8e 100644
--- a/core/java/com/android/internal/util/StateMachine.java
+++ b/core/java/com/android/internal/util/StateMachine.java
@@ -418,7 +418,7 @@
     public static final int SM_QUIT_CMD = -1;
 
     /** Message.what value when initializing */
-    public static final int SM_INIT_CMD = -1;
+    public static final int SM_INIT_CMD = -2;
 
     /**
      * Convenience constant that maybe returned by processMessage
@@ -569,6 +569,13 @@
         }
 
         /**
+         * Clear the list of Processed Message Info.
+         */
+        void cleanup() {
+            mMessages.clear();
+        }
+
+        /**
          * @return the information on a particular record. 0 is the oldest
          * record and size()-1 is the newest record. If the index is to
          * large null is returned.
@@ -608,6 +615,7 @@
         }
     }
 
+
     private static class SmHandler extends Handler {
 
         /** The debug flag */
@@ -782,15 +790,8 @@
              */
             if (destState != null) {
                 if (destState == mQuittingState) {
-                    /**
-                     * We are quitting so ignore all messages.
-                     */
-                    mSm.quitting();
-                    if (mSm.mSmThread != null) {
-                        // If we made the thread then quit looper which stops the thread.
-                        getLooper().quit();
-                        mSm.mSmThread = null;
-                    }
+                    cleanupAfterQuitting();
+
                 } else if (destState == mHaltingState) {
                     /**
                      * Call halting() if we've transitioned to the halting
@@ -803,6 +804,29 @@
         }
 
         /**
+         * Cleanup all the static variables and the looper after the SM has been quit.
+         */
+        private final void cleanupAfterQuitting() {
+            mSm.quitting();
+            if (mSm.mSmThread != null) {
+                // If we made the thread then quit looper which stops the thread.
+                getLooper().quit();
+                mSm.mSmThread = null;
+            }
+
+            mSm.mSmHandler = null;
+            mSm = null;
+            mMsg = null;
+            mProcessedMessages.cleanup();
+            mStateStack = null;
+            mTempStateStack = null;
+            mStateInfo.clear();
+            mInitialState = null;
+            mDestState = null;
+            mDeferredMessages.clear();
+        }
+
+        /**
          * Complete the construction of the state machine.
          */
         private final void completeConstruction() {
@@ -1343,10 +1367,12 @@
     /**
      * Get a message and set Message.target = this.
      *
-     * @return message
+     * @return message or null if SM has quit
      */
     public final Message obtainMessage()
     {
+        if (mSmHandler == null) return null;
+
         return Message.obtain(mSmHandler);
     }
 
@@ -1354,9 +1380,11 @@
      * Get a message and set Message.target = this and what
      *
      * @param what is the assigned to Message.what.
-     * @return message
+     * @return message or null if SM has quit
      */
     public final Message obtainMessage(int what) {
+        if (mSmHandler == null) return null;
+
         return Message.obtain(mSmHandler, what);
     }
 
@@ -1366,10 +1394,12 @@
      *
      * @param what is the assigned to Message.what.
      * @param obj is assigned to Message.obj.
-     * @return message
+     * @return message or null if SM has quit
      */
     public final Message obtainMessage(int what, Object obj)
     {
+        if (mSmHandler == null) return null;
+
         return Message.obtain(mSmHandler, what, obj);
     }
 
@@ -1380,10 +1410,13 @@
      * @param what  is assigned to Message.what
      * @param arg1  is assigned to Message.arg1
      * @param arg2  is assigned to Message.arg2
-     * @return  A Message object from the global pool.
+     * @return  A Message object from the global pool or null if
+     *          SM has quit
      */
     public final Message obtainMessage(int what, int arg1, int arg2)
     {
+        if (mSmHandler == null) return null;
+
         return Message.obtain(mSmHandler, what, arg1, arg2);
     }
 
@@ -1395,10 +1428,13 @@
      * @param arg1  is assigned to Message.arg1
      * @param arg2  is assigned to Message.arg2
      * @param obj is assigned to Message.obj
-     * @return  A Message object from the global pool.
+     * @return  A Message object from the global pool or null if
+     *          SM has quit
      */
     public final Message obtainMessage(int what, int arg1, int arg2, Object obj)
     {
+        if (mSmHandler == null) return null;
+
         return Message.obtain(mSmHandler, what, arg1, arg2, obj);
     }
 
@@ -1406,6 +1442,9 @@
      * Enqueue a message to this state machine.
      */
     public final void sendMessage(int what) {
+        // mSmHandler can be null if the state machine has quit.
+        if (mSmHandler == null) return;
+
         mSmHandler.sendMessage(obtainMessage(what));
     }
 
@@ -1413,6 +1452,9 @@
      * Enqueue a message to this state machine.
      */
     public final void sendMessage(int what, Object obj) {
+        // mSmHandler can be null if the state machine has quit.
+        if (mSmHandler == null) return;
+
         mSmHandler.sendMessage(obtainMessage(what,obj));
     }
 
@@ -1420,6 +1462,9 @@
      * Enqueue a message to this state machine.
      */
     public final void sendMessage(Message msg) {
+        // mSmHandler can be null if the state machine has quit.
+        if (mSmHandler == null) return;
+
         mSmHandler.sendMessage(msg);
     }
 
@@ -1427,6 +1472,9 @@
      * Enqueue a message to this state machine after a delay.
      */
     public final void sendMessageDelayed(int what, long delayMillis) {
+        // mSmHandler can be null if the state machine has quit.
+        if (mSmHandler == null) return;
+
         mSmHandler.sendMessageDelayed(obtainMessage(what), delayMillis);
     }
 
@@ -1434,6 +1482,9 @@
      * Enqueue a message to this state machine after a delay.
      */
     public final void sendMessageDelayed(int what, Object obj, long delayMillis) {
+        // mSmHandler can be null if the state machine has quit.
+        if (mSmHandler == null) return;
+
         mSmHandler.sendMessageDelayed(obtainMessage(what, obj), delayMillis);
     }
 
@@ -1441,6 +1492,9 @@
      * Enqueue a message to this state machine after a delay.
      */
     public final void sendMessageDelayed(Message msg, long delayMillis) {
+        // mSmHandler can be null if the state machine has quit.
+        if (mSmHandler == null) return;
+
         mSmHandler.sendMessageDelayed(msg, delayMillis);
     }
 
@@ -1485,6 +1539,9 @@
      * will be processed.
      */
     public final void quit() {
+        // mSmHandler can be null if the state machine has quit.
+        if (mSmHandler == null) return;
+
         mSmHandler.quit();
     }
 
@@ -1499,6 +1556,9 @@
      * @return if debugging is enabled
      */
     public boolean isDbg() {
+        // mSmHandler can be null if the state machine has quit.
+        if (mSmHandler == null) return false;
+
         return mSmHandler.isDbg();
     }
 
@@ -1508,6 +1568,9 @@
      * @param dbg is true to enable debugging.
      */
     public void setDbg(boolean dbg) {
+        // mSmHandler can be null if the state machine has quit.
+        if (mSmHandler == null) return;
+
         mSmHandler.setDbg(dbg);
     }
 
@@ -1515,6 +1578,9 @@
      * Start the state machine.
      */
     public void start() {
+        // mSmHandler can be null if the state machine has quit.
+        if (mSmHandler == null) return;
+
         /** Send the complete construction message */
         mSmHandler.completeConstruction();
     }
diff --git a/core/java/com/android/internal/view/BaseInputHandler.java b/core/java/com/android/internal/view/BaseInputHandler.java
deleted file mode 100644
index 74b4b06..0000000
--- a/core/java/com/android/internal/view/BaseInputHandler.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2010 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.view;
-
-import android.view.InputHandler;
-import android.view.InputQueue;
-import android.view.KeyEvent;
-import android.view.MotionEvent;
-
-/**
- * Base do-nothing implementation of an input handler.
- * @hide
- */
-public abstract class BaseInputHandler implements InputHandler {
-    public void handleKey(KeyEvent event, InputQueue.FinishedCallback finishedCallback) {
-        finishedCallback.finished(false);
-    }
-    
-    public void handleMotion(MotionEvent event, InputQueue.FinishedCallback finishedCallback) {
-        finishedCallback.finished(false);
-    }
-}
diff --git a/core/java/com/android/internal/widget/IRemoteViewsFactory.aidl b/core/java/com/android/internal/widget/IRemoteViewsFactory.aidl
index 18076c4..7317ecf 100644
--- a/core/java/com/android/internal/widget/IRemoteViewsFactory.aidl
+++ b/core/java/com/android/internal/widget/IRemoteViewsFactory.aidl
@@ -22,6 +22,7 @@
 /** {@hide} */
 interface IRemoteViewsFactory {
     void onDataSetChanged();
+    oneway void onDataSetChangedAsync();
     oneway void onDestroy(in Intent intent);
     int getCount();
     RemoteViews getViewAt(int position);
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index 71c5d26..bafee0e 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -47,10 +47,11 @@
 	android_database_SQLiteStatement.cpp \
 	android_emoji_EmojiFactory.cpp \
 	android_view_Display.cpp \
+	android_view_DisplayEventReceiver.cpp \
 	android_view_Surface.cpp \
 	android_view_TextureView.cpp \
 	android_view_InputChannel.cpp \
-	android_view_InputQueue.cpp \
+	android_view_InputEventReceiver.cpp \
 	android_view_KeyEvent.cpp \
 	android_view_KeyCharacterMap.cpp \
 	android_view_HardwareRenderer.cpp \
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 6d1410c..8db7b24 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -115,6 +115,7 @@
 extern int register_android_graphics_Xfermode(JNIEnv* env);
 extern int register_android_graphics_PixelFormat(JNIEnv* env);
 extern int register_android_view_Display(JNIEnv* env);
+extern int register_android_view_DisplayEventReceiver(JNIEnv* env);
 extern int register_android_view_GLES20Canvas(JNIEnv* env);
 extern int register_android_view_HardwareRenderer(JNIEnv* env);
 extern int register_android_view_Surface(JNIEnv* env);
@@ -168,7 +169,7 @@
 extern int register_android_app_ActivityThread(JNIEnv *env);
 extern int register_android_app_NativeActivity(JNIEnv *env);
 extern int register_android_view_InputChannel(JNIEnv* env);
-extern int register_android_view_InputQueue(JNIEnv* env);
+extern int register_android_view_InputEventReceiver(JNIEnv* env);
 extern int register_android_view_KeyEvent(JNIEnv* env);
 extern int register_android_view_MotionEvent(JNIEnv* env);
 extern int register_android_view_PointerIcon(JNIEnv* env);
@@ -1098,6 +1099,7 @@
     REG_JNI(register_android_os_SystemProperties),
     REG_JNI(register_android_os_Binder),
     REG_JNI(register_android_view_Display),
+    REG_JNI(register_android_view_DisplayEventReceiver),
     REG_JNI(register_android_nio_utils),
     REG_JNI(register_android_graphics_PixelFormat),
     REG_JNI(register_android_graphics_Graphics),
@@ -1192,7 +1194,7 @@
     REG_JNI(register_android_app_ActivityThread),
     REG_JNI(register_android_app_NativeActivity),
     REG_JNI(register_android_view_InputChannel),
-    REG_JNI(register_android_view_InputQueue),
+    REG_JNI(register_android_view_InputEventReceiver),
     REG_JNI(register_android_view_KeyEvent),
     REG_JNI(register_android_view_MotionEvent),
     REG_JNI(register_android_view_PointerIcon),
diff --git a/core/jni/android/graphics/Canvas.cpp b/core/jni/android/graphics/Canvas.cpp
index 7724646..feba1e6 100644
--- a/core/jni/android/graphics/Canvas.cpp
+++ b/core/jni/android/graphics/Canvas.cpp
@@ -732,11 +732,7 @@
                                       jcharArray text, int index, int count,
                                       jfloat x, jfloat y, int flags, SkPaint* paint) {
         jchar* textArray = env->GetCharArrayElements(text, NULL);
-#if RTL_USE_HARFBUZZ
         drawTextWithGlyphs(canvas, textArray + index, 0, count, x, y, flags, paint);
-#else
-        TextLayout::drawText(paint, textArray + index, count, flags, x, y, canvas);
-#endif
         env->ReleaseCharArrayElements(text, textArray, JNI_ABORT);
     }
 
@@ -745,11 +741,7 @@
                                           int start, int end,
                                           jfloat x, jfloat y, int flags, SkPaint* paint) {
         const jchar* textArray = env->GetStringChars(text, NULL);
-#if RTL_USE_HARFBUZZ
         drawTextWithGlyphs(canvas, textArray, start, end, x, y, flags, paint);
-#else
-        TextLayout::drawText(paint, textArray + start, end - start, flags, x, y, canvas);
-#endif
         env->ReleaseStringChars(text, textArray);
     }
 
@@ -770,12 +762,14 @@
         value = TextLayoutCache::getInstance().getValue(paint, textArray, start, count,
                 contextCount, flags);
         if (value == NULL) {
-            LOGE("Cannot get TextLayoutCache value");
+            LOGE("Cannot get TextLayoutCache value for text = '%s'",
+                    String8(textArray + start, count).string());
             return ;
         }
 #else
-        value = new TextLayoutCacheValue();
-        value->computeValues(paint, textArray, start, count, contextCount, flags);
+        value = new TextLayoutCacheValue(contextCount);
+        TextLayoutEngine::getInstance().computeValues(value.get(), paint,
+                reinterpret_cast<const UChar*>(textArray), start, count, contextCount, flags);
 #endif
         doDrawGlyphs(canvas, value->getGlyphs(), 0, value->getGlyphsCount(), x, y, flags, paint);
     }
@@ -802,13 +796,8 @@
         jfloat x, jfloat y, int dirFlags, SkPaint* paint) {
 
         jchar* chars = env->GetCharArrayElements(text, NULL);
-#if RTL_USE_HARFBUZZ
         drawTextWithGlyphs(canvas, chars + contextIndex, index - contextIndex,
                 count, contextCount, x, y, dirFlags, paint);
-#else
-        TextLayout::drawTextRun(paint, chars + contextIndex, index - contextIndex,
-                count, contextCount, dirFlags, x, y, canvas);
-#endif
         env->ReleaseCharArrayElements(text, chars, JNI_ABORT);
     }
 
@@ -820,13 +809,8 @@
         jint count = end - start;
         jint contextCount = contextEnd - contextStart;
         const jchar* chars = env->GetStringChars(text, NULL);
-#if RTL_USE_HARFBUZZ
         drawTextWithGlyphs(canvas, chars + contextStart, start - contextStart,
                 count, contextCount, x, y, dirFlags, paint);
-#else
-        TextLayout::drawTextRun(paint, chars + contextStart, start - contextStart,
-                count, contextCount, dirFlags, x, y, canvas);
-#endif
         env->ReleaseStringChars(text, chars);
     }
 
diff --git a/core/jni/android/graphics/Paint.cpp b/core/jni/android/graphics/Paint.cpp
index 883940b..19f53d7 100644
--- a/core/jni/android/graphics/Paint.cpp
+++ b/core/jni/android/graphics/Paint.cpp
@@ -350,14 +350,10 @@
         SkPaint* paint = GraphicsJNI::getNativePaint(env, jpaint);
         const jchar* textArray = env->GetCharArrayElements(text, NULL);
         jfloat result = 0;
-#if RTL_USE_HARFBUZZ
+
         TextLayout::getTextRunAdvances(paint, textArray, index, count, textLength,
                 paint->getFlags(), NULL /* dont need all advances */, &result);
-#else
-        // we double count, since measureText wants a byteLength
-        SkScalar width = paint->measureText(textArray + index, count << 1);
-        result = SkScalarToFloat(width);
-#endif
+
         env->ReleaseCharArrayElements(text, const_cast<jchar*>(textArray), JNI_ABORT);
         return result;
     }
@@ -380,13 +376,9 @@
         SkPaint* paint = GraphicsJNI::getNativePaint(env, jpaint);
         jfloat width = 0;
 
-#if RTL_USE_HARFBUZZ
         TextLayout::getTextRunAdvances(paint, textArray, start, count, textLength,
                 paint->getFlags(), NULL /* dont need all advances */, &width);
-#else
 
-        width = SkScalarToFloat(paint->measureText(textArray + start, count << 1));
-#endif
         env->ReleaseStringChars(text, textArray);
         return width;
     }
@@ -404,12 +396,9 @@
         SkPaint* paint = GraphicsJNI::getNativePaint(env, jpaint);
         jfloat width = 0;
 
-#if RTL_USE_HARFBUZZ
         TextLayout::getTextRunAdvances(paint, textArray, 0, textLength, textLength,
                 paint->getFlags(), NULL /* dont need all advances */, &width);
-#else
-        width = SkScalarToFloat(paint->measureText(textArray, textLength << 1));
-#endif
+
         env->ReleaseStringChars(text, textArray);
         return width;
     }
@@ -434,17 +423,9 @@
         AutoJavaFloatArray autoWidths(env, widths, count);
         jfloat* widthsArray = autoWidths.ptr();
 
-#if RTL_USE_HARFBUZZ
         TextLayout::getTextRunAdvances(paint, text, 0, count, count,
                 paint->getFlags(), widthsArray, NULL /* dont need totalAdvance */);
-#else
-        SkScalar* scalarArray = (SkScalar*)widthsArray;
 
-        count = paint->getTextWidths(text, count << 1, scalarArray);
-        for (int i = 0; i < count; i++) {
-            widthsArray[i] = SkScalarToFloat(scalarArray[i]);
-        }
-#endif
         return count;
     }
 
@@ -597,54 +578,11 @@
 
     static jint doTextRunCursor(JNIEnv *env, SkPaint* paint, const jchar *text, jint start,
             jint count, jint flags, jint offset, jint opt) {
-#if RTL_USE_HARFBUZZ
         jfloat scalarArray[count];
 
         TextLayout::getTextRunAdvances(paint, text, start, count, count, flags,
                 scalarArray, NULL /* dont need totalAdvance */);
-#else
-        SkScalar scalarArray[count];
-        jchar buffer[count];
 
-        // this is where we'd call harfbuzz
-        // for now we just use ushape.c and widths returned from skia
-
-        int widths;
-        if (flags & 0x1) { // rtl, call arabic shaping in case
-            UErrorCode status = U_ZERO_ERROR;
-            // Use fixed length since we need to keep start and count valid
-            u_shapeArabic(text + start, count, buffer, count,
-                    U_SHAPE_LENGTH_FIXED_SPACES_NEAR | U_SHAPE_TEXT_DIRECTION_LOGICAL |
-                    U_SHAPE_LETTERS_SHAPE | U_SHAPE_X_LAMALEF_SUB_ALTERNATE, &status);
-            // we shouldn't fail unless there's an out of memory condition,
-            // in which case we're hosed anyway
-            for (int i = 0; i < count; ++i) {
-              if (buffer[i] == 0xffff) {
-                buffer[i] = 0x200b; // zero-width-space for skia
-              }
-            }
-            widths = paint->getTextWidths(buffer, count << 1, scalarArray);
-        } else {
-            widths = paint->getTextWidths(text + start, count << 1, scalarArray);
-        }
-
-        if (widths < count) {
-            // Skia operates on code points, not code units, so surrogate pairs return only one
-            // value. Expand the result so we have one value per UTF-16 code unit.
-
-            // Note, skia's getTextWidth gets confused if it encounters a surrogate pair,
-            // leaving the remaining widths zero.  Not nice.
-            const jchar *chars = text + start;
-            for (int i = count, p = widths - 1; --i > p;) {
-                if (chars[i] >= 0xdc00 && chars[i] < 0xe000 &&
-                        chars[i-1] >= 0xd800 && chars[i-1] < 0xdc00) {
-                    scalarArray[i] = 0;
-                } else {
-                  scalarArray[i] = scalarArray[--p];
-                }
-            }
-        }
-#endif
         jint pos = offset - start;
         switch (opt) {
         case AFTER:
diff --git a/core/jni/android/graphics/RtlProperties.h b/core/jni/android/graphics/RtlProperties.h
index a41c91b..d43745f 100644
--- a/core/jni/android/graphics/RtlProperties.h
+++ b/core/jni/android/graphics/RtlProperties.h
@@ -45,9 +45,6 @@
     return kRtlDebugDisabled;
 }
 
-// Define if we want to use Harfbuzz (1) or not (0)
-#define RTL_USE_HARFBUZZ 1
-
 // Define if we want (1) to have Advances debug values or not (0)
 #define DEBUG_ADVANCES 0
 
diff --git a/core/jni/android/graphics/TextLayout.cpp b/core/jni/android/graphics/TextLayout.cpp
index e1398e9..bc30ace 100644
--- a/core/jni/android/graphics/TextLayout.cpp
+++ b/core/jni/android/graphics/TextLayout.cpp
@@ -14,6 +14,8 @@
  * limitations under the License.
  */
 
+#define LOG_TAG "TextLayout"
+
 #include "TextLayout.h"
 #include "TextLayoutCache.h"
 
@@ -46,211 +48,35 @@
     return false;
 }
 
-/**
- * Character-based Arabic shaping.
- *
- * We'll use harfbuzz and glyph-based shaping instead once we're set up for it.
- *
- * @context the text context
- * @start the start of the text to render
- * @count the length of the text to render, start + count  must be <= contextCount
- * @contextCount the length of the context
- * @shaped where to put the shaped text, must have capacity for count uchars
- * @return the length of the shaped text, or -1 if error
- */
-int TextLayout::shapeRtlText(const jchar* context, jsize start, jsize count, jsize contextCount,
-                        jchar* shaped, UErrorCode& status) {
-    SkAutoSTMalloc<CHAR_BUFFER_SIZE, jchar> tempBuffer(contextCount);
-    jchar* buffer = tempBuffer.get();
-
-    // Use fixed length since we need to keep start and count valid
-    u_shapeArabic(context, contextCount, buffer, contextCount,
-                   U_SHAPE_LENGTH_FIXED_SPACES_NEAR |
-                   U_SHAPE_TEXT_DIRECTION_LOGICAL | U_SHAPE_LETTERS_SHAPE |
-                   U_SHAPE_X_LAMALEF_SUB_ALTERNATE, &status);
-
-    if (U_SUCCESS(status)) {
-        // trim out UNICODE_NOT_A_CHAR following ligatures, if any
-        int end = 0;
-        for (int i = start, e = start + count; i < e; ++i) {
-            if (buffer[i] != UNICODE_NOT_A_CHAR) {
-                buffer[end++] = buffer[i];
-            }
-        }
-        count = end;
-        // ALOG(LOG_INFO, "CSRTL", "start %d count %d ccount %d\n", start, count, contextCount);
-        ubidi_writeReverse(buffer, count, shaped, count, UBIDI_DO_MIRRORING | UBIDI_OUTPUT_REVERSE
-                           | UBIDI_KEEP_BASE_COMBINING, &status);
-        if (U_SUCCESS(status)) {
-            return count;
-        }
-    }
-    return -1;
-}
-
-/**
- * Basic character-based layout supporting rtl and arabic shaping.
- * Runs bidi on the text and generates a reordered, shaped line in buffer, returning
- * the length.
- * @text the text
- * @len the length of the text in uchars
- * @dir receives the resolved paragraph direction
- * @buffer the buffer to receive the reordered, shaped line.  Must have capacity of
- * at least len jchars.
- * @flags line bidi flags
- * @return the length of the reordered, shaped line, or -1 if error
- */
-jint TextLayout::layoutLine(const jchar* text, jint len, jint flags, int& dir, jchar* buffer,
-        UErrorCode& status) {
-    static const int RTL_OPTS = UBIDI_DO_MIRRORING | UBIDI_KEEP_BASE_COMBINING |
-            UBIDI_REMOVE_BIDI_CONTROLS | UBIDI_OUTPUT_REVERSE;
-
-    UBiDiLevel bidiReq = 0;
-    switch (flags) {
-    case kBidi_LTR: bidiReq = 0; break; // no ICU constant, canonical LTR level
-    case kBidi_RTL: bidiReq = 1; break; // no ICU constant, canonical RTL level
-    case kBidi_Default_LTR: bidiReq = UBIDI_DEFAULT_LTR; break;
-    case kBidi_Default_RTL: bidiReq = UBIDI_DEFAULT_RTL; break;
-    case kBidi_Force_LTR: memcpy(buffer, text, len * sizeof(jchar)); return len;
-    case kBidi_Force_RTL: return shapeRtlText(text, 0, len, len, buffer, status);
-    }
-
-    int32_t result = -1;
-
-    UBiDi* bidi = ubidi_open();
-    if (bidi) {
-        ubidi_setPara(bidi, text, len, bidiReq, NULL, &status);
-        if (U_SUCCESS(status)) {
-            dir = ubidi_getParaLevel(bidi) & 0x1; // 0 if ltr, 1 if rtl
-
-            int rc = ubidi_countRuns(bidi, &status);
-            if (U_SUCCESS(status)) {
-                // ALOG(LOG_INFO, "LAYOUT", "para bidiReq=%d dir=%d rc=%d\n", bidiReq, dir, rc);
-
-                int32_t slen = 0;
-                for (int i = 0; i < rc; ++i) {
-                    int32_t start;
-                    int32_t length;
-                    UBiDiDirection runDir = ubidi_getVisualRun(bidi, i, &start, &length);
-
-                    if (runDir == UBIDI_RTL) {
-                        slen += shapeRtlText(text + start, 0, length, length, buffer + slen, status);
-                    } else {
-                        memcpy(buffer + slen, text + start, length * sizeof(jchar));
-                        slen += length;
-                    }
-                }
-                if (U_SUCCESS(status)) {
-                    result = slen;
-                }
-            }
-        }
-        ubidi_close(bidi);
-    }
-
-    return result;
-}
-
-bool TextLayout::prepareText(SkPaint* paint, const jchar* text, jsize len, jint bidiFlags,
-        const jchar** outText, int32_t* outBytes, jchar** outBuffer) {
-    const jchar *workText = text;
-    jchar *buffer = NULL;
-    int dir = kDirection_LTR;
-    if (needsLayout(text, len, bidiFlags)) {
-        buffer =(jchar *) malloc(len * sizeof(jchar));
-        if (!buffer) {
-            return false;
-        }
-        UErrorCode status = U_ZERO_ERROR;
-        len = layoutLine(text, len, bidiFlags, dir, buffer, status); // might change len, dir
-        if (!U_SUCCESS(status)) {
-            ALOG(LOG_WARN, "LAYOUT", "drawText error %d\n", status);
-            free(buffer);
-            return false; // can't render
-        }
-        workText = buffer; // use the shaped text
-    }
-
-    bool trimLeft = false;
-    bool trimRight = false;
-
-    SkPaint::Align horiz = paint->getTextAlign();
-    switch (horiz) {
-        case SkPaint::kLeft_Align: trimLeft = dir & kDirection_Mask; break;
-        case SkPaint::kCenter_Align: trimLeft = trimRight = true; break;
-        case SkPaint::kRight_Align: trimRight = !(dir & kDirection_Mask);
-        default: break;
-    }
-    const jchar* workLimit = workText + len;
-
-    if (trimLeft) {
-        while (workText < workLimit && *workText == ' ') {
-            ++workText;
-        }
-    }
-    if (trimRight) {
-        while (workLimit > workText && *(workLimit - 1) == ' ') {
-            --workLimit;
-        }
-    }
-
-    *outBytes = (workLimit - workText) << 1;
-    *outText = workText;
-    *outBuffer = buffer;
-
-    return true;
-}
-
 // Draws or gets the path of a paragraph of text on a single line, running bidi and shaping.
 // This will draw if canvas is not null, otherwise path must be non-null and it will create
 // a path representing the text that would have been drawn.
 void TextLayout::handleText(SkPaint *paint, const jchar* text, jsize len,
                             jint bidiFlags, jfloat x, jfloat y,SkCanvas *canvas, SkPath *path) {
-    const jchar *workText;
-    jchar *buffer = NULL;
-    int32_t workBytes;
-    if (prepareText(paint, text, len, bidiFlags, &workText, &workBytes, &buffer)) {
-        SkScalar x_ = SkFloatToScalar(x);
-        SkScalar y_ = SkFloatToScalar(y);
-        if (canvas) {
-            canvas->drawText(workText, workBytes, x_, y_, *paint);
-        } else {
-            paint->getTextPath(workText, workBytes, x_, y_, path);
-        }
-        free(buffer);
+    sp<TextLayoutCacheValue> value;
+#if USE_TEXT_LAYOUT_CACHE
+    // Return advances from the cache. Compute them if needed
+    value = TextLayoutCache::getInstance().getValue(paint, text, 0, len,
+            len, bidiFlags);
+#else
+    value = new TextLayoutCacheValue(len);
+    TextLayoutEngine::getInstance().computeValues(value.get(), paint,
+            reinterpret_cast<const UChar*>(text), 0, len, len, bidiFlags);
+#endif
+    if (value == NULL) {
+        LOGE("Cannot get TextLayoutCache value for text = '%s'",
+                String8(text, len).string());
+        return ;
     }
-}
-
-bool TextLayout::prepareRtlTextRun(const jchar* context, jsize start, jsize& count,
-        jsize contextCount, jchar* shaped) {
-    UErrorCode status = U_ZERO_ERROR;
-    count = shapeRtlText(context, start, count, contextCount, shaped, status);
-    if (U_SUCCESS(status)) {
-        return true;
+    SkScalar x_ = SkFloatToScalar(x);
+    SkScalar y_ = SkFloatToScalar(y);
+    if (canvas) {
+        canvas->drawText(value->getGlyphs(), value->getGlyphsCount() * 2, x_, y_, *paint);
     } else {
-        LOGW("drawTextRun error %d\n", status);
+        paint->getTextPath(value->getGlyphs(), value->getGlyphsCount() * 2, x_, y_, path);
     }
-    return false;
 }
 
-void TextLayout::drawTextRun(SkPaint* paint, const jchar* chars,
-                             jint start, jint count, jint contextCount,
-                             int dirFlags, jfloat x, jfloat y, SkCanvas* canvas) {
-
-     SkScalar x_ = SkFloatToScalar(x);
-     SkScalar y_ = SkFloatToScalar(y);
-
-     uint8_t rtl = dirFlags & 0x1;
-     if (rtl) {
-         SkAutoSTMalloc<CHAR_BUFFER_SIZE, jchar> buffer(contextCount);
-         if (prepareRtlTextRun(chars, start, count, contextCount, buffer.get())) {
-             canvas->drawText(buffer.get(), count << 1, x_, y_, *paint);
-         }
-     } else {
-         canvas->drawText(chars + start, count << 1, x_, y_, *paint);
-     }
- }
-
 void TextLayout::getTextRunAdvances(SkPaint* paint, const jchar* chars, jint start,
                                     jint count, jint contextCount, jint dirFlags,
                                     jfloat* resultAdvances, jfloat* resultTotalAdvance) {
@@ -260,16 +86,20 @@
     value = TextLayoutCache::getInstance().getValue(paint, chars, start, count,
             contextCount, dirFlags);
 #else
-    value = new TextLayoutCacheValue();
-    value->computeValues(paint, chars, start, count, contextCount, dirFlags);
+    value = new TextLayoutCacheValue(contextCount);
+    TextLayoutEngine::getInstance().computeValues(value.get(), paint,
+            reinterpret_cast<const UChar*>(chars), start, count, contextCount, dirFlags);
 #endif
-    if (value != NULL) {
-        if (resultAdvances) {
-            memcpy(resultAdvances, value->getAdvances(), value->getAdvancesCount() * sizeof(jfloat));
-        }
-        if (resultTotalAdvance) {
-            *resultTotalAdvance = value->getTotalAdvance();
-        }
+    if (value == NULL) {
+        LOGE("Cannot get TextLayoutCache value for text = '%s'",
+                String8(chars + start, count).string());
+        return ;
+    }
+    if (resultAdvances) {
+        memcpy(resultAdvances, value->getAdvances(), value->getAdvancesCount() * sizeof(jfloat));
+    }
+    if (resultTotalAdvance) {
+        *resultTotalAdvance = value->getTotalAdvance();
     }
 }
 
@@ -281,12 +111,6 @@
             resultAdvances, &resultTotalAdvance);
 }
 
-// Draws a paragraph of text on a single line, running bidi and shaping
-void TextLayout::drawText(SkPaint* paint, const jchar* text, jsize len,
-                          int bidiFlags, jfloat x, jfloat y, SkCanvas* canvas) {
-    handleText(paint, text, len, bidiFlags, x, y, canvas, NULL);
-}
-
 void TextLayout::getTextPath(SkPaint *paint, const jchar *text, jsize len,
                              jint bidiFlags, jfloat x, jfloat y, SkPath *path) {
     handleText(paint, text, len, bidiFlags, x, y, NULL, path);
@@ -305,14 +129,30 @@
         return;
     }
 
-    SkAutoSTMalloc<CHAR_BUFFER_SIZE, jchar> buffer(count);
-
-    int dir = kDirection_LTR;
-    UErrorCode status = U_ZERO_ERROR;
-    count = layoutLine(text, count, bidiFlags, dir, buffer.get(), status);
-    if (U_SUCCESS(status)) {
-        canvas->drawTextOnPathHV(buffer.get(), count << 1, *path, h_, v_, *paint);
+    sp<TextLayoutCacheValue> value;
+#if USE_TEXT_LAYOUT_CACHE
+    value = TextLayoutCache::getInstance().getValue(paint, text, 0, count,
+            count, bidiFlags);
+#else
+    value = new TextLayoutCacheValue(count);
+    TextLayoutEngine::getInstance().computeValues(value.get(), paint,
+            reinterpret_cast<const UChar*>(text), 0, count, count, bidiFlags);
+#endif
+    if (value == NULL) {
+        LOGE("Cannot get TextLayoutCache value for text = '%s'",
+                String8(text, count).string());
+        return ;
     }
+
+    // Save old text encoding
+    SkPaint::TextEncoding oldEncoding = paint->getTextEncoding();
+    // Define Glyph encoding
+    paint->setTextEncoding(SkPaint::kGlyphID_TextEncoding);
+
+    canvas->drawTextOnPathHV(value->getGlyphs(), value->getGlyphsCount() * 2, *path, h_, v_, *paint);
+
+    // Get back old encoding
+    paint->setTextEncoding(oldEncoding);
 }
 
 void TextLayout::computeAdvancesWithICU(SkPaint* paint, const UChar* chars,
diff --git a/core/jni/android/graphics/TextLayout.h b/core/jni/android/graphics/TextLayout.h
index 9df3829..1dabe32 100644
--- a/core/jni/android/graphics/TextLayout.h
+++ b/core/jni/android/graphics/TextLayout.h
@@ -62,13 +62,6 @@
 class TextLayout {
 public:
 
-    /*
-     * Draws a unidirectional run of text.
-     */
-    static void drawTextRun(SkPaint* paint, const jchar* chars,
-                            jint start, jint count, jint contextCount,
-                            int dirFlags, jfloat x, jfloat y, SkCanvas* canvas);
-
     static void getTextRunAdvances(SkPaint* paint, const jchar* chars, jint start,
                                    jint count, jint contextCount, jint dirFlags,
                                    jfloat* resultAdvances, jfloat* resultTotalAdvance);
@@ -77,29 +70,16 @@
                                    jint count, jint contextCount, jint dirFlags,
                                    jfloat* resultAdvances, jfloat& resultTotalAdvance);
 
-    static void drawText(SkPaint* paint, const jchar* text, jsize len,
-                         jint bidiFlags, jfloat x, jfloat y, SkCanvas* canvas);
-
     static void getTextPath(SkPaint* paint, const jchar* text, jsize len,
                             jint bidiFlags, jfloat x, jfloat y, SkPath* path);
 
     static void drawTextOnPath(SkPaint* paint, const jchar* text, jsize len,
                                int bidiFlags, jfloat hOffset, jfloat vOffset,
                                SkPath* path, SkCanvas* canvas);
-                               
-    static bool prepareText(SkPaint* paint, const jchar* text, jsize len, jint bidiFlags,
-        const jchar** outText, int32_t* outBytes, jchar** outBuffer);
-
-    static bool prepareRtlTextRun(const jchar* context, jsize start, jsize& count,
-        jsize contextCount, jchar* shaped);
-        
 
 private:
     static bool needsLayout(const jchar* text, jint len, jint bidiFlags);
-    static int shapeRtlText(const jchar* context, jsize start, jsize count, jsize contextCount,
-                            jchar* shaped, UErrorCode& status);
-    static jint layoutLine(const jchar* text, jint len, jint flags, int &dir, jchar* buffer,
-                           UErrorCode &status);
+
     static void handleText(SkPaint* paint, const jchar* text, jsize len,
                            int bidiFlags, jfloat x, jfloat y, SkCanvas* canvas, SkPath* path);
 
diff --git a/core/jni/android/graphics/TextLayoutCache.cpp b/core/jni/android/graphics/TextLayoutCache.cpp
index 17492aa..81bf4d5 100644
--- a/core/jni/android/graphics/TextLayoutCache.cpp
+++ b/core/jni/android/graphics/TextLayoutCache.cpp
@@ -34,10 +34,11 @@
 #if USE_TEXT_LAYOUT_CACHE
 
     ANDROID_SINGLETON_STATIC_INSTANCE(TextLayoutCache);
-    ANDROID_SINGLETON_STATIC_INSTANCE(TextLayoutEngine);
 
 #endif
 
+    ANDROID_SINGLETON_STATIC_INSTANCE(TextLayoutEngine);
+
 //--------------------------------------------------------------------------------------------------
 
 TextLayoutCache::TextLayoutCache() :
@@ -56,12 +57,12 @@
 
     mDebugLevel = readRtlDebugLevel();
     mDebugEnabled = mDebugLevel & kRtlDebugCaches;
-    LOGD("Using debug level: %d - Debug Enabled: %d", mDebugLevel, mDebugEnabled);
+    LOGD("Using debug level = %d - Debug Enabled = %d", mDebugLevel, mDebugEnabled);
 
     mCacheStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
     if (mDebugEnabled) {
-        LOGD("Initialization is done - Start time: %lld", mCacheStartTime);
+        LOGD("Initialization is done - Start time = %lld", mCacheStartTime);
     }
 
     mInitialized = true;
@@ -132,7 +133,7 @@
                     bool removedOne = mCache.removeOldest();
                     LOG_ALWAYS_FATAL_IF(!removedOne, "The cache is non-empty but we "
                             "failed to remove the oldest entry.  "
-                            "mSize=%u, size=%u, mMaxSize=%u, mCache.size()=%u",
+                            "mSize = %u, size = %u, mMaxSize = %u, mCache.size() = %u",
                             mSize, size, mMaxSize, mCache.size());
                 }
             }
@@ -147,15 +148,15 @@
             LOG_ALWAYS_FATAL_IF(!putOne, "Failed to put an entry into the cache.  "
                     "This indicates that the cache already has an entry with the "
                     "same key but it should not since we checked earlier!"
-                    " - start=%d count=%d contextCount=%d - Text='%s'",
+                    " - start = %d, count = %d, contextCount = %d - Text = '%s'",
                     start, count, contextCount, String8(text + start, count).string());
 
             if (mDebugEnabled) {
                 nsecs_t totalTime = systemTime(SYSTEM_TIME_MONOTONIC) - startTime;
                 LOGD("CACHE MISS: Added entry %p "
-                        "with start=%d count=%d contextCount=%d, "
+                        "with start = %d, count = %d, contextCount = %d, "
                         "entry size %d bytes, remaining space %d bytes"
-                        " - Compute time %0.6f ms - Put time %0.6f ms - Text='%s'",
+                        " - Compute time %0.6f ms - Put time %0.6f ms - Text = '%s'",
                         value.get(), start, count, contextCount, size, mMaxSize - mSize,
                         value->getElapsedTime() * 0.000001f,
                         (totalTime - value->getElapsedTime()) * 0.000001f,
@@ -164,9 +165,9 @@
         } else {
             if (mDebugEnabled) {
                 LOGD("CACHE MISS: Calculated but not storing entry because it is too big "
-                        "with start=%d count=%d contextCount=%d, "
+                        "with start = %d, count = %d, contextCount = %d, "
                         "entry size %d bytes, remaining space %d bytes"
-                        " - Compute time %0.6f ms - Text='%s'",
+                        " - Compute time %0.6f ms - Text = '%s'",
                         start, count, contextCount, size, mMaxSize - mSize,
                         value->getElapsedTime() * 0.000001f,
                         String8(text + start, count).string());
@@ -183,9 +184,9 @@
             if (value->getElapsedTime() > 0) {
                 float deltaPercent = 100 * ((value->getElapsedTime() - elapsedTimeThruCacheGet)
                         / ((float)value->getElapsedTime()));
-                LOGD("CACHE HIT #%d with start=%d count=%d contextCount=%d"
+                LOGD("CACHE HIT #%d with start = %d, count = %d, contextCount = %d"
                         "- Compute time %0.6f ms - "
-                        "Cache get time %0.6f ms - Gain in percent: %2.2f - Text='%s' ",
+                        "Cache get time %0.6f ms - Gain in percent: %2.2f - Text = '%s'",
                         mCacheHitCount, start, count, contextCount,
                         value->getElapsedTime() * 0.000001f,
                         elapsedTimeThruCacheGet * 0.000001f,
@@ -328,12 +329,7 @@
     return mElapsedTime;
 }
 
-//HB_ShaperItem TextLayoutEngine::mShaperItem;
-//HB_FontRec TextLayoutEngine::mFontRec;
-//SkPaint TextLayoutEngine::mShapingPaint;
-
-TextLayoutEngine::TextLayoutEngine() : mShaperItemGlyphArraySize(0),
-        mShaperItemLogClustersArraySize(0) {
+TextLayoutEngine::TextLayoutEngine() : mShaperItemGlyphArraySize(0) {
     mDefaultTypeface = SkFontHost::CreateTypeface(NULL, NULL, NULL, 0, SkTypeface::kNormal);
     mArabicTypeface = NULL;
     mHebrewRegularTypeface = NULL;
@@ -364,18 +360,22 @@
 void TextLayoutEngine::computeValues(TextLayoutCacheValue* value, SkPaint* paint, const UChar* chars,
         size_t start, size_t count, size_t contextCount, int dirFlags) {
 
-    computeValuesWithHarfbuzz(paint, chars, start, count, contextCount, dirFlags,
+    computeValues(paint, chars, start, count, contextCount, dirFlags,
             &value->mAdvances, &value->mTotalAdvance, &value->mGlyphs);
 #if DEBUG_ADVANCES
-    LOGD("Advances - start=%d, count=%d, contextCount=%d, totalAdvance=%f", start, count,
-            contextCount, mTotalAdvance);
+    LOGD("Advances - start = %d, count = %d, contextCount = %d, totalAdvance = %f", start, count,
+            contextCount, value->mTotalAdvance);
 #endif
 }
 
-void TextLayoutEngine::computeValuesWithHarfbuzz(SkPaint* paint, const UChar* chars,
+void TextLayoutEngine::computeValues(SkPaint* paint, const UChar* chars,
         size_t start, size_t count, size_t contextCount, int dirFlags,
         Vector<jfloat>* const outAdvances, jfloat* outTotalAdvance,
         Vector<jchar>* const outGlyphs) {
+        if (!count) {
+            *outTotalAdvance = 0;
+            return;
+        }
 
         UBiDiLevel bidiReq = 0;
         bool forceLTR = false;
@@ -399,22 +399,30 @@
             if (bidi) {
                 UErrorCode status = U_ZERO_ERROR;
 #if DEBUG_GLYPHS
-                LOGD("computeValuesWithHarfbuzz -- bidiReq=%d", bidiReq);
+                LOGD("******** ComputeValues -- start");
+                LOGD("      -- string = '%s'", String8(chars + start, count).string());
+                LOGD("      -- start = %d", start);
+                LOGD("      -- count = %d", count);
+                LOGD("      -- contextCount = %d", contextCount);
+                LOGD("      -- bidiReq = %d", bidiReq);
 #endif
                 ubidi_setPara(bidi, chars, contextCount, bidiReq, NULL, &status);
                 if (U_SUCCESS(status)) {
                     int paraDir = ubidi_getParaLevel(bidi) & kDirection_Mask; // 0 if ltr, 1 if rtl
                     ssize_t rc = ubidi_countRuns(bidi, &status);
 #if DEBUG_GLYPHS
-                    LOGD("computeValuesWithHarfbuzz -- dirFlags=%d run-count=%d paraDir=%d",
-                            dirFlags, rc, paraDir);
+                    LOGD("      -- dirFlags = %d", dirFlags);
+                    LOGD("      -- paraDir = %d", paraDir);
+                    LOGD("      -- run-count = %d", int(rc));
 #endif
                     if (U_SUCCESS(status) && rc == 1) {
                         // Normal case: one run, status is ok
                         isRTL = (paraDir == 1);
                         useSingleRun = true;
                     } else if (!U_SUCCESS(status) || rc < 1) {
-                        LOGW("computeValuesWithHarfbuzz -- need to force to single run");
+                        LOGW("Need to force to single run -- string = '%s',"
+                                " status = %d, rc = %d",
+                                String8(chars + start, count).string(), status, int(rc));
                         isRTL = (paraDir == 1);
                         useSingleRun = true;
                     } else {
@@ -427,7 +435,7 @@
                             if (startRun == -1 || lengthRun == -1) {
                                 // Something went wrong when getting the visual run, need to clear
                                 // already computed data before doing a single run pass
-                                LOGW("computeValuesWithHarfbuzz -- visual run is not valid");
+                                LOGW("Visual run is not valid");
                                 outGlyphs->clear();
                                 outAdvances->clear();
                                 *outTotalAdvance = 0;
@@ -454,23 +462,23 @@
                             isRTL = (runDir == UBIDI_RTL);
                             jfloat runTotalAdvance = 0;
 #if DEBUG_GLYPHS
-                            LOGD("computeValuesWithHarfbuzz -- run-start=%d run-len=%d isRTL=%d",
-                                    startRun, lengthRun, isRTL);
+                            LOGD("Processing Bidi Run = %d -- run-start = %d, run-len = %d, isRTL = %d",
+                                    i, startRun, lengthRun, isRTL);
 #endif
-                            computeRunValuesWithHarfbuzz(paint, chars + startRun, lengthRun, isRTL,
+                            computeRunValues(paint, chars + startRun, lengthRun, isRTL,
                                     outAdvances, &runTotalAdvance, outGlyphs);
 
                             *outTotalAdvance += runTotalAdvance;
                         }
                     }
                 } else {
-                    LOGW("computeValuesWithHarfbuzz -- cannot set Para");
+                    LOGW("Cannot set Para");
                     useSingleRun = true;
                     isRTL = (bidiReq = 1) || (bidiReq = UBIDI_DEFAULT_RTL);
                 }
                 ubidi_close(bidi);
             } else {
-                LOGW("computeValuesWithHarfbuzz -- cannot ubidi_open()");
+                LOGW("Cannot ubidi_open()");
                 useSingleRun = true;
                 isRTL = (bidiReq = 1) || (bidiReq = UBIDI_DEFAULT_RTL);
             }
@@ -479,34 +487,37 @@
         // Default single run case
         if (useSingleRun){
 #if DEBUG_GLYPHS
-            LOGD("computeValuesWithHarfbuzz -- Using a SINGLE Run "
-                    "-- run-start=%d run-len=%d isRTL=%d", start, count, isRTL);
+            LOGD("Using a SINGLE BiDi Run "
+                    "-- run-start = %d, run-len = %d, isRTL = %d", start, count, isRTL);
 #endif
-            computeRunValuesWithHarfbuzz(paint, chars + start, count, isRTL,
+            computeRunValues(paint, chars + start, count, isRTL,
                     outAdvances, outTotalAdvance, outGlyphs);
         }
 
 #if DEBUG_GLYPHS
-        LOGD("computeValuesWithHarfbuzz -- total-glyphs-count=%d", outGlyphs->size());
+        LOGD("      -- Total returned glyphs-count = %d", outGlyphs->size());
+        LOGD("******** ComputeValues -- end");
 #endif
 }
 
 static void logGlyphs(HB_ShaperItem shaperItem) {
-    LOGD("Got glyphs - count=%d", shaperItem.num_glyphs);
+    LOGD("         -- glyphs count=%d", shaperItem.num_glyphs);
     for (size_t i = 0; i < shaperItem.num_glyphs; i++) {
-        LOGD("      glyph[%d]=%d - offset.x=%f offset.y=%f", i, shaperItem.glyphs[i],
+        LOGD("         -- glyph[%d] = %d, offset.x = %f, offset.y = %f", i, shaperItem.glyphs[i],
                 HBFixedToFloat(shaperItem.offsets[i].x),
                 HBFixedToFloat(shaperItem.offsets[i].y));
     }
 }
 
-void TextLayoutEngine::computeRunValuesWithHarfbuzz(SkPaint* paint, const UChar* chars,
+void TextLayoutEngine::computeRunValues(SkPaint* paint, const UChar* chars,
         size_t count, bool isRTL,
         Vector<jfloat>* const outAdvances, jfloat* outTotalAdvance,
         Vector<jchar>* const outGlyphs) {
-
-    *outTotalAdvance = 0;
-    jfloat totalAdvance = 0;
+    if (!count) {
+        // We cannot shape an empty run.
+        *outTotalAdvance = 0;
+        return;
+    }
 
     // Set the string properties
     mShaperItem.string = chars;
@@ -523,25 +534,27 @@
     // into the shaperItem
     ssize_t indexFontRun = isRTL ? count - 1 : 0;
     unsigned numCodePoints = 0;
+    jfloat totalAdvance = 0;
     while ((isRTL) ?
             hb_utf16_script_run_prev(&numCodePoints, &mShaperItem.item, chars,
                     count, &indexFontRun):
             hb_utf16_script_run_next(&numCodePoints, &mShaperItem.item, chars,
                     count, &indexFontRun)) {
 
-        ssize_t startFontRun = mShaperItem.item.pos;
-        size_t countFontRun = mShaperItem.item.length;
-        ssize_t endFontRun = startFontRun + countFontRun;
+        ssize_t startScriptRun = mShaperItem.item.pos;
+        size_t countScriptRun = mShaperItem.item.length;
+        ssize_t endScriptRun = startScriptRun + countScriptRun;
 
 #if DEBUG_GLYPHS
-        LOGD("Shaping Font Run with");
-        LOGD("         -- isRTL=%d", isRTL);
-        LOGD("         -- HB script=%d", mShaperItem.item.script);
-        LOGD("         -- startFontRun=%d", startFontRun);
-        LOGD("         -- endFontRun=%d", endFontRun);
-        LOGD("         -- countFontRun=%d", countFontRun);
-        LOGD("         -- run='%s'", String8(chars + startFontRun, countFontRun).string());
-        LOGD("         -- string='%s'", String8(chars, count).string());
+        LOGD("-------- Start of Script Run --------");
+        LOGD("Shaping Script Run with");
+        LOGD("         -- isRTL = %d", isRTL);
+        LOGD("         -- HB script = %d", mShaperItem.item.script);
+        LOGD("         -- startFontRun = %d", int(startScriptRun));
+        LOGD("         -- endFontRun = %d", int(endScriptRun));
+        LOGD("         -- countFontRun = %d", countScriptRun);
+        LOGD("         -- run = '%s'", String8(chars + startScriptRun, countScriptRun).string());
+        LOGD("         -- string = '%s'", String8(chars, count).string());
 #endif
 
         // Initialize Harfbuzz Shaper and get the base glyph count for offsetting the glyphIDs
@@ -549,30 +562,31 @@
         size_t glyphBaseCount = shapeFontRun(paint, isRTL);
 
 #if DEBUG_GLYPHS
-        LOGD("HARFBUZZ -- num_glypth=%d - kerning_applied=%d", mShaperItem.num_glyphs,
-                mShaperItem.kerning_applied);
-        LOGD("         -- isDevKernText=%d", paint->isDevKernText());
-        LOGD("         -- glyphBaseCount=%d", glyphBaseCount);
+        LOGD("Got from Harfbuzz");
+        LOGD("         -- glyphBaseCount = %d", glyphBaseCount);
+        LOGD("         -- num_glypth = %d", mShaperItem.num_glyphs);
+        LOGD("         -- kerning_applied = %d", mShaperItem.kerning_applied);
+        LOGD("         -- isDevKernText = %d", paint->isDevKernText());
 
         logGlyphs(mShaperItem);
 #endif
         if (isRTL) {
-            endFontRun = startFontRun;
+            endScriptRun = startScriptRun;
 #if DEBUG_GLYPHS
-            LOGD("         -- updated endFontRun=%d", endFontRun);
+            LOGD("Updated endScriptRun = %d", int(endScriptRun));
 #endif
         } else {
-            startFontRun = endFontRun;
+            startScriptRun = endScriptRun;
 #if DEBUG_GLYPHS
-            LOGD("         -- updated startFontRun=%d", startFontRun);
+            LOGD("Updated startScriptRun = %d", int(startScriptRun));
 #endif
         }
 
         if (mShaperItem.advances == NULL || mShaperItem.num_glyphs == 0) {
 #if DEBUG_GLYPHS
-            LOGD("HARFBUZZ -- advances array is empty or num_glypth = 0");
+            LOGD("Advances array is empty or num_glypth = 0");
 #endif
-            outAdvances->insertAt(0, outAdvances->size(), countFontRun);
+            outAdvances->insertAt(0, outAdvances->size(), countScriptRun);
             continue;
         }
 
@@ -580,7 +594,7 @@
         jfloat currentAdvance = HBFixedToFloat(mShaperItem.advances[mShaperItem.log_clusters[0]]);
         jfloat totalFontRunAdvance = currentAdvance;
         outAdvances->add(currentAdvance);
-        for (size_t i = 1; i < countFontRun; i++) {
+        for (size_t i = 1; i < countScriptRun; i++) {
             size_t clusterPrevious = mShaperItem.log_clusters[i - 1];
             size_t cluster = mShaperItem.log_clusters[i];
             if (cluster == clusterPrevious) {
@@ -591,29 +605,39 @@
                 outAdvances->add(currentAdvance);
             }
         }
+
         totalAdvance += totalFontRunAdvance;
 
 #if DEBUG_ADVANCES
-        for (size_t i = 0; i < countFontRun; i++) {
-            LOGD("hb-adv[%d] = %f - log_clusters = %d - total = %f", i,
-                    (*outAdvances)[i], shaperItem.log_clusters[i], totalFontRunAdvance);
+        LOGD("Returned advances");
+        for (size_t i = 0; i < countScriptRun; i++) {
+            LOGD("         -- hb-adv[%d] = %f, log_clusters = %d, total = %f", i,
+                    (*outAdvances)[i], mShaperItem.log_clusters[i], totalFontRunAdvance);
         }
 #endif
 
         // Get Glyphs and reverse them in place if RTL
         if (outGlyphs) {
             size_t countGlyphs = mShaperItem.num_glyphs;
+#if DEBUG_GLYPHS
+            LOGD("Returned script run glyphs -- count = %d", countGlyphs);
+#endif
             for (size_t i = 0; i < countGlyphs; i++) {
                 jchar glyph = glyphBaseCount +
                         (jchar) mShaperItem.glyphs[(!isRTL) ? i : countGlyphs - 1 - i];
 #if DEBUG_GLYPHS
-                LOGD("HARFBUZZ  -- glyph[%d]=%d", i, glyph);
+                LOGD("         -- glyph[%d] = %d", i, glyph);
 #endif
                 outGlyphs->add(glyph);
             }
         }
     }
+
     *outTotalAdvance = totalAdvance;
+
+#if DEBUG_GLYPHS
+    LOGD("-------- End of Script Run --------");
+#endif
 }
 
 
@@ -681,7 +705,7 @@
     mShaperItem.face = getCachedHBFace(typeface);
 
 #if DEBUG_GLYPHS
-    LOGD("Run typeFace = %p, uniqueID = %d, hb_face = %p",
+    LOGD("Run typeface = %p, uniqueID = %d, hb_face = %p",
             typeface, typeface->uniqueID(), mShaperItem.face);
 #endif
 
@@ -703,7 +727,7 @@
     }
 
     // Shape
-    ensureShaperItemLogClustersArray(mShaperItem.item.length);
+    assert(mShaperItem.item.length > 0); // Harfbuzz will overwrite other memory if length is 0.
     ensureShaperItemGlyphArrays(mShaperItem.item.length * 3 / 2);
     mShaperItem.num_glyphs = mShaperItemGlyphArraySize;
     while (!HB_ShapeItem(&mShaperItem)) {
@@ -724,13 +748,20 @@
 
 void TextLayoutEngine::createShaperItemGlyphArrays(size_t size) {
 #if DEBUG_GLYPHS
-    LOGD("createGlyphArrays  -- size=%d", size);
+    LOGD("Creating Glyph Arrays with size = %d", size);
 #endif
     mShaperItemGlyphArraySize = size;
+
+    // These arrays are all indexed by glyph.
     mShaperItem.glyphs = new HB_Glyph[size];
     mShaperItem.attributes = new HB_GlyphAttributes[size];
     mShaperItem.advances = new HB_Fixed[size];
     mShaperItem.offsets = new HB_FixedPoint[size];
+
+    // Although the log_clusters array is indexed by character, Harfbuzz expects that
+    // it is big enough to hold one element per glyph.  So we allocate log_clusters along
+    // with the other glyph arrays above.
+    mShaperItem.log_clusters = new unsigned short[size];
 }
 
 void TextLayoutEngine::deleteShaperItemGlyphArrays() {
@@ -738,24 +769,6 @@
     delete[] mShaperItem.attributes;
     delete[] mShaperItem.advances;
     delete[] mShaperItem.offsets;
-}
-
-void TextLayoutEngine::ensureShaperItemLogClustersArray(size_t size) {
-    if (size > mShaperItemLogClustersArraySize) {
-        deleteShaperItemLogClustersArray();
-        createShaperItemLogClustersArray(size);
-    }
-}
-
-void TextLayoutEngine::createShaperItemLogClustersArray(size_t size) {
-#if DEBUG_GLYPHS
-    LOGD("createLogClustersArray  -- size=%d", size);
-#endif
-    mShaperItemLogClustersArraySize = size;
-    mShaperItem.log_clusters = new unsigned short[size];
-}
-
-void TextLayoutEngine::deleteShaperItemLogClustersArray() {
     delete[] mShaperItem.log_clusters;
 }
 
@@ -764,7 +777,7 @@
         *typeface = SkTypeface::CreateFromFile(path);
         (*typeface)->ref();
 #if DEBUG_GLYPHS
-        LOGD("Created SkTypeface from file: %s", path);
+        LOGD("Created SkTypeface from file '%s' with uniqueID = %d", path, (*typeface)->uniqueID());
 #endif
     }
     return *typeface;
@@ -779,7 +792,7 @@
     HB_Face face = HB_NewFace(typeface, harfbuzzSkiaGetTable);
     if (face) {
 #if DEBUG_GLYPHS
-        LOGD("Created HB_NewFace %p from paint typeface: %p", face, typeface);
+        LOGD("Created HB_NewFace %p from paint typeface = %p", face, typeface);
 #endif
         mCachedHBFaces.add(fontId, face);
     }
diff --git a/core/jni/android/graphics/TextLayoutCache.h b/core/jni/android/graphics/TextLayoutCache.h
index dfdcd03..fd9ccb1 100644
--- a/core/jni/android/graphics/TextLayoutCache.h
+++ b/core/jni/android/graphics/TextLayoutCache.h
@@ -252,16 +252,15 @@
     KeyedVector<SkFontID, HB_Face> mCachedHBFaces;
 
     size_t mShaperItemGlyphArraySize;
-    size_t mShaperItemLogClustersArraySize;
 
     size_t shapeFontRun(SkPaint* paint, bool isRTL);
 
-    void computeValuesWithHarfbuzz(SkPaint* paint, const UChar* chars,
+    void computeValues(SkPaint* paint, const UChar* chars,
             size_t start, size_t count, size_t contextCount, int dirFlags,
             Vector<jfloat>* const outAdvances, jfloat* outTotalAdvance,
             Vector<jchar>* const outGlyphs);
 
-    void computeRunValuesWithHarfbuzz(SkPaint* paint, const UChar* chars,
+    void computeRunValues(SkPaint* paint, const UChar* chars,
             size_t count, bool isRTL,
             Vector<jfloat>* const outAdvances, jfloat* outTotalAdvance,
             Vector<jchar>* const outGlyphs);
@@ -273,10 +272,6 @@
     void createShaperItemGlyphArrays(size_t size);
     void deleteShaperItemGlyphArrays();
 
-    void ensureShaperItemLogClustersArray(size_t size);
-    void createShaperItemLogClustersArray(size_t size);
-    void deleteShaperItemLogClustersArray();
-
 }; // TextLayoutEngine
 
 
diff --git a/core/jni/android_hardware_Camera.cpp b/core/jni/android_hardware_Camera.cpp
index 25763ac..953da79 100644
--- a/core/jni/android_hardware_Camera.cpp
+++ b/core/jni/android_hardware_Camera.cpp
@@ -795,6 +795,17 @@
     }
 }
 
+static void android_hardware_Camera_enableFocusMoveCallback(JNIEnv *env, jobject thiz, jint enable)
+{
+    ALOGV("enableFocusMoveCallback");
+    sp<Camera> camera = get_native_camera(env, thiz, NULL);
+    if (camera == 0) return;
+
+    if (camera->sendCommand(CAMERA_CMD_ENABLE_FOCUS_MOVE_MSG, enable, 0) != NO_ERROR) {
+        jniThrowRuntimeException(env, "enable focus move callback failed");
+    }
+}
+
 //-------------------------------------------------
 
 static JNINativeMethod camMethods[] = {
@@ -870,6 +881,9 @@
   { "_stopFaceDetection",
     "()V",
     (void *)android_hardware_Camera_stopFaceDetection},
+  { "enableFocusMoveCallback",
+    "(I)V",
+    (void *)android_hardware_Camera_enableFocusMoveCallback},
 };
 
 struct field {
diff --git a/core/jni/android_hardware_SensorManager.cpp b/core/jni/android_hardware_SensorManager.cpp
index 10ceb7b..202abf6 100644
--- a/core/jni/android_hardware_SensorManager.cpp
+++ b/core/jni/android_hardware_SensorManager.cpp
@@ -126,7 +126,7 @@
     ASensorEvent event;
 
     res = queue->read(&event, 1);
-    if (res == -EAGAIN) {
+    if (res == 0) {
         res = queue->waitForEvent();
         if (res != NO_ERROR)
             return -1;
diff --git a/core/jni/android_net_wifi_Wifi.cpp b/core/jni/android_net_wifi_Wifi.cpp
index 84c636b..90c24b5 100644
--- a/core/jni/android_net_wifi_Wifi.cpp
+++ b/core/jni/android_net_wifi_Wifi.cpp
@@ -34,6 +34,7 @@
 namespace android {
 
 static jboolean sScanModeActive = false;
+static jint DBG = false;
 
 static int doCommand(const char *cmd, char *replybuf, int replybuflen)
 {
@@ -527,6 +528,7 @@
     if (command.c_str() == NULL) {
         return JNI_FALSE;
     }
+    if (DBG) LOGD("doBoolean: %s", command.c_str());
     return doBooleanCommand("OK", "%s", command.c_str());
 }
 
@@ -536,6 +538,7 @@
     if (command.c_str() == NULL) {
         return -1;
     }
+    if (DBG) LOGD("doInt: %s", command.c_str());
     return doIntCommand("%s", command.c_str());
 }
 
@@ -545,6 +548,7 @@
     if (command.c_str() == NULL) {
         return NULL;
     }
+    if (DBG) LOGD("doString: %s", command.c_str());
     return doStringCommand(env, "%s", command.c_str());
 }
 
diff --git a/core/jni/android_view_DisplayEventReceiver.cpp b/core/jni/android_view_DisplayEventReceiver.cpp
new file mode 100644
index 0000000..f61795d
--- /dev/null
+++ b/core/jni/android_view_DisplayEventReceiver.cpp
@@ -0,0 +1,269 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "DisplayEventReceiver"
+
+//#define LOG_NDEBUG 0
+
+
+#include "JNIHelp.h"
+
+#include <android_runtime/AndroidRuntime.h>
+#include <utils/Log.h>
+#include <utils/Looper.h>
+#include <utils/threads.h>
+#include <gui/DisplayEventReceiver.h>
+#include "android_os_MessageQueue.h"
+
+namespace android {
+
+// Number of events to read at a time from the DisplayEventReceiver pipe.
+// The value should be large enough that we can quickly drain the pipe
+// using just a few large reads.
+static const size_t EVENT_BUFFER_SIZE = 100;
+
+static struct {
+    jclass clazz;
+
+    jmethodID dispatchVsync;
+} gDisplayEventReceiverClassInfo;
+
+
+class NativeDisplayEventReceiver : public RefBase {
+public:
+    NativeDisplayEventReceiver(JNIEnv* env,
+            jobject receiverObj, const sp<Looper>& looper);
+
+    status_t initialize();
+    status_t scheduleVsync();
+    static int handleReceiveCallback(int receiveFd, int events, void* data);
+
+protected:
+    virtual ~NativeDisplayEventReceiver();
+
+private:
+    jobject mReceiverObjGlobal;
+    sp<Looper> mLooper;
+    DisplayEventReceiver mReceiver;
+    bool mWaitingForVsync;
+    bool mFdCallbackRegistered;
+};
+
+
+NativeDisplayEventReceiver::NativeDisplayEventReceiver(JNIEnv* env,
+        jobject receiverObj, const sp<Looper>& looper) :
+        mReceiverObjGlobal(env->NewGlobalRef(receiverObj)),
+        mLooper(looper), mWaitingForVsync(false), mFdCallbackRegistered(false) {
+    ALOGV("receiver %p ~ Initializing input event receiver.", this);
+}
+
+NativeDisplayEventReceiver::~NativeDisplayEventReceiver() {
+    ALOGV("receiver %p ~ Disposing display event receiver.", this);
+
+    if (mFdCallbackRegistered) {
+        mLooper->removeFd(mReceiver.getFd());
+    }
+
+    JNIEnv* env = AndroidRuntime::getJNIEnv();
+    env->DeleteGlobalRef(mReceiverObjGlobal);
+}
+
+status_t NativeDisplayEventReceiver::initialize() {
+    status_t result = mReceiver.initCheck();
+    if (result) {
+        LOGW("Failed to initialize display event receiver, status=%d", result);
+        return result;
+    }
+
+    return OK;
+}
+
+status_t NativeDisplayEventReceiver::scheduleVsync() {
+    if (!mWaitingForVsync) {
+        ALOGV("receiver %p ~ Scheduling vsync.", this);
+
+        // Drain all pending events.
+        DisplayEventReceiver::Event buf[EVENT_BUFFER_SIZE];
+        ssize_t n;
+        while ((n = mReceiver.getEvents(buf, EVENT_BUFFER_SIZE)) > 0) {
+            ALOGV("receiver %p ~ Drained %d events.", this, int(n));
+        }
+
+        if (n < 0) {
+            LOGW("Failed to drain events from display event receiver, status=%d", status_t(n));
+            return status_t(n);
+        }
+
+        status_t status = mReceiver.requestNextVsync();
+        if (status) {
+            LOGW("Failed to request next vsync, status=%d", status);
+            return status;
+        }
+
+        if (!mFdCallbackRegistered) {
+            int rc = mLooper->addFd(mReceiver.getFd(), 0, ALOOPER_EVENT_INPUT,
+                    handleReceiveCallback, this);
+            if (rc < 0) {
+                return UNKNOWN_ERROR;
+            }
+            mFdCallbackRegistered = true;
+        }
+
+        mWaitingForVsync = true;
+    }
+    return OK;
+}
+
+int NativeDisplayEventReceiver::handleReceiveCallback(int receiveFd, int events, void* data) {
+    sp<NativeDisplayEventReceiver> r = static_cast<NativeDisplayEventReceiver*>(data);
+
+    if (events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP)) {
+        LOGE("Display event receiver pipe was closed or an error occurred.  "
+                "events=0x%x", events);
+        r->mFdCallbackRegistered = false;
+        return 0; // remove the callback
+    }
+
+    if (!(events & ALOOPER_EVENT_INPUT)) {
+        LOGW("Received spurious callback for unhandled poll event.  "
+                "events=0x%x", events);
+        return 1; // keep the callback
+    }
+
+    // Drain all pending events, keep the last vsync.
+    nsecs_t vsyncTimestamp = -1;
+    uint32_t vsyncCount = 0;
+
+    DisplayEventReceiver::Event buf[EVENT_BUFFER_SIZE];
+    ssize_t n;
+    while ((n = r->mReceiver.getEvents(buf, EVENT_BUFFER_SIZE)) > 0) {
+        ALOGV("receiver %p ~ Read %d events.", this, int(n));
+        while (n-- > 0) {
+            if (buf[n].header.type == DisplayEventReceiver::DISPLAY_EVENT_VSYNC) {
+                vsyncTimestamp = buf[n].header.timestamp;
+                vsyncCount = buf[n].vsync.count;
+                break; // stop at last vsync in the buffer
+            }
+        }
+    }
+
+    if (vsyncTimestamp < 0) {
+        ALOGV("receiver %p ~ Woke up but there was no vsync pulse!", this);
+        return 1; // keep the callback, did not obtain a vsync pulse
+    }
+
+    ALOGV("receiver %p ~ Vsync pulse: timestamp=%lld, count=%d",
+            this, vsyncTimestamp, vsyncCount);
+    r->mWaitingForVsync = false;
+
+    JNIEnv* env = AndroidRuntime::getJNIEnv();
+
+    ALOGV("receiver %p ~ Invoking vsync handler.", this);
+    env->CallVoidMethod(r->mReceiverObjGlobal,
+            gDisplayEventReceiverClassInfo.dispatchVsync, vsyncTimestamp, vsyncCount);
+    ALOGV("receiver %p ~ Returned from vsync handler.", this);
+
+    if (env->ExceptionCheck()) {
+        LOGE("An exception occurred while dispatching a vsync event.");
+        LOGE_EX(env);
+        env->ExceptionClear();
+    }
+
+    // Check whether dispatchVsync called scheduleVsync reentrantly and set mWaitingForVsync.
+    // If so, keep the callback, otherwise remove it.
+    if (r->mWaitingForVsync) {
+        return 1; // keep the callback
+    }
+    r->mFdCallbackRegistered = false;
+    return 0; // remove the callback
+}
+
+
+static jint nativeInit(JNIEnv* env, jclass clazz, jobject receiverObj,
+        jobject messageQueueObj) {
+    sp<Looper> looper = android_os_MessageQueue_getLooper(env, messageQueueObj);
+    if (looper == NULL) {
+        jniThrowRuntimeException(env, "MessageQueue is not initialized.");
+        return 0;
+    }
+
+    sp<NativeDisplayEventReceiver> receiver = new NativeDisplayEventReceiver(env,
+            receiverObj, looper);
+    status_t status = receiver->initialize();
+    if (status) {
+        String8 message;
+        message.appendFormat("Failed to initialize display event receiver.  status=%d", status);
+        jniThrowRuntimeException(env, message.string());
+        return 0;
+    }
+
+    receiver->incStrong(gDisplayEventReceiverClassInfo.clazz); // retain a reference for the object
+    return reinterpret_cast<jint>(receiver.get());
+}
+
+static void nativeDispose(JNIEnv* env, jclass clazz, jint receiverPtr) {
+    sp<NativeDisplayEventReceiver> receiver =
+            reinterpret_cast<NativeDisplayEventReceiver*>(receiverPtr);
+    receiver->decStrong(gDisplayEventReceiverClassInfo.clazz); // drop reference held by the object
+}
+
+static void nativeScheduleVsync(JNIEnv* env, jclass clazz, jint receiverPtr) {
+    sp<NativeDisplayEventReceiver> receiver =
+            reinterpret_cast<NativeDisplayEventReceiver*>(receiverPtr);
+    status_t status = receiver->scheduleVsync();
+    if (status) {
+        String8 message;
+        message.appendFormat("Failed to schedule next vertical sync pulse.  status=%d", status);
+        jniThrowRuntimeException(env, message.string());
+    }
+}
+
+
+static JNINativeMethod gMethods[] = {
+    /* name, signature, funcPtr */
+    { "nativeInit",
+            "(Landroid/view/DisplayEventReceiver;Landroid/os/MessageQueue;)I",
+            (void*)nativeInit },
+    { "nativeDispose",
+            "(I)V",
+            (void*)nativeDispose },
+    { "nativeScheduleVsync", "(I)V",
+            (void*)nativeScheduleVsync }
+};
+
+#define FIND_CLASS(var, className) \
+        var = env->FindClass(className); \
+        LOG_FATAL_IF(! var, "Unable to find class " className); \
+        var = jclass(env->NewGlobalRef(var));
+
+#define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \
+        var = env->GetMethodID(clazz, methodName, methodDescriptor); \
+        LOG_FATAL_IF(! var, "Unable to find method " methodName);
+
+int register_android_view_DisplayEventReceiver(JNIEnv* env) {
+    int res = jniRegisterNativeMethods(env, "android/view/DisplayEventReceiver",
+            gMethods, NELEM(gMethods));
+    LOG_FATAL_IF(res < 0, "Unable to register native methods.");
+
+    FIND_CLASS(gDisplayEventReceiverClassInfo.clazz, "android/view/DisplayEventReceiver");
+
+    GET_METHOD_ID(gDisplayEventReceiverClassInfo.dispatchVsync,
+            gDisplayEventReceiverClassInfo.clazz,
+            "dispatchVsync", "(JI)V");
+    return 0;
+}
+
+} // namespace android
diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp
index 4f75fad..5860658 100644
--- a/core/jni/android_view_GLES20Canvas.cpp
+++ b/core/jni/android_view_GLES20Canvas.cpp
@@ -23,6 +23,7 @@
 #include <nativehelper/JNIHelp.h>
 #include <android_runtime/AndroidRuntime.h>
 #include <android_runtime/android_graphics_SurfaceTexture.h>
+#include <cutils/properties.h>
 #include <utils/ResourceTypes.h>
 
 #include <gui/SurfaceTexture.h>
@@ -43,7 +44,7 @@
 #include <SkiaColorFilter.h>
 #include <Rect.h>
 
-#include <TextLayout.h>
+#include <TextLayoutCache.h>
 
 namespace android {
 
@@ -486,66 +487,45 @@
 
 static void renderText(OpenGLRenderer* renderer, const jchar* text, int count,
         jfloat x, jfloat y, int flags, SkPaint* paint) {
-#if RTL_USE_HARFBUZZ
     sp<TextLayoutCacheValue> value;
 #if USE_TEXT_LAYOUT_CACHE
     value = TextLayoutCache::getInstance().getValue(paint, text, 0, count, count, flags);
     if (value == NULL) {
-        LOGE("Cannot get TextLayoutCache value");
-        return ;
+        LOGE("Cannot get TextLayoutCache value for text = '%s'",
+                String8(text, count).string());
+        return;
     }
 #else
-    value = new TextLayoutCacheValue();
-    value->computeValues(paint, text, 0, count, count, flags);
+    value = new TextLayoutCacheValue(count);
+    TextLayoutEngine::getInstance().computeValues(value.get(), paint,
+            text, 0, count, count, flags);
 #endif
     const jchar* glyphs = value->getGlyphs();
     size_t glyphsCount = value->getGlyphsCount();
     int bytesCount = glyphsCount * sizeof(jchar);
     renderer->drawText((const char*) glyphs, bytesCount, glyphsCount, x, y, paint);
-#else
-    const jchar *workText;
-    jchar* buffer = NULL;
-    int32_t workBytes;
-    if (TextLayout::prepareText(paint, text, count, flags, &workText, &workBytes, &buffer)) {
-        renderer->drawText((const char*) workText, workBytes, count, x, y, paint);
-        free(buffer);
-    }
-#endif
 }
 
 static void renderTextRun(OpenGLRenderer* renderer, const jchar* text,
         jint start, jint count, jint contextCount, jfloat x, jfloat y,
         int flags, SkPaint* paint) {
-#if RTL_USE_HARFBUZZ
     sp<TextLayoutCacheValue> value;
 #if USE_TEXT_LAYOUT_CACHE
     value = TextLayoutCache::getInstance().getValue(paint, text, start, count, contextCount, flags);
     if (value == NULL) {
-        LOGE("Cannot get TextLayoutCache value");
-        return ;
+        LOGE("Cannot get TextLayoutCache value for text = '%s'",
+                String8(text + start, count).string());
+        return;
     }
 #else
-    value = new TextLayoutCacheValue();
-    value->computeValues(paint, text, start, count, contextCount, flags);
+    value = new TextLayoutCacheValue(count);
+    TextLayoutEngine::getInstance().computeValues(value.get(), paint,
+            text, start, count, contextCount, flags);
 #endif
     const jchar* glyphs = value->getGlyphs();
     size_t glyphsCount = value->getGlyphsCount();
     int bytesCount = glyphsCount * sizeof(jchar);
     renderer->drawText((const char*) glyphs, bytesCount, glyphsCount, x, y, paint);
-#else
-    uint8_t rtl = flags & 0x1;
-    if (rtl) {
-        SkAutoSTMalloc<80, jchar> buffer(contextCount);
-        jchar* shaped = buffer.get();
-        if (TextLayout::prepareRtlTextRun(text, start, count, contextCount, shaped)) {
-            renderer->drawText((const char*) shaped, count << 1, count, x, y, paint);
-        } else {
-            LOGW("drawTextRun error");
-        }
-    } else {
-        renderer->drawText((const char*) (text + start), count << 1, count, x, y, paint);
-    }
-#endif
 }
 
 static void android_view_GLES20Canvas_drawTextArray(JNIEnv* env, jobject clazz,
@@ -718,6 +698,10 @@
     LayerRenderer::destroyLayerDeferred(layer);
 }
 
+static void android_view_GLES20Canvas_flushLayer(JNIEnv* env, jobject clazz, Layer* layer) {
+    LayerRenderer::flushLayer(layer);
+}
+
 static void android_view_GLES20Canvas_drawLayer(JNIEnv* env, jobject clazz,
         OpenGLRenderer* renderer, Layer* layer, jfloat x, jfloat y, SkPaint* paint) {
     renderer->drawLayer(layer, x, y, paint);
@@ -736,7 +720,15 @@
 
 static jboolean android_view_GLES20Canvas_isAvailable(JNIEnv* env, jobject clazz) {
 #ifdef USE_OPENGL_RENDERER
-    return JNI_TRUE;
+    char prop[PROPERTY_VALUE_MAX];
+    if (property_get("ro.kernel.qemu", prop, NULL) == 0) {
+        // not in the emulator
+        return JNI_TRUE;
+    }
+    // In the emulator this property will be set to 1 when hardware GLES is
+    // enabled, 0 otherwise. On old emulator versions it will be undefined.
+    property_get("ro.kernel.qemu.gles", prop, "0");
+    return atoi(prop) == 1 ? JNI_TRUE : JNI_FALSE;
 #else
     return JNI_FALSE;
 #endif
@@ -860,6 +852,7 @@
     { "nSetTextureLayerTransform", "(II)V",    (void*) android_view_GLES20Canvas_setTextureLayerTransform },
     { "nDestroyLayer",           "(I)V",       (void*) android_view_GLES20Canvas_destroyLayer },
     { "nDestroyLayerDeferred",   "(I)V",       (void*) android_view_GLES20Canvas_destroyLayerDeferred },
+    { "nFlushLayer",             "(I)V",       (void*) android_view_GLES20Canvas_flushLayer },
     { "nDrawLayer",              "(IIFFI)V",   (void*) android_view_GLES20Canvas_drawLayer },
     { "nCopyLayer",              "(II)Z",      (void*) android_view_GLES20Canvas_copyLayer },
 
diff --git a/core/jni/android_view_InputEventReceiver.cpp b/core/jni/android_view_InputEventReceiver.cpp
new file mode 100644
index 0000000..523baf1
--- /dev/null
+++ b/core/jni/android_view_InputEventReceiver.cpp
@@ -0,0 +1,306 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "InputEventReceiver"
+
+//#define LOG_NDEBUG 0
+
+// Log debug messages about the dispatch cycle.
+#define DEBUG_DISPATCH_CYCLE 0
+
+
+#include "JNIHelp.h"
+
+#include <android_runtime/AndroidRuntime.h>
+#include <utils/Log.h>
+#include <utils/Looper.h>
+#include <utils/threads.h>
+#include <ui/InputTransport.h>
+#include "android_os_MessageQueue.h"
+#include "android_view_InputChannel.h"
+#include "android_view_KeyEvent.h"
+#include "android_view_MotionEvent.h"
+
+namespace android {
+
+static struct {
+    jclass clazz;
+
+    jmethodID dispatchInputEvent;
+} gInputEventReceiverClassInfo;
+
+
+class NativeInputEventReceiver : public RefBase {
+public:
+    NativeInputEventReceiver(JNIEnv* env,
+            jobject receiverObj, const sp<InputChannel>& inputChannel,
+            const sp<Looper>& looper);
+
+    status_t initialize();
+    status_t finishInputEvent(bool handled);
+    static int handleReceiveCallback(int receiveFd, int events, void* data);
+
+protected:
+    virtual ~NativeInputEventReceiver();
+
+private:
+    jobject mReceiverObjGlobal;
+    InputConsumer mInputConsumer;
+    sp<Looper> mLooper;
+    bool mEventInProgress;
+    PreallocatedInputEventFactory mInputEventFactory;
+
+    const char* getInputChannelName() {
+        return mInputConsumer.getChannel()->getName().string();
+    }
+};
+
+
+NativeInputEventReceiver::NativeInputEventReceiver(JNIEnv* env,
+        jobject receiverObj, const sp<InputChannel>& inputChannel, const sp<Looper>& looper) :
+        mReceiverObjGlobal(env->NewGlobalRef(receiverObj)),
+        mInputConsumer(inputChannel), mLooper(looper), mEventInProgress(false) {
+#if DEBUG_DISPATCH_CYCLE
+    LOGD("channel '%s' ~ Initializing input event receiver.", getInputChannelName());
+#endif
+}
+
+NativeInputEventReceiver::~NativeInputEventReceiver() {
+#if DEBUG_DISPATCH_CYCLE
+    LOGD("channel '%s' ~ Disposing input event receiver.", getInputChannelName());
+#endif
+
+    mLooper->removeFd(mInputConsumer.getChannel()->getReceivePipeFd());
+    if (mEventInProgress) {
+        mInputConsumer.sendFinishedSignal(false); // ignoring result
+    }
+
+    JNIEnv* env = AndroidRuntime::getJNIEnv();
+    env->DeleteGlobalRef(mReceiverObjGlobal);
+}
+
+status_t NativeInputEventReceiver::initialize() {
+    status_t result = mInputConsumer.initialize();
+    if (result) {
+        LOGW("Failed to initialize input consumer for input channel '%s', status=%d",
+                getInputChannelName(), result);
+        return result;
+    }
+
+    int32_t receiveFd = mInputConsumer.getChannel()->getReceivePipeFd();
+    mLooper->addFd(receiveFd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
+    return OK;
+}
+
+status_t NativeInputEventReceiver::finishInputEvent(bool handled) {
+    if (mEventInProgress) {
+#if DEBUG_DISPATCH_CYCLE
+        LOGD("channel '%s' ~ Finished input event.", getInputChannelName());
+#endif
+        mEventInProgress = false;
+
+        status_t status = mInputConsumer.sendFinishedSignal(handled);
+        if (status) {
+            LOGW("Failed to send finished signal on channel '%s'.  status=%d",
+                    getInputChannelName(), status);
+        }
+        return status;
+    } else {
+        LOGW("Ignoring attempt to finish input event while no event is in progress.");
+        return OK;
+    }
+}
+
+int NativeInputEventReceiver::handleReceiveCallback(int receiveFd, int events, void* data) {
+    sp<NativeInputEventReceiver> r = static_cast<NativeInputEventReceiver*>(data);
+
+    if (events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP)) {
+        LOGE("channel '%s' ~ Publisher closed input channel or an error occurred.  "
+                "events=0x%x", r->getInputChannelName(), events);
+        return 0; // remove the callback
+    }
+
+    if (!(events & ALOOPER_EVENT_INPUT)) {
+        LOGW("channel '%s' ~ Received spurious callback for unhandled poll event.  "
+                "events=0x%x", r->getInputChannelName(), events);
+        return 1;
+    }
+
+    status_t status = r->mInputConsumer.receiveDispatchSignal();
+    if (status) {
+        LOGE("channel '%s' ~ Failed to receive dispatch signal.  status=%d",
+                r->getInputChannelName(), status);
+        return 0; // remove the callback
+    }
+
+    if (r->mEventInProgress) {
+        LOGW("channel '%s' ~ Publisher sent spurious dispatch signal.",
+                r->getInputChannelName());
+        return 1;
+    }
+
+    InputEvent* inputEvent;
+    status = r->mInputConsumer.consume(&r->mInputEventFactory, &inputEvent);
+    if (status) {
+        LOGW("channel '%s' ~ Failed to consume input event.  status=%d",
+                r->getInputChannelName(), status);
+        r->mInputConsumer.sendFinishedSignal(false);
+        return 1;
+    }
+
+    JNIEnv* env = AndroidRuntime::getJNIEnv();
+    jobject inputEventObj;
+    switch (inputEvent->getType()) {
+    case AINPUT_EVENT_TYPE_KEY:
+#if DEBUG_DISPATCH_CYCLE
+        LOGD("channel '%s' ~ Received key event.",
+                r->getInputChannelName());
+#endif
+        inputEventObj = android_view_KeyEvent_fromNative(env,
+                static_cast<KeyEvent*>(inputEvent));
+        break;
+
+    case AINPUT_EVENT_TYPE_MOTION:
+#if DEBUG_DISPATCH_CYCLE
+        LOGD("channel '%s' ~ Received motion event.",
+                r->getInputChannelName());
+#endif
+        inputEventObj = android_view_MotionEvent_obtainAsCopy(env,
+                static_cast<MotionEvent*>(inputEvent));
+        break;
+
+    default:
+        assert(false); // InputConsumer should prevent this from ever happening
+        inputEventObj = NULL;
+    }
+
+    if (!inputEventObj) {
+        LOGW("channel '%s' ~ Failed to obtain event object.",
+                r->getInputChannelName());
+        r->mInputConsumer.sendFinishedSignal(false);
+        return 1;
+    }
+
+    r->mEventInProgress = true;
+
+#if DEBUG_DISPATCH_CYCLE
+    LOGD("channel '%s' ~ Invoking input handler.", r->getInputChannelName());
+#endif
+    env->CallVoidMethod(r->mReceiverObjGlobal,
+            gInputEventReceiverClassInfo.dispatchInputEvent, inputEventObj);
+#if DEBUG_DISPATCH_CYCLE
+    LOGD("channel '%s' ~ Returned from input handler.", r->getInputChannelName());
+#endif
+
+    if (env->ExceptionCheck()) {
+        LOGE("channel '%s' ~ An exception occurred while dispatching an event.",
+                r->getInputChannelName());
+        LOGE_EX(env);
+        env->ExceptionClear();
+
+        if (r->mEventInProgress) {
+            r->mInputConsumer.sendFinishedSignal(false);
+            r->mEventInProgress = false;
+        }
+    }
+
+    env->DeleteLocalRef(inputEventObj);
+    return 1;
+}
+
+
+static jint nativeInit(JNIEnv* env, jclass clazz, jobject receiverObj,
+        jobject inputChannelObj, jobject messageQueueObj) {
+    sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env,
+            inputChannelObj);
+    if (inputChannel == NULL) {
+        jniThrowRuntimeException(env, "InputChannel is not initialized.");
+        return 0;
+    }
+
+    sp<Looper> looper = android_os_MessageQueue_getLooper(env, messageQueueObj);
+    if (looper == NULL) {
+        jniThrowRuntimeException(env, "MessageQueue is not initialized.");
+        return 0;
+    }
+
+    sp<NativeInputEventReceiver> receiver = new NativeInputEventReceiver(env,
+            receiverObj, inputChannel, looper);
+    status_t status = receiver->initialize();
+    if (status) {
+        String8 message;
+        message.appendFormat("Failed to initialize input event receiver.  status=%d", status);
+        jniThrowRuntimeException(env, message.string());
+        return 0;
+    }
+
+    receiver->incStrong(gInputEventReceiverClassInfo.clazz); // retain a reference for the object
+    return reinterpret_cast<jint>(receiver.get());
+}
+
+static void nativeDispose(JNIEnv* env, jclass clazz, jint receiverPtr) {
+    sp<NativeInputEventReceiver> receiver =
+            reinterpret_cast<NativeInputEventReceiver*>(receiverPtr);
+    receiver->decStrong(gInputEventReceiverClassInfo.clazz); // drop reference held by the object
+}
+
+static void nativeFinishInputEvent(JNIEnv* env, jclass clazz, jint receiverPtr, jboolean handled) {
+    sp<NativeInputEventReceiver> receiver =
+            reinterpret_cast<NativeInputEventReceiver*>(receiverPtr);
+    status_t status = receiver->finishInputEvent(handled);
+    if (status) {
+        String8 message;
+        message.appendFormat("Failed to finish input event.  status=%d", status);
+        jniThrowRuntimeException(env, message.string());
+    }
+}
+
+
+static JNINativeMethod gMethods[] = {
+    /* name, signature, funcPtr */
+    { "nativeInit",
+            "(Landroid/view/InputEventReceiver;Landroid/view/InputChannel;Landroid/os/MessageQueue;)I",
+            (void*)nativeInit },
+    { "nativeDispose",
+            "(I)V",
+            (void*)nativeDispose },
+    { "nativeFinishInputEvent", "(IZ)V",
+            (void*)nativeFinishInputEvent }
+};
+
+#define FIND_CLASS(var, className) \
+        var = env->FindClass(className); \
+        LOG_FATAL_IF(! var, "Unable to find class " className); \
+        var = jclass(env->NewGlobalRef(var));
+
+#define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \
+        var = env->GetMethodID(clazz, methodName, methodDescriptor); \
+        LOG_FATAL_IF(! var, "Unable to find method " methodName);
+
+int register_android_view_InputEventReceiver(JNIEnv* env) {
+    int res = jniRegisterNativeMethods(env, "android/view/InputEventReceiver",
+            gMethods, NELEM(gMethods));
+    LOG_FATAL_IF(res < 0, "Unable to register native methods.");
+
+    FIND_CLASS(gInputEventReceiverClassInfo.clazz, "android/view/InputEventReceiver");
+
+    GET_METHOD_ID(gInputEventReceiverClassInfo.dispatchInputEvent,
+            gInputEventReceiverClassInfo.clazz,
+            "dispatchInputEvent", "(Landroid/view/InputEvent;)V");
+    return 0;
+}
+
+} // namespace android
diff --git a/core/jni/android_view_InputQueue.cpp b/core/jni/android_view_InputQueue.cpp
deleted file mode 100644
index 300c04a..0000000
--- a/core/jni/android_view_InputQueue.cpp
+++ /dev/null
@@ -1,530 +0,0 @@
-/*
- * Copyright (C) 2010 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 "InputQueue-JNI"
-
-//#define LOG_NDEBUG 0
-
-// Log debug messages about the dispatch cycle.
-#define DEBUG_DISPATCH_CYCLE 0
-
-// Log debug messages about registrations.
-#define DEBUG_REGISTRATION 0
-
-
-#include "JNIHelp.h"
-
-#include <android_runtime/AndroidRuntime.h>
-#include <utils/Log.h>
-#include <utils/Looper.h>
-#include <utils/KeyedVector.h>
-#include <utils/threads.h>
-#include <ui/InputTransport.h>
-#include "android_os_MessageQueue.h"
-#include "android_view_InputChannel.h"
-#include "android_view_KeyEvent.h"
-#include "android_view_MotionEvent.h"
-
-namespace android {
-
-// ----------------------------------------------------------------------------
-
-static struct {
-    jclass clazz;
-
-    jmethodID dispatchKeyEvent;
-    jmethodID dispatchMotionEvent;
-} gInputQueueClassInfo;
-
-// ----------------------------------------------------------------------------
-
-class NativeInputQueue {
-public:
-    NativeInputQueue();
-    ~NativeInputQueue();
-
-    status_t registerInputChannel(JNIEnv* env, jobject inputChannelObj,
-            jobject inputHandlerObj, jobject messageQueueObj);
-
-    status_t unregisterInputChannel(JNIEnv* env, jobject inputChannelObj);
-
-    status_t finished(JNIEnv* env, jlong finishedToken, bool handled, bool ignoreSpuriousFinish);
-
-private:
-    class Connection : public RefBase {
-    protected:
-        virtual ~Connection();
-
-    public:
-        enum Status {
-            // Everything is peachy.
-            STATUS_NORMAL,
-            // The input channel has been unregistered.
-            STATUS_ZOMBIE
-        };
-
-        Connection(uint16_t id,
-                const sp<InputChannel>& inputChannel, const sp<Looper>& looper);
-
-        inline const char* getInputChannelName() const { return inputChannel->getName().string(); }
-
-        // A unique id for this connection.
-        uint16_t id;
-
-        Status status;
-
-        sp<InputChannel> inputChannel;
-        InputConsumer inputConsumer;
-        sp<Looper> looper;
-        jobject inputHandlerObjGlobal;
-        PreallocatedInputEventFactory inputEventFactory;
-
-        // The sequence number of the current event being dispatched.
-        // This is used as part of the finished token as a way to determine whether the finished
-        // token is still valid before sending a finished signal back to the publisher.
-        uint16_t messageSeqNum;
-
-        // True if a message has been received from the publisher but not yet finished.
-        bool messageInProgress;
-    };
-
-    Mutex mLock;
-    uint16_t mNextConnectionId;
-    KeyedVector<int32_t, sp<Connection> > mConnectionsByReceiveFd;
-
-    ssize_t getConnectionIndex(const sp<InputChannel>& inputChannel);
-
-    static void handleInputChannelDisposed(JNIEnv* env,
-            jobject inputChannelObj, const sp<InputChannel>& inputChannel, void* data);
-
-    static int handleReceiveCallback(int receiveFd, int events, void* data);
-
-    static jlong generateFinishedToken(int32_t receiveFd,
-            uint16_t connectionId, uint16_t messageSeqNum);
-
-    static void parseFinishedToken(jlong finishedToken,
-            int32_t* outReceiveFd, uint16_t* outConnectionId, uint16_t* outMessageIndex);
-};
-
-// ----------------------------------------------------------------------------
-
-NativeInputQueue::NativeInputQueue() :
-        mNextConnectionId(0) {
-}
-
-NativeInputQueue::~NativeInputQueue() {
-}
-
-status_t NativeInputQueue::registerInputChannel(JNIEnv* env, jobject inputChannelObj,
-        jobject inputHandlerObj, jobject messageQueueObj) {
-    sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env,
-            inputChannelObj);
-    if (inputChannel == NULL) {
-        LOGW("Input channel is not initialized.");
-        return BAD_VALUE;
-    }
-
-#if DEBUG_REGISTRATION
-    LOGD("channel '%s' - Registered", inputChannel->getName().string());
-#endif
-
-    sp<Looper> looper = android_os_MessageQueue_getLooper(env, messageQueueObj);
-
-    { // acquire lock
-        AutoMutex _l(mLock);
-
-        if (getConnectionIndex(inputChannel) >= 0) {
-            LOGW("Attempted to register already registered input channel '%s'",
-                    inputChannel->getName().string());
-            return BAD_VALUE;
-        }
-
-        uint16_t connectionId = mNextConnectionId++;
-        sp<Connection> connection = new Connection(connectionId, inputChannel, looper);
-        status_t result = connection->inputConsumer.initialize();
-        if (result) {
-            LOGW("Failed to initialize input consumer for input channel '%s', status=%d",
-                    inputChannel->getName().string(), result);
-            return result;
-        }
-
-        connection->inputHandlerObjGlobal = env->NewGlobalRef(inputHandlerObj);
-
-        int32_t receiveFd = inputChannel->getReceivePipeFd();
-        mConnectionsByReceiveFd.add(receiveFd, connection);
-
-        looper->addFd(receiveFd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
-    } // release lock
-
-    android_view_InputChannel_setDisposeCallback(env, inputChannelObj,
-            handleInputChannelDisposed, this);
-    return OK;
-}
-
-status_t NativeInputQueue::unregisterInputChannel(JNIEnv* env, jobject inputChannelObj) {
-    sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env,
-            inputChannelObj);
-    if (inputChannel == NULL) {
-        LOGW("Input channel is not initialized.");
-        return BAD_VALUE;
-    }
-
-#if DEBUG_REGISTRATION
-    LOGD("channel '%s' - Unregistered", inputChannel->getName().string());
-#endif
-
-    { // acquire lock
-        AutoMutex _l(mLock);
-
-        ssize_t connectionIndex = getConnectionIndex(inputChannel);
-        if (connectionIndex < 0) {
-            LOGW("Attempted to unregister already unregistered input channel '%s'",
-                    inputChannel->getName().string());
-            return BAD_VALUE;
-        }
-
-        sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
-        mConnectionsByReceiveFd.removeItemsAt(connectionIndex);
-
-        connection->status = Connection::STATUS_ZOMBIE;
-
-        connection->looper->removeFd(inputChannel->getReceivePipeFd());
-
-        env->DeleteGlobalRef(connection->inputHandlerObjGlobal);
-        connection->inputHandlerObjGlobal = NULL;
-
-        if (connection->messageInProgress) {
-            LOGI("Sending finished signal for input channel '%s' since it is being unregistered "
-                    "while an input message is still in progress.",
-                    connection->getInputChannelName());
-            connection->messageInProgress = false;
-            connection->inputConsumer.sendFinishedSignal(false); // ignoring result
-        }
-    } // release lock
-
-    android_view_InputChannel_setDisposeCallback(env, inputChannelObj, NULL, NULL);
-    return OK;
-}
-
-ssize_t NativeInputQueue::getConnectionIndex(const sp<InputChannel>& inputChannel) {
-    ssize_t connectionIndex = mConnectionsByReceiveFd.indexOfKey(inputChannel->getReceivePipeFd());
-    if (connectionIndex >= 0) {
-        sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
-        if (connection->inputChannel.get() == inputChannel.get()) {
-            return connectionIndex;
-        }
-    }
-
-    return -1;
-}
-
-status_t NativeInputQueue::finished(JNIEnv* env, jlong finishedToken,
-        bool handled, bool ignoreSpuriousFinish) {
-    int32_t receiveFd;
-    uint16_t connectionId;
-    uint16_t messageSeqNum;
-    parseFinishedToken(finishedToken, &receiveFd, &connectionId, &messageSeqNum);
-
-    { // acquire lock
-        AutoMutex _l(mLock);
-
-        ssize_t connectionIndex = mConnectionsByReceiveFd.indexOfKey(receiveFd);
-        if (connectionIndex < 0) {
-            if (! ignoreSpuriousFinish) {
-                LOGI("Ignoring finish signal on channel that is no longer registered.");
-            }
-            return DEAD_OBJECT;
-        }
-
-        sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
-        if (connectionId != connection->id) {
-            if (! ignoreSpuriousFinish) {
-                LOGI("Ignoring finish signal on channel that is no longer registered.");
-            }
-            return DEAD_OBJECT;
-        }
-
-        if (messageSeqNum != connection->messageSeqNum || ! connection->messageInProgress) {
-            if (! ignoreSpuriousFinish) {
-                LOGW("Attempted to finish input twice on channel '%s'.  "
-                        "finished messageSeqNum=%d, current messageSeqNum=%d, messageInProgress=%d",
-                        connection->getInputChannelName(),
-                        messageSeqNum, connection->messageSeqNum, connection->messageInProgress);
-            }
-            return INVALID_OPERATION;
-        }
-
-        connection->messageInProgress = false;
-
-        status_t status = connection->inputConsumer.sendFinishedSignal(handled);
-        if (status) {
-            LOGW("Failed to send finished signal on channel '%s'.  status=%d",
-                    connection->getInputChannelName(), status);
-            return status;
-        }
-
-#if DEBUG_DISPATCH_CYCLE
-        LOGD("channel '%s' ~ Finished event.",
-                connection->getInputChannelName());
-#endif
-    } // release lock
-
-    return OK;
-}
-
-void NativeInputQueue::handleInputChannelDisposed(JNIEnv* env,
-        jobject inputChannelObj, const sp<InputChannel>& inputChannel, void* data) {
-    LOGW("Input channel object '%s' was disposed without first being unregistered with "
-            "the input queue!", inputChannel->getName().string());
-
-    NativeInputQueue* q = static_cast<NativeInputQueue*>(data);
-    q->unregisterInputChannel(env, inputChannelObj);
-}
-
-int NativeInputQueue::handleReceiveCallback(int receiveFd, int events, void* data) {
-    NativeInputQueue* q = static_cast<NativeInputQueue*>(data);
-    JNIEnv* env = AndroidRuntime::getJNIEnv();
-
-    sp<Connection> connection;
-    InputEvent* inputEvent;
-    jobject inputHandlerObjLocal;
-    jlong finishedToken;
-    { // acquire lock
-        AutoMutex _l(q->mLock);
-
-        ssize_t connectionIndex = q->mConnectionsByReceiveFd.indexOfKey(receiveFd);
-        if (connectionIndex < 0) {
-            LOGE("Received spurious receive callback for unknown input channel.  "
-                    "fd=%d, events=0x%x", receiveFd, events);
-            return 0; // remove the callback
-        }
-
-        connection = q->mConnectionsByReceiveFd.valueAt(connectionIndex);
-        if (events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP)) {
-            LOGE("channel '%s' ~ Publisher closed input channel or an error occurred.  "
-                    "events=0x%x", connection->getInputChannelName(), events);
-            return 0; // remove the callback
-        }
-
-        if (! (events & ALOOPER_EVENT_INPUT)) {
-            LOGW("channel '%s' ~ Received spurious callback for unhandled poll event.  "
-                    "events=0x%x", connection->getInputChannelName(), events);
-            return 1;
-        }
-
-        status_t status = connection->inputConsumer.receiveDispatchSignal();
-        if (status) {
-            LOGE("channel '%s' ~ Failed to receive dispatch signal.  status=%d",
-                    connection->getInputChannelName(), status);
-            return 0; // remove the callback
-        }
-
-        if (connection->messageInProgress) {
-            LOGW("channel '%s' ~ Publisher sent spurious dispatch signal.",
-                    connection->getInputChannelName());
-            return 1;
-        }
-
-        status = connection->inputConsumer.consume(& connection->inputEventFactory, & inputEvent);
-        if (status) {
-            LOGW("channel '%s' ~ Failed to consume input event.  status=%d",
-                    connection->getInputChannelName(), status);
-            connection->inputConsumer.sendFinishedSignal(false);
-            return 1;
-        }
-
-        connection->messageInProgress = true;
-        connection->messageSeqNum += 1;
-
-        finishedToken = generateFinishedToken(receiveFd, connection->id, connection->messageSeqNum);
-
-        inputHandlerObjLocal = env->NewLocalRef(connection->inputHandlerObjGlobal);
-    } // release lock
-
-    // Invoke the handler outside of the lock.
-    //
-    // Note: inputEvent is stored in a field of the connection object which could potentially
-    //       become disposed due to the input channel being unregistered concurrently.
-    //       For this reason, we explicitly keep the connection object alive by holding
-    //       a strong pointer to it within this scope.  We also grabbed a local reference to
-    //       the input handler object itself for the same reason.
-
-    int32_t inputEventType = inputEvent->getType();
-
-    jobject inputEventObj;
-    jmethodID dispatchMethodId;
-    switch (inputEventType) {
-    case AINPUT_EVENT_TYPE_KEY:
-#if DEBUG_DISPATCH_CYCLE
-        LOGD("channel '%s' ~ Received key event.", connection->getInputChannelName());
-#endif
-        inputEventObj = android_view_KeyEvent_fromNative(env,
-                static_cast<KeyEvent*>(inputEvent));
-        dispatchMethodId = gInputQueueClassInfo.dispatchKeyEvent;
-        break;
-
-    case AINPUT_EVENT_TYPE_MOTION:
-#if DEBUG_DISPATCH_CYCLE
-        LOGD("channel '%s' ~ Received motion event.", connection->getInputChannelName());
-#endif
-        inputEventObj = android_view_MotionEvent_obtainAsCopy(env,
-                static_cast<MotionEvent*>(inputEvent));
-        dispatchMethodId = gInputQueueClassInfo.dispatchMotionEvent;
-        break;
-
-    default:
-        assert(false); // InputConsumer should prevent this from ever happening
-        inputEventObj = NULL;
-    }
-
-    if (! inputEventObj) {
-        LOGW("channel '%s' ~ Failed to obtain DVM event object.",
-                connection->getInputChannelName());
-        env->DeleteLocalRef(inputHandlerObjLocal);
-        q->finished(env, finishedToken, false, false);
-        return 1;
-    }
-
-#if DEBUG_DISPATCH_CYCLE
-    LOGD("Invoking input handler.");
-#endif
-    env->CallStaticVoidMethod(gInputQueueClassInfo.clazz,
-            dispatchMethodId, inputHandlerObjLocal, inputEventObj,
-            jlong(finishedToken));
-#if DEBUG_DISPATCH_CYCLE
-    LOGD("Returned from input handler.");
-#endif
-
-    if (env->ExceptionCheck()) {
-        LOGE("An exception occurred while invoking the input handler for an event.");
-        LOGE_EX(env);
-        env->ExceptionClear();
-
-        q->finished(env, finishedToken, false, true /*ignoreSpuriousFinish*/);
-    }
-
-    env->DeleteLocalRef(inputEventObj);
-    env->DeleteLocalRef(inputHandlerObjLocal);
-    return 1;
-}
-
-jlong NativeInputQueue::generateFinishedToken(int32_t receiveFd, uint16_t connectionId,
-        uint16_t messageSeqNum) {
-    return (jlong(receiveFd) << 32) | (jlong(connectionId) << 16) | jlong(messageSeqNum);
-}
-
-void NativeInputQueue::parseFinishedToken(jlong finishedToken,
-        int32_t* outReceiveFd, uint16_t* outConnectionId, uint16_t* outMessageIndex) {
-    *outReceiveFd = int32_t(finishedToken >> 32);
-    *outConnectionId = uint16_t(finishedToken >> 16);
-    *outMessageIndex = uint16_t(finishedToken);
-}
-
-// ----------------------------------------------------------------------------
-
-NativeInputQueue::Connection::Connection(uint16_t id,
-        const sp<InputChannel>& inputChannel, const sp<Looper>& looper) :
-    id(id), status(STATUS_NORMAL), inputChannel(inputChannel), inputConsumer(inputChannel),
-    looper(looper), inputHandlerObjGlobal(NULL),
-    messageSeqNum(0), messageInProgress(false) {
-}
-
-NativeInputQueue::Connection::~Connection() {
-}
-
-// ----------------------------------------------------------------------------
-
-static NativeInputQueue gNativeInputQueue;
-
-static void android_view_InputQueue_nativeRegisterInputChannel(JNIEnv* env, jclass clazz,
-        jobject inputChannelObj, jobject inputHandlerObj, jobject messageQueueObj) {
-    status_t status = gNativeInputQueue.registerInputChannel(
-            env, inputChannelObj, inputHandlerObj, messageQueueObj);
-
-    if (status) {
-        String8 message;
-        message.appendFormat("Failed to register input channel.  status=%d", status);
-        jniThrowRuntimeException(env, message.string());
-    }
-}
-
-static void android_view_InputQueue_nativeUnregisterInputChannel(JNIEnv* env, jclass clazz,
-        jobject inputChannelObj) {
-    status_t status = gNativeInputQueue.unregisterInputChannel(env, inputChannelObj);
-
-    if (status) {
-        String8 message;
-        message.appendFormat("Failed to unregister input channel.  status=%d", status);
-        jniThrowRuntimeException(env, message.string());
-    }
-}
-
-static void android_view_InputQueue_nativeFinished(JNIEnv* env, jclass clazz,
-        jlong finishedToken, bool handled) {
-    status_t status = gNativeInputQueue.finished(
-            env, finishedToken, handled, false /*ignoreSpuriousFinish*/);
-
-    // We ignore the case where an event could not be finished because the input channel
-    // was no longer registered (DEAD_OBJECT) since it is a common race that can occur
-    // during application shutdown.  The input dispatcher recovers gracefully anyways.
-    if (status != OK && status != DEAD_OBJECT) {
-        String8 message;
-        message.appendFormat("Failed to finish input event.  status=%d", status);
-        jniThrowRuntimeException(env, message.string());
-    }
-}
-
-// ----------------------------------------------------------------------------
-
-static JNINativeMethod gInputQueueMethods[] = {
-    /* name, signature, funcPtr */
-    { "nativeRegisterInputChannel",
-            "(Landroid/view/InputChannel;Landroid/view/InputHandler;Landroid/os/MessageQueue;)V",
-            (void*)android_view_InputQueue_nativeRegisterInputChannel },
-    { "nativeUnregisterInputChannel",
-            "(Landroid/view/InputChannel;)V",
-            (void*)android_view_InputQueue_nativeUnregisterInputChannel },
-    { "nativeFinished", "(JZ)V",
-            (void*)android_view_InputQueue_nativeFinished }
-};
-
-#define FIND_CLASS(var, className) \
-        var = env->FindClass(className); \
-        LOG_FATAL_IF(! var, "Unable to find class " className); \
-        var = jclass(env->NewGlobalRef(var));
-
-#define GET_STATIC_METHOD_ID(var, clazz, methodName, methodDescriptor) \
-        var = env->GetStaticMethodID(clazz, methodName, methodDescriptor); \
-        LOG_FATAL_IF(! var, "Unable to find static method " methodName);
-
-int register_android_view_InputQueue(JNIEnv* env) {
-    int res = jniRegisterNativeMethods(env, "android/view/InputQueue",
-            gInputQueueMethods, NELEM(gInputQueueMethods));
-    LOG_FATAL_IF(res < 0, "Unable to register native methods.");
-
-    FIND_CLASS(gInputQueueClassInfo.clazz, "android/view/InputQueue");
-
-    GET_STATIC_METHOD_ID(gInputQueueClassInfo.dispatchKeyEvent, gInputQueueClassInfo.clazz,
-            "dispatchKeyEvent",
-            "(Landroid/view/InputHandler;Landroid/view/KeyEvent;J)V");
-
-    GET_STATIC_METHOD_ID(gInputQueueClassInfo.dispatchMotionEvent, gInputQueueClassInfo.clazz,
-            "dispatchMotionEvent",
-            "(Landroid/view/InputHandler;Landroid/view/MotionEvent;J)V");
-    return 0;
-}
-
-} // namespace android
diff --git a/core/jni/android_view_Surface.cpp b/core/jni/android_view_Surface.cpp
index 49441eb..bba4b47 100644
--- a/core/jni/android_view_Surface.cpp
+++ b/core/jni/android_view_Surface.cpp
@@ -752,6 +752,25 @@
     }
 }
 
+static void Surface_transferFrom(
+        JNIEnv* env, jobject clazz, jobject other)
+{
+    if (clazz == other)
+        return;
+
+    if (other == NULL) {
+        doThrowNPE(env);
+        return;
+    }
+
+    sp<SurfaceControl> control(getSurfaceControl(env, other));
+    sp<Surface> surface(Surface_getSurface(env, other));
+    setSurfaceControl(env, clazz, control);
+    setSurface(env, clazz, surface);
+    setSurfaceControl(env, other, 0);
+    setSurface(env, other, 0);
+}
+
 static void Surface_readFromParcel(
         JNIEnv* env, jobject clazz, jobject argParcel)
 {
@@ -820,6 +839,7 @@
     {"destroy",             "()V",  (void*)Surface_destroy },
     {"release",             "()V",  (void*)Surface_release },
     {"copyFrom",            "(Landroid/view/Surface;)V",  (void*)Surface_copyFrom },
+    {"transferFrom",        "(Landroid/view/Surface;)V",  (void*)Surface_transferFrom },
     {"isValid",             "()Z",  (void*)Surface_isValid },
     {"lockCanvasNative",    "(Landroid/graphics/Rect;)Landroid/graphics/Canvas;",  (void*)Surface_lockCanvas },
     {"unlockCanvasAndPost", "(Landroid/graphics/Canvas;)V", (void*)Surface_unlockCanvasAndPost },
diff --git a/core/res/res/anim/app_starting_exit.xml b/core/res/res/anim/app_starting_exit.xml
index ee8d80b..60e4109 100644
--- a/core/res/res/anim/app_starting_exit.xml
+++ b/core/res/res/anim/app_starting_exit.xml
@@ -18,7 +18,8 @@
 */
 -->
 
-<set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@interpolator/decelerate_quad">
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+        android:detachWallpaper="true" android:interpolator="@interpolator/decelerate_quad">
 	<alpha android:fromAlpha="1.0" android:toAlpha="0.0" android:duration="160" />
 </set>
 
diff --git a/core/res/res/drawable-hdpi/numberpicker_selection_divider.9.png b/core/res/res/drawable-hdpi/numberpicker_selection_divider.9.png
index fb5e54f..c9c72ba 100644
--- a/core/res/res/drawable-hdpi/numberpicker_selection_divider.9.png
+++ b/core/res/res/drawable-hdpi/numberpicker_selection_divider.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/numberpicker_selection_divider.9.png b/core/res/res/drawable-mdpi/numberpicker_selection_divider.9.png
index d49cf7a..076fc16 100644
--- a/core/res/res/drawable-mdpi/numberpicker_selection_divider.9.png
+++ b/core/res/res/drawable-mdpi/numberpicker_selection_divider.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_selection_divider.9.png b/core/res/res/drawable-xhdpi/numberpicker_selection_divider.9.png
index 200e581..97eb5fe 100644
--- a/core/res/res/drawable-xhdpi/numberpicker_selection_divider.9.png
+++ b/core/res/res/drawable-xhdpi/numberpicker_selection_divider.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable/ic_sysbar_back_ime.xml b/core/res/res/drawable/silent_mode_indicator.xml
similarity index 74%
rename from packages/SystemUI/res/drawable/ic_sysbar_back_ime.xml
rename to core/res/res/drawable/silent_mode_indicator.xml
index 248496d..c4e129f 100644
--- a/packages/SystemUI/res/drawable/ic_sysbar_back_ime.xml
+++ b/core/res/res/drawable/silent_mode_indicator.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2008 The Android Open Source Project
+<!-- 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.
@@ -15,7 +15,6 @@
 -->
 
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_pressed="true" android:drawable="@drawable/ic_sysbar_back_ime_pressed" />
-    <item android:drawable="@drawable/ic_sysbar_back_ime_default" />
+    <item android:state_selected="false" android:drawable="@android:color/transparent" />
+    <item android:state_selected="true"  android:drawable="@drawable/tab_selected_holo" />
 </selector>
-
diff --git a/core/res/res/layout-sw600dp/keyguard_screen_password_landscape.xml b/core/res/res/layout-sw600dp/keyguard_screen_password_landscape.xml
index f972843..7a5bb6a 100644
--- a/core/res/res/layout-sw600dp/keyguard_screen_password_landscape.xml
+++ b/core/res/res/layout-sw600dp/keyguard_screen_password_landscape.xml
@@ -134,6 +134,7 @@
                 android:layout_marginTop="5dip"
                 android:keyBackground="@drawable/btn_keyboard_key_ics"
                 android:visibility="gone"
+                android:clickable="true"
             />
 
             <!-- Emergency call button. Generally not used on tablet devices. -->
diff --git a/core/res/res/layout-sw600dp/keyguard_screen_password_portrait.xml b/core/res/res/layout-sw600dp/keyguard_screen_password_portrait.xml
index 8b65b22..6df22ca 100644
--- a/core/res/res/layout-sw600dp/keyguard_screen_password_portrait.xml
+++ b/core/res/res/layout-sw600dp/keyguard_screen_password_portrait.xml
@@ -133,6 +133,7 @@
             android:background="#40000000"
             android:keyBackground="@drawable/btn_keyboard_key_ics"
             android:layout_marginBottom="80dip"
+            android:clickable="true"
         />
 
         <!-- emergency call button -->
diff --git a/core/res/res/layout/date_picker.xml b/core/res/res/layout/date_picker.xml
index 6f0517d..9c1def2 100644
--- a/core/res/res/layout/date_picker.xml
+++ b/core/res/res/layout/date_picker.xml
@@ -32,7 +32,6 @@
     <LinearLayout android:id="@+id/pickers"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:layout_marginRight="22dip"
         android:layout_weight="1"
         android:orientation="horizontal"
         android:gravity="center">
@@ -77,7 +76,7 @@
         android:id="@+id/calendar_view"
         android:layout_width="245dip"
         android:layout_height="280dip"
-        android:layout_marginLeft="22dip"
+        android:layout_marginLeft="44dip"
         android:layout_weight="1"
         android:focusable="true"
         android:focusableInTouchMode="true"
diff --git a/core/res/res/layout/global_actions_item.xml b/core/res/res/layout/global_actions_item.xml
index 67b1644..694301e 100644
--- a/core/res/res/layout/global_actions_item.xml
+++ b/core/res/res/layout/global_actions_item.xml
@@ -14,48 +14,46 @@
      limitations under the License.
 -->
 
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<!-- RelativeLayouts have an issue enforcing minimum heights, so just
+     work around this for now with LinearLayouts. -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
-    android:layout_height="?android:attr/listPreferredItemHeight"
+    android:layout_height="wrap_content"
+    android:minHeight="?android:attr/listPreferredItemHeight"
+    android:orientation="horizontal"
 
-    android:paddingLeft="11dip"
+    android:paddingLeft="16dip"
     android:paddingTop="6dip"
     android:paddingBottom="6dip"
     >
-
     <ImageView android:id="@+id/icon"
         android:layout_width="wrap_content"
         android:layout_height="match_parent"
-        android:layout_alignParentTop="true"
-        android:layout_alignParentBottom="true"
-        android:layout_marginRight="9dip"
-            />
-
-
-    <TextView android:id="@+id/status"
-        android:layout_width="match_parent"
-        android:layout_height="26dip"
-
-        android:layout_toRightOf="@id/icon"
-        android:layout_alignParentBottom="true"
-        android:layout_alignParentRight="true"
-
-        android:textAppearance="?android:attr/textAppearanceSmall"
+        android:layout_gravity="center"
+        android:layout_marginRight="16dip"
         />
 
-
-    <TextView android:id="@+id/message"
+    <LinearLayout
+        android:orientation="vertical"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
+        android:layout_gravity="center_vertical"
+        >
+        <TextView android:id="@+id/message"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_gravity="top"
 
-        android:layout_toRightOf="@id/icon"
-        android:layout_alignParentRight="true"
-        android:layout_alignParentTop="true"
-        android:layout_above="@id/status"
-        android:layout_alignWithParentIfMissing="true"
-        android:gravity="center_vertical"
-        android:textAppearance="?android:attr/textAppearanceLarge"
-        />
+            android:gravity="center_vertical"
+            android:textAppearance="?android:attr/textAppearanceLarge"
+            />
+        <TextView android:id="@+id/status"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_gravity="bottom"
+            android:minHeight="26dp"
 
-
-</RelativeLayout>
+            android:textAppearance="?android:attr/textAppearanceSmall"
+            />
+    </LinearLayout>
+</LinearLayout>
\ No newline at end of file
diff --git a/core/res/res/layout/global_actions_silent_mode.xml b/core/res/res/layout/global_actions_silent_mode.xml
new file mode 100644
index 0000000..18b4715
--- /dev/null
+++ b/core/res/res/layout/global_actions_silent_mode.xml
@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:minHeight="?android:attr/listPreferredItemHeight"
+    android:orientation="horizontal"
+    >
+
+    <LinearLayout
+        android:id="@+id/option1"
+        android:layout_width="64dp"
+        android:layout_height="match_parent"
+        android:background="?android:attr/actionBarItemBackground"
+        android:contentDescription="@string/silent_mode_silent"
+        android:focusable="true"
+        >
+        <ImageView
+            android:layout_width="48dp"
+            android:layout_height="match_parent"
+            android:layout_gravity="center"
+            android:layout_marginLeft="8dp"
+            android:layout_marginRight="8dp"
+            android:layout_marginTop="6dp"
+            android:layout_marginBottom="6dp"
+            android:src="@drawable/ic_audio_vol_mute"
+            android:scaleType="center"
+            android:duplicateParentState="true"
+            android:background="@drawable/silent_mode_indicator"
+            />
+    </LinearLayout>
+    <!-- Spacer -->
+    <View android:layout_width="0dp"
+        android:layout_height="match_parent"
+        android:layout_weight="1"
+        android:visibility="invisible"/>
+
+    <LinearLayout
+        android:id="@+id/option2"
+        android:layout_width="64dp"
+        android:layout_height="match_parent"
+        android:background="?android:attr/actionBarItemBackground"
+        android:contentDescription="@string/silent_mode_vibrate"
+        android:focusable="true"
+        >
+        <ImageView
+            android:layout_width="48dp"
+            android:layout_height="match_parent"
+            android:layout_gravity="center"
+            android:layout_marginLeft="8dp"
+            android:layout_marginRight="8dp"
+            android:layout_marginTop="6dp"
+            android:layout_marginBottom="6dp"
+            android:src="@drawable/ic_audio_ring_notif_vibrate"
+            android:scaleType="center"
+            android:duplicateParentState="true"
+            android:background="@drawable/silent_mode_indicator"
+            />
+    </LinearLayout>
+
+    <!-- Spacer -->
+    <View android:layout_width="0dp"
+        android:layout_height="match_parent"
+        android:layout_weight="1"
+        android:visibility="invisible"/>
+
+    <LinearLayout
+        android:id="@+id/option3"
+        android:layout_width="64dp"
+        android:layout_height="match_parent"
+        android:background="?android:attr/actionBarItemBackground"
+        android:contentDescription="@string/silent_mode_ring"
+        android:focusable="true"
+        >
+        <ImageView
+            android:layout_width="48dp"
+            android:layout_height="match_parent"
+            android:layout_gravity="center"
+            android:layout_marginLeft="8dp"
+            android:layout_marginRight="8dp"
+            android:layout_marginTop="6dp"
+            android:layout_marginBottom="6dp"
+            android:src="@drawable/ic_audio_vol"
+            android:scaleType="center"
+            android:duplicateParentState="true"
+            android:background="@drawable/silent_mode_indicator"
+            />
+    </LinearLayout>
+</LinearLayout>
\ No newline at end of file
diff --git a/core/res/res/layout/keyguard_screen_password_landscape.xml b/core/res/res/layout/keyguard_screen_password_landscape.xml
index ba0c22f..e95553f 100644
--- a/core/res/res/layout/keyguard_screen_password_landscape.xml
+++ b/core/res/res/layout/keyguard_screen_password_landscape.xml
@@ -193,6 +193,7 @@
         android:keyBackground="@*android:drawable/btn_keyboard_key_ics"
         android:visibility="gone"
         android:layout_rowSpan="7"
+        android:clickable="true"
     />
 
     <!-- Music transport control -->
diff --git a/core/res/res/layout/keyguard_screen_password_portrait.xml b/core/res/res/layout/keyguard_screen_password_portrait.xml
index f6933c3..053acb2 100644
--- a/core/res/res/layout/keyguard_screen_password_portrait.xml
+++ b/core/res/res/layout/keyguard_screen_password_portrait.xml
@@ -157,6 +157,7 @@
         android:background="#40000000"
         android:keyBackground="@*android:drawable/btn_keyboard_key_ics"
         android:visibility="gone"
+        android:clickable="true"
     />
 
     <TextView
diff --git a/core/res/res/layout/wifi_p2p_dialog.xml b/core/res/res/layout/wifi_p2p_dialog.xml
new file mode 100644
index 0000000..8234187
--- /dev/null
+++ b/core/res/res/layout/wifi_p2p_dialog.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content">
+
+    <LinearLayout
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:orientation="vertical">
+
+        <LinearLayout android:id="@+id/info"
+            style="@style/wifi_section" />
+
+        <LinearLayout android:id="@+id/enter_pin_section"
+            style="@style/wifi_section"
+            android:visibility="gone">
+
+            <LinearLayout
+                style="@style/wifi_item">
+                <TextView
+                    android:text="@string/wifi_p2p_enter_pin_message"
+                    style="@style/wifi_item_label" />
+
+                <EditText android:id="@+id/wifi_p2p_wps_pin"
+                    android:inputType="textNoSuggestions"
+                    style="@style/wifi_item_content" />
+            </LinearLayout>
+        </LinearLayout>
+    </LinearLayout>
+
+</ScrollView>
diff --git a/core/res/res/layout/wifi_p2p_go_negotiation_request_alert.xml b/core/res/res/layout/wifi_p2p_dialog_row.xml
similarity index 68%
rename from core/res/res/layout/wifi_p2p_go_negotiation_request_alert.xml
rename to core/res/res/layout/wifi_p2p_dialog_row.xml
index 41ca657..ef810a0 100644
--- a/core/res/res/layout/wifi_p2p_go_negotiation_request_alert.xml
+++ b/core/res/res/layout/wifi_p2p_dialog_row.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 The Android Open Source Project
+<!-- Copyright (C) 2010 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.
@@ -15,12 +15,13 @@
 -->
 
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="wrap_content"
-    android:layout_height="wrap_content">
+    style="@style/wifi_item">
+    <TextView
+            style="@style/wifi_item_label"
+            android:id="@+id/name" />
 
-    <EditText android:id="@+id/wifi_p2p_wps_pin"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:inputType="textPassword"
-    />
+    <TextView
+            android:id="@+id/value"
+            style="@style/wifi_item_content"
+            android:textStyle="bold" />
 </LinearLayout>
diff --git a/core/res/res/values-af/donottranslate-cldr.xml b/core/res/res/values-af/donottranslate-cldr.xml
new file mode 100644
index 0000000..9d38717
--- /dev/null
+++ b/core/res/res/values-af/donottranslate-cldr.xml
@@ -0,0 +1,146 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="month_long_standalone_january">Januarie</string>
+    <string name="month_long_standalone_february">Februarie</string>
+    <string name="month_long_standalone_march">Maart</string>
+    <string name="month_long_standalone_april">April</string>
+    <string name="month_long_standalone_may">Mei</string>
+    <string name="month_long_standalone_june">Junie</string>
+    <string name="month_long_standalone_july">Julie</string>
+    <string name="month_long_standalone_august">Augustus</string>
+    <string name="month_long_standalone_september">September</string>
+    <string name="month_long_standalone_october">Oktober</string>
+    <string name="month_long_standalone_november">November</string>
+    <string name="month_long_standalone_december">Desember</string>
+
+    <string name="month_long_january">Januarie</string>
+    <string name="month_long_february">Februarie</string>
+    <string name="month_long_march">Maart</string>
+    <string name="month_long_april">April</string>
+    <string name="month_long_may">Mei</string>
+    <string name="month_long_june">Junie</string>
+    <string name="month_long_july">Julie</string>
+    <string name="month_long_august">Augustus</string>
+    <string name="month_long_september">September</string>
+    <string name="month_long_october">Oktober</string>
+    <string name="month_long_november">November</string>
+    <string name="month_long_december">Desember</string>
+
+    <string name="month_medium_january">Jan</string>
+    <string name="month_medium_february">Feb</string>
+    <string name="month_medium_march">Mar</string>
+    <string name="month_medium_april">Apr</string>
+    <string name="month_medium_may">Mei</string>
+    <string name="month_medium_june">Jun</string>
+    <string name="month_medium_july">Jul</string>
+    <string name="month_medium_august">Aug</string>
+    <string name="month_medium_september">Sep</string>
+    <string name="month_medium_october">Okt</string>
+    <string name="month_medium_november">Nov</string>
+    <string name="month_medium_december">Des</string>
+
+    <string name="month_shortest_january">1</string>
+    <string name="month_shortest_february">2</string>
+    <string name="month_shortest_march">3</string>
+    <string name="month_shortest_april">4</string>
+    <string name="month_shortest_may">5</string>
+    <string name="month_shortest_june">6</string>
+    <string name="month_shortest_july">7</string>
+    <string name="month_shortest_august">8</string>
+    <string name="month_shortest_september">9</string>
+    <string name="month_shortest_october">10</string>
+    <string name="month_shortest_november">11</string>
+    <string name="month_shortest_december">12</string>
+
+    <string name="day_of_week_long_sunday">Sondag</string>
+    <string name="day_of_week_long_monday">Maandag</string>
+    <string name="day_of_week_long_tuesday">Dinsdag</string>
+    <string name="day_of_week_long_wednesday">Woensdag</string>
+    <string name="day_of_week_long_thursday">Donderdag</string>
+    <string name="day_of_week_long_friday">Vrydag</string>
+    <string name="day_of_week_long_saturday">Saterdag</string>
+
+    <string name="day_of_week_medium_sunday">So</string>
+    <string name="day_of_week_medium_monday">Ma</string>
+    <string name="day_of_week_medium_tuesday">Di</string>
+    <string name="day_of_week_medium_wednesday">Wo</string>
+    <string name="day_of_week_medium_thursday">Do</string>
+    <string name="day_of_week_medium_friday">Vr</string>
+    <string name="day_of_week_medium_saturday">Sa</string>
+
+    <string name="day_of_week_short_sunday">So</string>
+    <string name="day_of_week_short_monday">Ma</string>
+    <string name="day_of_week_short_tuesday">Di</string>
+    <string name="day_of_week_short_wednesday">Wo</string>
+    <string name="day_of_week_short_thursday">Do</string>
+    <string name="day_of_week_short_friday">Vr</string>
+    <string name="day_of_week_short_saturday">Sa</string>
+
+    <string name="day_of_week_shortest_sunday">1</string>
+    <string name="day_of_week_shortest_monday">2</string>
+    <string name="day_of_week_shortest_tuesday">3</string>
+    <string name="day_of_week_shortest_wednesday">4</string>
+    <string name="day_of_week_shortest_thursday">5</string>
+    <string name="day_of_week_shortest_friday">6</string>
+    <string name="day_of_week_shortest_saturday">7</string>
+
+    <string name="am">vm.</string>
+    <string name="pm">nm.</string>
+
+    <string name="hour_minute_24">%-k:%M</string>
+    <string name="hour_minute_ampm">%-l:%M %p</string>
+    <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
+    <string name="twelve_hour_time_format">h:mm a</string>
+    <string name="twenty_four_hour_time_format">H:mm</string>
+    <string name="numeric_date">%Y/%m/%d</string>
+    <string name="numeric_date_format">yyyy/MM/dd</string>
+    <string name="numeric_date_template">"%s/%s/%s"</string>
+    <string name="month_day_year">%d %B %Y</string>
+    <string name="time_of_day">%-l:%M:%S %p</string>
+    <string name="date_and_time">%-l:%M:%S %p %d %b %Y</string>
+    <string name="date_time">%2$s %1$s</string>
+    <string name="time_date">%1$s %3$s</string>
+    <string name="abbrev_month_day_year">%d %b %Y</string>
+    <string name="month_day">%-e %B</string>
+    <string name="month">%-B</string>
+    <string name="month_year">%B %Y</string>
+    <string name="abbrev_month_day">%b %-e</string>
+    <string name="abbrev_month">%b</string>
+    <string name="abbrev_month_year">%Y %b</string>
+    <string name="time1_time2">%1$s - %2$s</string>
+    <string name="date1_date2">%2$s - %5$s</string>
+    <string name="numeric_md1_md2">%2$s-%3$s - %7$s-%8$s</string>
+    <string name="numeric_wday1_md1_wday2_md2">%1$s, %2$s-%3$s - %6$s, %7$s-%8$s</string>
+    <string name="numeric_mdy1_mdy2">%4$s-%2$s-%3$s - %9$s-%7$s-%8$s</string>
+    <string name="numeric_wday1_mdy1_wday2_mdy2">%1$s, %4$s-%2$s-%3$s - %6$s, %9$s-%7$s-%8$s</string>
+    <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %4$s-%2$s-%3$s - %10$s %6$s, %9$s-%7$s-%8$s</string>
+    <string name="numeric_md1_time1_md2_time2">%5$s %2$s-%3$s - %10$s %7$s-%8$s</string>
+    <string name="numeric_wday1_md1_time1_wday2_md2_time2">%5$s %1$s, %2$s-%3$s - %10$s %6$s, %7$s-%8$s</string>
+    <string name="numeric_mdy1_time1_mdy2_time2">%5$s %4$s/%2$s/%3$s - %10$s %9$s/%7$s/%8$s</string>
+    <string name="wday1_date1_time1_wday2_date2_time2">%3$s %1$s, %2$s - %6$s %4$s, %5$s</string>
+    <string name="wday1_date1_wday2_date2">%1$s, %2$s - %4$s, %5$s</string>
+    <string name="date1_time1_date2_time2">%3$s %2$s - %6$s %5$s</string>
+    <string name="time_wday_date">%1$s %2$s, %3$s</string>
+    <string name="wday_date">%2$s, %3$s</string>
+    <string name="time_wday">%1$s %2$s</string>
+    <string name="same_year_md1_md2">%3$s %2$s - %8$s %7$s</string>
+    <string name="same_year_wday1_md1_wday2_md2">%1$s %2$s %3$s - %6$s %7$s %8$s</string>
+    <string name="same_year_md1_time1_md2_time2">%5$s %3$s %2$s - %10$s %8$s %7$s</string>
+    <string name="same_month_md1_time1_md2_time2">%5$s %3$s %2$s - %10$s %8$s %7$s</string>
+    <string name="same_year_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %2$s %3$s - %10$s %6$s %7$s %8$s</string>
+    <string name="same_month_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %2$s %3$s - %10$s %6$s %7$s %8$s</string>
+    <string name="same_year_mdy1_time1_mdy2_time2">%5$s %4$s %2$s %3$s - %10$s %9$s %7$s %8$s</string>
+    <string name="same_month_mdy1_time1_mdy2_time2">%5$s %4$s %2$s %3$s - %10$s %9$s %7$s %8$s</string>
+    <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %4$s %2$s %3$s - %10$s %6$s, %9$s %7$s %8$s</string>
+    <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %4$s %2$s %3$s - %10$s %6$s, %9$s %7$s %8$s</string>
+    <string name="same_month_wday1_mdy1_wday2_mdy2">%1$s, %4$s %2$s %3$s - %6$s, %9$s %7$s %8$s</string>
+    <string name="same_month_md1_md2">%2$s %3$s-%8$s</string>
+    <string name="same_month_wday1_md1_wday2_md2">%1$s %2$s %3$s - %6$s %7$s %8$s</string>
+    <string name="same_year_mdy1_mdy2">%9$s %2$s %3$s - %7$s %8$s</string>
+    <string name="same_month_mdy1_mdy2">%9$s %2$s %3$s-%8$s</string>
+    <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s, %9$s %2$s %3$s - %6$s, y %7$s %8$s</string>
+    <string name="short_format_month">%b</string>
+    <string name="full_wday_month_day_no_year">E MMMM d</string>
+    <string name="abbrev_wday_month_day_year">E, y MMM dd</string>
+</resources>
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index d57e223..5942633 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -301,6 +301,8 @@
     <string name="permlab_readLogs" msgid="6615778543198967614">"lees sensitiewe logdata"</string>
     <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"Laat die program toe om uit die stelsel se verskeie loglêers te lees. Dit laat \'n program toe om algemene inligting te ontdek oor wat jy met die tablet doen, wat moontlik persoonlike of private inligting kan insluit."</string>
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Laat die program toe om uit die stelsel se verskeie loglêers te lees. Dit laat \'n program toe om algemene inligting te ontdek oor wat jy met die foon doen, wat moontlik persoonlike of private inligting kan insluit."</string>
+    <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"gebruik enige mediadekodeerder vir terugspeel"</string>
+    <string name="permdesc_anyCodecForPlayback" msgid="2101444559995480174">"Hiermee kan \'n program enige geïnstalleerde mediadekodeerder gebruik om te dekodeer vir terugspeel."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"lees/skryf na bronne wat diag besit"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Laat die program toe om na enige hulpbron wat deur die diag-groep besit word, te skryf, byvoorbeeld lêers in /dev. Dit kan potensieel stelselstabiliteit en sekuriteit affekteer. Dit moet NET gebruik word vir hardewarespesifieke diagnose deur die vervaardiger of operateur."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"aktiveer of deaktiveer programkomponente"</string>
@@ -465,9 +467,9 @@
     <string name="permlab_bluetoothAdmin" msgid="3606576270792236062">"Bluetooth-administrasie"</string>
     <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"Laat die program toe om die plaaslike Bluetooth-tablet op te stel, en om met afstandbeheer toestelle saam te bind."</string>
     <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"Laat die program toe om die plaaslike Bluetooth-foon op te stel en te ontdek en met afgeleë toestelle saam te bind."</string>
-    <!-- outdated translation 2800410363171809280 -->     <string name="permlab_accessWimaxState" msgid="1232061307208861588">"sien WiMAX-status"</string>
+    <string name="permlab_accessWimaxState" msgid="1232061307208861588">"Sien WiMAX-status"</string>
     <string name="permdesc_accessWimaxState" msgid="8298035866227524023">"Laat \'n program toe om die inligting oor die status van WiMAX te sien."</string>
-    <!-- outdated translation 340465839241528618 -->     <string name="permlab_changeWimaxState" msgid="2405042267131496579">"verander WiMAX-status"</string>
+    <string name="permlab_changeWimaxState" msgid="2405042267131496579">"Verander WiMAX-status"</string>
     <string name="permdesc_changeWimaxState" msgid="474918005058989421">"Laat \'n program toe om aan die WiMAX-netwerk te koppel en te ontkoppel."</string>
     <string name="permlab_bluetooth" msgid="8361038707857018732">"skep Bluetooth-verbindings"</string>
     <string name="permdesc_bluetooth" product="tablet" msgid="7007851048416363446">"Laat die program toe om die opstelling van die plaaslike Bluetooth-tablet te sien, en om verbindings met saamgebinde toestelle te maak en te aanvaar."</string>
@@ -492,7 +494,7 @@
     <string name="permdesc_writeDictionary" msgid="8185385716255065291">"Laat die program toe om nuwe woorde in die gebruikerwoordeboek te skryf."</string>
     <string name="permlab_sdcardWrite" product="nosdcard" msgid="85430876310764752">"verander/vee uit USB-berging se inhoud"</string>
     <string name="permlab_sdcardWrite" product="default" msgid="8079403759001777291">"wysig/vee uit SD-kaart se inhoud"</string>
-    <string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"Laat die program toe om die USB-geheue te skryf."</string>
+    <string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"Laat die program toe om die USB-berging te skryf."</string>
     <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Laat die program toe om na die SD-kaart te skryf."</string>
     <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"verander/vee uit interne mediabergingsinhoud"</string>
     <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Laat die program toe om die inhoud van die interne mediaberging te verander."</string>
@@ -632,7 +634,7 @@
     <string name="relationTypeParent" msgid="4755635567562925226">"Ouer"</string>
     <string name="relationTypePartner" msgid="7266490285120262781">"Vennoot"</string>
     <string name="relationTypeReferredBy" msgid="101573059844135524">"Verwys deur"</string>
-    <string name="relationTypeRelative" msgid="1799819930085610271">"Relatief"</string>
+    <string name="relationTypeRelative" msgid="1799819930085610271">"Familielid"</string>
     <string name="relationTypeSister" msgid="1735983554479076481">"Suster"</string>
     <string name="relationTypeSpouse" msgid="394136939428698117">"Eggenoot"</string>
     <string name="sipAddressTypeCustom" msgid="2473580593111590945">"Gepasmaakte"</string>
@@ -998,15 +1000,15 @@
     <string name="usb_storage_error_message" product="default" msgid="120810397713773275">"Kon nie jou SD-kaart vir USB-massaberging gebruik nie."</string>
     <string name="usb_storage_notification_title" msgid="8175892554757216525">"USB gekoppel"</string>
     <string name="usb_storage_notification_message" msgid="7380082404288219341">"Kies om lêers na/van jou rekenaar te kopieer."</string>
-    <string name="usb_storage_stop_notification_title" msgid="2336058396663516017">"Skakel USB-geheue af"</string>
-    <string name="usb_storage_stop_notification_message" msgid="2591813490269841539">"Kies om USB-geheue af te skakel."</string>
+    <string name="usb_storage_stop_notification_title" msgid="2336058396663516017">"Skakel USB-berging af"</string>
+    <string name="usb_storage_stop_notification_message" msgid="2591813490269841539">"Kies om USB-berging af te skakel."</string>
     <string name="usb_storage_stop_title" msgid="660129851708775853">"USB-berging in gebruik"</string>
     <string name="usb_storage_stop_message" product="nosdcard" msgid="1368842269463745067">"Voordat jy USB-berging afskakel, maak seker dat jy jou Android se USB-berging van jou rekenaar ontheg (\"uitgestoot\") het."</string>
     <string name="usb_storage_stop_message" product="default" msgid="3613713396426604104">"Voordat jy die USB-berging afskakel, maak seker dat jy jou Android se SD-kaart uit die rekenaar ontheg (uitgeskiet) het."</string>
     <string name="usb_storage_stop_button_mount" msgid="7060218034900696029">"Skakel USB-berging af"</string>
     <string name="usb_storage_stop_error_message" msgid="143881914840412108">"Kon nie USB-berging afskakel nie. Kontroleer of jy die USB-gasheer ontheg het, en probeer dan weer."</string>
     <string name="dlg_confirm_kill_storage_users_title" msgid="963039033470478697">"Skakel USB-berging aan"</string>
-    <string name="dlg_confirm_kill_storage_users_text" msgid="6206212680430268343">"As jy die USB-geheue aanskakel, sal sekere programme wat jy gebruik, stop en onbeskikbaar wees totdat jy die USB-geheue afskakel."</string>
+    <string name="dlg_confirm_kill_storage_users_text" msgid="6206212680430268343">"As jy die USB-berging aanskakel, sal sekere programme wat jy gebruik, stop en onbeskikbaar wees totdat jy die USB-berging afskakel."</string>
     <string name="dlg_error_title" msgid="7323658469626514207">"USB-handeling was onsuksesvol"</string>
     <string name="dlg_ok" msgid="7376953167039865701">"OK"</string>
     <string name="usb_mtp_notification_title" msgid="3699913097391550394">"Gekoppel as \'n mediatoestel"</string>
@@ -1014,9 +1016,9 @@
     <string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Gekoppel as \'n installeerder"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Gekoppel aan \'n USB-toebehoorsel"</string>
     <string name="usb_notification_message" msgid="4447869605109736382">"Raak vir ander USB-opsies"</string>
-    <string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"Formateer USB-geheue?"</string>
+    <string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"Formateer USB-berging?"</string>
     <string name="extmedia_format_title" product="default" msgid="3648415921526526069">"Formateer SD-kaart?"</string>
-    <string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"Alle lêers wat op jou  USB-geheue gestoor is, sal uitgevee word. Hierdie handeling kan nie omgekeer word nie!"</string>
+    <string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"Alle lêers wat op jou  USB-berging gestoor is, sal uitgevee word. Hierdie handeling kan nie omgekeer word nie!"</string>
     <string name="extmedia_format_message" product="default" msgid="14131895027543830">"Alle data op jou kaart sal verlore gaan."</string>
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"Formaat"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-ontfouter gekoppel"</string>
@@ -1219,4 +1221,7 @@
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"Deel met"</string>
     <string name="status_bar_device_locked" msgid="3092703448690669768">"Toestel gesluit."</string>
     <string name="list_delimeter" msgid="3975117572185494152">", "</string>
+    <string name="sending" msgid="8715108995741758718">"Stuur tans..."</string>
+    <string name="launchBrowserDefault" msgid="2057951947297614725">"Begin webblaaier?"</string>
+    <string name="SetupCallDefault" msgid="6870275517518479651">"Aanvaar oproep?"</string>
 </resources>
diff --git a/core/res/res/values-am/donottranslate-cldr.xml b/core/res/res/values-am/donottranslate-cldr.xml
new file mode 100644
index 0000000..2319fbf
--- /dev/null
+++ b/core/res/res/values-am/donottranslate-cldr.xml
@@ -0,0 +1,146 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="month_long_standalone_january">ጃንዩወሪ</string>
+    <string name="month_long_standalone_february">ፌብሩወሪ</string>
+    <string name="month_long_standalone_march">ማርች</string>
+    <string name="month_long_standalone_april">ኤፕረል</string>
+    <string name="month_long_standalone_may">ሜይ</string>
+    <string name="month_long_standalone_june">ጁን</string>
+    <string name="month_long_standalone_july">ጁላይ</string>
+    <string name="month_long_standalone_august">ኦገስት</string>
+    <string name="month_long_standalone_september">ሴፕቴምበር</string>
+    <string name="month_long_standalone_october">ኦክተውበር</string>
+    <string name="month_long_standalone_november">ኖቬምበር</string>
+    <string name="month_long_standalone_december">ዲሴምበር</string>
+
+    <string name="month_long_january">ጃንዩወሪ</string>
+    <string name="month_long_february">ፌብሩወሪ</string>
+    <string name="month_long_march">ማርች</string>
+    <string name="month_long_april">ኤፕረል</string>
+    <string name="month_long_may">ሜይ</string>
+    <string name="month_long_june">ጁን</string>
+    <string name="month_long_july">ጁላይ</string>
+    <string name="month_long_august">ኦገስት</string>
+    <string name="month_long_september">ሴፕቴምበር</string>
+    <string name="month_long_october">ኦክተውበር</string>
+    <string name="month_long_november">ኖቬምበር</string>
+    <string name="month_long_december">ዲሴምበር</string>
+
+    <string name="month_medium_january">ጃንዩ</string>
+    <string name="month_medium_february">ፌብሩ</string>
+    <string name="month_medium_march">ማርች</string>
+    <string name="month_medium_april">ኤፕረ</string>
+    <string name="month_medium_may">ሜይ</string>
+    <string name="month_medium_june">ጁን</string>
+    <string name="month_medium_july">ጁላይ</string>
+    <string name="month_medium_august">ኦገስ</string>
+    <string name="month_medium_september">ሴፕቴ</string>
+    <string name="month_medium_october">ኦክተ</string>
+    <string name="month_medium_november">ኖቬም</string>
+    <string name="month_medium_december">ዲሴም</string>
+
+    <string name="month_shortest_january">ጃ</string>
+    <string name="month_shortest_february">ፌ</string>
+    <string name="month_shortest_march">ማ</string>
+    <string name="month_shortest_april">ኤ</string>
+    <string name="month_shortest_may">ሜ</string>
+    <string name="month_shortest_june">ጁ</string>
+    <string name="month_shortest_july">ጁ</string>
+    <string name="month_shortest_august">ኦ</string>
+    <string name="month_shortest_september">ሴ</string>
+    <string name="month_shortest_october">ኦ</string>
+    <string name="month_shortest_november">ኖ</string>
+    <string name="month_shortest_december">ዲ</string>
+
+    <string name="day_of_week_long_sunday">እሑድ</string>
+    <string name="day_of_week_long_monday">ሰኞ</string>
+    <string name="day_of_week_long_tuesday">ማክሰኞ</string>
+    <string name="day_of_week_long_wednesday">ረቡዕ</string>
+    <string name="day_of_week_long_thursday">ሐሙስ</string>
+    <string name="day_of_week_long_friday">ዓርብ</string>
+    <string name="day_of_week_long_saturday">ቅዳሜ</string>
+
+    <string name="day_of_week_medium_sunday">እሑድ</string>
+    <string name="day_of_week_medium_monday">ሰኞ</string>
+    <string name="day_of_week_medium_tuesday">ማክሰ</string>
+    <string name="day_of_week_medium_wednesday">ረቡዕ</string>
+    <string name="day_of_week_medium_thursday">ሐሙስ</string>
+    <string name="day_of_week_medium_friday">ዓርብ</string>
+    <string name="day_of_week_medium_saturday">ቅዳሜ</string>
+
+    <string name="day_of_week_short_sunday">እሑድ</string>
+    <string name="day_of_week_short_monday">ሰኞ</string>
+    <string name="day_of_week_short_tuesday">ማክሰ</string>
+    <string name="day_of_week_short_wednesday">ረቡዕ</string>
+    <string name="day_of_week_short_thursday">ሐሙስ</string>
+    <string name="day_of_week_short_friday">ዓርብ</string>
+    <string name="day_of_week_short_saturday">ቅዳሜ</string>
+
+    <string name="day_of_week_shortest_sunday">እ</string>
+    <string name="day_of_week_shortest_monday">ሰ</string>
+    <string name="day_of_week_shortest_tuesday">ማ</string>
+    <string name="day_of_week_shortest_wednesday">ረ</string>
+    <string name="day_of_week_shortest_thursday">ሐ</string>
+    <string name="day_of_week_shortest_friday">ዓ</string>
+    <string name="day_of_week_shortest_saturday">ቅ</string>
+
+    <string name="am">ጡዋት</string>
+    <string name="pm">ከሳዓት</string>
+
+    <string name="hour_minute_24">%-k:%M</string>
+    <string name="hour_minute_ampm">%-l:%M %p</string>
+    <string name="hour_minute_cap_ampm">%-l:%M %p</string>
+    <string name="twelve_hour_time_format">h:mm a</string>
+    <string name="twenty_four_hour_time_format">H:mm</string>
+    <string name="numeric_date">%d/%m/%Y</string>
+    <string name="numeric_date_format">dd/MM/yyyy</string>
+    <string name="numeric_date_template">"%s/%s/%s"</string>
+    <string name="month_day_year">%d %B %Y</string>
+    <string name="time_of_day">%-l:%M:%S %p</string>
+    <string name="date_and_time">%-l:%M:%S %p %b %-e %Y</string>
+    <string name="date_time">%2$s %1$s</string>
+    <string name="time_date">%1$s %3$s</string>
+    <string name="abbrev_month_day_year">%b %-e %Y</string>
+    <string name="month_day">%B %-e</string>
+    <string name="month">%-B</string>
+    <string name="month_year">%B %Y</string>
+    <string name="abbrev_month_day">%b %-e</string>
+    <string name="abbrev_month">%b</string>
+    <string name="abbrev_month_year">%Y %b</string>
+    <string name="time1_time2">%1$s - %2$s</string>
+    <string name="date1_date2">%2$s - %5$s</string>
+    <string name="numeric_md1_md2">%2$s-%3$s - %7$s-%8$s</string>
+    <string name="numeric_wday1_md1_wday2_md2">%1$s, %2$s-%3$s - %6$s, %7$s-%8$s</string>
+    <string name="numeric_mdy1_mdy2">%4$s-%2$s-%3$s - %9$s-%7$s-%8$s</string>
+    <string name="numeric_wday1_mdy1_wday2_mdy2">%1$s, %4$s-%2$s-%3$s - %6$s, %9$s-%7$s-%8$s</string>
+    <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %4$s-%2$s-%3$s - %10$s %6$s, %9$s-%7$s-%8$s</string>
+    <string name="numeric_md1_time1_md2_time2">%5$s %2$s-%3$s - %10$s %7$s-%8$s</string>
+    <string name="numeric_wday1_md1_time1_wday2_md2_time2">%5$s %1$s, %2$s-%3$s - %10$s %6$s, %7$s-%8$s</string>
+    <string name="numeric_mdy1_time1_mdy2_time2">%5$s %3$s/%2$s/%4$s - %10$s %8$s/%7$s/%9$s</string>
+    <string name="wday1_date1_time1_wday2_date2_time2">%3$s %1$s, %2$s - %6$s %4$s, %5$s</string>
+    <string name="wday1_date1_wday2_date2">%1$s, %2$s - %4$s, %5$s</string>
+    <string name="date1_time1_date2_time2">%3$s %2$s - %6$s %5$s</string>
+    <string name="time_wday_date">%1$s %2$s, %3$s</string>
+    <string name="wday_date">%2$s, %3$s</string>
+    <string name="time_wday">%1$s %2$s</string>
+    <string name="same_year_md1_md2">%2$s %3$s - %7$s %8$s</string>
+    <string name="same_year_wday1_md1_wday2_md2">%1$s %2$s %3$s - %6$s %7$s %8$s</string>
+    <string name="same_year_md1_time1_md2_time2">%5$s %2$s %3$s - %10$s %7$s %8$s</string>
+    <string name="same_month_md1_time1_md2_time2">%5$s %2$s %3$s - %10$s %7$s %8$s</string>
+    <string name="same_year_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %2$s %3$s - %10$s %6$s %7$s %8$s</string>
+    <string name="same_month_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %2$s %3$s - %10$s %6$s %7$s %8$s</string>
+    <string name="same_year_mdy1_time1_mdy2_time2">%5$s %4$s %2$s %3$s - %10$s %9$s %7$s %8$s</string>
+    <string name="same_month_mdy1_time1_mdy2_time2">%5$s %4$s %2$s %3$s - %10$s %9$s %7$s %8$s</string>
+    <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %4$s %2$s %3$s - %10$s %6$s, %9$s %7$s %8$s</string>
+    <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %4$s %2$s %3$s - %10$s %6$s, %9$s %7$s %8$s</string>
+    <string name="same_month_wday1_mdy1_wday2_mdy2">%1$s, %4$s %2$s %3$s - %6$s, %9$s %7$s %8$s</string>
+    <string name="same_month_md1_md2">%2$s %3$s-%8$s</string>
+    <string name="same_month_wday1_md1_wday2_md2">%1$s %2$s %3$s - %6$s %7$s %8$s</string>
+    <string name="same_year_mdy1_mdy2">%9$s %2$s %3$s - %7$s %8$s</string>
+    <string name="same_month_mdy1_mdy2">%9$s %2$s %3$s-%8$s</string>
+    <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s, %9$s %2$s %3$s - %6$s, y %7$s %8$s</string>
+    <string name="short_format_month">%b</string>
+    <string name="full_wday_month_day_no_year">E MMMM d</string>
+    <string name="abbrev_wday_month_day_year">E, y MMM dd</string>
+</resources>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 7b0cad7..507d6fa 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -301,6 +301,8 @@
     <string name="permlab_readLogs" msgid="6615778543198967614">"ወሳኝ የማስታወሻ ውሂብ አንብብ"</string>
     <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">" ከስርዓቱ የተለያዩ የማስታወሻ ፋይሎች ውስጥ ለማንበብ ለመተግበሪያ ይፈቅዳሉ። ይህ ስለ ጡባዊ ተኮህ ምን እያደረክበት እንደሆነ የግላዊ  ወይም የግል መረጃን ጨምሮ ጠቅላላ መረጃ ለማግኘት ይፈቅዳል።"</string>
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">" ከስርዓቱ የተለያዩ የማስታወሻ ፋይሎች ውስጥ ለማንበብ ለመተግበሪያይፈቅዳሉ። ይህ ስለ ስልክህ ምን እያደረክበት እንደሆነ የግላዊ  ወይም የግል መረጃን ጨምሮ ጠቅላላ መረጃ ለማግኘት ይፈቅዳል።"</string>
+    <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"ለመልሰህ አጫውት ማንኛውምንም የማህደረ መረጃ ዲኮደር ተጠቀም"</string>
+    <string name="permdesc_anyCodecForPlayback" msgid="2101444559995480174">"ለመልሰህ አጫውት ፍታን በማንኛውም የተጫኑ በማህደረ መረጃ ዲኮደር ለመጠቀም  ለመተግበሪያ ይፈቅዳል፡፡"</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"በdiag ባለቤትነት ያሉ ንብረቶችን አንብብ/ፃፍ"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"በዲያግ ቡድን ባለቤትነት ወደ አለ ማንኛውም ንብረት ለምሳሌ በ/dev ያሉ ፋይሎች ለማንበብ እና ለመፃፍ ለመተግበሪያው ይፈቅዳሉ። ይህ በመሰረቱ የስርዓት መረጋጋትን እና ደህንነትን ሊጎዳ ይችላል። ይህ ውስን የሀርድዌር-ተኮር ዲያግኖስቲክስ በአምራቹ ወይም ከዋኙ ብቻ መሆን አለበት።"</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"የመተግበሪያ ምንዝሮችን አንቃ ወይም አቦዝን"</string>
@@ -465,9 +467,9 @@
     <string name="permlab_bluetoothAdmin" msgid="3606576270792236062">"የብሉቱዝ  አስተዳደር"</string>
     <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"የአካባቢውን ብሉቱዝ ጡባዊ ለማዋቀር እና አግኝቶ ከሩቅ መሣሪያዎች ጋር ለማጣመር ለመተግበሪያው ይፈቅዳሉ።"</string>
     <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"የአካባቢውን ብሉቱዝ ጡባዊ ለማዋቀር እና አግኝቶ ከሩቅ መሣሪያዎች ጋር ለማጣመር ለመተግበሪያው ይፈቅዳሉ።"</string>
-    <!-- outdated translation 2800410363171809280 -->     <string name="permlab_accessWimaxState" msgid="1232061307208861588">"የ WiMAX ሁኔታን ዕይ"</string>
+    <string name="permlab_accessWimaxState" msgid="1232061307208861588">"የ WiMAX ሁኔታን ዕይ"</string>
     <string name="permdesc_accessWimaxState" msgid="8298035866227524023">"ትግበራ ስለWi-Fi ሁኔታ መረጃን ለማየት ይፈቅዳል።"</string>
-    <!-- outdated translation 340465839241528618 -->     <string name="permlab_changeWimaxState" msgid="2405042267131496579">"የWiMAX ሁኔታ ለውጥ"</string>
+    <string name="permlab_changeWimaxState" msgid="2405042267131496579">"የWiMAX ሁኔታ ለውጥ"</string>
     <string name="permdesc_changeWimaxState" msgid="474918005058989421">"ትግበራ ከ WiMAX አውታረመረብ ለመያያዝ እና ለመለያየት ይፈቅዳል።"</string>
     <string name="permlab_bluetooth" msgid="8361038707857018732">"የብሉቱዝ ተያያዦችን ፍጠር"</string>
     <string name="permdesc_bluetooth" product="tablet" msgid="7007851048416363446">"የአካባቢውን ብሉቱዝ ጡባዊ ተኮ  ውቅር ለማየት፣ እና ከተጣመረው መሣሪያ ጋር ግንኙነት ለማድረግ እና ለመቀበል ለመተግበሪያው ይፈቅዳሉ።"</string>
@@ -1219,4 +1221,7 @@
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"ተጋራ ከ"</string>
     <string name="status_bar_device_locked" msgid="3092703448690669768">"መሣሪያ ተቆልፏል።"</string>
     <string name="list_delimeter" msgid="3975117572185494152">"፣ "</string>
+    <string name="sending" msgid="8715108995741758718">"በመላክ ላይ......."</string>
+    <string name="launchBrowserDefault" msgid="2057951947297614725">"ማሰሺያን አስነሳ?"</string>
+    <string name="SetupCallDefault" msgid="6870275517518479651">"ጥሪ ተቀበል?"</string>
 </resources>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index ec7a982..2ef6161 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -233,7 +233,7 @@
     <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"منع التبديل بين التطبيقات"</string>
     <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"لمنع المستخدم من التبديل إلى تطبيق آخر."</string>
     <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"مراقبة بدء تشغيل جميع التطبيقات والتحكم فيها"</string>
-    <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"للسماح للتطبيق بمراقبة كيفية بدء النظام للأنشطة والتحكم فيها. قد تُعرِّض التطبيقات الضارة النظام للضرر بشكل كامل. لن تكون هناك حاجة لهذا الإذن سوى للتطوير فقط، وليس للاستخدام العادي على الإطلاق."</string>
+    <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"للسماح للتطبيق بمراقبة كيفية بدء النظام للأنشطة والتحكم فيها. قد تُعرِّض التطبيقات الضارة النظام للضرر بشكل كامل. لن تكون هناك حاجة لهذا الإذن سوى للتطوير فقط، وليس للاستخدام العادي على الإطلاق."</string>
     <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"إرسال بث الحزمة الذي تمت إزالته"</string>
     <string name="permdesc_broadcastPackageRemoved" msgid="6621901216207931089">"للسماح للتطبيق ببث تنبيه يفيد بإزالة حزمة أحد التطبيقات. قد تستخدم التطبيقات الضارة هذا لإنهاء أية تطبيقات أخرى قيد التشغيل."</string>
     <string name="permlab_broadcastSmsReceived" msgid="5689095009030336593">"إرسال بث SMS مستلم"</string>
@@ -301,8 +301,10 @@
     <string name="permlab_readLogs" msgid="6615778543198967614">"قراءة بيانات السجل الحساسة"</string>
     <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"للسماح للتطبيق بالقراءة من ملفات سجلات النظام المتنوعة. ويسمح ذلك للتطبيق باكتشاف المعلومات العامة حول ما تفعله بالجهاز اللوحي، ومن المحتمل أن يتضمن معلومات شخصية أو خاصة."</string>
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"للسماح للتطبيق بالقراءة من ملفات سجلات النظام المتنوعة. ويسمح ذلك للتطبيق باكتشاف المعلومات العامة حول ما تفعله بالهاتف، ومن المحتمل أن يتضمن معلومات شخصية أو خاصة."</string>
+    <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"استخدام أي برنامج فك تشفير وسائط من أجل التشغيل"</string>
+    <string name="permdesc_anyCodecForPlayback" msgid="2101444559995480174">"السماح للتطبيق باستخدام أي برنامج فك تشفير وسائط مثبت لفك التشفير من أجل التشغيل."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"قراءة/كتابة إلى الموارد المملوكة بواسطة التشخيص"</string>
-    <string name="permdesc_diagnostic" msgid="6608295692002452283">"للسماح للتطبيق بالقراءة والكتابة إلى أي مورد مملوك بواسطة مجموعة التشخيصات؛ على سبيل المثال، الملفات في /dev. من المحتمل أن يؤثر ذلك في استقرار النظام وأمانه. يجب ألا يستخدم ذلك سوى للتشخيصات الخاصة بالنظام من قِبل المصنِّع أو المشغِّل."</string>
+    <string name="permdesc_diagnostic" msgid="6608295692002452283">"للسماح للتطبيق بالقراءة والكتابة إلى أي مورد مملوك بواسطة مجموعة التشخيصات؛ على سبيل المثال، الملفات في /dev. من المحتمل أن يؤثر ذلك في استقرار النظام وأمانه. يجب ألا يستخدم ذلك سوى للتشخيصات الخاصة بالنظام من قِبل المصنِّع أو المشغِّل."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"تمكين مكونات التطبيق أو تعطيلها"</string>
     <string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"للسماح للتطبيق بتغيير ما إذا كان سيتم تمكين مكون لتطبيق آخر أم لا. يمكن أن تستخدم التطبيقات الضارة ذلك لتعطيل قدرات الجهاز اللوحي المهمة. يجب توخي الحذر عند استخدام هذا الإذن، وذلك لأنه من الممكن أن يؤدي ذلك إلى جعل حالة مكونات التطبيق غير قابلة للاستخدام أو غير متناسقة أو غير مستقرة."</string>
     <string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"للسماح للتطبيق بتغيير ما إذا كان سيتم تمكين مكون لتطبيق آخر أم لا. يمكن أن تستخدم التطبيقات الضارة ذلك لتعطيل قدرات الهاتف المهمة. يجب توخي الحذر عند استخدام هذا الإذن، وذلك لأنه من الممكن أن يؤدي ذلك إلى جعل حالة مكونات التطبيق غير قابلة للاستخدام أو غير متناسقة أو غير مستقرة."</string>
@@ -419,8 +421,8 @@
     <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"للسماح للتطبيق بتشغيل الجهاز اللوحي أو إيقاف تشغيله."</string>
     <string name="permdesc_devicePower" product="default" msgid="6037057348463131032">"للسماح للتطبيق بتشغيل الهاتف أو إيقاف تشغيله."</string>
     <string name="permlab_factoryTest" msgid="3715225492696416187">"تشغيل في وضع اختبار المصنع"</string>
-    <string name="permdesc_factoryTest" product="tablet" msgid="3952059318359653091">"التشغيل كاختبار للشركة المصنعة من المستوى المنخفض، مما يسمح بإكمال الدخول إلى الجهاز اللوحي. ويتوفر فقط عندما يتم تشغيل الجهاز اللوحي في وضع اختبار المصنِّع."</string>
-    <string name="permdesc_factoryTest" product="default" msgid="8136644990319244802">"للتشغيل كاختبار مصنِّع بمستوى أدنى، مما يسمح بالدخول الكامل إلى جهاز الهاتف. لا يتوفر سوى عند تشغيل الهاتف في وضع اختبار المصنِّع."</string>
+    <string name="permdesc_factoryTest" product="tablet" msgid="3952059318359653091">"التشغيل كاختبار للشركة المصنعة من المستوى المنخفض، مما يسمح بإكمال الدخول إلى الجهاز اللوحي. ويتوفر فقط عندما يتم تشغيل الجهاز اللوحي في وضع اختبار المصنِّع."</string>
+    <string name="permdesc_factoryTest" product="default" msgid="8136644990319244802">"للتشغيل كاختبار مصنِّع بمستوى أدنى، مما يسمح بالدخول الكامل إلى جهاز الهاتف. لا يتوفر سوى عند تشغيل الهاتف في وضع اختبار المصنِّع."</string>
     <string name="permlab_setWallpaper" msgid="6627192333373465143">"تعيين الخلفية"</string>
     <string name="permdesc_setWallpaper" msgid="7373447920977624745">"للسماح للتطبيق بتعيين خلفية النظام."</string>
     <string name="permlab_setWallpaperHints" msgid="3600721069353106851">"تعيين تلميحات حجم الخلفية"</string>
@@ -434,12 +436,12 @@
     <string name="permdesc_setTimeZone" product="tablet" msgid="1676983712315827645">"للسماح للتطبيق بتغيير المنطقة الزمنية للجهاز اللوحي."</string>
     <string name="permdesc_setTimeZone" product="default" msgid="4499943488436633398">"للسماح للتطبيق بتغيير المنطقة الزمنية للهاتف."</string>
     <string name="permlab_accountManagerService" msgid="4829262349691386986">"العمل كخدمة مدير حساب"</string>
-    <string name="permdesc_accountManagerService" msgid="2684502137670299915">"للسماح لأحد التطبيقات بإجراء مكالمات إلى مصدِّقي الحساب."</string>
+    <string name="permdesc_accountManagerService" msgid="2684502137670299915">"للسماح لأحد التطبيقات بإجراء مكالمات إلى مصدِّقي الحساب."</string>
     <string name="permlab_getAccounts" msgid="4549918644233460103">"اكتشاف الحسابات المعروفة"</string>
     <string name="permdesc_getAccounts" product="tablet" msgid="3238360555257773358">"للسماح للتطبيق بالحصول على قائمة الحسابات المعروفة بواسطة الجهاز اللوحي."</string>
     <string name="permdesc_getAccounts" product="default" msgid="2735689364629830348">"للسماح للتطبيق بالحصول على قائمة الحسابات المعروفة بواسطة الهاتف."</string>
-    <string name="permlab_authenticateAccounts" msgid="3940505577982882450">"العمل كمصدِّق للحساب"</string>
-    <string name="permdesc_authenticateAccounts" msgid="5472124296908977260">"للسماح للتطبيق باستخدام إمكانيات مصدِّق الحساب لـ AccountManager، بما في ذلك إنشاء حسابات والحصول على كلمات مرورها وتعينها."</string>
+    <string name="permlab_authenticateAccounts" msgid="3940505577982882450">"العمل كمصدِّق للحساب"</string>
+    <string name="permdesc_authenticateAccounts" msgid="5472124296908977260">"للسماح للتطبيق باستخدام إمكانيات مصدِّق الحساب لـ AccountManager، بما في ذلك إنشاء حسابات والحصول على كلمات مرورها وتعينها."</string>
     <string name="permlab_manageAccounts" msgid="4440380488312204365">"إدارة قائمة الحسابات"</string>
     <string name="permdesc_manageAccounts" msgid="8698295625488292506">"للسماح للتطبيق بإجراء عمليات مثل إضافة حسابات وإزالتها وحذف كلمات مرورها."</string>
     <string name="permlab_useCredentials" msgid="6401886092818819856">"استخدام بيانات اعتماد المصادقة لأحد الحسابات"</string>
@@ -465,9 +467,9 @@
     <string name="permlab_bluetoothAdmin" msgid="3606576270792236062">"إدارة البلوتوث"</string>
     <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"للسماح للتطبيق بتهيئة لوحة البلوتوث المحلي، واكتشاف أجهزة التحكم عن بعد والاقتران بها."</string>
     <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"للسماح للتطبيق بتهيئة هاتف البلوتوث المحلي، واكتشاف أجهزة التحكم عن بعد والاقتران بها."</string>
-    <!-- outdated translation 2800410363171809280 -->     <string name="permlab_accessWimaxState" msgid="1232061307208861588">"عرض حالة WiMAX"</string>
+    <string name="permlab_accessWimaxState" msgid="1232061307208861588">"عرض حالة WiMAX"</string>
     <string name="permdesc_accessWimaxState" msgid="8298035866227524023">"للسماح لتطبيق ما بعرض معلومات حول حالة WiMAX."</string>
-    <!-- outdated translation 340465839241528618 -->     <string name="permlab_changeWimaxState" msgid="2405042267131496579">"تغيير حالة WiMAX"</string>
+    <string name="permlab_changeWimaxState" msgid="2405042267131496579">"تغيير حالة WiMAX"</string>
     <string name="permdesc_changeWimaxState" msgid="474918005058989421">"للسماح لتطبيق ما بالاتصال بشبكة WiMAX وقطع الاتصال بها."</string>
     <string name="permlab_bluetooth" msgid="8361038707857018732">"إنشاء اتصالات بلوتوث"</string>
     <string name="permdesc_bluetooth" product="tablet" msgid="7007851048416363446">"للسماح للتطبيق بعرض تهيئة جهاز البلوتوث اللوحي المحلي وإجراء اتصالات وقبولها مع الأجهزة المقترنة."</string>
@@ -1219,4 +1221,7 @@
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"مشاركة مع"</string>
     <string name="status_bar_device_locked" msgid="3092703448690669768">"تم تأمين الجهاز."</string>
     <string name="list_delimeter" msgid="3975117572185494152">"، "</string>
+    <string name="sending" msgid="8715108995741758718">"جارٍ الإرسال..."</string>
+    <string name="launchBrowserDefault" msgid="2057951947297614725">"تشغيل المتصفح؟"</string>
+    <string name="SetupCallDefault" msgid="6870275517518479651">"قبول المكالمة؟"</string>
 </resources>
diff --git a/core/res/res/values-be/donottranslate-cldr.xml b/core/res/res/values-be/donottranslate-cldr.xml
new file mode 100644
index 0000000..365e60d
--- /dev/null
+++ b/core/res/res/values-be/donottranslate-cldr.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="month_long_standalone_may">травень</string>
+
+    <string name="month_long_january">студзень</string>
+    <string name="month_long_february">люты</string>
+    <string name="month_long_march">сакавік</string>
+    <string name="month_long_april">красавік</string>
+    <string name="month_long_may">май</string>
+    <string name="month_long_june">чэрвень</string>
+    <string name="month_long_july">ліпень</string>
+    <string name="month_long_august">жнівень</string>
+    <string name="month_long_september">верасень</string>
+    <string name="month_long_october">кастрычнік</string>
+    <string name="month_long_november">лістапад</string>
+    <string name="month_long_december">снежань</string>
+
+    <string name="month_medium_january">сту</string>
+    <string name="month_medium_february">лют</string>
+    <string name="month_medium_march">сак</string>
+    <string name="month_medium_april">кра</string>
+    <string name="month_medium_may">май</string>
+    <string name="month_medium_june">чэр</string>
+    <string name="month_medium_july">ліп</string>
+    <string name="month_medium_august">жні</string>
+    <string name="month_medium_september">вер</string>
+    <string name="month_medium_october">кас</string>
+    <string name="month_medium_november">ліс</string>
+    <string name="month_medium_december">сне</string>
+
+    <string name="month_shortest_january">с</string>
+    <string name="month_shortest_february">л</string>
+    <string name="month_shortest_march">с</string>
+    <string name="month_shortest_april">к</string>
+    <string name="month_shortest_may">м</string>
+    <string name="month_shortest_june">ч</string>
+    <string name="month_shortest_july">л</string>
+    <string name="month_shortest_august">ж</string>
+    <string name="month_shortest_september">в</string>
+    <string name="month_shortest_october">к</string>
+    <string name="month_shortest_november">л</string>
+    <string name="month_shortest_december">с</string>
+
+    <string name="day_of_week_long_sunday">нядзеля</string>
+    <string name="day_of_week_long_monday">панядзелак</string>
+    <string name="day_of_week_long_tuesday">аўторак</string>
+    <string name="day_of_week_long_wednesday">серада</string>
+    <string name="day_of_week_long_thursday">чацвер</string>
+    <string name="day_of_week_long_friday">пятніца</string>
+    <string name="day_of_week_long_saturday">субота</string>
+
+    <string name="day_of_week_medium_sunday">нд</string>
+    <string name="day_of_week_medium_monday">пн</string>
+    <string name="day_of_week_medium_tuesday">аў</string>
+    <string name="day_of_week_medium_wednesday">ср</string>
+    <string name="day_of_week_medium_thursday">чц</string>
+    <string name="day_of_week_medium_friday">пт</string>
+    <string name="day_of_week_medium_saturday">сб</string>
+
+    <string name="day_of_week_short_sunday">нд</string>
+    <string name="day_of_week_short_monday">пн</string>
+    <string name="day_of_week_short_tuesday">аў</string>
+    <string name="day_of_week_short_wednesday">ср</string>
+    <string name="day_of_week_short_thursday">чц</string>
+    <string name="day_of_week_short_friday">пт</string>
+    <string name="day_of_week_short_saturday">сб</string>
+
+    <string name="day_of_week_shortest_sunday">н</string>
+    <string name="day_of_week_shortest_monday">п</string>
+    <string name="day_of_week_shortest_tuesday">а</string>
+    <string name="day_of_week_shortest_wednesday">с</string>
+    <string name="day_of_week_shortest_thursday">ч</string>
+    <string name="day_of_week_shortest_friday">п</string>
+    <string name="day_of_week_shortest_saturday">с</string>
+
+    <string name="am">да палудня</string>
+    <string name="pm">пасля палудня</string>
+    <string name="yesterday">учора</string>
+    <string name="today">сёння</string>
+    <string name="tomorrow">заўтра</string>
+
+    <string name="hour_minute_24">%-k.%M</string>
+    <string name="hour_minute_ampm">%-l.%M %p</string>
+    <string name="hour_minute_cap_ampm">%-l.%M %p</string>
+    <string name="twelve_hour_time_format">h.mm a</string>
+    <string name="twenty_four_hour_time_format">H.mm</string>
+    <string name="numeric_date">%-e.%-m.%Y</string>
+    <string name="numeric_date_format">d.M.yyyy</string>
+    <string name="numeric_date_template">"%s.%s.%s"</string>
+    <string name="month_day_year">%-e %B %Y</string>
+    <string name="time_of_day">%H.%M.%S</string>
+    <string name="date_and_time">%H.%M.%S %-e.%-m.%Y</string>
+    <string name="date_time">%2$s %1$s</string>
+    <string name="time_date">%1$s %3$s</string>
+    <string name="abbrev_month_day_year">%-e.%-m.%Y</string>
+    <string name="month_day">%B %-e</string>
+    <string name="month">%-B</string>
+    <string name="month_year">%B %Y</string>
+    <string name="abbrev_month_day">%-e %b</string>
+    <string name="abbrev_month">%-b</string>
+    <string name="abbrev_month_year">%b %Y</string>
+    <string name="time1_time2">%1$s - %2$s</string>
+    <string name="date1_date2">%2$s - %5$s</string>
+    <string name="numeric_md1_md2">%3$s.%2$s - %8$s.%7$s</string>
+    <string name="numeric_wday1_md1_wday2_md2">%1$s, %3$s.%2$s - %6$s, %8$s.%7$s</string>
+    <string name="numeric_mdy1_mdy2">%3$s.%2$s.%4$s - %8$s.%7$s.%9$s</string>
+    <string name="numeric_wday1_mdy1_wday2_mdy2">%1$s, %3$s.%2$s.%4$s - %6$s, %8$s.%7$s.%9$s</string>
+    <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %3$s/%2$s/%4$s - %10$s %6$s, %8$s/%7$s/%9$s</string>
+    <string name="numeric_md1_time1_md2_time2">%5$s %3$s.%2$s - %10$s %8$s.%7$s</string>
+    <string name="numeric_wday1_md1_time1_wday2_md2_time2">%5$s %1$s, %3$s %2$s - %10$s %6$s, %8$s %7$s</string>
+    <string name="numeric_mdy1_time1_mdy2_time2">%5$s %3$s.%2$s.%4$s - %10$s %8$s.%7$s.%9$s</string>
+    <string name="wday1_date1_time1_wday2_date2_time2">%3$s %1$s, %2$s - %6$s %4$s, %5$s</string>
+    <string name="wday1_date1_wday2_date2">%1$s, %2$s - %4$s, %5$s</string>
+    <string name="date1_time1_date2_time2">%3$s %2$s - %6$s %5$s</string>
+    <string name="time_wday_date">%1$s %2$s, %3$s</string>
+    <string name="wday_date">%2$s, %3$s</string>
+    <string name="time_wday">%1$s %2$s</string>
+    <string name="same_year_md1_md2">%2$s %3$s - %7$s %8$s</string>
+    <string name="same_year_wday1_md1_wday2_md2">%2$s %3$s, %1$s - %7$s %8$s, %6$s</string>
+    <string name="same_year_md1_time1_md2_time2">%5$s %2$s %3$s - %10$s %7$s %8$s</string>
+    <string name="same_month_md1_time1_md2_time2">%5$s %2$s %3$s - %10$s %7$s %8$s</string>
+    <string name="same_year_wday1_md1_time1_wday2_md2_time2">%5$s %2$s %3$s, %1$s - %10$s %7$s %8$s, %6$s</string>
+    <string name="same_month_wday1_md1_time1_wday2_md2_time2">%5$s %2$s %3$s, %1$s - %10$s %7$s %8$s, %6$s</string>
+    <string name="same_year_mdy1_time1_mdy2_time2">%5$s %3$s %2$s %4$s - %10$s %8$s %7$s %9$s</string>
+    <string name="same_month_mdy1_time1_mdy2_time2">%5$s %3$s %2$s %4$s - %10$s %8$s %7$s %9$s</string>
+    <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %3$s %2$s %4$s - %10$s %6$s, %8$s %7$s %9$s</string>
+    <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %3$s %2$s %4$s - %10$s %6$s, %8$s %7$s %9$s</string>
+    <string name="same_month_wday1_mdy1_wday2_mdy2">%1$s, %3$s %2$s %4$s - %6$s, %8$s %7$s %9$s</string>
+    <string name="same_month_md1_md2">%3$s-%8$s %2$s</string>
+    <string name="same_month_wday1_md1_wday2_md2">%2$s %3$s, %1$s - %7$s %8$s, %6$s</string>
+    <string name="same_year_mdy1_mdy2">%3$s %2$s - %8$s %7$s %9$s</string>
+    <string name="same_month_mdy1_mdy2">%3$s-%8$s %2$s %9$s</string>
+    <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s, %3$s %2$s - %6$s, %8$s %7$s %9$s</string>
+    <string name="short_format_month">%b</string>
+    <string name="full_wday_month_day_no_year">MMMM d, EEEE</string>
+    <string name="abbrev_wday_month_day_year">EEE, d MMM y</string>
+</resources>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 1323c84..466e435 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -301,6 +301,8 @@
     <string name="permlab_readLogs" msgid="6615778543198967614">"четене на поверителни данни от регистрационните файлове"</string>
     <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"Разрешава на приложението да чете от различните регистрационни файлове на системата. Това му позволява да получи обща информация какво правите с таблета, потенциално включително и лични или поверителни данни."</string>
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Разрешава на приложението да чете от различните регистрационни файлове на системата. Това му позволява да получи обща информация какво правите с телефона, потенциално включително и лични или поверителни данни."</string>
+    <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"използване на всеки медиен декодер за възпроизвеждане"</string>
+    <string name="permdesc_anyCodecForPlayback" msgid="2101444559995480174">"Разрешава на приложението да използва всеки инсталиран медиен декодер с цел декодиране за възпроизвеждане."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"четене/запис в ресурси, притежавани от diag"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Разрешава на приложението да чете и записва във всеки ресурс, притежаван от групата diag, например файловете в /dev. Това потенциално може да засегне стабилността и сигурността на системата. То трябва да се използва САМО за диагностика, конкретно за хардуера, от страна на производителя или оператора."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"активиране или деактивиране на компоненти на приложенията"</string>
@@ -465,9 +467,9 @@
     <string name="permlab_bluetoothAdmin" msgid="3606576270792236062">"администриране на Bluetooth"</string>
     <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"Разрешава на приложението да конфигурира локалния таблет с Bluetooth, както и да открива и да се сдвоява с отдалечени устройства."</string>
     <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"Разрешава на приложението да конфигурира локалния телефон с Bluetooth, както и да открива и да се сдвоява с отдалечени устройства."</string>
-    <!-- outdated translation 2800410363171809280 -->     <string name="permlab_accessWimaxState" msgid="1232061307208861588">"преглед на състоянието на WiMAX мрежата"</string>
+    <string name="permlab_accessWimaxState" msgid="1232061307208861588">"Преглед на състоянието на WiMAX мрежата"</string>
     <string name="permdesc_accessWimaxState" msgid="8298035866227524023">"Разрешава на приложението да вижда информацията за състоянието на WiMAX мрежата."</string>
-    <!-- outdated translation 340465839241528618 -->     <string name="permlab_changeWimaxState" msgid="2405042267131496579">"промяна на състоянието на WiMAX мрежата"</string>
+    <string name="permlab_changeWimaxState" msgid="2405042267131496579">"Промяна на състоянието на WiMAX мрежата"</string>
     <string name="permdesc_changeWimaxState" msgid="474918005058989421">"Разрешава на приложението да се свързва към WiMAX мрежа и да прекратява връзката с нея."</string>
     <string name="permlab_bluetooth" msgid="8361038707857018732">"създаване на връзки през Bluetooth"</string>
     <string name="permdesc_bluetooth" product="tablet" msgid="7007851048416363446">"Разрешава на приложението да вижда конфигурацията на локалния таблет с Bluetooth и да изгражда и приема връзки със сдвоени устройства."</string>
@@ -667,7 +669,7 @@
     <string name="lockscreen_missing_sim_message" product="tablet" msgid="151659196095791474">"В таблета няма SIM карта."</string>
     <string name="lockscreen_missing_sim_message" product="default" msgid="2186920585695169078">"В телефона няма SIM карта."</string>
     <string name="lockscreen_missing_sim_instructions" msgid="5372787138023272615">"Поставете SIM карта."</string>
-    <string name="lockscreen_missing_sim_instructions_long" msgid="3526573099019319472">"SIM картата липсва или е нечетима. Поставете SIM карта."</string>
+    <string name="lockscreen_missing_sim_instructions_long" msgid="3526573099019319472">"SIM картата липсва или е нечетлива. Поставете SIM карта."</string>
     <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"SIM картата ви е деактивирана за постоянно."\n"Свържете се с оператора на безжичната си връзка, за да получите друга."</string>
     <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"Бутон за предишния запис"</string>
     <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Бутон за следващия запис"</string>
@@ -1219,4 +1221,7 @@
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"Споделяне със:"</string>
     <string name="status_bar_device_locked" msgid="3092703448690669768">"Устройството е заключено."</string>
     <string name="list_delimeter" msgid="3975117572185494152">", "</string>
+    <string name="sending" msgid="8715108995741758718">"Изпраща се..."</string>
+    <string name="launchBrowserDefault" msgid="2057951947297614725">"Да се стартира ли браузърът?"</string>
+    <string name="SetupCallDefault" msgid="6870275517518479651">"Да се приеме ли обаждането?"</string>
 </resources>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 8a04863..7c63b06 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -301,6 +301,8 @@
     <string name="permlab_readLogs" msgid="6615778543198967614">"llegir dades de registre personals"</string>
     <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"Permet que l\'aplicació llegeixi els diversos fitxers de registre del sistema. Això li permet descobrir informació general sobre què estàs fent amb la tauleta, i pot incloure informació personal o privada."</string>
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Permet que l\'aplicació llegeixi els diversos fitxers de registre del sistema. Això li permet descobrir informació general sobre què estàs fent amb el telèfon i, potencialment, pot incloure informació personal o privada."</string>
+    <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"utilitza qualsevol descodificador de mitjans per a la reproducció"</string>
+    <string name="permdesc_anyCodecForPlayback" msgid="2101444559995480174">"Permet que una aplicació utilitzi qualsevol descodificador de mitjans instal·lat per descodificar per a la reproducció."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"llegir/escriure recursos propietat de diag"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Permet que l\'aplicació llegeixi i escrigui a qualsevol recurs propietat del grup diag; per exemple, els fitxers de /dev. Això podria afectar l\'estabilitat i la seguretat del sistema. NOMÉS l\'hauria d\'utilitzar el fabricant o l\'operador per a diagnòstics específics de maquinari."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"activa o desactiva els components de l\'aplicació"</string>
@@ -465,9 +467,9 @@
     <string name="permlab_bluetoothAdmin" msgid="3606576270792236062">"Administració de Bluetooth"</string>
     <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"Permet que l\'aplicació configuri la tauleta Bluetooth local i que cerqui i emparelli dispositius remots."</string>
     <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"Permet que l\'aplicació configuri el telèfon Bluetooth local i que cerqui i emparelli dispositius remots."</string>
-    <!-- outdated translation 2800410363171809280 -->     <string name="permlab_accessWimaxState" msgid="1232061307208861588">"visualitza l\'estat de WiMAX"</string>
+    <string name="permlab_accessWimaxState" msgid="1232061307208861588">"Visualitza l\'estat de WiMAX"</string>
     <string name="permdesc_accessWimaxState" msgid="8298035866227524023">"Permet que una aplicació visualitzi la informació sobre l\'estat de WiMAX."</string>
-    <!-- outdated translation 340465839241528618 -->     <string name="permlab_changeWimaxState" msgid="2405042267131496579">"canvia l\'estat de WiMAX"</string>
+    <string name="permlab_changeWimaxState" msgid="2405042267131496579">"Canvia l\'estat de WiMAX"</string>
     <string name="permdesc_changeWimaxState" msgid="474918005058989421">"Permet que una aplicació es connecti i es desconnecti d\'una xarxa WiMAX."</string>
     <string name="permlab_bluetooth" msgid="8361038707857018732">"crear connexions Bluetooth"</string>
     <string name="permdesc_bluetooth" product="tablet" msgid="7007851048416363446">"Permet que l\'aplicació mostri la configuració de la tauleta Bluetooth local i que estableixi i accepti connexions amb dispositius emparellats."</string>
@@ -1219,4 +1221,7 @@
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"Comparteix amb"</string>
     <string name="status_bar_device_locked" msgid="3092703448690669768">"Dispositiu bloquejat."</string>
     <string name="list_delimeter" msgid="3975117572185494152">", "</string>
+    <string name="sending" msgid="8715108995741758718">"S\'està enviant..."</string>
+    <string name="launchBrowserDefault" msgid="2057951947297614725">"Vols iniciar el navegador?"</string>
+    <string name="SetupCallDefault" msgid="6870275517518479651">"Vols acceptar la trucada?"</string>
 </resources>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 8fd166d..a8247bf 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -301,6 +301,8 @@
     <string name="permlab_readLogs" msgid="6615778543198967614">"číst citlivá data v protokolech"</string>
     <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"Umožňuje aplikaci číst různé systémové soubory protokolů. Toto oprávnění aplikaci umožní získat obecné informace o činnostech s tabletem, které by mohly obsahovat osobní či soukromé informace."</string>
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Umožňuje aplikaci číst různé systémové soubory protokolů. Toto oprávnění aplikaci umožní získat obecné informace o činnostech s telefonem, které by mohly obsahovat osobní či soukromé informace."</string>
+    <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"použít jakýkoliv dekodér pro přehrávání médií"</string>
+    <string name="permdesc_anyCodecForPlayback" msgid="2101444559995480174">"Umožňuje aplikaci používat libovolný nainstalovaný dekodér médií k dekódování při přehrávání."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"čtení nebo zápis do prostředků funkce diag"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Umožňuje aplikaci číst libovolné prostředky ve skupině diag, např. soubory ve složce /dev, a zapisovat do nich. Může dojít k ovlivnění stability a bezpečnosti systému. Toto nastavení by měl používat POUZE výrobce či operátor pro diagnostiku hardwaru."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"aktivace či deaktivace komponent aplikací"</string>
@@ -465,9 +467,9 @@
     <string name="permlab_bluetoothAdmin" msgid="3606576270792236062">"správa rozhraní Bluetooth"</string>
     <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"Umožňuje aplikaci konfigurovat místní tablet s rozhraním Bluetooth a vyhledávat a párovat vzdálená zařízení."</string>
     <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"Umožňuje aplikaci konfigurovat místní telefon s rozhraním Bluetooth a vyhledávat a párovat vzdálená zařízení."</string>
-    <!-- outdated translation 2800410363171809280 -->     <string name="permlab_accessWimaxState" msgid="1232061307208861588">"zobrazit stav připojení WiMAX"</string>
+    <string name="permlab_accessWimaxState" msgid="1232061307208861588">"Zobrazit stav připojení WiMAX"</string>
     <string name="permdesc_accessWimaxState" msgid="8298035866227524023">"Umožňuje aplikaci zobrazit informace o stavu připojení WiMAX."</string>
-    <!-- outdated translation 340465839241528618 -->     <string name="permlab_changeWimaxState" msgid="2405042267131496579">"měnit stav připojení WiMAX"</string>
+    <string name="permlab_changeWimaxState" msgid="2405042267131496579">"Změnit stav připojení WiMAX"</string>
     <string name="permdesc_changeWimaxState" msgid="474918005058989421">"Umožňuje aplikaci připojovat se k síti WiMAX a odpojovat se od ní."</string>
     <string name="permlab_bluetooth" msgid="8361038707857018732">"vytvoření připojení Bluetooth"</string>
     <string name="permdesc_bluetooth" product="tablet" msgid="7007851048416363446">"Umožňuje aplikaci zobrazit konfiguraci místního tabletu s rozhraním Bluetooth, vytvářet připojení ke spárovaným zařízením a přijímat tato připojení."</string>
@@ -1219,4 +1221,7 @@
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"Sdílet s"</string>
     <string name="status_bar_device_locked" msgid="3092703448690669768">"Zařízení je uzamčeno."</string>
     <string name="list_delimeter" msgid="3975117572185494152">", "</string>
+    <string name="sending" msgid="8715108995741758718">"Odesílání..."</string>
+    <string name="launchBrowserDefault" msgid="2057951947297614725">"Spustit prohlížeč?"</string>
+    <string name="SetupCallDefault" msgid="6870275517518479651">"Přijmout hovor?"</string>
 </resources>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 2b0060b..f1f80a0 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -301,6 +301,8 @@
     <string name="permlab_readLogs" msgid="6615778543198967614">"læse følsomme logdata"</string>
     <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"Tillader, at appen kan læse de forskellige logfiler i systemet. Dermed kan generelle oplysninger om dine handlinger på tabletten registreres, f.eks. personlige eller private oplysninger."</string>
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Tillader, at appen kan læse i systemets forskellige logfiler. Dermed kan generelle oplysninger om, hvad du laver med telefonen registreres, også personlige eller private oplysninger."</string>
+    <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"brug enhver mediedekoder til afspilning"</string>
+    <string name="permdesc_anyCodecForPlayback" msgid="2101444559995480174">"Tillader, at en applikation bruger enhver installeret mediedekoder til at afkode til afspilning."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"læs/skriv til ressourcer ejet af diag"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Tillader, at appen kan læse og skrive til alle ressourcer, der ejes af diag-gruppen,  f.eks. filer i /dev. Dette kan muligvis påvirke systemets stabilitet og sikkerhed. Dette bør KUN bruges til hardwarespecifik diagnosticering, som foretages af producenten eller udbyderen."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"aktivere eller deaktivere appkomponenter"</string>
@@ -465,9 +467,9 @@
     <string name="permlab_bluetoothAdmin" msgid="3606576270792236062">"Administration af Bluetooth"</string>
     <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"Tillader, at appen kan konfigurere den lokale Bluetooth-tablet samt finde og parre med fjerne enheder."</string>
     <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"Tillader, at appen kan konfigurere den lokale Bluetooth-telefon samt finde og parre med eksterne enheder."</string>
-    <!-- outdated translation 2800410363171809280 -->     <string name="permlab_accessWimaxState" msgid="1232061307208861588">"vise WiMAX-tilstand"</string>
+    <string name="permlab_accessWimaxState" msgid="1232061307208861588">"Få vist WiMAX-tilstand"</string>
     <string name="permdesc_accessWimaxState" msgid="8298035866227524023">"Tillader, at en applikation viser oplysninger om WiMAX-tilstanden."</string>
-    <!-- outdated translation 340465839241528618 -->     <string name="permlab_changeWimaxState" msgid="2405042267131496579">"skifte WiMAX-tilstand"</string>
+    <string name="permlab_changeWimaxState" msgid="2405042267131496579">"Skift WiMAX-tilstand"</string>
     <string name="permdesc_changeWimaxState" msgid="474918005058989421">"Tillader, at en applikation opretter og afbryder forbindelsen til WiMAX-netværk."</string>
     <string name="permlab_bluetooth" msgid="8361038707857018732">"opret Bluetooth-forbindelser"</string>
     <string name="permdesc_bluetooth" product="tablet" msgid="7007851048416363446">"Tillader, at appen kan se konfigurationen af ​​den lokale Bluetooth-tablet og oprette og acceptere forbindelser med parrede enheder."</string>
@@ -1219,4 +1221,7 @@
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"Del med"</string>
     <string name="status_bar_device_locked" msgid="3092703448690669768">"Enhed låst."</string>
     <string name="list_delimeter" msgid="3975117572185494152">", "</string>
+    <string name="sending" msgid="8715108995741758718">"Sender..."</string>
+    <string name="launchBrowserDefault" msgid="2057951947297614725">"Vil du starte browseren?"</string>
+    <string name="SetupCallDefault" msgid="6870275517518479651">"Vil du besvare opkaldet?"</string>
 </resources>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index ba147e5..0430789 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -301,6 +301,8 @@
     <string name="permlab_readLogs" msgid="6615778543198967614">"Lesen vertraulicher Protokolldaten"</string>
     <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"Ermöglicht der App, die verschiedenen Protokolldateien des Systems zu lesen. So können allgemeine Informationen zu den auf Ihrem Tablet durchgeführten Aktionen eingesehen werden, darunter auch persönliche oder geheime Daten."</string>
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Ermöglicht der App, die verschiedenen Protokolldateien des Systems zu lesen. So können allgemeine Informationen zu den auf Ihrem Telefon durchgeführten Aktionen eingesehen werden, darunter auch persönliche oder geheime Daten."</string>
+    <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"Für Wiedergabe beliebigen Mediendecodierer verwenden"</string>
+    <string name="permdesc_anyCodecForPlayback" msgid="2101444559995480174">"Ermöglicht einer App, einen beliebigen Mediendecodierer für die Wiedergabe zu verwenden"</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"Lese-/Schreibberechtigung für zu Diagnosegruppe gehörige Elemente"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Ermöglicht der App, alle Elemente in der Diagnosegruppe zu lesen und zu bearbeiten, etwa Dateien in \"/dev\". Dies könnte eine potenzielle Gefährdung für die Stabilität und Sicherheit des Systems darstellen und sollte NUR für hardwarespezifische Diagnosen des Herstellers oder Mobilfunkanbieters verwendet werden."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"App-Komponenten aktivieren oder deaktivieren"</string>
@@ -465,9 +467,9 @@
     <string name="permlab_bluetoothAdmin" msgid="3606576270792236062">"Bluetooth-Verwaltung"</string>
     <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"Ermöglicht der App, das lokale Bluetooth-Tablet zu konfigurieren, Remote-Geräte zu erkennen und eine Verbindung zu diesen herzustellen"</string>
     <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"Ermöglicht der App, das lokale Bluetooth-Telefon zu konfigurieren, Remote-Geräte zu erkennen und eine Verbindung zu diesen herzustellen"</string>
-    <!-- outdated translation 2800410363171809280 -->     <string name="permlab_accessWimaxState" msgid="1232061307208861588">"WiMAX-Status anzeigen"</string>
+    <string name="permlab_accessWimaxState" msgid="1232061307208861588">"WiMAX-Status anzeigen"</string>
     <string name="permdesc_accessWimaxState" msgid="8298035866227524023">"Ermöglicht einer App, die Informationen zum WiMAX-Status einzusehen"</string>
-    <!-- outdated translation 340465839241528618 -->     <string name="permlab_changeWimaxState" msgid="2405042267131496579">"WiMAX-Status ändern"</string>
+    <string name="permlab_changeWimaxState" msgid="2405042267131496579">"WiMAX-Status ändern"</string>
     <string name="permdesc_changeWimaxState" msgid="474918005058989421">"Ermöglicht einer App, eine Verbindung mit dem WiMAX-Netzwerk herzustellen bzw. zu trennen"</string>
     <string name="permlab_bluetooth" msgid="8361038707857018732">"Bluetooth-Verbindungen herstellen"</string>
     <string name="permdesc_bluetooth" product="tablet" msgid="7007851048416363446">"Ermöglicht der App, die Konfiguration des lokalen Bluetooth-Tablets einzusehen und Verbindungen zu Partnergeräten herzustellen und zu akzeptieren"</string>
@@ -1097,7 +1099,7 @@
     <string name="throttled_notification_title" msgid="6269541897729781332">"Mobildatenlimit überschritten"</string>
     <string name="throttled_notification_message" msgid="4712369856601275146">"Durch Berühren weitere Informationen zur Mobildatennutzung aufrufen"</string>
     <string name="no_matches" msgid="8129421908915840737">"Keine Treffer"</string>
-    <string name="find_on_page" msgid="1946799233822820384">"Auf Seite suchen"</string>
+    <string name="find_on_page" msgid="1946799233822820384">"Suchen"</string>
   <plurals name="matches_found">
     <item quantity="one" msgid="8167147081136579439">"1 Treffer"</item>
     <item quantity="other" msgid="4641872797067609177">"<xliff:g id="INDEX">%d</xliff:g> von <xliff:g id="TOTAL">%d</xliff:g>"</item>
@@ -1219,4 +1221,7 @@
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"Teilen mit"</string>
     <string name="status_bar_device_locked" msgid="3092703448690669768">"Gerät gesperrt"</string>
     <string name="list_delimeter" msgid="3975117572185494152">", "</string>
+    <string name="sending" msgid="8715108995741758718">"Wird gesendet..."</string>
+    <string name="launchBrowserDefault" msgid="2057951947297614725">"Browser starten?"</string>
+    <string name="SetupCallDefault" msgid="6870275517518479651">"Anruf annehmen?"</string>
 </resources>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 4d95d5f..cca6868 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -301,6 +301,8 @@
     <string name="permlab_readLogs" msgid="6615778543198967614">"ανάγνωση ευαίσθητων δεδομένων αρχείου καταγραφής"</string>
     <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"Επιτρέπει στην εφαρμογή την ανάγνωση των αρχείων καταγραφής του συστήματος. Έτσι, μπορεί να ανακαλύψει γενικές πληροφορίες σχετικά με τις δραστηριότητές σας στο τηλέφωνο, συμπεριλαμβάνοντας πιθανώς και προσωπικές ή ιδιωτικές πληροφορίες."</string>
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Επιτρέπει στην εφαρμογή την ανάγνωση των αρχείων καταγραφής του συστήματος. Έτσι, μπορεί να ανακαλύψει γενικές πληροφορίες σχετικά με τις δραστηριότητές σας στο τηλέφωνο, συμπεριλαμβάνοντας πιθανώς και προσωπικές ή ιδιωτικές πληροφορίες."</string>
+    <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"χρήση οποιουδήποτε αποκωδικοποιητή μέσων για αναπαραγωγή"</string>
+    <string name="permdesc_anyCodecForPlayback" msgid="2101444559995480174">"Επιτρέπει σε μια εφαρμογή να χρησιμοποιεί οποιοδήποτε εγκατεστημένο αποκωδικοποιητή μέσων προκειμένου να πραγματοποιήσει αποκωδικοποίηση για αναπαραγωγή."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"ανάγνωση/εγγραφή σε πόρους που ανήκουν στο διαγνωστικό"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Επιτρέπει στην εφαρμογή την ανάγνωση και την εγγραφή σε οποιονδήποτε πόρο που ανήκει στην ομάδα διαγνωστικού (π.χ. αρχεία στον κατάλογο /dev). Αυτό ενδέχεται να επηρεάσει την σταθερότητα και την ασφάλεια του συστήματος. Θα πρέπει να χρησιμοποιείται ΜΟΝΟ για διαγνωστικά υλικού από τον κατασκευαστή ή τον χειριστή."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"ενεργοποίηση ή απενεργοποίηση στοιχείων εφαρμογής"</string>
@@ -465,9 +467,9 @@
     <string name="permlab_bluetoothAdmin" msgid="3606576270792236062">"διαχείριση bluetooth"</string>
     <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"Επιτρέπει στην εφαρμογή τη διαμόρφωση του τοπικού tablet Bluetooth, τον εντοπισμό και τη σύζευξη με απομακρυσμένες συσκευές."</string>
     <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"Επιτρέπει στην εφαρμογή τη διαμόρφωση του τοπικού tablet Bluetooth, τον εντοπισμό και τη σύζευξη με απομακρυσμένες συσκευές."</string>
-    <!-- outdated translation 2800410363171809280 -->     <string name="permlab_accessWimaxState" msgid="1232061307208861588">"προβολή κατάστασης WiMAX"</string>
+    <string name="permlab_accessWimaxState" msgid="1232061307208861588">"Προβολή κατάστασης WiMAX"</string>
     <string name="permdesc_accessWimaxState" msgid="8298035866227524023">"Επιτρέπει σε μια εφαρμογή την προβολή των πληροφοριών σχετικά με την κατάσταση του WiMAX."</string>
-    <!-- outdated translation 340465839241528618 -->     <string name="permlab_changeWimaxState" msgid="2405042267131496579">"αλλαγή κατάστασης WiMAX"</string>
+    <string name="permlab_changeWimaxState" msgid="2405042267131496579">"Αλλαγή κατάστασης WiMAX"</string>
     <string name="permdesc_changeWimaxState" msgid="474918005058989421">"Επιτρέπει σε μια εφαρμογή τη σύνδεση και αποσύνδεση από το δίκτυο WiMAX."</string>
     <string name="permlab_bluetooth" msgid="8361038707857018732">"δημιουργία συνδέσεων Bluetooth"</string>
     <string name="permdesc_bluetooth" product="tablet" msgid="7007851048416363446">"Επιτρέπει στην εφαρμογή να προβάλει τη διαμόρφωση του τοπικού tablet Bluetooth και επίσης να πραγματοποιεί και να αποδέχεται συνδέσεις με συζευγμένες συσκευές."</string>
@@ -1219,4 +1221,7 @@
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"Κοινή χρήση με"</string>
     <string name="status_bar_device_locked" msgid="3092703448690669768">"Η συσκευή κλειδώθηκε."</string>
     <string name="list_delimeter" msgid="3975117572185494152">", "</string>
+    <string name="sending" msgid="8715108995741758718">"Αποστολή..."</string>
+    <string name="launchBrowserDefault" msgid="2057951947297614725">"Εκκίνηση προγράμματος περιήγησης;"</string>
+    <string name="SetupCallDefault" msgid="6870275517518479651">"Αποδοχή κλήσης;"</string>
 </resources>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index d6474a4..f936ab9 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -301,6 +301,8 @@
     <string name="permlab_readLogs" msgid="6615778543198967614">"read sensitive log data"</string>
     <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"Allows the app to read from the system\'s various log files. This allows it to discover general information about what you are doing with the tablet, potentially including personal or private information."</string>
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Allows the app to read from the system\'s various log files. This allows it to discover general information about what you are doing with the phone, potentially including personal or private information."</string>
+    <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"use any media decoder for playback"</string>
+    <string name="permdesc_anyCodecForPlayback" msgid="2101444559995480174">"Allows an application to use any media decoder installed to decode for playback."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"read/write to resources owned by diag"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Allows the app to read and write to any resource owned by the diag group; for example, files in /dev. This could potentially affect system stability and security. This should ONLY be used for hardware-specific diagnostics by the manufacturer or operator."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"enable or disable app components"</string>
@@ -465,9 +467,9 @@
     <string name="permlab_bluetoothAdmin" msgid="3606576270792236062">"Bluetooth administration"</string>
     <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"Allows the app to configure the local Bluetooth tablet and to discover and pair with remote devices."</string>
     <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"Allows the app to configure the local Bluetooth phone and to discover and pair with remote devices."</string>
-    <!-- outdated translation 2800410363171809280 -->     <string name="permlab_accessWimaxState" msgid="1232061307208861588">"view WiMAX state"</string>
+    <string name="permlab_accessWimaxState" msgid="1232061307208861588">"view WiMAX state"</string>
     <string name="permdesc_accessWimaxState" msgid="8298035866227524023">"Allows an application to view the information about the state of WiMAX."</string>
-    <!-- outdated translation 340465839241528618 -->     <string name="permlab_changeWimaxState" msgid="2405042267131496579">"change WiMAX state"</string>
+    <string name="permlab_changeWimaxState" msgid="2405042267131496579">"change WiMAX state"</string>
     <string name="permdesc_changeWimaxState" msgid="474918005058989421">"Allows an application to connect to and disconnect from WiMAX network."</string>
     <string name="permlab_bluetooth" msgid="8361038707857018732">"create Bluetooth connections"</string>
     <string name="permdesc_bluetooth" product="tablet" msgid="7007851048416363446">"Allows the app to view the configuration of the local Bluetooth tablet, and to make and accept connections with paired devices."</string>
@@ -1219,4 +1221,7 @@
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"Share with"</string>
     <string name="status_bar_device_locked" msgid="3092703448690669768">"Device locked."</string>
     <string name="list_delimeter" msgid="3975117572185494152">", "</string>
+    <string name="sending" msgid="8715108995741758718">"Sending..."</string>
+    <string name="launchBrowserDefault" msgid="2057951947297614725">"Launch Browser?"</string>
+    <string name="SetupCallDefault" msgid="6870275517518479651">"Accept Call?"</string>
 </resources>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 6de487c..fcfe5f4 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -301,6 +301,8 @@
     <string name="permlab_readLogs" msgid="6615778543198967614">"lee los datos confidenciales del registro"</string>
     <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"Permite que la aplicación lea diversos archivos de registro del sistema. Esto le permite descubrir información general acerca de lo que haces con la tableta, lo que podría incluir información personal o privada."</string>
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Permite que la aplicación lea los diversos archivos de registro del sistema. Esto le permite descubrir información general acerca de lo que haces con el teléfono, que puede incluir información personal o privada."</string>
+    <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"Usar cualquier decodificador de medios para la reproducción"</string>
+    <string name="permdesc_anyCodecForPlayback" msgid="2101444559995480174">"Permite que una aplicación use cualquier codificador de medios instalado para decodificar archivos para su reproducción."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"leer y escribir a recursos dentro del grupo de diagnóstico"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Permite que la aplicación lea y escriba en cualquier recurso propiedad del grupo de diagnóstico como, por ejemplo, archivos in/dev. Este permiso podría afectar la seguridad y estabilidad del sistema. SOLO se debe utilizar para diagnósticos específicos de hardware realizados por el fabricante o el operador."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"activar o desactivar componentes de la aplicación"</string>
@@ -465,9 +467,9 @@
     <string name="permlab_bluetoothAdmin" msgid="3606576270792236062">"Administración de Bluetooth"</string>
     <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"Permite que la aplicación configure la tableta Bluetooth local y descubra y se sincronice con dispositivos remotos."</string>
     <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"Permite que la aplicación configure el teléfono Bluetooth local y descubra y se sincronice con dispositivos remotos."</string>
-    <!-- outdated translation 2800410363171809280 -->     <string name="permlab_accessWimaxState" msgid="1232061307208861588">"ver el estado de WiMAX"</string>
+    <string name="permlab_accessWimaxState" msgid="1232061307208861588">"Ver el estado de WiMAX"</string>
     <string name="permdesc_accessWimaxState" msgid="8298035866227524023">"Permite que una aplicación vea la información acerca del estado de WiMAX."</string>
-    <!-- outdated translation 340465839241528618 -->     <string name="permlab_changeWimaxState" msgid="2405042267131496579">"cambiar estado de WiMAX"</string>
+    <string name="permlab_changeWimaxState" msgid="2405042267131496579">"Cambiar el estado de WiMAX"</string>
     <string name="permdesc_changeWimaxState" msgid="474918005058989421">"Permite que una aplicación se conecte a una red WiMAX y se desconecte de esta."</string>
     <string name="permlab_bluetooth" msgid="8361038707857018732">"crear conexiones de Bluetooth"</string>
     <string name="permdesc_bluetooth" product="tablet" msgid="7007851048416363446">"Permite que la aplicación vea la configuración de la tableta Bluetooth local, y que cree y acepte conexiones con los dispositivos sincronizados."</string>
@@ -1031,7 +1033,7 @@
     <string name="ext_media_checking_notification_message" msgid="8287319882926737053">"Verificando errores"</string>
     <string name="ext_media_nofs_notification_title" product="nosdcard" msgid="7788040745686229307">"Almacenamiento USB en blanco"</string>
     <string name="ext_media_nofs_notification_title" product="default" msgid="780477838241212997">"Tarjeta SD vacía"</string>
-    <string name="ext_media_nofs_notification_message" product="nosdcard" msgid="8623130522556087311">"Almacenamiento USB en blanco o sistema de archivos no compatible."</string>
+    <string name="ext_media_nofs_notification_message" product="nosdcard" msgid="8623130522556087311">"Almacenamiento USB vacío o sistema de archivos no compatible"</string>
     <string name="ext_media_nofs_notification_message" product="default" msgid="3817704088027829380">"Tarjeta SD en blanco o el sistema de archivos no es compatible."</string>
     <string name="ext_media_unmountable_notification_title" product="nosdcard" msgid="2090046769532713563">"Almacenamiento USB dañado"</string>
     <string name="ext_media_unmountable_notification_title" product="default" msgid="6410723906019100189">"Tarjeta SD dañada"</string>
@@ -1039,7 +1041,7 @@
     <string name="ext_media_unmountable_notification_message" product="default" msgid="6902531775948238989">"Tarjeta SD dañada. Es posible que debas reformatearla."</string>
     <string name="ext_media_badremoval_notification_title" product="nosdcard" msgid="1661683031330951073">"Almacenamiento USB extraído inesperadamente"</string>
     <string name="ext_media_badremoval_notification_title" product="default" msgid="6872152882604407837">"Almacenamiento USB extraído de forma imprevista"</string>
-    <string name="ext_media_badremoval_notification_message" product="nosdcard" msgid="4329848819865594241">"Desmontar el almacenamiento USB antes de extraerlo para evitar la pérdida de datos."</string>
+    <string name="ext_media_badremoval_notification_message" product="nosdcard" msgid="4329848819865594241">"Desactivar el almacenamiento USB antes de extraerlo para evitar la pérdida de datos."</string>
     <string name="ext_media_badremoval_notification_message" product="default" msgid="7260183293747448241">"Desmontar la tarjeta SD antes de extraerla para evitar la pérdida de datos."</string>
     <string name="ext_media_safe_unmount_notification_title" product="nosdcard" msgid="3967973893270360230">"Es seguro extraer el almacenamiento USB"</string>
     <string name="ext_media_safe_unmount_notification_title" product="default" msgid="6729801130790616200">"Es seguro extraer la tarjeta SD"</string>
@@ -1219,4 +1221,7 @@
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"Compartir con"</string>
     <string name="status_bar_device_locked" msgid="3092703448690669768">"Dispositivo bloqueado"</string>
     <string name="list_delimeter" msgid="3975117572185494152">", "</string>
+    <string name="sending" msgid="8715108995741758718">"Envío en curso..."</string>
+    <string name="launchBrowserDefault" msgid="2057951947297614725">"¿Deseas iniciar el navegador?"</string>
+    <string name="SetupCallDefault" msgid="6870275517518479651">"¿Deseas aceptar la llamada?"</string>
 </resources>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index f7890ff..0ca6516 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -115,7 +115,7 @@
     <string name="httpErrorProxyAuth" msgid="1788207010559081331">"La autenticación mediante el servidor proxy no se ha realizado correctamente."</string>
     <string name="httpErrorConnect" msgid="7623096283505770433">"La conexión con el servidor no se ha realizado correctamente."</string>
     <string name="httpErrorIO" msgid="4270874999047767599">"El servidor no ha podido establecer la comunicación. Inténtalo de nuevo más tarde."</string>
-    <string name="httpErrorTimeout" msgid="4743403703762883954">"Se ha agotado el tiempo de espera de conexión al servidor."</string>
+    <string name="httpErrorTimeout" msgid="4743403703762883954">"Se ha agotado el tiempo de espera de conexión con el servidor."</string>
     <string name="httpErrorRedirectLoop" msgid="8679596090392779516">"La página contiene demasiados redireccionamientos de servidor."</string>
     <string name="httpErrorUnsupportedScheme" msgid="5015730812906192208">"Protocolo no admitido"</string>
     <string name="httpErrorFailedSslHandshake" msgid="3088290300440289771">"No se ha podido establecer una conexión segura."</string>
@@ -301,6 +301,8 @@
     <string name="permlab_readLogs" msgid="6615778543198967614">"leer datos de registro personales"</string>
     <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"Permite que la aplicación lea distintos archivos de registro del sistema. La aplicación puede usar este permiso para obtener información general sobre las acciones que haces con el tablet, que puede incluir datos personales o privados."</string>
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Permite que la aplicación consulte distintos archivos de registro del sistema. La aplicación puede usar este permiso para obtener información general sobre las acciones que realizas con el dispositivo, que puede incluir datos personales o privados."</string>
+    <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"Utilizar cualquier decodificador de archivos multimedia para la reproducción"</string>
+    <string name="permdesc_anyCodecForPlayback" msgid="2101444559995480174">"Permite que una aplicación utilice cualquier decodificador de archivos multimedia instalado para la reproducción."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"leer/escribir en los recursos propiedad del grupo de diagnóstico"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Permite que la aplicación consulte y escriba en cualquier recurso del grupo de diagnóstico como, por ejemplo, archivos en /dev. Este permiso podría afectar a la seguridad y estabilidad del sistema. SOLO se debe usar para diagnósticos específicos de hardware realizados por el fabricante o el operador."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"habilitar o inhabilitar componentes de la aplicación"</string>
@@ -465,9 +467,9 @@
     <string name="permlab_bluetoothAdmin" msgid="3606576270792236062">"administración de Bluetooth"</string>
     <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"Permite que la aplicación configure el tablet Bluetooth local y que detecte dispositivos remotos y se sincronice con ellos."</string>
     <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"Permite que la aplicación configure el teléfono Bluetooth local y que detecte dispositivos remotos y se sincronice con ellos."</string>
-    <!-- outdated translation 2800410363171809280 -->     <string name="permlab_accessWimaxState" msgid="1232061307208861588">"ver estado de WiMAX"</string>
+    <string name="permlab_accessWimaxState" msgid="1232061307208861588">"Ver estado de WiMAX"</string>
     <string name="permdesc_accessWimaxState" msgid="8298035866227524023">"Permite que una aplicación acceda a la información sobre el estado de la conectividad WiMAX."</string>
-    <!-- outdated translation 340465839241528618 -->     <string name="permlab_changeWimaxState" msgid="2405042267131496579">"cambiar estado de WiMAX"</string>
+    <string name="permlab_changeWimaxState" msgid="2405042267131496579">"Cambiar estado de WiMAX"</string>
     <string name="permdesc_changeWimaxState" msgid="474918005058989421">"Permite a una aplicación conectarse a una red WiMAX y desconectarse de ella."</string>
     <string name="permlab_bluetooth" msgid="8361038707857018732">"crear conexiones de Bluetooth"</string>
     <string name="permdesc_bluetooth" product="tablet" msgid="7007851048416363446">"Permite que la aplicación acceda a la configuración del tablet Bluetooth local y que establezca y acepte conexiones con los dispositivos sincronizados."</string>
@@ -791,7 +793,7 @@
     <string name="last_month" msgid="3959346739979055432">"El mes pasado"</string>
     <string name="older" msgid="5211975022815554840">"Anterior"</string>
   <plurals name="num_days_ago">
-    <item quantity="one" msgid="861358534398115820">"ayer"</item>
+    <item quantity="one" msgid="861358534398115820">"Ayer"</item>
     <item quantity="other" msgid="2479586466153314633">"Hace <xliff:g id="COUNT">%d</xliff:g> días"</item>
   </plurals>
   <plurals name="in_num_seconds">
@@ -823,7 +825,7 @@
     <item quantity="other" msgid="6889970745748538901">"hace <xliff:g id="COUNT">%d</xliff:g> horas"</item>
   </plurals>
   <plurals name="abbrev_num_days_ago">
-    <item quantity="one" msgid="8463161711492680309">"ayer"</item>
+    <item quantity="one" msgid="8463161711492680309">"Ayer"</item>
     <item quantity="other" msgid="3453342639616481191">"hace <xliff:g id="COUNT">%d</xliff:g> días"</item>
   </plurals>
   <plurals name="abbrev_in_num_seconds">
@@ -917,10 +919,10 @@
     <string name="screen_compat_mode_hint" msgid="1064524084543304459">"Para volver a habilitar esta opción, accede a Ajustes &gt; Aplicaciones &gt; Descargadas."</string>
     <string name="smv_application" msgid="3307209192155442829">"La aplicación <xliff:g id="APPLICATION">%1$s</xliff:g> (proceso <xliff:g id="PROCESS">%2$s</xliff:g>) ha infringido su política StrictMode autoaplicable."</string>
     <string name="smv_process" msgid="5120397012047462446">"El proceso <xliff:g id="PROCESS">%1$s</xliff:g> ha infringido su política StrictMode autoaplicable."</string>
-    <string name="android_upgrading_title" msgid="1584192285441405746">"Actualizando Android..."</string>
-    <string name="android_upgrading_apk" msgid="7904042682111526169">"Optimizando aplicación <xliff:g id="NUMBER_0">%1$d</xliff:g> de <xliff:g id="NUMBER_1">%2$d</xliff:g>"</string>
+    <string name="android_upgrading_title" msgid="1584192285441405746">"Actualizando Android"</string>
+    <string name="android_upgrading_apk" msgid="7904042682111526169">"Optimizando aplicación <xliff:g id="NUMBER_0">%1$d</xliff:g> de <xliff:g id="NUMBER_1">%2$d</xliff:g>..."</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Iniciando aplicaciones"</string>
-    <string name="android_upgrading_complete" msgid="1405954754112999229">"Finalizando arranque"</string>
+    <string name="android_upgrading_complete" msgid="1405954754112999229">"Finalizando inicio..."</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> en ejecución"</string>
     <string name="heavy_weight_notification_detail" msgid="1721681741617898865">"Toca esta opción para cambiar a la aplicación."</string>
     <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"¿Cambiar aplicaciones?"</string>
@@ -1219,4 +1221,7 @@
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"Compartir con"</string>
     <string name="status_bar_device_locked" msgid="3092703448690669768">"Dispositivo bloqueado"</string>
     <string name="list_delimeter" msgid="3975117572185494152">", "</string>
+    <string name="sending" msgid="8715108995741758718">"Enviando..."</string>
+    <string name="launchBrowserDefault" msgid="2057951947297614725">"¿Iniciar el navegador?"</string>
+    <string name="SetupCallDefault" msgid="6870275517518479651">"¿Aceptar la llamada?"</string>
 </resources>
diff --git a/core/res/res/values-et/donottranslate-cldr.xml b/core/res/res/values-et/donottranslate-cldr.xml
new file mode 100644
index 0000000..d50d041
--- /dev/null
+++ b/core/res/res/values-et/donottranslate-cldr.xml
@@ -0,0 +1,149 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="month_long_standalone_january">jaanuar</string>
+    <string name="month_long_standalone_february">veebruar</string>
+    <string name="month_long_standalone_march">märts</string>
+    <string name="month_long_standalone_april">aprill</string>
+    <string name="month_long_standalone_may">mai</string>
+    <string name="month_long_standalone_june">juuni</string>
+    <string name="month_long_standalone_july">juuli</string>
+    <string name="month_long_standalone_august">august</string>
+    <string name="month_long_standalone_september">september</string>
+    <string name="month_long_standalone_october">oktoober</string>
+    <string name="month_long_standalone_november">november</string>
+    <string name="month_long_standalone_december">detsember</string>
+
+    <string name="month_long_january">jaanuar</string>
+    <string name="month_long_february">veebruar</string>
+    <string name="month_long_march">märts</string>
+    <string name="month_long_april">aprill</string>
+    <string name="month_long_may">mai</string>
+    <string name="month_long_june">juuni</string>
+    <string name="month_long_july">juuli</string>
+    <string name="month_long_august">august</string>
+    <string name="month_long_september">september</string>
+    <string name="month_long_october">oktoober</string>
+    <string name="month_long_november">november</string>
+    <string name="month_long_december">detsember</string>
+
+    <string name="month_medium_january">jaan</string>
+    <string name="month_medium_february">veebr</string>
+    <string name="month_medium_march">märts</string>
+    <string name="month_medium_april">apr</string>
+    <string name="month_medium_may">mai</string>
+    <string name="month_medium_june">juuni</string>
+    <string name="month_medium_july">juuli</string>
+    <string name="month_medium_august">aug</string>
+    <string name="month_medium_september">sept</string>
+    <string name="month_medium_october">okt</string>
+    <string name="month_medium_november">nov</string>
+    <string name="month_medium_december">dets</string>
+
+    <string name="month_shortest_january">1</string>
+    <string name="month_shortest_february">2</string>
+    <string name="month_shortest_march">3</string>
+    <string name="month_shortest_april">4</string>
+    <string name="month_shortest_may">5</string>
+    <string name="month_shortest_june">6</string>
+    <string name="month_shortest_july">7</string>
+    <string name="month_shortest_august">8</string>
+    <string name="month_shortest_september">9</string>
+    <string name="month_shortest_october">10</string>
+    <string name="month_shortest_november">11</string>
+    <string name="month_shortest_december">12</string>
+
+    <string name="day_of_week_long_sunday">pühapäev</string>
+    <string name="day_of_week_long_monday">esmaspäev</string>
+    <string name="day_of_week_long_tuesday">teisipäev</string>
+    <string name="day_of_week_long_wednesday">kolmapäev</string>
+    <string name="day_of_week_long_thursday">neljapäev</string>
+    <string name="day_of_week_long_friday">reede</string>
+    <string name="day_of_week_long_saturday">laupäev</string>
+
+    <string name="day_of_week_medium_sunday">P</string>
+    <string name="day_of_week_medium_monday">E</string>
+    <string name="day_of_week_medium_tuesday">T</string>
+    <string name="day_of_week_medium_wednesday">K</string>
+    <string name="day_of_week_medium_thursday">N</string>
+    <string name="day_of_week_medium_friday">R</string>
+    <string name="day_of_week_medium_saturday">L</string>
+
+    <string name="day_of_week_short_sunday">P</string>
+    <string name="day_of_week_short_monday">E</string>
+    <string name="day_of_week_short_tuesday">T</string>
+    <string name="day_of_week_short_wednesday">K</string>
+    <string name="day_of_week_short_thursday">N</string>
+    <string name="day_of_week_short_friday">R</string>
+    <string name="day_of_week_short_saturday">L</string>
+
+    <string name="day_of_week_shortest_sunday">1</string>
+    <string name="day_of_week_shortest_monday">2</string>
+    <string name="day_of_week_shortest_tuesday">3</string>
+    <string name="day_of_week_shortest_wednesday">4</string>
+    <string name="day_of_week_shortest_thursday">5</string>
+    <string name="day_of_week_shortest_friday">6</string>
+    <string name="day_of_week_shortest_saturday">7</string>
+
+    <string name="am">AM</string>
+    <string name="pm">PM</string>
+    <string name="yesterday">Yesterday</string>
+    <string name="today">Today</string>
+    <string name="tomorrow">Tomorrow</string>
+
+    <string name="hour_minute_24">%-k:%M</string>
+    <string name="hour_minute_ampm">%-l:%M %p</string>
+    <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
+    <string name="twelve_hour_time_format">h:mm a</string>
+    <string name="twenty_four_hour_time_format">H:mm</string>
+    <string name="numeric_date">%d.%m.%Y</string>
+    <string name="numeric_date_format">dd.MM.yyyy</string>
+    <string name="numeric_date_template">"%s.%s.%s"</string>
+    <string name="month_day_year">%-e %B %Y</string>
+    <string name="time_of_day">%-k:%M:%S</string>
+    <string name="date_and_time">%-k:%M:%S %d.%m.%Y</string>
+    <string name="date_time">%2$s %1$s</string>
+    <string name="time_date">%1$s %3$s</string>
+    <string name="abbrev_month_day_year">%d.%m.%Y</string>
+    <string name="month_day">%-e %B</string>
+    <string name="month">%-B</string>
+    <string name="month_year">%B %Y</string>
+    <string name="abbrev_month_day">%-e %b</string>
+    <string name="abbrev_month">%b</string>
+    <string name="abbrev_month_year">%b %Y</string>
+    <string name="time1_time2">%1$s - %2$s</string>
+    <string name="date1_date2">%2$s - %5$s</string>
+    <string name="numeric_md1_md2">%3$s.%2$s - %8$s.%7$s</string>
+    <string name="numeric_wday1_md1_wday2_md2">%1$s, %3$s.%2$s - %6$s, %8$s.%7$s</string>
+    <string name="numeric_mdy1_mdy2">%3$s.%2$s.%4$s - %8$s.%7$s.%9$s</string>
+    <string name="numeric_wday1_mdy1_wday2_mdy2">%1$s, %3$s.%2$s.%4$s - %6$s, %8$s.%7$s.%9$s</string>
+    <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %3$s.%2$s.%4$s - %10$s %6$s, %8$s.%7$s.%9$s</string>
+    <string name="numeric_md1_time1_md2_time2">%5$s %3$s.%2$s - %10$s %8$s.%7$s</string>
+    <string name="numeric_wday1_md1_time1_wday2_md2_time2">%5$s %1$s, %3$s.%2$s - %10$s %6$s, %8$s.%7$s</string>
+    <string name="numeric_mdy1_time1_mdy2_time2">%5$s %3$s.%2$s.%4$s - %10$s %8$s.%7$s.%9$s</string>
+    <string name="wday1_date1_time1_wday2_date2_time2">%3$s %1$s, %2$s - %6$s %4$s, %5$s</string>
+    <string name="wday1_date1_wday2_date2">%1$s, %2$s - %4$s, %5$s</string>
+    <string name="date1_time1_date2_time2">%3$s %2$s - %6$s %5$s</string>
+    <string name="time_wday_date">%1$s %2$s, %3$s</string>
+    <string name="wday_date">%2$s, %3$s</string>
+    <string name="time_wday">%1$s %2$s</string>
+    <string name="same_year_md1_md2">%3$s %2$s - %8$s %7$s</string>
+    <string name="same_year_wday1_md1_wday2_md2">%1$s %2$s %3$s - %6$s %7$s %8$s</string>
+    <string name="same_year_md1_time1_md2_time2">%5$s %3$s %2$s - %10$s %8$s %7$s</string>
+    <string name="same_month_md1_time1_md2_time2">%5$s %3$s %2$s - %10$s %8$s %7$s</string>
+    <string name="same_year_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %2$s %3$s - %10$s %6$s %7$s %8$s</string>
+    <string name="same_month_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %2$s %3$s - %10$s %6$s %7$s %8$s</string>
+    <string name="same_year_mdy1_time1_mdy2_time2">%5$s %3$s %2$s %4$s - %10$s %8$s %7$s %9$s</string>
+    <string name="same_month_mdy1_time1_mdy2_time2">%5$s %3$s %2$s %4$s - %10$s %8$s %7$s %9$s</string>
+    <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %3$s, %2$s %4$s - %10$s %6$s, %8$s, %7$s %9$s</string>
+    <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %3$s, %2$s %4$s - %10$s %6$s, %8$s, %7$s %9$s</string>
+    <string name="same_month_wday1_mdy1_wday2_mdy2">%1$s, %3$s, %2$s %4$s - %6$s, %8$s, %7$s %9$s</string>
+    <string name="same_month_md1_md2">%3$s-%8$s %2$s</string>
+    <string name="same_month_wday1_md1_wday2_md2">%1$s %2$s %3$s - %6$s %7$s %8$s</string>
+    <string name="same_year_mdy1_mdy2">%3$s %2$s - %8$s %7$s %9$s</string>
+    <string name="same_month_mdy1_mdy2">%3$s-%8$s %2$s %9$s</string>
+    <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s, %3$s, %2$s - %6$s, %8$s, %7$s %9$s</string>
+    <string name="short_format_month">%b</string>
+    <string name="full_wday_month_day_no_year">E MMMM d</string>
+    <string name="abbrev_wday_month_day_year">E, d, MMM y</string>
+</resources>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 377b036..505e245 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -301,6 +301,8 @@
     <string name="permlab_readLogs" msgid="6615778543198967614">"مطالعه داده های گزارش حساس"</string>
     <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"به برنامه اجازه می‎دهد فایلهای مختلف گزارش سیستم را بخواند. با این کار، برنامه اطلاعات کلی مربوط به کاری که با رایانه لوحی انجام می‎دهید را کشف می کند، که ممکن است حاوی اطلاعات شخصی و خصوصی باشند."</string>
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"به برنامه اجازه می‎دهد تا فایلهای گزارش مختلف سیستم را بخواند. این کار به برنامه اجازه می‎دهد اطلاعات عمومی کاری که با تلفن انجام می‎دهید مثلا اطلاعات خصوصی و شخصی را کشف کند."</string>
+    <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"استفاده از هر رمزگشای رسانه‎ای برای بازپخش"</string>
+    <string name="permdesc_anyCodecForPlayback" msgid="2101444559995480174">"به یک برنامه اجازه می‌دهد تا از هر رمزگشای رسانه نصب شده برای رمزگشایی جهت بازپخش استفاده کند."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"خواندن/نوشتن منابع متعلق به تشخیص"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"به برنامه اجازه می‌دهد هر منبعی را که متعلق به گروه تشخیص است بخواند و در آن بنویسد؛ بعنوان مثال، فایل‌های /dev. این امر بصورت بالقوه می‌تواند بر پایدار بودن و امنیت سیستم تأثیر بگذارد. این تنها باید برای تشخیص‎‌های مختص سخت‌افزار توسط تولیدکننده یا اپراتور استفاده شود."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"فعال یا غیر فعال کردن اجزای برنامه"</string>
@@ -465,9 +467,9 @@
     <string name="permlab_bluetoothAdmin" msgid="3606576270792236062">"مدیریت بلوتوث"</string>
     <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"به برنامه اجازه می‎دهد تا رایانه لوحی بلوتوث محلی را پیکربندی کرده، دستگاههای راه دور را شناسایی کرده و با آنها جفت شود."</string>
     <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"به برنامه اجازه می‎دهد تا تلفن بلوتوث محلی را پیکربندی کند و دستگاههای راه دور را پیدا کند و با آنها جفت شود."</string>
-    <!-- outdated translation 2800410363171809280 -->     <string name="permlab_accessWimaxState" msgid="1232061307208861588">"مشاهده وضعیت WiMAX"</string>
+    <string name="permlab_accessWimaxState" msgid="1232061307208861588">"مشاهده وضعیت WiMAX"</string>
     <string name="permdesc_accessWimaxState" msgid="8298035866227524023">"به یک برنامه کاربردی امکان می دهد اطلاعات مربوط به وضعیت WiMAX را مشاهده کند."</string>
-    <!-- outdated translation 340465839241528618 -->     <string name="permlab_changeWimaxState" msgid="2405042267131496579">"تغییر وضعیت WiMAX"</string>
+    <string name="permlab_changeWimaxState" msgid="2405042267131496579">"تغییر وضعیت WiMAX"</string>
     <string name="permdesc_changeWimaxState" msgid="474918005058989421">"به یک برنامه کاربردی امکان می دهد به شبکه WiMAX متصل یا از آن قطع شود."</string>
     <string name="permlab_bluetooth" msgid="8361038707857018732">"ایجاد اتصال های بلوتوث"</string>
     <string name="permdesc_bluetooth" product="tablet" msgid="7007851048416363446">"به برنامه اجازه می‎دهد تا پیکربندی رایانه لوحی بلوتوث محلی را مشاهده کند و اتصال با دستگاههای جفت شده را برقرار کرده و بپذیرد."</string>
@@ -1219,4 +1221,7 @@
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"اشتراک‌گذاری با"</string>
     <string name="status_bar_device_locked" msgid="3092703448690669768">"دستگاه قفل است."</string>
     <string name="list_delimeter" msgid="3975117572185494152">"، "</string>
+    <string name="sending" msgid="8715108995741758718">"در حال ارسال..."</string>
+    <string name="launchBrowserDefault" msgid="2057951947297614725">"مرورگر راه‌اندازی شود؟"</string>
+    <string name="SetupCallDefault" msgid="6870275517518479651">"تماس را می‌پذیرید؟"</string>
 </resources>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 163bb1f..73910d3 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -301,6 +301,8 @@
     <string name="permlab_readLogs" msgid="6615778543198967614">"lukea arkaluonteisia lokitietoja"</string>
     <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"Antaa sovelluksen lukea järjestelmän lokitiedostoja. Näin sovellus saa yleisiä tietoja siitä, mitä teet tablet-laitteella, sekä mahdollisia yksityisiä tai arkaluonteisia tietoja."</string>
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Antaa sovelluksen lukea järjestelmän lokitiedostoja. Näin sovellus saa yleisiä tietoja siitä, mitä teet puhelimella, sekä mahdollisia yksityisiä tai arkaluonteisia tietoja."</string>
+    <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"käytä mitä tahansa tietovälineen koodin purkajaa toistoa varten"</string>
+    <string name="permdesc_anyCodecForPlayback" msgid="2101444559995480174">"Sallii sovelluksen käyttää mitä tahansa asennettua tietovälineen koodin purkajaa toistoa varten."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"lue diag:in omistamia resursseja / kirjoita resursseihin"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Antaa sovelluksen lukea ja kirjoittaa diag-ryhmän omistamiin resursseihin, esimerkiksi /dev-hakemistossa oleviin tiedostoihin. Tämä voi vaikuttaa järjestelmän vakauteen ja turvallisuuteen. Tämä lupa tulee myöntää VAIN valmistajan tai operaattorin laitteistotesteille."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"sovelluskomponenttien ottaminen käyttöön tai pois käytöstä"</string>
@@ -465,9 +467,9 @@
     <string name="permlab_bluetoothAdmin" msgid="3606576270792236062">"Bluetooth-hallinta"</string>
     <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"Antaa sovelluksen määrittää paikallisen Bluetooth-tabletin asetukset sekä tunnistaa muita laitteita ja muodostaa niiden kanssa laitepareja."</string>
     <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"Antaa sovelluksen määrittää paikallisen Bluetooth-puhelimen asetukset sekä tunnistaa muita laitteita ja muodostaa niiden kanssa laitepareja."</string>
-    <!-- outdated translation 2800410363171809280 -->     <string name="permlab_accessWimaxState" msgid="1232061307208861588">"tarkastele WiMAX-verkon tilaa"</string>
+    <string name="permlab_accessWimaxState" msgid="1232061307208861588">"Tarkastele WiMAX-verkon tilaa"</string>
     <string name="permdesc_accessWimaxState" msgid="8298035866227524023">"Antaa sovelluksen tarkastella WiMAX-verkon tilaa."</string>
-    <!-- outdated translation 340465839241528618 -->     <string name="permlab_changeWimaxState" msgid="2405042267131496579">"vaihda WiMAX-verkon tilaa"</string>
+    <string name="permlab_changeWimaxState" msgid="2405042267131496579">"Vaihda WiMAX-verkon tilaa"</string>
     <string name="permdesc_changeWimaxState" msgid="474918005058989421">"Antaa sovelluksen muodostaa yhteyden WiMAX-verkkoon ja katkaista yhteyden."</string>
     <string name="permlab_bluetooth" msgid="8361038707857018732">"luo Bluetooth-yhteyksiä"</string>
     <string name="permdesc_bluetooth" product="tablet" msgid="7007851048416363446">"Antaa sovelluksen tarkastella paikallisen Bluetooth-tabletin asetuksia sekä muodostaa ja hyväksyä laitepariyhteyksiä."</string>
@@ -1219,4 +1221,7 @@
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"Jaa seuraavien kanssa"</string>
     <string name="status_bar_device_locked" msgid="3092703448690669768">"Laite lukittu."</string>
     <string name="list_delimeter" msgid="3975117572185494152">", "</string>
+    <string name="sending" msgid="8715108995741758718">"Lähetetään..."</string>
+    <string name="launchBrowserDefault" msgid="2057951947297614725">"Käynnistetäänkö selain?"</string>
+    <string name="SetupCallDefault" msgid="6870275517518479651">"Vastataanko puheluun?"</string>
 </resources>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 7d2babf..d4e1b75 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -20,7 +20,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="byteShort" msgid="8340973892742019101">"O"</string>
+    <string name="byteShort" msgid="8340973892742019101">"o"</string>
     <string name="kilobyteShort" msgid="5973789783504771878">"Ko"</string>
     <string name="megabyteShort" msgid="6355851576770428922">"Mo"</string>
     <string name="gigabyteShort" msgid="3259882455212193214">"Go"</string>
@@ -290,7 +290,7 @@
     <string name="permlab_deleteCacheFiles" msgid="3128665571837408675">"vider le cache des autres applications"</string>
     <string name="permdesc_deleteCacheFiles" msgid="3812998599006730196">"Permet à l\'application de supprimer les fichiers du cache."</string>
     <string name="permlab_getPackageSize" msgid="7472921768357981986">"évaluer l\'espace de stockage de l\'application"</string>
-    <string name="permdesc_getPackageSize" msgid="3921068154420738296">"Permet à l\'application de récupérer la taille de son code, de ses données et de sa mémoire cache."</string>
+    <string name="permdesc_getPackageSize" msgid="3921068154420738296">"Permet à l\'application de récupérer son code, ses données et la taille de sa mémoire cache."</string>
     <string name="permlab_installPackages" msgid="2199128482820306924">"installer directement les applications"</string>
     <string name="permdesc_installPackages" msgid="5628530972548071284">"Permet à l\'application d\'installer des packages Android nouveaux ou mis à jour. Des applications malveillantes peuvent exploiter cette fonctionnalité pour ajouter de nouvelles applications à l\'aide d\'autorisations anormalement élevées."</string>
     <string name="permlab_clearAppCache" msgid="7487279391723526815">"supprimer toutes les données du cache de l\'application"</string>
@@ -301,6 +301,8 @@
     <string name="permlab_readLogs" msgid="6615778543198967614">"lire les données des journaux à caractère confidentiel"</string>
     <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"Permet à l\'application de lire les différents fichiers journaux du système afin d\'obtenir des informations générales sur la façon dont vous utilisez votre tablette. Celles-ci peuvent éventuellement inclure des informations d\'ordre personnel ou privé."</string>
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Permet à l\'application de lire les différents fichiers journaux du système afin d\'obtenir des informations générales sur la façon dont vous utilisez votre téléphone. Celles-ci peuvent éventuellement inclure des informations d\'ordre personnel ou privé."</string>
+    <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"utiliser n\'importe quel décodeur pour lire les fichiers multimédias"</string>
+    <string name="permdesc_anyCodecForPlayback" msgid="2101444559995480174">"Permet à une application d\'utiliser n\'importe quel décodeur installé pour lire les fichiers multimédias."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"Lecture/écriture dans les ressources appartenant aux diagnostics"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Permet à l\'application d\'obtenir des droits en lecture/écriture concernant toute ressource appartenant au groupe de diagnostics (par exemple, les fichiers du répertoire /dev). Ceci peut affecter la stabilité et la sécurité du système. Cette fonctionnalité est UNIQUEMENT réservée aux diagnostics matériels effectués par le fabricant ou l\'opérateur."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"activer ou désactiver les composants de l\'application"</string>
@@ -449,7 +451,7 @@
     <string name="permlab_createNetworkSockets" msgid="9121633680349549585">"Accès Internet complet"</string>
     <string name="permdesc_createNetworkSockets" msgid="5963922297444265950">"Permet à l\'application de créer des connecteurs réseau."</string>
     <string name="permlab_writeApnSettings" msgid="505660159675751896">"changer/intercepter les paramètres et le trafic du réseau"</string>
-    <string name="permdesc_writeApnSettings" msgid="5333798886412714193">"Permet à l\'application de modifier les paramètres réseau, ainsi que d\'intercepter et de surveiller tout le trafic réseau dans le but de modifier le proxy et le port d\'un APN, par exemple. Des applications malveillantes peuvent exploiter cette fonctionnalité pour surveiller, rediriger ou modifier les paquets réseau à votre insu."</string>
+    <string name="permdesc_writeApnSettings" msgid="5333798886412714193">"Permet à l\'application de modifier les paramètres réseau, ainsi que d\'intercepter et de surveiller tout le trafic réseau ayant pour but de modifier le proxy et le port d\'un APN, par exemple. Des applications malveillantes peuvent exploiter cette fonctionnalité pour surveiller, rediriger ou modifier les paquets réseau à votre insu."</string>
     <string name="permlab_changeNetworkState" msgid="958884291454327309">"Modification de la connectivité du réseau"</string>
     <string name="permdesc_changeNetworkState" msgid="6789123912476416214">"Permet à l\'application de modifier l\'état de la connectivité du réseau."</string>
     <string name="permlab_changeTetherState" msgid="5952584964373017960">"changer la connectivité du partage de connexion"</string>
@@ -465,9 +467,9 @@
     <string name="permlab_bluetoothAdmin" msgid="3606576270792236062">"gestion Bluetooth"</string>
     <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"Permet à l\'application de configurer la tablette Bluetooth locale, d\'identifier des appareils distants et de les associer à la tablette."</string>
     <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"Permet à l\'application de configurer le téléphone Bluetooth local, d\'identifier des appareils distants et de les associer au téléphone."</string>
-    <!-- outdated translation 2800410363171809280 -->     <string name="permlab_accessWimaxState" msgid="1232061307208861588">"afficher l\'état du WiMAX"</string>
+    <string name="permlab_accessWimaxState" msgid="1232061307208861588">"Afficher l\'état du WiMAX"</string>
     <string name="permdesc_accessWimaxState" msgid="8298035866227524023">"Permet à une application d\'afficher les informations concernant l\'état du WiMAX."</string>
-    <!-- outdated translation 340465839241528618 -->     <string name="permlab_changeWimaxState" msgid="2405042267131496579">"modifier l\'état du WiMAX"</string>
+    <string name="permlab_changeWimaxState" msgid="2405042267131496579">"Modifier l\'état du WiMAX"</string>
     <string name="permdesc_changeWimaxState" msgid="474918005058989421">"Permet à une application de se connecter au réseau WiMAX et de s\'en déconnecter."</string>
     <string name="permlab_bluetooth" msgid="8361038707857018732">"Création de connexions Bluetooth"</string>
     <string name="permdesc_bluetooth" product="tablet" msgid="7007851048416363446">"Permet à l\'application d\'obtenir la configuration de la tablette Bluetooth locale, de se connecter à des appareils associés et d\'accepter leur connexion."</string>
@@ -510,7 +512,7 @@
     <string name="policydesc_limitPassword" msgid="9083400080861728056">"Gérer le nombre et le type de caractères autorisés dans les mots de passe de déverrouillage de l\'écran"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Gérer les tentatives de déverrouillage de l\'écran"</string>
     <string name="policydesc_watchLogin" product="tablet" msgid="3215729294215070072">"Contrôler le nombre de mots de passe incorrects saisis pour le déverrouillage de l\'écran, puis verrouiller la tablette ou effacer toutes ses données si le nombre maximal de tentatives de saisie du mot de passe est atteint"</string>
-    <string name="policydesc_watchLogin" product="default" msgid="5712323091846761073">"Contrôler le nombre de mots de passe incorrects saisis pour le déverrouillage de l\'écran, puis verrouiller le téléphone ou effacer toutes ses données si le nombre maximal de tentatives de saisie du mot de passe est atteint"</string>
+    <string name="policydesc_watchLogin" product="default" msgid="5712323091846761073">"Contrôle le nombre de mots de passe incorrects saisis pour le déverrouillage de l\'écran, puis verrouille le téléphone ou efface toutes ses données si le nombre maximal de tentatives de saisie du mot de passe est atteint."</string>
     <string name="policylab_resetPassword" msgid="2620077191242688955">"Modifier le mot de passe de déverrouillage de l\'écran"</string>
     <string name="policydesc_resetPassword" msgid="5391240616981297361">"Modifier le mot de passe de déverrouillage de l\'écran"</string>
     <string name="policylab_forceLock" msgid="2274085384704248431">"Verrouiller l\'écran"</string>
@@ -875,7 +877,7 @@
     <string name="replace" msgid="5781686059063148930">"Remplacer..."</string>
     <string name="delete" msgid="6098684844021697789">"Supprimer"</string>
     <string name="copyUrl" msgid="2538211579596067402">"Copier l\'URL"</string>
-    <string name="selectTextMode" msgid="1018691815143165326">"Sélectionner le texte"</string>
+    <string name="selectTextMode" msgid="1018691815143165326">"Sélectionner texte"</string>
     <string name="textSelectionCABTitle" msgid="5236850394370820357">"Sélection de texte"</string>
     <string name="addToDictionary" msgid="9090375111134433012">"ajouter au dictionnaire"</string>
     <string name="deleteText" msgid="7070985395199629156">"supprimer"</string>
@@ -1014,7 +1016,7 @@
     <string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Connecté en tant que programme d\'installation"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Connecté à un accessoire USB"</string>
     <string name="usb_notification_message" msgid="4447869605109736382">"Appuyez pour accéder aux autres options USB."</string>
-    <string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"Formater la mémoire ?"</string>
+    <string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"Formater mémoire ?"</string>
     <string name="extmedia_format_title" product="default" msgid="3648415921526526069">"Formater la carte SD ?"</string>
     <string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"Tous les fichiers stockés sur la mémoire de stockage USB vont être effacés. Cette action est irréversible."</string>
     <string name="extmedia_format_message" product="default" msgid="14131895027543830">"Toutes les données stockées sur votre carte seront perdues."</string>
@@ -1219,4 +1221,7 @@
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"Partager avec"</string>
     <string name="status_bar_device_locked" msgid="3092703448690669768">"Appareil verrouillé"</string>
     <string name="list_delimeter" msgid="3975117572185494152">", "</string>
+    <string name="sending" msgid="8715108995741758718">"Envoi en cours…"</string>
+    <string name="launchBrowserDefault" msgid="2057951947297614725">"Lancer le navigateur ?"</string>
+    <string name="SetupCallDefault" msgid="6870275517518479651">"Prendre l\'appel ?"</string>
 </resources>
diff --git a/core/res/res/values-hi/donottranslate-cldr.xml b/core/res/res/values-hi/donottranslate-cldr.xml
new file mode 100644
index 0000000..d9405d8
--- /dev/null
+++ b/core/res/res/values-hi/donottranslate-cldr.xml
@@ -0,0 +1,149 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="month_long_standalone_january">जनवरी</string>
+    <string name="month_long_standalone_february">फरवरी</string>
+    <string name="month_long_standalone_march">मार्च</string>
+    <string name="month_long_standalone_april">अप्रैल</string>
+    <string name="month_long_standalone_may">मई</string>
+    <string name="month_long_standalone_june">जून</string>
+    <string name="month_long_standalone_july">जुलाई</string>
+    <string name="month_long_standalone_august">अगस्त</string>
+    <string name="month_long_standalone_september">सितम्बर</string>
+    <string name="month_long_standalone_october">अक्तूबर</string>
+    <string name="month_long_standalone_november">नवम्बर</string>
+    <string name="month_long_standalone_december">दिसम्बर</string>
+
+    <string name="month_long_january">जनवरी</string>
+    <string name="month_long_february">फरवरी</string>
+    <string name="month_long_march">मार्च</string>
+    <string name="month_long_april">अप्रैल</string>
+    <string name="month_long_may">मई</string>
+    <string name="month_long_june">जून</string>
+    <string name="month_long_july">जुलाई</string>
+    <string name="month_long_august">अगस्त</string>
+    <string name="month_long_september">सितम्बर</string>
+    <string name="month_long_october">अक्तूबर</string>
+    <string name="month_long_november">नवम्बर</string>
+    <string name="month_long_december">दिसम्बर</string>
+
+    <string name="month_medium_january">जनवरी</string>
+    <string name="month_medium_february">फरवरी</string>
+    <string name="month_medium_march">मार्च</string>
+    <string name="month_medium_april">अप्रैल</string>
+    <string name="month_medium_may">मई</string>
+    <string name="month_medium_june">जून</string>
+    <string name="month_medium_july">जुलाई</string>
+    <string name="month_medium_august">अगस्त</string>
+    <string name="month_medium_september">सितम्बर</string>
+    <string name="month_medium_october">अक्तूबर</string>
+    <string name="month_medium_november">नवम्बर</string>
+    <string name="month_medium_december">दिसम्बर</string>
+
+    <string name="month_shortest_january">ज</string>
+    <string name="month_shortest_february">फ़</string>
+    <string name="month_shortest_march">मा</string>
+    <string name="month_shortest_april">अ</string>
+    <string name="month_shortest_may">म</string>
+    <string name="month_shortest_june">जू</string>
+    <string name="month_shortest_july">जु</string>
+    <string name="month_shortest_august">अ</string>
+    <string name="month_shortest_september">सि</string>
+    <string name="month_shortest_october">अ</string>
+    <string name="month_shortest_november">न</string>
+    <string name="month_shortest_december">दि</string>
+
+    <string name="day_of_week_long_sunday">रविवार</string>
+    <string name="day_of_week_long_monday">सोमवार</string>
+    <string name="day_of_week_long_tuesday">मंगलवार</string>
+    <string name="day_of_week_long_wednesday">बुधवार</string>
+    <string name="day_of_week_long_thursday">गुरुवार</string>
+    <string name="day_of_week_long_friday">शुक्रवार</string>
+    <string name="day_of_week_long_saturday">शनिवार</string>
+
+    <string name="day_of_week_medium_sunday">रवि</string>
+    <string name="day_of_week_medium_monday">सोम</string>
+    <string name="day_of_week_medium_tuesday">मंगल</string>
+    <string name="day_of_week_medium_wednesday">बुध</string>
+    <string name="day_of_week_medium_thursday">गुरु</string>
+    <string name="day_of_week_medium_friday">शुक्र</string>
+    <string name="day_of_week_medium_saturday">शनि</string>
+
+    <string name="day_of_week_short_sunday">रवि</string>
+    <string name="day_of_week_short_monday">सोम</string>
+    <string name="day_of_week_short_tuesday">मंगल</string>
+    <string name="day_of_week_short_wednesday">बुध</string>
+    <string name="day_of_week_short_thursday">गुरु</string>
+    <string name="day_of_week_short_friday">शुक्र</string>
+    <string name="day_of_week_short_saturday">शनि</string>
+
+    <string name="day_of_week_shortest_sunday">र</string>
+    <string name="day_of_week_shortest_monday">सो</string>
+    <string name="day_of_week_shortest_tuesday">मं</string>
+    <string name="day_of_week_shortest_wednesday">बु</string>
+    <string name="day_of_week_shortest_thursday">गु</string>
+    <string name="day_of_week_shortest_friday">शु</string>
+    <string name="day_of_week_shortest_saturday">श</string>
+
+    <string name="am">AM</string>
+    <string name="pm">PM</string>
+    <string name="yesterday">Yesterday</string>
+    <string name="today">Today</string>
+    <string name="tomorrow">Tomorrow</string>
+
+    <string name="hour_minute_24">%-k:%M</string>
+    <string name="hour_minute_ampm">%-l:%M %p</string>
+    <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
+    <string name="twelve_hour_time_format">h:mm a</string>
+    <string name="twenty_four_hour_time_format">H:mm</string>
+    <string name="numeric_date">%-e-%-m-%Y</string>
+    <string name="numeric_date_format">d-M-yyyy</string>
+    <string name="numeric_date_template">"%s-%s-%s"</string>
+    <string name="month_day_year">%-e %B %Y</string>
+    <string name="time_of_day">%-l:%M:%S %p</string>
+    <string name="date_and_time">%-l:%M:%S %p %d-%m-%Y</string>
+    <string name="date_time">%2$s %1$s</string>
+    <string name="time_date">%1$s %3$s</string>
+    <string name="abbrev_month_day_year">%d-%m-%Y</string>
+    <string name="month_day">%-e %B</string>
+    <string name="month">%-B</string>
+    <string name="month_year">%B %Y</string>
+    <string name="abbrev_month_day">%-e %b</string>
+    <string name="abbrev_month">%-b</string>
+    <string name="abbrev_month_year">%b %Y</string>
+    <string name="time1_time2">%1$s – %2$s</string>
+    <string name="date1_date2">%2$s – %5$s</string>
+    <string name="numeric_md1_md2">%2$s-%3$s – %7$s-%8$s</string>
+    <string name="numeric_wday1_md1_wday2_md2">%1$s, %2$s-%3$s – %6$s, %7$s-%8$s</string>
+    <string name="numeric_mdy1_mdy2">%4$s-%2$s-%3$s – %9$s-%7$s-%8$s</string>
+    <string name="numeric_wday1_mdy1_wday2_mdy2">%1$s, %4$s-%2$s-%3$s – %6$s, %9$s-%7$s-%8$s</string>
+    <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %4$s-%2$s-%3$s – %10$s %6$s, %9$s-%7$s-%8$s</string>
+    <string name="numeric_md1_time1_md2_time2">%5$s %3$s/%2$s – %10$s %8$s/%7$s</string>
+    <string name="numeric_wday1_md1_time1_wday2_md2_time2">%5$s %1$s, %3$s/%2$s – %10$s %6$s, %8$s/%7$s</string>
+    <string name="numeric_mdy1_time1_mdy2_time2">%5$s %3$s-%2$s-%4$s – %10$s %8$s-%7$s-%9$s</string>
+    <string name="wday1_date1_time1_wday2_date2_time2">%3$s %1$s, %2$s – %6$s %4$s, %5$s</string>
+    <string name="wday1_date1_wday2_date2">%1$s, %2$s – %4$s, %5$s</string>
+    <string name="date1_time1_date2_time2">%3$s %2$s – %6$s %5$s</string>
+    <string name="time_wday_date">%1$s %2$s, %3$s</string>
+    <string name="wday_date">%2$s, %3$s</string>
+    <string name="time_wday">%1$s %2$s</string>
+    <string name="same_year_md1_md2">%3$s %2$s – %8$s %7$s</string>
+    <string name="same_year_wday1_md1_wday2_md2">%1$s, %3$s %2$s – %6$s, %8$s %7$s</string>
+    <string name="same_year_md1_time1_md2_time2">%5$s %3$s %2$s – %10$s %8$s %7$s</string>
+    <string name="same_month_md1_time1_md2_time2">%5$s %3$s %2$s – %10$s %8$s %7$s</string>
+    <string name="same_year_wday1_md1_time1_wday2_md2_time2">%5$s %1$s, %3$s %2$s – %10$s %6$s, %8$s %7$s</string>
+    <string name="same_month_wday1_md1_time1_wday2_md2_time2">%5$s %1$s, %3$s %2$s – %10$s %6$s, %8$s %7$s</string>
+    <string name="same_year_mdy1_time1_mdy2_time2">%5$s %4$s-%2$s-%3$s – %10$s %9$s-%7$s-%8$s</string>
+    <string name="same_month_mdy1_time1_mdy2_time2">%5$s %4$s-%2$s-%3$s – %10$s %9$s-%7$s-%8$s</string>
+    <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %3$s %2$s %4$s – %10$s %6$s, %8$s %7$s %9$s</string>
+    <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %3$s %2$s %4$s – %10$s %6$s, %8$s %7$s %9$s</string>
+    <string name="same_month_wday1_mdy1_wday2_mdy2">%1$s, %3$s %2$s %4$s – %6$s, %8$s %7$s %9$s</string>
+    <string name="same_month_md1_md2">%2$s-%3$s – %8$s</string>
+    <string name="same_month_wday1_md1_wday2_md2">%1$s, %3$s %2$s – %6$s, %8$s %7$s</string>
+    <string name="same_year_mdy1_mdy2">%9$s-%2$s-%3$s – %7$s-%8$s</string>
+    <string name="same_month_mdy1_mdy2">%9$s-%2$s-%3$s – %8$s</string>
+    <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s, %9$s-%2$s-%3$s – %6$s, yyyy-%7$s-%8$s</string>
+    <string name="short_format_month">%b</string>
+    <string name="full_wday_month_day_no_year">E, d MMMM</string>
+    <string name="abbrev_wday_month_day_year">EEE, d MMM y</string>
+</resources>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 367d704..9645451 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -195,7 +195,7 @@
     <string name="permlab_receiveEmergencyBroadcast" msgid="1803477660846288089">"आपातकालीन प्रसारण प्राप्त करें"</string>
     <string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"एप्लिकेशन को आपातकालीन प्रसारण संदेशों को प्राप्त करने और संसाधित करने देता है. यह अनुमति केवल सिस्टम एप्लिकेशन में उपलब्ध है."</string>
     <string name="permlab_sendSms" msgid="5600830612147671529">"SMS संदेश भेजें"</string>
-    <string name="permdesc_sendSms" msgid="906546667507626156">"एप्लिकेशन को SMS संदेशों को भेजने देता है. दुर्भावनापूर्ण एप्लिकेशन आपकी पुष्टि के बिना आपको संदेश भेजकर आप पर शुल्क लगा सकते हैं."</string>
+    <string name="permdesc_sendSms" msgid="906546667507626156">"एप्लिकेशन को SMS संदेशों को भेजने देता है. दुर्भावनापूर्ण एप्लिकेशन आपकी पुष्टि के बिना संदेश भेजकर आप पर शुल्क लगा सकते हैं."</string>
     <string name="permlab_sendSmsNoConfirmation" msgid="4781483105951730228">"बिना कि‍सी पुष्टि के SMS संदेश भेजें"</string>
     <string name="permdesc_sendSmsNoConfirmation" msgid="3437759207020400204">"एप्लिकेशन को SMS संदेशों को भेजने देता है. दुर्भावनापूर्ण एप्लिकेशन आपकी पुष्टि के बिना संदेशों को भेजकर आप पर शुल्क लगा सकते हैं."</string>
     <string name="permlab_readSms" msgid="4085333708122372256">"SMS या MMS पढ़ें"</string>
@@ -301,6 +301,8 @@
     <string name="permlab_readLogs" msgid="6615778543198967614">"संवेदनशील लॉग डेटा पढ़ें"</string>
     <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"किसी एप्‍लिकेशन को सिस्‍टम की विभिन्‍न लॉग फ़ाइलों से पढ़ने देता है. संभावित रूप से व्यक्तिगत या निजी जानकारी शामिल करते हुए, टेबलेट के साथ आप क्‍या कर रहे हैं इस बारे में सामान्‍य जानकारी खोजने देता है."</string>
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"एप्‍लिकेशन को सिस्‍टम की विभिन्‍न लॉग फ़ाइलें पढ़ने देता है. संभावित रूप से व्यक्तिगत या निजी जानकारी सहित, यह इसे इस बारे में सामान्य जानकारी खोजने देता है कि आप फ़ोन से क्‍या कर रहे हैं."</string>
+    <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"प्लेबैक के लिए किसी भी मीडिया डीकोडर का उपयोग करें"</string>
+    <string name="permdesc_anyCodecForPlayback" msgid="2101444559995480174">"एप्लिकेशन को प्लेबैक डीकोड करने के लिए, किसी भी इंस्टॉल किए गए डीकोडर का उपयोग करने देता है."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"निदान के स्‍वामित्‍व वाले संसाधनों को पढ़ें/लिखें"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"एप्‍लिकेशन को diag समूह के स्‍वामित्‍व वाले किसी संसाधन को पढ़ने और उसमें लिखने देता है; उदाहरण के लिए, /dev की फ़ाइलें. यह सिस्‍टम की स्‍थिरता और सुरक्षा को संभावित रूप से प्रभावित कर सकता है. इसका उपयोग निर्माता या ऑपरेटर द्वारा केवल हार्डवेयर-विशिष्ट निदान के लिए किया जाना चाहिए."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"एप्‍लिकेशन घटकों को सक्षम या अक्षम करें"</string>
@@ -372,7 +374,7 @@
     <string name="permlab_mount_unmount_filesystems" msgid="1761023272170956541">"फ़ाइलसिस्‍टम माउंट और अनमाउंट करें"</string>
     <string name="permdesc_mount_unmount_filesystems" msgid="1829290701658992347">"एप्‍लिकेशन को निकाले जाने योग्‍य संग्रहण के लिए फ़ाइल सिस्‍टम माउंट और अनमाउंट करने देता है."</string>
     <string name="permlab_mount_format_filesystems" msgid="5523285143576718981">"बाहरी संग्रहण प्रारूपित करें"</string>
-    <string name="permdesc_mount_format_filesystems" msgid="8784268246779198627">"एप्‍लिकेशन को निकालने योग्‍य संग्रहण फ़ॉर्मेट करने देता है."</string>
+    <string name="permdesc_mount_format_filesystems" msgid="8784268246779198627">"एप्‍लिकेशन को निकालने योग्‍य संग्रहण फ़ॉर्मेट करने देता है."</string>
     <string name="permlab_asec_access" msgid="3411338632002193846">"आंतरिक संग्रहण पर जानकारी प्राप्त करें"</string>
     <string name="permdesc_asec_access" msgid="3094563844593878548">"एप्लिकेशन को आंतरिक संग्रहण की जानकारी प्राप्‍त करने देता है."</string>
     <string name="permlab_asec_create" msgid="6414757234789336327">"आंतरिक संग्रहण बनाएं"</string>
@@ -412,7 +414,7 @@
     <string name="permdesc_readPhoneState" msgid="5127767618743602782">"एप्लिकेशन को उपकरण की फ़ोन सुविधाओं तक पहुंचने देता है. इस अनुमति वाला कोई एप्लिकेशन इस फ़ोन का फ़ोन नंबर और सीरियल नंबर बता सकता है, यह बता सकता है कि कोई कॉल चल रहा है, वह नंबर जिससे कॉल किया गया है और ऐसी ही अन्य जानकारी."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"टेबलेट को निष्‍क्रिय होने से रोकें"</string>
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"फ़ोन को निष्‍क्रिय होने से रोकें"</string>
-    <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"एप्लिकेशन को टैबलेट को निष्क्रिय हो जाने से रोकता है."</string>
+    <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"एप्लिकेशन को टेबलेट को निष्क्रिय हो जाने से रोकता है."</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"एप्लिकेशन को फ़ोन को निष्क्रिय होने से रोकता है."</string>
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"टेबलेट चालू या बंद करें"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"फ़ोन चालू या बंद करें"</string>
@@ -465,9 +467,9 @@
     <string name="permlab_bluetoothAdmin" msgid="3606576270792236062">"Bluetooth व्यवस्थापन"</string>
     <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"किसी एप्‍लिकेशन को स्‍थानीय Bluetooth टेबलेट कॉन्‍फ़िगर करने की और रिमोट उपकरणों के साथ खोजने और युग्‍मित करने देता है."</string>
     <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"एप्‍लिकेशन को स्‍थानीय Bluetooth फ़ोन कॉन्‍फ़िगर करने देता है, और रिमोट उपकरणों के साथ खोजने और युग्‍मित करने देता है."</string>
-    <!-- outdated translation 2800410363171809280 -->     <string name="permlab_accessWimaxState" msgid="1232061307208861588">"WiMAX स्‍थिति देखें"</string>
+    <string name="permlab_accessWimaxState" msgid="1232061307208861588">"WiMAX स्‍थिति देखें"</string>
     <string name="permdesc_accessWimaxState" msgid="8298035866227524023">"किसी एप्‍लिकेशन को WiMAX की स्‍थिति की जानकारी देखने की सुविधा देता है."</string>
-    <!-- outdated translation 340465839241528618 -->     <string name="permlab_changeWimaxState" msgid="2405042267131496579">"WiMAX स्‍थिति बदलें"</string>
+    <string name="permlab_changeWimaxState" msgid="2405042267131496579">"WiMAX स्‍थिति बदलें"</string>
     <string name="permdesc_changeWimaxState" msgid="474918005058989421">"किसी एप्लिकेशन को WiMAX नेटवर्क से कनेक्‍ट और डिस्‍कनेक्‍ट होने की सुविधा देता है."</string>
     <string name="permlab_bluetooth" msgid="8361038707857018732">"Bluetooth कनेक्‍शन बनाएं"</string>
     <string name="permdesc_bluetooth" product="tablet" msgid="7007851048416363446">"एप्‍लिकेशन को स्‍थानीय Bluetooth टेबलेट का कॉन्‍फ़िगरेशन देखने और युग्‍मित उपकरणों के साथ कनेक्‍शन बनाने और स्‍वीकार करने देता है."</string>
@@ -480,7 +482,7 @@
     <string name="permdesc_readSyncSettings" msgid="5464056785274229278">"एप्लिकेशन को समन्वयन सेटिंग पढ़ने देता है, जैसे लोग एप्लिकेशन के लिए समन्वयन सक्षम है या नहीं."</string>
     <string name="permlab_writeSyncSettings" msgid="6297138566442486462">"सिंक सेटिंग लिखें"</string>
     <string name="permdesc_writeSyncSettings" msgid="1466056564502117130">"एप्‍लिकेशन को समन्‍वयन सेटिंग संशोधित करने देता है, जैसे लोग एप्‍लिकेशन के लिए समन्‍वयन सक्षम है या नहीं."</string>
-    <string name="permlab_readSyncStats" msgid="7396577451360202448">"सिंक आंकड़े पढ़ें"</string>
+    <string name="permlab_readSyncStats" msgid="7396577451360202448">"सिंक आंकड़े पढ़ें"</string>
     <string name="permdesc_readSyncStats" msgid="3801971839939951678">"एप्‍लिकेशन को समन्वयन आंकड़े पढ़ने देता है; उदा. हो चुके समन्वयनों का इतिहास."</string>
     <string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"ग्राहकी-प्राप्त फ़ीड पढ़ें"</string>
     <string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"एप्‍लिकेशन को वर्तमान में समन्वयित फ़ीड के बारे में विवरण प्राप्त करने देता है."</string>
@@ -685,10 +687,10 @@
     <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"आपने अपना पिन <xliff:g id="NUMBER_0">%d</xliff:g> बार गलत तरीके से लिखा है. "\n\n"<xliff:g id="NUMBER_1">%d</xliff:g> सेकंड में पुनः प्रयास करें."</string>
     <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"आपने अपना अनलॉक प्रतिमान <xliff:g id="NUMBER_0">%d</xliff:g> बार गलत बनाया है. <xliff:g id="NUMBER_1">%d</xliff:g> और असफल प्रयासों के बाद, आपसे अपने Google साइन-इन का उपयोग करके आपके टेबलेट को अनलॉक करने को कहा जाएगा."\n\n" <xliff:g id="NUMBER_2">%d</xliff:g> सेकंड में पुन: प्रयास करें."</string>
     <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"आपने अपना अनलॉक प्रतिमान <xliff:g id="NUMBER_0">%d</xliff:g> बार गलत बनाया है. <xliff:g id="NUMBER_1">%d</xliff:g> और असफल प्रयासों के बाद, आपसे अपने Google साइन-इन का उपयोग करके आपके फ़ोन को अनलॉक करने को कहा जाएगा."\n\n" <xliff:g id="NUMBER_2">%d</xliff:g> सेकंड में पुन: प्रयास करें."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"आप गलत तरीके से टेबलेट को अनलॉक करने का प्रयास <xliff:g id="NUMBER_0">%d</xliff:g> बार कर चुके हैं. <xliff:g id="NUMBER_1">%d</xliff:g> और असफल प्रयास के बाद, टेबलेट फ़ैक्‍टरी डिफ़ॉल्‍ट पर रीसेट हो जाएगा और सभी उपयोगकर्ता डेटा खो जाएगा."</string>
-    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"आप गलत तरीके से फ़ोन को अनलॉक करने का प्रयास <xliff:g id="NUMBER_0">%d</xliff:g> बार कर चुके हैं. <xliff:g id="NUMBER_1">%d</xliff:g> और असफल प्रयास के बाद, फ़ोन फ़ैक्‍टरी डिफ़ॉल्‍ट पर रीसेट हो जाएगा और सभी उपयोगकर्ता डेटा खो जाएगा."</string>
-    <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"आप टेबलेट को गलत तरीके से <xliff:g id="NUMBER">%d</xliff:g> बार अनलॉक करने का प्रयास कर चुके हैं. टेबलेट अब फ़ैक्‍टरी डिफ़ॉल्‍ट पर रीसेट हो जाएगा."</string>
-    <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"आप फ़ोन को गलत तरीके से <xliff:g id="NUMBER">%d</xliff:g> बार अनलॉक करने का प्रयास कर चुके हैं. फ़ोन अब फ़ैक्‍टरी डिफ़ॉल्‍ट पर रीसेट हो जाएगा."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"आप गलत तरीके से टेबलेट को अनलॉक करने का प्रयास <xliff:g id="NUMBER_0">%d</xliff:g> बार कर चुके हैं. <xliff:g id="NUMBER_1">%d</xliff:g> और असफल प्रयास के बाद, टेबलेट फ़ैक्‍टरी डिफ़ॉल्‍ट पर रीसेट हो जाएगा और सभी उपयोगकर्ता डेटा खो जाएगा."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"आप गलत तरीके से फ़ोन को अनलॉक करने का प्रयास <xliff:g id="NUMBER_0">%d</xliff:g> बार कर चुके हैं. <xliff:g id="NUMBER_1">%d</xliff:g> और असफल प्रयास के बाद, फ़ोन फ़ैक्‍टरी डिफ़ॉल्‍ट पर रीसेट हो जाएगा और सभी उपयोगकर्ता डेटा खो जाएगा."</string>
+    <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"आप टेबलेट को गलत तरीके से <xliff:g id="NUMBER">%d</xliff:g> बार अनलॉक करने का प्रयास कर चुके हैं. टेबलेट अब फ़ैक्‍टरी डिफ़ॉल्‍ट पर रीसेट हो जाएगा."</string>
+    <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"आप फ़ोन को गलत तरीके से <xliff:g id="NUMBER">%d</xliff:g> बार अनलॉक करने का प्रयास कर चुके हैं. फ़ोन अब फ़ैक्‍टरी डिफ़ॉल्‍ट पर रीसेट हो जाएगा."</string>
     <string name="lockscreen_too_many_failed_attempts_countdown" msgid="6251480343394389665">"<xliff:g id="NUMBER">%d</xliff:g> सेकंड में पुन: प्रयास करें."</string>
     <string name="lockscreen_forgot_pattern_button_text" msgid="2626999449610695930">"प्रतिमान भूल गए?"</string>
     <string name="lockscreen_glogin_forgot_pattern" msgid="2588521501166032747">"खाता अनलॉक"</string>
@@ -742,8 +744,8 @@
     <string name="permlab_readHistoryBookmarks" msgid="1284843728203412135">"ब्राउज़र का इतिहास और बुकमार्क पढ़ें"</string>
     <string name="permdesc_readHistoryBookmarks" msgid="4577476392604595921">"एप्लिकेशन को ब्राउज़र द्वारा देखे गए सभी URL, और ब्राउज़र के सभी बुकमार्क पढ़ने देता है."</string>
     <string name="permlab_writeHistoryBookmarks" msgid="9009434109836280374">"ब्राउज़र का इतिहास और बुकमार्क लिखें"</string>
-    <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="1757103804824209530">"एप्लिकेशन को आपके टेबलेट में संग्रहीत ब्राउजर इतिहास या बुकमार्क को संशोधित करने देता है. दुर्भावनापूर्ण एप्लिकेशन इसका उपयोग आपके ब्राउजर डेटा को मिटाने या संशोधित करने के लिए कर सकते हैं."</string>
-    <string name="permdesc_writeHistoryBookmarks" product="default" msgid="6693764355720719197">"एप्लिकेशन को आपके फ़ोन में संग्रहीत ब्राउजर इतिहास या बुकमार्क को संशोधित करने देता है. दुर्भावनापूर्ण एप्लिकेशन इसका उपयोग आपके ब्राउजर डेटा को मिटाने या संशोधित करने के लिए कर सकते हैं."</string>
+    <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="1757103804824209530">"एप्लिकेशन को आपके टेबलेट में संग्रहीत ब्राउज़र इतिहास या बुकमार्क को संशोधित करने देता है. दुर्भावनापूर्ण एप्लिकेशन इसका उपयोग आपके ब्राउज़र डेटा को मिटाने या संशोधित करने के लिए कर सकते हैं."</string>
+    <string name="permdesc_writeHistoryBookmarks" product="default" msgid="6693764355720719197">"एप्लिकेशन को आपके फ़ोन में संग्रहीत ब्राउज़र इतिहास या बुकमार्क को संशोधित करने देता है. दुर्भावनापूर्ण एप्लिकेशन इसका उपयोग आपके ब्राउज़र डेटा को मिटाने या संशोधित करने के लिए कर सकते हैं."</string>
     <string name="permlab_setAlarm" msgid="5924401328803615165">"अलार्म क्लॉक में अलार्म सेट करें"</string>
     <string name="permdesc_setAlarm" msgid="316392039157473848">"एप्‍लिकेशन को इंस्‍टॉल किए गए अलार्म घड़ी एप्‍लिकेशन में अलार्म सेट करने देता है. हो सकता है कुछ अलार्म घड़ी एप्‍लिकेशन में यह सुविधा न हो."</string>
     <string name="permlab_addVoicemail" msgid="5525660026090959044">"ध्‍वनिमेल जोड़ें"</string>
@@ -961,7 +963,7 @@
     <!-- no translation found for wifi_available_sign_in_detailed (6797764740339907572) -->
     <skip />
     <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Wi-Fi से कनेक्‍ट नहीं हो सका"</string>
-    <string name="wifi_watchdog_network_disabled_detailed" msgid="4917472096696322767">" के पास एक कमज़ोर इंटरनेट कनेक्‍शन है."</string>
+    <string name="wifi_watchdog_network_disabled_detailed" msgid="4917472096696322767">" के पास एक कमज़ोर इंटरनेट कनेक्‍शन है."</string>
     <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi प्रत्यक्ष"</string>
     <string name="wifi_p2p_turnon_message" msgid="2804722042556269129">"Wi-Fi प्रत्‍यक्ष कार्यवाही प्रारंभ करें. इससे Wi-Fi क्‍लाइंट/हॉटस्पॉट कार्यवाही बंद हो जाएगी."</string>
     <string name="wifi_p2p_failed_message" msgid="1820097493844848281">"Wi-Fi प्रत्‍यक्ष प्रारंभ नहीं हो सका"</string>
@@ -985,7 +987,7 @@
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"समय सेट करें"</string>
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"दिनांक सेट करें"</string>
     <string name="date_time_set" msgid="5777075614321087758">"सेट करें"</string>
-    <string name="default_permission_group" msgid="2690160991405646128">"डिफ़ॉल्ट"</string>
+    <string name="default_permission_group" msgid="2690160991405646128">"डिफ़ॉल्ट"</string>
     <string name="no_permissions" msgid="7283357728219338112">"किसी अनुमति की आवश्‍यकता नहीं है"</string>
     <string name="perms_hide" msgid="7283915391320676226"><b>"छुपाएं"</b></string>
     <string name="perms_show_all" msgid="2671791163933091180"><b>"सभी दिखाएं"</b></string>
@@ -1014,7 +1016,7 @@
     <string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"किसी इंस्‍टॉलर के रूप में कनेक्‍ट किया गया"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB सहायक सामग्री से कनेक्‍ट कि‍या गया"</string>
     <string name="usb_notification_message" msgid="4447869605109736382">"अन्‍य USB विकल्‍पों के लिए स्पर्श करें"</string>
-    <string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"USB संग्रहण फ़ॉर्मेट करें?"</string>
+    <string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"USB संग्रहण फ़ॉर्मेट करें?"</string>
     <string name="extmedia_format_title" product="default" msgid="3648415921526526069">"SD कार्ड प्रारूपित करें?"</string>
     <string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"आपके USB संग्रहण में संग्रहीत सभी फ़ाइलें मिट जाएंगी. यह क्रिया पूर्ववत नहीं की जा सकती!"</string>
     <string name="extmedia_format_message" product="default" msgid="14131895027543830">"आपके कार्ड का सभी डेटा खो जाएगा."</string>
@@ -1130,7 +1132,7 @@
     <string name="sync_undo_deletes" msgid="8610996708225006328">"हटाए गए को पूर्ववत करें."</string>
     <string name="sync_do_nothing" msgid="8717589462945226869">"अभी कुछ न करें."</string>
     <string name="choose_account_label" msgid="5655203089746423927">"कोई खाता चुनें"</string>
-    <string name="add_account_label" msgid="2935267344849993553">"कोई खाता जोड़ें"</string>
+    <string name="add_account_label" msgid="2935267344849993553">"कोई खाता जोड़ें"</string>
     <string name="choose_account_text" msgid="6891230675141555481">"आप किस खाते का उपयोग करना चाहेंगे?"</string>
     <string name="add_account_button_label" msgid="3611982894853435874">"खाता जोड़ें"</string>
     <string name="number_picker_increment_button" msgid="4830170763103463443">"वृद्धि"</string>
@@ -1219,4 +1221,7 @@
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"इसके साथ साझा करें:"</string>
     <string name="status_bar_device_locked" msgid="3092703448690669768">"उपकरण लॉक कर दिया गया."</string>
     <string name="list_delimeter" msgid="3975117572185494152">", "</string>
+    <string name="sending" msgid="8715108995741758718">"भेज रहा है..."</string>
+    <string name="launchBrowserDefault" msgid="2057951947297614725">"ब्राउज़र लॉन्च करें?"</string>
+    <string name="SetupCallDefault" msgid="6870275517518479651">"कॉल स्वीकार करें?"</string>
 </resources>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 3d5f8d0..813e89a 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -301,6 +301,8 @@
     <string name="permlab_readLogs" msgid="6615778543198967614">"čitaj osjetljive podatke dnevnika"</string>
     <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"Aplikaciji omogućuje čitanje raznih sistemskih datoteka dnevnika. Tako može otkriti opće informacije o tome što radite na tabletnom računalu, što potencijalno uključuje osobne ili privatne informacije."</string>
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Aplikaciji omogućuje čitanje raznih sistemskih datoteka zapisnika. Tako može otkriti opće informacije o tome što radite na telefonu, što potencijalno uključuje osobne ili privatne informacije."</string>
+    <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"upotrijebi bilo koji dekoder za reprodukciju"</string>
+    <string name="permdesc_anyCodecForPlayback" msgid="2101444559995480174">"Aplikaciji omogućuje upotrebu svih instaliranih dekodera za dekodiranje medija radi reprodukcije."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"pisanje/čitanje u resursima čije je vlasnik dijagnostika"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Aplikaciji omogućuje čitanje i pisanje na bilo koji resurs u vlasništvu dijag. grupe; na primjer, datoteke u sustavu /dev. To bi moglo utjecati na stabilnost sustava i sigurnost. Dozvolu bi trebao upotrebljavati proizvođač ili operater SAMO za dijagnostiku koja se odnosi na hardver."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"omogućavanje ili onemogućavanje komponenti aplikacije"</string>
@@ -465,9 +467,9 @@
     <string name="permlab_bluetoothAdmin" msgid="3606576270792236062">"Bluetooth administracija"</string>
     <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"Aplikaciji omogućuje konfiguraciju lokalnog tabletnog računala s Bluetoothom te otkrivanje i uparivanje s udaljenim  uređajima."</string>
     <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"Aplikaciji omogućuje konfiguraciju lokalnog Bluetooth telefona i otkrivanje i uparivanje s udaljenim uređajima."</string>
-    <!-- outdated translation 2800410363171809280 -->     <string name="permlab_accessWimaxState" msgid="1232061307208861588">"prikaz stanja WiMAX mreže"</string>
+    <string name="permlab_accessWimaxState" msgid="1232061307208861588">"Prikaz stanja WiMAX mreže"</string>
     <string name="permdesc_accessWimaxState" msgid="8298035866227524023">"Aplikaciji omogućuje prikaz informacija o stanju WiMAX mreže."</string>
-    <!-- outdated translation 340465839241528618 -->     <string name="permlab_changeWimaxState" msgid="2405042267131496579">"promjena stanja WiMAX mreže"</string>
+    <string name="permlab_changeWimaxState" msgid="2405042267131496579">"Promjena stanja WiMAX mreže"</string>
     <string name="permdesc_changeWimaxState" msgid="474918005058989421">"Omogućuje aplikaciji povezivanje i prekid veze s WiMAX mrežom."</string>
     <string name="permlab_bluetooth" msgid="8361038707857018732">"stvaranje Bluetooth veza"</string>
     <string name="permdesc_bluetooth" product="tablet" msgid="7007851048416363446">"Aplikaciji omogućuje pregled konfiguracije lokalnog Bluetooth tabletnog računala i uspostavljanje i prihvaćanje veza s uparenim uređajima."</string>
@@ -1219,4 +1221,7 @@
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"Dijeljenje s"</string>
     <string name="status_bar_device_locked" msgid="3092703448690669768">"Uređaj zaključan."</string>
     <string name="list_delimeter" msgid="3975117572185494152">", "</string>
+    <string name="sending" msgid="8715108995741758718">"Slanje u tijeku..."</string>
+    <string name="launchBrowserDefault" msgid="2057951947297614725">"Pokrenuti preglednik?"</string>
+    <string name="SetupCallDefault" msgid="6870275517518479651">"Prihvatiti poziv?"</string>
 </resources>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index f1a2ca1..02c113c 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -301,11 +301,13 @@
     <string name="permlab_readLogs" msgid="6615778543198967614">"érzékeny naplóadatok olvasása"</string>
     <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"Lehetővé teszi az alkalmazás számára, hogy olvassa a rendszer különböző naplófájljait. Ezáltal általános információkat deríthet ki arról, hogy mire használja a táblagépét, valamint személyes, magánjellegű adatokhoz is hozzájuthat."</string>
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Lehetővé teszi az alkalmazás számára, hogy olvassa a rendszer különböző naplófájljait. Ezáltal általános információkat deríthet ki arról, hogy mire használja a telefonját, valamint személyes, magánjellegű adatokhoz is hozzájuthat."</string>
+    <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"bármely médiadekóder használata lejátszáshoz"</string>
+    <string name="permdesc_anyCodecForPlayback" msgid="2101444559995480174">"Lehetővé teszi egy alkalmazás számára bármely telepített médiadekóder használatát a lejátszás dekódolásához."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"a diag tulajdonában lévő erőforrások olvasása és írása"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Lehetővé teszi egy alkalmazás számára, hogy olvassa és írja a diagnosztikai csoport minden erőforrását, például a /dev könyvtárban lévő fájlokat. Ez potenciálisan befolyásolhatja a rendszer stabilitását és biztonságát, ezért CSAK a gyártó vagy a szolgáltató használhatja hardverspecifikus diagnosztizálásra."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"alkalmazáskomponensek be- és kikapcsolása"</string>
-    <string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Lehetővé teszi az alkalmazás számára annak módosítását, hogy más alkalmazások komponensei engedélyezve vannak-e vagy sem. A rosszindulatú alkalmazások ezt a táblagép fontos képességeinek kikapcsolására használhatják. Óvatosan kell eljárni az engedély megadásával, mert lehetséges, hogy a komponensek használhatatlanok, inkonzisztensek vagy instabil állapotúak lesznek."</string>
-    <string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Lehetővé teszi az alkalmazás számára annak módosítását, hogy más alkalmazások komponensei engedélyezve vannak-e vagy sem. A rosszindulatú alkalmazások ezt a telefon fontos képességeinek kikapcsolására használhatják. Óvatosan kell eljárni az engedély megadásával, mert lehetséges, hogy a komponensek használhatatlanok, inkonzisztensek vagy instabil állapotúak lesznek."</string>
+    <string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Lehetővé teszi az alkalmazás számára annak módosítását, hogy más alkalmazások komponensei engedélyezve vannak-e vagy sem. A rosszindulatú alkalmazások ezt a táblagép fontos funkcióinak kikapcsolására használhatják. Óvatosan kell eljárni az engedély megadásával, mert lehetséges, hogy a komponensek használhatatlanok, inkonzisztensek vagy instabilak lesznek."</string>
+    <string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Lehetővé teszi az alkalmazás számára annak módosítását, hogy más alkalmazások komponensei engedélyezve vannak-e vagy sem. A rosszindulatú alkalmazások ezt a telefon fontos funkcióinak kikapcsolására használhatják. Óvatosan kell eljárni az engedély megadásával, mert lehetséges, hogy a komponensek használhatatlanok, inkonzisztensek vagy instabilak lesznek."</string>
     <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"előnyben részesített alkalmazások beállítása"</string>
     <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Lehetővé teszi az alkalmazás számára a preferált alkalmazások módosítását. A rosszindulatú alkalmazások ezáltal észrevétlenül megváltoztathatják a futó alkalmazásokat, személyes adatokat gyűjtve Öntől."</string>
     <string name="permlab_writeSettings" msgid="1365523497395143704">"rendszer globális beállításainak módosítása"</string>
@@ -331,7 +333,7 @@
     <string name="permlab_writeProfile" msgid="4679878325177177400">"írás a profiladatokba"</string>
     <string name="permdesc_writeProfile" product="default" msgid="4637366723793045603">"Lehetővé teszi az alkalmazás számára a készüléken tárolt személyes profiladatok, például a név és elérhetőség módosítását vagy hozzáadását. Ez azt jelenti, hogy más alkalmazások is azonosíthatják Önt, és elküldhetik másoknak a profiladatait."</string>
     <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"közösségi adatfolyam olvasása"</string>
-    <string name="permdesc_readSocialStream" product="default" msgid="3419050808547335320">"Lehetővé teszi az alkalmazás számára, hogy hozzáférjen közösségi frissítéseihez, és szinkronizálja azokat. Rosszindulatú alkalmazások használhatják ezt, hogy hozzáférjenek barátaival történő magánbeszélgetéseihez a közösségi hálózatokon."</string>
+    <string name="permdesc_readSocialStream" product="default" msgid="3419050808547335320">"Lehetővé teszi az alkalmazás számára, hogy hozzáférjen közösségi frissítéseihez, és szinkronizálja azokat. Rosszindulatú alkalmazások arra használhatják ezt, hogy hozzáférjenek barátaival történő magánbeszélgetéseihez a közösségi hálózatokon."</string>
     <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"írás a közösség adatfolyamra"</string>
     <string name="permdesc_writeSocialStream" product="default" msgid="3496277176955721451">"Lehetővé teszi az alkalmazás számára, hogy megjelenítse barátai közösségi frissítéseit. A rosszindulatú alkalmazások ismerősnek tettethetik magukat, hogy jelszavakat és más bizalmas információt csaljanak ki Öntől."</string>
     <string name="permlab_readCalendar" msgid="5972727560257612398">"naptári események és bizalmas információk beolvasása"</string>
@@ -356,7 +358,7 @@
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"keretpuffer olvasása"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Lehetővé teszi az alkalmazás számára a keretpuffer tartalmának olvasását."</string>
     <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"hangbeállítások módosítása"</string>
-    <string name="permdesc_modifyAudioSettings" msgid="7343951185408396919">"Lehetővé teszi az alkalmazás számára a globális hangbeállítások, például a hangerő és az útválasztás módosítását."</string>
+    <string name="permdesc_modifyAudioSettings" msgid="7343951185408396919">"Lehetővé teszi az alkalmazás számára az általános hangbeállítások, például a hangerő és az útválasztás módosítását."</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"hanganyag rögzítése"</string>
     <string name="permdesc_recordAudio" msgid="2387462233976248635">"Lehetővé teszi az alkalmazás számára a hozzáférést a hangfelvétel elérési útjához."</string>
     <string name="permlab_camera" msgid="3616391919559751192">"fotók és videók készítése"</string>
@@ -439,7 +441,7 @@
     <string name="permdesc_getAccounts" product="tablet" msgid="3238360555257773358">"Lehetővé teszi az alkalmazás számára, hogy lekérje a táblagép által ismert fiókok listáját."</string>
     <string name="permdesc_getAccounts" product="default" msgid="2735689364629830348">"Lehetővé teszi az alkalmazás számára, hogy lekérje a telefon által ismert fiókok listáját."</string>
     <string name="permlab_authenticateAccounts" msgid="3940505577982882450">"fiókhitelesítőként szereplés"</string>
-    <string name="permdesc_authenticateAccounts" msgid="5472124296908977260">"Lehetővé teszi az alkalmazás számára, hogy használja a Fiókkezelő fiókhitelesítő képességeit, beleértve a fiókok létrehozását, illetve jelszavuk lekérdezését és beállítását."</string>
+    <string name="permdesc_authenticateAccounts" msgid="5472124296908977260">"Lehetővé teszi az alkalmazás számára, hogy használja a Fiókkezelő fiókhitelesítő funkcióit, beleértve a fiókok létrehozását, illetve jelszavuk lekérdezését és beállítását."</string>
     <string name="permlab_manageAccounts" msgid="4440380488312204365">"fióklista kezelése"</string>
     <string name="permdesc_manageAccounts" msgid="8698295625488292506">"Lehetővé teszi az alkalmazás számára olyan műveletek végrehajtását, mint a fiókok hozzáadása és eltávolítása, illetve a jelszavuk törlése."</string>
     <string name="permlab_useCredentials" msgid="6401886092818819856">"egy fiók bejelentkezési adatainak használata"</string>
@@ -461,13 +463,13 @@
     <string name="permlab_changeWifiState" msgid="7280632711057112137">"Wi-Fi állapot módosítása"</string>
     <string name="permdesc_changeWifiState" msgid="7399961004537946240">"Lehetővé teszi az alkalmazás számára, hogy kapcsolódjon Wi-Fi hozzáférési pontokhoz, és megszüntesse a kapcsolatot, valamint hogy módosítsa a beállított Wi-Fi hálózatokat."</string>
     <string name="permlab_changeWifiMulticastState" msgid="1368253871483254784">"Wi-Fi multicast vétel engedélyezése"</string>
-    <string name="permdesc_changeWifiMulticastState" msgid="7633598524564320817">"Lehetővé teszi az alkalmazás számára a nem közvetlenül a készüléknek címzett csomagok fogadását. Ez hasznos lehet a közelben kínált szolgáltatások felfedezésére. Több energiát használ, mint a nem multicast üzemmód."</string>
+    <string name="permdesc_changeWifiMulticastState" msgid="7633598524564320817">"Lehetővé teszi az alkalmazás számára a nem közvetlenül a készüléknek címzett csomagok fogadását. Ez hasznos lehet a közelben kínált szolgáltatások felfedezésére. Több energiát használ, mint a nem többirányú üzemmód."</string>
     <string name="permlab_bluetoothAdmin" msgid="3606576270792236062">"Bluetooth-adminisztráció"</string>
     <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"Lehetővé teszi az alkalmazás számára, hogy konfigurálja a helyi Bluetooth-t, valamint hogy távoli eszközöket fedezzen fel és párosítson."</string>
     <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"Lehetővé teszi az alkalmazás számára, hogy konfigurálja a helyi Bluetooth telefont, valamint hogy távoli eszközöket fedezzen fel és párosítson."</string>
-    <!-- outdated translation 2800410363171809280 -->     <string name="permlab_accessWimaxState" msgid="1232061307208861588">"WiMAX-állapot megtekintése"</string>
+    <string name="permlab_accessWimaxState" msgid="1232061307208861588">"WiMAX-állapot megtekintése"</string>
     <string name="permdesc_accessWimaxState" msgid="8298035866227524023">"Lehetővé teszi az alkalmazás számára a WiMAX állapotinformációk megtekintését."</string>
-    <!-- outdated translation 340465839241528618 -->     <string name="permlab_changeWimaxState" msgid="2405042267131496579">"WiMAX-állapot módosítása"</string>
+    <string name="permlab_changeWimaxState" msgid="2405042267131496579">"WiMAX-állapot módosítása"</string>
     <string name="permdesc_changeWimaxState" msgid="474918005058989421">"Lehetővé teszi, hogy egy alkalmazás csatlakozzon a WiMAX hálózathoz, illetve megszüntesse a kapcsolatot a hálózattal."</string>
     <string name="permlab_bluetooth" msgid="8361038707857018732">"Bluetooth kapcsolatok létrehozása"</string>
     <string name="permdesc_bluetooth" product="tablet" msgid="7007851048416363446">"Lehetővé teszi az alkalmazás számára a helyi Bluetooth táblagép konfigurációjának megtekintését, valamint kapcsolatok kezdeményezését és fogadását a párosított eszközökkel."</string>
@@ -657,7 +659,7 @@
     <string name="lockscreen_emergency_call" msgid="5347633784401285225">"Segélyhívás"</string>
     <string name="lockscreen_return_to_call" msgid="5244259785500040021">"Hívás folytatása"</string>
     <string name="lockscreen_pattern_correct" msgid="9039008650362261237">"Helyes!"</string>
-    <string name="lockscreen_pattern_wrong" msgid="4317955014948108794">"Újrapróbálás"</string>
+    <string name="lockscreen_pattern_wrong" msgid="4317955014948108794">"Próbálja újra"</string>
     <string name="lockscreen_password_wrong" msgid="5737815393253165301">"Újra"</string>
     <string name="lockscreen_plugged_in" msgid="8057762828355572315">"Töltés (<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>)"</string>
     <string name="lockscreen_charged" msgid="4938930459620989972">"Feltöltve."</string>
@@ -680,7 +682,7 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Nézze meg a felhasználói útmutatót, vagy vegye fel a kapcsolatot az ügyfélszolgálattal."</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"A SIM-kártya le van zárva."</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"SIM-kártya feloldása..."</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"<xliff:g id="NUMBER_0">%d</xliff:g> alkalommal rosszul rajzolta le feloldási mintáját. "\n\n"Kérjük, <xliff:g id="NUMBER_1">%d</xliff:g> másodperc múlva próbálja újra."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"<xliff:g id="NUMBER_0">%d</xliff:g> alkalommal rosszul rajzolta le feloldási mintát. "\n\n"Kérjük, <xliff:g id="NUMBER_1">%d</xliff:g> másodperc múlva próbálja újra."</string>
     <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Ön helytelenül adta meg a jelszót <xliff:g id="NUMBER_0">%d</xliff:g> alkalommal. "\n" "\n" Próbálja újra <xliff:g id="NUMBER_1">%d</xliff:g> másodperc múlva."</string>
     <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Ön <xliff:g id="NUMBER_0">%d</xliff:g> alkalommal helytelenül adta meg PIN kódját. "\n" "\n" Próbálja újra <xliff:g id="NUMBER_1">%d</xliff:g> másodperc múlva."</string>
     <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Helytelenül rajzolta le a feloldási mintát <xliff:g id="NUMBER_0">%d</xliff:g> alkalommal. További <xliff:g id="NUMBER_1">%d</xliff:g> sikertelen kísérlet után a Google rendszerében használt bejelentkezési adataival kell feloldania a táblagépét."\n\n" Kérjük, próbálja újra <xliff:g id="NUMBER_2">%d</xliff:g> másodperc múlva."</string>
@@ -902,10 +904,10 @@
     <string name="aerr_application" msgid="932628488013092776">"A(z) <xliff:g id="APPLICATION">%1$s</xliff:g> alkalmazás sajnos leállt."</string>
     <string name="aerr_process" msgid="4507058997035697579">"Sajnos a(z) <xliff:g id="PROCESS">%1$s</xliff:g> folyamat leállt."</string>
     <string name="anr_title" msgid="4351948481459135709"></string>
-    <string name="anr_activity_application" msgid="1904477189057199066">"A(z) <xliff:g id="APPLICATION">%2$s</xliff:g> nem válaszol."\n\n"Be szeretné zárni?"</string>
-    <string name="anr_activity_process" msgid="5776209883299089767">"A(z) <xliff:g id="ACTIVITY">%1$s</xliff:g> tevékenység nem válaszol."\n\n"Be szeretné zárni?"</string>
-    <string name="anr_application_process" msgid="8941757607340481057">"A(z) <xliff:g id="APPLICATION">%1$s</xliff:g> alkalmazás nem válaszol. Be szeretné zárni?"</string>
-    <string name="anr_process" msgid="6513209874880517125">"A(z) <xliff:g id="PROCESS">%1$s</xliff:g> folyamat nem válaszol. "\n\n"Be szeretné zárni?"</string>
+    <string name="anr_activity_application" msgid="1904477189057199066">"A(z) <xliff:g id="APPLICATION">%2$s</xliff:g> nem válaszol."\n\n"Szeretné bezárni?"</string>
+    <string name="anr_activity_process" msgid="5776209883299089767">"A(z) <xliff:g id="ACTIVITY">%1$s</xliff:g> tevékenység nem válaszol."\n\n"Szeretné bezárni?"</string>
+    <string name="anr_application_process" msgid="8941757607340481057">"A(z) <xliff:g id="APPLICATION">%1$s</xliff:g> alkalmazás nem válaszol. Szeretné bezárni?"</string>
+    <string name="anr_process" msgid="6513209874880517125">"A(z) <xliff:g id="PROCESS">%1$s</xliff:g> folyamat nem válaszol. "\n\n"Szeretné bezárni?"</string>
     <string name="force_close" msgid="8346072094521265605">"OK"</string>
     <string name="report" msgid="4060218260984795706">"Jelentés"</string>
     <string name="wait" msgid="7147118217226317732">"Várakozás"</string>
@@ -923,7 +925,7 @@
     <string name="android_upgrading_complete" msgid="1405954754112999229">"Rendszerindítás befejezése."</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> fut"</string>
     <string name="heavy_weight_notification_detail" msgid="1721681741617898865">"Érintse meg az alkalmazásra váltáshoz"</string>
-    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"Váltás az alkalmazások között?"</string>
+    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"Átvált az alkalmazások között?"</string>
     <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"Már fut egy másik alkalmazás, amelyet le kell állítania, mielőtt egy újat indíthatna el."</string>
     <string name="old_app_action" msgid="493129172238566282">"Visszatérés a(z) <xliff:g id="OLD_APP">%1$s</xliff:g> alkalmazáshoz"</string>
     <string name="old_app_description" msgid="2082094275580358049">"Ne indítsa el az új alkalmazást."</string>
@@ -1016,7 +1018,7 @@
     <string name="usb_notification_message" msgid="4447869605109736382">"Érintse meg a további USB-opciókért"</string>
     <string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"USB-tár formázása?"</string>
     <string name="extmedia_format_title" product="default" msgid="3648415921526526069">"SD-kártya formázása?"</string>
-    <string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"Minden, az USB-háttértáron tárolt fájl törlődik. Ez a művelet nem visszavonható!"</string>
+    <string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"Az USB-háttértáron tárolt összes fájl törlésre kerül. Ez a művelet nem visszavonható!"</string>
     <string name="extmedia_format_message" product="default" msgid="14131895027543830">"A kártyán lévő összes adat elvész."</string>
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"Formázás"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB hibakereső csatlakoztatva"</string>
@@ -1219,4 +1221,7 @@
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"Megosztás"</string>
     <string name="status_bar_device_locked" msgid="3092703448690669768">"Az eszköz le van zárva."</string>
     <string name="list_delimeter" msgid="3975117572185494152">", "</string>
+    <string name="sending" msgid="8715108995741758718">"Küldés..."</string>
+    <string name="launchBrowserDefault" msgid="2057951947297614725">"Böngésző indítása?"</string>
+    <string name="SetupCallDefault" msgid="6870275517518479651">"Hívás fogadása?"</string>
 </resources>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index d651d1d..cdbc667 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -301,6 +301,8 @@
     <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="permlab_anyCodecForPlayback" msgid="715805555823881818">"menggunakan media pengawasandi apa pun untuk pemutaran"</string>
+    <string name="permdesc_anyCodecForPlayback" msgid="2101444559995480174">"Mengizinkan aplikasi 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="permlab_changeComponentState" msgid="6335576775711095931">"mengaktifkan atau menonaktifkan komponen apl"</string>
@@ -444,7 +446,7 @@
     <string name="permdesc_manageAccounts" msgid="8698295625488292506">"Mengizinkan apl melakukan operasi seperti menambah dan menghapus akun, serta menghapus sandinya."</string>
     <string name="permlab_useCredentials" msgid="6401886092818819856">"gunakan kredensial autentikasi dari suatu akun"</string>
     <string name="permdesc_useCredentials" msgid="7984227147403346422">"Mengizinkan apl meminta token autentikasi."</string>
-    <string name="permlab_accessNetworkState" msgid="6865575199464405769">"lihat kondisi jaringan"</string>
+    <string name="permlab_accessNetworkState" msgid="6865575199464405769">"melihat keadaan jaringan"</string>
     <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>
@@ -465,9 +467,9 @@
     <string name="permlab_bluetoothAdmin" msgid="3606576270792236062">"Administrasi Bluetooth"</string>
     <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"Mengizinkan apl mengonfigurasi tablet Bluetooth lokal, dan menemukan serta menyandingkan dengan perangkat jarak jauh."</string>
     <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"Mengizinkan apl mengonfigurasi ponsel Bluetooth lokal, dan menemukan serta menyandingkan dengan perangkat jarak jauh."</string>
-    <!-- outdated translation 2800410363171809280 -->     <string name="permlab_accessWimaxState" msgid="1232061307208861588">"lihat status WiMAX"</string>
+    <string name="permlab_accessWimaxState" msgid="1232061307208861588">"Lihat status WiMAX"</string>
     <string name="permdesc_accessWimaxState" msgid="8298035866227524023">"Mengizinkan aplikasi melihat informasi tentang status WiMAX."</string>
-    <!-- outdated translation 340465839241528618 -->     <string name="permlab_changeWimaxState" msgid="2405042267131496579">"Ganti status WiMAX"</string>
+    <string name="permlab_changeWimaxState" msgid="2405042267131496579">"Ubah status WiMAX"</string>
     <string name="permdesc_changeWimaxState" msgid="474918005058989421">"Mengizinkan aplikasi menyambung ke dan memutus dari jaringan WiMAX."</string>
     <string name="permlab_bluetooth" msgid="8361038707857018732">"buat sambungan Bluetooth"</string>
     <string name="permdesc_bluetooth" product="tablet" msgid="7007851048416363446">"Mengizinkan apl melihat konfigurasi tablet Bluetooth lokal, dan membuat serta menerima sambungan dengan perangkat yang disandingkan."</string>
@@ -907,7 +909,7 @@
     <string name="anr_application_process" msgid="8941757607340481057">"<xliff:g id="APPLICATION">%1$s</xliff:g> tidak menanggapi. Anda ingin menutupnya?"</string>
     <string name="anr_process" msgid="6513209874880517125">"Proses <xliff:g id="PROCESS">%1$s</xliff:g> tidak menanggapi."\n\n"Anda ingin menutupnya?"</string>
     <string name="force_close" msgid="8346072094521265605">"OK"</string>
-    <string name="report" msgid="4060218260984795706">"Laporkan sebagai"</string>
+    <string name="report" msgid="4060218260984795706">"Laporkan"</string>
     <string name="wait" msgid="7147118217226317732">"Tunggu"</string>
     <string name="launch_warning_title" msgid="1547997780506713581">"Apl dialihkan"</string>
     <string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> sedang berjalan."</string>
@@ -1219,4 +1221,7 @@
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"Berbagi dengan"</string>
     <string name="status_bar_device_locked" msgid="3092703448690669768">"Perangkat tergembok."</string>
     <string name="list_delimeter" msgid="3975117572185494152">", "</string>
+    <string name="sending" msgid="8715108995741758718">"Mengirim..."</string>
+    <string name="launchBrowserDefault" msgid="2057951947297614725">"Luncurkan Peramban?"</string>
+    <string name="SetupCallDefault" msgid="6870275517518479651">"Terima Panggilan?"</string>
 </resources>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index f3df270..5bfc968 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -301,6 +301,8 @@
     <string name="permlab_readLogs" msgid="6615778543198967614">"Lettura dati di registro sensibili"</string>
     <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"Consente all\'applicazione di leggere vari file di registro del sistema per trovare informazioni generali sulle operazioni effettuate con il tablet. Tali file potrebbero contenere informazioni personali o riservate."</string>
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Consente all\'applicazione di leggere vari file di registro del sistema per trovare informazioni generali sulle operazioni effettuate con il telefono. Tali file potrebbero contenere informazioni personali o riservate."</string>
+    <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"uso di qualsiasi decoder multimediale per la riproduzione"</string>
+    <string name="permdesc_anyCodecForPlayback" msgid="2101444559995480174">"Consente a un\'applicazione di utilizzare qualsiasi decoder multimediale installato per la decodifica ai fini della riproduzione."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"lettura/scrittura risorse di proprietà di diag"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Consente all\'applicazione di leggere le risorse del gruppo diag e scrivere in esse, ad esempio i file in /dev. Ciò potrebbe influire su stabilità e sicurezza del sistema. Dovrebbe essere utilizzata SOLTANTO per diagnostiche specifiche dell\'hardware effettuate dal produttore o dall\'operatore."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"attivazione/disattivazione componenti applicazioni"</string>
@@ -465,9 +467,9 @@
     <string name="permlab_bluetoothAdmin" msgid="3606576270792236062">"gestione Bluetooth"</string>
     <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"Consente all\'applicazione di configurare il tablet Bluetooth locale e di rilevare ed effettuare l\'accoppiamento con dispositivi remoti."</string>
     <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"Consente all\'applicazione di configurare il telefono Bluetooth locale e di rilevare ed effettuare l\'accoppiamento con dispositivi remoti."</string>
-    <!-- outdated translation 2800410363171809280 -->     <string name="permlab_accessWimaxState" msgid="1232061307208861588">"visualizzazione stato WiMAX"</string>
+    <string name="permlab_accessWimaxState" msgid="1232061307208861588">"Visualizzazione stato WiMAX"</string>
     <string name="permdesc_accessWimaxState" msgid="8298035866227524023">"Consente a un\'applicazione di visualizzare le informazioni relative allo stato della rete WiMAX."</string>
-    <!-- outdated translation 340465839241528618 -->     <string name="permlab_changeWimaxState" msgid="2405042267131496579">"modifica stato WiMAX"</string>
+    <string name="permlab_changeWimaxState" msgid="2405042267131496579">"Modifica stato WiMAX"</string>
     <string name="permdesc_changeWimaxState" msgid="474918005058989421">"Consente a un\'applicazione di connettersi/disconnettersi dalla rete WiMAX."</string>
     <string name="permlab_bluetooth" msgid="8361038707857018732">"creazione connessioni Bluetooth"</string>
     <string name="permdesc_bluetooth" product="tablet" msgid="7007851048416363446">"Consente all\'applicazione di visualizzare la configurazione del tablet Bluetooth locale e di stabilire e accettare connessioni con dispositivi accoppiati."</string>
@@ -1219,4 +1221,7 @@
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"Condividi con"</string>
     <string name="status_bar_device_locked" msgid="3092703448690669768">"Dispositivo bloccato."</string>
     <string name="list_delimeter" msgid="3975117572185494152">", "</string>
+    <string name="sending" msgid="8715108995741758718">"Invio..."</string>
+    <string name="launchBrowserDefault" msgid="2057951947297614725">"Avviare l\'applicazione Browser?"</string>
+    <string name="SetupCallDefault" msgid="6870275517518479651">"Accettare la chiamata?"</string>
 </resources>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index d70f4b8..04bf9c7 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -137,7 +137,7 @@
     <string name="turn_off_radio" msgid="8198784949987062346">"כבה אלחוטי"</string>
     <string name="screen_lock" msgid="799094655496098153">"נעילת מסך"</string>
     <string name="power_off" msgid="4266614107412865048">"כיבוי"</string>
-    <string name="shutdown_progress" msgid="2281079257329981203">"מבצע כיבוי..."</string>
+    <string name="shutdown_progress" msgid="2281079257329981203">"מכבה..."</string>
     <string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"הטבלט שלך יכבה."</string>
     <string name="shutdown_confirm" product="default" msgid="649792175242821353">"הטלפון שלך יכובה."</string>
     <string name="shutdown_confirm_question" msgid="2906544768881136183">"האם ברצונך לבצע כיבוי?"</string>
@@ -301,6 +301,8 @@
     <string name="permlab_readLogs" msgid="6615778543198967614">"קרא נתונים רגישים של יומן רישום"</string>
     <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"מאפשר ליישום לקרוא מקובצי היומן השונים של המערכת. כך מתאפשר ליישום לגלות מידע כללי על הפעולות שלך בטבלט, מידע שעשוי לכלול מידע אישי או פרטי."</string>
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"מאפשר ליישום לקרוא מקובצי היומן השונים של המערכת. כך מתאפשר ליישום לגלות מידע כללי על הפעולות שלך בטלפון, מידע שעשוי לכלול מידע אישי או פרטי."</string>
+    <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"שימוש בכל מפענח מדיה שהוא להפעלה"</string>
+    <string name="permdesc_anyCodecForPlayback" msgid="2101444559995480174">"אפשרות ליישום להשתמש בכל מפענח מדיה מותקן לצורך פענוח להפעלה."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"קרא/כתוב במשאבים בבעלות diag"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"מאפשר ליישום לקרוא ולכתוב בכל משאב שבבעלות קבוצת ה-diag; לדוגמה, קבצים ב-‎/dev. פעולה זו עשויה להשפיע על היציבות והאבטחה של המערכת. אפשרות זו צריכה לשמש רק את היצרן או המפעיל, לצורך אבחונים ספציפיים לחומרה."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"הפעלה או השבתה של רכיבי יישומים"</string>
@@ -465,9 +467,9 @@
     <string name="permlab_bluetoothAdmin" msgid="3606576270792236062">"ניהול Bluetooth"</string>
     <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"מאפשר ליישום להגדיר את תצורתו של הטבלט המקומי מסוג Bluetooth וכן לגלות מכשירים מרוחקים ולבצע התאמה איתם."</string>
     <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"מאפשר ליישום להגדיר את תצורתו של הטלפון המקומי מסוג Bluetooth וכן לגלות מכשירים מרוחקים ולבצע התאמה איתם."</string>
-    <!-- outdated translation 2800410363171809280 -->     <string name="permlab_accessWimaxState" msgid="1232061307208861588">"הצג את מצב WiMAX"</string>
+    <string name="permlab_accessWimaxState" msgid="1232061307208861588">"הצג את מצב WiMAX"</string>
     <string name="permdesc_accessWimaxState" msgid="8298035866227524023">"מאפשר ליישום להציג את המידע על המצב של WiMAX."</string>
-    <!-- outdated translation 340465839241528618 -->     <string name="permlab_changeWimaxState" msgid="2405042267131496579">"שנה את מצב WiMAX"</string>
+    <string name="permlab_changeWimaxState" msgid="2405042267131496579">"שנה את מצב WiMAX"</string>
     <string name="permdesc_changeWimaxState" msgid="474918005058989421">"מאפשר ליישום להתחבר ולהתנתק מרשת WiMAX."</string>
     <string name="permlab_bluetooth" msgid="8361038707857018732">"צור חיבורי Bluetooth"</string>
     <string name="permdesc_bluetooth" product="tablet" msgid="7007851048416363446">"מאפשר ליישום להציג את התצורה של הטבלט המקומי מסוג Bluetooth וכן ליצור ולקבל חיבורים עם מכשירים מותאמים."</string>
@@ -899,7 +901,7 @@
     <string name="chooseUsbActivity" msgid="6894748416073583509">"בחר יישום עבור התקן ה-USB"</string>
     <string name="noApplications" msgid="2991814273936504689">"אין יישומים שיכולים לבצע פעולה זו."</string>
     <string name="aerr_title" msgid="1905800560317137752"></string>
-    <string name="aerr_application" msgid="932628488013092776">"לצערנו ה<xliff:g id="APPLICATION">%1$s</xliff:g> הפסיק לפעול."</string>
+    <string name="aerr_application" msgid="932628488013092776">"לצערנו, פעולת ה<xliff:g id="APPLICATION">%1$s</xliff:g> הופסקה."</string>
     <string name="aerr_process" msgid="4507058997035697579">"לצערנו, התהליך <xliff:g id="PROCESS">%1$s</xliff:g> הופסק."</string>
     <string name="anr_title" msgid="4351948481459135709"></string>
     <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> אינו מגיב."\n\n"תרצה לסגור אותו?"</string>
@@ -1219,4 +1221,7 @@
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"שתף עם"</string>
     <string name="status_bar_device_locked" msgid="3092703448690669768">"המכשיר נעול."</string>
     <string name="list_delimeter" msgid="3975117572185494152">", "</string>
+    <string name="sending" msgid="8715108995741758718">"שולח..."</string>
+    <string name="launchBrowserDefault" msgid="2057951947297614725">"להפעיל את הדפדפן?"</string>
+    <string name="SetupCallDefault" msgid="6870275517518479651">"לקבל את השיחה?"</string>
 </resources>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 3a472fd..7d16d12 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -301,6 +301,8 @@
     <string name="permlab_readLogs" msgid="6615778543198967614">"機密ログデータの読み取り"</string>
     <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"システムの各種ログファイルの読み取りをアプリに許可します。許可すると、アプリではタブレットの使用に関する全般的な情報を読み取れるようになります。この情報には個人情報や機密情報が含まれる場合があります。"</string>
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"システムの各種ログファイルの読み取りをアプリに許可します。許可すると、アプリでは携帯端末の使用に関する全般的な情報を読み取れるようになります。この情報には個人情報や機密情報が含まれる場合があります。"</string>
+    <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"再生用にメディア デコーダーを使用"</string>
+    <string name="permdesc_anyCodecForPlayback" msgid="2101444559995480174">"インストール済みのメディア デコーダーを使用して再生用にデコードすることをアプリケーションに許可します。"</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"diagが所有するリソースの読み書き"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"diagグループが所有するリソース(/dev内のファイルなど)の読み書きをアプリに許可します。許可すると、システムの安定性とセキュリティに影響が生じる可能性があります。メーカー/通信事業者によるハードウェア固有の診断以外には使用しないでください。"</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"アプリのコンポーネントの有効/無効化"</string>
@@ -465,9 +467,9 @@
     <string name="permlab_bluetoothAdmin" msgid="3606576270792236062">"Bluetoothの管理"</string>
     <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"ローカルのBluetoothタブレットを設定することと、リモート端末を検出してペアに設定することをアプリに許可します。"</string>
     <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"ローカルのBluetooth携帯端末を設定することと、リモート端末を検出してペアに設定することをアプリに許可します。"</string>
-    <!-- outdated translation 2800410363171809280 -->     <string name="permlab_accessWimaxState" msgid="1232061307208861588">"WiMAX状態の表示"</string>
+    <string name="permlab_accessWimaxState" msgid="1232061307208861588">"WiMAX状態の表示"</string>
     <string name="permdesc_accessWimaxState" msgid="8298035866227524023">"WiMAX状態に関する情報の表示をアプリケーションに許可します。"</string>
-    <!-- outdated translation 340465839241528618 -->     <string name="permlab_changeWimaxState" msgid="2405042267131496579">"WiMAX状態の変更"</string>
+    <string name="permlab_changeWimaxState" msgid="2405042267131496579">"WiMAX状態の変更"</string>
     <string name="permdesc_changeWimaxState" msgid="474918005058989421">"WiMAXネットワークへの接続と接続解除をアプリケーションに許可します。"</string>
     <string name="permlab_bluetooth" msgid="8361038707857018732">"Bluetooth接続の作成"</string>
     <string name="permdesc_bluetooth" product="tablet" msgid="7007851048416363446">"ローカルのBluetoothタブレットの設定を表示することと、ペアの端末に接続すること/ペアの端末からの接続を受け入れることをアプリに許可します。"</string>
@@ -1219,4 +1221,7 @@
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"共有"</string>
     <string name="status_bar_device_locked" msgid="3092703448690669768">"端末がロックされています。"</string>
     <string name="list_delimeter" msgid="3975117572185494152">"、 "</string>
+    <string name="sending" msgid="8715108995741758718">"送信しています..."</string>
+    <string name="launchBrowserDefault" msgid="2057951947297614725">"ブラウザを起動しますか?"</string>
+    <string name="SetupCallDefault" msgid="6870275517518479651">"通話を受けますか?"</string>
 </resources>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index a01a369..0e2b7e8 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -223,7 +223,7 @@
     <string name="permlab_forceStopPackages" msgid="2329627428832067700">"다른 앱 강제 종료"</string>
     <string name="permdesc_forceStopPackages" msgid="5253157296183940812">"앱이 다른 앱을 강제로 종료할 수 있도록 허용합니다."</string>
     <string name="permlab_forceBack" msgid="652935204072584616">"앱 강제 종료"</string>
-    <string name="permdesc_forceBack" msgid="3892295830419513623">"앱이 포그라운드에 있는 활동을 강제로 닫고 되돌아갈 수 있도록 허용합니다. 일반 앱에는 필요하지 않습니다."</string>
+    <string name="permdesc_forceBack" msgid="3892295830419513623">"앱이 포그라운드에 있는 작업을 강제로 닫고 되돌아갈 수 있도록 허용합니다. 일반 앱에는 필요하지 않습니다."</string>
     <string name="permlab_dump" msgid="1681799862438954752">"시스템 내부 상태 검색"</string>
     <string name="permdesc_dump" msgid="1778299088692290329">"앱이 시스템의 내부 상태를 검색할 수 있도록 허용합니다. 이 경우 악성 앱이 이 기능을 이용하여 일반적으로 필요하지 않은 다양한 개인정보와 보안정보를 검색할 수 있습니다."</string>
     <string name="permlab_retrieve_window_content" msgid="8022588608994589938">"화면 콘텐츠 검색"</string>
@@ -301,6 +301,8 @@
     <string name="permlab_readLogs" msgid="6615778543198967614">"중요한 로그 데이터 읽기"</string>
     <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"앱이 시스템의 다양한 로그 파일을 읽을 수 있도록 허용합니다. 이렇게 되면 앱이 개인정보 또는 비공개 정보를 포함하여 태블릿으로 수행하는 작업에 대한 일반적인 정보를 검색할 수 있습니다."</string>
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"앱이 시스템의 다양한 로그 파일을 읽을 수 있도록 허용합니다. 이렇게 되면 앱이 개인정보 또는 비공개 정보를 포함하여 휴대전화로 수행하는 작업에 대한 일반적인 정보를 검색할 수 있습니다."</string>
+    <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"재생에 모든 미디어 디코더 사용"</string>
+    <string name="permdesc_anyCodecForPlayback" msgid="2101444559995480174">"애플리케이션에서 설치된 모든 미디어 디코더를 사용하여 디코딩 후 재생할 수 있도록 허용합니다."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"진단 그룹 소유의 리소스 읽기/쓰기"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"앱이 진단 그룹 소유의 리소스(예: /dev에 있는 파일)를 읽고 쓸 수 있도록 허용합니다. 이 기능은 시스템 안정성 및 보안에 영향을 미칠 수 있으므로 제조업체 또는 사업자가 하드웨어 관련 진단을 수행하는 경우에만 사용해야 합니다."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"앱 구성요소 사용 또는 사용 안함"</string>
@@ -465,9 +467,9 @@
     <string name="permlab_bluetoothAdmin" msgid="3606576270792236062">"블루투스 관리"</string>
     <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"앱이 로컬 블루투스 태블릿을 설정한 다음 원격 기기를 검색하여 페어링할 수 있도록 허용합니다."</string>
     <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"앱이 로컬 블루투스 휴대전화를 설정한 다음 원격 기기를 검색하여 페어링할 수 있도록 허용합니다."</string>
-    <!-- outdated translation 2800410363171809280 -->     <string name="permlab_accessWimaxState" msgid="1232061307208861588">"WiMAX 상태 보기"</string>
+    <string name="permlab_accessWimaxState" msgid="1232061307208861588">"WiMAX 상태 보기"</string>
     <string name="permdesc_accessWimaxState" msgid="8298035866227524023">"애플리케이션이 WiMAX의 상태에 대한 정보를 볼 수 있도록 합니다."</string>
-    <!-- outdated translation 340465839241528618 -->     <string name="permlab_changeWimaxState" msgid="2405042267131496579">"WiMAX 상태 변경"</string>
+    <string name="permlab_changeWimaxState" msgid="2405042267131496579">"WiMAX 상태 변경"</string>
     <string name="permdesc_changeWimaxState" msgid="474918005058989421">"애플리케이션이 WiMAX 네트워크에 연결하거나 연결을 끊을 수 있도록 합니다."</string>
     <string name="permlab_bluetooth" msgid="8361038707857018732">"블루투스 연결 만들기"</string>
     <string name="permdesc_bluetooth" product="tablet" msgid="7007851048416363446">"앱이 로컬 블루투스 태블릿의 구성을 보고 페어링된 기기에 연결하며 연결을 수락할 수 있도록 허용합니다."</string>
@@ -903,7 +905,7 @@
     <string name="aerr_process" msgid="4507058997035697579">"<xliff:g id="PROCESS">%1$s</xliff:g> 프로세스가 중지되었습니다."</string>
     <string name="anr_title" msgid="4351948481459135709"></string>
     <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g>이(가) 응답하지 않습니다."\n\n"닫으시겠습니까?"</string>
-    <string name="anr_activity_process" msgid="5776209883299089767">"<xliff:g id="ACTIVITY">%1$s</xliff:g> 활동이 응답하지 않습니다."\n\n"닫으시겠습니까?"</string>
+    <string name="anr_activity_process" msgid="5776209883299089767">"<xliff:g id="ACTIVITY">%1$s</xliff:g>이(가) 응답하지 않습니다."\n\n"닫으시겠습니까?"</string>
     <string name="anr_application_process" msgid="8941757607340481057">"<xliff:g id="APPLICATION">%1$s</xliff:g>이(가) 응답하지 않습니다. 닫으시겠습니까?"</string>
     <string name="anr_process" msgid="6513209874880517125">"<xliff:g id="PROCESS">%1$s</xliff:g> 프로세스가 응답하지 않습니다."\n\n"닫으시겠습니까?"</string>
     <string name="force_close" msgid="8346072094521265605">"확인"</string>
@@ -1215,8 +1217,11 @@
     <string name="sha256_fingerprint" msgid="4391271286477279263">"SHA-256 지문:"</string>
     <string name="sha1_fingerprint" msgid="7930330235269404581">"SHA-1 지문:"</string>
     <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"전체 보기"</string>
-    <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"활동 선택"</string>
+    <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"작업 선택"</string>
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"공유 대상"</string>
     <string name="status_bar_device_locked" msgid="3092703448690669768">"기기가 잠겼습니다."</string>
     <string name="list_delimeter" msgid="3975117572185494152">", "</string>
+    <string name="sending" msgid="8715108995741758718">"보내는 중..."</string>
+    <string name="launchBrowserDefault" msgid="2057951947297614725">"브라우저를 실행하시겠습니까?"</string>
+    <string name="SetupCallDefault" msgid="6870275517518479651">"통화를 수락하시겠습니까?"</string>
 </resources>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 1191d23..ba336df 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -301,6 +301,8 @@
     <string name="permlab_readLogs" msgid="6615778543198967614">"skaityti slaptus žurnalo duomenis"</string>
     <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"Leidžiama programai skaityti iš įvairių sistemos žurnalų failų. Taip galima atrasti bendrą informaciją apie tai, ką darote naudodami planšetinį kompiuterį, potencialiai įtraukiant asmeninę ar privačią informaciją."</string>
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Leidžiama programai skaityti iš įvairių sistemos žurnalų failų. Taip galima atrasti bendrą informaciją apie tai, ką darote telefonu, potencialiai įtraukiant asmeninę ar privačią informaciją."</string>
+    <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"atkuriant naudoti bet kurį medijos dekoderį"</string>
+    <string name="permdesc_anyCodecForPlayback" msgid="2101444559995480174">"Leidžiama programai naudoti bet kurį įdiegtą medijos dekoderį norint iššifruoti atkūrimą."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"skaityti / rašyti ištekliuose, priklausančiuose diagnostikai"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Leidžiama programai skaityti ir rašyti visuose diagnostikos grupei priklausančiuose ištekliuose, pvz., failuose, esančiuose /dev. Tai gali paveikti sistemos stabilumą ir saugą. Tai turėtų būti naudojama TIK gamintojui ar operatoriui atliekant aparatinės įrangos diagnostiką."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"įgalinti programos komponentus arba jų neleisti"</string>
@@ -465,9 +467,9 @@
     <string name="permlab_bluetoothAdmin" msgid="3606576270792236062">"„Bluetooth“ administravimas"</string>
     <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"Leidžiama programai konfigūruoti vietinį „Bluetooth“ planšetinį kompiuterį ir atrasti nuotolinius įrenginius bei su jais susieti."</string>
     <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"Leidžiama programai konfigūruoti vietinį „Bluetooth“ telefoną ir atrasti bei susieti su nuotoliniais įrenginiais."</string>
-    <!-- outdated translation 2800410363171809280 -->     <string name="permlab_accessWimaxState" msgid="1232061307208861588">"žiūrėti „WiMAX“ būseną"</string>
+    <string name="permlab_accessWimaxState" msgid="1232061307208861588">"Žiūrėti „WiMAX“ būseną"</string>
     <string name="permdesc_accessWimaxState" msgid="8298035866227524023">"Leidžiama programai matyti informaciją apie „WiMAX“ būseną."</string>
-    <!-- outdated translation 340465839241528618 -->     <string name="permlab_changeWimaxState" msgid="2405042267131496579">"keisti „WiMAX“ būseną"</string>
+    <string name="permlab_changeWimaxState" msgid="2405042267131496579">"Keisti „WiMAX“ būseną"</string>
     <string name="permdesc_changeWimaxState" msgid="474918005058989421">"Leidžiama programai prisijungti prie „WiMAX“ tinklo ir nuo jo atsijungti."</string>
     <string name="permlab_bluetooth" msgid="8361038707857018732">"kurti „Bluetooth“ ryšius"</string>
     <string name="permdesc_bluetooth" product="tablet" msgid="7007851048416363446">"Leidžiama programai peržiūrėti vietinio „Bluetooth“ planšetinio kompiuterio konfigūraciją ir užmegzti bei priimti ryšius iš susietų įrenginių."</string>
@@ -1219,4 +1221,7 @@
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"Bendrinti su"</string>
     <string name="status_bar_device_locked" msgid="3092703448690669768">"Įrenginys užrakintas."</string>
     <string name="list_delimeter" msgid="3975117572185494152">", "</string>
+    <string name="sending" msgid="8715108995741758718">"Siunčiama..."</string>
+    <string name="launchBrowserDefault" msgid="2057951947297614725">"Paleisti naršyklę?"</string>
+    <string name="SetupCallDefault" msgid="6870275517518479651">"Priimti skambutį?"</string>
 </resources>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 8696e9a..231e69b 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -301,6 +301,8 @@
     <string name="permlab_readLogs" msgid="6615778543198967614">"lasīt sensitīvus žurnāla datus"</string>
     <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"Ļauj lietotnei lasīt informāciju no dažādiem sistēmas žurnālfailiem. Šādi lietotne var atrast vispārīgu informāciju par jūsu darbībām planšetdatorā, tostarp arī personas vai privātu informāciju."</string>
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Ļauj lietotnei lasīt informāciju no dažādiem sistēmas žurnālfailiem. Šādi lietotne var atrast vispārīgu informāciju par jūsu darbībām tālrunī, tostarp arī personas vai privātu informāciju."</string>
+    <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"multivides failu atskaņošanai izmantot jebkuru dekodētāju"</string>
+    <string name="permdesc_anyCodecForPlayback" msgid="2101444559995480174">"Ļauj lietojumprogrammai izmantot jebkuru instalētu multivides failu dekodētāju, lai dekodētu failus atskaņošanai."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"lasīt grupas “diag” resursus un rakstīt tajos"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Ļauj lietotnei lasīt un rakstīt jebkurā resursā, kas pieder diagnostikas grupai, piemēram, failiem mapē /dev. Tas var ietekmēt sistēmas stabilitāti un drošību. Var izmantot ražotājs vai operators TIKAI konkrētas aparatūras diagnostikai."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"iespējot vai atspējot lietotnes komponentus"</string>
@@ -465,9 +467,9 @@
     <string name="permlab_bluetoothAdmin" msgid="3606576270792236062">"Bluetooth administrēšana"</string>
     <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"Ļauj lietotnei konfigurēt vietējo Bluetooth planšetdatoru, kā arī atklāt attālas ierīces un savienot tās pārī."</string>
     <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"Ļauj lietotnei konfigurēt vietējo Bluetooth tālruni, kā arī atklāt attālas ierīces un savienot tās pārī."</string>
-    <!-- outdated translation 2800410363171809280 -->     <string name="permlab_accessWimaxState" msgid="1232061307208861588">"WiMAX statusa skatīšana"</string>
+    <string name="permlab_accessWimaxState" msgid="1232061307208861588">"WiMAX statusa skatīšana"</string>
     <string name="permdesc_accessWimaxState" msgid="8298035866227524023">"Ļauj lietojumprogrammai skatīt informāciju par WiMAX statusu."</string>
-    <!-- outdated translation 340465839241528618 -->     <string name="permlab_changeWimaxState" msgid="2405042267131496579">"WiMAX statusa mainīšana"</string>
+    <string name="permlab_changeWimaxState" msgid="2405042267131496579">"WiMAX statusa mainīšana"</string>
     <string name="permdesc_changeWimaxState" msgid="474918005058989421">"Ļauj lietojumprogrammai izveidot un pārtraukt savienojumu ar WiMAX tīklu."</string>
     <string name="permlab_bluetooth" msgid="8361038707857018732">"izveidot Bluetooth savienojumus"</string>
     <string name="permdesc_bluetooth" product="tablet" msgid="7007851048416363446">"Ļauj lietotnei skatīt vietējā Bluetooth planšetdatora konfigurāciju, kā arī veidot un pieņemt savienojumus ar pārī savienotām ierīcēm."</string>
@@ -1219,4 +1221,7 @@
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"Kopīgošana ar:"</string>
     <string name="status_bar_device_locked" msgid="3092703448690669768">"Ierīce ir bloķēta."</string>
     <string name="list_delimeter" msgid="3975117572185494152">", "</string>
+    <string name="sending" msgid="8715108995741758718">"Notiek sūtīšana..."</string>
+    <string name="launchBrowserDefault" msgid="2057951947297614725">"Vai palaist pārlūkprogrammu?"</string>
+    <string name="SetupCallDefault" msgid="6870275517518479651">"Vai pieņemt zvanu?"</string>
 </resources>
diff --git a/core/res/res/values-ms/donottranslate-cldr.xml b/core/res/res/values-ms/donottranslate-cldr.xml
new file mode 100644
index 0000000..09d461c
--- /dev/null
+++ b/core/res/res/values-ms/donottranslate-cldr.xml
@@ -0,0 +1,149 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="month_long_standalone_january">Januari</string>
+    <string name="month_long_standalone_february">Februari</string>
+    <string name="month_long_standalone_march">Mac</string>
+    <string name="month_long_standalone_april">April</string>
+    <string name="month_long_standalone_may">Mei</string>
+    <string name="month_long_standalone_june">Jun</string>
+    <string name="month_long_standalone_july">Julai</string>
+    <string name="month_long_standalone_august">Ogos</string>
+    <string name="month_long_standalone_september">September</string>
+    <string name="month_long_standalone_october">Oktober</string>
+    <string name="month_long_standalone_november">November</string>
+    <string name="month_long_standalone_december">Disember</string>
+
+    <string name="month_long_january">Januari</string>
+    <string name="month_long_february">Februari</string>
+    <string name="month_long_march">Mac</string>
+    <string name="month_long_april">April</string>
+    <string name="month_long_may">Mei</string>
+    <string name="month_long_june">Jun</string>
+    <string name="month_long_july">Julai</string>
+    <string name="month_long_august">Ogos</string>
+    <string name="month_long_september">September</string>
+    <string name="month_long_october">Oktober</string>
+    <string name="month_long_november">November</string>
+    <string name="month_long_december">Disember</string>
+
+    <string name="month_medium_january">Jan</string>
+    <string name="month_medium_february">Feb</string>
+    <string name="month_medium_march">Mac</string>
+    <string name="month_medium_april">Apr</string>
+    <string name="month_medium_may">Mei</string>
+    <string name="month_medium_june">Jun</string>
+    <string name="month_medium_july">Jul</string>
+    <string name="month_medium_august">Ogos</string>
+    <string name="month_medium_september">Sep</string>
+    <string name="month_medium_october">Okt</string>
+    <string name="month_medium_november">Nov</string>
+    <string name="month_medium_december">Dis</string>
+
+    <string name="month_shortest_january">1</string>
+    <string name="month_shortest_february">2</string>
+    <string name="month_shortest_march">3</string>
+    <string name="month_shortest_april">4</string>
+    <string name="month_shortest_may">5</string>
+    <string name="month_shortest_june">6</string>
+    <string name="month_shortest_july">7</string>
+    <string name="month_shortest_august">8</string>
+    <string name="month_shortest_september">9</string>
+    <string name="month_shortest_october">10</string>
+    <string name="month_shortest_november">11</string>
+    <string name="month_shortest_december">12</string>
+
+    <string name="day_of_week_long_sunday">Ahad</string>
+    <string name="day_of_week_long_monday">Isnin</string>
+    <string name="day_of_week_long_tuesday">Selasa</string>
+    <string name="day_of_week_long_wednesday">Rabu</string>
+    <string name="day_of_week_long_thursday">Khamis</string>
+    <string name="day_of_week_long_friday">Jumaat</string>
+    <string name="day_of_week_long_saturday">Sabtu</string>
+
+    <string name="day_of_week_medium_sunday">Ahd</string>
+    <string name="day_of_week_medium_monday">Isn</string>
+    <string name="day_of_week_medium_tuesday">Sel</string>
+    <string name="day_of_week_medium_wednesday">Rab</string>
+    <string name="day_of_week_medium_thursday">Kha</string>
+    <string name="day_of_week_medium_friday">Jum</string>
+    <string name="day_of_week_medium_saturday">Sab</string>
+
+    <string name="day_of_week_short_sunday">Ahd</string>
+    <string name="day_of_week_short_monday">Isn</string>
+    <string name="day_of_week_short_tuesday">Sel</string>
+    <string name="day_of_week_short_wednesday">Rab</string>
+    <string name="day_of_week_short_thursday">Kha</string>
+    <string name="day_of_week_short_friday">Jum</string>
+    <string name="day_of_week_short_saturday">Sab</string>
+
+    <string name="day_of_week_shortest_sunday">1</string>
+    <string name="day_of_week_shortest_monday">2</string>
+    <string name="day_of_week_shortest_tuesday">3</string>
+    <string name="day_of_week_shortest_wednesday">4</string>
+    <string name="day_of_week_shortest_thursday">5</string>
+    <string name="day_of_week_shortest_friday">6</string>
+    <string name="day_of_week_shortest_saturday">7</string>
+
+    <string name="am">AM</string>
+    <string name="pm">PM</string>
+    <string name="yesterday">Yesterday</string>
+    <string name="today">Today</string>
+    <string name="tomorrow">Tomorrow</string>
+
+    <string name="hour_minute_24">%-k:%M</string>
+    <string name="hour_minute_ampm">%-l:%M %p</string>
+    <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
+    <string name="twelve_hour_time_format">h:mm a</string>
+    <string name="twenty_four_hour_time_format">H:mm</string>
+    <string name="numeric_date">%d/%m/%Y</string>
+    <string name="numeric_date_format">dd/MM/yyyy</string>
+    <string name="numeric_date_template">"%s/%s/%s"</string>
+    <string name="month_day_year">%d %B %Y</string>
+    <string name="time_of_day">%-l:%M:%S %p</string>
+    <string name="date_and_time">%-l:%M:%S %p %d %b %Y</string>
+    <string name="date_time">%2$s %1$s</string>
+    <string name="time_date">%1$s %3$s</string>
+    <string name="abbrev_month_day_year">%d %b %Y</string>
+    <string name="month_day">%B %-e</string>
+    <string name="month">%-B</string>
+    <string name="month_year">%B %Y</string>
+    <string name="abbrev_month_day">%b %-e</string>
+    <string name="abbrev_month">%-b</string>
+    <string name="abbrev_month_year">%Y %b</string>
+    <string name="time1_time2">%1$s – %2$s</string>
+    <string name="date1_date2">%2$s – %5$s</string>
+    <string name="numeric_md1_md2">%2$s-%3$s – %7$s-%8$s</string>
+    <string name="numeric_wday1_md1_wday2_md2">%1$s, %2$s-%3$s – %6$s, %7$s-%8$s</string>
+    <string name="numeric_mdy1_mdy2">%4$s-%2$s-%3$s – %9$s-%7$s-%8$s</string>
+    <string name="numeric_wday1_mdy1_wday2_mdy2">%1$s, %4$s-%2$s-%3$s – %6$s, %9$s-%7$s-%8$s</string>
+    <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %4$s-%2$s-%3$s – %10$s %6$s, %9$s-%7$s-%8$s</string>
+    <string name="numeric_md1_time1_md2_time2">%5$s %2$s-%3$s – %10$s %7$s-%8$s</string>
+    <string name="numeric_wday1_md1_time1_wday2_md2_time2">%5$s %1$s, %2$s-%3$s – %10$s %6$s, %7$s-%8$s</string>
+    <string name="numeric_mdy1_time1_mdy2_time2">%5$s %3$s/%2$s/%4$s – %10$s %8$s/%7$s/%9$s</string>
+    <string name="wday1_date1_time1_wday2_date2_time2">%3$s %1$s %2$s – %6$s %4$s %5$s</string>
+    <string name="wday1_date1_wday2_date2">%1$s %2$s – %4$s %5$s</string>
+    <string name="date1_time1_date2_time2">%3$s %2$s – %6$s %5$s</string>
+    <string name="time_wday_date">%1$s %2$s %3$s</string>
+    <string name="wday_date">%2$s %3$s</string>
+    <string name="time_wday">%1$s %2$s</string>
+    <string name="same_year_md1_md2">%2$s %3$s – %7$s %8$s</string>
+    <string name="same_year_wday1_md1_wday2_md2">%1$s %2$s %3$s – %6$s %7$s %8$s</string>
+    <string name="same_year_md1_time1_md2_time2">%5$s %2$s %3$s – %10$s %7$s %8$s</string>
+    <string name="same_month_md1_time1_md2_time2">%5$s %2$s %3$s – %10$s %7$s %8$s</string>
+    <string name="same_year_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %2$s %3$s – %10$s %6$s %7$s %8$s</string>
+    <string name="same_month_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %2$s %3$s – %10$s %6$s %7$s %8$s</string>
+    <string name="same_year_mdy1_time1_mdy2_time2">%5$s %4$s-%2$s-%3$s – %10$s %9$s-%7$s-%8$s</string>
+    <string name="same_month_mdy1_time1_mdy2_time2">%5$s %4$s-%2$s-%3$s – %10$s %9$s-%7$s-%8$s</string>
+    <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %4$s %2$s %3$s – %10$s %6$s, %9$s %7$s %8$s</string>
+    <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %4$s %2$s %3$s – %10$s %6$s, %9$s %7$s %8$s</string>
+    <string name="same_month_wday1_mdy1_wday2_mdy2">%1$s, %4$s %2$s %3$s – %6$s, %9$s %7$s %8$s</string>
+    <string name="same_month_md1_md2">%2$s-%3$s – %8$s</string>
+    <string name="same_month_wday1_md1_wday2_md2">%1$s %2$s %3$s – %6$s %7$s %8$s</string>
+    <string name="same_year_mdy1_mdy2">%9$s-%2$s-%3$s – %7$s-%8$s</string>
+    <string name="same_month_mdy1_mdy2">%9$s-%2$s-%3$s – %8$s</string>
+    <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s, %9$s-%2$s-%3$s – %6$s, yyyy-%7$s-%8$s</string>
+    <string name="short_format_month">%b</string>
+    <string name="full_wday_month_day_no_year">E MMMM d</string>
+    <string name="abbrev_wday_month_day_year">EEE, y MMM d</string>
+</resources>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index 1a5a032..fa862ce 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -142,7 +142,7 @@
     <string name="shutdown_confirm" product="default" msgid="649792175242821353">"Telefon anda akan dimatikan."</string>
     <string name="shutdown_confirm_question" msgid="2906544768881136183">"Adakah anda mahu menutup?"</string>
     <string name="recent_tasks_title" msgid="3691764623638127888">"Baru-baru ini"</string>
-    <string name="no_recent_tasks" msgid="8794906658732193473">"Tiada aplikasi terbaharu"</string>
+    <string name="no_recent_tasks" msgid="8794906658732193473">"Tiada apl terbaharu"</string>
     <string name="global_actions" product="tablet" msgid="408477140088053665">"Pilihan tablet"</string>
     <string name="global_actions" product="default" msgid="2406416831541615258">"Pilihan telefon"</string>
     <string name="global_action_lock" msgid="2844945191792119712">"Kunci skrin"</string>
@@ -157,7 +157,7 @@
     <string name="safeMode" msgid="2788228061547930246">"Mod selamat"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Sistem Android"</string>
     <string name="permgrouplab_costMoney" msgid="5429808217861460401">"Perkhidmatan yang anda perlu bayar"</string>
-    <string name="permgroupdesc_costMoney" msgid="8596717365335027057">"Membenarkan aplikasi melakukan perkara yang boleh mengenakan bayaran kepada anda."</string>
+    <string name="permgroupdesc_costMoney" msgid="8596717365335027057">"Membenarkan apl melakukan perkara yang boleh mengenakan bayaran kepada anda."</string>
     <string name="permgrouplab_messages" msgid="7521249148445456662">"Mesej anda"</string>
     <string name="permgroupdesc_messages" msgid="7821999071003699236">"Membaca dan menulis SMS, e-mel, dan mesej lain."</string>
     <string name="permgrouplab_personalInfo" msgid="3519163141070533474">"Maklumat peribadi anda"</string>
@@ -166,7 +166,7 @@
     <string name="permgrouplab_location" msgid="635149742436692049">"Lokasi anda"</string>
     <string name="permgroupdesc_location" msgid="2430258821648348660">"Pantau lokasi fizikal anda"</string>
     <string name="permgrouplab_network" msgid="5808983377727109831">"Komunikasi rangkaian"</string>
-    <string name="permgroupdesc_network" msgid="4917593670797570584">"Membenarkan aplikasi mengakses pelbagai ciri rangkaian"</string>
+    <string name="permgroupdesc_network" msgid="4917593670797570584">"Membenarkan apl mengakses pelbagai ciri rangkaian"</string>
     <string name="permgrouplab_accounts" msgid="3359646291125325519">"Akaun anda"</string>
     <string name="permgroupdesc_accounts" msgid="4948732641827091312">"Akses akaun yang tersedia."</string>
     <string name="permgrouplab_hardwareControls" msgid="7998214968791599326">"Kawalan perkakasan"</string>
@@ -176,340 +176,342 @@
     <string name="permgrouplab_systemTools" msgid="4652191644082714048">"Alatan sistem"</string>
     <string name="permgroupdesc_systemTools" msgid="8162102602190734305">"Akses dan kawalan peringkat lebih rendah bagi sistem."</string>
     <string name="permgrouplab_developmentTools" msgid="3446164584710596513">"Alatan pembangunan"</string>
-    <string name="permgroupdesc_developmentTools" msgid="7058828032358142018">"Ciri hanya diperlukan untuk pembangun aplikasi."</string>
+    <string name="permgroupdesc_developmentTools" msgid="7058828032358142018">"Ciri hanya diperlukan untuk pembangun apl."</string>
     <string name="permgrouplab_storage" msgid="1971118770546336966">"Storan"</string>
     <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"Akses storan USB."</string>
     <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"Akses kad SD."</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"lumpuhkan atau ubah suai bar status"</string>
-    <string name="permdesc_statusBar" msgid="8434669549504290975">"Membenarkan aplikasi melumpuhkan bar status atau menambah dan mengalih keluar ikon sistem."</string>
+    <string name="permdesc_statusBar" msgid="8434669549504290975">"Membenarkan apl melumpuhkan bar status atau menambah dan mengalih keluar ikon sistem."</string>
     <string name="permlab_statusBarService" msgid="7247281911387931485">"bar status"</string>
-    <string name="permdesc_statusBarService" msgid="716113660795976060">"Membenarkan aplikasi menjadi bar status."</string>
+    <string name="permdesc_statusBarService" msgid="716113660795976060">"Membenarkan apl menjadi bar status."</string>
     <string name="permlab_expandStatusBar" msgid="1148198785937489264">"kembangkan/runtuhkan bar status"</string>
-    <string name="permdesc_expandStatusBar" msgid="6917549437129401132">"Membenarkan aplikasi mengembangkan atau meruntuhkan bar status."</string>
+    <string name="permdesc_expandStatusBar" msgid="6917549437129401132">"Membenarkan apl mengembangkan atau meruntuhkan bar status."</string>
     <string name="permlab_processOutgoingCalls" msgid="1136262550878335980">"sekat panggilan keluar"</string>
-    <string name="permdesc_processOutgoingCalls" msgid="1152111671618301044">"Membenarkan aplikasi untuk memproses panggilan keluar dan menukar nombor yang perlu didail. Aplikasi berniat jahat boleh memantau, mengalih, atau menghalang panggilan keluar."</string>
+    <string name="permdesc_processOutgoingCalls" msgid="1152111671618301044">"Membenarkan apl untuk memproses panggilan keluar dan menukar nombor yang perlu didail. Apl hasad boleh memantau, mengalih, atau menghalang panggilan keluar."</string>
     <string name="permlab_receiveSms" msgid="2697628268086208535">"menerima SMS"</string>
-    <string name="permdesc_receiveSms" msgid="8107887121893611793">"Membenarkan aplikasi untuk menerima dan memproses mesej SMS. Aplikasi berniat jahat boleh memantau mesej anda atau memadamnya tanpa menunjukkannya kepada anda."</string>
+    <string name="permdesc_receiveSms" msgid="8107887121893611793">"Membenarkan apl untuk menerima dan memproses mesej SMS. Apl hasad boleh memantau mesej anda atau memadamnya tanpa menunjukkannya kepada anda."</string>
     <string name="permlab_receiveMms" msgid="8894700916188083287">"terima MMS"</string>
-    <string name="permdesc_receiveMms" msgid="1424805308566612086">"Membenarkan aplikasi untuk menerima dan memproses mesej MMS. Aplikasi berniat jahat boleh memantau mesej anda atau memadamnya tanpa menunjukkannya kepada anda."</string>
+    <string name="permdesc_receiveMms" msgid="1424805308566612086">"Membenarkan apl untuk menerima dan memproses mesej MMS. Apl hasad boleh memantau mesej anda atau memadamnya tanpa menunjukkannya kepada anda."</string>
     <string name="permlab_receiveEmergencyBroadcast" msgid="1803477660846288089">"terima siaran kecemasan"</string>
-    <string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"Membenarkan aplikasi untuk menerima dan memproses mesej siaran kecemasan. Kebenaran ini hanya tersedia kepada aplikasi sistem."</string>
+    <string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"Membenarkan apl untuk menerima dan memproses mesej siaran kecemasan. Kebenaran ini hanya tersedia kepada apl sistem."</string>
     <string name="permlab_sendSms" msgid="5600830612147671529">"hantar mesej SMS"</string>
-    <string name="permdesc_sendSms" msgid="906546667507626156">"Membenarkan aplikasi untuk menghantar mesej SMS. Aplikasi berniat jahat boleh menyebabkan anda kehilangan wang dengan menghantar mesej tanpa pengesahan anda."</string>
+    <string name="permdesc_sendSms" msgid="906546667507626156">"Membenarkan apl untuk menghantar mesej SMS. Apl hasad boleh menyebabkan anda kehilangan wang dengan menghantar mesej tanpa pengesahan anda."</string>
     <string name="permlab_sendSmsNoConfirmation" msgid="4781483105951730228">"hantar mesej SMS tanpa pengesahan"</string>
-    <string name="permdesc_sendSmsNoConfirmation" msgid="3437759207020400204">"Membenarkan aplikasi untuk menghantar mesej SMS. Aplikasi berniat jahat boleh menyebabkan anda kehilangan wang dengan menghantar mesej tanpa pengesahan anda."</string>
+    <string name="permdesc_sendSmsNoConfirmation" msgid="3437759207020400204">"Membenarkan apl untuk menghantar mesej SMS. Apl hasad boleh menyebabkan anda kehilangan wang dengan menghantar mesej tanpa pengesahan anda."</string>
     <string name="permlab_readSms" msgid="4085333708122372256">"baca SMS atau MMS"</string>
-    <string name="permdesc_readSms" product="tablet" msgid="2341692916884515613">"Membenarkan aplikasi untuk membaca mesej SMS yang disimpan pada tablet atau kad SIM anda. Aplikasi berniat jahat boleh membaca mesej sulit anda."</string>
-    <string name="permdesc_readSms" product="default" msgid="5653850482025875493">"Membenarkan aplikasi untuk membaca mesej SMS yang disimpan pada telefon atau kad SIM anda. Aplikasi berniat jahat boleh membaca mesej sulit anda."</string>
+    <string name="permdesc_readSms" product="tablet" msgid="2341692916884515613">"Membenarkan apl untuk membaca mesej SMS yang disimpan pada tablet atau kad SIM anda. Apl hasad boleh membaca mesej sulit anda."</string>
+    <string name="permdesc_readSms" product="default" msgid="5653850482025875493">"Membenarkan apl untuk membaca mesej SMS yang disimpan pada telefon atau kad SIM anda. Apl hasad boleh membaca mesej sulit anda."</string>
     <string name="permlab_writeSms" msgid="6881122575154940744">"edit SMS atau MMS"</string>
-    <string name="permdesc_writeSms" product="tablet" msgid="5160413947794501538">"Membenarkan aplikasi untuk menulis kepada mesej SMS yang disimpan pada tablet atau kad SIM anda. Aplikasi berniat jahat boleh memadam mesej anda."</string>
-    <string name="permdesc_writeSms" product="default" msgid="7268668709052328567">"Membenarkan aplikasi untuk menulis kepada mesej SMS yang disimpan pada telefon atau kad SIM anda. Aplikasi berniat jahat boleh memadam mesej anda."</string>
+    <string name="permdesc_writeSms" product="tablet" msgid="5160413947794501538">"Membenarkan apl untuk menulis kepada mesej SMS yang disimpan pada tablet atau kad SIM anda. Apl hasad boleh memadam mesej anda."</string>
+    <string name="permdesc_writeSms" product="default" msgid="7268668709052328567">"Membenarkan apl untuk menulis kepada mesej SMS yang disimpan pada telefon atau kad SIM anda. Apl hasad boleh memadam mesej anda."</string>
     <string name="permlab_receiveWapPush" msgid="8258226427716551388">"terima WAP"</string>
-    <string name="permdesc_receiveWapPush" msgid="7983455145335316872">"Membenarkan aplikasi untuk menerima dan memproses mesej WAP. Aplikasi berniat jahat boleh memantau mesej anda atau memadamnya tanpa menunjukkannya kepada anda."</string>
-    <string name="permlab_getTasks" msgid="6466095396623933906">"dapatkan semula aplikasi yang sedang dijalankan"</string>
-    <string name="permdesc_getTasks" msgid="6608159250520381359">"Membenarkan aplikasi untuk mendapatkan maklumat tugasan yang sedang dan baharu berjalan. Aplikasi berniat jahat boleh mendapat maklumat peribadi tentang aplikasi lain."</string>
-    <string name="permlab_reorderTasks" msgid="2018575526934422779">"susun semula tertib aplikasi yang dijalankan"</string>
-    <string name="permdesc_reorderTasks" msgid="4175137612205663399">"Membenarkan aplikasi untuk memindahkan tugasan ke latar depan dan latar belakang. Aplikasi berniat jahat boleh memaksa diri mereka ke hadapan tanpa kawalan anda."</string>
-    <string name="permlab_removeTasks" msgid="6821513401870377403">"hentikan aplikasi yang sedang dijalankan"</string>
-    <string name="permdesc_removeTasks" msgid="1000226123143185094">"Membenarkan aplikasi untuk mengalih keluar tugasan dan melupuskan aplikasi itu. Aplikasi berniat jahat boleh mengganggu tingkah laku aplikasi lain."</string>
-    <string name="permlab_setDebugApp" msgid="3022107198686584052">"dayakan penyahpepijatan aplikasi"</string>
-    <string name="permdesc_setDebugApp" msgid="6215654419903651172">"Membenarkan aplikasi untuk menghidupkan nyahpepijat untuk aplikasi lain. Aplikasi berniat jahat boleh menggunakan ini untuk membunuh aplikasi lain."</string>
+    <string name="permdesc_receiveWapPush" msgid="7983455145335316872">"Membenarkan apl untuk menerima dan memproses mesej WAP. Apl hasad boleh memantau mesej anda atau memadamnya tanpa menunjukkannya kepada anda."</string>
+    <string name="permlab_getTasks" msgid="6466095396623933906">"dapatkan semula apl yang sedang dijalankan"</string>
+    <string name="permdesc_getTasks" msgid="6608159250520381359">"Membenarkan apl untuk mendapatkan maklumat tugasan yang sedang dan baru berjalan. Apl hasad boleh mendapat maklumat peribadi tentang apl lain."</string>
+    <string name="permlab_reorderTasks" msgid="2018575526934422779">"susun semula tertib apl yang dijalankan"</string>
+    <string name="permdesc_reorderTasks" msgid="4175137612205663399">"Membenarkan apl untuk memindahkan tugasan ke latar depan dan latar belakang. Apl hasad boleh memaksa diri mereka ke hadapan tanpa kawalan anda."</string>
+    <string name="permlab_removeTasks" msgid="6821513401870377403">"hentikan apl yang sedang dijalankan"</string>
+    <string name="permdesc_removeTasks" msgid="1000226123143185094">"Membenarkan apl untuk mengalih keluar tugasan dan melupuskan apl itu. Apl hasad boleh mengganggu tingkah laku apl lain."</string>
+    <string name="permlab_setDebugApp" msgid="3022107198686584052">"dayakan penyahpepijatan apl"</string>
+    <string name="permdesc_setDebugApp" msgid="6215654419903651172">"Membenarkan apl untuk menghidupkan nyahpepijat untuk apl lain. Apl hasad boleh menggunakannya untuk membunuh apl lain."</string>
     <string name="permlab_changeConfiguration" msgid="8214475779521218295">"tukar tetapan UI anda"</string>
-    <string name="permdesc_changeConfiguration" msgid="4104052649900380324">"Membenarkan aplikasi mengubah konfigurasi semasa seperti tempat peristiwa atau saiz fon keseluruhan."</string>
+    <string name="permdesc_changeConfiguration" msgid="4104052649900380324">"Membenarkan apl mengubah konfigurasi semasa seperti tempat peristiwa atau saiz fon keseluruhan."</string>
     <string name="permlab_enableCarMode" msgid="5684504058192921098">"dayakan mod kereta"</string>
-    <string name="permdesc_enableCarMode" msgid="4853187425751419467">"Membenarkan aplikasi mendayakan mod kereta."</string>
+    <string name="permdesc_enableCarMode" msgid="4853187425751419467">"Membenarkan apl mendayakan mod kereta."</string>
     <string name="permlab_killBackgroundProcesses" msgid="8373714752793061963">"bunuh proses latar belakang"</string>
-    <string name="permdesc_killBackgroundProcesses" msgid="931129103262126617">"Membenarkan aplikasi untuk membunuh proses latar belakang aplikasi lain, walaupun memori tidak rendah."</string>
-    <string name="permlab_forceStopPackages" msgid="2329627428832067700">"paksa aplikasi lain supaya berhenti"</string>
-    <string name="permdesc_forceStopPackages" msgid="5253157296183940812">"Membenarkan aplikasi menghentikan aplikasi lain secara paksa."</string>
-    <string name="permlab_forceBack" msgid="652935204072584616">"memaksa aplikasi untuk menutup"</string>
-    <string name="permdesc_forceBack" msgid="3892295830419513623">"Membenarkan aplikasi untuk memaksa apa-apa aktiviti yang ada di latar depan untuk tutup dan kembali. Tidak sekali-kali diperlukan untuk aplikasi biasa."</string>
+    <string name="permdesc_killBackgroundProcesses" msgid="931129103262126617">"Membenarkan apl untuk membunuh proses latar belakang apl lain, walaupun memori tidak rendah."</string>
+    <string name="permlab_forceStopPackages" msgid="2329627428832067700">"paksa apl lain supaya berhenti"</string>
+    <string name="permdesc_forceStopPackages" msgid="5253157296183940812">"Membenarkan apl menghentikan apl lain secara paksa."</string>
+    <string name="permlab_forceBack" msgid="652935204072584616">"memaksa apl untuk menutup"</string>
+    <string name="permdesc_forceBack" msgid="3892295830419513623">"Membenarkan apl untuk memaksa apa-apa aktiviti yang ada di latar depan untuk tutup dan kembali. Tidak sekali-kali diperlukan untuk apl biasa."</string>
     <string name="permlab_dump" msgid="1681799862438954752">"mendapatkan semula keadaan dalaman sistem"</string>
-    <string name="permdesc_dump" msgid="1778299088692290329">"Membenarkan aplikasi untuk mendapatkan semula keadaan dalaman sistem. Aplikasi berniat jahat boleh mendapatkan pelbagai maklumat peribadi dan selamat yang biasanya tidak ia perlukan."</string>
+    <string name="permdesc_dump" msgid="1778299088692290329">"Membenarkan apl untuk mendapatkan semula keadaan dalaman sistem. Apl hasad boleh mendapatkan pelbagai maklumat peribadi dan selamat yang biasanya tidak ia perlukan."</string>
     <string name="permlab_retrieve_window_content" msgid="8022588608994589938">"dapatkan semula kandungan skrin"</string>
-    <string name="permdesc_retrieve_window_content" msgid="3193269069469700265">"Membenarkan aplikasi untuk mendapatkan kandungan tetingkap aktif. Aplikasi berniat jahat boleh mengambil keseluruhan kandungan tetingkap dan memeriksa semua teks kecuali kata laluan."</string>
+    <string name="permdesc_retrieve_window_content" msgid="3193269069469700265">"Membenarkan apl untuk mendapatkan kandungan tetingkap aktif. Apl hasad boleh mengambil keseluruhan kandungan tetingkap dan memeriksa semua teks kecuali kata laluan."</string>
     <string name="permlab_shutdown" msgid="7185747824038909016">"penutupan separa"</string>
     <string name="permdesc_shutdown" msgid="7046500838746291775">"Meletakkan pengurus aktiviti dalam keadaan tutup. Tidak melaksanakan penutupan lengkap."</string>
     <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"halang pertukaran apl"</string>
-    <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"Menghalang pengguna daripada bertukar kepada aplikasi lain."</string>
-    <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"pantau dan kawal semua pelancaran aplikasi"</string>
-    <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"Membenarkan aplikasi untuk memantau dan mengawal bagaimana sistem melancarkan aktiviti. Aplikasi berniat jahat boleh menjejaskan sistem sepenuhnya. Kebenaran ini hanya diperlukan untuk pembangunan, tidak sekali-kali untuk penggunaan biasa."</string>
+    <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"Menghalang pengguna daripada bertukar kepada apl lain."</string>
+    <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"pantau dan kawal semua pelancaran apl"</string>
+    <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"Membenarkan apl untuk memantau dan mengawal cara sistem melancarkan aktiviti. Apl hasad boleh menjejaskan sistem sepenuhnya. Kebenaran ini hanya diperlukan untuk pembangunan, tidak sekali-kali untuk penggunaan biasa."</string>
     <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"hantar siaran bahawa pakej telah dialih keluar"</string>
-    <string name="permdesc_broadcastPackageRemoved" msgid="6621901216207931089">"Membenarkan aplikasi untuk menyiarkan pemberitahuan bahawa pakej aplikasi telah dikeluarkan. Aplikasi berniat jahat boleh menggunakan ini untuk membunuh mana-mana aplikasi lain yang sedang berjalan."</string>
+    <string name="permdesc_broadcastPackageRemoved" msgid="6621901216207931089">"Membenarkan apl untuk menyiarkan pemberitahuan bahawa pakej apl telah dikeluarkan. Apl hasad boleh menggunakannya untuk membunuh mana-mana apl lain yang sedang berjalan."</string>
     <string name="permlab_broadcastSmsReceived" msgid="5689095009030336593">"hantar siaran SMS diterima"</string>
-    <string name="permdesc_broadcastSmsReceived" msgid="4152037720034365492">"Membenarkan aplikasi untuk menyiarkan pemberitahuan bahawa mesej SMS telah diterima. Aplikasi berniat jahat boleh menggunakan ini untuk memalsukan mesej SMS masuk."</string>
+    <string name="permdesc_broadcastSmsReceived" msgid="4152037720034365492">"Membenarkan apl untuk menyiarkan pemberitahuan bahawa mesej SMS telah diterima. Apl hasad boleh menggunakannya untuk memalsukan mesej SMS masuk."</string>
     <string name="permlab_broadcastWapPush" msgid="3145347413028582371">"hantar siaran WAP-TOLAK-diterima"</string>
-    <string name="permdesc_broadcastWapPush" msgid="4783402525039442729">"Membenarkan aplikasi untuk menyiarkan pemberitahuan bahawa mesej WAP PUSH telah diterima. Aplikasi berniat jahat boleh menggunakan ini untuk memalsukan penerimaan mesej MMS atau secara diam-diam menggantikan kandungan mana-mana laman web dengan varian berniat jahat."</string>
+    <string name="permdesc_broadcastWapPush" msgid="4783402525039442729">"Membenarkan apl untuk menyiarkan pemberitahuan bahawa mesej WAP PUSH telah diterima. Apl hasad boleh menggunakannya untuk memalsukan penerimaan mesej MMS atau secara diam-diam menggantikan kandungan mana-mana laman web dengan varian hasad."</string>
     <string name="permlab_setProcessLimit" msgid="2451873664363662666">"hadkan bilangan proses yang dijalankan"</string>
-    <string name="permdesc_setProcessLimit" msgid="7318061314040879542">"Membenarkan aplikasi untuk mengawal bilangan maksimum proses yang akan berlangsung. Tidak sekali-kali diperlukan untuk aplikasi biasa."</string>
-    <string name="permlab_setAlwaysFinish" msgid="238828158465736054">"jadikan semua aplikasi latar belakang ditutup"</string>
-    <string name="permdesc_setAlwaysFinish" msgid="7471310652868841499">"Membenarkan aplikasi untuk mengawal sama ada aktiviti sentiasa selesai sebaik sahaja ia pergi ke latar belakang. Tidak sekali-kali diperlukan untuk aplikasi biasa."</string>
+    <string name="permdesc_setProcessLimit" msgid="7318061314040879542">"Membenarkan apl untuk mengawal bilangan maksimum proses yang akan berlangsung. Tidak sekali-kali diperlukan untuk apl biasa."</string>
+    <string name="permlab_setAlwaysFinish" msgid="238828158465736054">"jadikan semua apl latar belakang ditutup"</string>
+    <string name="permdesc_setAlwaysFinish" msgid="7471310652868841499">"Membenarkan apl untuk mengawal sama ada aktiviti sentiasa selesai sebaik sahaja ia pergi ke latar belakang. Tidak sekali-kali diperlukan untuk apl biasa."</string>
     <string name="permlab_batteryStats" msgid="7863923071360031652">"ubah suai statistik bateri"</string>
-    <string name="permdesc_batteryStats" msgid="6835186932305744068">"Membenarkan aplikasi untuk mengubah suai statistik bateri yang dikumpul. Bukan untuk kegunaan aplikasi biasa."</string>
+    <string name="permdesc_batteryStats" msgid="6835186932305744068">"Membenarkan apl untuk mengubah suai statistik bateri yang dikumpul. Bukan untuk kegunaan apl biasa."</string>
     <string name="permlab_backup" msgid="470013022865453920">"sandaran dan pemulihan sistem kawalan"</string>
-    <string name="permdesc_backup" msgid="6912230525140589891">"Membenarkan aplikasi untuk mengawal sandaran sistem dan memulihkan mekanisme. Bukan untuk digunakan oleh aplikasi biasa."</string>
+    <string name="permdesc_backup" msgid="6912230525140589891">"Membenarkan apl untuk mengawal sandaran sistem dan memulihkan mekanisme. Bukan untuk digunakan oleh apl biasa."</string>
     <string name="permlab_confirm_full_backup" msgid="5557071325804469102">"sahkan penyandaran penuh atau pemulihan operasi"</string>
-    <string name="permdesc_confirm_full_backup" msgid="1748762171637699562">"Membenarkan aplikasi untuk memulakan UI pengesahan sandaran penuh. Bukan untuk diguakan oleh mana-mana aplikasi."</string>
+    <string name="permdesc_confirm_full_backup" msgid="1748762171637699562">"Membenarkan apl untuk memulakan UI pengesahan sandaran penuh. Bukan untuk diguakan oleh mana-mana apl."</string>
     <string name="permlab_internalSystemWindow" msgid="2148563628140193231">"memapaparkan tetingkap yang tiada kebenaran"</string>
-    <string name="permdesc_internalSystemWindow" msgid="6510907081810231374">"Membenarkan aplikasi untuk membuat tetingkap yang dimaksudkan untuk digunakan oleh antara muka pengguna sistem dalaman. Bukan untuk digunakan oleh aplikasi biasa."</string>
+    <string name="permdesc_internalSystemWindow" msgid="6510907081810231374">"Membenarkan apl untuk membuat tetingkap yang dimaksudkan untuk digunakan oleh antara muka pengguna sistem dalaman. Bukan untuk digunakan oleh apl biasa."</string>
     <string name="permlab_systemAlertWindow" msgid="3372321942941168324">"paparkan amaran peringkat sistem"</string>
-    <string name="permdesc_systemAlertWindow" msgid="8507863469978066409">"Membenarkan aplikasi untuk menunjukkan tetingkap amaran sistem. Aplikasi berniat jahat boleh mengambil alih seluruh skrin."</string>
+    <string name="permdesc_systemAlertWindow" msgid="8507863469978066409">"Membenarkan apl untuk menunjukkan tetingkap amaran sistem. Apl hasad boleh mengambil alih keseluruhan skrin."</string>
     <string name="permlab_setAnimationScale" msgid="2805103241153907174">"mengubah suai kelajuan animasi global"</string>
-    <string name="permdesc_setAnimationScale" msgid="6505093307223395456">"Membenarkan aplikasi menukar kelajuan animasi global (animasi yang lebih laju atau lebih perlahan) pada bila-bila masa sahaja."</string>
-    <string name="permlab_manageAppTokens" msgid="1286505717050121370">"urus rtoken aplikasi"</string>
-    <string name="permdesc_manageAppTokens" msgid="8043431713014395671">"Membenarkan aplikasi untuk membuat dan menguruskan token mereka sendiri, dengan memintas susunan-Z biasanya. Tidak sekali-kali diperlukan untuk aplikasi biasa."</string>
+    <string name="permdesc_setAnimationScale" msgid="6505093307223395456">"Membenarkan apl menukar kelajuan animasi global (animasi yang lebih laju atau lebih perlahan) pada bila-bila masa sahaja."</string>
+    <string name="permlab_manageAppTokens" msgid="1286505717050121370">"urus token apl"</string>
+    <string name="permdesc_manageAppTokens" msgid="8043431713014395671">"Membenarkan apl untuk membuat dan menguruskan token mereka sendiri, dengan memintas susunan-Z biasanya. Tidak sekali-kali diperlukan untuk apl biasa."</string>
     <string name="permlab_injectEvents" msgid="1378746584023586600">"menekan kekunci dan butang kawalan"</string>
-    <string name="permdesc_injectEvents" product="tablet" msgid="206352565599968632">"Membenarkan aplikasi untuk menyampaikan peristiwa input sendiri (tekanan kekunci, dan sebagainya) kepada aplikasi lain. Aplikasi berniat jahat boleh menggunakan ini untuk mengambil alih tablet."</string>
-    <string name="permdesc_injectEvents" product="default" msgid="653128057572326253">"Membenarkan aplikasi untuk menyampaikan peristiwa input sendiri (tekanan kekunci, dan sebagainya) kepada aplikasi lain. Aplikasi berniat jahat boleh menggunakan ini untuk mengambil alih telefon."</string>
+    <string name="permdesc_injectEvents" product="tablet" msgid="206352565599968632">"Membenarkan apl untuk menyampaikan peristiwa input sendiri (tekanan kekunci, dan sebagainya) kepada apl lain. Apl hasad boleh menggunakannya untuk mengambil alih tablet."</string>
+    <string name="permdesc_injectEvents" product="default" msgid="653128057572326253">"Membenarkan apl untuk menyampaikan peristiwa input sendiri (tekanan kekunci, dan sebagainya) kepada apl lain. Apl hasad boleh menggunakannya untuk mengambil alih telefon."</string>
     <string name="permlab_readInputState" msgid="469428900041249234">"rakam apa yang anda taipkan dan tindakan yang anda ambil"</string>
-    <string name="permdesc_readInputState" msgid="8387754901688728043">"Membenarkan aplikasi untuk melihat kekunci yang anda tekan walaupun semasa berinteraksi dengan aplikasi lain (seperti menaip kata laluan). Tidak sekali-kali diperlukan untuk aplikasi biasa."</string>
+    <string name="permdesc_readInputState" msgid="8387754901688728043">"Membenarkan apl untuk melihat kekunci yang anda tekan walaupun semasa berinteraksi dengan apl lain (seperti menaip kata laluan). Tidak sekali-kali diperlukan untuk apl biasa."</string>
     <string name="permlab_bindInputMethod" msgid="3360064620230515776">"terikat kepada kaedah input"</string>
-    <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Membenarkan pemegang terikat dengan antara muka peringkat tertinggi bagi kaedah input itu. Tidak sekali-kali diperlukan untuk aplikasi biasa."</string>
+    <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Membenarkan pemegang terikat dengan antara muka peringkat tertinggi bagi kaedah input itu. Tidak sekali-kali diperlukan untuk apl biasa."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"terikat kepada perkhidmatan teks"</string>
-    <string name="permdesc_bindTextService" msgid="8151968910973998670">"Membenarkan pemegang mengikat kepada antara muka tahap tinggi perkhidmatan teks(mis. PerkhidmatanPenyemakEjaan). Tidak seharusnya diperlukan untuk aplikasi biasa."</string>
+    <string name="permdesc_bindTextService" msgid="8151968910973998670">"Membenarkan pemegang mengikat kepada antara muka peringkat atasan perkhidmatan teks(mis. PerkhidmatanPenyemakEjaan). Tidak seharusnya diperlukan untuk apl biasa."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"terikat kepada perkhidmatan VPN"</string>
-    <string name="permdesc_bindVpnService" msgid="2067845564581693905">"Membenarkan pemegang terikat dengan antara muka peringkat tertinggi bagi perkhidmatan Vpn. Tidak sekali-kali diperlukan untuk aplikasi biasa."</string>
+    <string name="permdesc_bindVpnService" msgid="2067845564581693905">"Membenarkan pemegang terikat dengan antara muka peringkat tertinggi bagi perkhidmatan Vpn. Tidak sekali-kali diperlukan untuk apl biasa."</string>
     <string name="permlab_bindWallpaper" msgid="8716400279937856462">"terikat pada kertas dinding"</string>
-    <string name="permdesc_bindWallpaper" msgid="7108428692595491668">"Membenarkan pemegang terikat dengan antara muka peringkat tertinggi bagi kertas dinding. Tidak sekali-kali diperlukan untuk aplikasi biasa."</string>
+    <string name="permdesc_bindWallpaper" msgid="7108428692595491668">"Membenarkan pemegang terikat dengan antara muka peringkat tertinggi bagi kertas dinding. Tidak sekali-kali diperlukan untuk apl biasa."</string>
     <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"terikat kepada perkhidmatan widget"</string>
-    <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Membenarkan pemegang terikat dengan antara muka peringkat tertinggi bagi perkhidmatan widget. Tidak sekali-kali diperlukan untuk aplikasi biasa."</string>
+    <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Membenarkan pemegang terikat dengan antara muka peringkat tertinggi bagi perkhidmatan widget. Tidak sekali-kali diperlukan untuk apl biasa."</string>
     <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"berinteraksi dengan pentadbir peranti"</string>
-    <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Membenarkan pemegang menghantar tujuan kepada pentadbir peranti. Tidak sekali-kali diperlukan untuk aplikasi biasa."</string>
+    <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Membenarkan pemegang menghantar tujuan kepada pentadbir peranti. Tidak sekali-kali diperlukan untuk apl biasa."</string>
     <string name="permlab_setOrientation" msgid="3365947717163866844">"tukar orientasi skrin"</string>
-    <string name="permdesc_setOrientation" msgid="3046126619316671476">"Membenarkan aplikasi untuk menukar putaran skrin pada bila-bila masa. Tidak sekali-kali diperlukan untuk aplikasi biasa."</string>
+    <string name="permdesc_setOrientation" msgid="3046126619316671476">"Membenarkan apl untuk menukar putaran skrin pada bila-bila masa. Tidak sekali-kali diperlukan untuk apl biasa."</string>
     <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"tukar kelajuan penuding"</string>
-    <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"Membenarkan aplikasi untuk menukar kelajuan penunjuk tetikus atau pad jejak pada bila-bila masa. Tidak sekali-kali diperlukan untuk aplikasi biasa."</string>
-    <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"hantar isyarat Linux kepada aplikasi"</string>
-    <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"Membenarkan aplikasi meminta isyarat yang dibekalkan dihantar kepada semua proses yang berterusan."</string>
-    <string name="permlab_persistentActivity" msgid="8841113627955563938">"buatkan aplikasi sentiasa berjalan"</string>
-    <string name="permdesc_persistentActivity" msgid="4909910271316074418">"Membenarkan aplikasi untuk membuat sebahagian dirinya berterusan, agar sistem itu tidak boleh menggunakannya untuk aplikasi lain."</string>
-    <string name="permlab_deletePackages" msgid="184385129537705938">"padam aplikasi"</string>
-    <string name="permdesc_deletePackages" msgid="7411480275167205081">"Membenarkan aplikasi untuk memadam pakej Android. Aplikasi berniat jahat boleh menggunakan ini untuk memadam aplikasi penting."</string>
-    <string name="permlab_clearAppUserData" msgid="274109191845842756">"padamkan data aplikasi lain"</string>
-    <string name="permdesc_clearAppUserData" msgid="4625323684125459488">"Membenarkan aplikasi mengosongkan data pengguna."</string>
-    <string name="permlab_deleteCacheFiles" msgid="3128665571837408675">"padamkan cache aplikasi lain"</string>
-    <string name="permdesc_deleteCacheFiles" msgid="3812998599006730196">"Membenarkan aplikasi memadamkan fail cache."</string>
-    <string name="permlab_getPackageSize" msgid="7472921768357981986">"ukur ruang storan aplikasi"</string>
-    <string name="permdesc_getPackageSize" msgid="3921068154420738296">"Membenarkan aplikasi mendapatkan semula kodnya, datanya dan saiz cachenya"</string>
-    <string name="permlab_installPackages" msgid="2199128482820306924">"pasang terus aplikasi"</string>
-    <string name="permdesc_installPackages" msgid="5628530972548071284">"Membenarkan aplikasi untuk memasang pakej Android yang baharu atau yang dikemas kini. Aplikasi berniat jahat boleh menggunakan ini untuk menambah aplikasi baharu dengan keizinan berkuasa secara sewenang-wenangnya."</string>
-    <string name="permlab_clearAppCache" msgid="7487279391723526815">"padamkan semua data cache aplikasi"</string>
-    <string name="permdesc_clearAppCache" product="tablet" msgid="3523396284474042284">"Membenarkan aplikasi untuk mengosongkan storan tablet dengan memadam fail dalam direktori cache aplikasi. Akses sangat terhad biasanya kepada proses sistem."</string>
-    <string name="permdesc_clearAppCache" product="default" msgid="5067988373366292186">"Membenarkan aplikasi untuk mengosongkan storan telefon dengan memadam fail dalam direktori cache aplikasi. Akses sangat terhad biasanya kepada proses sistem."</string>
-    <string name="permlab_movePackage" msgid="3289890271645921411">"Alih sumber aplikasi"</string>
-    <string name="permdesc_movePackage" msgid="319562217778244524">"Membenarkan aplikasi untuk memindahkan sumber aplikasi dari media dalaman ke luaran dan sebaliknya."</string>
+    <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"Membenarkan apl untuk menukar kelajuan penunjuk tetikus atau pad jejak pada bila-bila masa. Tidak sekali-kali diperlukan untuk apl biasa."</string>
+    <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"hantar isyarat Linux kepada apl"</string>
+    <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"Membenarkan apl meminta isyarat yang dibekalkan dihantar kepada semua proses yang berterusan."</string>
+    <string name="permlab_persistentActivity" msgid="8841113627955563938">"buatkan apl sentiasa berjalan"</string>
+    <string name="permdesc_persistentActivity" msgid="4909910271316074418">"Membenarkan apl untuk membuat sebahagian dirinya berkeras, agar sistem itu tidak boleh menggunakannya untuk apl lain."</string>
+    <string name="permlab_deletePackages" msgid="184385129537705938">"padam apl"</string>
+    <string name="permdesc_deletePackages" msgid="7411480275167205081">"Membenarkan apl untuk memadam pakej Android. Apl hasad boleh menggunakannya untuk memadam apl penting."</string>
+    <string name="permlab_clearAppUserData" msgid="274109191845842756">"padamkan data apl lain"</string>
+    <string name="permdesc_clearAppUserData" msgid="4625323684125459488">"Membenarkan apl mengosongkan data pengguna."</string>
+    <string name="permlab_deleteCacheFiles" msgid="3128665571837408675">"padamkan cache apl lain"</string>
+    <string name="permdesc_deleteCacheFiles" msgid="3812998599006730196">"Membenarkan apl memadamkan fail cache."</string>
+    <string name="permlab_getPackageSize" msgid="7472921768357981986">"ukur ruang storan apl"</string>
+    <string name="permdesc_getPackageSize" msgid="3921068154420738296">"Membenarkan apl mendapatkan semula kodnya, datanya dan saiz cachenya"</string>
+    <string name="permlab_installPackages" msgid="2199128482820306924">"pasang terus apl"</string>
+    <string name="permdesc_installPackages" msgid="5628530972548071284">"Membenarkan apl untuk memasang pakej Android yang baharu atau yang dikemas kini. Apl hasad boleh menggunakannya untuk menambah apl baharu dengan keizinan berkuasa secara sewenang-wenangnya."</string>
+    <string name="permlab_clearAppCache" msgid="7487279391723526815">"padamkan semua data cache apl"</string>
+    <string name="permdesc_clearAppCache" product="tablet" msgid="3523396284474042284">"Membenarkan apl untuk mengosongkan storan tablet dengan memadam fail dalam direktori cache apl. Kebiasaannya, akses adalah terhad kepada proses sistem."</string>
+    <string name="permdesc_clearAppCache" product="default" msgid="5067988373366292186">"Membenarkan apl untuk mengosongkan storan telefon dengan memadam fail dalam direktori cache apl. Kebiasaannya, akses adalah terhad kepada proses sistem."</string>
+    <string name="permlab_movePackage" msgid="3289890271645921411">"Alih sumber apl"</string>
+    <string name="permdesc_movePackage" msgid="319562217778244524">"Membenarkan apl untuk memindahkan sumber apl dari media dalaman ke luaran dan sebaliknya."</string>
     <string name="permlab_readLogs" msgid="6615778543198967614">"baca data log sensitif"</string>
-    <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"Membenarkan aplikasi membaca daripada pelbagai fail log sistem. Hal ini membenarkannya menemui maklumat umum mengenai perkara yang anda lakukan dengan tablet, juga berpotensi menemui maklumat persendirian dan peribadi."</string>
-    <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Membenarkan aplikasi membaca daripada pelbagai fail log sistem. Hal ini membenarkannya menemui maklumat umum mengenai perkara yang anda lakukan dengan telefon, juga berpotensi menyertakan maklumat persendirian dan peribadi."</string>
+    <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"Membenarkan apl membaca daripada pelbagai fail log sistem. Hal ini membenarkannya menemui maklumat umum mengenai perkara yang anda lakukan dengan tablet, juga berpotensi menemui maklumat persendirian dan peribadi."</string>
+    <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Membenarkan apl membaca daripada pelbagai fail log sistem. Hal ini membenarkannya menemui maklumat umum mengenai perkara yang anda lakukan dengan telefon, juga berpotensi menyertakan maklumat persendirian dan peribadi."</string>
+    <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"gunakan mana-mana penyahkod media untuk main semula"</string>
+    <string name="permdesc_anyCodecForPlayback" msgid="2101444559995480174">"Membenarkan aplikasi untuk menggunakan mana-mana penyahkod media yang dipasang untuk menyahkod main semula."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"baca/tulis ke sumber yang dimiliki oleh diag"</string>
-    <string name="permdesc_diagnostic" msgid="6608295692002452283">"Membenarkan aplikasi membaca dan menulis ke sebarang sumber yang dimiliki oleh kumpulan diag; contohnya, fail dalam /dev. Hal ini berpotensi menjejaskan kestabilan dan keselamatan sistem. Perkara ini HANYA harus digunakan untuk diagnosis khusus perkakasan oleh pengilang atau pengendali."</string>
-    <string name="permlab_changeComponentState" msgid="6335576775711095931">"dayakan atau lumpuhkan komponen aplikasi"</string>
-    <string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Membenarkan aplikasi untuk menukar sama ada komponen aplikasi lain didayakan atau tidak. Aplikasi berniat jahat boleh menggunakan ini untuk melumpuhkan keupayaan telefon yang penting. Berhati-hati semasa menggunakan kebenaran ini, kerana ia boleh menjadikan komponen aplikasi berada dalam keadaan tidak boleh digunakan, tidak konsisten, atau tidak stabil."</string>
-    <string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Membenarkan aplikasi untuk menukar sama ada komponen aplikasi lain didayakan atau tidak. Aplikasi berniat jahat boleh menggunakan ini untuk melumpuhkan keupayaan telefon yang penting. Berhati-hati semasa menggunakan kebenaran ini, kerana ia boleh menjadikan komponen aplikasi berada dalam keadaan tidak boleh digunakan, tidak konsisten, atau tidak stabil."</string>
-    <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"tetapkan keutamaan aplikasi"</string>
-    <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Membenarkan aplikasi untuk mengubah suai aplikasi pilihan anda. Aplikasi berniat jahat secara diam-diam boleh menukar aplikasi yang dijalankan, menipu aplikasi anda yang sedia ada untuk mengumpul data peribadi daripada anda."</string>
+    <string name="permdesc_diagnostic" msgid="6608295692002452283">"Membenarkan apl membaca dan menulis ke sebarang sumber yang dimiliki oleh kumpulan diag; contohnya, fail dalam /dev. Hal ini berpotensi menjejaskan kestabilan dan keselamatan sistem. Perkara ini seharusnya HANYA digunakan untuk diagnosis khusus perkakasan oleh pengilang atau pengendali."</string>
+    <string name="permlab_changeComponentState" msgid="6335576775711095931">"dayakan atau lumpuhkan komponen apl"</string>
+    <string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Membenarkan apl untuk menukar sama ada komponen apl lain didayakan atau tidak. Apl hasad boleh menggunakannya untuk melumpuhkan keupayaan telefon yang penting. Berhati-hati semasa menggunakan kebenaran ini, kerana hal ini boleh menjadikan komponen apl berada dalam keadaan tidak boleh digunakan, tidak konsisten, atau tidak stabil."</string>
+    <string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Membenarkan apl untuk menukar sama ada komponen apl lain didayakan atau tidak. Apl hasad boleh menggunakannya untuk melumpuhkan keupayaan telefon yang penting. Berhati-hati semasa menggunakan kebenaran ini, kerana hal ini boleh menjadikan komponen apl berada dalam keadaan tidak boleh digunakan, tidak konsisten, atau tidak stabil."</string>
+    <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"tetapkan keutamaan apl"</string>
+    <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Membenarkan apl untuk mengubah suai apl pilihan anda. Apl hasad secara diam-diam boleh menukar apl yang dijalankan, menipu apl anda yang sedia ada untuk mengumpul data peribadi daripada anda."</string>
     <string name="permlab_writeSettings" msgid="1365523497395143704">"mengubah suai tetapan sistem global"</string>
-    <string name="permdesc_writeSettings" msgid="7775723441558907181">"Membenarkan aplikasi untuk mengubah suai data tetapan sistem. Aplikasi berniat jahat boleh merosakkan konfigurasi sistem anda."</string>
+    <string name="permdesc_writeSettings" msgid="7775723441558907181">"Membenarkan apl untuk mengubah suai data tetapan sistem. Apl hasad boleh merosakkan konfigurasi sistem anda."</string>
     <string name="permlab_writeSecureSettings" msgid="204676251876718288">"ubah suai tetapan sistem selamat"</string>
-    <string name="permdesc_writeSecureSettings" msgid="8159535613020137391">"Membenarkan aplikasi untuk mengubah suai data tetapan selamat sistem. Bukan untuk digunakan oleh aplikasi biasa."</string>
+    <string name="permdesc_writeSecureSettings" msgid="8159535613020137391">"Membenarkan apl untuk mengubah suai data tetapan selamat sistem. Bukan untuk digunakan oleh apl biasa."</string>
     <string name="permlab_writeGservices" msgid="2149426664226152185">"mengubah suai peta perkhidmatan Google"</string>
-    <string name="permdesc_writeGservices" msgid="1287309437638380229">"Membolehkan aplikasi mengubah suai peta perkhidmatan Google. Bukan untuk kegunaan oleh aplikasi biasa."</string>
+    <string name="permdesc_writeGservices" msgid="1287309437638380229">"Membolehkan apl mengubah suai peta perkhidmatan Google. Bukan untuk kegunaan oleh apl biasa."</string>
     <string name="permlab_receiveBootCompleted" msgid="7776779842866993377">"mulakan secara automatik semasa but"</string>
-    <string name="permdesc_receiveBootCompleted" product="tablet" msgid="7390304664116880704">"Membenarkan aplikasi untuk memulakan dirinya sendiri sebaik sahaja sistem selesai mengebut. Ini boleh membuat masa untuk menghidupkan tablet menjadi lebih lama dan membenarkan aplikasi untuk memperlahankan keseluruhan tablet dengan sentiasa berjalan."</string>
-    <string name="permdesc_receiveBootCompleted" product="default" msgid="513950589102617504">"Membenarkan aplikasi bermula sendiri sebaik sahaja sistem telah selesai mengebut. Ini boleh menjadikannya mengambil masa yang lama untuk menghidupkan telefon dan membenarkan aplikasi untuk melambatkan keseluruhan telefon dengan sentiasa berjalan."</string>
+    <string name="permdesc_receiveBootCompleted" product="tablet" msgid="7390304664116880704">"Membenarkan apl untuk memulakan dirinya sendiri sebaik sahaja sistem selesai mengebut. Ini boleh membuat masa untuk menghidupkan tablet menjadi lebih lama dan membenarkan apl untuk memperlahankan keseluruhan tablet dengan sentiasa berjalan."</string>
+    <string name="permdesc_receiveBootCompleted" product="default" msgid="513950589102617504">"Membenarkan apl bermula sendiri sebaik sahaja sistem telah selesai mengebut. Ini boleh menjadikannya mengambil masa yang lama untuk menghidupkan telefon dan membenarkan apl untuk melambatkan keseluruhan telefon dengan sentiasa berjalan."</string>
     <string name="permlab_broadcastSticky" msgid="7919126372606881614">"hantar siaran lekit"</string>
-    <string name="permdesc_broadcastSticky" product="tablet" msgid="1181582512022829259">"Membolehkan aplikasi untuk menghantar siaran melekat, yang kekal selepas siaran berakhir. Aplikasi berniat jahat boleh membuat tablet perlahan atau tidak stabil dengan menyebabkannya menggunakan memori yang terlalu banyak."</string>
-    <string name="permdesc_broadcastSticky" product="default" msgid="3287869131621514325">"Membolehkan aplikasi untuk menghantar siaran melekat, yang kekal selepas siaran berakhir. Aplikasi berniat jahat boleh membuat telefon perlahan atau tidak stabil dengan menyebabkannya menggunakan memori yang terlalu banyak."</string>
+    <string name="permdesc_broadcastSticky" product="tablet" msgid="1181582512022829259">"Membolehkan apl untuk menghantar siaran melekit, yang kekal selepas siaran berakhir. Apl hasad boleh membuat tablet perlahan atau tidak stabil dengan menyebabkannya menggunakan memori yang terlalu banyak."</string>
+    <string name="permdesc_broadcastSticky" product="default" msgid="3287869131621514325">"Membolehkan apl untuk menghantar siaran melekit, yang kekal selepas siaran berakhir. Apl hasad boleh membuat telefon perlahan atau tidak stabil dengan menyebabkannya menggunakan memori yang terlalu banyak."</string>
     <string name="permlab_readContacts" msgid="6219652189510218240">"baca data kenalan"</string>
-    <string name="permdesc_readContacts" product="tablet" msgid="4028657556924039119">"Membenarkan aplikasi untuk membaca semua data kenalan (alamat) yang disimpan pada tablet anda. Aplikasi berniat jahat boleh menggunakan ini untuk menghantar data anda kepada orang lain."</string>
-    <string name="permdesc_readContacts" product="default" msgid="2032222056456498547">"Membenarkan aplikasi untuk membaca semua data kenalan (alamat) yang disimpan pada telefon anda. Aplikasi berniat jahat boleh menggunakan ini untuk menghantar data anda kepada orang lain."</string>
+    <string name="permdesc_readContacts" product="tablet" msgid="4028657556924039119">"Membenarkan apl untuk membaca semua data kenalan (alamat) yang disimpan pada tablet anda. Apl hasad boleh menggunakannya untuk menghantar data anda kepada orang lain."</string>
+    <string name="permdesc_readContacts" product="default" msgid="2032222056456498547">"Membenarkan apl untuk membaca semua data kenalan (alamat) yang disimpan pada telefon anda. Apl hasad boleh menggunakannya untuk menghantar data anda kepada orang lain."</string>
     <string name="permlab_writeContacts" msgid="644616215860933284">"tulis data kenalan"</string>
-    <string name="permdesc_writeContacts" product="tablet" msgid="988969759110632978">"Membenarkan aplikasi untuk mengubah suai data kenalan (alamat) yang disimpan pada tablet anda. Aplikasi berniat jahat boleh menggunakan ini untuk memadam atau mengubah suai data kenalan anda."</string>
-    <string name="permdesc_writeContacts" product="default" msgid="5075164818647934067">"Membenarkan aplikasi untuk mengubah suai data kenalan (alamat) yang disimpan pada telefon anda. Aplikasi berniat jahat boleh menggunakan ini untuk memadam atau mengubah suai data kenalan anda."</string>
+    <string name="permdesc_writeContacts" product="tablet" msgid="988969759110632978">"Membenarkan apl untuk mengubah suai data kenalan (alamat) yang disimpan pada tablet anda. Apl hasad boleh menggunakannya untuk memadam atau mengubah suai data kenalan anda."</string>
+    <string name="permdesc_writeContacts" product="default" msgid="5075164818647934067">"Membenarkan apl untuk mengubah suai data kenalan (alamat) yang disimpan pada telefon anda. Apl hasad boleh menggunakannya untuk memadam atau mengubah suai data kenalan anda."</string>
     <string name="permlab_readProfile" msgid="6824681438529842282">"baca data profil anda"</string>
-    <string name="permdesc_readProfile" product="default" msgid="94520753797630679">"Membenarkan aplikasi untuk membaca maklumat profil peribadi yang disimpan dalam peranti anda, seperti nama dan maklumat kenalan anda. Ini bermakna aplikasi lain boleh mengenal pasti anda dan menghantar maklumat profil anda kepada orang lain."</string>
+    <string name="permdesc_readProfile" product="default" msgid="94520753797630679">"Membenarkan apl untuk membaca maklumat profil peribadi yang disimpan dalam peranti anda, seperti nama dan maklumat kenalan anda. Ini bermakna apl lain boleh mengenal pasti anda dan menghantar maklumat profil anda kepada orang lain."</string>
     <string name="permlab_writeProfile" msgid="4679878325177177400">"tulis ke data profil anda"</string>
-    <string name="permdesc_writeProfile" product="default" msgid="4637366723793045603">"Membenarkan aplikasi untuk menukar atau menambah maklumat profil peribadi yang disimpan dalam peranti anda, seperti nama dan maklumat kenalan anda. Ini bermakna aplikasi lain boleh mengenal pasti anda dan menghantar maklumat profil anda kepada orang lain."</string>
+    <string name="permdesc_writeProfile" product="default" msgid="4637366723793045603">"Membenarkan apl untuk menukar atau menambah maklumat profil peribadi yang disimpan dalam peranti anda, seperti nama dan maklumat kenalan anda. Ini bermakna apl lain boleh mengenal pasti anda dan menghantar maklumat profil anda kepada orang lain."</string>
     <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"baca aliran sosial anda"</string>
-    <string name="permdesc_readSocialStream" product="default" msgid="3419050808547335320">"Membenarkan aplikasi mengakses dan menyegerakkan kemas kini sosial daripada rakan-rakan anda. Aplikasi berniat jahat boleh menggunakan ini untuk membaca komunikasi peribadi di antara anda dan rakan-rakan anda pada rangkaian sosial."</string>
+    <string name="permdesc_readSocialStream" product="default" msgid="3419050808547335320">"Membenarkan apl mengakses dan menyegerakkan kemas kini sosial daripada rakan-rakan anda. Apl hasad boleh menggunakannya untuk membaca komunikasi peribadi di antara anda dan rakan-rakan anda pada rangkaian sosial."</string>
     <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"tulis ke aliran sosial anda"</string>
-    <string name="permdesc_writeSocialStream" product="default" msgid="3496277176955721451">"Membenarkan aplikasi memaparkan kemas kini sosial daripada rakan-rakan anda. Aplikasi berniat jahat boleh menggunakan ini untuk berpura-pura menjadi rakan dan memperdayakan anda untuk mendedahkan kata laluan atau maklumat sulit lain."</string>
+    <string name="permdesc_writeSocialStream" product="default" msgid="3496277176955721451">"Membenarkan apl memaparkan kemas kini sosial daripada rakan-rakan anda. Apl hasad boleh menggunakannya untuk berpura-pura menjadi rakan dan memperdayakan anda untuk mendedahkan kata laluan atau maklumat sulit lain."</string>
     <string name="permlab_readCalendar" msgid="5972727560257612398">"baca acara kalendar serta maklumat sulit"</string>
-    <string name="permdesc_readCalendar" product="tablet" msgid="2338414551004122687">"Membenarkan aplikasi untuk membaca semua acara kalendar yang disimpan pada tablet anda, termasuk milik rakan atau rakan sekerja. Aplikasi berniat jahat boleh mengekstrak maklumat peribadi dari kalendar ini tanpa pengetahuan pemilik."</string>
-    <string name="permdesc_readCalendar" product="default" msgid="5693933067751827753">"Membenarkan aplikasi untuk membaca semua acara kalendar yang disimpan pada tablet anda, termasuk milik rakan atau rakan sekerja. Aplikasi berniat jahat boleh mengekstrak maklumat peribadi dari kalendar ini tanpa pengetahuan pemilik."</string>
+    <string name="permdesc_readCalendar" product="tablet" msgid="2338414551004122687">"Membenarkan apl untuk membaca semua acara kalendar yang disimpan pada tablet anda, termasuk milik rakan atau rakan sekerja. Apl hasad boleh mengekstrak maklumat peribadi dari kalendar ini tanpa pengetahuan pemilik."</string>
+    <string name="permdesc_readCalendar" product="default" msgid="5693933067751827753">"Membenarkan apl untuk membaca semua acara kalendar yang disimpan pada tablet anda, termasuk milik rakan atau rakan sekerja. Apl hasad boleh mengekstrak maklumat peribadi dari kalendar sebegini tanpa pengetahuan pemilik."</string>
     <string name="permlab_writeCalendar" msgid="8438874755193825647">"tambah atau ubah suai acara kalendar dan hantar e-mel kepada tetamu tanpa pengetahuan pemilik"</string>
-    <string name="permdesc_writeCalendar" msgid="2243771395254848873">"Membenarkan aplikasi untuk menghantar jemputan acara sebagai pemilik kalendar dan menambah, membuang, menukar acara yang boleh anda ubah suai pada peranti anda, termasuk milik rakan-rakan atau rakan sekerja. Aplikasi berniat jahat boleh menghantar e-mel spam yang kelihatan seperti datang daripada pemilik kalendar, mengubah suai acara tanpa pengetahuan pemilik, atau menambah acara palsu."</string>
+    <string name="permdesc_writeCalendar" msgid="2243771395254848873">"Membenarkan apl untuk menghantar jemputan acara sebagai pemilik kalendar dan menambah, membuang, menukar acara yang boleh anda ubah suai pada peranti anda, termasuk milik rakan-rakan atau rakan sekerja. Apl hasad boleh menghantar e-mel spam yang kelihatan seperti datang daripada pemilik kalendar, mengubah suai acara tanpa pengetahuan pemilik, atau menambah acara palsu."</string>
     <string name="permlab_accessMockLocation" msgid="8688334974036823330">"gunakan sumber lokasi olok-olok untuk pengujian"</string>
-    <string name="permdesc_accessMockLocation" msgid="7577931556422993949">"Buat sumber lokasi palsu untuk ujian. Aplikasi berniat jahat boleh menggunakannya untuk menolak lokasi dan/atau status yang dikembalikan oleh sumber lokasi sebenar seperti GPS atau pembekal Rangkaian."</string>
+    <string name="permdesc_accessMockLocation" msgid="7577931556422993949">"Buat sumber lokasi palsu untuk ujian. Apl hasad boleh menggunakannya untuk menolak lokasi dan/atau status yang dikembalikan oleh sumber lokasi sebenar seperti GPS atau pembekal Rangkaian."</string>
     <string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"akses perintah tambahan pembekal lokasi"</string>
-    <string name="permdesc_accessLocationExtraCommands" msgid="6737736970602176133">"Membenarkan aplikasi untuk mengakses arahan pembekal lokasi tambahan. Aplikasi berniat jahat boleh menggunakan ini untuk campur tangan dengan operasi GPS atau sumber lokasi lain."</string>
+    <string name="permdesc_accessLocationExtraCommands" msgid="6737736970602176133">"Membenarkan apl untuk mengakses arahan pembekal lokasi tambahan. Apl hasad boleh menggunakannya untuk campur tangan dengan operasi GPS atau sumber lokasi lain."</string>
     <string name="permlab_installLocationProvider" msgid="6578101199825193873">"kebenaran untuk memasang pembekal lokasi"</string>
-    <string name="permdesc_installLocationProvider" msgid="1742577679350078373">"Buat sumber lokasi palsu untuk ujian. Aplikasi berniat jahat boleh menggunakannya untuk menolak lokasi dan/atau status yang dikembalikan oleh sumber lokasi sebenar seperti GPS atau pembekal Rangkaian atau memantau dan melaporkan lokasi anda kepada sumber luaran."</string>
+    <string name="permdesc_installLocationProvider" msgid="1742577679350078373">"Buat sumber lokasi palsu untuk ujian. Apl hasad boleh menggunakannya untuk menolak lokasi dan/atau status yang dikembalikan oleh sumber lokasi sebenar seperti GPS atau pembekal Rangkaian atau memantau dan melaporkan lokasi anda kepada sumber luaran."</string>
     <string name="permlab_accessFineLocation" msgid="8116127007541369477">"perhalusi lokasi (GPS)"</string>
-    <string name="permdesc_accessFineLocation" product="tablet" msgid="5326423948268164934">"Mengakses sumber lokasi diperhalus seperti Sistem Kedudukan Sejagat pada tablet, sekiranya ada. Aplikasi berniat jahat boleh menggunakannya untuk menentukan lokasi anda dan boleh menggunakan kuasa bateri tambahan."</string>
-    <string name="permdesc_accessFineLocation" product="default" msgid="7130267914433890869">"Mengakses sumber lokasi halus seperti Sistem Kedudukan Sejagat pada telefon, sekiranya ada. Aplikasi berniat jahat boleh menggunakannya untuk menentukan lokasi anda dan boleh menggunakan kuasa bateri tambahan."</string>
+    <string name="permdesc_accessFineLocation" product="tablet" msgid="5326423948268164934">"Mengakses sumber lokasi diperhalus seperti Sistem Kedudukan Sejagat pada tablet, sekiranya ada. Apl hasad boleh menggunakannya untuk menentukan lokasi anda dan boleh menggunakan kuasa bateri tambahan."</string>
+    <string name="permdesc_accessFineLocation" product="default" msgid="7130267914433890869">"Mengakses sumber lokasi halus seperti Sistem Kedudukan Sejagat pada telefon, sekiranya ada. Apl hasad boleh menggunakannya untuk menentukan lokasi anda dan boleh menggunakan kuasa bateri tambahan."</string>
     <string name="permlab_accessCoarseLocation" msgid="4642255009181975828">"lokasi kasar (berasaskan rangkaian)"</string>
-    <string name="permdesc_accessCoarseLocation" product="tablet" msgid="5460726396318105483">"Mengakses sumber lokasi kasar seperti pangkalan data rangkaian selular untuk menentukan lokasi anggaran tablet, sekiranya ada. Aplikasi berniat jahat boleh menggunakannya untuk menentukan anggaran tempat anda berada."</string>
-    <string name="permdesc_accessCoarseLocation" product="default" msgid="8900795778057579522">"Mengakses sumber lokasi kasar seperti pangkalan data rangkaian selular untuk menentukan lokasi anggaran telefon, jika tersedia. Aplikasi berniat jahat boleh menggunakannya untuk menentukan di mana anda berada."</string>
+    <string name="permdesc_accessCoarseLocation" product="tablet" msgid="5460726396318105483">"Mengakses sumber lokasi kasar seperti pangkalan data rangkaian selular untuk menentukan lokasi anggaran tablet, sekiranya ada. Apl hasad boleh menggunakannya untuk menentukan anggaran tempat anda berada."</string>
+    <string name="permdesc_accessCoarseLocation" product="default" msgid="8900795778057579522">"Mengakses sumber lokasi kasar seperti pangkalan data rangkaian selular untuk menentukan lokasi anggaran telefon, jika tersedia. Apl hasad boleh menggunakannya untuk menentukan di mana anda berada."</string>
     <string name="permlab_accessSurfaceFlinger" msgid="2363969641792388947">"akses SurfaceFlinger"</string>
-    <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Membenarkan aplikasi menggunakan ciri peringkat rendah SurfaceFlinger."</string>
+    <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Membenarkan apl menggunakan ciri peringkat rendah SurfaceFlinger."</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"baca penimbal bingkai"</string>
-    <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Membenarkan aplikasi membaca kandungan penimbal bingkai."</string>
+    <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Membenarkan apl membaca kandungan penimbal bingkai."</string>
     <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"tukar tetapan audio anda"</string>
-    <string name="permdesc_modifyAudioSettings" msgid="7343951185408396919">"Membolehkan aplikasi mengubah suai tetapan audio global seperti kelantangan dan penghalaan."</string>
+    <string name="permdesc_modifyAudioSettings" msgid="7343951185408396919">"Membolehkan apl mengubah suai tetapan audio global seperti kelantangan dan penghalaan."</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"rakam audio"</string>
-    <string name="permdesc_recordAudio" msgid="2387462233976248635">"Membenarkan aplikasi mengakses laluan rakaman audio."</string>
+    <string name="permdesc_recordAudio" msgid="2387462233976248635">"Membenarkan apl mengakses laluan rakaman audio."</string>
     <string name="permlab_camera" msgid="3616391919559751192">"ambil gambar dan video"</string>
-    <string name="permdesc_camera" msgid="1507407407002492176">"Membenarkan aplikasi untuk mengambil gambar dan video dengan kamera. Ini membolehkan aplikasi pada bila-bila masa mengumpul imej yang kamera lihat."</string>
+    <string name="permdesc_camera" msgid="1507407407002492176">"Membenarkan apl untuk mengambil gambar dan video menggunakan kamera. Ini membolehkan apl pada bila-bila masa mengumpul imej yang kamera lihat."</string>
     <string name="permlab_brick" product="tablet" msgid="2961292205764488304">"melumpuhkan tablet secara kekal"</string>
     <string name="permlab_brick" product="default" msgid="8337817093326370537">"lumpuhkan telefon secara kekal"</string>
-    <string name="permdesc_brick" product="tablet" msgid="4334818808001699530">"Membenarkan aplikasi melumpuhkan keseluruhan tablet secara kekal. Ini amat berbahaya."</string>
-    <string name="permdesc_brick" product="default" msgid="5788903297627283099">"Membenarkan aplikasi melumpuhkan keseluruhan telefon secara kekal. Ini amat berbahaya."</string>
+    <string name="permdesc_brick" product="tablet" msgid="4334818808001699530">"Membenarkan apl melumpuhkan keseluruhan tablet secara kekal. Ini amat berbahaya."</string>
+    <string name="permdesc_brick" product="default" msgid="5788903297627283099">"Membenarkan apl melumpuhkan keseluruhan telefon secara kekal. Ini amat berbahaya."</string>
     <string name="permlab_reboot" product="tablet" msgid="3436634972561795002">"memaksa tablet but semula"</string>
     <string name="permlab_reboot" product="default" msgid="2898560872462638242">"paksa telefon but semula"</string>
-    <string name="permdesc_reboot" product="tablet" msgid="8172056180063700741">"Membenarkan aplikasi memaksa tablet untuk but semula."</string>
-    <string name="permdesc_reboot" product="default" msgid="5326008124289989969">"Membenarkan aplikasi memaksa telefon untuk but semula."</string>
+    <string name="permdesc_reboot" product="tablet" msgid="8172056180063700741">"Membenarkan apl memaksa tablet untuk but semula."</string>
+    <string name="permdesc_reboot" product="default" msgid="5326008124289989969">"Membenarkan apl memaksa telefon untuk but semula."</string>
     <string name="permlab_mount_unmount_filesystems" msgid="1761023272170956541">"melekapkan dan menyahlekapkan sistem fail"</string>
-    <string name="permdesc_mount_unmount_filesystems" msgid="1829290701658992347">"Membenarkan aplikasi melekapkan dan menyahlekapkan sistem fail untuk storan boleh alih."</string>
+    <string name="permdesc_mount_unmount_filesystems" msgid="1829290701658992347">"Membenarkan apl melekapkan dan menyahlekapkan sistem fail untuk storan boleh alih."</string>
     <string name="permlab_mount_format_filesystems" msgid="5523285143576718981">"format storan luaran"</string>
-    <string name="permdesc_mount_format_filesystems" msgid="8784268246779198627">"Membenarkan aplikasi memformatkan storan boleh alih."</string>
+    <string name="permdesc_mount_format_filesystems" msgid="8784268246779198627">"Membenarkan apl memformatkan storan boleh alih."</string>
     <string name="permlab_asec_access" msgid="3411338632002193846">"dapatkan maklumat tentang storan dalaman"</string>
-    <string name="permdesc_asec_access" msgid="3094563844593878548">"Membenarkan aplikasi mendapatkan maklumat dari storan dalaman."</string>
+    <string name="permdesc_asec_access" msgid="3094563844593878548">"Membenarkan apl mendapatkan maklumat dari storan dalaman."</string>
     <string name="permlab_asec_create" msgid="6414757234789336327">"buat storan dalaman"</string>
-    <string name="permdesc_asec_create" msgid="4558869273585856876">"Membenarkan aplikasi membuat storan dalaman."</string>
+    <string name="permdesc_asec_create" msgid="4558869273585856876">"Membenarkan apl membuat storan dalaman."</string>
     <string name="permlab_asec_destroy" msgid="526928328301618022">"memusnahkan storan dalaman"</string>
-    <string name="permdesc_asec_destroy" msgid="7218749286145526537">"Membenarkan aplikasi memusnahkan storan dalaman."</string>
+    <string name="permdesc_asec_destroy" msgid="7218749286145526537">"Membenarkan apl memusnahkan storan dalaman."</string>
     <string name="permlab_asec_mount_unmount" msgid="8877998101944999386">"lekap/nyahlekap storan dalaman"</string>
-    <string name="permdesc_asec_mount_unmount" msgid="3451360114902490929">"Membenarkan aplikasi melekapkan/menyahlekapkan storan dalaman."</string>
+    <string name="permdesc_asec_mount_unmount" msgid="3451360114902490929">"Membenarkan apl melekapkan/menyahlekapkan storan dalaman."</string>
     <string name="permlab_asec_rename" msgid="7496633954080472417">"namakan semula storan dalaman"</string>
-    <string name="permdesc_asec_rename" msgid="1794757588472127675">"Membenarkan aplikasi menamakan semula storan dalaman."</string>
+    <string name="permdesc_asec_rename" msgid="1794757588472127675">"Membenarkan apl menamakan semula storan dalaman."</string>
     <string name="permlab_vibrate" msgid="7768356019980849603">"kawal penggetar"</string>
-    <string name="permdesc_vibrate" msgid="6284989245902300945">"Membenarkan aplikasi mengawal penggetar."</string>
+    <string name="permdesc_vibrate" msgid="6284989245902300945">"Membenarkan apl mengawal penggetar."</string>
     <string name="permlab_flashlight" msgid="2155920810121984215">"mengawal lampu suluh"</string>
-    <string name="permdesc_flashlight" msgid="6522284794568368310">"Membenarkan aplikasi mengawal lampu suluh."</string>
+    <string name="permdesc_flashlight" msgid="6522284794568368310">"Membenarkan apl mengawal lampu suluh."</string>
     <string name="permlab_manageUsb" msgid="1113453430645402723">"urus pilihan dan kebenaran untuk peranti USB"</string>
-    <string name="permdesc_manageUsb" msgid="7776155430218239833">"Membenarkan aplikasi untuk menguruskan pilihan dan kebenaran untuk peranti USB."</string>
+    <string name="permdesc_manageUsb" msgid="7776155430218239833">"Membenarkan apl untuk menguruskan pilihan dan kebenaran untuk peranti USB."</string>
     <string name="permlab_accessMtp" msgid="4953468676795917042">"laksanakan protokol MTP"</string>
     <string name="permdesc_accessMtp" msgid="6532961200486791570">"Membenarkan akses kepada pemacu inti MTP untuk melaksanakan protokol USB MTP."</string>
     <string name="permlab_hardware_test" msgid="4148290860400659146">"uji perkakasan"</string>
-    <string name="permdesc_hardware_test" msgid="6597964191208016605">"Membenarkan aplikasi mengawal pelbagai persisian untuk tujuan pengujian perkakasan."</string>
+    <string name="permdesc_hardware_test" msgid="6597964191208016605">"Membenarkan apl mengawal pelbagai persisian untuk tujuan pengujian perkakasan."</string>
     <string name="permlab_callPhone" msgid="3925836347681847954">"panggil terus nombor telefon"</string>
-    <string name="permdesc_callPhone" msgid="6396463004110544744">"Membenarkan aplikasi untuk memanggil nombor telefon tanpa campur tangan anda. Aplikasi berniat jahat boleh menyebabkan panggilan yang tidak dijangka pada bil telefon anda. Sila maklum bahawa ini tidak membenarkan aplikasi untuk memanggil nombor kecemasan."</string>
+    <string name="permdesc_callPhone" msgid="6396463004110544744">"Membenarkan apl untuk memanggil nombor telefon tanpa campur tangan anda. Apl hasad boleh menyebabkan panggilan yang tidak dijangka pada bil telefon anda. Sila maklum bahawa ini tidak membenarkan apl untuk memanggil nombor kecemasan."</string>
     <string name="permlab_callPrivileged" msgid="4198349211108497879">"panggil terus sebarang nombor telefon"</string>
-    <string name="permdesc_callPrivileged" msgid="1689024901509996810">"Membenarkan aplikasi untuk memanggil mana-mana nombor telefon, termasuk nombor kecemasan, tanpa campur tangan anda. Aplikasi berniat jahat boleh membuat panggilan yang tidak perlu dan salah di sisi undang-undang kepada perkhidmatan kecemasan."</string>
+    <string name="permdesc_callPrivileged" msgid="1689024901509996810">"Membenarkan apl untuk memanggil mana-mana nombor telefon, termasuk nombor kecemasan, tanpa campur tangan anda. Apl hasad boleh membuat panggilan yang tidak perlu dan salah di sisi undang-undang ke perkhidmatan kecemasan."</string>
     <string name="permlab_performCdmaProvisioning" product="tablet" msgid="4842576994144604821">"mulakan terus persediaan tablet CDMA"</string>
     <string name="permlab_performCdmaProvisioning" product="default" msgid="5604848095315421425">"memulakan persediaan telefon CDMA secara langsung"</string>
-    <string name="permdesc_performCdmaProvisioning" msgid="1994193538802314186">"Membenarkan aplikasi memulakan peruntukan CDMA. Aplikasi berniat jahat boleh memulakan peruntukan CDMA yang tidak perlu"</string>
+    <string name="permdesc_performCdmaProvisioning" msgid="1994193538802314186">"Membenarkan apl memulakan peruntukan CDMA. Apl hasad boleh memulakan peruntukan CDMA yang tidak perlu."</string>
     <string name="permlab_locationUpdates" msgid="7785408253364335740">"kawal pemberitahuan kemas kini lokasi"</string>
-    <string name="permdesc_locationUpdates" msgid="1120741557891438876">"Membenarkan aplikasi untuk mendayakan/melumpuhkan pemberitahuan kemas kini lokasi dari radio. Bukan untuk kegunaan aplikasi biasa."</string>
+    <string name="permdesc_locationUpdates" msgid="1120741557891438876">"Membenarkan apl untuk mendayakan/melumpuhkan pemberitahuan kemas kini lokasi dari radio. Bukan untuk kegunaan apl biasa."</string>
     <string name="permlab_checkinProperties" msgid="7855259461268734914">"akses sifat daftar masuk"</string>
-    <string name="permdesc_checkinProperties" msgid="4024526968630194128">"Membenarkan aplikasi membaca/menulis akses kepada sifat yang dimuat naik oleh perkhidmatan checkin. Bukan untuk digunakan oleh aplikasi biasa."</string>
+    <string name="permdesc_checkinProperties" msgid="4024526968630194128">"Membenarkan apl membaca/menulis akses kepada sifat yang dimuat naik oleh perkhidmatan checkin. Bukan untuk digunakan oleh apl biasa."</string>
     <string name="permlab_bindGadget" msgid="776905339015863471">"pilih widget"</string>
-    <string name="permdesc_bindGadget" msgid="8261326938599049290">"Membenarkan aplikasi untuk memberitahu sistem widget mana yang boleh digunakan oleh aplikasi mana. Aplikasi dengan kebenaran ini boleh memberi akses kepada data peribadi kepada aplikasi lain. Bukan untuk digunakan oleh aplikasi biasa."</string>
+    <string name="permdesc_bindGadget" msgid="8261326938599049290">"Membenarkan apl untuk memberitahu sistem widget mana yang boleh digunakan oleh apl yang mana. Apl dengan kebenaran ini boleh memberi akses kepada data peribadi kepada apl lain. Bukan untuk digunakan oleh apl biasa."</string>
     <string name="permlab_modifyPhoneState" msgid="8423923777659292228">"ubah suai keadaan telefon"</string>
-    <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Membenarkan aplikasi untuk mengawal ciri-ciri telefon peranti. Aplikasi dengan kebenaran ini boleh menukar rangkaian, menghidupkan dan mematikan radio telefon dan sebagainya tanpa memberitahu anda."</string>
+    <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Membenarkan apl untuk mengawal ciri-ciri telefon peranti. Apl dengan kebenaran ini boleh menukar rangkaian, menghidupkan dan mematikan radio telefon dan sebagainya tanpa memberitahu anda."</string>
     <string name="permlab_readPhoneState" msgid="2326172951448691631">"baca keadaan dan identiti telefon"</string>
-    <string name="permdesc_readPhoneState" msgid="5127767618743602782">"Membenarkan aplikasi untuk mengakses ciri-ciri telefon peranti. Aplikasi dengan kebenaran ini boleh menentukan nombor telefon dan nombor siri telefon ini, sama ada panggilan aktif, nombor panggilan itu disambungkan dan sebagainya."</string>
+    <string name="permdesc_readPhoneState" msgid="5127767618743602782">"Membenarkan apl untuk mengakses ciri-ciri telefon peranti. Apl dengan kebenaran ini boleh menentukan nombor telefon dan nombor siri telefon ini, sama ada panggilan aktif, nombor kepada panggilan itu disambungkan dan sebagainya."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"menghalang tablet daripada tidur"</string>
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"halang telefon daripada tidur"</string>
-    <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Membenarkan aplikasi menghalang tablet daripada tidur."</string>
-    <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Membenarkan aplikasi menghalang telefon daripada tidur."</string>
+    <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Membenarkan apl menghalang tablet daripada tidur."</string>
+    <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Membenarkan apl menghalang telefon daripada tidur."</string>
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"menghidupkan atau mematikan kuasa tablet"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"kuasakan telefon hidup atau mati"</string>
-    <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"Membenarkan aplikasi menghidupkan atau mematikan tablet."</string>
-    <string name="permdesc_devicePower" product="default" msgid="6037057348463131032">"Membenarkan aplikasi menghidupkan atau mematikan telefon."</string>
+    <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"Membenarkan apl menghidupkan atau mematikan tablet."</string>
+    <string name="permdesc_devicePower" product="default" msgid="6037057348463131032">"Membenarkan apl menghidupkan atau mematikan telefon."</string>
     <string name="permlab_factoryTest" msgid="3715225492696416187">"jalankan dalam mod ujian kilang"</string>
     <string name="permdesc_factoryTest" product="tablet" msgid="3952059318359653091">"Jalankan sebagai ujian pengeluar peringkat rendah, membenarkan akses penuh kepada perkakasan tablet. Hanya tersedia apabila tablet dijalankan dalam mod ujian pengeluar."</string>
     <string name="permdesc_factoryTest" product="default" msgid="8136644990319244802">"Menjalankan sebagai ujian pengilang peringkat rendah, membenarkan akses penuh kepada perkakasan telefon. Hanya tersedia apabila telefon dijalankan dalam mod ujian pengilang."</string>
     <string name="permlab_setWallpaper" msgid="6627192333373465143">"tetapkan kertas dinding"</string>
-    <string name="permdesc_setWallpaper" msgid="7373447920977624745">"Membenarkan aplikasi menetapkan kertas dinding sistem."</string>
+    <string name="permdesc_setWallpaper" msgid="7373447920977624745">"Membenarkan apl menetapkan kertas dinding sistem."</string>
     <string name="permlab_setWallpaperHints" msgid="3600721069353106851">"tetapkan pembayang saiz kertas dinding"</string>
-    <string name="permdesc_setWallpaperHints" msgid="8235784384223730091">"Membenarkan aplikasi menetapkan pembayang saiz kertas dinding sistem."</string>
+    <string name="permdesc_setWallpaperHints" msgid="8235784384223730091">"Membenarkan apl menetapkan pembayang saiz kertas dinding sistem."</string>
     <string name="permlab_masterClear" msgid="2315750423139697397">"menetapkan semula sistem kepada lalai kilang"</string>
-    <string name="permdesc_masterClear" msgid="3665380492633910226">"Membenarkan aplikasi untuk menetapkan semula sistem kepada tetapan kilang sepenuhnya, memadam semua data, konfigurasi, dan aplikasi yang dipasang."</string>
+    <string name="permdesc_masterClear" msgid="3665380492633910226">"Membenarkan apl untuk menetapkan semula sistem kepada tetapan kilang sepenuhnya, memadam semua data, konfigurasi, dan apl yang dipasang."</string>
     <string name="permlab_setTime" msgid="2021614829591775646">"tetapkan masa"</string>
-    <string name="permdesc_setTime" product="tablet" msgid="1896341438151152881">"Membenarkan aplikasi untuk menukar masa jam tablet."</string>
-    <string name="permdesc_setTime" product="default" msgid="1855702730738020">"Membolehkan aplikasi untuk menukar waktu jam telefon."</string>
+    <string name="permdesc_setTime" product="tablet" msgid="1896341438151152881">"Membenarkan apl untuk menukar masa jam tablet."</string>
+    <string name="permdesc_setTime" product="default" msgid="1855702730738020">"Membolehkan apl untuk menukar waktu jam telefon."</string>
     <string name="permlab_setTimeZone" msgid="2945079801013077340">"tetapkan zon waktu"</string>
-    <string name="permdesc_setTimeZone" product="tablet" msgid="1676983712315827645">"Membenarkan aplikasi menukar zon waktu tablet."</string>
-    <string name="permdesc_setTimeZone" product="default" msgid="4499943488436633398">"Membenarkan aplikasi menukar zon waktu telefon."</string>
+    <string name="permdesc_setTimeZone" product="tablet" msgid="1676983712315827645">"Membenarkan apl menukar zon waktu tablet."</string>
+    <string name="permdesc_setTimeZone" product="default" msgid="4499943488436633398">"Membenarkan apl menukar zon waktu telefon."</string>
     <string name="permlab_accountManagerService" msgid="4829262349691386986">"bertindak sebagai PerkhidmatanPengurusAkaun"</string>
-    <string name="permdesc_accountManagerService" msgid="2684502137670299915">"Membenarkan aplikasi membuat panggilan ke Pengesah Akaun"</string>
+    <string name="permdesc_accountManagerService" msgid="2684502137670299915">"Membenarkan apl membuat panggilan kepada Pengesah Akaun"</string>
     <string name="permlab_getAccounts" msgid="4549918644233460103">"menemui akaun yang diketahui"</string>
-    <string name="permdesc_getAccounts" product="tablet" msgid="3238360555257773358">"Membenarkan aplikasi mendapatkan senarai akaun yang diketahui tablet."</string>
-    <string name="permdesc_getAccounts" product="default" msgid="2735689364629830348">"Membenarkan aplikasi mendapatkan senarai akaun yang diketahui telefon."</string>
+    <string name="permdesc_getAccounts" product="tablet" msgid="3238360555257773358">"Membenarkan apl mendapatkan senarai akaun yang diketahui tablet."</string>
+    <string name="permdesc_getAccounts" product="default" msgid="2735689364629830348">"Membenarkan apl mendapatkan senarai akaun yang diketahui telefon."</string>
     <string name="permlab_authenticateAccounts" msgid="3940505577982882450">"sebagai pengesah akaun"</string>
-    <string name="permdesc_authenticateAccounts" msgid="5472124296908977260">"Membenarkan aplikasi menggunakan kebolehan pengesah akaun Pengurus Akaun, termasuk membuat akaun dan mendapatkan serta menetapkan kata laluannya."</string>
+    <string name="permdesc_authenticateAccounts" msgid="5472124296908977260">"Membenarkan apl menggunakan kebolehan pengesah akaun Pengurus Akaun, termasuk membuat akaun dan mendapatkan serta menetapkan kata laluannya."</string>
     <string name="permlab_manageAccounts" msgid="4440380488312204365">"urus senarai akaun"</string>
-    <string name="permdesc_manageAccounts" msgid="8698295625488292506">"Membenarkan aplikasi melaksanakan operasi seperti menambah dan mengalih keluar akaun dan memadamkan kata laluannya."</string>
+    <string name="permdesc_manageAccounts" msgid="8698295625488292506">"Membenarkan apl melaksanakan operasi seperti menambah dan mengalih keluar akaun dan memadamkan kata laluannya."</string>
     <string name="permlab_useCredentials" msgid="6401886092818819856">"menggunakan bukti kelayakan pengesahan akaun"</string>
-    <string name="permdesc_useCredentials" msgid="7984227147403346422">"Membenarkan aplikasi meminta token pengesahan."</string>
+    <string name="permdesc_useCredentials" msgid="7984227147403346422">"Membenarkan apl meminta token pengesahan."</string>
     <string name="permlab_accessNetworkState" msgid="6865575199464405769">"lihat keadaan rangkaian"</string>
-    <string name="permdesc_accessNetworkState" msgid="479772796952547198">"Membenarkan aplikasi melihat keadaan semua rangkaian."</string>
+    <string name="permdesc_accessNetworkState" msgid="479772796952547198">"Membenarkan apl melihat keadaan semua rangkaian."</string>
     <string name="permlab_createNetworkSockets" msgid="9121633680349549585">"akses penuh Internet"</string>
-    <string name="permdesc_createNetworkSockets" msgid="5963922297444265950">"Membenarkan aplikasi membuat soket rangkaian."</string>
+    <string name="permdesc_createNetworkSockets" msgid="5963922297444265950">"Membenarkan apl membuat soket rangkaian."</string>
     <string name="permlab_writeApnSettings" msgid="505660159675751896">"mengubah/memintas tetapan dan lalu lintas rangkaian"</string>
-    <string name="permdesc_writeApnSettings" msgid="5333798886412714193">"Membenarkan aplikasi untuk menukar tetapan rangkaian dan untuk memintas serta memeriksa semua trafik rangkaian, contohnya untuk menukar proksi dan port mana-mana APN. Aplikasi berniat jahat boleh memantau, mengubah hala, atau mengubah suai paket rangkaian tanpa pengetahuan anda."</string>
+    <string name="permdesc_writeApnSettings" msgid="5333798886412714193">"Membenarkan apl untuk menukar tetapan rangkaian dan untuk memintas serta memeriksa semua trafik rangkaian, contohnya untuk menukar proksi dan port mana-mana APN. Apl hasad boleh memantau, mengubah hala, atau mengubah suai paket rangkaian tanpa pengetahuan anda."</string>
     <string name="permlab_changeNetworkState" msgid="958884291454327309">"tukar kesambungan rangkaian"</string>
-    <string name="permdesc_changeNetworkState" msgid="6789123912476416214">"Membenarkan aplikasi untuk mengubah keadaan kesambungan rangkaian."</string>
+    <string name="permdesc_changeNetworkState" msgid="6789123912476416214">"Membenarkan apl untuk mengubah keadaan kesambungan rangkaian."</string>
     <string name="permlab_changeTetherState" msgid="5952584964373017960">"tukar kesambungan bertambat"</string>
-    <string name="permdesc_changeTetherState" msgid="1524441344412319780">"Membenarkan aplikasi untuk mengubah keadaan kesambungan rangkaian tambatan."</string>
+    <string name="permdesc_changeTetherState" msgid="1524441344412319780">"Membenarkan apl untuk mengubah keadaan kesambungan rangkaian tambatan."</string>
     <string name="permlab_changeBackgroundDataSetting" msgid="1400666012671648741">"tukar tetapan penggunaan data latar belakang"</string>
-    <string name="permdesc_changeBackgroundDataSetting" msgid="5347729578468744379">"Membenarkan aplikasi menukar tetapan penggunaan data latar belakang."</string>
+    <string name="permdesc_changeBackgroundDataSetting" msgid="5347729578468744379">"Membenarkan apl menukar tetapan penggunaan data latar belakang."</string>
     <string name="permlab_accessWifiState" msgid="8100926650211034400">"lihat keadaan Wi-Fi"</string>
-    <string name="permdesc_accessWifiState" msgid="7770452658226256831">"Membenarkan aplikasi melihat maklumat mengenai keadaan Wi-Fi."</string>
+    <string name="permdesc_accessWifiState" msgid="7770452658226256831">"Membenarkan apl melihat maklumat mengenai keadaan Wi-Fi."</string>
     <string name="permlab_changeWifiState" msgid="7280632711057112137">"ubah keadaan Wi-Fi"</string>
-    <string name="permdesc_changeWifiState" msgid="7399961004537946240">"Membenarkan aplikasi menyambung ke dan memutuskan sambungan dari titik capaian Wi-Fi dan membuat perubahan pada rangkaian Wi-Fi yang telah dikonfigurasikan."</string>
+    <string name="permdesc_changeWifiState" msgid="7399961004537946240">"Membenarkan apl menyambung ke dan memutuskan sambungan dari titik capaian Wi-Fi dan membuat perubahan pada rangkaian Wi-Fi yang telah dikonfigurasikan."</string>
     <string name="permlab_changeWifiMulticastState" msgid="1368253871483254784">"benarkan penerimaan Wi-Fi Multisiar"</string>
-    <string name="permdesc_changeWifiMulticastState" msgid="7633598524564320817">"Membenarkan aplikasi menerima bingkisan yang tidak ditujukan secara langsung ke peranti anda. Hal ini boleh menjadi berguna apabila menemui perkhidmatan yang ditawarkan di kawasan berdekatan. Ia menggunakan lebih banyak kuasa daripada mod bukan multisiar."</string>
-    <string name="permlab_bluetoothAdmin" msgid="3606576270792236062">"pentadbiran Bluetooth"</string>
-    <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"Membenarkan aplikasi mengkonfigurasikan tablet Bluetooth setempat dan menemui serta berpasangan dengan peranti jauh."</string>
-    <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"Membenarkan aplikasi mengkonfigurasikan telefon Bluetooth setempat dan menemui serta berpasangan dengan peranti jauh."</string>
-    <!-- outdated translation 2800410363171809280 -->     <string name="permlab_accessWimaxState" msgid="1232061307208861588">"lihat keadaan WiMAX"</string>
+    <string name="permdesc_changeWifiMulticastState" msgid="7633598524564320817">"Membenarkan apl menerima bingkisan yang tidak ditujukan secara langsung ke peranti anda. Hal ini boleh menjadi berguna apabila menemui perkhidmatan yang ditawarkan di kawasan berdekatan. Ia menggunakan lebih banyak kuasa daripada mod bukan multisiar."</string>
+    <string name="permlab_bluetoothAdmin" msgid="3606576270792236062">"Pentadbiran Bluetooth"</string>
+    <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"Membenarkan apl mengkonfigurasikan tablet Bluetooth setempat dan menemui serta berpasangan dengan peranti jauh."</string>
+    <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"Membenarkan apl mengkonfigurasikan telefon Bluetooth setempat dan menemui serta berpasangan dengan peranti jauh."</string>
+    <string name="permlab_accessWimaxState" msgid="1232061307208861588">"Lihat keadaan WiMAX"</string>
     <string name="permdesc_accessWimaxState" msgid="8298035866227524023">"Membolehkan aplikasi melihat maklumat mengenai keadaan WiMAX."</string>
-    <!-- outdated translation 340465839241528618 -->     <string name="permlab_changeWimaxState" msgid="2405042267131496579">"tukar keadaan WiMAX"</string>
+    <string name="permlab_changeWimaxState" msgid="2405042267131496579">"Tukar keadaan WiMAX"</string>
     <string name="permdesc_changeWimaxState" msgid="474918005058989421">"Membenarkan aplikasi untuk menyambung dan memutuskan sambungan dari rangkaian WiMAX."</string>
     <string name="permlab_bluetooth" msgid="8361038707857018732">"buat sambungan Bluetooth"</string>
-    <string name="permdesc_bluetooth" product="tablet" msgid="7007851048416363446">"Membenarkan aplikasi melihat konfigurasi tablet Bluetooth setempat dan membuat dan menerima sambungan dengan peranti yang dipasangkan."</string>
-    <string name="permdesc_bluetooth" product="default" msgid="31846362767164948">"Membenarkan aplikasi melihat konfigurasi telefon Bluetooth setempat dan membuat dan menerima sambungan dengan peranti yang dipasangkan."</string>
+    <string name="permdesc_bluetooth" product="tablet" msgid="7007851048416363446">"Membenarkan apl melihat konfigurasi tablet Bluetooth setempat dan membuat dan menerima sambungan dengan peranti yang dipasangkan."</string>
+    <string name="permdesc_bluetooth" product="default" msgid="31846362767164948">"Membenarkan apl melihat konfigurasi telefon Bluetooth setempat dan membuat dan menerima sambungan dengan peranti yang dipasangkan."</string>
     <string name="permlab_nfc" msgid="4423351274757876953">"mengawal Komunikasi Medan Dekat"</string>
-    <string name="permdesc_nfc" msgid="7120611819401789907">"Membenarkan aplikasi berkomunikasi dengan teg, kad dan pembaca Komunikasi Medan Dekat (NFC)."</string>
+    <string name="permdesc_nfc" msgid="7120611819401789907">"Membenarkan apl berkomunikasi dengan teg, kad dan pembaca Komunikasi Medan Dekat (NFC)."</string>
     <string name="permlab_disableKeyguard" msgid="4977406164311535092">"lumpuhkan kunci kekunci"</string>
-    <string name="permdesc_disableKeyguard" msgid="6231611286892232626">"Membenarkan aplikasi melumpuhkan kunci kekunci dan sebarang keselamatan kata laluan yang berkaitan. Contoh yang berkaitan adalah telefon melumpuhkan kunci kekunci apabila menerima panggilan telefon masuk kemudian mendayakan semula kunci kekunci apabila panggilan selesai."</string>
+    <string name="permdesc_disableKeyguard" msgid="6231611286892232626">"Membenarkan apl melumpuhkan kunci kekunci dan sebarang keselamatan kata laluan yang berkaitan. Contoh yang berkaitan ialah telefon melumpuhkan kunci kekunci apabila menerima panggilan telefon masuk kemudian mendayakan semula kunci kekunci apabila panggilan selesai."</string>
     <string name="permlab_readSyncSettings" msgid="6201810008230503052">"membaca tetapan penyegerakan"</string>
-    <string name="permdesc_readSyncSettings" msgid="5464056785274229278">"Membenarkan aplikasi untuk membaca tetapan penyegerakan, seperti sama ada penyegerakan didayakan untuk aplikasi Orang."</string>
+    <string name="permdesc_readSyncSettings" msgid="5464056785274229278">"Membenarkan apl untuk membaca tetapan penyegerakan, seperti sama ada penyegerakan didayakan untuk apl Orang."</string>
     <string name="permlab_writeSyncSettings" msgid="6297138566442486462">"tulis tetapan penyegerakan"</string>
-    <string name="permdesc_writeSyncSettings" msgid="1466056564502117130">"Membenarkan aplikasi untuk mengubah suai tetapan penyegerakan, seperti sama ada penyegerakan didayakan untuk aplikasi Orang."</string>
+    <string name="permdesc_writeSyncSettings" msgid="1466056564502117130">"Membenarkan apl untuk mengubah suai tetapan penyegerakan, seperti sama ada penyegerakan didayakan untuk apl Orang."</string>
     <string name="permlab_readSyncStats" msgid="7396577451360202448">"baca statistik penyegerakan"</string>
-    <string name="permdesc_readSyncStats" msgid="3801971839939951678">"Membenarkan aplikasi membaca statistik penyegerakan; cth., sejarah penyegerakan yang telah berlaku."</string>
+    <string name="permdesc_readSyncStats" msgid="3801971839939951678">"Membenarkan apl membaca statistik penyegerakan; cth., sejarah penyegerakan yang telah berlaku."</string>
     <string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"baca suapan langganan"</string>
-    <string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Membenarkan aplikasi mendapatkan butiran mengenai suapan tersegerak semasa."</string>
+    <string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Membenarkan apl mendapatkan butiran mengenai suapan tersegerak semasa."</string>
     <string name="permlab_subscribedFeedsWrite" msgid="9015246325408209296">"tulis suapan yang dilanggan"</string>
-    <string name="permdesc_subscribedFeedsWrite" msgid="6928930188826089413">"Membenarkan aplikasi untuk mengubah suai suapan segerakan semasa anda. Aplikasi berniat jahat boleh menukar suapan segerakan anda."</string>
+    <string name="permdesc_subscribedFeedsWrite" msgid="6928930188826089413">"Membenarkan apl untuk mengubah suai suapan segerakan semasa anda. Apl hasad boleh menukar suapan anda yang disegerakkan."</string>
     <string name="permlab_readDictionary" msgid="8410247960433376352">"baca kamus ditakrifkan pengguna"</string>
-    <string name="permdesc_readDictionary" msgid="8977815988329283705">"Membenarkan aplikasi membaca sebarang kata-kata peribadi, nama dan frasa yang mungkin telah disimpan oleh pengguna dalam kamus pengguna."</string>
+    <string name="permdesc_readDictionary" msgid="8977815988329283705">"Membenarkan apl membaca sebarang kata-kata peribadi, nama dan frasa yang mungkin telah disimpan oleh pengguna dalam kamus pengguna."</string>
     <string name="permlab_writeDictionary" msgid="2296383164914812772">"tulis ke kamus yang ditakrifkan pengguna"</string>
-    <string name="permdesc_writeDictionary" msgid="8185385716255065291">"Membenarkan aplikasi menulis perkataan baharu ke dalam kamus pengguna."</string>
+    <string name="permdesc_writeDictionary" msgid="8185385716255065291">"Membenarkan apl menulis perkataan baharu ke dalam kamus pengguna."</string>
     <string name="permlab_sdcardWrite" product="nosdcard" msgid="85430876310764752">"ubah suai/padam kdgn storn USB"</string>
     <string name="permlab_sdcardWrite" product="default" msgid="8079403759001777291">"ubah suai/padamkan kandungan kad SD"</string>
-    <string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"Membenarkan aplikasi menulis ke storan USB."</string>
-    <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Membenarkan aplikasi menulis ke kad SD."</string>
+    <string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"Membenarkan apl menulis ke storan USB."</string>
+    <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Membenarkan apl menulis ke kad SD."</string>
     <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"ubh suai/pdm kdg strn mdia dlm"</string>
-    <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Membenarkan aplikasi mengubah suai kandungan storan media dalaman."</string>
+    <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Membenarkan apl mengubah suai kandungan storan media dalaman."</string>
     <string name="permlab_cache_filesystem" msgid="5656487264819669824">"akses sistem fail cache"</string>
-    <string name="permdesc_cache_filesystem" msgid="5578967642265550955">"Membenarkan aplikasi membaca dan menulis cache sistem fail."</string>
+    <string name="permdesc_cache_filesystem" msgid="5578967642265550955">"Membenarkan apl membaca dan menulis cache sistem fail."</string>
     <string name="permlab_use_sip" msgid="5986952362795870502">"membuat/menerima panggilan Internet"</string>
-    <string name="permdesc_use_sip" msgid="4717632000062674294">"Membenarkan aplikasi menggunakan perkhidmatan SIP untuk membuat/menerima panggilan Internet."</string>
+    <string name="permdesc_use_sip" msgid="4717632000062674294">"Membenarkan apl menggunakan perkhidmatan SIP untuk membuat/menerima panggilan Internet."</string>
     <string name="permlab_readNetworkUsageHistory" msgid="7862593283611493232">"baca sejarah penggunaan rangkaian"</string>
-    <string name="permdesc_readNetworkUsageHistory" msgid="7689060749819126472">"Membenarkan aplikasi membaca sejarah penggunaan rangkaian untuk rangkaian dan aplikasi khusus."</string>
+    <string name="permdesc_readNetworkUsageHistory" msgid="7689060749819126472">"Membenarkan apl membaca sejarah penggunaan rangkaian untuk rangkaian dan apl khusus."</string>
     <string name="permlab_manageNetworkPolicy" msgid="2562053592339859990">"urus dasar rangkaian"</string>
-    <string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"Membenarkan aplikasi mengurus dasar rangkaian dan menentukan peraturan khusus aplikasi."</string>
+    <string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"Membenarkan apl mengurus dasar rangkaian dan menentukan peraturan khusus apl."</string>
     <string name="permlab_modifyNetworkAccounting" msgid="5088217309088729650">"ubah suai perakaunan penggunaan rangkaian"</string>
-    <string name="permdesc_modifyNetworkAccounting" msgid="8553240749784321765">"Membenarkan aplikasi untuk mengubah suai bagaimana penggunaan rangkaian diambil kira terhadap aplikasi. Bukan untuk digunakan oleh aplikasi biasa."</string>
+    <string name="permdesc_modifyNetworkAccounting" msgid="8553240749784321765">"Membenarkan apl untuk mengubah suai bagaimana penggunaan rangkaian diambil kira terhadap apl. Bukan untuk digunakan oleh apl biasa."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Tetapkan peraturan kata laluan"</string>
     <string name="policydesc_limitPassword" msgid="9083400080861728056">"Mengawal panjang dan aksara yang dibenarkan dalam kata laluan buka kunci skrin"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Memantau percubaan buka kunci skrin"</string>
-    <string name="policydesc_watchLogin" product="tablet" msgid="3215729294215070072">"Memantau bilangan kata laluan yang tidak betul yang ditaip apabila membuka skrin, dan mengunci tablet atau memadam semua data tablet jika terlalu banyak kata laluan yang salah ditaip."</string>
+    <string name="policydesc_watchLogin" product="tablet" msgid="3215729294215070072">"Memantau bilangan kata laluan yang tersilap ditaip apabila membuka skrin, dan mengunci tablet atau memadam semua data tablet jika terlalu banyak kesilapan menaip kata laluan."</string>
     <string name="policydesc_watchLogin" product="default" msgid="5712323091846761073">"Memantau bilangan kata laluan salah yang ditaip semasa membuka skrin, dan mengunci telefon atau memadam semua data telefon jika terlalu banyak kata laluan salah ditaip."</string>
     <string name="policylab_resetPassword" msgid="2620077191242688955">"Tukar kata laluan buka kunci skrin"</string>
     <string name="policydesc_resetPassword" msgid="5391240616981297361">"Tukar kata laluan buka kunci skrin"</string>
@@ -523,7 +525,7 @@
     <string name="policylab_expirePassword" msgid="885279151847254056">"Ttpkn tmt tmph k/lln kci skrin"</string>
     <string name="policydesc_expirePassword" msgid="4844430354224822074">"Mengawal kekerapan penukaran kata laluan kunci skrin"</string>
     <string name="policylab_encryptedStorage" msgid="8901326199909132915">"Tetapkan penyulitan storan"</string>
-    <string name="policydesc_encryptedStorage" msgid="8877192718681120469">"Memerlukan data aplikasi yang disimpan itu disulitkan"</string>
+    <string name="policydesc_encryptedStorage" msgid="8877192718681120469">"Memerlukan data apl yang disimpan itu disulitkan"</string>
     <string name="policylab_disableCamera" msgid="6395301023152297826">"Lumpuhkan kamera"</string>
     <string name="policydesc_disableCamera" msgid="5680054212889413366">"Menghalang penggunaan semua kamera peranti"</string>
   <string-array name="phoneTypes">
@@ -640,9 +642,9 @@
     <string name="sipAddressTypeWork" msgid="6920725730797099047">"Kerja"</string>
     <string name="sipAddressTypeOther" msgid="4408436162950119849">"Lain-lain"</string>
     <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Taip kod PIN"</string>
-    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Taip PUK dan kod PIN baru"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Taip PUK dan kod PIN baharu"</string>
     <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"Kod PUK"</string>
-    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Kod PIN Baru"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Kod PIN Baharu"</string>
     <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Sentuh untuk menaip kata laluan"</font></string>
     <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Taip kata laluan untuk membuka kunci"</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Taip PIN untuk membuka kunci"</string>
@@ -680,11 +682,11 @@
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Lihat Panduan Pengguna atau hubungi Penjagaan Pelanggan."</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"Kad SIM dikunci."</string>
     <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"Membuka kunci kad SIM..."</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Anda telah melukis corak buka kunci anda dengan salah sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. "\n\n"Sila cuba lagi dalam <xliff:g id="NUMBER_1">%d</xliff:g> saat."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Anda telah menaip kata laluan anda secara salah sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. "\n\n"Cuba lagi dalam <xliff:g id="NUMBER_1">%d</xliff:g> saat."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Anda telah menaip PIN anda secara salah sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. "\n\n"Cuba lagi dalam <xliff:g id="NUMBER_1">%d</xliff:g> saat."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Anda telah melukis corak buka kunci secara salah sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. Selepas <xliff:g id="NUMBER_1">%d</xliff:g> lagi percubaan yang tidak berjaya, anda akan diminta membuka kunci tablet anda menggunakan log masuk Google anda."\n\n" Cuba lagi dalam <xliff:g id="NUMBER_2">%d</xliff:g> saat."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Anda telah melukis corak buka kunci dengan salah sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. Selepas <xliff:g id="NUMBER_1">%d</xliff:g> lagi percubaan yang tidak berjaya, anda akan diminta membuka kunci telefon anda menggunakan log masuk Google anda."\n\n" Sila cuba lagi dalam <xliff:g id="NUMBER_2">%d</xliff:g> saat."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Anda telah tersilap melukis corak buka kunci anda sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. "\n\n"Sila cuba lagi dalam <xliff:g id="NUMBER_1">%d</xliff:g> saat."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Anda telah tersilap taip menaip kata laluan anda sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. "\n\n"Cuba lagi dalam <xliff:g id="NUMBER_1">%d</xliff:g> saat."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Anda telah tersilap taip PIN anda sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. "\n\n"Cuba lagi dalam <xliff:g id="NUMBER_1">%d</xliff:g> saat."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Anda telah tersilap melukis corak buka kunci sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. Selepas <xliff:g id="NUMBER_1">%d</xliff:g> lagi percubaan yang tidak berjaya, anda akan diminta membuka kunci tablet anda menggunakan log masuk Google anda."\n\n" Cuba lagi dalam <xliff:g id="NUMBER_2">%d</xliff:g> saat."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Anda telah tersilap lukis corak buka kunci sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. Selepas <xliff:g id="NUMBER_1">%d</xliff:g> lagi percubaan yang tidak berjaya, anda akan diminta membuka kunci telefon anda menggunakan log masuk Google anda."\n\n" Sila cuba lagi dalam <xliff:g id="NUMBER_2">%d</xliff:g> saat."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Anda telah mencuba untuk membuka kunci tablet dengan salah sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. Selepas <xliff:g id="NUMBER_1">%d</xliff:g> lagi percubaan yang tidak berjaya, tablet akan ditetapkan semula kepada tetapan lalai kilang dan semua data pengguna akan hilang."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Anda telah mencuba untuk membuka kunci telefon dengan salah sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. Selepas <xliff:g id="NUMBER_1">%d</xliff:g> lagi percubaan yang tidak berjaya, telefon akan ditetapkan semula kepada tetapan lalai kilang dan semua data pengguna akan hilang."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Anda telah mencuba untuk membuka kunci tablet secara salah sebanyak <xliff:g id="NUMBER">%d</xliff:g> kali. Tablet kini akan ditetapkan semula ke tetapan lalai kilang."</string>
@@ -740,20 +742,20 @@
     <string name="autofill_area" msgid="3547409050889952423">"Kawasan"</string>
     <string name="autofill_emirate" msgid="2893880978835698818">"Emiriah"</string>
     <string name="permlab_readHistoryBookmarks" msgid="1284843728203412135">"baca sejarah dan penanda halaman Penyemak imbas"</string>
-    <string name="permdesc_readHistoryBookmarks" msgid="4577476392604595921">"Membenarkan aplikasi membaca semua URL yang telah dilawati oleh Penyemak Imbas dan semua penanda halaman Penyemak Imbas."</string>
+    <string name="permdesc_readHistoryBookmarks" msgid="4577476392604595921">"Membenarkan apl membaca semua URL yang telah dilawati oleh Penyemak Imbas dan semua penanda halaman Penyemak Imbas."</string>
     <string name="permlab_writeHistoryBookmarks" msgid="9009434109836280374">"tulis sejarah dan penanda halaman Penyemak Imbas"</string>
-    <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="1757103804824209530">"Membenarkan aplikasi untuk mengubah suai sejarah atau penanda buku Penyemak Imbas yang disimpan di dalam tablet anda. Aplikasi berniat jahat boleh menggunakan ini untuk memadam atau mengubah suai data Penyemak Imbas anda."</string>
-    <string name="permdesc_writeHistoryBookmarks" product="default" msgid="6693764355720719197">"Membenarkan aplikasi untuk mengubah suai sejarah atau penanda buku Penyemak Imbas yang disimpan di dalam telefon anda. Aplikasi berniat jahat boleh menggunakan ini untuk memadam atau mengubah suai data Penyemak Imbas anda."</string>
+    <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="1757103804824209530">"Membenarkan apl untuk mengubah suai sejarah atau penanda buku Penyemak Imbas yang disimpan di dalam tablet anda. Apl hasad boleh menggunakannya untuk memadam atau mengubah suai data Penyemak Imbas anda."</string>
+    <string name="permdesc_writeHistoryBookmarks" product="default" msgid="6693764355720719197">"Membenarkan apl untuk mengubah suai sejarah atau penanda buku Penyemak Imbas yang disimpan di dalam telefon anda. Apl hasad boleh menggunakannya untuk memadam atau mengubah suai data Penyemak Imbas anda."</string>
     <string name="permlab_setAlarm" msgid="5924401328803615165">"menetapkan penggera pada jam penggera"</string>
-    <string name="permdesc_setAlarm" msgid="316392039157473848">"Membenarkan aplikasi untuk menetapkan penggera dalam aplikasi penggera jam yang dipasang. Sesetengah applikasi jam penggera tidak boleh melaksanakan ciri ini."</string>
+    <string name="permdesc_setAlarm" msgid="316392039157473848">"Membenarkan apl untuk menetapkan penggera dalam apl penggera jam yang dipasang. Sesetengah applikasi jam penggera tidak boleh melaksanakan ciri ini."</string>
     <string name="permlab_addVoicemail" msgid="5525660026090959044">"tambah mel suara"</string>
-    <string name="permdesc_addVoicemail" msgid="6604508651428252437">"Membenarkan aplikasi untuk menambahkan mesej pada peti masuk mel suara anda."</string>
+    <string name="permdesc_addVoicemail" msgid="6604508651428252437">"Membenarkan apl untuk menambahkan mesej pada peti masuk mel suara anda."</string>
     <string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"ubah suai kebenaran geolokasi Penyemak Imbas"</string>
-    <string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"Membenarkan aplikasi untuk mengubah suai kebenaran geolokasi Penyemak Imbas. Aplikasi berniat jahat boleh menggunakan ini untuk membenarkan menghantar maklumat lokasi kepada laman web sembarangan."</string>
+    <string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"Membenarkan apl untuk mengubah suai kebenaran geolokasi Penyemak Imbas. Apl hasad boleh menggunakannya untuk membenarkan menghantar maklumat lokasi kepada laman web sembarangan."</string>
     <string name="permlab_packageVerificationAgent" msgid="5568139100645829117">"sahkan pakej"</string>
-    <string name="permdesc_packageVerificationAgent" msgid="8437590190990843381">"Membenarkan aplikasi untuk mengesahkan bahawa pakej boleh dipasang."</string>
+    <string name="permdesc_packageVerificationAgent" msgid="8437590190990843381">"Membenarkan apl untuk mengesahkan bahawa pakej boleh dipasang."</string>
     <string name="permlab_bindPackageVerifier" msgid="4187786793360326654">"ikat kepada pengesah pakej"</string>
-    <string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"Membenarkan pemegang membuat permintaan pengesah pakej. Tidak akan diperlukan untuk aplikasi normal."</string>
+    <string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"Membenarkan pemegang membuat permintaan pengesah pakej. Tidak sekali-kali diperlukan untuk apl normal."</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>
@@ -857,9 +859,9 @@
     <string name="weeks" msgid="6509623834583944518">"minggu"</string>
     <string name="year" msgid="4001118221013892076">"tahun"</string>
     <string name="years" msgid="6881577717993213522">"tahun"</string>
-    <string name="VideoView_error_title" msgid="5927895235831021723">"Tidak boleh memainkan video."</string>
+    <string name="VideoView_error_title" msgid="5927895235831021723">"Tidak dapat memainkan video."</string>
     <string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"Maaf, video ini tidak sah untuk penstriman ke peranti ini."</string>
-    <string name="VideoView_error_text_unknown" msgid="4309847331399592194">"Maaf, video ini tidak boleh dimainkan."</string>
+    <string name="VideoView_error_text_unknown" msgid="4309847331399592194">"Maaf, video ini tidak dapat dimainkan."</string>
     <string name="VideoView_error_button" msgid="2822238215100679592">"OK"</string>
     <string name="relative_time" msgid="1818557177829411417">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="noon" msgid="7245353528818587908">"tengah hari"</string>
@@ -894,10 +896,10 @@
     <string name="capital_off" msgid="6815870386972805832">"MATIKAN"</string>
     <string name="whichApplication" msgid="4533185947064773386">"Selesaikan tindakan menggunakan"</string>
     <string name="alwaysUse" msgid="4583018368000610438">"Gunakannya secara lalai untuk tindakan ini."</string>
-    <string name="clearDefaultHintMsg" msgid="3252584689512077257">"Padam bersih lalai dalam tetapan Sistem &gt; Aplikasi &gt; Dimuat turun."</string>
+    <string name="clearDefaultHintMsg" msgid="3252584689512077257">"Padam bersih lalai dalam tetapan Sistem &gt; Apl &gt; Dimuat turun."</string>
     <string name="chooseActivity" msgid="1009246475582238425">"Pilih tindakan"</string>
-    <string name="chooseUsbActivity" msgid="6894748416073583509">"Pilih aplikasi untuk peranti USB"</string>
-    <string name="noApplications" msgid="2991814273936504689">"Tiada aplikasi yang boleh menjalankan tindakan ini."</string>
+    <string name="chooseUsbActivity" msgid="6894748416073583509">"Pilih apl untuk peranti USB"</string>
+    <string name="noApplications" msgid="2991814273936504689">"Tiada apl yang boleh menjalankan tindakan ini."</string>
     <string name="aerr_title" msgid="1905800560317137752"></string>
     <string name="aerr_application" msgid="932628488013092776">"Malangnya, <xliff:g id="APPLICATION">%1$s</xliff:g> telah berhenti."</string>
     <string name="aerr_process" msgid="4507058997035697579">"Malangnya, proses <xliff:g id="PROCESS">%1$s</xliff:g> telah berhenti."</string>
@@ -909,26 +911,26 @@
     <string name="force_close" msgid="8346072094521265605">"OK"</string>
     <string name="report" msgid="4060218260984795706">"Laporkan"</string>
     <string name="wait" msgid="7147118217226317732">"Tunggu"</string>
-    <string name="launch_warning_title" msgid="1547997780506713581">"Aplikasi diubah hala"</string>
+    <string name="launch_warning_title" msgid="1547997780506713581">"Apl diubah hala"</string>
     <string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> kini sedang berjalan."</string>
     <string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g> pada asalnya telah dilancarkan."</string>
     <string name="screen_compat_mode_scale" msgid="3202955667675944499">"Skala"</string>
     <string name="screen_compat_mode_show" msgid="4013878876486655892">"Sentiasa tunjukkan"</string>
-    <string name="screen_compat_mode_hint" msgid="1064524084543304459">"Dayakan semula ini tetapan Sistem &gt; Aplikasi &gt; Dimuat turun."</string>
-    <string name="smv_application" msgid="3307209192155442829">"Aplikasi <xliff:g id="APPLICATION">%1$s</xliff:g> (proses <xliff:g id="PROCESS">%2$s</xliff:g>) telah melanggar dasar Mod Tegasnya sendiri."</string>
+    <string name="screen_compat_mode_hint" msgid="1064524084543304459">"Dayakan semula kod kompak ini tetapan Sistem &gt; Apl &gt; Dimuat turun."</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 dasar Mod Tegasnya sendiri."</string>
     <string name="smv_process" msgid="5120397012047462446">"Proses <xliff:g id="PROCESS">%1$s</xliff:g> telah melanggar dasar Mod Tegasnya sendiri."</string>
     <string name="android_upgrading_title" msgid="1584192285441405746">"Android sedang menaik taraf..."</string>
-    <string name="android_upgrading_apk" msgid="7904042682111526169">"Mengoptimumkan aplikasi <xliff:g id="NUMBER_0">%1$d</xliff:g> daripada <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
-    <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Memulakan aplikasi."</string>
+    <string name="android_upgrading_apk" msgid="7904042682111526169">"Mengoptimumkan apl <xliff:g id="NUMBER_0">%1$d</xliff:g> daripada <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
+    <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Memulakan apl."</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"But akhir."</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> dijalankan"</string>
-    <string name="heavy_weight_notification_detail" msgid="1721681741617898865">"Sentuh untuk bertukar ke aplikasi"</string>
-    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"Tukar aplikasi?"</string>
-    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"Aplikasi lain sudah pun dijalankan yang mesti dihentikan sebelum anda boleh memulakan yang baru."</string>
+    <string name="heavy_weight_notification_detail" msgid="1721681741617898865">"Sentuh untuk bertukar ke apl"</string>
+    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"Tukar apl?"</string>
+    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"Apl lain sudah pun dijalankan yang mesti dihentikan sebelum anda boleh memulakan yang baharu."</string>
     <string name="old_app_action" msgid="493129172238566282">"Kembali ke <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="old_app_description" msgid="2082094275580358049">"Jangan mulakan aplikasi baru."</string>
+    <string name="old_app_description" msgid="2082094275580358049">"Jangan mulakan apl baharu."</string>
     <string name="new_app_action" msgid="5472756926945440706">"Mulakan <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="new_app_description" msgid="1932143598371537340">"Hentikan aplikasi lama tanpa menyimpan."</string>
+    <string name="new_app_description" msgid="1932143598371537340">"Hentikan apl lama tanpa menyimpan."</string>
     <string name="sendText" msgid="5132506121645618310">"Pilih tindakan untuk teks"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"Kelantangan pendering"</string>
     <string name="volume_music" msgid="5421651157138628171">"Kelantangan media"</string>
@@ -971,7 +973,7 @@
     <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"Wi-Fi Direct dihidupkan"</string>
     <string name="wifi_p2p_enabled_notification_message" msgid="1638949953993894335">"Sentuh untuk tetapan"</string>
     <string name="select_character" msgid="3365550120617701745">"Masukkan aksara"</string>
-    <string name="sms_control_default_app_name" msgid="3058577482636640465">"Aplikasi tidak diketahui"</string>
+    <string name="sms_control_default_app_name" msgid="3058577482636640465">"Apl tidak diketahui"</string>
     <string name="sms_control_title" msgid="7296612781128917719">"Menghantar mesej SMS"</string>
     <string name="sms_control_message" msgid="4073755190243093924">"Sejumlah besar mesej SMS sedang dihantar. Sentuh \"OK\" untuk meneruskan atau \"Batal\" untuk menghentikan penghantaran."</string>
     <string name="sms_control_yes" msgid="2532062172402615953">"OK"</string>
@@ -1006,7 +1008,7 @@
     <string name="usb_storage_stop_button_mount" msgid="7060218034900696029">"Matikan storan USB"</string>
     <string name="usb_storage_stop_error_message" msgid="143881914840412108">"Terdapat masalah mematikan storan USB. Semak untuk memastikan anda sudah menyahlekap hos USB, kemudian cuba lagi."</string>
     <string name="dlg_confirm_kill_storage_users_title" msgid="963039033470478697">"Hidupkan storan USB."</string>
-    <string name="dlg_confirm_kill_storage_users_text" msgid="6206212680430268343">"Jika anda menghidupkan storan USB, sesetengah aplikasi yang anda sedang gunakan akan terhenti dan mungkin tidak akan tersedia sehingga anda memadamkan storan USB."</string>
+    <string name="dlg_confirm_kill_storage_users_text" msgid="6206212680430268343">"Jika anda menghidupkan storan USB, sesetengah apl yang anda sedang gunakan akan terhenti dan mungkin tidak akan tersedia sehingga anda memadamkan storan USB."</string>
     <string name="dlg_error_title" msgid="7323658469626514207">"Operasi USB tidak berjaya"</string>
     <string name="dlg_ok" msgid="7376953167039865701">"OK"</string>
     <string name="usb_mtp_notification_title" msgid="3699913097391550394">"Disambungkan sebagai peranti media"</string>
@@ -1051,9 +1053,9 @@
     <string name="ext_media_nomedia_notification_message" product="default" msgid="3870120652983659641">"Kad SD telah dikeluarkan. Masukkan yang baru."</string>
     <string name="activity_list_empty" msgid="4168820609403385789">"Tiada aktiviti yang sepadan ditemui"</string>
     <string name="permlab_pkgUsageStats" msgid="8787352074326748892">"kemas kini statistik penggunaan komponen"</string>
-    <string name="permdesc_pkgUsageStats" msgid="1106612424254277630">"Membenarkan aplikasi untuk mengubah suai statistik penggunaan komponen yang dikumpul. Bukan untuk kegunaan aplikasi biasa."</string>
+    <string name="permdesc_pkgUsageStats" msgid="1106612424254277630">"Membenarkan apl untuk mengubah suai statistik penggunaan komponen yang dikumpul. Bukan untuk kegunaan apl biasa."</string>
     <string name="permlab_copyProtectedData" msgid="4341036311211406692">"salin kandungan"</string>
-    <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Membenarkan aplikasi untuk menggunakan perkhidmatan bekas lalai untuk menyalin kandungan. Bukan untuk digunakan oleh aplikasi biasa."</string>
+    <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Membenarkan apl untuk menggunakan perkhidmatan bekas lalai untuk menyalin kandungan. Bukan untuk digunakan oleh apl biasa."</string>
     <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Sentuh dua kali untuk mendapatkan kawalan zum"</string>
     <string name="gadget_host_error_inflating" msgid="2613287218853846830">"Ralat mengembungkan widget"</string>
     <string name="ime_action_go" msgid="8320845651737369027">"Pergi"</string>
@@ -1065,7 +1067,7 @@
     <string name="ime_action_default" msgid="2840921885558045721">"Laksanakan"</string>
     <string name="dial_number_using" msgid="5789176425167573586">"Dail nombor"\n"menggunakan <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="create_contact_using" msgid="4947405226788104538">"Wujudkan kenalan"\n"menggunakan <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"Satu atau lebih aplikasi berikut meminta kebenaran untuk mengakses akaun anda, sekarang dan pada masa hadapan."</string>
+    <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"Satu atau lebih apl berikut meminta kebenaran untuk mengakses akaun anda, sekarang dan pada masa hadapan."</string>
     <string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"Adakah anda mahu membenarkan permintaan ini?"</string>
     <string name="grant_permissions_header_text" msgid="2722567482180797717">"Permintaan Akses"</string>
     <string name="allow" msgid="7225948811296386551">"Benarkan"</string>
@@ -1164,7 +1166,7 @@
     <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Perubahan mod"</string>
     <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
     <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Masuk"</string>
-    <string name="activitychooserview_choose_application" msgid="2125168057199941199">"Pilih aplikasi"</string>
+    <string name="activitychooserview_choose_application" msgid="2125168057199941199">"Pilih apl"</string>
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Kongsi dengan"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Kongsi dengan <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Pemegang gelongsor. Sentuh &amp; tahan."</string>
@@ -1219,4 +1221,7 @@
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"Kongsi dengan"</string>
     <string name="status_bar_device_locked" msgid="3092703448690669768">"Peranti dikunci."</string>
     <string name="list_delimeter" msgid="3975117572185494152">", "</string>
+    <string name="sending" msgid="8715108995741758718">"Menghantar..."</string>
+    <string name="launchBrowserDefault" msgid="2057951947297614725">"Lancarkan Penyemak Imbas?"</string>
+    <string name="SetupCallDefault" msgid="6870275517518479651">"Terima Panggilan?"</string>
 </resources>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index b63e0af..1575bfd 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -301,6 +301,8 @@
     <string name="permlab_readLogs" msgid="6615778543198967614">"lese sensitive loggdata"</string>
     <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"Lar appen lese fra diverse loggfiler på systemet. Disse inneholder generell informasjon om hva som gjøres med nettbrettet, og kan inneholde personlig eller privat informasjon."</string>
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Lar appen lese fra diverse loggfiler på systemet. Disse inneholder generell informasjon om hva som gjøres med telefonen, og kan inneholde personlig eller privat informasjon."</string>
+    <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"bruke en hvilken som helst mediedekoder for avspilling"</string>
+    <string name="permdesc_anyCodecForPlayback" msgid="2101444559995480174">"Lar apper bruke en hvilken som helst installert mediedekoder for å dekode for avspilling."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"lese/skrive ressurser eid av diag"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Lar appen lese og skrive til alle ressurser som eies av gruppen «diag», som for eksempel filer i /dev. Dette kan potensielt påvirke systemets sikkerhet og stabilitet. Dette bør BARE brukes av produsenten eller operatøren til maskinvarespesifikk diagnostikk."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"aktivere eller deaktivere appkomponenter"</string>
@@ -465,9 +467,9 @@
     <string name="permlab_bluetoothAdmin" msgid="3606576270792236062">"Bluetooth-administrasjon"</string>
     <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"Lar appen konfigurere det lokale Bluetooth-nettbrettet, samt oppdage og koble sammen med eksterne enheter."</string>
     <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"Lar appen konfigurere den lokale Bluetooth-telefonen, samt oppdage og koble sammen med eksterne enheter."</string>
-    <!-- outdated translation 2800410363171809280 -->     <string name="permlab_accessWimaxState" msgid="1232061307208861588">"vis WiMAX-status"</string>
+    <string name="permlab_accessWimaxState" msgid="1232061307208861588">"Se WiMAX-status"</string>
     <string name="permdesc_accessWimaxState" msgid="8298035866227524023">"Dette gjør det mulig for en app å vise informasjon om WiMAX-statusen."</string>
-    <!-- outdated translation 340465839241528618 -->     <string name="permlab_changeWimaxState" msgid="2405042267131496579">"endre WiMAX-status"</string>
+    <string name="permlab_changeWimaxState" msgid="2405042267131496579">"Endre WiMAX-status"</string>
     <string name="permdesc_changeWimaxState" msgid="474918005058989421">"Gjør at en app kan koble til og fra WiMAX-nettverk."</string>
     <string name="permlab_bluetooth" msgid="8361038707857018732">"opprette Bluetooth-tilkoblinger"</string>
     <string name="permdesc_bluetooth" product="tablet" msgid="7007851048416363446">"Lar appen se konfigurasjonen av det lokale Bluetooth-nettbrettet samt opprette og godta tilkoblinger med sammenkoblede enheter."</string>
@@ -1219,4 +1221,7 @@
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"Deling med"</string>
     <string name="status_bar_device_locked" msgid="3092703448690669768">"Enheten er låst."</string>
     <string name="list_delimeter" msgid="3975117572185494152">", "</string>
+    <string name="sending" msgid="8715108995741758718">"Sender …"</string>
+    <string name="launchBrowserDefault" msgid="2057951947297614725">"Vil du starte nettleseren?"</string>
+    <string name="SetupCallDefault" msgid="6870275517518479651">"Vil du besvare anropet?"</string>
 </resources>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index f7efc17..b624cd07 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -301,6 +301,8 @@
     <string name="permlab_readLogs" msgid="6615778543198967614">"gevoelige logbestandsgegevens lezen"</string>
     <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"Hiermee kan de app de verschillende logbestanden van het systeem lezen. De app kan op deze manier algemene informatie achterhalen over uw tabletgebruik, mogelijk inclusief persoonlijke of privé-informatie."</string>
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Hiermee kan de app de verschillende logbestanden van het systeem lezen. De app kan op deze manier algemene informatie achterhalen over uw telefoongebruik, mogelijk inclusief persoonlijke of privé-informatie."</string>
+    <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"elke mediadecoder gebruiken voor afspelen"</string>
+    <string name="permdesc_anyCodecForPlayback" msgid="2101444559995480174">"Hiermee kan een app alle geïnstalleerde mediadecoders gebruiken om te decoderen voor het afspelen."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"lezen/schrijven naar bronnen van diag"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Hiermee kan de app lezen en schrijven naar elke bron die hoort bij de diagnostische groep, zoals bestanden in /dev. Hierdoor kan de systeemstabiliteit en -veiligheid worden beïnvloed. Dit mag ALLEEN worden gebruikt voor hardwarespecifieke diagnostiek door de fabrikant of provider."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"componenten van apps in- of uitschakelen"</string>
@@ -465,9 +467,9 @@
     <string name="permlab_bluetoothAdmin" msgid="3606576270792236062">"Bluetooth-beheer"</string>
     <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"Hiermee kan de app de lokale Bluetooth-tablet configureren en externe apparaten zoeken en koppelen."</string>
     <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"Hiermee kan de app de lokale Bluetooth-telefoon configureren en externe apparaten zoeken en koppelen."</string>
-    <!-- outdated translation 2800410363171809280 -->     <string name="permlab_accessWimaxState" msgid="1232061307208861588">"WiMAX-status bekijken"</string>
+    <string name="permlab_accessWimaxState" msgid="1232061307208861588">"WiMAX-status bekijken"</string>
     <string name="permdesc_accessWimaxState" msgid="8298035866227524023">"Hiermee kan een app informatie over de WiMAX-status bekijken."</string>
-    <!-- outdated translation 340465839241528618 -->     <string name="permlab_changeWimaxState" msgid="2405042267131496579">"WiMAX-status wijzigen"</string>
+    <string name="permlab_changeWimaxState" msgid="2405042267131496579">"WiMAX-status wijzigen"</string>
     <string name="permdesc_changeWimaxState" msgid="474918005058989421">"Hiermee kan een app verbinding maken met een WiMAX-netwerk en deze verbreken."</string>
     <string name="permlab_bluetooth" msgid="8361038707857018732">"Bluetooth-verbindingen maken"</string>
     <string name="permdesc_bluetooth" product="tablet" msgid="7007851048416363446">"Hiermee kan de app de configuratie van een lokale Bluetooth-tablet bekijken en verbindingen met gekoppelde apparaten maken en accepteren."</string>
@@ -1219,4 +1221,7 @@
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"Delen met"</string>
     <string name="status_bar_device_locked" msgid="3092703448690669768">"Apparaat vergrendeld."</string>
     <string name="list_delimeter" msgid="3975117572185494152">", "</string>
+    <string name="sending" msgid="8715108995741758718">"Verzenden..."</string>
+    <string name="launchBrowserDefault" msgid="2057951947297614725">"Browser starten?"</string>
+    <string name="SetupCallDefault" msgid="6870275517518479651">"Oproep accepteren?"</string>
 </resources>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 840aaa8..3935813 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -36,7 +36,7 @@
     <string name="defaultMsisdnAlphaTag" msgid="2850889754919584674">"MSISDN1"</string>
     <string name="mmiError" msgid="5154499457739052907">"Problem z połączeniem lub błędny kod MMI."</string>
     <string name="mmiFdnError" msgid="5224398216385316471">"Operacja jest ograniczona wyłącznie do numerów ustalonych."</string>
-    <string name="serviceEnabled" msgid="8147278346414714315">"Usługa była włączona."</string>
+    <string name="serviceEnabled" msgid="8147278346414714315">"Usługa została włączona."</string>
     <string name="serviceEnabledFor" msgid="6856228140453471041">"Usługa została włączona dla:"</string>
     <string name="serviceDisabled" msgid="1937553226592516411">"Usługa została wyłączona."</string>
     <string name="serviceRegistered" msgid="6275019082598102493">"Rejestracja powiodła się."</string>
@@ -301,6 +301,8 @@
     <string name="permlab_readLogs" msgid="6615778543198967614">"odczyt wrażliwych danych dziennika"</string>
     <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"Pozwala aplikacji na odczyt różnych plików dzienników systemowych. Dzięki temu może ona uzyskać ogólne informacje na temat korzystania z tabletu, co potencjalnie może obejmować również informacje prywatne lub osobiste."</string>
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Pozwala aplikacji na odczyt różnych plików dzienników systemowych. Dzięki temu może ona poznać ogólne informacje na temat korzystania z telefonu, co potencjalnie może obejmować również informacje prywatne lub osobiste."</string>
+    <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"użycie dowolnego dekodera multimediów w celu odtwarzania"</string>
+    <string name="permdesc_anyCodecForPlayback" msgid="2101444559995480174">"Zezwala aplikacji na użycie dowolnego zainstalowanego dekodera multimediów w celu odtwarzania."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"czytanie/zapisywanie w zasobach należących do diagnostyki"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Pozwala aplikacji na czytanie i zapisywanie wszystkich zasobów należących do grupy diagnostyki, na przykład plików w katalogu /dev. Może to potencjalnie wpłynąć na stabilność i bezpieczeństwo systemu. Powinno być wykorzystywane WYŁĄCZNIE do diagnozowania sprzętu przez producenta lub operatora."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"włączanie lub wyłączanie składników aplikacji"</string>
@@ -465,9 +467,9 @@
     <string name="permlab_bluetoothAdmin" msgid="3606576270792236062">"administrowanie Bluetooth"</string>
     <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"Pozwala aplikacji na konfigurowanie lokalnego tabletu z funkcją Bluetooth oraz na wykrywanie urządzeń zdalnych i parowanie z nimi."</string>
     <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"Pozwala aplikacji na konfigurowanie lokalnego telefonu z funkcją Bluetooth oraz na wykrywanie urządzeń zdalnych i parowanie z nimi."</string>
-    <!-- outdated translation 2800410363171809280 -->     <string name="permlab_accessWimaxState" msgid="1232061307208861588">"wyświetlanie stanu WiMAX"</string>
+    <string name="permlab_accessWimaxState" msgid="1232061307208861588">"Wyświetl stan WiMAX"</string>
     <string name="permdesc_accessWimaxState" msgid="8298035866227524023">"Zezwala aplikacji na dostęp do informacji o stanie połączenia WiMAX."</string>
-    <!-- outdated translation 340465839241528618 -->     <string name="permlab_changeWimaxState" msgid="2405042267131496579">"zmiana stanu WiMAX"</string>
+    <string name="permlab_changeWimaxState" msgid="2405042267131496579">"Zmień stan WiMAX"</string>
     <string name="permdesc_changeWimaxState" msgid="474918005058989421">"Zezwala aplikacji na łączenie się i rozłączanie z siecią WiMAX."</string>
     <string name="permlab_bluetooth" msgid="8361038707857018732">"tworzenie połączeń Bluetooth"</string>
     <string name="permdesc_bluetooth" product="tablet" msgid="7007851048416363446">"Pozwala aplikacji na wyświetlanie konfiguracji lokalnego tabletu z funkcją Bluetooth oraz na nawiązywanie i akceptowanie połączeń ze sparowanymi urządzeniami."</string>
@@ -1219,4 +1221,7 @@
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"Udostępnij"</string>
     <string name="status_bar_device_locked" msgid="3092703448690669768">"Urządzenie zablokowane."</string>
     <string name="list_delimeter" msgid="3975117572185494152">", "</string>
+    <string name="sending" msgid="8715108995741758718">"Wysyłanie..."</string>
+    <string name="launchBrowserDefault" msgid="2057951947297614725">"Uruchomić przeglądarkę?"</string>
+    <string name="SetupCallDefault" msgid="6870275517518479651">"Odebrać połączenie?"</string>
 </resources>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 8ec8391..83b18f3 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -51,7 +51,7 @@
     <string name="needPuk" msgid="919668385956251611">"O seu cartão SIM está bloqueado com PUK. Introduza o código PUK para desbloqueá-lo."</string>
     <string name="needPuk2" msgid="4526033371987193070">"Introduza o PUK2 para desbloquear o cartão SIM."</string>
     <string name="ClipMmi" msgid="6952821216480289285">"ID do Autor da Chamada"</string>
-    <string name="ClirMmi" msgid="7784673673446833091">"ID do autor da chamada efectuada"</string>
+    <string name="ClirMmi" msgid="7784673673446833091">"ID do autor da chamada efetuada"</string>
     <string name="CfMmi" msgid="5123218989141573515">"Encaminhamento de chamadas"</string>
     <string name="CwMmi" msgid="9129678056795016867">"Chamada em espera"</string>
     <string name="BaMmi" msgid="455193067926770581">"Barramento de chamadas"</string>
@@ -170,7 +170,7 @@
     <string name="permgrouplab_accounts" msgid="3359646291125325519">"As suas contas"</string>
     <string name="permgroupdesc_accounts" msgid="4948732641827091312">"Aceda às contas disponíveis."</string>
     <string name="permgrouplab_hardwareControls" msgid="7998214968791599326">"Controlos de hardware"</string>
-    <string name="permgroupdesc_hardwareControls" msgid="4357057861225462702">"Aceda directamente ao hardware no telefone."</string>
+    <string name="permgroupdesc_hardwareControls" msgid="4357057861225462702">"Aceda diretamente ao hardware no telefone."</string>
     <string name="permgrouplab_phoneCalls" msgid="9067173988325865923">"Chamadas telefónicas"</string>
     <string name="permgroupdesc_phoneCalls" msgid="7489701620446183770">"Monitorize, grave e processe chamadas telefónicas."</string>
     <string name="permgrouplab_systemTools" msgid="4652191644082714048">"Ferramentas do sistema"</string>
@@ -301,6 +301,8 @@
     <string name="permlab_readLogs" msgid="6615778543198967614">"ler dados sensíveis de registo"</string>
     <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"Permite que a aplicação leia a partir dos diversos ficheiros de registo do sistema. Isto permite descobrir informações gerais sobre a forma como o utilizador utiliza o tablet, podendo, inclusive, incluir dados pessoais ou privados."</string>
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Permite que a aplicação leia a partir dos diversos ficheiros de registo do sistema. Isto permite descobrir informações gerais sobre a forma como o utilizador usa o telemóvel, podendo, inclusive, incluir dados pessoais ou privados."</string>
+    <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"Utilizar qualquer descodificador de multimédia para a reprodução"</string>
+    <string name="permdesc_anyCodecForPlayback" msgid="2101444559995480174">"Permite que uma aplicação utilize qualquer descodificador de multimédia instalado para descodificar a reprodução."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"ler/escrever em recursos propriedade de diag"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Permite à aplicação ler e escrever em qualquer recurso que seja propriedade do grupo diag; por exemplo, ficheiros em /dev. Isto pode potencialmente afetar a estabilidade e a segurança do sistema e deve ser utilizado APENAS para diagnósticos específicos do hardware pelo fabricante ou pelo operador."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"ativar ou desativar componentes da aplicação"</string>
@@ -393,12 +395,12 @@
     <string name="permdesc_accessMtp" msgid="6532961200486791570">"Permite o acesso ao controlador MTP de kernel para implementar o protocolo MTP USB."</string>
     <string name="permlab_hardware_test" msgid="4148290860400659146">"testar hardware"</string>
     <string name="permdesc_hardware_test" msgid="6597964191208016605">"Permite à aplicação controlar vários periféricos para fins de teste de hardware."</string>
-    <string name="permlab_callPhone" msgid="3925836347681847954">"marcar números de telefone directamente"</string>
+    <string name="permlab_callPhone" msgid="3925836347681847954">"marcar números de telefone diretamente"</string>
     <string name="permdesc_callPhone" msgid="6396463004110544744">"Permite que a aplicação marque números de telefone sem a intervenção do utilizador. As aplicações maliciosas podem provocar o aparecimento de chamadas inesperadas na sua conta telefónica. Tenha em atenção que isto não permite à aplicação marcar números de emergência."</string>
-    <string name="permlab_callPrivileged" msgid="4198349211108497879">"marcar directamente quaisquer números de telefone"</string>
+    <string name="permlab_callPrivileged" msgid="4198349211108497879">"marcar diretamente quaisquer números de telefone"</string>
     <string name="permdesc_callPrivileged" msgid="1689024901509996810">"Permite que a aplicação marque qualquer número de telefone, incluindo números de emergência, sem a intervenção do utilizador. As aplicações maliciosas podem efetuar chamadas desnecessárias e ilegais para serviços de emergência."</string>
-    <string name="permlab_performCdmaProvisioning" product="tablet" msgid="4842576994144604821">"iniciar directamente a configuração do tablet CDMA"</string>
-    <string name="permlab_performCdmaProvisioning" product="default" msgid="5604848095315421425">"iniciar directamente a configuração do telefone CDMA"</string>
+    <string name="permlab_performCdmaProvisioning" product="tablet" msgid="4842576994144604821">"iniciar diretamente a configuração do tablet CDMA"</string>
+    <string name="permlab_performCdmaProvisioning" product="default" msgid="5604848095315421425">"iniciar diretamente a configuração do telefone CDMA"</string>
     <string name="permdesc_performCdmaProvisioning" msgid="1994193538802314186">"Permite que a aplicação inicie a administração CDMA. As aplicações maliciosas podem iniciar a administração CDMA desnecessariamente."</string>
     <string name="permlab_locationUpdates" msgid="7785408253364335740">"controlar notificações de actualização de localização"</string>
     <string name="permdesc_locationUpdates" msgid="1120741557891438876">"Permite que a aplicação ative/desative as notificações de atualização de localização do rádio. Não se destina a utilização por aplicações normais."</string>
@@ -465,9 +467,9 @@
     <string name="permlab_bluetoothAdmin" msgid="3606576270792236062">"Administração de Bluetooth"</string>
     <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"Permite à aplicação configurar o tablet Bluetooth local, bem como descobrir e emparelhar com dispositivos remotos."</string>
     <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"Permite que a aplicação configure o telemóvel Bluetooth local, bem como descobrir e emparelhar com dispositivos remotos."</string>
-    <!-- outdated translation 2800410363171809280 -->     <string name="permlab_accessWimaxState" msgid="1232061307208861588">"ver estado do WiMAX"</string>
+    <string name="permlab_accessWimaxState" msgid="1232061307208861588">"Ver estado do WiMAX"</string>
     <string name="permdesc_accessWimaxState" msgid="8298035866227524023">"Permite a uma aplicação ver as informações acerca do estado do Wi-Fi."</string>
-    <!-- outdated translation 340465839241528618 -->     <string name="permlab_changeWimaxState" msgid="2405042267131496579">"alterar estado do WiMAX"</string>
+    <string name="permlab_changeWimaxState" msgid="2405042267131496579">"Alterar estado do WiMAX"</string>
     <string name="permdesc_changeWimaxState" msgid="474918005058989421">"Permite a uma aplicação ligar-se e desligar-se da rede WiMAX."</string>
     <string name="permlab_bluetooth" msgid="8361038707857018732">"criar ligações Bluetooth"</string>
     <string name="permdesc_bluetooth" product="tablet" msgid="7007851048416363446">"Permite que a aplicação veja a configuração do tablet Bluetooth local, bem como efetuar e aceitar ligações com dispositivos emparelhados."</string>
@@ -933,7 +935,7 @@
     <string name="volume_ringtone" msgid="6885421406845734650">"Volume da campainha"</string>
     <string name="volume_music" msgid="5421651157138628171">"Volume de multimédia"</string>
     <string name="volume_music_hint_playing_through_bluetooth" msgid="9165984379394601533">"A reproduzir através de Bluetooth"</string>
-    <string name="volume_music_hint_silent_ringtone_selected" msgid="6158339745293431194">"Toque silencioso seleccionado"</string>
+    <string name="volume_music_hint_silent_ringtone_selected" msgid="6158339745293431194">"Toque silencioso selecionado"</string>
     <string name="volume_call" msgid="3941680041282788711">"Volume da chamada recebida"</string>
     <string name="volume_bluetooth_call" msgid="2002891926351151534">"Volume de chamada recebida em Bluetooth"</string>
     <string name="volume_alarm" msgid="1985191616042689100">"Volume do alarme"</string>
@@ -1082,7 +1084,7 @@
     <string name="vpn_text" msgid="1610714069627824309">"Toque para gerir a rede."</string>
     <string name="vpn_text_long" msgid="4907843483284977618">"Ligado a <xliff:g id="SESSION">%s</xliff:g>. Toque para gerir a rede."</string>
     <string name="upload_file" msgid="2897957172366730416">"Escolher ficheiro"</string>
-    <string name="no_file_chosen" msgid="6363648562170759465">"Não foi seleccionado nenhum ficheiro"</string>
+    <string name="no_file_chosen" msgid="6363648562170759465">"Não foi selecionado nenhum ficheiro"</string>
     <string name="reset" msgid="2448168080964209908">"Repor"</string>
     <string name="submit" msgid="1602335572089911941">"Enviar"</string>
     <string name="car_mode_disable_notification_title" msgid="3164768212003864316">"Modo automóvel activado"</string>
@@ -1219,4 +1221,7 @@
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"Partilhar com"</string>
     <string name="status_bar_device_locked" msgid="3092703448690669768">"Aparelho bloqueado."</string>
     <string name="list_delimeter" msgid="3975117572185494152">", "</string>
+    <string name="sending" msgid="8715108995741758718">"A enviar..."</string>
+    <string name="launchBrowserDefault" msgid="2057951947297614725">"Iniciar Navegador?"</string>
+    <string name="SetupCallDefault" msgid="6870275517518479651">"Aceitar Chamada?"</string>
 </resources>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 96ae7b1..3709d32 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -301,6 +301,8 @@
     <string name="permlab_readLogs" msgid="6615778543198967614">"ler dados de registro de informações confidenciais"</string>
     <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"Permite que o aplicativo leia os diversos arquivos de registro do sistema. Isso permite que ele descubra informações gerais sobre o que você está fazendo com o tablet, inclusive informações pessoais ou particulares."</string>
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Permite que o aplicativo leia os diversos arquivos de registro do sistema. Isso permite que ele descubra informações gerais sobre o que você está fazendo com o telefone, inclusive possíveis informações pessoais ou privadas."</string>
+    <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"usar qualquer decodificador de mídia para reprodução"</string>
+    <string name="permdesc_anyCodecForPlayback" msgid="2101444559995480174">"Permite que um aplicativo use qualquer decodificador de mídia instalado para decodificar e reproduzir."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"ler/gravar em recursos pertencentes ao diag"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Permite que um aplicativo leia e grave em qualquer recurso que pertença ao grupo de diagnósticos, por exemplo, arquivos in/dev. Isso pode afetar a estabilidade e a segurança do sistema. Esse recurso deve ser usado APENAS para diagnósticos específicos do hardware realizados pelo fabricante ou pela operadora."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"ativar ou desativar os componentes do aplicativo"</string>
@@ -465,9 +467,9 @@
     <string name="permlab_bluetoothAdmin" msgid="3606576270792236062">"administração de Bluetooth"</string>
     <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"Permite que um aplicativo configure o tablet Bluetooth local, descubra dispositivos remotos e emparelhe com eles."</string>
     <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"Permite que um aplicativo configure o telefone Bluetooth local, descubra e emparelhe com dispositivos remotos."</string>
-    <!-- outdated translation 2800410363171809280 -->     <string name="permlab_accessWimaxState" msgid="1232061307208861588">"visualizar estado do WiMAX"</string>
+    <string name="permlab_accessWimaxState" msgid="1232061307208861588">"Visualizar estado do WiMAX"</string>
     <string name="permdesc_accessWimaxState" msgid="8298035866227524023">"Permite que um aplicativo veja as informações sobre o estado do WiMAX."</string>
-    <!-- outdated translation 340465839241528618 -->     <string name="permlab_changeWimaxState" msgid="2405042267131496579">"alterar estado do WiMAX"</string>
+    <string name="permlab_changeWimaxState" msgid="2405042267131496579">"Alterar estado do WiMAX"</string>
     <string name="permdesc_changeWimaxState" msgid="474918005058989421">"Permite que um aplicativo seja conectado e desconectado à uma rede WiMAX."</string>
     <string name="permlab_bluetooth" msgid="8361038707857018732">"criar conexões Bluetooth"</string>
     <string name="permdesc_bluetooth" product="tablet" msgid="7007851048416363446">"Permite que o aplicativo visualize a configuração do tablet Bluetooth local e faça e aceite conexões com dispositivos emparelhados."</string>
@@ -890,8 +892,8 @@
     <string name="no" msgid="5141531044935541497">"Cancelar"</string>
     <string name="dialog_alert_title" msgid="2049658708609043103">"Atenção"</string>
     <string name="loading" msgid="7933681260296021180">"Carregando…"</string>
-    <string name="capital_on" msgid="1544682755514494298">"ATIVADO"</string>
-    <string name="capital_off" msgid="6815870386972805832">"DESATIVADO"</string>
+    <string name="capital_on" msgid="1544682755514494298">"LIG"</string>
+    <string name="capital_off" msgid="6815870386972805832">"DESL"</string>
     <string name="whichApplication" msgid="4533185947064773386">"Complete a ação usando"</string>
     <string name="alwaysUse" msgid="4583018368000610438">"Usar como padrão para esta ação."</string>
     <string name="clearDefaultHintMsg" msgid="3252584689512077257">"Padrão claro em Configurações do sistema &gt; Aplicativos &gt; Baixado."</string>
@@ -1219,4 +1221,7 @@
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"Compartilhar com"</string>
     <string name="status_bar_device_locked" msgid="3092703448690669768">"Dispositivo bloqueado."</string>
     <string name="list_delimeter" msgid="3975117572185494152">", "</string>
+    <string name="sending" msgid="8715108995741758718">"Enviando..."</string>
+    <string name="launchBrowserDefault" msgid="2057951947297614725">"Abrir Navegador?"</string>
+    <string name="SetupCallDefault" msgid="6870275517518479651">"Aceitar chamada?"</string>
 </resources>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index b7b9c80..a1fb2d8 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -301,6 +301,8 @@
     <string name="permlab_readLogs" msgid="6615778543198967614">"citire date de jurnal problematice"</string>
     <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"Permite aplicaţiei să citească din diverse fişiere jurnal ale sistemului. În acest mod poate descoperi informaţii generale cu privire la utilizarea tabletei de către dvs. şi probabil informaţii personale sau private."</string>
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Permite aplicaţiei să citească din diverse fişiere jurnal ale sistemului. În acest mod poate descoperi informaţii generale cu privire la utilizarea telefonului de către dvs., care ar putea include şi informaţii personale sau private."</string>
+    <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"utilizaţi orice decodor media pentru redare"</string>
+    <string name="permdesc_anyCodecForPlayback" msgid="2101444559995480174">"Permite unei aplicaţii să utilizeze orice decodor media instalat pentru a decodifica redarea."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"citire/scriere în resursele deţinute de diag"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Permite aplicaţiei să citească şi să scrie în orice resursă deţinută de grupul diag, de ex., fişierele din /dev. Această permisiune ar putea să afecteze stabilitatea şi securitatea sistemului. Permisiunea trebuie utilizată NUMAI de producător sau de operator pentru diagnostice specifice pentru hardware."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"activare sau dezactivare a componentelor aplicaţiei"</string>
@@ -465,9 +467,9 @@
     <string name="permlab_bluetoothAdmin" msgid="3606576270792236062">"administrare Bluetooth"</string>
     <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"Permite aplicaţiei să configureze tableta Bluetooth locală, să descopere şi să se împerecheze cu dispozitive la distanţă."</string>
     <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"Permite aplicaţiei să configureze telefonul Bluetooth local, să descopere şi să se împerecheze cu dispozitive la distanţă."</string>
-    <!-- outdated translation 2800410363171809280 -->     <string name="permlab_accessWimaxState" msgid="1232061307208861588">"vizualizaţi starea WiMAX"</string>
+    <string name="permlab_accessWimaxState" msgid="1232061307208861588">"Vizualizaţi starea WiMAX"</string>
     <string name="permdesc_accessWimaxState" msgid="8298035866227524023">"Permite unei aplicaţii să vizualizeze informaţiile despre starea WiMAX."</string>
-    <!-- outdated translation 340465839241528618 -->     <string name="permlab_changeWimaxState" msgid="2405042267131496579">"schimbaţi starea WiMAX"</string>
+    <string name="permlab_changeWimaxState" msgid="2405042267131496579">"Schimbaţi starea WiMAX"</string>
     <string name="permdesc_changeWimaxState" msgid="474918005058989421">"Permite unei aplicaţii să se conecteze şi să se deconecteze de la reţeaua WiMAX."</string>
     <string name="permlab_bluetooth" msgid="8361038707857018732">"creare conexiuni Bluetooth"</string>
     <string name="permdesc_bluetooth" product="tablet" msgid="7007851048416363446">"Permite aplicaţiei să vizualizeze configuraţia tabletei Bluetooth locale, să efectueze şi să accepte conexiuni cu dispozitive împerecheate."</string>
@@ -1219,4 +1221,7 @@
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"Distribuiţi pentru"</string>
     <string name="status_bar_device_locked" msgid="3092703448690669768">"Dispozitiv blocat."</string>
     <string name="list_delimeter" msgid="3975117572185494152">", "</string>
+    <string name="sending" msgid="8715108995741758718">"Se trimite..."</string>
+    <string name="launchBrowserDefault" msgid="2057951947297614725">"Lansaţi browserul?"</string>
+    <string name="SetupCallDefault" msgid="6870275517518479651">"Acceptaţi apelul?"</string>
 </resources>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index af68d12..4ddefe9 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -301,6 +301,8 @@
     <string name="permlab_readLogs" msgid="6615778543198967614">"считывать конфиденциальные данные журнала"</string>
     <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"Приложение сможет считывать информацию из различных системных журналов. Приложение может получать сведения о работе пользователя на планшетном ПК, в том числе к личной и конфиденциальной информации."</string>
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Приложение сможет считывать информацию из различных системных журналов, а также получать сведения о работе пользователя на телефоне, в том числе к личной и конфиденциальной информации."</string>
+    <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"Использование любых дешифраторов"</string>
+    <string name="permdesc_anyCodecForPlayback" msgid="2101444559995480174">"Приложение сможет использовать любой установленный дешифратор."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"считывать/записывать данные в ресурсы, принадлежащие группе диагностики"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Приложение сможет считывать и записывать данные системы диагностики (например, файлы в каталоге /dev). Это может повлиять на стабильность и безопасность системы. Это разрешение должно использоваться ТОЛЬКО производителем или оператором для диагностики аппаратного обеспечения."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"включение и отключение компонентов приложения"</string>
@@ -348,7 +350,7 @@
     <string name="permlab_accessFineLocation" msgid="8116127007541369477">"точное местоположение (GPS)"</string>
     <string name="permdesc_accessFineLocation" product="tablet" msgid="5326423948268164934">"Приложение получит доступ к источникам точного местоположения, таким как GPS, когда это возможно. Вредоносные программы смогут таким образом определять ваше местоположение и повысить расход заряда батареи."</string>
     <string name="permdesc_accessFineLocation" product="default" msgid="7130267914433890869">"Приложение получит доступ к источникам точного местоположения, таким как GPS, когда это возможно. Вредоносные программы смогут таким образом определять ваше местоположение и повысить расход заряда батареи."</string>
-    <string name="permlab_accessCoarseLocation" msgid="4642255009181975828">"отслеживать местоположение по сигналам сети"</string>
+    <string name="permlab_accessCoarseLocation" msgid="4642255009181975828">"примерное местоположение по координатам сети"</string>
     <string name="permdesc_accessCoarseLocation" product="tablet" msgid="5460726396318105483">"Приложение получит доступ к источникам данных о местоположении, таким как база данных сотовой сети, для определения приблизительного местоположения планшетного ПК, когда это возможно. Вредоносные программы смогут таким образом определять ваше местоположение."</string>
     <string name="permdesc_accessCoarseLocation" product="default" msgid="8900795778057579522">"Приложение получит доступ к источникам данных о местоположении, таким как база данных сотовой сети, для определения приблизительного местоположения телефона, когда это возможно. Вредоносные программы смогут таким образом определять ваше местоположение."</string>
     <string name="permlab_accessSurfaceFlinger" msgid="2363969641792388947">"получать доступ к SurfaceFlinger"</string>
@@ -465,9 +467,9 @@
     <string name="permlab_bluetoothAdmin" msgid="3606576270792236062">"управление Bluetooth"</string>
     <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"Приложение сможет настраивать параметры локального планшетного ПК с поддержкой Bluetooth, а также обнаруживать удаленные устройства и выполнять сопряжение с ними."</string>
     <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"Приложение сможет настраивать параметры локального телефона с поддержкой Bluetooth, а также обнаруживать удаленные устройства и выполнять сопряжение с ними."</string>
-    <!-- outdated translation 2800410363171809280 -->     <string name="permlab_accessWimaxState" msgid="1232061307208861588">"получать сведения о состоянии WiMAX"</string>
+    <string name="permlab_accessWimaxState" msgid="1232061307208861588">"Узнавать о состоянии WiMAX"</string>
     <string name="permdesc_accessWimaxState" msgid="8298035866227524023">"Позволяет приложению получать сведения о состоянии WiMAX."</string>
-    <!-- outdated translation 340465839241528618 -->     <string name="permlab_changeWimaxState" msgid="2405042267131496579">"изменять состояние WiMAX"</string>
+    <string name="permlab_changeWimaxState" msgid="2405042267131496579">"Изменять состояние WiMAX"</string>
     <string name="permdesc_changeWimaxState" msgid="474918005058989421">"Позволяет приложению подключаться к сети WiMAX и отключаться от нее."</string>
     <string name="permlab_bluetooth" msgid="8361038707857018732">"создавать подключения Bluetooth"</string>
     <string name="permdesc_bluetooth" product="tablet" msgid="7007851048416363446">"Приложение сможет просматривать конфигурацию локального планшетного ПК с поддержкой Bluetooth, а также создавать и принимать соединения с сопряженными устройствами."</string>
@@ -745,7 +747,7 @@
     <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="1757103804824209530">"Приложение сможет изменять историю или закладки браузера, сохраненные на устройстве. Вредоносные программы смогут таким образом удалять и изменять ваши данные в браузере."</string>
     <string name="permdesc_writeHistoryBookmarks" product="default" msgid="6693764355720719197">"Приложение может изменять историю или закладки браузера, сохраненные на устройстве. Вредоносные программы смогут таким образом удалять и изменять ваши данные в браузере."</string>
     <string name="permlab_setAlarm" msgid="5924401328803615165">"настраивать сигнал будильника"</string>
-    <string name="permdesc_setAlarm" msgid="316392039157473848">"Приложение сможет настраивать будильник. Функция поддерживаться не во всех программах."</string>
+    <string name="permdesc_setAlarm" msgid="316392039157473848">"Приложение сможет настраивать будильник. Функция поддерживается не во всех программах."</string>
     <string name="permlab_addVoicemail" msgid="5525660026090959044">"добавлять голосовые сообщения"</string>
     <string name="permdesc_addVoicemail" msgid="6604508651428252437">"Приложение сможет добавлять голосовые сообщения в папку \"Входящие\"."</string>
     <string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"изменение прав доступа к геоданным в браузере"</string>
@@ -789,7 +791,7 @@
     <item quantity="other" msgid="3069992808164318268">"Последние <xliff:g id="COUNT">%d</xliff:g> дн."</item>
   </plurals>
     <string name="last_month" msgid="3959346739979055432">"Прошлый месяц"</string>
-    <string name="older" msgid="5211975022815554840">"Пред."</string>
+    <string name="older" msgid="5211975022815554840">"Еще раньше"</string>
   <plurals name="num_days_ago">
     <item quantity="one" msgid="861358534398115820">"вчера"</item>
     <item quantity="other" msgid="2479586466153314633">"<xliff:g id="COUNT">%d</xliff:g> дн. назад"</item>
@@ -1190,7 +1192,7 @@
     <string name="data_usage_warning_body" msgid="7217480745540055170">"Проверить трафик и настройки"</string>
     <string name="data_usage_3g_limit_title" msgid="7093334419518706686">"Передача данных 2G/3G отключена"</string>
     <string name="data_usage_4g_limit_title" msgid="7636489436819470761">"Передача данных 4G отключена"</string>
-    <string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"Мобильный Интернет отключен"</string>
+    <string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"Моб. Интернет отключен"</string>
     <string name="data_usage_wifi_limit_title" msgid="8992154736441284865">"Передача данных через Wi-Fi отключена"</string>
     <string name="data_usage_limit_body" msgid="4313857592916426843">"Нажмите, чтобы включить"</string>
     <string name="data_usage_3g_limit_snoozed_title" msgid="7026739121138005231">"Превышен лимита трафика 2G и 3G"</string>
@@ -1219,4 +1221,7 @@
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"Открыть доступ"</string>
     <string name="status_bar_device_locked" msgid="3092703448690669768">"Устройство заблокировано."</string>
     <string name="list_delimeter" msgid="3975117572185494152">", "</string>
+    <string name="sending" msgid="8715108995741758718">"Отправка..."</string>
+    <string name="launchBrowserDefault" msgid="2057951947297614725">"Запустить браузер?"</string>
+    <string name="SetupCallDefault" msgid="6870275517518479651">"Принять вызов?"</string>
 </resources>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index d838b72..c346e72 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -301,6 +301,8 @@
     <string name="permlab_readLogs" msgid="6615778543198967614">"čítať citlivé údaje denníkov"</string>
     <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"Umožňuje aplikácii čítať rôzne systémové súbory denníkov. Toto nastavenie aplikácie umožňuje získať všeobecné informácie o činnostiach s tabletom, ktoré by mohli obsahovať osobné alebo súkromné informácie."</string>
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Umožňuje aplikácii čítať rôzne systémové súbory denníkov. Toto nastavenie aplikácii umožňuje získať všeobecné informácie o činnostiach s telefónom, ktoré by mohli obsahovať osobné alebo súkromné informácie."</string>
+    <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"použiť ľubovoľný dekódovač médií na reprodukciu"</string>
+    <string name="permdesc_anyCodecForPlayback" msgid="2101444559995480174">"Povoľuje aplikácii používať ľubovoľný nainštalovaný dekódovač na dekódovanie pre reprodukciu."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"čítanie alebo zápis do prostriedkov funkcie diag"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Umožňuje aplikácii čítať ľubovoľné prostriedky v skupine diag, napr. súbory v priečinku /dev, a zapisovať do nich. Môže dôjsť k ovplyvneniu stability a bezpečnosti systému. Toto nastavenie by mal používať IBA výrobca či operátor na diagnostiku hardvéru."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"povoliť alebo zakázať súčasti aplikácie"</string>
@@ -465,9 +467,9 @@
     <string name="permlab_bluetoothAdmin" msgid="3606576270792236062">"správa rozhrania Bluetooth"</string>
     <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"Umožňuje aplikácii konfigurovať miestny tablet s rozhraním Bluetooth a vyhľadávať a spárovať vzdialené zariadenia."</string>
     <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"Umožňuje aplikácii konfigurovať miestny telefón s rozhraním Bluetooth, vyhľadávať a spárovať vzdialené zariadenia."</string>
-    <!-- outdated translation 2800410363171809280 -->     <string name="permlab_accessWimaxState" msgid="1232061307208861588">"zobraziť stav WiMAX"</string>
+    <string name="permlab_accessWimaxState" msgid="1232061307208861588">"Zobraziť stav siete WiMAX"</string>
     <string name="permdesc_accessWimaxState" msgid="8298035866227524023">"Umožňuje aplikácii zobraziť informácie o stave siete WiMAX."</string>
-    <!-- outdated translation 340465839241528618 -->     <string name="permlab_changeWimaxState" msgid="2405042267131496579">"zmeniť stav WiMAX"</string>
+    <string name="permlab_changeWimaxState" msgid="2405042267131496579">"Zmeniť stav siete WiMAX"</string>
     <string name="permdesc_changeWimaxState" msgid="474918005058989421">"Umožňuje aplikácii pripojiť sa a odpojiť zo siete WiMAX."</string>
     <string name="permlab_bluetooth" msgid="8361038707857018732">"vytvorenie pripojenia Bluetooth"</string>
     <string name="permdesc_bluetooth" product="tablet" msgid="7007851048416363446">"Umožňuje aplikácii zobraziť konfiguráciu miestneho tabletu s rozhraním Bluetooth, vytvárať pripojenie na spárované zariadenia a prijímať tieto pripojenia."</string>
@@ -1219,4 +1221,7 @@
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"Zdieľať s"</string>
     <string name="status_bar_device_locked" msgid="3092703448690669768">"Zariadenie je zamknuté."</string>
     <string name="list_delimeter" msgid="3975117572185494152">", "</string>
+    <string name="sending" msgid="8715108995741758718">"Prebieha odosielanie..."</string>
+    <string name="launchBrowserDefault" msgid="2057951947297614725">"Spustiť prehliadač?"</string>
+    <string name="SetupCallDefault" msgid="6870275517518479651">"Prijať hovor?"</string>
 </resources>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 06df932..35f6d3d 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -301,6 +301,8 @@
     <string name="permlab_readLogs" msgid="6615778543198967614">"branje občutljivih dnevniških podatkov"</string>
     <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"Programu omogoča branje različnih sistemskih dnevniških datotek. To mu omogoča dostop do splošnih podatkov v tabličnem računalniku, lahko tudi do osebnih podatkov."</string>
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Programu omogoča branje različnih sistemskih dnevniških datotek. To mu omogoča dostop do splošnih podatkov v telefonu, lahko tudi do osebnih podatkov."</string>
+    <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"uporaba katerega koli predstavnostnega dekodirnika za predvajanje"</string>
+    <string name="permdesc_anyCodecForPlayback" msgid="2101444559995480174">"Programu dovoljuje uporabo katerega koli nameščenega predstavnostnega dekodirnika za dekodiranje pri predvajanju."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"branje/pisanje v sredstva, ki so v lasti skupine za diagnostiko"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Programu omogoča branje in pisanje na poljuben vir, ki je v lasti skupine za diagnostiko; na primer datoteke v mapi /dev. To lahko vpliva na stabilnost in varnost sistema. To naj uporablja SAMO izdelovalec ali operater za diagnostiko, specifično za strojno opremo."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"omogočanje ali onemogočanje komponent programa"</string>
@@ -465,9 +467,9 @@
     <string name="permlab_bluetoothAdmin" msgid="3606576270792236062">"skrbništvo storitve Bluetooth"</string>
     <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"Programu omogoča konfiguriranje lokalnega tabličnega računalnika Bluetooth ter zaznavanje oddaljenih naprav in združevanje z njimi."</string>
     <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"Programu omogoča konfiguriranje lokalnega telefona s tehnologijo Bluetooth ter odkrivanje oddaljenih naprav in povezovanje z njimi."</string>
-    <!-- outdated translation 2800410363171809280 -->     <string name="permlab_accessWimaxState" msgid="1232061307208861588">"prikaz stanja omrežja WiMAX"</string>
+    <string name="permlab_accessWimaxState" msgid="1232061307208861588">"Prikaz stanja omrežja WiMAX"</string>
     <string name="permdesc_accessWimaxState" msgid="8298035866227524023">"Programu omogoča prikaz podatkov o stanju omrežja WiMAX."</string>
-    <!-- outdated translation 340465839241528618 -->     <string name="permlab_changeWimaxState" msgid="2405042267131496579">"sprememba stanja omrežja WiMAX"</string>
+    <string name="permlab_changeWimaxState" msgid="2405042267131496579">"Sprememba stanja omrežja WiMAX"</string>
     <string name="permdesc_changeWimaxState" msgid="474918005058989421">"Programu omogoča povezovanje v omrežje WiMAX in prekinitev povezave."</string>
     <string name="permlab_bluetooth" msgid="8361038707857018732">"ustvarjanje povezav Bluetooth"</string>
     <string name="permdesc_bluetooth" product="tablet" msgid="7007851048416363446">"Programu omogoča ogled konfiguracije lokalnega tabličnega računalnika Bluetooth ter vzpostavljanje in sprejemanje povezave z združenimi napravami."</string>
@@ -1219,4 +1221,7 @@
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"Delite z"</string>
     <string name="status_bar_device_locked" msgid="3092703448690669768">"Naprava zaklenjena."</string>
     <string name="list_delimeter" msgid="3975117572185494152">", "</string>
+    <string name="sending" msgid="8715108995741758718">"Pošiljanje ..."</string>
+    <string name="launchBrowserDefault" msgid="2057951947297614725">"Ali želite odpreti brskalnik?"</string>
+    <string name="SetupCallDefault" msgid="6870275517518479651">"Ali želite sprejeti klic?"</string>
 </resources>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 238bf97..4cf5eec 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -195,9 +195,9 @@
     <string name="permlab_receiveEmergencyBroadcast" msgid="1803477660846288089">"пријем хитних преноса"</string>
     <string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"Дозвољава апликацији да прима и обрађује поруке хитног преноса. Ова дозвола је доступна само за системске апликације."</string>
     <string name="permlab_sendSms" msgid="5600830612147671529">"слање SMS порука"</string>
-    <string name="permdesc_sendSms" msgid="906546667507626156">"Дозвољава апликацији да шаље SMS поруке. Злонамерне апликације могу да шаљу поруке без ваше потврде, што вам  може створити трошкове."</string>
+    <string name="permdesc_sendSms" msgid="906546667507626156">"Дозвољава апликацији да шаље SMS поруке. Злонамерне апликације могу да шаљу поруке без ваше потврде, што вам  може изазвати трошкове."</string>
     <string name="permlab_sendSmsNoConfirmation" msgid="4781483105951730228">"слање SMS порука без потврде"</string>
-    <string name="permdesc_sendSmsNoConfirmation" msgid="3437759207020400204">"Дозвољава апликацији да шаље SMS поруке. Злонамерне апликације могу да шаљу поруке без ваше потврде, што вам може створити трошкове."</string>
+    <string name="permdesc_sendSmsNoConfirmation" msgid="3437759207020400204">"Дозвољава апликацији да шаље SMS поруке. Злонамерне апликације могу да шаљу поруке без ваше потврде, што вам може изазвати трошкове."</string>
     <string name="permlab_readSms" msgid="4085333708122372256">"читање SMS или MMS порука"</string>
     <string name="permdesc_readSms" product="tablet" msgid="2341692916884515613">"Дозвољава апликацији да чита SMS поруке сачуване на таблету или SIM картици. Злонамерне апликације могу да читају поверљиве поруке."</string>
     <string name="permdesc_readSms" product="default" msgid="5653850482025875493">"Дозвољава апликацији да чита SMS поруке сачуване на телефону или SIM картици. Злонамерне апликације могу да читају поверљиве поруке."</string>
@@ -301,6 +301,8 @@
     <string name="permlab_readLogs" msgid="6615778543198967614">"читање поверљивих података из евиденције"</string>
     <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"Дозвољава апликацији да чита разне системске датотеке евиденције. То јој омогућава увид у опште информације о начину на који користите таблет, при чему могу да буду обухваћене личне или приватне информације."</string>
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Дозвољава апликацији да чита разне системске датотеке евиденције. То јој омогућава увид у опште информације о начину на који користите телефон, при чему могу да буду обухваћене личне или приватне информације."</string>
+    <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"користи било који декодер медија за репродукцију"</string>
+    <string name="permdesc_anyCodecForPlayback" msgid="2101444559995480174">"Омогућава апликацији да користи било који инсталирани декодер медија за декодирање за репродукцију."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"читање ресурса у власништву дијагностике и уписивање података у њих"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Дозвољава апликацији да чита и уписује податке у било који ресурс у власништву групе за дијагностиковање, на пример, датотеке у директоријуму /dev. То може да угрози стабилност и безбедност система и треба да је користе САМО произвођач или оператер у сврхе дијагностиковањa хардвера."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"омогућавање или онемогућавање компоненти апликације"</string>
@@ -465,9 +467,9 @@
     <string name="permlab_bluetoothAdmin" msgid="3606576270792236062">"Администрирање преко Bluetooth-а"</string>
     <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"Дозвољава апликацији да конфигурише локални Bluetooth таблет, као и да открије даљинске уређаје и упари се са њима."</string>
     <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"Дозвољава апликацији да конфигурише локални Bluetooth телефон, као и да открије даљинске уређаје и упари се са њима."</string>
-    <!-- outdated translation 2800410363171809280 -->     <string name="permlab_accessWimaxState" msgid="1232061307208861588">"прикажи WiMAX статуса"</string>
+    <string name="permlab_accessWimaxState" msgid="1232061307208861588">"Прикажи WiMAX статус"</string>
     <string name="permdesc_accessWimaxState" msgid="8298035866227524023">"Омогућава апликацији преглед информација о WiMAX статусу."</string>
-    <!-- outdated translation 340465839241528618 -->     <string name="permlab_changeWimaxState" msgid="2405042267131496579">"промени WiMAX статуса"</string>
+    <string name="permlab_changeWimaxState" msgid="2405042267131496579">"Промени WiMAX статус"</string>
     <string name="permdesc_changeWimaxState" msgid="474918005058989421">"Омогућава апликацији повезивање и прекид везе са WiMAX мрежом."</string>
     <string name="permlab_bluetooth" msgid="8361038707857018732">"креирање Bluetooth веза"</string>
     <string name="permdesc_bluetooth" product="tablet" msgid="7007851048416363446">"Дозвољава апликацији да конфигурише локални Bluetooth таблет, као и да успоставља и прихвата везе са упареним уређајима."</string>
@@ -1219,4 +1221,7 @@
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"Дели са"</string>
     <string name="status_bar_device_locked" msgid="3092703448690669768">"Уређај је закључан."</string>
     <string name="list_delimeter" msgid="3975117572185494152">", "</string>
+    <string name="sending" msgid="8715108995741758718">"Слање..."</string>
+    <string name="launchBrowserDefault" msgid="2057951947297614725">"Желите ли да покренете прегледач?"</string>
+    <string name="SetupCallDefault" msgid="6870275517518479651">"Желите ли да прихватите позив?"</string>
 </resources>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index b236504..6d94d89 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -301,6 +301,8 @@
     <string name="permlab_readLogs" msgid="6615778543198967614">"läsa känsliga loggdata"</string>
     <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"Tillåter att appen läser från systemets olika loggfiler. Det innebär att appen kan upptäcka allmän information om vad du gör med pekdatorn, vilket kan inkludera personlig eller privat information."</string>
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Tillåter att appen läser från systemets olika loggfiler. Det innebär att appen kan upptäcka allmän information om vad du gör med mobilen, vilket kan inkludera personlig eller privat information."</string>
+    <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"använda alla medieavkodare för uppspelning"</string>
+    <string name="permdesc_anyCodecForPlayback" msgid="2101444559995480174">"Tillåter att ett program använder installerade medieavkodare för att avkoda media för uppspelning."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"läsa/skriva till resurser som ägs av diag"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Tillåter att appen läser och skriver till en resurs som ägs av diag-gruppen, till exempel filer i /dev. Detta kan eventuellt påverka systemets stabilitet och säkerhet. Detta bör ENDAST användas av tillverkaren eller operatören för maskinvaruspecifik diagnostik."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"aktivera eller inaktivera appkomponenter"</string>
@@ -465,9 +467,9 @@
     <string name="permlab_bluetoothAdmin" msgid="3606576270792236062">"Administrera bluetooth"</string>
     <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"Tillåter att appen konfigurerar den lokala Bluetooth-pekdatorn samt upptäcker och parkopplar den med fjärranslutna enheter."</string>
     <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"Tillåter att appen konfigurerar den lokala Bluetooth-mobilen samt upptäcker och parkopplar den med fjärranslutna enheter."</string>
-    <!-- outdated translation 2800410363171809280 -->     <string name="permlab_accessWimaxState" msgid="1232061307208861588">"visa WiMAX-status"</string>
+    <string name="permlab_accessWimaxState" msgid="1232061307208861588">"visa WiMAX-status"</string>
     <string name="permdesc_accessWimaxState" msgid="8298035866227524023">"Gör att en app kan visa information om WiMAX-status."</string>
-    <!-- outdated translation 340465839241528618 -->     <string name="permlab_changeWimaxState" msgid="2405042267131496579">"ändra WiMAX-status"</string>
+    <string name="permlab_changeWimaxState" msgid="2405042267131496579">"ändra WiMAX-status"</string>
     <string name="permdesc_changeWimaxState" msgid="474918005058989421">"Gör att en app kan anslutas till och kopplas ifrån WiMAX-nätverk."</string>
     <string name="permlab_bluetooth" msgid="8361038707857018732">"skapa Bluetooth-anslutningar"</string>
     <string name="permdesc_bluetooth" product="tablet" msgid="7007851048416363446">"Tillåter att appen ser den lokala Bluetooth-pekdatorns konfiguration och skapar och accepterar anslutningar med parkopplade enheter."</string>
@@ -1219,4 +1221,7 @@
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"Dela med"</string>
     <string name="status_bar_device_locked" msgid="3092703448690669768">"Enheten är låst."</string>
     <string name="list_delimeter" msgid="3975117572185494152">", "</string>
+    <string name="sending" msgid="8715108995741758718">"Skickas ..."</string>
+    <string name="launchBrowserDefault" msgid="2057951947297614725">"Vill du öppna webbläsaren?"</string>
+    <string name="SetupCallDefault" msgid="6870275517518479651">"Vill du ta emot samtal?"</string>
 </resources>
diff --git a/core/res/res/values-sw/donottranslate-cldr.xml b/core/res/res/values-sw/donottranslate-cldr.xml
new file mode 100644
index 0000000..2bc07c1
--- /dev/null
+++ b/core/res/res/values-sw/donottranslate-cldr.xml
@@ -0,0 +1,149 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="month_long_standalone_january">Januari</string>
+    <string name="month_long_standalone_february">Februari</string>
+    <string name="month_long_standalone_march">Machi</string>
+    <string name="month_long_standalone_april">Aprili</string>
+    <string name="month_long_standalone_may">Mei</string>
+    <string name="month_long_standalone_june">Juni</string>
+    <string name="month_long_standalone_july">Julai</string>
+    <string name="month_long_standalone_august">Agosti</string>
+    <string name="month_long_standalone_september">Septemba</string>
+    <string name="month_long_standalone_october">Oktoba</string>
+    <string name="month_long_standalone_november">Novemba</string>
+    <string name="month_long_standalone_december">Desemba</string>
+
+    <string name="month_long_january">Januari</string>
+    <string name="month_long_february">Februari</string>
+    <string name="month_long_march">Machi</string>
+    <string name="month_long_april">Aprili</string>
+    <string name="month_long_may">Mei</string>
+    <string name="month_long_june">Juni</string>
+    <string name="month_long_july">Julai</string>
+    <string name="month_long_august">Agosti</string>
+    <string name="month_long_september">Septemba</string>
+    <string name="month_long_october">Oktoba</string>
+    <string name="month_long_november">Novemba</string>
+    <string name="month_long_december">Desemba</string>
+
+    <string name="month_medium_january">Jan</string>
+    <string name="month_medium_february">Feb</string>
+    <string name="month_medium_march">Mac</string>
+    <string name="month_medium_april">Apr</string>
+    <string name="month_medium_may">Mei</string>
+    <string name="month_medium_june">Jun</string>
+    <string name="month_medium_july">Jul</string>
+    <string name="month_medium_august">Ago</string>
+    <string name="month_medium_september">Sep</string>
+    <string name="month_medium_october">Okt</string>
+    <string name="month_medium_november">Nov</string>
+    <string name="month_medium_december">Des</string>
+
+    <string name="month_shortest_january">1</string>
+    <string name="month_shortest_february">2</string>
+    <string name="month_shortest_march">3</string>
+    <string name="month_shortest_april">4</string>
+    <string name="month_shortest_may">5</string>
+    <string name="month_shortest_june">6</string>
+    <string name="month_shortest_july">7</string>
+    <string name="month_shortest_august">8</string>
+    <string name="month_shortest_september">9</string>
+    <string name="month_shortest_october">10</string>
+    <string name="month_shortest_november">11</string>
+    <string name="month_shortest_december">12</string>
+
+    <string name="day_of_week_long_sunday">Jumapili</string>
+    <string name="day_of_week_long_monday">Jumatatu</string>
+    <string name="day_of_week_long_tuesday">Jumanne</string>
+    <string name="day_of_week_long_wednesday">Jumatano</string>
+    <string name="day_of_week_long_thursday">Alhamisi</string>
+    <string name="day_of_week_long_friday">Ijumaa</string>
+    <string name="day_of_week_long_saturday">Jumamosi</string>
+
+    <string name="day_of_week_medium_sunday">Jpi</string>
+    <string name="day_of_week_medium_monday">Jtt</string>
+    <string name="day_of_week_medium_tuesday">Jnn</string>
+    <string name="day_of_week_medium_wednesday">Jtn</string>
+    <string name="day_of_week_medium_thursday">Alh</string>
+    <string name="day_of_week_medium_friday">Iju</string>
+    <string name="day_of_week_medium_saturday">Jmo</string>
+
+    <string name="day_of_week_short_sunday">Jpi</string>
+    <string name="day_of_week_short_monday">Jtt</string>
+    <string name="day_of_week_short_tuesday">Jnn</string>
+    <string name="day_of_week_short_wednesday">Jtn</string>
+    <string name="day_of_week_short_thursday">Alh</string>
+    <string name="day_of_week_short_friday">Iju</string>
+    <string name="day_of_week_short_saturday">Jmo</string>
+
+    <string name="day_of_week_shortest_sunday">1</string>
+    <string name="day_of_week_shortest_monday">2</string>
+    <string name="day_of_week_shortest_tuesday">3</string>
+    <string name="day_of_week_shortest_wednesday">4</string>
+    <string name="day_of_week_shortest_thursday">5</string>
+    <string name="day_of_week_shortest_friday">6</string>
+    <string name="day_of_week_shortest_saturday">7</string>
+
+    <string name="am">AM</string>
+    <string name="pm">PM</string>
+    <string name="yesterday">Yesterday</string>
+    <string name="today">Today</string>
+    <string name="tomorrow">Tomorrow</string>
+
+    <string name="hour_minute_24">%-k:%M</string>
+    <string name="hour_minute_ampm">%-l:%M %p</string>
+    <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
+    <string name="twelve_hour_time_format">h:mm a</string>
+    <string name="twenty_four_hour_time_format">H:mm</string>
+    <string name="numeric_date">%Y/%m/%d</string>
+    <string name="numeric_date_format">yyyy/MM/dd</string>
+    <string name="numeric_date_template">"%s/%s/%s"</string>
+    <string name="month_day_year">%Y %B %-e</string>
+    <string name="time_of_day">%H:%M:%S</string>
+    <string name="date_and_time">%H:%M:%S %Y %b %-e</string>
+    <string name="date_time">%2$s %1$s</string>
+    <string name="time_date">%1$s %3$s</string>
+    <string name="abbrev_month_day_year">%Y %b %-e</string>
+    <string name="month_day">%B %-e</string>
+    <string name="month">%-B</string>
+    <string name="month_year">%Y %B</string>
+    <string name="abbrev_month_day">%b %-e</string>
+    <string name="abbrev_month">%-b</string>
+    <string name="abbrev_month_year">%Y %b</string>
+    <string name="time1_time2">%1$s – %2$s</string>
+    <string name="date1_date2">%2$s – %5$s</string>
+    <string name="numeric_md1_md2">%2$s-%3$s – %7$s-%8$s</string>
+    <string name="numeric_wday1_md1_wday2_md2">%1$s, %2$s-%3$s – %6$s, %7$s-%8$s</string>
+    <string name="numeric_mdy1_mdy2">%4$s-%2$s-%3$s – %9$s-%7$s-%8$s</string>
+    <string name="numeric_wday1_mdy1_wday2_mdy2">%1$s, %4$s-%2$s-%3$s – %6$s, %9$s-%7$s-%8$s</string>
+    <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %4$s-%2$s-%3$s – %10$s %6$s, %9$s-%7$s-%8$s</string>
+    <string name="numeric_md1_time1_md2_time2">%5$s %2$s-%3$s – %10$s %7$s-%8$s</string>
+    <string name="numeric_wday1_md1_time1_wday2_md2_time2">%5$s %1$s, %2$s-%3$s – %10$s %6$s, %7$s-%8$s</string>
+    <string name="numeric_mdy1_time1_mdy2_time2">%5$s %4$s/%2$s/%3$s – %10$s %9$s/%7$s/%8$s</string>
+    <string name="wday1_date1_time1_wday2_date2_time2">%3$s %1$s %2$s – %6$s %4$s %5$s</string>
+    <string name="wday1_date1_wday2_date2">%1$s %2$s – %4$s %5$s</string>
+    <string name="date1_time1_date2_time2">%3$s %2$s – %6$s %5$s</string>
+    <string name="time_wday_date">%1$s %2$s %3$s</string>
+    <string name="wday_date">%2$s %3$s</string>
+    <string name="time_wday">%1$s %2$s</string>
+    <string name="same_year_md1_md2">%2$s %3$s – %7$s %8$s</string>
+    <string name="same_year_wday1_md1_wday2_md2">%1$s %2$s %3$s – %6$s %7$s %8$s</string>
+    <string name="same_year_md1_time1_md2_time2">%5$s %2$s %3$s – %10$s %7$s %8$s</string>
+    <string name="same_month_md1_time1_md2_time2">%5$s %2$s %3$s – %10$s %7$s %8$s</string>
+    <string name="same_year_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %2$s %3$s – %10$s %6$s %7$s %8$s</string>
+    <string name="same_month_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %2$s %3$s – %10$s %6$s %7$s %8$s</string>
+    <string name="same_year_mdy1_time1_mdy2_time2">%5$s %4$s-%2$s-%3$s – %10$s %9$s-%7$s-%8$s</string>
+    <string name="same_month_mdy1_time1_mdy2_time2">%5$s %4$s-%2$s-%3$s – %10$s %9$s-%7$s-%8$s</string>
+    <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %4$s %2$s %3$s – %10$s %6$s, %9$s %7$s %8$s</string>
+    <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %4$s %2$s %3$s – %10$s %6$s, %9$s %7$s %8$s</string>
+    <string name="same_month_wday1_mdy1_wday2_mdy2">%1$s, %4$s %2$s %3$s – %6$s, %9$s %7$s %8$s</string>
+    <string name="same_month_md1_md2">%2$s-%3$s – %8$s</string>
+    <string name="same_month_wday1_md1_wday2_md2">%1$s %2$s %3$s – %6$s %7$s %8$s</string>
+    <string name="same_year_mdy1_mdy2">%9$s-%2$s-%3$s – %7$s-%8$s</string>
+    <string name="same_month_mdy1_mdy2">%9$s-%2$s-%3$s – %8$s</string>
+    <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s, %9$s-%2$s-%3$s – %6$s, yyyy-%7$s-%8$s</string>
+    <string name="short_format_month">%b</string>
+    <string name="full_wday_month_day_no_year">E MMMM d</string>
+    <string name="abbrev_wday_month_day_year">EEE, y MMM d</string>
+</resources>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 67f397a..66fe1a6 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -44,12 +44,12 @@
     <string name="passwordIncorrect" msgid="7612208839450128715">"Nenosiri si sahihi."</string>
     <string name="mmiComplete" msgid="8232527495411698359">"MMI imekamilika."</string>
     <string name="badPin" msgid="9015277645546710014">"PIN ya awali uliyoingiza si sahihi."</string>
-    <string name="badPuk" msgid="5487257647081132201">"PUK uliyochapisha si sahihi."</string>
+    <string name="badPuk" msgid="5487257647081132201">"PUK uliyoingiza si sahihi."</string>
     <string name="mismatchPin" msgid="609379054496863419">"PIN ulizoingiza haziambatani."</string>
     <string name="invalidPin" msgid="3850018445187475377">"Chapisha PIN ambayo ina nambari 4 hadi 8."</string>
     <string name="invalidPuk" msgid="8761456210898036513">"Andika PUK ambayo ina urefu wa nambari 8 au zaidi."</string>
     <string name="needPuk" msgid="919668385956251611">"Kadi yako ya SIM imefungwa na PUK. Anika msimbo wa PUK ili kuifungua."</string>
-    <string name="needPuk2" msgid="4526033371987193070">"Chapisha PUK2 ili kufungua kadi ya SIM."</string>
+    <string name="needPuk2" msgid="4526033371987193070">"Chapisha PUK2 ili kufungua SIM kadi."</string>
     <string name="ClipMmi" msgid="6952821216480289285">"Kitambulisho cha Mpigaji wa Simu Inayoingia"</string>
     <string name="ClirMmi" msgid="7784673673446833091">"ID ya Mpigaji simu Inayotoka nje"</string>
     <string name="CfMmi" msgid="5123218989141573515">"Kusambaza simu"</string>
@@ -159,14 +159,14 @@
     <string name="permgrouplab_costMoney" msgid="5429808217861460401">"Huduma ambazo zinakugharimu pesa"</string>
     <string name="permgroupdesc_costMoney" msgid="8596717365335027057">"Inaruhusu programu kufanya vitu ambavyo vinaweza kukugharimu pesa."</string>
     <string name="permgrouplab_messages" msgid="7521249148445456662">"Ujumbe wako"</string>
-    <string name="permgroupdesc_messages" msgid="7821999071003699236">"Soma na kuandika ujumbe mfupi, barua pepe, na ujumbe zako zingine."</string>
+    <string name="permgroupdesc_messages" msgid="7821999071003699236">"Soma na kuandika SMS, barua pepe, na jumbe zako zingine."</string>
     <string name="permgrouplab_personalInfo" msgid="3519163141070533474">"Maelezo yako ya kibinafsi"</string>
     <string name="permgroupdesc_personalInfo" product="tablet" msgid="6975389054186265786">"Ufikiaji wa moja kwa moja wa anwani zako na kalenda iliyohifadhiwa kwenye kompyuta ndogo."</string>
     <string name="permgroupdesc_personalInfo" product="default" msgid="5488050357388806068">"Ufikiaji wa moja kwa moja wa anwani zako na kalenda zilizohifadhiwa kwenye simu."</string>
     <string name="permgrouplab_location" msgid="635149742436692049">"Mahali pako"</string>
     <string name="permgroupdesc_location" msgid="2430258821648348660">"Fuatilia mahali pako pa mwili"</string>
     <string name="permgrouplab_network" msgid="5808983377727109831">"Mawasiliano ya mtandao"</string>
-    <string name="permgroupdesc_network" msgid="4917593670797570584">"Ruhusu programu kufikia sifa mbalimbali za mtandao."</string>
+    <string name="permgroupdesc_network" msgid="4917593670797570584">"Ruhusu programu kufikia vipengee mbalimbali vya mtandao."</string>
     <string name="permgrouplab_accounts" msgid="3359646291125325519">"Akaunti zako"</string>
     <string name="permgroupdesc_accounts" msgid="4948732641827091312">"Fikia akaunti zinazopatikana."</string>
     <string name="permgrouplab_hardwareControls" msgid="7998214968791599326">"Vidhibiti vya maunzi"</string>
@@ -176,44 +176,44 @@
     <string name="permgrouplab_systemTools" msgid="4652191644082714048">"Zana za mfumo"</string>
     <string name="permgroupdesc_systemTools" msgid="8162102602190734305">"Ufikiaji wa kiwango cha chini na udhibiti wa mfumo."</string>
     <string name="permgrouplab_developmentTools" msgid="3446164584710596513">"Zana za utengenezaji"</string>
-    <string name="permgroupdesc_developmentTools" msgid="7058828032358142018">"Mandhari zinahitajika tu na wasinidi wa programu."</string>
+    <string name="permgroupdesc_developmentTools" msgid="7058828032358142018">"Vipengee vinahitajika tu na wasinidi wa programu."</string>
     <string name="permgrouplab_storage" msgid="1971118770546336966">"Hifadhi"</string>
     <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"Fikia hifadhi ya USB."</string>
     <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"Fikia kadi ya SD."</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"lemaza au rekebisha mwambaa hali"</string>
-    <string name="permdesc_statusBar" msgid="8434669549504290975">"Inaruhusu programu kulemeza upau wa hali au kuongeza na kutoa ikoni ya mfumo."</string>
+    <string name="permdesc_statusBar" msgid="8434669549504290975">"Inaruhusu programu kulemaza upau wa hali au kuongeza na kutoa ikoni za mfumo."</string>
     <string name="permlab_statusBarService" msgid="7247281911387931485">"mwamba hali"</string>
     <string name="permdesc_statusBarService" msgid="716113660795976060">"Inaruhusu programu kuwa upau wa hali."</string>
     <string name="permlab_expandStatusBar" msgid="1148198785937489264">"panua/kunja mwambaa hali"</string>
     <string name="permdesc_expandStatusBar" msgid="6917549437129401132">"Inaruhusu programu kupanua au kukunja upau wa hali."</string>
     <string name="permlab_processOutgoingCalls" msgid="1136262550878335980">"ingilia simu zinazotoka"</string>
-    <string name="permdesc_processOutgoingCalls" msgid="1152111671618301044">"Inaruhusu programu kuchakata simu zinazotoka na kubadilisha nambari itakayopigwa. Programu hasidi zinaweza kufuatilia, kuelekeza, au kuzuia simu zinazotoka."</string>
+    <string name="permdesc_processOutgoingCalls" msgid="1152111671618301044">"Inaruhusu programu kuchakata simu zinazotoka na kubadilisha nambari itakayopigwa. Programu hasidi zinaweza kufuatilia, kuelekeza kwingine, au kuzuia simu zinazotoka."</string>
     <string name="permlab_receiveSms" msgid="2697628268086208535">"pokea SMS"</string>
-    <string name="permdesc_receiveSms" msgid="8107887121893611793">"Inaruhusu programu kupokea na kuchakata ujumbe mfupi. Programu mbovu zinaweza kufuatilia ujumbe wako au kufuta bila kukuonyesha."</string>
+    <string name="permdesc_receiveSms" msgid="8107887121893611793">"Inaruhusu programu kupokea na kuchakata jumbe za SMS. Programu hasidi zinaweza kufuatilia jumbe zako au kuzifuta bila kukuonyesha."</string>
     <string name="permlab_receiveMms" msgid="8894700916188083287">"pokea MMS"</string>
     <string name="permdesc_receiveMms" msgid="1424805308566612086">"Inaruhusu programu kupokea na kuchakata jumbe za MMS. Programu hasidi zinaweza  kufuatilia jumbe zako au kuzifuta bila kukuonyesha."</string>
     <string name="permlab_receiveEmergencyBroadcast" msgid="1803477660846288089">"Pokea matangazo ya dharura"</string>
-    <string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"Inaruhusu programu kupokea na kuchakata matangazo ya dharura. Ruhusa hii inapatikana tu kwa programu za mfumo."</string>
+    <string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"Inaruhusu programu kupokea na kuchakata jumbe za dharura. Ruhusa hii inapatikana tu kwa programu za mfumo."</string>
     <string name="permlab_sendSms" msgid="5600830612147671529">"tuma ujumbe wa SMS"</string>
-    <string name="permdesc_sendSms" msgid="906546667507626156">"Inaruhusu programu kutuma ujumbe mfupi. Programu hasidi zinaweza kukugharimu fedha kwa kutuma jumbe bila uthibitisho wako."</string>
+    <string name="permdesc_sendSms" msgid="906546667507626156">"Inaruhusu programu kutuma jumbe za SMS. Programu hasidi zinaweza kukugharimu fedha kwa kutuma jumbe bila uthibitisho wako."</string>
     <string name="permlab_sendSmsNoConfirmation" msgid="4781483105951730228">"Tuma ujumbe wa SMS bila ya thibitisho"</string>
-    <string name="permdesc_sendSmsNoConfirmation" msgid="3437759207020400204">"Huruhusu programu kutuma ujumbe wa SMS. Programu mbovu huenda ikakugharimu pesa kwa kutuma ujumbe bila uthibitisho wako."</string>
+    <string name="permdesc_sendSmsNoConfirmation" msgid="3437759207020400204">"Huruhusu programu kutuma jumbe wa SMS. Programu hasidi huenda zikakugharimu pesa kwa kutuma jumbe bila uthibitisho wako."</string>
     <string name="permlab_readSms" msgid="4085333708122372256">"soma SMS au MMS"</string>
-    <string name="permdesc_readSms" product="tablet" msgid="2341692916884515613">"Inaruhusu programu kusoma ujumbe mfupi uliyohifadhiwa kwenye kompyuta ndogo au SIM kadi. Programu mbovu zinaweza kusoma ujumbe wako wa siri."</string>
-    <string name="permdesc_readSms" product="default" msgid="5653850482025875493">"Inaruhusu programu kusoma ujumbe mfupi uliyohifadiwa kwenye simu ya au SIM kadi. Programu mbovu zinaweza kusoma ujumbe wako wa siri."</string>
+    <string name="permdesc_readSms" product="tablet" msgid="2341692916884515613">"Inaruhusu programu kusoma jumbe za SMS zilizohifadhiwa kwenye kompyuta kibao au SIM kadi yako. Programu hasidi zinaweza kusoma jumbe zako za siri."</string>
+    <string name="permdesc_readSms" product="default" msgid="5653850482025875493">"Inaruhusu programu kusoma jumbe za SMS zilizohifadiwa kwenye simu ya au SIM kadi. Programu hasidi zinaweza kusoma jumbe zako za siri."</string>
     <string name="permlab_writeSms" msgid="6881122575154940744">"hariri SMS au MMS"</string>
-    <string name="permdesc_writeSms" product="tablet" msgid="5160413947794501538">"Inaruhusu programu kuandika ujumbe mfupi unaohifadhiwa kwenye kompyuta yako ndogo au kadi ya SIM. Programu mbovu zinaweza kufuta ujumbe zako."</string>
-    <string name="permdesc_writeSms" product="default" msgid="7268668709052328567">"Inaruhusu programu kuandika ujumbe mfupi unaohifadhiwa kwenye simu yako au kadi ya SIM. Programu mbovu zinaweza kufuta ujumbe zako."</string>
+    <string name="permdesc_writeSms" product="tablet" msgid="5160413947794501538">"Inaruhusu programu kuandikia jumbe za SMS zinazohifadhiwa kwenye kompyuta yako kibao au SIM kadi. Programu hasidi zinaweza kufuta jumbe zako."</string>
+    <string name="permdesc_writeSms" product="default" msgid="7268668709052328567">"Inaruhusu programu kuandika jumbe za SMS zinazohifadhiwa kwenye simu yako au SIM kadi. programu hasidi zinaweza kufuta ujumbe zako."</string>
     <string name="permlab_receiveWapPush" msgid="8258226427716551388">"pokea WAP"</string>
-    <string name="permdesc_receiveWapPush" msgid="7983455145335316872">"Inaruhusu programu kupokea na kuchakata ujumbe za WAP. Programu mbovu zinaweza kufuatilia ujumbe wako au kufuta bila kukuonyesha."</string>
-    <string name="permlab_getTasks" msgid="6466095396623933906">"Rudisha programu zinazoendeshwa"</string>
-    <string name="permdesc_getTasks" msgid="6608159250520381359">"Inaruhusu programu kupata taarifa kuhusu kazi za sasa na hivi karibuni. Programu mbovu zinaweza kugundua taarifa kuhusu programu zingine."</string>
+    <string name="permdesc_receiveWapPush" msgid="7983455145335316872">"Inaruhusu programu kupokea na kuchakata jumbe za WAP. Programu hasidi zinaweza kufuatilia jumbe zako au kuzifuta bila kukuonyesha."</string>
+    <string name="permlab_getTasks" msgid="6466095396623933906">"rudisha programu zinazoendeshwa"</string>
+    <string name="permdesc_getTasks" msgid="6608159250520381359">"Inaruhusu programu kupata taarifa kuhusu kazi zinazoendelea sasa na hivi karibuni. Programu hasidi zinaweza kugundua taarifa ya kibinafsi kuhusu programu zingine."</string>
     <string name="permlab_reorderTasks" msgid="2018575526934422779">"Agiza tena programu za kuendeshwa"</string>
-    <string name="permdesc_reorderTasks" msgid="4175137612205663399">"Inaruhusu programu kusongesha hoja za kazi kwa mandhari ya mbele na nyuma. Programu mbovu zinaweza kujilazimisha mbele bila udhibiti wako."</string>
-    <string name="permlab_removeTasks" msgid="6821513401870377403">"Komesha uendeshaji wa programu"</string>
+    <string name="permdesc_reorderTasks" msgid="4175137612205663399">"Inaruhusu programu kusongesha kazi kwenye mandhari-mbele na mandhari-nyuma. Programu hasidi zinaweza kujilazimisha mbele bila udhibiti wako."</string>
+    <string name="permlab_removeTasks" msgid="6821513401870377403">"Komesha programu zinazoendeshwa"</string>
     <string name="permdesc_removeTasks" msgid="1000226123143185094">"Inaruhusu programu kuondoa kazi na kuua programu zao. Programu hasidi zinaweza  katiza mwenendo wa programu zingine."</string>
-    <string name="permlab_setDebugApp" msgid="3022107198686584052">"wezesha programu kueua"</string>
-    <string name="permdesc_setDebugApp" msgid="6215654419903651172">"Inaruhusu Programu kuwezesha kueua kwa programu nyingine. Programu mbovu zinaweza kutumia hii kuua programu zingine."</string>
+    <string name="permlab_setDebugApp" msgid="3022107198686584052">"wezesha utatuaji wa programu"</string>
+    <string name="permdesc_setDebugApp" msgid="6215654419903651172">"Inaruhusu Programu kuwezesha utatuaji kwa programu nyingine. Programu hasidi zinaweza kutumia hii kuua programu zingine."</string>
     <string name="permlab_changeConfiguration" msgid="8214475779521218295">"badilisha mipangilio yako ya onyesho"</string>
     <string name="permdesc_changeConfiguration" msgid="4104052649900380324">"Inaruhusu programu kubadilisha usanidi wa sasa, kama vile mahali au ukubwa wa jumla wa fonti."</string>
     <string name="permlab_enableCarMode" msgid="5684504058192921098">"Wezesha mtindo wa gari"</string>
@@ -222,135 +222,137 @@
     <string name="permdesc_killBackgroundProcesses" msgid="931129103262126617">"Inaruhusu programu kuua mchakato wa usuli wa programu zingine, hata kama kumbukumbu si ndogo."</string>
     <string name="permlab_forceStopPackages" msgid="2329627428832067700">"Lazimisha kukomesha programu zingine"</string>
     <string name="permdesc_forceStopPackages" msgid="5253157296183940812">"Inaruhusu programu kulazimisha programu zingine kuacha."</string>
-    <string name="permlab_forceBack" msgid="652935204072584616">"Lazimisha programu kufunga"</string>
-    <string name="permdesc_forceBack" msgid="3892295830419513623">"Huruhusu programu kulazimisha shughuli yoyote iliyo mbele kufunga na kurudi nyuma. Kamwe haitahitajika kwa programu za kawaida."</string>
+    <string name="permlab_forceBack" msgid="652935204072584616">"lazimisha programu kufunga"</string>
+    <string name="permdesc_forceBack" msgid="3892295830419513623">"Huruhusu programu kulazimisha shughuli yoyote iliyo kwenye mandhari-mbele kufunga na kurudi nyuma. Kamwe haitahitajika kwa programu za kawaida."</string>
     <string name="permlab_dump" msgid="1681799862438954752">"epua hali ya ndani ya mfumo"</string>
     <string name="permdesc_dump" msgid="1778299088692290329">"Inaruhusu programu kutoa hali ya ndani ya mfumo. Programu hasidi zinaweza kutoa aina nyingi za taarifa za faragha na salama ambazo kwa kawaida hazihitaji."</string>
     <string name="permlab_retrieve_window_content" msgid="8022588608994589938">"epua maudhui ya skrini"</string>
-    <string name="permdesc_retrieve_window_content" msgid="3193269069469700265">"Inaruhusu programu kutoa maudhui ya dirisha amilifu. Programu mbovu zinaweza kuepua maudhui yote ya dirisha na kuchunguza maandishi yake yote ispokuwa nenosiri."</string>
+    <string name="permdesc_retrieve_window_content" msgid="3193269069469700265">"Inaruhusu programu kutoa maudhui ya dirisha amilifu. Programu hasidi zinaweza kutoa maudhui yote ya dirisha na kuchunguza maandishi yake yote isipokuwa nenosiri."</string>
     <string name="permlab_shutdown" msgid="7185747824038909016">"Zima nusu"</string>
     <string name="permdesc_shutdown" msgid="7046500838746291775">"Huweka kisimamia shughuli katika hali ya kuzima. Haiadhiri uzimaji kamili"</string>
     <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"zuia swichi za app"</string>
-    <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"Huzuia mtumiaji dhidi ya kubadilisha kwa programu nyingine."</string>
+    <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"Huzuia mtumiaji dhidi ya kubadilisha na kwenda kwa programu nyingine."</string>
     <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"Fuatilia na kudhibiti uzinduzi wote wa programu"</string>
-    <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"Inaruhusu programu kufuatilia na kudhibiti jinsi mfumo unazindua shughuli. Programu mbovu zinaweza ingilia mfumo. Ruhusa inahitajika kwa usanidi, si kwa ajili ya matumizi ya kawaida."</string>
+    <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"Inaruhusu programu kufuatilia na kudhibiti jinsi mfumo unazindua shughuli. Programu hasidi zinaweza kutia mfumo hatarini. Ruhusa inahitajika tu kwa usanidi, kamwe sio kwa matumizi ya kawaida."</string>
     <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"furushi lililotumwa limeondoa tangazo"</string>
-    <string name="permdesc_broadcastPackageRemoved" msgid="6621901216207931089">"Inaruhusu programu kutangaza taarifa kwamba furushi ya programu imetolewa. Programu mbovu zinaweza kutumia hii kuua programu yeyote inayoendeshwa."</string>
+    <string name="permdesc_broadcastPackageRemoved" msgid="6621901216207931089">"Inaruhusu programu kutangaza taarifa kwamba furushi ya programu imetolewa. Programu hasidi zinaweza kutumia hii kuua programu yoyote inayoendeshwa."</string>
     <string name="permlab_broadcastSmsReceived" msgid="5689095009030336593">"tuma matanazo yaliyopokewa ya SMS"</string>
-    <string name="permdesc_broadcastSmsReceived" msgid="4152037720034365492">"Inaruhusu programu kutangaza taarifa kwamba ujumbe mfupi umepatikana. Programu mbovu zinaweza tumia hii kubuni ujumbe mfupi unaoingia."</string>
+    <string name="permdesc_broadcastSmsReceived" msgid="4152037720034365492">"Inaruhusu programu kutangaza taarifa kwamba ujumbe wa SMS umepokewa. Programu hasidi zinaweza tumia hii kubuni jumbe za SMS zinazoingia."</string>
     <string name="permlab_broadcastWapPush" msgid="3145347413028582371">"tuma tangazo lililopokewa la MSUKUMO WA WAP"</string>
-    <string name="permdesc_broadcastWapPush" msgid="4783402525039442729">"Inaruhusu programu kutangaza taarifa kwamba ujumbe wa WAP PUSH umesajiliwa. Programu mbovu zinaweza kutumia hii kubuni risiti ya ujumbe wa MMS au kubadilisha maudhui yoyote ya ukurasa wa tovuti na vibadala vibovu."</string>
+    <string name="permdesc_broadcastWapPush" msgid="4783402525039442729">"Inaruhusu programu kutangaza taarifa kwamba ujumbe wa WAP PUSH umepokewa. Programu hasidi zinaweza kutumia hii kubuni risiti ya ujumbe wa MMS au polepole kubadilisha maudhui yoyote ya ukurasa wa tovuti na vibadala vibovu."</string>
     <string name="permlab_setProcessLimit" msgid="2451873664363662666">"zuia idadi ya michakato inayoendeshwa"</string>
     <string name="permdesc_setProcessLimit" msgid="7318061314040879542">"Inaruhusu programu kudhibiti upeo wa idadi ya michakato ambayo itaendeshwa. Kamwe hazihitajiki kwa programu za kwaida."</string>
     <string name="permlab_setAlwaysFinish" msgid="238828158465736054">"fanya programu zote za usuli zifunge"</string>
-    <string name="permdesc_setAlwaysFinish" msgid="7471310652868841499">"Inaruhusu programu kudhibiti kama daima shughuli zinamalizwa wakati ziendapo kwa mandhari. Kamwe hazihitajiki kwa programu za kawaida."</string>
+    <string name="permdesc_setAlwaysFinish" msgid="7471310652868841499">"Inaruhusu programu kudhibiti kama daima shughuli zinamalizwa wakati ziendapo kwa mandhari-nyuma. Kamwe hazihitajiki kwa programu za kawaida."</string>
     <string name="permlab_batteryStats" msgid="7863923071360031652">"rekebisha takwimu za betri"</string>
     <string name="permdesc_batteryStats" msgid="6835186932305744068">"Inaruhusu programu kurekebisha takwimu za betri zilizokusanywa. Si kwa matumizi ya programu za kawaida."</string>
     <string name="permlab_backup" msgid="470013022865453920">"Dhibiti chelezo la mfumo na rejesha"</string>
-    <string name="permdesc_backup" msgid="6912230525140589891">"Inaruhusu programu kudhibiti mfumo wa chelezo na kurejesha mashine. Si kwa matumizi na programu za kawaida."</string>
+    <string name="permdesc_backup" msgid="6912230525140589891">"Inaruhusu programu kudhibiti utaratibu wa kucheleza na kurejesha wa mfumo. Si kwa matumizi na programu za kawaida."</string>
     <string name="permlab_confirm_full_backup" msgid="5557071325804469102">"thibitisha chelezo kamilifu au rejesha upya uendeshaji"</string>
-    <string name="permdesc_confirm_full_backup" msgid="1748762171637699562">"Inaruhusu programu kuzindua UI kamili ya kuthibitisha wa chelezo kamili ya UI. Si ya kutumiwa na programu yoyote."</string>
+    <string name="permdesc_confirm_full_backup" msgid="1748762171637699562">"Inaruhusu programu kuzindua UI ya kuthibitisha chelezo kamili. Si ya kutumiwa na programu yoyote."</string>
     <string name="permlab_internalSystemWindow" msgid="2148563628140193231">"onyesha madirisha yasiyoidhinishwa"</string>
-    <string name="permdesc_internalSystemWindow" msgid="6510907081810231374">"Inaruhusu programu kuunda windows ambazo zinanuiwa kutumiwa na mfumo wa ndani wa kusano ya mtumiaji. Si ya matumizi na programu za kawaida."</string>
+    <string name="permdesc_internalSystemWindow" msgid="6510907081810231374">"Inaruhusu programu kuunda madirisha ambayo zinanuiwa kutumiwa na mfumo wa ndani wa kusano ya mtumiaji. Si ya matumizi na programu za kawaida."</string>
     <string name="permlab_systemAlertWindow" msgid="3372321942941168324">"onyesha tahadhari za kiwango cha mfumo"</string>
-    <string name="permdesc_systemAlertWindow" msgid="8507863469978066409">"Inaruhusu programu kuonyesha mfumo wa tahadhari wa windows. Programu mbovu zaweza kuchukua skrini nzima."</string>
+    <string name="permdesc_systemAlertWindow" msgid="8507863469978066409">"Inaruhusu programu kuonyesha dirisha za arifa za mfumo. Programu hasidi zaweza kutawala skrini nzima."</string>
     <string name="permlab_setAnimationScale" msgid="2805103241153907174">"rekebisha kasi ya jumla ya uhuisho"</string>
     <string name="permdesc_setAnimationScale" msgid="6505093307223395456">"Inaruhusu programu kubadilisha kasi ya uhuishaji jumla (uhuisho wa polepole au wa haraka) wakati wowote."</string>
     <string name="permlab_manageAppTokens" msgid="1286505717050121370">"Dhibiti shuhuda za programu"</string>
-    <string name="permdesc_manageAppTokens" msgid="8043431713014395671">"Inaruhusu programu kuunda na kudhibiti shuhuda zake, kupita agizo zao za kawaida. Haitahitajika kamwe na programu za kawaida."</string>
+    <string name="permdesc_manageAppTokens" msgid="8043431713014395671">"Inaruhusu programu kuunda na kudhibiti shuhuda zake, kukwepa mipangilio yao ya kawaida. Haitahitajika kamwe na programu za kawaida."</string>
     <string name="permlab_injectEvents" msgid="1378746584023586600">"bonyeza vitufe na vitufe vya kudhibiti"</string>
-    <string name="permdesc_injectEvents" product="tablet" msgid="206352565599968632">"Huruhusu programu kuwasilisha matukio yake yenyewe ya ingizo (mibofyo ya vitufe, nk.) kwa programu zingine. Programu mbovu zinaweza kutumia hii ili kutawala kompyuta ndogo."</string>
-    <string name="permdesc_injectEvents" product="default" msgid="653128057572326253">"Inaruhusu programu kuwasilisha ingizo la tukio(mibofyo ya kitufe, nk.)kwa programu zingine.Programu mbovu zinaweza kutumia hii kuchukua simu."</string>
+    <string name="permdesc_injectEvents" product="tablet" msgid="206352565599968632">"Huruhusu programu kuwasilisha matukio yake ya ingizo (mibonyezo ya vitufe, nk.) kwa programu zingine. programu hasidi zinaweza kutumia hii ili kutawala kompyuta kibao."</string>
+    <string name="permdesc_injectEvents" product="default" msgid="653128057572326253">"Inaruhusu programu kuwasilisha matukio yake ya ingizo (mibonyezo ya kitufe, nk.)kwa programu zingine.Programu hasidi zinaweza kutumia hii kutawala simu."</string>
     <string name="permlab_readInputState" msgid="469428900041249234">"rekodi unachochapa na hatua unazochukua"</string>
-    <string name="permdesc_readInputState" msgid="8387754901688728043">"Inaruhusu programu kuangalia vibonye unavyo bonyeza hata wakati unapo shirikiana na programu nyingine (kama vile kuweka nywila). Kamwe isihitajike na programu za kawaida."</string>
+    <string name="permdesc_readInputState" msgid="8387754901688728043">"Inaruhusu programu kuangalia vibonye unavyo bonyeza hata wakati unapo shirikiana na programu nyingine (kama vile kuweka neno). Kamwe isihitajike na programu za kawaida."</string>
     <string name="permlab_bindInputMethod" msgid="3360064620230515776">"funganisha kwa mbinu ya uingizaji"</string>
-    <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Inaruhusu kishikiliaji kushurutisha kusano ya kiwango cha juu. Haipaswi kuhitajika kwa programu za kawaida."</string>
+    <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Inaruhusu mmiliki kushurutisha kwenye kusano ya kiwango cha juu ya mbinu ya ingizo. Haipaswi kuhitajika kwa programu za kawaida."</string>
     <string name="permlab_bindTextService" msgid="7358378401915287938">"Imefungwa kwa huduma ya maandishi"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"Inaruhusu kishikiliaji kushurutisha kusano ya kiwango cha juu ya huduma ya matini(k.m.SpellCheckerService). Haipaswi kuhitajika kwa programu za kawaida."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"funga kwa huduma ya VPN"</string>
     <string name="permdesc_bindVpnService" msgid="2067845564581693905">"Inaruhusu kishikiliaji kushurutisha kusano ya kiwango cha juu cha huduma ya Vpn. Haipaswi kuhitajika kwa programu za kawaida."</string>
-    <string name="permlab_bindWallpaper" msgid="8716400279937856462">"funga kwa pazia"</string>
-    <string name="permdesc_bindWallpaper" msgid="7108428692595491668">"Inaruhusu kishikiliaji kushurutisha kwa kusano ya kiwango cha juu cha mandhari.usano cha kiwango cha pazia. Haipaswi kamwe kuhitajika kwa programu za kawaida."</string>
+    <string name="permlab_bindWallpaper" msgid="8716400279937856462">"funga kwa mandhari"</string>
+    <string name="permdesc_bindWallpaper" msgid="7108428692595491668">"Inaruhusu kishikiliaji kushurutisha kwa kusano ya kiwango cha juu cha mandhari. Haipaswi kamwe kuhitajika kwa programu za kawaida."</string>
     <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"funga kwenye huduma ya widget"</string>
-    <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Inaruhusu kishikiliaji kushurutisha kusano ya kiwango cha juu ya huduma ya wijeti. Haipaswi kuhitajika kwa programu za kawaida."</string>
+    <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Inaruhusu mmiliki kushurutisha kusano ya kiwango cha juu ya huduma ya wijeti. Haipaswi kuhitajika kwa programu za kawaida."</string>
     <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"jiunge na msimamizi wa kifaa"</string>
-    <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Inamruhusu mshikiliaji kutuma malengo kwa msimamizi wa kifaa. Haipaswi kuhitajika kwa programu za kawaida."</string>
+    <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Inamruhusu mmiliki kutuma malengo kwa msimamizi wa kifaa. Haipaswi kuhitajika kwa programu za kawaida."</string>
     <string name="permlab_setOrientation" msgid="3365947717163866844">"badilisha uelekezo wa skrini"</string>
     <string name="permdesc_setOrientation" msgid="3046126619316671476">"Inaruhusu programu kubadilisha mzunguko wa skrini wakati wowote. Kamwe hazihitajiki kwa programu za kawaida."</string>
     <string name="permlab_setPointerSpeed" msgid="9175371613322562934">"Badilisha kasi ya pointa"</string>
-    <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"Inaruhusu programu kubadilisha kasi ya kipanya au kasi ya poiniti pedi ya kufuatilia wakati wowote. Kamwe haitahitajika kwa programu za kawaida."</string>
+    <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"Inaruhusu programu kubadilisha kasi ya kielekezi cha kipanya au pedi ya kufuatilia wakati wowote. Kamwe haitahitajika kwa programu za kawaida."</string>
     <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"Tuma ishara za Linux kwa programu"</string>
     <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"Inaruhusu programu kuomba ishara iliyotolewa kutumwa kwa michakato inyoendelea."</string>
     <string name="permlab_persistentActivity" msgid="8841113627955563938">"Fanya programu kuendeshwa kila mara"</string>
-    <string name="permdesc_persistentActivity" msgid="4909910271316074418">"Inaruhusu programu kufanya sehemu zingine kuendelea kuwepo, kwa hivyo mfumo hauwezi kuitumia kwa programu zingine."</string>
+    <string name="permdesc_persistentActivity" msgid="4909910271316074418">"Inaruhusu programu kufanya sehemu zake zingine kuendelea kuwepo, kwa hivyo mfumo hauwezi kuitumia kwa programu zingine."</string>
     <string name="permlab_deletePackages" msgid="184385129537705938">"futa programu"</string>
-    <string name="permdesc_deletePackages" msgid="7411480275167205081">"Inaruhusu programu kufuta furushi za Android. Programu mbovu zinaweza kutumia hii kufuta programu muhimu."</string>
-    <string name="permlab_clearAppUserData" msgid="274109191845842756">"Futa data za programu\' zingine"</string>
-    <string name="permdesc_clearAppUserData" msgid="4625323684125459488">"Inaruhusu programu kutoa data ya mtumiaji."</string>
+    <string name="permdesc_deletePackages" msgid="7411480275167205081">"Inaruhusu programu kufuta furushi za Android. Programu hasidi zinaweza kutumia hii kufuta programu muhimu."</string>
+    <string name="permlab_clearAppUserData" msgid="274109191845842756">"Futa data za programu zingine"</string>
+    <string name="permdesc_clearAppUserData" msgid="4625323684125459488">"Inaruhusu programu kufuta data ya mtumiaji."</string>
     <string name="permlab_deleteCacheFiles" msgid="3128665571837408675">"Futa kache za programu zingine"</string>
     <string name="permdesc_deleteCacheFiles" msgid="3812998599006730196">"Inaruhusu programu kufuta faili za kache."</string>
-    <string name="permlab_getPackageSize" msgid="7472921768357981986">"Pima eneo la hifadhi ya programu"</string>
-    <string name="permdesc_getPackageSize" msgid="3921068154420738296">"Inaruhusu Programu kupata tena msimbo, data na ukubwa wa kache."</string>
+    <string name="permlab_getPackageSize" msgid="7472921768357981986">"Pima nafasi ya hifadhi ya programu"</string>
+    <string name="permdesc_getPackageSize" msgid="3921068154420738296">"Inaruhusu Programu kupata tena msimbo, data na ukubwa wa kache yake."</string>
     <string name="permlab_installPackages" msgid="2199128482820306924">"sakinisha programu moja kwa moja"</string>
-    <string name="permdesc_installPackages" msgid="5628530972548071284">"Inaruhusu programu kusakanisha au kusasishaji furushi mpya za Android. Programu mbovu zinaweza kutumia hii kuongeza programu mpya ambazo zina ruhusa za nguvu."</string>
-    <string name="permlab_clearAppCache" msgid="7487279391723526815">"Futa kache yote ya data ya programu"</string>
-    <string name="permdesc_clearAppCache" product="tablet" msgid="3523396284474042284">"Inaruhusu programu  kutoa hifadhi  ya kompyuta ndogo kwa kufuta faili katika programu ya saraka ya kache. Upatikanaji umekomeshwa kwa mfumo wa uendeshaji tu."</string>
-    <string name="permdesc_clearAppCache" product="default" msgid="5067988373366292186">"Inaruhusu programu  kutoa hifadhi  ya simu kwa kufuta faili katika programu ya saraka ya kache. Upatikanaji umekomeshwa kwa mfumo wa uendeshaji tu."</string>
+    <string name="permdesc_installPackages" msgid="5628530972548071284">"Inaruhusu programu kusakanisha au kusasisha furushi mpya za Android. Programu hasidi zinaweza kutumia hii kuongeza programu mpya ambazo zina ruhusa zenye nguvu."</string>
+    <string name="permlab_clearAppCache" msgid="7487279391723526815">"Futa data yote kwenye kache ya programu"</string>
+    <string name="permdesc_clearAppCache" product="tablet" msgid="3523396284474042284">"Inaruhusu programu kuongeza hifadhi ya kompyuta kibao kwa kufuta faili katika saraka ya kache ya programu. Upatikanaji umezuiwa kwa mfumo wa uendeshaji tu."</string>
+    <string name="permdesc_clearAppCache" product="default" msgid="5067988373366292186">"Inaruhusu programu  kuongeza hifadhi  ya simu kwa kufuta faili katika programu ya saraka ya kache. Upatikanaji umefungiwa kwa mfumo wa uendeshaji tu."</string>
     <string name="permlab_movePackage" msgid="3289890271645921411">"songesha rasilimali ya programu"</string>
-    <string name="permdesc_movePackage" msgid="319562217778244524">"Huruhusu programu kuhamisha nyenzo za programu kutoka midia ya ndani hadi ya nje na kinyumbe chake."</string>
+    <string name="permdesc_movePackage" msgid="319562217778244524">"Huruhusu programu kuhamisha nyenzo za programu kutoka midia ya ndani hadi ya nje na kinyume chake."</string>
     <string name="permlab_readLogs" msgid="6615778543198967614">"soma kumbukumbu ya data muhimu"</string>
-    <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"Inaruhusu programu kusoma kutoka kwa faili mbalimbali za batli za mfumo. Hii inairuhusu kutambua maelezo ya jumla kuhusu unachofanya na kompyuta ndogo, kwa hivyo kujumuisha maelezo ya kibinafsi na ya siri."</string>
-    <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Inaruhusu programu kusoma kutoka kwa faili mbalimbali za kumbukumbu za mfumo. Hii inairuhusu kutambua maelezo ya jumla kuhusu unachofanya na simu, kwa hivyo kujumuisha maelezo ya kibinafsi na ya siri."</string>
+    <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"Inaruhusu programu kusoma kutoka kwa faili mbalimbali za kumbukumbu za mfumo. Hii inairuhusu kutambua maelezo ya jumla kuhusu unachofanya na kompyuta kibao, kwa hivyo kujumuisha maelezo ya kibinafsi na ya siri."</string>
+    <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Inaruhusu programu kusoma kutoka kwa faili mbalimbali za kumbukumbu za mfumo. Hii inairuhusu kutambua maelezo ya jumla kuhusu unachofanya na simu, yanayoweza kujumuisha maelezo ya kibinafsi na ya siri."</string>
+    <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"Tumia chombo chochote cha habari cha kufasiria maandishi ya siri ili kucheza tena."</string>
+    <string name="permdesc_anyCodecForPlayback" msgid="2101444559995480174">"Huruhusu programu ya kompyuta kutumia vyombo vyovyote vya habari vya kufasiria maandishi ya siri, vilivyosanikishwa, ili kusimbua kwa kucheza tena."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"soma/andika kwa vyanzo vinavyomilikiwa na diag"</string>
-    <string name="permdesc_diagnostic" msgid="6608295692002452283">"Inaruhusu programu kusoma na kuandika kwa chanzo chochote kinachomilikiwa na kikundi cha diag; kwa mfano, faili katika /dev. Hii inaweza kuathiri udhabiti na usalama wa mfumo. Hii inapaswa kutumiwa TU kwa utambuzi mahsusi wa maunzi na mtengenezaji au opereta."</string>
+    <string name="permdesc_diagnostic" msgid="6608295692002452283">"Inaruhusu programu kusoma na kuandika kwa chanzo chochote kinachomilikiwa na kikundi cha diag; kwa mfano, faili katika /dev. Hii inaweza kuathiri udhabiti na usalama wa mfumo. Hii inapaswa kutumiwa TU kwa utambuzi mahsusi wa maunzi na mtengenezaji au opareta."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"wezesha au lemeza vijenzi vya programu"</string>
-    <string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Inaruhusu programu kubadilisha kama kijenzi cha programu nyingine kimewezeshwa au la. Programu mbovu zinaweza kutumia hii kulemeza uwezo muhimu wa kompyuta ndogo.Uangalifu lazima utumike kwa ruhusa hii, kuna uwezekano kupata vijenzi vya programu katika hali isiyotumika,haiendani, au hali isiyo thabiti."</string>
-    <string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Inaruhusu programu kubadilisha kama kijenzi cha programu nyingine kimewezeshwa au la. Programu hasidi zinaweza kutumia hii kulemeza mambo muhimu ambayo simu inaweza kufanya. Lazima uangalifu utumike kwa ruhusa hii, kwani kuna uwezekano kufanya vijenzi vya programu kuwa katika hali ya kutotumika, kubadilika badilika, au kutokuwa thabiti."</string>
+    <string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Inaruhusu programu kubadilisha kama kijenzi cha programu nyingine kimewezeshwa au la. Programu hasidi zinaweza kutumia hii kulemeza uwezo muhimu wa kompyuta kibao. Lazina uangalifu utumike kwa ruhusa hii, kwani kuna uwezekano kupata vijenzi vya programu katika hali isiyotumika, isiyowiana, au hali isiyo thabiti."</string>
+    <string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Inaruhusu programu kubadilisha kama kijenzi cha programu nyingine kimewezeshwa au la. Programu hasidi zinaweza kutumia hii kulemeza mambo muhimu ambayo simu inaweza kufanya. Lazima uangalifu utumike kwa ruhusa hii, kwani kuna uwezekano kufanya vijenzi vya programu kuwa katika hali ya kutotumika, kutokuwa na uwiano, au kutokuwa thabiti."</string>
     <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"kuweka programu zinazopendelewa"</string>
-    <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Inaruhusu programu kurekebisha programu unazo pendelea. Programu mbovu zinaweza badilisha programu zinazo endeshwa kikimya, inajifanya programu zako zilizopo kukusanya data ya kibinafsi kutoka kwako."</string>
+    <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Inaruhusu programu kurekebisha programu unazopendelea. Programu hasidi zinaweza, polepole, kubadilisha programu zinazoendeshwa, na kuzifanya programu ulizo nazo kukusanya data ya kibinafsi kutoka kwako."</string>
     <string name="permlab_writeSettings" msgid="1365523497395143704">"rekebisha mipangilio ya mfumo jumla"</string>
-    <string name="permdesc_writeSettings" msgid="7775723441558907181">"Inaruhusu programu kurekebisha mipangilio ya mfumo wa data.Programu mbovu zinaweza kuvuruga usanidi wa mfumo wako."</string>
+    <string name="permdesc_writeSettings" msgid="7775723441558907181">"Inaruhusu programu kurekebisha mipangilio ya mfumo wa data. Programu hasidi zinaweza kuvuruga usanidi wa mfumo wako."</string>
     <string name="permlab_writeSecureSettings" msgid="204676251876718288">"rekebisha mipangilio ya mfumo salama"</string>
-    <string name="permdesc_writeSecureSettings" msgid="8159535613020137391">"Inaruhusu programu kurekebisha mipagilio ya mfumo wa data salama. Si matumizi na programu za kawaida."</string>
+    <string name="permdesc_writeSecureSettings" msgid="8159535613020137391">"Inaruhusu programu kurekebisha mipagilio ya mfumo wa data salama. Si ya kutumiwa na programu za kawaida."</string>
     <string name="permlab_writeGservices" msgid="2149426664226152185">"rekebisha ramani ya Google services"</string>
     <string name="permdesc_writeGservices" msgid="1287309437638380229">"Inaruhusu programu kurekebisha ramani ya huduma za Google. Si ya kutumiwa na programu za kawaida."</string>
     <string name="permlab_receiveBootCompleted" msgid="7776779842866993377">"anzisha kiotomatiki inapowashwa"</string>
-    <string name="permdesc_receiveBootCompleted" product="tablet" msgid="7390304664116880704">"Inaruhusu programu yenyewe kujianzisha baada ya mfumo kumaliza kuuanza upya. Hii inaweza kufanya ichukue muda mrefu kuanza kompyuta ndogo na kuruhusu programu kupunguza kasi ya kompyuta ndogo kijumla kwa kuendeshwa siku zote."</string>
-    <string name="permdesc_receiveBootCompleted" product="default" msgid="513950589102617504">"Inaruhusu programu kujianzisha yenyewe mfumo unapo maliza kuanza upya. Hii inaweza kuchukua muda mrefu simu kuanza na kuruhusu programu kupunguza kasi ya siku kijumla kwa kuendshwa polepole."</string>
+    <string name="permdesc_receiveBootCompleted" product="tablet" msgid="7390304664116880704">"Inaruhusu programu yenyewe kujianzisha baada ya mfumo kumaliza kuuanza upya. Hii inaweza kufanya ichukue muda mrefu kuanza kompyuta kibao na kuruhusu programu kupunguza kasi ya kompyuta kibao kijumla kwa kuendeshwa siku zote."</string>
+    <string name="permdesc_receiveBootCompleted" product="default" msgid="513950589102617504">"Inaruhusu programu kujianzisha yenyewe mfumo unapo maliza kuanza upya. Hii inaweza kuchukua muda mrefu simu kuanza na kuruhusu programu kupunguza kasi ya simu kwa jumla kwa kuendeshwa polepole kila wakati."</string>
     <string name="permlab_broadcastSticky" msgid="7919126372606881614">"tuma tangazo la kulanata"</string>
-    <string name="permdesc_broadcastSticky" product="tablet" msgid="1181582512022829259">"Inaruhusu programu kutuma matangazo nata, ambayo hubakia baada ya matangazo kuisha. Programu hasidi zinaweza fanya kompyuta ndogo kufanya kazi polepole au kuifanya isiwe thabiti kwa kuifanya itumie kumbukumbu kubwa zaidi."</string>
-    <string name="permdesc_broadcastSticky" product="default" msgid="3287869131621514325">"Inaruhusu programu kutuma matangazo nata, ambayo hubakia baada ya matangazo kuisha. Programu mbovu zinaweza fanya simu kufanya polepole au kuifanya isiwe thabiti kwa kutumia kumbukumbu kubwa zaidi."</string>
+    <string name="permdesc_broadcastSticky" product="tablet" msgid="1181582512022829259">"Inaruhusu programu kutuma matangazo nata, ambayo hubakia baada ya matangazo kuisha. Programu hasidi zinaweza fanya kompyuta kibao kufanya kazi polepole au kuifanya isiwe thabiti kwa kuifanya itumie kumbukumbu kubwa zaidi."</string>
+    <string name="permdesc_broadcastSticky" product="default" msgid="3287869131621514325">"Inaruhusu programu kutuma matangazo nata, ambayo hubakia baada ya matangazo kuisha. Programu hasidi zinaweza fanya simu kufanya kazi polepole au kuifanya isiwe thabiti kwa kuifanya itumie kumbukumbu kubwa zaidi."</string>
     <string name="permlab_readContacts" msgid="6219652189510218240">"soma data ya anwani"</string>
-    <string name="permdesc_readContacts" product="tablet" msgid="4028657556924039119">"Inaruhusu Programu kusoma data zote za  mwasiliani(anwani) zilohifadhiwa kwa  kompyuta yako ndogo. Programu mbovu inaweza kutumia hii kutuma data zako kwa watu wengine."</string>
+    <string name="permdesc_readContacts" product="tablet" msgid="4028657556924039119">"Inaruhusu Programu kusoma data zote za  mwasiliani(anwani) zilohifadhiwa kwa  kompyuta yako kibao. Programu hasidi zinaweza kutumia hii kutuma data zako kwa watu wengine."</string>
     <string name="permdesc_readContacts" product="default" msgid="2032222056456498547">"Inaruhusu Programu kusoma data zote za  mwasiliani(anwani) zilizohifadhiwa kwenye simu yako. Programu hasidi zinaweza kutumia hii kutuma data zako kwa watu wengine."</string>
     <string name="permlab_writeContacts" msgid="644616215860933284">"andika data ya anwani"</string>
-    <string name="permdesc_writeContacts" product="tablet" msgid="988969759110632978">"Inaruhusu programu kurekebisha data ya mwasiliani(anwani) iliyohifadhiwa kwenye kompyuta yako ki. Programu mbovu zinaweza tumia hii kufuta au kurekebisha data yako ya mwasiliani."</string>
-    <string name="permdesc_writeContacts" product="default" msgid="5075164818647934067">"Inaruhusu programu kurekebisha data ya mwasiliani(anwani) iliyohifadhiwa kwenye simu yako. Programu mbovu zinaweza tumia hii kufuta au kurekebisha data yako ya mwasiliani."</string>
+    <string name="permdesc_writeContacts" product="tablet" msgid="988969759110632978">"Inaruhusu programu kurekebisha data ya mwasiliani(anwani) iliyohifadhiwa kwenye kompyuta yako ki. programu hasidi zinaweza tumia hii kufuta au kurekebisha data yako ya mwasiliani."</string>
+    <string name="permdesc_writeContacts" product="default" msgid="5075164818647934067">"Inaruhusu programu kurekebisha data ya mwasiliani(anwani) iliyohifadhiwa kwenye simu yako. Programu hasidi zinaweza kutumia hii kufuta au kurekebisha data yako ya mwasiliani."</string>
     <string name="permlab_readProfile" msgid="6824681438529842282">"soma data ya maelezo yako mafupi"</string>
     <string name="permdesc_readProfile" product="default" msgid="94520753797630679">"Inaruhusu programu kusoma maelezo mafupi ya kibinafsi yaliyohifadhiwa kwenye kifaa chako, kama vile jina lako na taarifa ya kuwasiliana. Hii ina maanisha programu inaweza kukutambua na kutuma taarifa yako fupi ya kibinafsi kwa wengine."</string>
     <string name="permlab_writeProfile" msgid="4679878325177177400">"andika kwenye data ya maelezo yako mafupi"</string>
-    <string name="permdesc_writeProfile" product="default" msgid="4637366723793045603">"Inaruhusu programu kubadilisha au kuongeza taarifa ya kibinafsi ya mfumo iliyohifadhiwa katika kifaa chako, kama vile jina lako na maelezo ya mawasiliani. Hii ina maanisha programu zingine zinaweza kutambua mfumo wako na kutuma maelezo kwa wengine."</string>
+    <string name="permdesc_writeProfile" product="default" msgid="4637366723793045603">"Inaruhusu programu kubadilisha au kuongeza taarifa fupi ya kibinafsi iliyohifadhiwa katika kifaa chako, kama vile jina lako na maelezo ya kuwasiliana. Hii ina maanisha kwamba programu zingine zinaweza kukutambua na kutuma taarifa yako fupi kwa wengine."</string>
     <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"soma mkondo wako wa kijamii"</string>
-    <string name="permdesc_readSocialStream" product="default" msgid="3419050808547335320">"Inaruhusu programu kufikia na kulandanisha usasisho kutoka kwako na marafiki zako. Programu mbovu zinaweza kutumia hii kusoma mawasiliano ya kibinafsi kati yako na marafiki zako kwenye mitandao ya kijamii."</string>
+    <string name="permdesc_readSocialStream" product="default" msgid="3419050808547335320">"Inaruhusu programu kufikia na kulandanisha sasisho za kijamii kutoka kwako na marafiki zako. Programu hasidi zinaweza kutumia hii kusoma mawasiliano ya kibinafsi kati yako na marafiki zako kwenye mitandao ya kijamii."</string>
     <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"andika kwa mkondo wako wa kijamii"</string>
-    <string name="permdesc_writeSocialStream" product="default" msgid="3496277176955721451">"Inaruhusu programu kuonyesha usasisho wa kijamii kutoka kwa marafiki zako. Programu mbovu zinaweza kutumia hii kujifanya kuwa rafiki na kukuhadaa kuonyesha nywila au taarifa zingine za siri."</string>
+    <string name="permdesc_writeSocialStream" product="default" msgid="3496277176955721451">"Inaruhusu programu kuonyesha sasisho za kijamii kutoka kwa marafiki zako. Programu hasidi zinaweza kutumia hii kujifanya kuwa rafiki na kukuhadaa kuonyesha nenosiri au taarifa zingine za siri."</string>
     <string name="permlab_readCalendar" msgid="5972727560257612398">"soma matukio ya kalenda pamoja na maelezo ya siri"</string>
-    <string name="permdesc_readCalendar" product="tablet" msgid="2338414551004122687">"Inaruhusu programu kusoma matukio yote ya kalenda yaliyohifadhiwa kwa kompyuta yako ndogo pamoja na za marafiki au wafanyakazi. Programu mbovu zinaweza kutoa maelezo ya kibinafsi kutoka kwa kalenda hizi bila wamiliki kujua."</string>
-    <string name="permdesc_readCalendar" product="default" msgid="5693933067751827753">"Inaruhusu programu kusoma matukio yote ya kalenda yaliyohifadhiwa kwa simu yako go pamoja na za marafiki au wafanyakazi. Programu mbovu zinaweza kutoa maelezo ya kibinafsi kutoka kwa kalenda hizi bila wamiliki kujua."</string>
+    <string name="permdesc_readCalendar" product="tablet" msgid="2338414551004122687">"Inaruhusu programu kusoma matukio yote ya kalenda yaliyohifadhiwa kwa kompyuta yako kibao pamoja na za marafiki au wafanyakazi wenzako. Programu hasidi zinaweza kutoa maelezo ya kibinafsi kutoka kwa kalenda hizi bila wamiliki kujua."</string>
+    <string name="permdesc_readCalendar" product="default" msgid="5693933067751827753">"Inaruhusu programu kusoma matukio yote ya kalenda yaliyohifadhiwa kwa simu yako, ikiwa ni pamoja na yale ya marafiki au wafanyakazi wenzako. Programu hasidi zinaweza kutoa maelezo ya kibinafsi kutoka kwa kalenda hizi bila wamiliki kujua."</string>
     <string name="permlab_writeCalendar" msgid="8438874755193825647">"ongeza au rekebisha matukio ya kalenda na utume barua pepe kwa wageni bila ufahamu wa mmiliki"</string>
-    <string name="permdesc_writeCalendar" msgid="2243771395254848873">"Inaruhusu programu kutuma mialiko ya tukio kama mmiliki wa kalenda na kuongeza, kutoa, kubadilisha matukio unayoweza kurekebisha na kifaa chako, ikiwa ni pamoja na wale wa marafiki au wafanyakazi. Programu mbovu zinaweza tuma barua pepe taka amboza zinaweza kuonekana kutoka wamiliki wa kalenda, kurekebisha matukio bila wamiliki\' kujua, au kuongeza matukio bandia."</string>
+    <string name="permdesc_writeCalendar" msgid="2243771395254848873">"Inaruhusu programu kutuma mialiko ya tukio kama mmiliki wa kalenda na kuongeza, kutoa, kubadilisha matukio unayoweza kurekebisha kwenye kifaa chako, ikiwa ni pamoja na yale ya marafiki au wafanyakazi wenzako. Programu hasidi zinaweza tuma barua pepe taka amboza zinaweza kuonekana kutoka kwa wamiliki kalenda, kurekebisha matukio bila wamiliki kujua, au kuongeza matukio bandia."</string>
     <string name="permlab_accessMockLocation" msgid="8688334974036823330">"vyanzo vya jaribio la mahali kwa lengo la majaribio"</string>
-    <string name="permdesc_accessMockLocation" msgid="7577931556422993949">"Inaruhusu programu kuunda eneo baandia ya jaribio. Programu mbovu zinaweza tumia hii kupuuza eneo na/au hali iliyorejeshwa na vyanzo halisi vya eneo kama vile  GPS au wahudumu wa Mtandao."</string>
+    <string name="permdesc_accessMockLocation" msgid="7577931556422993949">"Inaruhusu programu kuunda eneo baandia ya jaribio. Programu hasidi zinaweza tumia hii kupuuza eneo na/au hali iliyorejeshwa na vyanzo halisi vya eneo kama vile  GPS au wahudumu wa Mtandao."</string>
     <string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"fikia amri za ziada za mtoa huduma ya mahali"</string>
-    <string name="permdesc_accessLocationExtraCommands" msgid="6737736970602176133">"Inaruhusu programu kupata amri za ziada za mtoa eneo. Programu mbovu zinaweza kutumia kuingilia kati uendeshaji wa GPS au vyanzo vingine eneo."</string>
+    <string name="permdesc_accessLocationExtraCommands" msgid="6737736970602176133">"Inaruhusu programu kupata amri za ziada za mtoa eneo. Programu hasidi zinaweza kutumia hii kuingilia kati uendeshaji wa GPS au vyanzo vingine eneo."</string>
     <string name="permlab_installLocationProvider" msgid="6578101199825193873">"kibali ili kusakinisha mtoa huduma ya mahali"</string>
-    <string name="permdesc_installLocationProvider" msgid="1742577679350078373">"Unda vyanzo vya mahali vya kuiga vya kufanya majaribio. Programu hasidi zinaweza kutumia hii kupuuza eneo na au hali iliyorejeshwa na vyanzo halisi vya eneo kama vile watoa huduma za GPS au Mtandao au kufuatilia na kuripoti eneo lako chanzo cha nje."</string>
+    <string name="permdesc_installLocationProvider" msgid="1742577679350078373">"Unda vyanzo vya mahali vya kuiga vya kufanya majaribio. Programu hasidi zinaweza kutumia hii kupuuza eneo na/au hali iliyorejeshwa na vyanzo halisi vya eneo kama vile watoa huduma za GPS au Mtandao au kufuatilia na kuripoti eneo lako kwa chanzo cha nje."</string>
     <string name="permlab_accessFineLocation" msgid="8116127007541369477">"mahali laini (GPS)"</string>
-    <string name="permdesc_accessFineLocation" product="tablet" msgid="5326423948268164934">"Fikia eneo bora vya mahali kama vile Global Positioning System kwenye kompyuta ndogo, mahali popote inapopatikana. Programu mbovu zinaweza kutumia hii ili kubainisha mahali ulipo, na huenda ikatumia nguvu zaidi ya betri."</string>
-    <string name="permdesc_accessFineLocation" product="default" msgid="7130267914433890869">"Fikia eneo bora vya mahali kama vile Global Positioning System kwenye simu, mahali popote inapopatikana. Programu mbovu zinaweza kutumia hii ili kubainisha mahali ulipo, na huenda ikatumia nguvu zaidi ya betri."</string>
+    <string name="permdesc_accessFineLocation" product="tablet" msgid="5326423948268164934">"Fikia vyanzo vya eneo bora kama vile Global Positioning System kwenye kompyuta kibao, mahali popote inapopatikana. Programu hasidi zinaweza kutumia hii ili kubainisha mahali ulipo, na huenda ikatumia nguvu zaidi ya betri."</string>
+    <string name="permdesc_accessFineLocation" product="default" msgid="7130267914433890869">"Fikia vyanzo vya eneo bora kama vile Global Positioning System kwenye simu, mahali popote inapopatikana. Programu hasidi zinaweza kutumia hii ili kubainisha mahali ulipo, na huenda ikatumia nguvu zaidi ya betri."</string>
     <string name="permlab_accessCoarseLocation" msgid="4642255009181975828">"mahali kwa kutegemea mtandao) pasipo shwari"</string>
-    <string name="permdesc_accessCoarseLocation" product="tablet" msgid="5460726396318105483">"Fikia vyanzo vya eneo kama vile hifadhidata ya mtandao wa simu za mkononi ili kubainisha mahali pa kompyuta ndogo palipo karibu, kama pana patikana. Programu mbovu zinaweza kutumia hii ili kubainisha mahali ulipo pa karibu."</string>
-    <string name="permdesc_accessCoarseLocation" product="default" msgid="8900795778057579522">"Fikia vyanzo vya eneo kama vile hifadhidata ya mtandao wa simu za mkononi ili kubainisha mahali pa simu palipo karibu, kama pana patikana. Programu mbovu zinaweza kutumia hii ili kubainisha mahali ulipo pa karibu."</string>
+    <string name="permdesc_accessCoarseLocation" product="tablet" msgid="5460726396318105483">"Fikia vyanzo vya eneo kama vile hifadhidata ya mtandao wa simu za mkononi ili kubainisha umbali wa mahali penye kompyuta kibao, kama inapatikana. Programu hasidi zinaweza kutumia hii ili kubainisha takriban mahali ulipo."</string>
+    <string name="permdesc_accessCoarseLocation" product="default" msgid="8900795778057579522">"Fikia vyanzo vya eneo kama vile hifadhidata ya mtandao wa simu za mkononi ili kubainisha mahali pa simu palipo karibu, kama pana patikana. Programu hasidi zinaweza kutumia hii ili kubainisha takriban umbali wa mahali ulipo."</string>
     <string name="permlab_accessSurfaceFlinger" msgid="2363969641792388947">"fikia SurfaceFlinger"</string>
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Inaruhusu programu kutumia vipengee vya kiwango cha chini vya SurfaceFlinger."</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"soma bafa ya fremu"</string>
@@ -358,16 +360,16 @@
     <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"badilisha mipangilio yako ya sauti"</string>
     <string name="permdesc_modifyAudioSettings" msgid="7343951185408396919">"Inaruhusu programu kurekebisha mipangilio ya jumla ya sauti kama vile sauti na kipanga njia."</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"rekodi sauti"</string>
-    <string name="permdesc_recordAudio" msgid="2387462233976248635">"Inaruhusu programu kufikia njia ya sauti ya rekodi."</string>
+    <string name="permdesc_recordAudio" msgid="2387462233976248635">"Inaruhusu programu kufikia njia ya rekodi ya sauti."</string>
     <string name="permlab_camera" msgid="3616391919559751192">"chukua picha na video"</string>
     <string name="permdesc_camera" msgid="1507407407002492176">"Inaruhusu programu kuchukua picha na video kwa kamera. Hii inaruhusu programu kukusanya picha ambazo kamera inaona wakati wowote."</string>
     <string name="permlab_brick" product="tablet" msgid="2961292205764488304">"lemaza kompyuta ndogo kabisa"</string>
     <string name="permlab_brick" product="default" msgid="8337817093326370537">"simu iliyolemazwa kabisa"</string>
-    <string name="permdesc_brick" product="tablet" msgid="4334818808001699530">"Inaruhusu programu kulemaza kompyuta yote ndogo kabisa. Hii ni hatari sana."</string>
+    <string name="permdesc_brick" product="tablet" msgid="4334818808001699530">"Inaruhusu programu kulemaza kompyuta yote kibao kabisa. Hii ni hatari sana."</string>
     <string name="permdesc_brick" product="default" msgid="5788903297627283099">"Inaruhusu programu kulemaza simu yote kabisa. Hii ni hatari sana."</string>
     <string name="permlab_reboot" product="tablet" msgid="3436634972561795002">"lazimisha kompyuta ndogo kuwaka upya"</string>
     <string name="permlab_reboot" product="default" msgid="2898560872462638242">"lazimisha kwasha upya simu"</string>
-    <string name="permdesc_reboot" product="tablet" msgid="8172056180063700741">"Inaruhusu programu kulazimisha kompyuta ndogo kuwashwa upya."</string>
+    <string name="permdesc_reboot" product="tablet" msgid="8172056180063700741">"Inaruhusu programu kulazimisha kompyuta kibao kuwashwa upya."</string>
     <string name="permdesc_reboot" product="default" msgid="5326008124289989969">"Inaruhusu programu kulazimisha simu kujiwasha upya."</string>
     <string name="permlab_mount_unmount_filesystems" msgid="1761023272170956541">"weka na ondoa mifumo ya faili"</string>
     <string name="permdesc_mount_unmount_filesystems" msgid="1829290701658992347">"Inaruhusu programu kupachika au kupachua mifumo ya faili ya hifadhi inayoweza kutolewa."</string>
@@ -379,8 +381,8 @@
     <string name="permdesc_asec_create" msgid="4558869273585856876">"Inaruhusu programu kuunda hifadhi ya mfumo."</string>
     <string name="permlab_asec_destroy" msgid="526928328301618022">"haribu hifadhi ya ndani"</string>
     <string name="permdesc_asec_destroy" msgid="7218749286145526537">"Inaruhusu programu kuharibu hifadhi ya ndani."</string>
-    <string name="permlab_asec_mount_unmount" msgid="8877998101944999386">"Pachika/ondoa hifadhi ya ndani"</string>
-    <string name="permdesc_asec_mount_unmount" msgid="3451360114902490929">"Inaruhusu programu kupachika/kutoa hifadhi ya ndani."</string>
+    <string name="permlab_asec_mount_unmount" msgid="8877998101944999386">"Pachika/pachua hifadhi ya ndani"</string>
+    <string name="permdesc_asec_mount_unmount" msgid="3451360114902490929">"Inaruhusu programu kupachika/kupachua hifadhi ya ndani."</string>
     <string name="permlab_asec_rename" msgid="7496633954080472417">"ipe hifadhi ya ndani jina jipya"</string>
     <string name="permdesc_asec_rename" msgid="1794757588472127675">"Inaruhusu programu kubadilisha jina la hifadhi ya ndani."</string>
     <string name="permlab_vibrate" msgid="7768356019980849603">"dhibiti kitingishi"</string>
@@ -388,60 +390,60 @@
     <string name="permlab_flashlight" msgid="2155920810121984215">"dhibiti tochi"</string>
     <string name="permdesc_flashlight" msgid="6522284794568368310">"Inaruhusu programu kudhibiti tochi."</string>
     <string name="permlab_manageUsb" msgid="1113453430645402723">"dhibiti mapendekezo na vibali vya vifaa vya USB"</string>
-    <string name="permdesc_manageUsb" msgid="7776155430218239833">"Inaruhusu programu kudhibiti mapendekezo na idhini ya vifaa vya USB."</string>
+    <string name="permdesc_manageUsb" msgid="7776155430218239833">"Inaruhusu programu kudhibiti mapendekezo na idhini za vifaa vya USB."</string>
     <string name="permlab_accessMtp" msgid="4953468676795917042">"tekeleza itifaki ya MTP"</string>
     <string name="permdesc_accessMtp" msgid="6532961200486791570">"Huruhusu ufikiaji wa kiendeshaji cha kernel MTP ili kutekeleza itifaki ya USB ya MTP."</string>
     <string name="permlab_hardware_test" msgid="4148290860400659146">"jaribu maunzi"</string>
-    <string name="permdesc_hardware_test" msgid="6597964191208016605">"Inaruhusu programu kudhibiti vifaa mbalimbali kwa lengo la kujaribu maunzi."</string>
+    <string name="permdesc_hardware_test" msgid="6597964191208016605">"Inaruhusu programu kudhibiti vifaa mbalimbali kwa lengo la kujaribia maunzi."</string>
     <string name="permlab_callPhone" msgid="3925836347681847954">"piga simu moja kwa moja kwa nambari za simu"</string>
-    <string name="permdesc_callPhone" msgid="6396463004110544744">"Inaruhusu programu kupiga namba za simu bila wewe kuingilia. Programu mbovu zinaweza kusababisha kupiga simu zisizotarajiwa kwa bili yako ya simu. Kumbuka ya kuwa hii hairuhusu programu kupiga namba za dharura."</string>
+    <string name="permdesc_callPhone" msgid="6396463004110544744">"Inaruhusu programu kupiga namba za simu bila wewe kuingilia. Programu hasidi zinaweza kusababisha kupiga simu zisizotarajiwa kwa bili yako ya simu. Kumbuka ya kuwa hii hairuhusu programu kupiga namba za dharura."</string>
     <string name="permlab_callPrivileged" msgid="4198349211108497879">"piga simu moja kwa moja kwa nambari zozote za simu"</string>
     <string name="permdesc_callPrivileged" msgid="1689024901509996810">"Inaruhusu programu kupiga namba yoyote ya simu, ikiwa ni pamoja na namba za dharura, bila wewe kuingilia kati.Programu hasidi zinaweza piga simu zisizo za lazima na haramu kwa huduma za dharura."</string>
     <string name="permlab_performCdmaProvisioning" product="tablet" msgid="4842576994144604821">"anzisha usanidi wa kompyuta ndogo ya CDMA moja kwa moja"</string>
     <string name="permlab_performCdmaProvisioning" product="default" msgid="5604848095315421425">"anzisha moja kwa moja usanidi wa simu ya CDMA"</string>
-    <string name="permdesc_performCdmaProvisioning" msgid="1994193538802314186">"Inaruhusu programu kuanza ugawaji wa CDMA. Programu hasidi zinaweza anza ugawaji wa CDMA usiokuwa wa lazima."</string>
+    <string name="permdesc_performCdmaProvisioning" msgid="1994193538802314186">"Inaruhusu programu kuanza ugawaji wa CDMA. Programu hasidi zinaweza anza ugawaji wa CDMA usio wa lazima."</string>
     <string name="permlab_locationUpdates" msgid="7785408253364335740">"dhibiti arifa za usasishaji mahali"</string>
     <string name="permdesc_locationUpdates" msgid="1120741557891438876">"Inaruhusu programu kuwezesha/kulemeza arifa za usasishaji za eneo kutoka kwa redio. Si ya matumizi na programu za kawaida."</string>
     <string name="permlab_checkinProperties" msgid="7855259461268734914">"fikia mipangilio ya ukaguzi"</string>
-    <string name="permdesc_checkinProperties" msgid="4024526968630194128">"Inaruhusu programu kusoma/kuandika kwa mipangilio iliyo pakiwa na huduma ya kuangalia. Si ya matumizi na programu za kawaida."</string>
+    <string name="permdesc_checkinProperties" msgid="4024526968630194128">"Inaruhusu kusoma/kuandika kwa programu kufikia mipangilio iliyopakiwa na huduma ya kuangalia. Si ya matumizi na programu za kawaida."</string>
     <string name="permlab_bindGadget" msgid="776905339015863471">"chagua wijeti"</string>
-    <string name="permdesc_bindGadget" msgid="8261326938599049290">"Inaruhusu programu kuwaambia mfumo wijeti ambazo zinaweza kutumika na programu. Programu ambayo ina ruhusa hii inaweza peana mfiko kwa data binafsi na kwa programu nyingine. Si kwa matumizi na programu za kawaida."</string>
+    <string name="permdesc_bindGadget" msgid="8261326938599049290">"Inaruhusu programu kuwaambia mfumo wijeti ambazo zinaweza kutumika na programu. Programu ambayo ina ruhusa hii inaweza kuruhusu ufikiaji wa data binafsi na kwa programu nyingine. Si ya kutumiwa na programu za kawaida."</string>
     <string name="permlab_modifyPhoneState" msgid="8423923777659292228">"badiliisha hali ya simu"</string>
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Inaruhusu programu kudhibiti vipengee vya kifaa. Programu iliyo na ruhusa hii inaweza badilisha mtandao, kuzima na kuwasha redio ya simu bila hata kukujulisha."</string>
     <string name="permlab_readPhoneState" msgid="2326172951448691631">"soma hali ya simu na itambue"</string>
-    <string name="permdesc_readPhoneState" msgid="5127767618743602782">"Inaruhusu programu kufikia sifa za simu ya kifaa. Programu inayoruhusa hii inaweza kuamua namba ya simu na namba tambulishi ya simu hii, kama simu ni amilifu, namba ya simu hiyo imeuganishwa kwa na kama hivyo."</string>
+    <string name="permdesc_readPhoneState" msgid="5127767618743602782">"Inaruhusu programu kufikia vipengee vya simu vya kifaa. Programu inayo na ruhusa hii inaweza kuamua namba ya simu na namba tambulishi ya simu hii, kama kuna simu inapigwa, namba inayopigiwa simu hiyo na mengine kama hayo."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"zuia kompyuta ndogo dhidi ya kulala"</string>
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"zuia simu dhidi ya kulala"</string>
-    <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Inaruhusu programu kuzuia kompyuta ndogo  kwenda kulala."</string>
+    <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Inaruhusu programu kuzuia kompyuta kibao  kwenda kulala."</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Inaruhusu programu kuzuia simu isiende kulala."</string>
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"Washa au zima kompyuta ndogo"</string>
     <string name="permlab_devicePower" product="default" msgid="4928622470980943206">"washa au zima simu"</string>
-    <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"Inaruhusu programu kuwasha au kuzima kompyuta ndogo."</string>
+    <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"Inaruhusu programu kuwasha au kuzima kompyuta kibao."</string>
     <string name="permdesc_devicePower" product="default" msgid="6037057348463131032">"Inaruhusu programu kuwasha au kuzima simu."</string>
     <string name="permlab_factoryTest" msgid="3715225492696416187">"endesha katika hali ya jaribio ya kiwanda"</string>
     <string name="permdesc_factoryTest" product="tablet" msgid="3952059318359653091">"Endesha kama jaribio la mtengenezaji la kiwango cha chini, kwa hivyo kuruhusu ufikiaji kamili wa maunzi ya kompyuta ndogo. Inapatikana tu wakati kompyuta ndogo inaendeshwa katika hali ya jaribio la mtengenezaji."</string>
     <string name="permdesc_factoryTest" product="default" msgid="8136644990319244802">"Endesha kama jaribio la kiwango cha chini cha mtengenezaji, kwa hivyo kuruhusu ufikiaji kamili wa maunzi ya simu. Inapatikana tu wakati simu inaendeshwa katika gumzo ya jaribio ya mtengenezaji."</string>
-    <string name="permlab_setWallpaper" msgid="6627192333373465143">"weka pazia"</string>
+    <string name="permlab_setWallpaper" msgid="6627192333373465143">"weka mandhari"</string>
     <string name="permdesc_setWallpaper" msgid="7373447920977624745">"Inaruhusu programu kuweka mfumo wa mandhari."</string>
-    <string name="permlab_setWallpaperHints" msgid="3600721069353106851">"weka vidokezo vya ukubwa wa pazia"</string>
+    <string name="permlab_setWallpaperHints" msgid="3600721069353106851">"weka vidokezo vya ukubwa wa mandhari"</string>
     <string name="permdesc_setWallpaperHints" msgid="8235784384223730091">"Inaruhusu programu kuweka vidokezo vya ukubwa wa mandhari ya mfumo."</string>
     <string name="permlab_masterClear" msgid="2315750423139697397">"weka upya mfumo kwa chaguo-msingi za kiwanda"</string>
-    <string name="permdesc_masterClear" msgid="3665380492633910226">"Inaruhusu programu kuweka upya mfumo kwa mipangilio ya kiwanda, inafuta usanidi wa data wote, na programu zilizosanikishwa."</string>
+    <string name="permdesc_masterClear" msgid="3665380492633910226">"Inaruhusu programu kuweka upya kabisa mfumo kwa mipangilio yake ya kiwanda, huku ikifuta data yote, usanidi, na programu zilizosanikishwa."</string>
     <string name="permlab_setTime" msgid="2021614829591775646">"weka muda"</string>
-    <string name="permdesc_setTime" product="tablet" msgid="1896341438151152881">"Inaruhusu programu kubadilisha wakati wa saa ya kompyuta ndogo."</string>
+    <string name="permdesc_setTime" product="tablet" msgid="1896341438151152881">"Inaruhusu programu kubadilisha wakati wa saa ya kompyuta kibao."</string>
     <string name="permdesc_setTime" product="default" msgid="1855702730738020">"Inaruhusu programu kubadilisha wakati wa saa ya simu."</string>
     <string name="permlab_setTimeZone" msgid="2945079801013077340">"weka ukanda wa saa"</string>
-    <string name="permdesc_setTimeZone" product="tablet" msgid="1676983712315827645">"Inaruhusu programu kubadilisha  majira ya saa ya kompyuta ndogo."</string>
-    <string name="permdesc_setTimeZone" product="default" msgid="4499943488436633398">"Inaruhusu programu kubadilisha  majira ya saa ya kompyuta ndogo."</string>
+    <string name="permdesc_setTimeZone" product="tablet" msgid="1676983712315827645">"Inaruhusu programu kubadilisha  majira ya saa ya kompyuta kibao."</string>
+    <string name="permdesc_setTimeZone" product="default" msgid="4499943488436633398">"Inaruhusu programu kubadilisha  majira ya saa ya simu."</string>
     <string name="permlab_accountManagerService" msgid="4829262349691386986">"tenda kama Huduma ya Meneja wa Akaunti"</string>
     <string name="permdesc_accountManagerService" msgid="2684502137670299915">"Inaruhusu programu kupiga simu kwa Wathibitishaji Akaunti"</string>
     <string name="permlab_getAccounts" msgid="4549918644233460103">"tambua akaunti zinazojulikana"</string>
-    <string name="permdesc_getAccounts" product="tablet" msgid="3238360555257773358">"Inaruhusu programu  kupata orodha ya akaunti zinazojulikana na kompyuta ndogo."</string>
+    <string name="permdesc_getAccounts" product="tablet" msgid="3238360555257773358">"Inaruhusu programu  kupata orodha ya akaunti zinazojulikana na kompyuta kibao."</string>
     <string name="permdesc_getAccounts" product="default" msgid="2735689364629830348">"Inaruhusu programu kupata orodha ya akaunti zinazojulikana na simu."</string>
     <string name="permlab_authenticateAccounts" msgid="3940505577982882450">"tenda kama mhalalishaji"</string>
-    <string name="permdesc_authenticateAccounts" msgid="5472124296908977260">"Inaruhusu programu kutumia uthibitishaji wa akaunti ya  KidhibitiAkaunti, pamoja na kuunda akaunti na kupata na kuweka nywila zao."</string>
+    <string name="permdesc_authenticateAccounts" msgid="5472124296908977260">"Inaruhusu programu kutumia uwezo wa uthibitishaji akaunti wa KidhibitiAkaunti, pamoja na kuunda akaunti na kupata na kuweka nywila zao."</string>
     <string name="permlab_manageAccounts" msgid="4440380488312204365">"simamia orodha ya akaunti"</string>
-    <string name="permdesc_manageAccounts" msgid="8698295625488292506">"Inaruhusu programu kutekeleza shughuli kama vile kuongeza, na kutoa akaunti na kufuta nywila zao."</string>
+    <string name="permdesc_manageAccounts" msgid="8698295625488292506">"Inaruhusu programu kutekeleza shughuli kama vile kuongeza na kutoa akaunti, na kufuta manenosiri yazo."</string>
     <string name="permlab_useCredentials" msgid="6401886092818819856">"tumia hati-tambulishi za uhalalishaji akaunti"</string>
     <string name="permdesc_useCredentials" msgid="7984227147403346422">"Inaruhusu programu kuomba shuhuda za uthibitisho."</string>
     <string name="permlab_accessNetworkState" msgid="6865575199464405769">"angalia hali ya mtandao"</string>
@@ -449,68 +451,68 @@
     <string name="permlab_createNetworkSockets" msgid="9121633680349549585">"ufikiaji kamili wa mtandao"</string>
     <string name="permdesc_createNetworkSockets" msgid="5963922297444265950">"Inaruhusu programu kuunda soketi za mtandao."</string>
     <string name="permlab_writeApnSettings" msgid="505660159675751896">"mabadiliko / kuingilia mipangilio ya mtandao/msonmgamano"</string>
-    <string name="permdesc_writeApnSettings" msgid="5333798886412714193">"Inaruhusu programu kubadilisha mipangilio ya mtandao na kukatiza na kukagua wendaji wa mtandao, kwa mfano kwa kubadilisha kituo tarishi na mbadala wa APN wowote. Programu mbovu zinaweza kuangalia, kuelekeza, au kurekebisha furushi za mtandao bila ya wewe kujua."</string>
+    <string name="permdesc_writeApnSettings" msgid="5333798886412714193">"Inaruhusu programu kubadilisha mipangilio ya mtandao na kukatiza na kukagua uendaji wa mtandao, kwa mfano kubadilisha kituo tarishi na mbadala cha APN yoyote. Programu hasidi zinaweza kuangalia, kuelekeza kwingine, au kurekebisha furushi za mtandao bila ya wewe kujua."</string>
     <string name="permlab_changeNetworkState" msgid="958884291454327309">"badilisha muunganisho wa mtandao"</string>
     <string name="permdesc_changeNetworkState" msgid="6789123912476416214">"Inaruhusu programu kubadilisha hali ya muunganisho wa mtandao."</string>
-    <string name="permlab_changeTetherState" msgid="5952584964373017960">"Badilisha muunganisho uliofungwa"</string>
+    <string name="permlab_changeTetherState" msgid="5952584964373017960">"Badilisha muunganisho uliofunganishwa"</string>
     <string name="permdesc_changeTetherState" msgid="1524441344412319780">"Inaruhusu programu kubadilisha hali ya muunganisho wa mtandao uliofungwa."</string>
     <string name="permlab_changeBackgroundDataSetting" msgid="1400666012671648741">"badilisha mpangilio wa utumiaji data ya mandharinyuma"</string>
-    <string name="permdesc_changeBackgroundDataSetting" msgid="5347729578468744379">"Inaruhusu programu kubadilisha mpangilio wa matumizi ya data ya nyuma."</string>
+    <string name="permdesc_changeBackgroundDataSetting" msgid="5347729578468744379">"Inaruhusu programu kubadilisha mpangilio wa matumizi ya data ya usuli."</string>
     <string name="permlab_accessWifiState" msgid="8100926650211034400">"ona hali ya mtandao-hewa"</string>
     <string name="permdesc_accessWifiState" msgid="7770452658226256831">"Inaruhusu programu kuona taarifa kuhusu hali ya Wi-Fi."</string>
     <string name="permlab_changeWifiState" msgid="7280632711057112137">"badilisha hali ya Wi-Fi"</string>
     <string name="permdesc_changeWifiState" msgid="7399961004537946240">"Inaruhusu programu kuunganisha na kutenganisha kutoka kwa pointi za ufikivu za Wi-Fi, na kufanya mabadiliko kwa mitandao ya Wi-Fi iliyosanidiwa."</string>
     <string name="permlab_changeWifiMulticastState" msgid="1368253871483254784">"ruhusu upokeaji wa Wi-Fi Multicast"</string>
-    <string name="permdesc_changeWifiMulticastState" msgid="7633598524564320817">"Inaruhusu programu kupata furushi amabazo hazijaelekezwa kwa kifaa chako. Hii inaweza kuwa muhimu wakati wa kutambua huduma zinazotolewa karibu na eneo hilo. Inatumia nguvu zaidi kuliko mtindo wa kutupa mbali mbali.."</string>
+    <string name="permdesc_changeWifiMulticastState" msgid="7633598524564320817">"Inaruhusu programu kupata furushi amabazo hazijaelekezwa moja kwa moja kwa kifaa chako. Hii inaweza kuwa muhimu wakati wa kutambua huduma zinazotolewa karibu na eneo hilo. Inatumia nguvu zaidi kuliko mtindo wa kutupa mbali mbali.."</string>
     <string name="permlab_bluetoothAdmin" msgid="3606576270792236062">"Usimamizi wa bluetooth"</string>
-    <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"Inaruhusu programu kusanidi kompyuta ndogo ya Bluetooth na kutambua na kuoanisha na vidhibiti vya mbali."</string>
-    <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"Inaruhusu programu kusanidi simu ya ndani ya Bluetooth, na kutambua na kuoanisha na vifaa vya mbali."</string>
-    <!-- outdated translation 2800410363171809280 -->     <string name="permlab_accessWimaxState" msgid="1232061307208861588">"Tazama hali ya wiMAX"</string>
+    <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"Inaruhusu programu kusanidi kompyuta kibao ya karibu ya Bluetooth na kutambua na kuoanisha na vifaa vya kudhibiti."</string>
+    <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"Inaruhusu programu kusanidi simu ya karibu ya Bluetooth, na kutambua na kuoanisha na vifaa vya mbali."</string>
+    <string name="permlab_accessWimaxState" msgid="1232061307208861588">"Ona hali ya WiMAX"</string>
     <string name="permdesc_accessWimaxState" msgid="8298035866227524023">"Huruhusu programu kuangalia maelezo kuhusu hali ya WiMAX."</string>
-    <!-- outdated translation 340465839241528618 -->     <string name="permlab_changeWimaxState" msgid="2405042267131496579">"badilisha hali ya WiMAX"</string>
+    <string name="permlab_changeWimaxState" msgid="2405042267131496579">"Badilisha hali ya WiMAX"</string>
     <string name="permdesc_changeWimaxState" msgid="474918005058989421">"Huruhusu programu kuunganisha kwa na kukata muunganisho kutoka mtandao wa WiMAX."</string>
     <string name="permlab_bluetooth" msgid="8361038707857018732">"unda muunganisho wa Bluetooth"</string>
-    <string name="permdesc_bluetooth" product="tablet" msgid="7007851048416363446">"Inaruhusu programu kuona usanidi wa kompyuta ndogo ya karibu ya Bluetooth, na kuwezesha na kukubali muunganisho na vifaa vilivyolinganishwa."</string>
-    <string name="permdesc_bluetooth" product="default" msgid="31846362767164948">"Inaruhusu programu kuangalia usanidi wa simu ya ndani ya Bluetooth, na kufanya na kukubali muunganisho na vifaa vilivyolinganishwa."</string>
+    <string name="permdesc_bluetooth" product="tablet" msgid="7007851048416363446">"Inaruhusu programu kuona usanidi wa kompyuta kibao ya karibu ya Bluetooth, na kuwezesha na kukubali muunganisho na vifaa vilivyo oanishwa."</string>
+    <string name="permdesc_bluetooth" product="default" msgid="31846362767164948">"Inaruhusu programu kuangalia usanidi wa simu ya karibu ya Bluetooth, na kufanya na kukubali miunganisho na vifaa vilivyolinganishwa."</string>
     <string name="permlab_nfc" msgid="4423351274757876953">"dhibiti Mawasiliano Karibu na Uga"</string>
-    <string name="permdesc_nfc" msgid="7120611819401789907">"Inaruhusu programu kuwasiliana na lebo za Near Field Communication (NFC), kadi, na wasomaji."</string>
+    <string name="permdesc_nfc" msgid="7120611819401789907">"Inaruhusu programu kuwasiliana na lebo, kadi na wasomaji wa Near Field Communication (NFC)."</string>
     <string name="permlab_disableKeyguard" msgid="4977406164311535092">"lemaza ufunguo wa vitufe"</string>
-    <string name="permdesc_disableKeyguard" msgid="6231611286892232626">"Inaruhusu programu kulemaza kifunga kitufe na usalama wowote unaohusishwa na nywila. Mfano halisi wa hii ni simu kulemaza kifunga kitufe wakati wa kupokea simu inayoingia, kisha kuwezesha kifunga kitufe upya simu inapomalizika."</string>
+    <string name="permdesc_disableKeyguard" msgid="6231611286892232626">"Inaruhusu programu kulemaza kifunga kitufe na usalama wowote unaohusishwa na nenosiri. Mfano halisi wa hii ni simu kulemaza kifunga kitufe wakati wa kupokea simu inayoingia, kisha kuwezesha upya kifunga kitufe simu inapomalizika."</string>
     <string name="permlab_readSyncSettings" msgid="6201810008230503052">"soma mipangilio ya usawazishaji"</string>
-    <string name="permdesc_readSyncSettings" msgid="5464056785274229278">"Inaruhusu programu kurekebisha mipangilio ya ulandanishi, kama vile ulandanishi imewezeshwa kwa programu ya People."</string>
+    <string name="permdesc_readSyncSettings" msgid="5464056785274229278">"Inaruhusu programu kusoma mipangilio ya ulandanishi, kama vile ikiwa ulandanishi imewezeshwa kwa programu ya Watu."</string>
     <string name="permlab_writeSyncSettings" msgid="6297138566442486462">"andika mipangilio ya usawazishaji"</string>
-    <string name="permdesc_writeSyncSettings" msgid="1466056564502117130">"Inaruhusu programu kurekebisha mipangilio ya ulandanishi, kama vile ulandanishi umewezeshwa kwa programu ya Watu."</string>
+    <string name="permdesc_writeSyncSettings" msgid="1466056564502117130">"Inaruhusu programu kurekebisha mipangilio ya ulandanishi, kama vile ikiwa ulandanishi umewezeshwa kwa programu ya Watu."</string>
     <string name="permlab_readSyncStats" msgid="7396577451360202448">"soma takwimu za usawazishaji"</string>
     <string name="permdesc_readSyncStats" msgid="3801971839939951678">"Inaruhu programu kusoma takwimu zilizolandanishwa; k.v., historia ya ulandanishi ambao umetokea."</string>
     <string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"soma milisho ya kujiunga"</string>
-    <string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Inaruhusu programu kupata maelezo kuhusu mlisho sasa synced."</string>
+    <string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Inaruhusu programu kupata maelezo kuhusu mlisho iliyolandanishwa kwa sasa."</string>
     <string name="permlab_subscribedFeedsWrite" msgid="9015246325408209296">"andika milisho ya kujiunga"</string>
-    <string name="permdesc_subscribedFeedsWrite" msgid="6928930188826089413">"Inaruhusu programu kurekebisha lishe zako zilizolandanishwa kwa sasa. Programu mbovu zinaweza kubadilisha lishe zako zilizolandanishwa."</string>
+    <string name="permdesc_subscribedFeedsWrite" msgid="6928930188826089413">"Inaruhusu programu kurekebisha milisho yako iliyolandanishwa kwa sasa. Programu hasidi zinaweza kubadilisha milisho yako iliyolandanishwa."</string>
     <string name="permlab_readDictionary" msgid="8410247960433376352">"soma kamusi iliyobainishwa na mtumiaji"</string>
     <string name="permdesc_readDictionary" msgid="8977815988329283705">"Inaruhusu programu kusoma maneno, majina na vifungu vyovyote vya kibinafsi, ambavyo huenda mtumiaji amehifadhi katika kamusi ya mtumiaji."</string>
     <string name="permlab_writeDictionary" msgid="2296383164914812772">"andika kwa kamusi iliyobainishwa na mtumiaji"</string>
     <string name="permdesc_writeDictionary" msgid="8185385716255065291">"Inaruhusu programu kuandika maneno mapya katika kamusi ya mtumiaji."</string>
     <string name="permlab_sdcardWrite" product="nosdcard" msgid="85430876310764752">"rekebisha/futa maudhui ya hifadhi ya USB"</string>
     <string name="permlab_sdcardWrite" product="default" msgid="8079403759001777291">"rekebisha/futa maudhui ya kadi ya SD"</string>
-    <string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"Inaruhusu programu kuandika kwa hifadhi ya USB."</string>
-    <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Inaruhusu programu kuandika kwa kadi ya SD."</string>
+    <string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"Inaruhusu programu kuandikia hifadhi ya USB."</string>
+    <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Inaruhusu programu kuandikia kadi ya SD."</string>
     <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"badilisha/futa maudhui ya hifadhi ya media ya ndani."</string>
     <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Inaruhusu programu kurekebisha maudhui ya hifadhi ya ndani vyombo vya habari."</string>
     <string name="permlab_cache_filesystem" msgid="5656487264819669824">"fikia faili za mfumo za kache"</string>
-    <string name="permdesc_cache_filesystem" msgid="5578967642265550955">"Inruhusu programu kusoma na kuandika mfumo wa faili wa kache."</string>
+    <string name="permdesc_cache_filesystem" msgid="5578967642265550955">"Inaruhusu programu kusoma na kuandika mfumo wa faili wa kache."</string>
     <string name="permlab_use_sip" msgid="5986952362795870502">"piga/pokea simu za mtandao"</string>
-    <string name="permdesc_use_sip" msgid="4717632000062674294">"Inaruhusu programu kutumia huduma ya SIP kupiga/kupokea simu ya mtandao."</string>
+    <string name="permdesc_use_sip" msgid="4717632000062674294">"Inaruhusu programu kutumia huduma ya SIP kupiga/kupokea simu za mtandao."</string>
     <string name="permlab_readNetworkUsageHistory" msgid="7862593283611493232">"soma matumizi ya historia ya mtandao"</string>
-    <string name="permdesc_readNetworkUsageHistory" msgid="7689060749819126472">"Inaruhusu programu kusoma historia ya matumizi wa mtandao kwa mitandao maalum na programu."</string>
+    <string name="permdesc_readNetworkUsageHistory" msgid="7689060749819126472">"Inaruhusu programu kusoma historia ya matumizi ya mtandao kwa mitandao maalum na programu."</string>
     <string name="permlab_manageNetworkPolicy" msgid="2562053592339859990">"dhibiti sera ya mtandao"</string>
     <string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"Inaruhusu programu kudhibiti sera za mtandao na kufafanua sheria maalum za programu."</string>
     <string name="permlab_modifyNetworkAccounting" msgid="5088217309088729650">"badilisha uthibitishaji wa matumizi ya mtandao"</string>
-    <string name="permdesc_modifyNetworkAccounting" msgid="8553240749784321765">"Inaruhusu programu  kurekebisha jinsi ya matumizi ya mtandao yana hesabika dhidi ya programu. Si ya matumizi na programu za kawaida."</string>
+    <string name="permdesc_modifyNetworkAccounting" msgid="8553240749784321765">"Inaruhusu programu kurekebisha jinsi ya matumizi ya mtandao yana hesabika dhidi ya programu. Si ya matumizi na programu za kawaida."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Weka kanuni za nenosiri"</string>
     <string name="policydesc_limitPassword" msgid="9083400080861728056">"Dhibiti urefu na vibambo vilivyoruhusiwa kwenye manenosiri ya kufungua skrini"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Chunguza majaribio ya kutofun gua skrini"</string>
-    <string name="policydesc_watchLogin" product="tablet" msgid="3215729294215070072">"Fuatilia idadi ya nywila zisizo sahihi zilizo ingizwa wakati  wakufungua skrini, na ufunge kompyuta ndogo au futa data yote ya kompyuta ndogo kama nywila nyingi zenye makosa zimeingizwa."</string>
-    <string name="policydesc_watchLogin" product="default" msgid="5712323091846761073">"Fuatilia idadi ya nywila sahihi zilizochapishwa. Unapofungua skrini, funga simu au futa data yote ya simu kama nywila sahihi zimechapishwa."</string>
+    <string name="policydesc_watchLogin" product="tablet" msgid="3215729294215070072">"Fuatilia idadi ya manenosiri yasiyo sahihi yaliyoingizwa wakati wa wakufungua skrini, na ufunge kompyuta kibao au ufute data yote ya kompyuta kibao kama manenosiri mengi yenye makosa yameingizwa."</string>
+    <string name="policydesc_watchLogin" product="default" msgid="5712323091846761073">"Fuatilia idadi ya manenosiri yasiyo sahihi yaliyoingizwa wakati wa kufungua skrini, na ufunge simu au ufute data yote ya simu kama manenosiri mengi sana yameingizwa."</string>
     <string name="policylab_resetPassword" msgid="2620077191242688955">"Badilisha nenosiri la kufungua skrini"</string>
     <string name="policydesc_resetPassword" msgid="5391240616981297361">"Badilisha nenosiri la kufungua skrini"</string>
     <string name="policylab_forceLock" msgid="2274085384704248431">"Funga skrini"</string>
@@ -639,11 +641,11 @@
     <string name="sipAddressTypeHome" msgid="6093598181069359295">"Nyumbani"</string>
     <string name="sipAddressTypeWork" msgid="6920725730797099047">"Kazi"</string>
     <string name="sipAddressTypeOther" msgid="4408436162950119849">"Nyinginezo"</string>
-    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Aina ya msimbo wa PIN"</string>
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Ingiza msimbo wa PIN"</string>
     <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Ingiza PUK na msimbo mpya wa PIN"</string>
     <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"Msimbo wa PUK"</string>
     <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Msimbo mpya wa PIN"</string>
-    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Gusa kuweka nywila "</font></string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Gusa kuingiza nenosiri "</font></string>
     <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Charaza nenosiri ili kufungua"</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Ingiza PIN ili kufungua"</string>
     <string name="keyguard_password_wrong_pin_code" msgid="1295984114338107718">"Msimbo wa PIN sio sahihi!"</string>
@@ -663,11 +665,11 @@
     <string name="lockscreen_charged" msgid="4938930459620989972">"Imechajiwa."</string>
     <string name="lockscreen_battery_short" msgid="3617549178603354656">"Kishika nafasi<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 kadi ya SIM."</string>
-    <string name="lockscreen_missing_sim_message" product="tablet" msgid="151659196095791474">"Hakuna kadi ya SIM katika kompyuta ndogo."</string>
-    <string name="lockscreen_missing_sim_message" product="default" msgid="2186920585695169078">"Hakuna kadi ya SIM kwenye simu."</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>
+    <string name="lockscreen_missing_sim_message" product="default" msgid="2186920585695169078">"Hakuna SIM kadi kwenye simu."</string>
     <string name="lockscreen_missing_sim_instructions" msgid="5372787138023272615">"Ingiza SIM kadi."</string>
-    <string name="lockscreen_missing_sim_instructions_long" msgid="3526573099019319472">"Kadi ya SIM haiko au haisomeki. Tafadhali ingiza kadi ya SIM."</string>
+    <string name="lockscreen_missing_sim_instructions_long" msgid="3526573099019319472">"Kadi ya SIM haiko au haisomeki. Tafadhali ingiza SIM kadi."</string>
     <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"SIM kadi yako imelemezwa kabisa."\n" Wasiliana na mtoa huduma wako wa pasi waya ili upate SIM kadi nyingine."</string>
     <string name="lockscreen_transport_prev_description" msgid="201594905152746886">"Kitufe cha awali cha wimbo"</string>
     <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Kitufe cha wimbo unaofuata"</string>
@@ -677,14 +679,14 @@
     <string name="emergency_calls_only" msgid="6733978304386365407">"Simu za dharura pekee"</string>
     <string name="lockscreen_network_locked_message" msgid="143389224986028501">"Mtandao umefungwa"</string>
     <string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"Kadi ya SIM imefungwa na PUK."</string>
-    <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Tafadhali angalia Mwongozo wa Mtumiaji au wasiliana na Huduma ya Wateja."</string>
+    <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Angalia Mwongozo wa Mtumiaji au wasiliana na Huduma ya Wateja."</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"Kadi ya SIM imefungwa."</string>
-    <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"Inafungua kadi ya SIM..."</string>
-    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Umevuta mchoro wako wa kufunga kwa makosa mara <xliff:g id="NUMBER_0">%d</xliff:g>. "\n\n" Jaribu tena kwa sekunde <xliff:g id="NUMBER_1">%d</xliff:g>."</string>
-    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Umeingiza nywila yako kimakosa mara <xliff:g id="NUMBER_0">%d</xliff:g>. "\n\n" Jaribu tena katika sekunde <xliff:g id="NUMBER_1">%d</xliff:g>."</string>
-    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Umeingiza nywila yako kimakosa mara <xliff:g id="NUMBER_0">%d</xliff:g>. "\n\n" Jaribu tena katika sekunde <xliff:g id="NUMBER_1">%d</xliff:g>."</string>
+    <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"Inafungua SIM kadi..."</string>
+    <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Umekosea katika kuchora ruwaza yako ya kufungua mara <xliff:g id="NUMBER_0">%d</xliff:g>. "\n\n" Jaribu tena kwa sekunde <xliff:g id="NUMBER_1">%d</xliff:g>."</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Umekosea mara <xliff:g id="NUMBER_0">%d</xliff:g> katika kuingiza nenosiri lako. "\n\n" Jaribu tena katika sekunde <xliff:g id="NUMBER_1">%d</xliff:g>."</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Umekosea katika kuingiza PIN yako mara <xliff:g id="NUMBER_0">%d</xliff:g>. "\n\n" Jaribu tena katika sekunde <xliff:g id="NUMBER_1">%d</xliff:g>."</string>
     <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Umekosea katika kuweka mchoro wako wa kufungua mara <xliff:g id="NUMBER_0">%d</xliff:g>. Baada ya majaribio <xliff:g id="NUMBER_1">%d</xliff:g> bila kufaulu, utaulizwa kufungua kompyuta yako ndogo kwa kuingia kwa Google."\n\n" Jaribu tena katika sekunde <xliff:g id="NUMBER_2">%d</xliff:g>."</string>
-    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Umeweka mchoro wa kufungua na makosa mara <xliff:g id="NUMBER_0">%d</xliff:g>. Baada ya majaribio <xliff:g id="NUMBER_1">%d</xliff:g> yasiyofaulu, utaulizwa kufungua simu kwa kutumia Google."\n\n" Jaribu tena katika sekunde <xliff:g id="NUMBER_2">%d</xliff:g>."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Umekosea kuchora mchoro wako wa kufungua mara <xliff:g id="NUMBER_0">%d</xliff:g>. Baada ya majaribio <xliff:g id="NUMBER_1">%d</xliff:g> yasiyofaulu, utaulizwa kufungua simu kupitia kuingia Google."\n\n" Jaribu tena katika sekunde <xliff:g id="NUMBER_2">%d</xliff:g>."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Umejaribu kufungua kompyuta ndogo kwa njia isiyo sahihi mara <xliff:g id="NUMBER_0">%d</xliff:g>. Baada ya zaidi ya <xliff:g id="NUMBER_1">%d</xliff:g> majaribio yasiyofanikiwa, kompyuta ndogo itawekwa upya kwa kiwanda chaguo-msingi na data yote ya mtumiaji itapotea."</string>
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Umejaribu kufungua simu kwa njia isiyo sahihi mara <xliff:g id="NUMBER_0">%d</xliff:g>. Baada ya majaribio <xliff:g id="NUMBER_1">%d</xliff:g> zaidi yasiyofanikiwa, simu itawekwa upya kwa kiwanda chaguo-msingi na data yote ya mtumiaji itapotea."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Umejaribu kufungua kompyuta ndogo kwa njia isiyo sahihi mara <xliff:g id="NUMBER">%d</xliff:g>. Kompyuta ndogo haitaweza kuwekwa upya kwa kiwanda chaguo-msingi."</string>
@@ -742,18 +744,18 @@
     <string name="permlab_readHistoryBookmarks" msgid="1284843728203412135">"soma historia na alamisho za Kivinjari"</string>
     <string name="permdesc_readHistoryBookmarks" msgid="4577476392604595921">"Inaruhusu programu kusoma URL zote ambazo Kivinjari kimetembelea, na alamisho zote za Kivinjari."</string>
     <string name="permlab_writeHistoryBookmarks" msgid="9009434109836280374">"andika historia ya Kivinjari na alamisho"</string>
-    <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="1757103804824209530">"Inaruhusu programu kurekebisha historia ya Kivinjari au alamisho zilizohifadhiwa  katika kompyuta yako ndogo. Programu hasidi zinaweza kutumia hii kufuta au kurekebisha data ya Kivinjari chako."</string>
-    <string name="permdesc_writeHistoryBookmarks" product="default" msgid="6693764355720719197">"Inaruhusu programu kurekebisha historia ya kivinjari au alamisho zilizohifadhiwa  katika simu yako. Programu mbovu zinaweza kutumia hii kufuta au kurekebisha data ya kivinjari chako."</string>
+    <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="1757103804824209530">"Inaruhusu programu kurekebisha historia ya Kivinjari au alamisho zilizohifadhiwa  katika kompyuta yako kibao. Programu hasidi zinaweza kutumia hii kufuta au kurekebisha data ya Kivinjari chako."</string>
+    <string name="permdesc_writeHistoryBookmarks" product="default" msgid="6693764355720719197">"Inaruhusu programu kurekebisha historia au alamisho za Kivinjari zilizohifadhiwa  katika simu yako. Programu hasidi zinaweza kutumia hii kufuta au kurekebisha data ya Kivinjari chako."</string>
     <string name="permlab_setAlarm" msgid="5924401328803615165">"weka kengele kwenye saa ya kengele"</string>
-    <string name="permdesc_setAlarm" msgid="316392039157473848">"Inaruhusu programu kuweka kengele katika programu iliyosakinishwa ya kengele. Kengele zingine hazitatekeleza mandhari hii."</string>
+    <string name="permdesc_setAlarm" msgid="316392039157473848">"Inaruhusu programu kuweka kengele katika programu iliyosakinishwa ya kengele. Programu zingine za kengele zinawezakosa kutekeleza kipengee hiki."</string>
     <string name="permlab_addVoicemail" msgid="5525660026090959044">"ongeza barua ya sauti"</string>
-    <string name="permdesc_addVoicemail" msgid="6604508651428252437">"Inaruhusu programu kuongeza ujumbe kwa kikasha cha ujumbe wa sauti."</string>
+    <string name="permdesc_addVoicemail" msgid="6604508651428252437">"Inaruhusu programu kuongeza jumbe kwenye kikasha cha ujumbe wa sauti."</string>
     <string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"Rekebisha vibali vya Kivinjari cha eneo la jio"</string>
     <string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"Inaruhusu programu kurekebisha ruhusa za eneo la jio za kivinjari. Programu hasidi zinaweza tumia hii kuruhusu kutuma taarifa ya eneo kwa wavuti holela."</string>
     <string name="permlab_packageVerificationAgent" msgid="5568139100645829117">"thibitisha furushi"</string>
     <string name="permdesc_packageVerificationAgent" msgid="8437590190990843381">"Inaruhusu programu kuthibitisha kuwa furushi linaweza kusakinishwa."</string>
     <string name="permlab_bindPackageVerifier" msgid="4187786793360326654">"Funga kwa kithibitishaji cha furushi"</string>
-    <string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"Inaruhusu mmiliki kufanya maombi ya furushi la vibainishi. Kamwe hazitahitajika kwa programu za kawaida."</string>
+    <string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"Inaruhusu mmiliki kutuma maombi ya vibainishi furushi. Kamwe hazitahitajika kwa programu za kawaida."</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>
@@ -842,7 +844,7 @@
     <item quantity="one" msgid="2178576254385739855">"kesho"</item>
     <item quantity="other" msgid="2973062968038355991">"kati ya siku <xliff:g id="COUNT">%d</xliff:g>"</item>
   </plurals>
-    <string name="preposition_for_date" msgid="9093949757757445117">"mnamo <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="preposition_for_date" msgid="9093949757757445117">"tarehe <xliff:g id="DATE">%s</xliff:g>"</string>
     <string name="preposition_for_time" msgid="5506831244263083793">"Saa <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="preposition_for_year" msgid="5040395640711867177">"ndani  ya <xliff:g id="YEAR">%s</xliff:g>"</string>
     <string name="day" msgid="8144195776058119424">"siku"</string>
@@ -857,8 +859,8 @@
     <string name="weeks" msgid="6509623834583944518">"wiki"</string>
     <string name="year" msgid="4001118221013892076">"mwaka"</string>
     <string name="years" msgid="6881577717993213522">"miaka"</string>
-    <string name="VideoView_error_title" msgid="5927895235831021723">"Video haiwezi kuchezwa."</string>
-    <string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"Video hii si halali kwa mtiririko kwa kifaa hiki."</string>
+    <string name="VideoView_error_title" msgid="5927895235831021723">"Haiwezi kucheza video."</string>
+    <string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"Video hii si halali kutiririshwa kwa kifaa hiki."</string>
     <string name="VideoView_error_text_unknown" msgid="4309847331399592194">"Video hii haiwezi chezwa"</string>
     <string name="VideoView_error_button" msgid="2822238215100679592">"Sawa"</string>
     <string name="relative_time" msgid="1818557177829411417">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
@@ -890,11 +892,11 @@
     <string name="no" msgid="5141531044935541497">"Ghairi"</string>
     <string name="dialog_alert_title" msgid="2049658708609043103">"Zingatia"</string>
     <string name="loading" msgid="7933681260296021180">"Inapakia…"</string>
-    <string name="capital_on" msgid="1544682755514494298">"Mnamo"</string>
+    <string name="capital_on" msgid="1544682755514494298">"Washa"</string>
     <string name="capital_off" msgid="6815870386972805832">"ZIMA"</string>
     <string name="whichApplication" msgid="4533185947064773386">"Kamilisha kitendo kwa kutumia"</string>
     <string name="alwaysUse" msgid="4583018368000610438">"Tumia kama chaguo-msingi la kitendo hiki."</string>
-    <string name="clearDefaultHintMsg" msgid="3252584689512077257">"Futa chaguo-msingi katika mipangilio ya mfumo &gt; Apps &gt; iliyopakuliwa."</string>
+    <string name="clearDefaultHintMsg" msgid="3252584689512077257">"Futa chaguo-msingi katika mipangilio ya Mfumo &gt; Apps &gt; iliyopakuliwa."</string>
     <string name="chooseActivity" msgid="1009246475582238425">"Chagua kitendo"</string>
     <string name="chooseUsbActivity" msgid="6894748416073583509">"Chagua programu ya kifaa cha USB"</string>
     <string name="noApplications" msgid="2991814273936504689">"Hakuna programu zinazoweza kufanya tendo hili."</string>
@@ -903,19 +905,19 @@
     <string name="aerr_process" msgid="4507058997035697579">"Kwa bahati mbaya, mchakato <xliff:g id="PROCESS">%1$s</xliff:g> umekoma."</string>
     <string name="anr_title" msgid="4351948481459135709"></string>
     <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> haifanyi kazi."\n\n"Unataka kuifunga?"</string>
-    <string name="anr_activity_process" msgid="5776209883299089767">"Shughuli <xliff:g id="ACTIVITY">%1$s</xliff:g> haijibu. "\n\n" Unataka kuifunga"</string>
+    <string name="anr_activity_process" msgid="5776209883299089767">"Shughuli <xliff:g id="ACTIVITY">%1$s</xliff:g> haijibu. "\n\n" Unataka kuifunga?"</string>
     <string name="anr_application_process" msgid="8941757607340481057">"<xliff:g id="APPLICATION">%1$s</xliff:g> haijibu. Unataka kufunga?"</string>
     <string name="anr_process" msgid="6513209874880517125">"Mchakato <xliff:g id="PROCESS">%1$s</xliff:g> haijibu. "\n\n" Unataka kuifunga?"</string>
     <string name="force_close" msgid="8346072094521265605">"Sawa"</string>
     <string name="report" msgid="4060218260984795706">"Ripoti"</string>
     <string name="wait" msgid="7147118217226317732">"Subiri"</string>
-    <string name="launch_warning_title" msgid="1547997780506713581">"Programu imeelekezwa"</string>
+    <string name="launch_warning_title" msgid="1547997780506713581">"Programu imeelekezwa kwingine"</string>
     <string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g>inaendesha sasa."</string>
     <string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g> ilizinduliwa mwanzoni."</string>
     <string name="screen_compat_mode_scale" msgid="3202955667675944499">"Kipimo"</string>
     <string name="screen_compat_mode_show" msgid="4013878876486655892">"Onyesha kila wakati"</string>
-    <string name="screen_compat_mode_hint" msgid="1064524084543304459">"Wezesha tena hii katika mipangilio ya Mfumo &gt; Programu &gt;  vipakuliwa."</string>
-    <string name="smv_application" msgid="3307209192155442829">"Programu <xliff:g id="APPLICATION">%1$s</xliff:g>  (uendeshaji  <xliff:g id="PROCESS">%2$s</xliff:g>) imeenda kinyume na sera yake ya StrictMode."</string>
+    <string name="screen_compat_mode_hint" msgid="1064524084543304459">"Wezesha tena hii katika mipangilio ya Mfumo &gt; Programu &gt;  iliyopakuliwa."</string>
+    <string name="smv_application" msgid="3307209192155442829">"Programu <xliff:g id="APPLICATION">%1$s</xliff:g>  (utaratibu  <xliff:g id="PROCESS">%2$s</xliff:g>) imeenda kinyume na sera yake ya StrictMode."</string>
     <string name="smv_process" msgid="5120397012047462446">"Shughuli ya <xliff:g id="PROCESS">%1$s</xliff:g> imeenda kinyume na kulazimisha sera yake ya StrictMode."</string>
     <string name="android_upgrading_title" msgid="1584192285441405746">"Android inapandishwa gredi..."</string>
     <string name="android_upgrading_apk" msgid="7904042682111526169">"Inasadifisha programu <xliff:g id="NUMBER_0">%1$d</xliff:g> ya <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
@@ -924,9 +926,9 @@
     <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> inaendelea"</string>
     <string name="heavy_weight_notification_detail" msgid="1721681741617898865">"Gusa ili kubadilisha hadi programu"</string>
     <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"Badilisha programu?"</string>
-    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"Programmu nyingine inaendeshwa tayari lazima hiyo ikomeshwe kabla ya kuanza nyingine mpya."</string>
+    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"Programmu nyingine tayari inaendeshwa na lazima hiyo ikomeshwe kabla ya kuanza nyingine mpya."</string>
     <string name="old_app_action" msgid="493129172238566282">"Rejea katika <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
-    <string name="old_app_description" msgid="2082094275580358049">"Usianze programu mpya."</string>
+    <string name="old_app_description" msgid="2082094275580358049">"Usianzishe programu mpya."</string>
     <string name="new_app_action" msgid="5472756926945440706">"Anza <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
     <string name="new_app_description" msgid="1932143598371537340">"Komesha programu ya zamani bila kuhifadhi."</string>
     <string name="sendText" msgid="5132506121645618310">"Chagua kitendo cha jaribio"</string>
@@ -973,11 +975,11 @@
     <string name="select_character" msgid="3365550120617701745">"Ingiza kibambo"</string>
     <string name="sms_control_default_app_name" msgid="3058577482636640465">"Programu isiyojulikana"</string>
     <string name="sms_control_title" msgid="7296612781128917719">"Inatuma ujumbe wa SMS"</string>
-    <string name="sms_control_message" msgid="4073755190243093924">"Idadi kubwa ya ujumbe mfupi inatumwa. Gusa SAWA kuendelea, au Ghairi kuwacha kutuma."</string>
+    <string name="sms_control_message" msgid="4073755190243093924">"Idadi kubwa ya jumbe za SMS inatumwa. Gusa SAWA kuendelea, au Ghairi kuwacha kutuma."</string>
     <string name="sms_control_yes" msgid="2532062172402615953">"Sawa"</string>
     <string name="sms_control_no" msgid="1715320703137199869">"Ghairi"</string>
     <string name="sim_removed_title" msgid="6227712319223226185">"Kadi ya SIM imeondolewa"</string>
-    <string name="sim_removed_message" msgid="2333164559970958645">"mtandao wa simu hutapatika hadi uanzishe upya na kadi ya SIM halali iliyoingizwa."</string>
+    <string name="sim_removed_message" msgid="2333164559970958645">"mtandao wa simu hutapatika hadi uanzishe upya na SIM kadi halali iliyoingizwa."</string>
     <string name="sim_done_button" msgid="827949989369963775">"Kwisha"</string>
     <string name="sim_added_title" msgid="3719670512889674693">"Kadi ya SIM imeongezwa"</string>
     <string name="sim_added_message" msgid="1209265974048554242">"Lazima uwashe upya kifaa chako ili kufikia mtandao wa simu."</string>
@@ -1006,7 +1008,7 @@
     <string name="usb_storage_stop_button_mount" msgid="7060218034900696029">"Inazima hifadhi ya USB"</string>
     <string name="usb_storage_stop_error_message" msgid="143881914840412108">"Kulikuwa na tatizo la kuzima uhifadhi wa USB. angalia kwa kuhakikisha umeangua mpangishi wa USB, kisha jaribu tena."</string>
     <string name="dlg_confirm_kill_storage_users_title" msgid="963039033470478697">"Wezesha hifadhi ya USB"</string>
-    <string name="dlg_confirm_kill_storage_users_text" msgid="6206212680430268343">"Ukiwezesha hifadhi ya USB, baadhi ya programu unazozitumia zitakoma na huenda zisipatikane hadi ulemeze hifadhi ya USB."</string>
+    <string name="dlg_confirm_kill_storage_users_text" msgid="6206212680430268343">"Ukiwezesha hifadhi ya USB, baadhi ya programu unazozitumia zitakoma na huenda zisipatikane hadi ulemaze hifadhi ya USB."</string>
     <string name="dlg_error_title" msgid="7323658469626514207">"Uendeshaji wa USB hujafanikiwa"</string>
     <string name="dlg_ok" msgid="7376953167039865701">"Sawa"</string>
     <string name="usb_mtp_notification_title" msgid="3699913097391550394">"Imeunganishwa kama kifaa cha midia"</string>
@@ -1015,12 +1017,12 @@
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Imeunganishwa kwa kifuasi cha USB"</string>
     <string name="usb_notification_message" msgid="4447869605109736382">"Gusa kwa machaguo mengine ya USB"</string>
     <string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"Fomati hifadhi ya USB?"</string>
-    <string name="extmedia_format_title" product="default" msgid="3648415921526526069">"Umbizo wa kadi ya SD."</string>
+    <string name="extmedia_format_title" product="default" msgid="3648415921526526069">"Umbiza kadi ya SD."</string>
     <string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"Faili zote zilizohifadhiwa katika hifadhi yako ya USB zitafutwa. Hatua hii haiwezi kubadilishwa!"</string>
     <string name="extmedia_format_message" product="default" msgid="14131895027543830">"Data yote kwenye kadi yako itapotea."</string>
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"Fomati"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Utatuaji USB umeunganishwa"</string>
-    <string name="adb_active_notification_message" msgid="1016654627626476142">"Gusa ili kulemaza kueua USB."</string>
+    <string name="adb_active_notification_message" msgid="1016654627626476142">"Gusa ili kulemaza utatuaji wa USB."</string>
     <string name="select_input_method" msgid="4653387336791222978">"Chagua njia ya ingizo"</string>
     <string name="configure_input_methods" msgid="9091652157722495116">"Weka mbinu za ingizo"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1053,8 +1055,8 @@
     <string name="permlab_pkgUsageStats" msgid="8787352074326748892">"sasisha takwimu za utumiaji vijenzi"</string>
     <string name="permdesc_pkgUsageStats" msgid="1106612424254277630">"Inaruhusu programu kurekebisha takwimu za matumizi za kijenzi zilizokusanywa. Si ya kutumiwa na programu za kawaida."</string>
     <string name="permlab_copyProtectedData" msgid="4341036311211406692">"nakili maudhui"</string>
-    <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Inaruhusu programu kuweka chaguo-msingi ya huduma ya chobo kunakili maudhui. Si ya matumizi na programu za kawiada."</string>
-    <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Gusa mara mbili kwa kidhibiti cha kuza"</string>
+    <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Inaruhusu programu kuomba huduma ya chombo chaguo-msingi kunakili maudhui. Si ya matumizi na programu za kawiada."</string>
+    <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Gusa mara mbili kwa udhibiti cha kuza"</string>
     <string name="gadget_host_error_inflating" msgid="2613287218853846830">"Hitilafu ya kushinikiza wijeti"</string>
     <string name="ime_action_go" msgid="8320845651737369027">"Nenda"</string>
     <string name="ime_action_search" msgid="658110271822807811">"Tafuta"</string>
@@ -1065,7 +1067,7 @@
     <string name="ime_action_default" msgid="2840921885558045721">"Tekeleza"</string>
     <string name="dial_number_using" msgid="5789176425167573586">"Piga nambari "\n" kwa kutumia <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="create_contact_using" msgid="4947405226788104538">"Unda anwani "\n" kwa kutumia <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"Programu moja au zaidi zifuatazo zinaomba ruhusa ya kufikia akaunti yako, sasa na katika siku za usoni."</string>
+    <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"Programu moja au zaidi zifuatazo zinaomba ruhusa ya kufikia akaunti yako, sasa na baadaye."</string>
     <string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"Unataka kuruhusu ombi hili?"</string>
     <string name="grant_permissions_header_text" msgid="2722567482180797717">"Ombi la Kufikia"</string>
     <string name="allow" msgid="7225948811296386551">"Ruhusu"</string>
@@ -1075,8 +1077,8 @@
     <string name="input_method_binding_label" msgid="1283557179944992649">"Mbinu ya uingizaji"</string>
     <string name="sync_binding_label" msgid="3687969138375092423">"Sawazisha"</string>
     <string name="accessibility_binding_label" msgid="4148120742096474641">"Ufikiaji"</string>
-    <string name="wallpaper_binding_label" msgid="1240087844304687662">"Pazia"</string>
-    <string name="chooser_wallpaper" msgid="7873476199295190279">"Badilisha pazia"</string>
+    <string name="wallpaper_binding_label" msgid="1240087844304687662">"Mandhari"</string>
+    <string name="chooser_wallpaper" msgid="7873476199295190279">"Badilisha mandhari"</string>
     <string name="vpn_title" msgid="8219003246858087489">"VPN imeamilishwa."</string>
     <string name="vpn_title_long" msgid="6400714798049252294">"VPN imeamilishwa na <xliff:g id="APP">%s</xliff:g>"</string>
     <string name="vpn_text" msgid="1610714069627824309">"Gonga ili kudhibiti mtandao."</string>
@@ -1153,7 +1155,7 @@
     <string name="checkbox_not_checked" msgid="5174639551134444056">"haijakaguliwa"</string>
     <string name="radiobutton_selected" msgid="8603599808486581511">"Iliyochaguliwa"</string>
     <string name="radiobutton_not_selected" msgid="2908760184307722393">"Haijachaguliwa"</string>
-    <string name="switch_on" msgid="551417728476977311">"Mnamo"</string>
+    <string name="switch_on" msgid="551417728476977311">"Washa"</string>
     <string name="switch_off" msgid="7249798614327155088">"zima"</string>
     <string name="togglebutton_pressed" msgid="4180411746647422233">"iliyobonyezwa"</string>
     <string name="togglebutton_not_pressed" msgid="4495147725636134425">"Haijabonyezwa"</string>
@@ -1216,7 +1218,10 @@
     <string name="sha1_fingerprint" msgid="7930330235269404581">"Alama ya kidole ya  SHA-1:"</string>
     <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"Angalia zote"</string>
     <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"Chagua shughuli"</string>
-    <string name="share_action_provider_share_with" msgid="5247684435979149216">"Gawa na"</string>
+    <string name="share_action_provider_share_with" msgid="5247684435979149216">"Shiriki na"</string>
     <string name="status_bar_device_locked" msgid="3092703448690669768">"Kifaa kimefungwa."</string>
     <string name="list_delimeter" msgid="3975117572185494152">", "</string>
+    <string name="sending" msgid="8715108995741758718">"Inatuma..."</string>
+    <string name="launchBrowserDefault" msgid="2057951947297614725">"Zindua Kivinjari?"</string>
+    <string name="SetupCallDefault" msgid="6870275517518479651">"Kubali Simu?"</string>
 </resources>
diff --git a/core/res/res/values-sw600dp/dimens.xml b/core/res/res/values-sw600dp/dimens.xml
index 921bcf4..431a502 100644
--- a/core/res/res/values-sw600dp/dimens.xml
+++ b/core/res/res/values-sw600dp/dimens.xml
@@ -62,8 +62,8 @@
 
     <!-- Default padding to apply to AppWidgetHostViews containing widgets targeting API level 14 and up. -->
     <dimen name="default_app_widget_padding_left">12dp</dimen>
-    <dimen name="default_app_widget_padding_top">12dp</dimen>
-    <dimen name="default_app_widget_padding_right">4dp</dimen>
+    <dimen name="default_app_widget_padding_top">4dp</dimen>
+    <dimen name="default_app_widget_padding_right">12dp</dimen>
     <dimen name="default_app_widget_padding_bottom">20dp</dimen>
 
     <!-- Minimum width for an action button in the menu area of an action bar -->
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index f171f5d..7a4825f 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -301,6 +301,8 @@
     <string name="permlab_readLogs" msgid="6615778543198967614">"อ่านข้อมูลบันทึกที่สำคัญ"</string>
     <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"อนุญาตให้แอปพลิเคชันอ่านจากไฟล์บันทึกต่างๆ ของระบบ เพื่อค้นหาข้อมูลทั่วไปเกี่ยวกับสิ่งที่คุณกำลังทำอยู่กับแท็บเล็ต ซึ่งอาจรวมไปถึงข้อมูลส่วนบุคคลหรือส่วนตัว"</string>
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"อนุญาตให้แอปพลิเคชันอ่านจากไฟล์บันทึกต่างๆ ของระบบ เพื่อค้นหาข้อมูลทั่วไปเกี่ยวกับสิ่งที่คุณกำลังทำอยู่กับโทรศัพท์ ซึ่งอาจรวมไปถึงข้อมูลส่วนบุคคลหรือส่วนตัว"</string>
+    <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"ใช้ตัวถอดรหัสสื่อใดๆ ก็ได้สำหรับการเล่น"</string>
+    <string name="permdesc_anyCodecForPlayback" msgid="2101444559995480174">"อนุญาตให้แอปพลิเคชันใช้ตัวถอดรหัสสื่อใดก็ได้ที่ติดตั้งไว้เพื่อถอดรหัสสำหรับการเล่น"</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"อ่าน/เขียนไปยังรีซอร์สที่เป็นเจ้าของโดยกลุ่มวินิจฉัย"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"อนุญาตให้แอปพลิเคชันอ่านและเขียนไปยังทรัพยากรที่เป็นของกลุ่มวินิจฉัย เช่น ไฟล์ใน /dev การทำเช่นนี้อาจส่งผลต่อความเสถียรและความปลอดภัยของระบบ และควรใช้สำหรับการวินิจฉัยเกี่ยวกับฮาร์ดแวร์โดยเฉพาะที่ทำโดยผู้ผลิตหรือผู้ให้บริการเท่านั้น"</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"เปิดหรือปิดใช้งานคอมโพเนนต์ของแอปพลิเคชัน"</string>
@@ -465,9 +467,9 @@
     <string name="permlab_bluetoothAdmin" msgid="3606576270792236062">"การจัดการบลูทูธ"</string>
     <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"อนุญาตให้แอปพลิเคชันกำหนดค่าแท็บเล็ตบลูทูธในตัวเครื่อง รวมทั้งค้นหาและจับคู่กับอุปกรณ์ที่อยู่ระยะไกล"</string>
     <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"อนุญาตให้แอปพลิเคชันกำหนดค่าโทรศัพท์บลูทูธในตัวเครื่อง ตลอดจนค้นหาและจับคู่กับอุปกรณ์ที่อยู่ระยะไกล"</string>
-    <!-- outdated translation 2800410363171809280 -->     <string name="permlab_accessWimaxState" msgid="1232061307208861588">"ดูสถานะของ WiMAX"</string>
+    <string name="permlab_accessWimaxState" msgid="1232061307208861588">"ดูสถานะของ WiMAX"</string>
     <string name="permdesc_accessWimaxState" msgid="8298035866227524023">"อนุญาตให้แอปพลิเคชันดูข้อมูลเกี่ยวกับสถานะของ WiMAX"</string>
-    <!-- outdated translation 340465839241528618 -->     <string name="permlab_changeWimaxState" msgid="2405042267131496579">"เปลี่ยนสถานะของ WiMAX"</string>
+    <string name="permlab_changeWimaxState" msgid="2405042267131496579">"เปลี่ยนสถานะของ WiMAX"</string>
     <string name="permdesc_changeWimaxState" msgid="474918005058989421">"อนุญาตให้แอปพลิเคชันเชื่อมต่อและยกเลิกการเชื่อมต่อกับเครือข่าย WiMAX"</string>
     <string name="permlab_bluetooth" msgid="8361038707857018732">"สร้างการเชื่อมต่อบลูทูธ"</string>
     <string name="permdesc_bluetooth" product="tablet" msgid="7007851048416363446">"อนุญาตให้แอปพลิเคชันดูการกำหนดค่าของแท็บเล็ตบลูทูธในตัวเครื่อง ตลอดจนเชื่อมต่อและยอมรับการเชื่อมต่อกับอุปกรณ์ที่จับคู่ไว้"</string>
@@ -1219,4 +1221,7 @@
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"แบ่งปันกับ"</string>
     <string name="status_bar_device_locked" msgid="3092703448690669768">"ล็อกอุปกรณ์อยู่"</string>
     <string name="list_delimeter" msgid="3975117572185494152">", "</string>
+    <string name="sending" msgid="8715108995741758718">"กำลังส่ง..."</string>
+    <string name="launchBrowserDefault" msgid="2057951947297614725">"เปิดเบราว์เซอร์หรือไม่"</string>
+    <string name="SetupCallDefault" msgid="6870275517518479651">"รับสายหรือไม่"</string>
 </resources>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index e8b1302..bc47662 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -301,6 +301,8 @@
     <string name="permlab_readLogs" msgid="6615778543198967614">"magbasa ng sensitibong data ng tala"</string>
     <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"Pinapayagan ang app na magbasa mula sa iba\'t ibang mga file ng log ng system. Pinapayagan ito nito na tumuklas ng pangkalahatang impormasyon tungkol sa kung ano ang iyong ginagawa sa tablet, potensyal na kabilang ang personal o pribadong impormasyon."</string>
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Pinapayagan ang app na magbasa mula sa iba\'t ibang mga file ng log ng system. Pinapayagan ito nito na tumuklas ng pangkalahatang impormasyon tungkol sa kung ano ang iyong ginagawa sa telepono, potensyal na kabilang ang personal o pribadong impormasyon."</string>
+    <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"gumamit ng anumang media decoder para sa pag-playback"</string>
+    <string name="permdesc_anyCodecForPlayback" msgid="2101444559995480174">"Pinapayagan ka ng application na gumamit ng anumang naka-install na media decoder upang mag-decode para sa pag-playback."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"magbasa/magsulat sa mga mapagkukunang pag-aari ng diag"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Pinapayagan ang app na magbasa at magsulat sa anumang mapagkukunang pag-aari ng pangkat ng diag; halimbawa, mga file sa /dev. Maaaring potensyal na maapektuhan nito ang katatagan at seguridad ng system. Dapat LAMANG itong gamitin para sa diagnostics na tukoy sa hardware ng tagagawa o operator."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"paganahin o huwag paganahin ang mga bahagi ng app"</string>
@@ -465,9 +467,9 @@
     <string name="permlab_bluetoothAdmin" msgid="3606576270792236062">"Pangangasiwa sa Bluetooth"</string>
     <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"Pinapayagan ang app na i-configure ang lokal na Bluetooth tablet, at tumuklas ng at ipares sa mga malayuang device."</string>
     <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"Pinapayagan ang app na i-configure ang lokal na Bluetooth na telepono, at tumuklas ng at ipares sa mga malayuang device."</string>
-    <!-- outdated translation 2800410363171809280 -->     <string name="permlab_accessWimaxState" msgid="1232061307208861588">"tingnan ang katayuan ng WiMAX"</string>
+    <string name="permlab_accessWimaxState" msgid="1232061307208861588">"Tingnan ang katayuan ng WiMAX"</string>
     <string name="permdesc_accessWimaxState" msgid="8298035866227524023">"Pinapayagan ang application na tingnan ang impormasyon tungkol sa katayuan ng WiMAX."</string>
-    <!-- outdated translation 340465839241528618 -->     <string name="permlab_changeWimaxState" msgid="2405042267131496579">"baguhin ang katayuan ng WiMAX"</string>
+    <string name="permlab_changeWimaxState" msgid="2405042267131496579">"Baguhin ang katayuan ng WiMAX"</string>
     <string name="permdesc_changeWimaxState" msgid="474918005058989421">"Pinapayagan ang isang application na makakonekta sa at maalis sa pagkakakonekta mula sa network ng WiMAX."</string>
     <string name="permlab_bluetooth" msgid="8361038707857018732">"lumikha ng mga koneksyon ng Bluetooth"</string>
     <string name="permdesc_bluetooth" product="tablet" msgid="7007851048416363446">"Pinapayagan ang app na tingnan ang configuration ng lokal na Bluetooth tablet, at upang gumawa at tumanggap ng mga koneksyon sa mga nakapares na device."</string>
@@ -1219,4 +1221,7 @@
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"Ibahagi sa"</string>
     <string name="status_bar_device_locked" msgid="3092703448690669768">"Naka-lock ang device."</string>
     <string name="list_delimeter" msgid="3975117572185494152">", "</string>
+    <string name="sending" msgid="8715108995741758718">"Ipinapadala..."</string>
+    <string name="launchBrowserDefault" msgid="2057951947297614725">"Ilunsad ang Browser?"</string>
+    <string name="SetupCallDefault" msgid="6870275517518479651">"Tanggapin ang Tawag?"</string>
 </resources>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 01cb48b..806e2e6 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -301,6 +301,8 @@
     <string name="permlab_readLogs" msgid="6615778543198967614">"hassas günlük verilerini okuma"</string>
     <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"Uygulamaya, sisteme ait çeşitli günlük dosyalarındaki bilgileri okuma izni verir. Bu izin, uygulamanın, kişisel ve gizli bilgileriniz de dahil olmak üzere tablette yaptıklarınızla ilgili genel bilgileri bulmasına olanak verir."</string>
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Uygulamaya, sisteme ait çeşitli günlük dosyalarındaki bilgileri okuma izni verir. Bu izin, uygulamanın, kişisel ve gizli bilgileriniz de dahil olmak üzere telefonda yaptıklarınızla ilgili genel bilgileri bulmasına olanak verir."</string>
+    <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"oynatma için herhangi bir medya kod çözücüyü kullan"</string>
+    <string name="permdesc_anyCodecForPlayback" msgid="2101444559995480174">"Uygulamaya, oynatma kodunu çözmek için herhangi bir yüklü medya kod çözücüyü kullanma izni verir."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"sahibi tanılama olan kaynakları oku/bunlara yaz"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Uygulamaya, tanılama grubunun sahip olduğu tüm kaynaklara (örneğin /dev içindeki dosyalar) okuma ve yazma izni verir. Bu işlevin sistem kararlılığını ve güvenliğini olumsuz etkileme olasılığı vardır. Üretici veya operatör tarafından YALNIZCA donanıma özgü tanılama için kullanılmalıdır."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"uygulama bileşenlerini etkinleştir veya devre dışı bırak"</string>
@@ -465,9 +467,9 @@
     <string name="permlab_bluetoothAdmin" msgid="3606576270792236062">"Bluetooth yönetimi"</string>
     <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"Uygulamaya, yerel Bluetooth tabletini yapılandırma ve uzak cihazları keşfedip bunlarla eşleşme izni verir."</string>
     <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"Uygulamaya, yerel Bluetooth telefonunu yapılandırma ve uzak cihazları keşfedip bunlarla eşleşme izni verir."</string>
-    <!-- outdated translation 2800410363171809280 -->     <string name="permlab_accessWimaxState" msgid="1232061307208861588">"WiMAX durumunu görüntüle"</string>
+    <string name="permlab_accessWimaxState" msgid="1232061307208861588">"WiMAX durumunu görüntüle"</string>
     <string name="permdesc_accessWimaxState" msgid="8298035866227524023">"Uygulamanın, WiMAX\'ın durumuyla ilgili bilgileri görüntülemesine izin verir."</string>
-    <!-- outdated translation 340465839241528618 -->     <string name="permlab_changeWimaxState" msgid="2405042267131496579">"WiMAX durumunu değiştir"</string>
+    <string name="permlab_changeWimaxState" msgid="2405042267131496579">"WiMAX durumunu değiştir"</string>
     <string name="permdesc_changeWimaxState" msgid="474918005058989421">"Uygulamanın, WiMAX ağına bağlanmasına veya bağlantısını kesmesine izin verir."</string>
     <string name="permlab_bluetooth" msgid="8361038707857018732">"Bluetooth bağlantıları oluştur"</string>
     <string name="permdesc_bluetooth" product="tablet" msgid="7007851048416363446">"Uygulamaya, yerel Bluetooth tabletinin yapılandırmasını görüntüleme, eşleştirilmiş cihazlarla bağlantı yapma ve bu tür bağlantıları kabul etme izni verir."</string>
@@ -1219,4 +1221,7 @@
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"Şununla paylaş:"</string>
     <string name="status_bar_device_locked" msgid="3092703448690669768">"Cihaz kilitli."</string>
     <string name="list_delimeter" msgid="3975117572185494152">", "</string>
+    <string name="sending" msgid="8715108995741758718">"Gönderiliyor..."</string>
+    <string name="launchBrowserDefault" msgid="2057951947297614725">"Tarayıcı Başlatılsın mı?"</string>
+    <string name="SetupCallDefault" msgid="6870275517518479651">"Çağrı Kabul Edilsin mi?"</string>
 </resources>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 436b6d7..0ed981d 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -197,7 +197,7 @@
     <string name="permlab_sendSms" msgid="5600830612147671529">"надсил. SMS повідом."</string>
     <string name="permdesc_sendSms" msgid="906546667507626156">"Дозволяє програмі надсилати SMS повідомлення. Шкідливі програми можуть надсилати повідомлення без вашого підтвердження, заставляючи вас платити."</string>
     <string name="permlab_sendSmsNoConfirmation" msgid="4781483105951730228">"надсилати SMS-повідомлення без підтвердження"</string>
-    <string name="permdesc_sendSmsNoConfirmation" msgid="3437759207020400204">"Дозволяє програмі надсилати SMS повідомлення. Шкідливі програми можуть надсилати повідомлення без вашого підтвердження, заставляючи вас платити."</string>
+    <string name="permdesc_sendSmsNoConfirmation" msgid="3437759207020400204">"Дозволяє програмі надсилати SMS повідомлення. Шкідливі програми можуть надсилати повідомлення без вашого підтвердження, змушуючи вас платити."</string>
     <string name="permlab_readSms" msgid="4085333708122372256">"читати SMS або MMS"</string>
     <string name="permdesc_readSms" product="tablet" msgid="2341692916884515613">"Дозволяє програмі читати SMS повідомлення, збережені в планшетному ПК чи на SIM-карті. Шкідливі програми можуть читати ваші конфіденційні повідомлення."</string>
     <string name="permdesc_readSms" product="default" msgid="5653850482025875493">"Дозволяє програмі читати SMS повідомлення, збережені в телефоні чи на SIM-карті. Шкідливі програми можуть читати ваші конфіденційні повідомлення."</string>
@@ -233,7 +233,7 @@
     <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"запобіг. зміні програм"</string>
     <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"Запобігати переходу користувача до іншої програми."</string>
     <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"відстежувати та контролювати запуски всіх програм"</string>
-    <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"Дозволяє програмі відстежувати та контролювати, як саме система запускає дії. Шкідливі програми можуть повністю зламувати систему. Цей дозвіл потрібний лише для розробки, а не для звичайного користування."</string>
+    <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"Дозволяє програмі відстежувати та контролювати, як саме система запускає дії. Шкідливі програми можуть отримати повний контроль над системою. Цей дозвіл потрібний лише для розробки, а не для звичайного користування."</string>
     <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"надсил. запис про видал. пакета"</string>
     <string name="permdesc_broadcastPackageRemoved" msgid="6621901216207931089">"Дозволяє програмі передавати сповіщення про видалення пакета програми. Шкідливі програми можуть використовувати це для примусового припинення роботи будь-якої іншої запущеної програми."</string>
     <string name="permlab_broadcastSmsReceived" msgid="5689095009030336593">"надсил. запис, отрим. в SMS"</string>
@@ -242,7 +242,7 @@
     <string name="permdesc_broadcastWapPush" msgid="4783402525039442729">"Дозволяє програмі передавати сповіщення про отримання повідомлення WAP PUSH. Шкідливі програми можуть використовувати це для підробки отримання MMS повідомлень або для непомітної заміни вмісту будь-якої веб-сторінки шкідливими варіантами."</string>
     <string name="permlab_setProcessLimit" msgid="2451873664363662666">"обмежувати кількість запущ. процесів"</string>
     <string name="permdesc_setProcessLimit" msgid="7318061314040879542">"Дозволяє програмі контролювати максимальну кількість процесів, які буде запущено. Ніколи не вимагається для звичайних програм."</string>
-    <string name="permlab_setAlwaysFinish" msgid="238828158465736054">"заставляти всі фонові програми закриватися"</string>
+    <string name="permlab_setAlwaysFinish" msgid="238828158465736054">"примушувати всі фонові програми закриватися"</string>
     <string name="permdesc_setAlwaysFinish" msgid="7471310652868841499">"Дозволяє програмі контролювати обов’язкове завершення всіх дій, які переходять у фоновий режим. Ніколи не вимагається для звичайних програм."</string>
     <string name="permlab_batteryStats" msgid="7863923071360031652">"змінювати статистику батареї"</string>
     <string name="permdesc_batteryStats" msgid="6835186932305744068">"Дозволяє програмі змінювати зібрану статистику акумулятора. Не для використання звичайними програмами."</string>
@@ -301,6 +301,8 @@
     <string name="permlab_readLogs" msgid="6615778543198967614">"зчит. закриті дані журн."</string>
     <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"Дозволяє програмі читати з різних файлів журналу системи. Це дозволяє дізнаватися загальну інформацію про ваші дії в планшетному ПК, яка потенційно може містити особисті чи конфіденційні дані."</string>
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Дозволяє програмі читати з різних файлів журналу системи. Це дозволяє дізнаватися загальну інформацію про ваші дії в телефоні, яка потенційно може містити особисті чи конфіденційні дані."</string>
+    <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"використовувати будь-який медіа-декодер для відтворення"</string>
+    <string name="permdesc_anyCodecForPlayback" msgid="2101444559995480174">"Дозволяє програмі використовувати будь-який установлений медіа-декодер для декодування з метою відтворення."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"чит./зап. на ресури., якими вол. діаг."</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Дозволяє програмі читати та писати на будь-який ресурс, яким володіє діагностична група; наприклад, у файли в папці /dev. Це потенційно може вплинути на стабільність і безпеку системи. Потрібно використовувати ЛИШЕ для певної діагностики обладнання, яку виконує виробник чи оператор."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"вмикати чи вимикати компоненти програми"</string>
@@ -461,13 +463,13 @@
     <string name="permlab_changeWifiState" msgid="7280632711057112137">"змінити стан Wi-Fi"</string>
     <string name="permdesc_changeWifiState" msgid="7399961004537946240">"Дозволяє програмі підключатися та відключатися від точок доступу Wi-Fi, а також вносити зміни в налаштовані мережі Wi-Fi."</string>
     <string name="permlab_changeWifiMulticastState" msgid="1368253871483254784">"дозвол. отримання багатоадр. Wi-Fi"</string>
-    <string name="permdesc_changeWifiMulticastState" msgid="7633598524564320817">"Дозволяє програмі отримувати пакети, не адресовані безпосередньо вашому пристрою. Це може придатися для виявлення служб, які надаються поблизу. Використовує більше заряду, ніж режим не-багатоадресних пакетів."</string>
+    <string name="permdesc_changeWifiMulticastState" msgid="7633598524564320817">"Дозволяє програмі отримувати пакети, не адресовані безпосередньо вашому пристрою. Це може буди корисним для виявлення служб, які надаються поблизу. Використовує більше заряду, ніж режим не-багатоадресних пакетів."</string>
     <string name="permlab_bluetoothAdmin" msgid="3606576270792236062">"адміністрування Bluetooth"</string>
     <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"Дозволяє програмі налаштовувати планшетний ПК із локальним Bluetooth, а також знаходити віддалені пристрої та створювати з ними пару."</string>
     <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"Дозволяє програмі налаштовувати телефон із локальним Bluetooth, а також знаходити віддалені пристрої та створювати з ними пару."</string>
-    <!-- outdated translation 2800410363171809280 -->     <string name="permlab_accessWimaxState" msgid="1232061307208861588">"переглядати стан WiMAX"</string>
+    <string name="permlab_accessWimaxState" msgid="1232061307208861588">"Переглянути стан WiMAX"</string>
     <string name="permdesc_accessWimaxState" msgid="8298035866227524023">"Дозволяє програмі переглядати інформацію про стан WiMAX."</string>
-    <!-- outdated translation 340465839241528618 -->     <string name="permlab_changeWimaxState" msgid="2405042267131496579">"змінювати стан WiMAX"</string>
+    <string name="permlab_changeWimaxState" msgid="2405042267131496579">"Змінити стан WiMAX"</string>
     <string name="permdesc_changeWimaxState" msgid="474918005058989421">"Дозволяє програмі підключатися та відключатися від мережі WiMAX."</string>
     <string name="permlab_bluetooth" msgid="8361038707857018732">"створюв. підключення Bluetooth"</string>
     <string name="permdesc_bluetooth" product="tablet" msgid="7007851048416363446">"Дозволяє програмі переглядати конфігурацію планшетного ПК із локальним Bluetooth, а також створювати та приймати з’єднання зі спареними пристроями."</string>
@@ -492,7 +494,7 @@
     <string name="permdesc_writeDictionary" msgid="8185385716255065291">"Дозволяє програмі писати нові слова в словник користувача."</string>
     <string name="permlab_sdcardWrite" product="nosdcard" msgid="85430876310764752">"змінювати/видаляти вміст носія USB"</string>
     <string name="permlab_sdcardWrite" product="default" msgid="8079403759001777291">"змінювати/видал. вміст карти SD"</string>
-    <string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"Дозвол.прогр. пис.на носій USB"</string>
+    <string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"Дозволяє програмі писати на носій USB"</string>
     <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Дозволяє програмі записувати на карту SD."</string>
     <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"змінювати/видаляти вміст внутр. сховища даних"</string>
     <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Дозволяє програмі змінювати вміст внутрішнього сховища даних."</string>
@@ -858,7 +860,7 @@
     <string name="year" msgid="4001118221013892076">"рік"</string>
     <string name="years" msgid="6881577717993213522">"р."</string>
     <string name="VideoView_error_title" msgid="5927895235831021723">"Неможливо відтворити відео"</string>
-    <string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"Відео не придатне для потокового передавання цьому пристрою."</string>
+    <string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"Відео не придатне для потокового передавання в цей пристрій."</string>
     <string name="VideoView_error_text_unknown" msgid="4309847331399592194">"Це відео неможливо відтворити."</string>
     <string name="VideoView_error_button" msgid="2822238215100679592">"OK"</string>
     <string name="relative_time" msgid="1818557177829411417">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
@@ -905,7 +907,7 @@
     <string name="anr_activity_application" msgid="1904477189057199066">"Програма <xliff:g id="APPLICATION">%2$s</xliff:g> не відповідає."\n\n"Закрити її?"</string>
     <string name="anr_activity_process" msgid="5776209883299089767">"Дія <xliff:g id="ACTIVITY">%1$s</xliff:g> не відповідає."\n\n"Закінчити її?"</string>
     <string name="anr_application_process" msgid="8941757607340481057">"Програма <xliff:g id="APPLICATION">%1$s</xliff:g> не відповідає. Закрити її?"</string>
-    <string name="anr_process" msgid="6513209874880517125">"Процес <xliff:g id="PROCESS">%1$s</xliff:g> не відповідає."\n\n"Закінчити його?"</string>
+    <string name="anr_process" msgid="6513209874880517125">"Процес <xliff:g id="PROCESS">%1$s</xliff:g> не відповідає."\n\n"Завершити його?"</string>
     <string name="force_close" msgid="8346072094521265605">"OK"</string>
     <string name="report" msgid="4060218260984795706">"Повідом."</string>
     <string name="wait" msgid="7147118217226317732">"Чекати"</string>
@@ -1167,7 +1169,7 @@
     <string name="activitychooserview_choose_application" msgid="2125168057199941199">"Вибрати програму"</string>
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Надіслати через"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Надіслати через <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
-    <string name="content_description_sliding_handle" msgid="415975056159262248">"Вказівник-повзунок. Торкніться й утримуйте/"</string>
+    <string name="content_description_sliding_handle" msgid="415975056159262248">"Вказівник-повзунок. Торкніться й утримуйте."</string>
     <string name="description_direction_up" msgid="1983114130441878529">"Угору, щоб <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
     <string name="description_direction_down" msgid="4294993639091088240">"Униз, щоб <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
     <string name="description_direction_left" msgid="6814008463839915747">"Ліворуч, щоб <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
@@ -1219,4 +1221,7 @@
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"Спільний доступ для:"</string>
     <string name="status_bar_device_locked" msgid="3092703448690669768">"Пристрій заблоковано."</string>
     <string name="list_delimeter" msgid="3975117572185494152">", "</string>
+    <string name="sending" msgid="8715108995741758718">"Надсилання..."</string>
+    <string name="launchBrowserDefault" msgid="2057951947297614725">"Запустити веб-переглядач?"</string>
+    <string name="SetupCallDefault" msgid="6870275517518479651">"Прийняти виклик?"</string>
 </resources>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index f0b0c96..4c3b6c1 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -32,15 +32,15 @@
     <string name="ellipsis_two_dots" msgid="1228078994866030736">"‥"</string>
     <string name="emptyPhoneNumber" msgid="7694063042079676517">"(Không có số điện thoại nào)"</string>
     <string name="unknownName" msgid="2277556546742746522">"(Không xác định)"</string>
-    <string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"Thư thoại"</string>
+    <string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"Thư thoại"</string>
     <string name="defaultMsisdnAlphaTag" msgid="2850889754919584674">"MSISDN1"</string>
     <string name="mmiError" msgid="5154499457739052907">"Sự cố kết nối hoặc mã MMI không hợp lệ."</string>
     <string name="mmiFdnError" msgid="5224398216385316471">"Chỉ hạn chế thao tác đối với số quay số định sẵn."</string>
     <string name="serviceEnabled" msgid="8147278346414714315">"Dịch vụ đã được bật."</string>
     <string name="serviceEnabledFor" msgid="6856228140453471041">"Dịch vụ đã được bật cho:"</string>
-    <string name="serviceDisabled" msgid="1937553226592516411">"Dịch vụ đã bị vô hiệu hoá."</string>
+    <string name="serviceDisabled" msgid="1937553226592516411">"Dịch vụ đã bị vô hiệu hóa."</string>
     <string name="serviceRegistered" msgid="6275019082598102493">"Đăng ký thành công."</string>
-    <string name="serviceErased" msgid="1288584695297200972">"Xoá thành công."</string>
+    <string name="serviceErased" msgid="1288584695297200972">"Xóa thành công."</string>
     <string name="passwordIncorrect" msgid="7612208839450128715">"Mật khẩu không chính xác."</string>
     <string name="mmiComplete" msgid="8232527495411698359">"MMI hoàn tất."</string>
     <string name="badPin" msgid="9015277645546710014">"Mã PIN cũ bạn đã nhập không chính xác."</string>
@@ -48,7 +48,7 @@
     <string name="mismatchPin" msgid="609379054496863419">"Mã PIN bạn đã nhập không khớp."</string>
     <string name="invalidPin" msgid="3850018445187475377">"Nhập mã PIN có từ 4 đến 8 số."</string>
     <string name="invalidPuk" msgid="8761456210898036513">"Nhập PUK có từ 8 số trở lên."</string>
-    <string name="needPuk" msgid="919668385956251611">"Thẻ SIM của bạn đã bị khoá PUK. Nhập mã PUK để mở khoá thẻ SIM đó."</string>
+    <string name="needPuk" msgid="919668385956251611">"Thẻ SIM của bạn đã bị khóa PUK. Nhập mã PUK để mở khóa thẻ SIM đó."</string>
     <string name="needPuk2" msgid="4526033371987193070">"Nhập mã PUK2 để bỏ chặn thẻ SIM."</string>
     <string name="ClipMmi" msgid="6952821216480289285">"Số gọi đến"</string>
     <string name="ClirMmi" msgid="7784673673446833091">"Số gọi đi"</string>
@@ -83,7 +83,7 @@
     <string name="serviceClassFAX" msgid="5566624998840486475">"FAX"</string>
     <string name="serviceClassSMS" msgid="2015460373701527489">"SMS"</string>
     <string name="serviceClassDataAsync" msgid="4523454783498551468">"Không đồng bộ"</string>
-    <string name="serviceClassDataSync" msgid="7530000519646054776">"Đồng bộ hoá"</string>
+    <string name="serviceClassDataSync" msgid="7530000519646054776">"Đồng bộ hóa"</string>
     <string name="serviceClassPacket" msgid="6991006557993423453">"Gói"</string>
     <string name="serviceClassPAD" msgid="3235259085648271037">"PAD"</string>
     <string name="roamingText0" msgid="7170335472198694945">"Chỉ báo Chuyển vùng Bật"</string>
@@ -124,11 +124,11 @@
     <string name="httpErrorFileNotFound" msgid="5588380756326017105">"Không tìm thấy tệp được yêu cầu."</string>
     <string name="httpErrorTooManyRequests" msgid="1235396927087188253">"Quá nhiều yêu cầu đang được xử lý. Hãy thử lại sau."</string>
     <string name="notification_title" msgid="1259940370369187045">"Lỗi đăng nhập đối với <xliff:g id="ACCOUNT">%1$s</xliff:g>"</string>
-    <string name="contentServiceSync" msgid="8353523060269335667">"Đồng bộ hoá"</string>
-    <string name="contentServiceSyncNotificationTitle" msgid="397743349191901458">"Đồng bộ hoá"</string>
-    <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"Quá nhiều lần xoá <xliff:g id="CONTENT_TYPE">%s</xliff:g>."</string>
+    <string name="contentServiceSync" msgid="8353523060269335667">"Đồng bộ hóa"</string>
+    <string name="contentServiceSyncNotificationTitle" msgid="397743349191901458">"Đồng bộ hóa"</string>
+    <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"Quá nhiều lần xóa <xliff:g id="CONTENT_TYPE">%s</xliff:g>."</string>
     <string name="low_memory" product="tablet" msgid="2292820184396262278">"Bộ nhớ máy tính bảng đã đầy! Hãy xóa một số tệp để giải phóng dung lượng."</string>
-    <string name="low_memory" product="default" msgid="6632412458436461203">"Bộ nhớ điện thoại đã đầy! Hãy xoá một số tệp để tạo thêm dung lượng."</string>
+    <string name="low_memory" product="default" msgid="6632412458436461203">"Bộ nhớ điện thoại đã đầy! Hãy xóa một số tệp để tạo thêm dung lượng."</string>
     <string name="me" msgid="6545696007631404292">"Tôi"</string>
     <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Tùy chọn máy tính bảng"</string>
     <string name="power_dialog" product="default" msgid="1319919075463988638">"Tùy chọn điện thoại"</string>
@@ -180,7 +180,7 @@
     <string name="permgrouplab_storage" msgid="1971118770546336966">"Dung lượng"</string>
     <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"Truy cập bộ nhớ USB."</string>
     <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"Truy cập thẻ SD."</string>
-    <string name="permlab_statusBar" msgid="7417192629601890791">"vô hiệu hoá hoặc sửa đổi thanh trạng thái"</string>
+    <string name="permlab_statusBar" msgid="7417192629601890791">"vô hiệu hóa hoặc sửa đổi thanh trạng thái"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Cho phép ứng dụng vô hiệu hóa thanh trạng thái hoặc thêm và xóa biểu tượng hệ thống."</string>
     <string name="permlab_statusBarService" msgid="7247281911387931485">"thanh trạng thái"</string>
     <string name="permdesc_statusBarService" msgid="716113660795976060">"Cho phép ứng dụng trở thành thanh trạng thái."</string>
@@ -234,7 +234,7 @@
     <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"Ngăn người dùng chuyển sang ứng dụng khác."</string>
     <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"giám sát và kiểm soát tất cả hoạt động khởi chạy ứng dụng"</string>
     <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"Cho phép ứng dụng giám sát và kiểm soát cách hệ thống khởi chạy các hoạt động. Ứng dụng độc hại hoàn toàn có thể làm tổn hại hệ thống. Quyền này chỉ cần cho mục đích phát triển, không dành cho mục đích sử dụng thông thường."</string>
-    <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"gửi truyền phát đã xoá của gói"</string>
+    <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"gửi truyền phát đã xóa của gói"</string>
     <string name="permdesc_broadcastPackageRemoved" msgid="6621901216207931089">"Cho phép ứng dụng truyền phát thông báo cho biết rằng gói ứng dụng đã bị xóa. Ứng dụng độc hại có thể sử dụng quyền này để loại bỏ bất kỳ ứng dụng nào khác đang chạy."</string>
     <string name="permlab_broadcastSmsReceived" msgid="5689095009030336593">"gửi truyền phát SMS nhận được"</string>
     <string name="permdesc_broadcastSmsReceived" msgid="4152037720034365492">"Cho phép ứng dụng truyền phát thông báo cho biết đã nhận được tin nhắn SMS. Ứng dụng độc hại có thể sử dụng quyền này để giả mạo tin nhắn SMS đến."</string>
@@ -301,6 +301,8 @@
     <string name="permlab_readLogs" msgid="6615778543198967614">"đọc dữ liệu nhật ký nhạy cảm"</string>
     <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"Cho phép ứng dụng đọc từ nhiều tệp nhật ký khác nhau của hệ thống. Quyền này cho phép ứng dụng phát hiện thông tin chung về những gì bạn đang thực hiện với máy tính bảng, có thể bao gồm thông tin cá nhân hoặc riêng tư."</string>
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Cho phép ứng dụng đọc từ nhiều tệp nhật ký khác nhau của hệ thống. Quyền này cho phép ứng dụng phát hiện thông tin chung về những gì bạn đang thực hiện với điện thoại, có thể bao gồm thông tin cá nhân hoặc riêng tư."</string>
+    <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"sử dụng bất kỳ bộ giải mã phương tiện nào để phát lại"</string>
+    <string name="permdesc_anyCodecForPlayback" msgid="2101444559995480174">"Cho phép ứng dụng sử dụng bất kỳ bộ giải mã phương tiện đã cài đặt nào để giải mã phát lại."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"đọc/ghi vào tài nguyên do chẩn đoán sở hữu"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Cho phép ứng dụng đọc và ghi vào bất kỳ tài nguyên nào do nhóm chẩn đoán sở hữu; ví dụ: các tệp trong /dev. Quyền này có thể ảnh hưởng đến sự ổn định và tính bảo mật của hệ thống. CHỈ nên sử dụng quyền này cho các chẩn đoán phần cứng cụ thể của nhà sản xuất hoặc nhà cung cấp."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"bật hoặc tắt cấu phần ứng dụng"</string>
@@ -357,12 +359,12 @@
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Cho phép ứng dụng đọc nội dung của bộ đệm khung."</string>
     <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"thay đổi cài đặt âm thanh của bạn"</string>
     <string name="permdesc_modifyAudioSettings" msgid="7343951185408396919">"Cho phép ứng dụng sửa đổi các cài đặt âm thanh chung chẳng hạn như âm lượng và định tuyến."</string>
-    <string name="permlab_recordAudio" msgid="3876049771427466323">"ghi âm thanh"</string>
-    <string name="permdesc_recordAudio" msgid="2387462233976248635">"Cho phép ứng dụng truy cập đường dẫn đến bản ghi âm thanh."</string>
+    <string name="permlab_recordAudio" msgid="3876049771427466323">"ghi âm"</string>
+    <string name="permdesc_recordAudio" msgid="2387462233976248635">"Cho phép ứng dụng truy cập đường dẫn đến bản ghi âm."</string>
     <string name="permlab_camera" msgid="3616391919559751192">"chụp ảnh và quay video"</string>
     <string name="permdesc_camera" msgid="1507407407002492176">"Cho phép ứng dụng chụp ảnh và quay video bằng máy ảnh. Quyền này cho phép ứng dụng thu thập hình ảnh mà máy ảnh chụp/quay bất cứ lúc nào."</string>
     <string name="permlab_brick" product="tablet" msgid="2961292205764488304">"vô hiệu hóa vĩnh viễn máy tính bảng"</string>
-    <string name="permlab_brick" product="default" msgid="8337817093326370537">"vĩnh viễn vô hiệu hoá điện thoại"</string>
+    <string name="permlab_brick" product="default" msgid="8337817093326370537">"vĩnh viễn vô hiệu hóa điện thoại"</string>
     <string name="permdesc_brick" product="tablet" msgid="4334818808001699530">"Cho phép ứng dụng vô hiệu hóa vĩnh viễn toàn bộ máy tính bảng. Điều này rất nguy hiểm."</string>
     <string name="permdesc_brick" product="default" msgid="5788903297627283099">"Cho phép ứng dụng vô hiệu hóa vĩnh viễn toàn bộ điện thoại. Điều này rất nguy hiểm."</string>
     <string name="permlab_reboot" product="tablet" msgid="3436634972561795002">"buộc máy tính bảng khởi động lại"</string>
@@ -465,22 +467,22 @@
     <string name="permlab_bluetoothAdmin" msgid="3606576270792236062">"Quản trị Bluetooth"</string>
     <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"Cho phép ứng dụng định cấu hình máy tính bảng Bluetooth cục bộ cũng như phát hiện và ghép nối với các thiết bị từ xa."</string>
     <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"Cho phép ứng dụng định cấu hình điện thoại Bluetooth cục bộ cũng như phát hiện và ghép nối với các thiết bị từ xa."</string>
-    <!-- outdated translation 2800410363171809280 -->     <string name="permlab_accessWimaxState" msgid="1232061307208861588">"xem trạng thái WiMAX"</string>
+    <string name="permlab_accessWimaxState" msgid="1232061307208861588">"Xem trạng thái WiMAX"</string>
     <string name="permdesc_accessWimaxState" msgid="8298035866227524023">"Cho phép ứng dụng xem thông tin về trạng thái của WiMAX."</string>
-    <!-- outdated translation 340465839241528618 -->     <string name="permlab_changeWimaxState" msgid="2405042267131496579">"thay đổi trạng thái WiMAX"</string>
+    <string name="permlab_changeWimaxState" msgid="2405042267131496579">"Thay đổi trạng thái WiMAX"</string>
     <string name="permdesc_changeWimaxState" msgid="474918005058989421">"Cho phép ứng dụng kết nối và ngắt kết nối khỏi mạng WiMAX."</string>
     <string name="permlab_bluetooth" msgid="8361038707857018732">"tạo kết nối Bluetooth"</string>
     <string name="permdesc_bluetooth" product="tablet" msgid="7007851048416363446">"Cho phép ứng dụng xem cấu hình của máy tính bảng Bluetooth cục bộ cũng như tạo và chấp nhận các kết nối với thiết bị được ghép nối."</string>
     <string name="permdesc_bluetooth" product="default" msgid="31846362767164948">"Cho phép ứng dụng xem cấu hình của điện thoại Bluetooth cục bộ cũng như tạo và chấp nhận các kết nối với thiết bị được ghép nối."</string>
     <string name="permlab_nfc" msgid="4423351274757876953">"kiểm soát Liên lạc trường gần"</string>
     <string name="permdesc_nfc" msgid="7120611819401789907">"Cho phép ứng dụng giao tiếp với thẻ Giao tiếp trường gần (NFC), thẻ và trình đọc."</string>
-    <string name="permlab_disableKeyguard" msgid="4977406164311535092">"vô hiệu hoá khoá phím"</string>
+    <string name="permlab_disableKeyguard" msgid="4977406164311535092">"vô hiệu hóa khóa phím"</string>
     <string name="permdesc_disableKeyguard" msgid="6231611286892232626">"Cho phép ứng dụng tắt khóa phím và bất kỳ bảo mật mật khẩu được liên kết nào. Ví dụ thích hợp của việc này là điện thoại tắt khóa phím khi nhận được cuộc gọi đến, sau đó bật lại khóa phím khi cuộc gọi kết thúc."</string>
-    <string name="permlab_readSyncSettings" msgid="6201810008230503052">"đọc cài đặt đồng bộ hoá"</string>
+    <string name="permlab_readSyncSettings" msgid="6201810008230503052">"đọc cài đặt đồng bộ hóa"</string>
     <string name="permdesc_readSyncSettings" msgid="5464056785274229278">"Cho phép ứng dụng đọc cài đặt đồng bộ hóa, chẳng hạn như liệu đồng bộ hóa đã được bật cho ứng dụng Liên hệ hay chưa."</string>
-    <string name="permlab_writeSyncSettings" msgid="6297138566442486462">"ghi cài đặt đồng bộ hoá"</string>
+    <string name="permlab_writeSyncSettings" msgid="6297138566442486462">"ghi cài đặt đồng bộ hóa"</string>
     <string name="permdesc_writeSyncSettings" msgid="1466056564502117130">"Cho phép ứng dụng sửa đổi cài đặt đồng bộ hóa, chẳng hạn như có bật đồng bộ hóa cho ứng dụng Liên hệ hay không."</string>
-    <string name="permlab_readSyncStats" msgid="7396577451360202448">"đọc thống kê đồng bộ hoá"</string>
+    <string name="permlab_readSyncStats" msgid="7396577451360202448">"đọc thống kê đồng bộ hóa"</string>
     <string name="permdesc_readSyncStats" msgid="3801971839939951678">"Cho phép ứng dụng đọc các số liệu thống kê về đồng bộ hóa; ví dụ: lịch sử đồng bộ hóa đã diễn ra."</string>
     <string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"đọc nguồn cấp dữ liệu đã đăng ký"</string>
     <string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Cho phép ứng dụng lấy thông tin chi tiết về nguồn cấp dữ liệu hiện được đồng bộ hóa."</string>
@@ -491,7 +493,7 @@
     <string name="permlab_writeDictionary" msgid="2296383164914812772">"ghi vào từ điển do người dùng xác định"</string>
     <string name="permdesc_writeDictionary" msgid="8185385716255065291">"Cho phép ứng dụng ghi từ mới vào từ điển của người dùng."</string>
     <string name="permlab_sdcardWrite" product="nosdcard" msgid="85430876310764752">"sửa đổi/xóa nội dung bộ nhớ USB"</string>
-    <string name="permlab_sdcardWrite" product="default" msgid="8079403759001777291">"sửa đổi/xoá nội dung thẻ SD"</string>
+    <string name="permlab_sdcardWrite" product="default" msgid="8079403759001777291">"sửa đổi/xóa nội dung thẻ SD"</string>
     <string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"Cho phép ứng dụng ghi vào bộ lưu trữ USB."</string>
     <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Cho phép ứng dụng ghi vào thẻ SD."</string>
     <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"sửa đổi/xóa nội dung trên bộ nhớ phương tiện cục bộ"</string>
@@ -515,7 +517,7 @@
     <string name="policydesc_resetPassword" msgid="5391240616981297361">"Thay đổi mật khẩu mở khóa màn hình"</string>
     <string name="policylab_forceLock" msgid="2274085384704248431">"Khóa màn hình"</string>
     <string name="policydesc_forceLock" msgid="5696964126226028442">"Kiểm tra cách và thời điểm khóa màn hình"</string>
-    <string name="policylab_wipeData" msgid="3910545446758639713">"Xoá tất cả dữ liệu"</string>
+    <string name="policylab_wipeData" msgid="3910545446758639713">"Xóa tất cả dữ liệu"</string>
     <string name="policydesc_wipeData" product="tablet" msgid="314455232799486222">"Xóa dữ liệu trên máy tính bảng mà không cần cảnh báo, bằng cách thực hiện đặt lại về dữ liệu gốc"</string>
     <string name="policydesc_wipeData" product="default" msgid="7669895333814222586">"Xóa dữ liệu trên điện thoại mà không cần cảnh báo, bằng cách thực hiện đặt lại về dữ liệu gốc"</string>
     <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"Đặt proxy chung của điện thoại"</string>
@@ -530,34 +532,34 @@
     <item msgid="8901098336658710359">"Nhà riêng"</item>
     <item msgid="869923650527136615">"ĐT di động"</item>
     <item msgid="7897544654242874543">"Cơ quan"</item>
-    <item msgid="1103601433382158155">"Số fax Cơ quan"</item>
-    <item msgid="1735177144948329370">"Số fax Nhà riêng"</item>
-    <item msgid="603878674477207394">"Số máy nhắn tin"</item>
+    <item msgid="1103601433382158155">"Số fax Cơ quan"</item>
+    <item msgid="1735177144948329370">"Số fax Nhà riêng"</item>
+    <item msgid="603878674477207394">"Số máy nhắn tin"</item>
     <item msgid="1650824275177931637">"Khác"</item>
-    <item msgid="9192514806975898961">"Tùy chỉnh"</item>
+    <item msgid="9192514806975898961">"Tùy chỉnh"</item>
   </string-array>
   <string-array name="emailAddressTypes">
     <item msgid="8073994352956129127">"Nhà riêng"</item>
     <item msgid="7084237356602625604">"Cơ quan"</item>
     <item msgid="1112044410659011023">"Khác"</item>
-    <item msgid="2374913952870110618">"Tùy chỉnh"</item>
+    <item msgid="2374913952870110618">"Tùy chỉnh"</item>
   </string-array>
   <string-array name="postalAddressTypes">
     <item msgid="6880257626740047286">"Nhà riêng"</item>
     <item msgid="5629153956045109251">"Cơ quan"</item>
     <item msgid="4966604264500343469">"Khác"</item>
-    <item msgid="4932682847595299369">"Tùy chỉnh"</item>
+    <item msgid="4932682847595299369">"Tùy chỉnh"</item>
   </string-array>
   <string-array name="imAddressTypes">
     <item msgid="1738585194601476694">"Nhà riêng"</item>
     <item msgid="1359644565647383708">"Cơ quan"</item>
     <item msgid="7868549401053615677">"Khác"</item>
-    <item msgid="3145118944639869809">"Tùy chỉnh"</item>
+    <item msgid="3145118944639869809">"Tùy chỉnh"</item>
   </string-array>
   <string-array name="organizationTypes">
     <item msgid="7546335612189115615">"Cơ quan"</item>
     <item msgid="4378074129049520373">"Khác"</item>
-    <item msgid="3455047468583965104">"Tùy chỉnh"</item>
+    <item msgid="3455047468583965104">"Tùy chỉnh"</item>
   </string-array>
   <string-array name="imProtocols">
     <item msgid="8595261363518459565">"AIM"</item>
@@ -569,13 +571,13 @@
     <item msgid="2506857312718630823">"ICQ"</item>
     <item msgid="1648797903785279353">"Jabber"</item>
   </string-array>
-    <string name="phoneTypeCustom" msgid="1644738059053355820">"Tùy chỉnh"</string>
+    <string name="phoneTypeCustom" msgid="1644738059053355820">"Tùy chỉnh"</string>
     <string name="phoneTypeHome" msgid="2570923463033985887">"Nhà riêng"</string>
     <string name="phoneTypeMobile" msgid="6501463557754751037">"ĐT di động"</string>
     <string name="phoneTypeWork" msgid="8863939667059911633">"Cơ quan"</string>
-    <string name="phoneTypeFaxWork" msgid="3517792160008890912">"Số fax Cơ quan"</string>
-    <string name="phoneTypeFaxHome" msgid="2067265972322971467">"Số fax Nhà riêng"</string>
-    <string name="phoneTypePager" msgid="7582359955394921732">"Số máy nhắn tin"</string>
+    <string name="phoneTypeFaxWork" msgid="3517792160008890912">"Số fax Cơ quan"</string>
+    <string name="phoneTypeFaxHome" msgid="2067265972322971467">"Số fax Nhà riêng"</string>
+    <string name="phoneTypePager" msgid="7582359955394921732">"Số máy nhắn tin"</string>
     <string name="phoneTypeOther" msgid="1544425847868765990">"Khác"</string>
     <string name="phoneTypeCallback" msgid="2712175203065678206">"Số gọi lại"</string>
     <string name="phoneTypeCar" msgid="8738360689616716982">"Ô tô"</string>
@@ -590,24 +592,24 @@
     <string name="phoneTypeWorkPager" msgid="649938731231157056">"Số Máy nhắn tin tại Cơ quan"</string>
     <string name="phoneTypeAssistant" msgid="5596772636128562884">"Số điện thoại Hỗ trợ"</string>
     <string name="phoneTypeMms" msgid="7254492275502768992">"MMS"</string>
-    <string name="eventTypeCustom" msgid="7837586198458073404">"Tùy chỉnh"</string>
+    <string name="eventTypeCustom" msgid="7837586198458073404">"Tùy chỉnh"</string>
     <string name="eventTypeBirthday" msgid="2813379844211390740">"Ngày sinh"</string>
     <string name="eventTypeAnniversary" msgid="3876779744518284000">"Ngày kỷ niệm"</string>
     <string name="eventTypeOther" msgid="7388178939010143077">"Khác"</string>
-    <string name="emailTypeCustom" msgid="8525960257804213846">"Tùy chỉnh"</string>
+    <string name="emailTypeCustom" msgid="8525960257804213846">"Tùy chỉnh"</string>
     <string name="emailTypeHome" msgid="449227236140433919">"Nhà riêng"</string>
     <string name="emailTypeWork" msgid="3548058059601149973">"Cơ quan"</string>
     <string name="emailTypeOther" msgid="2923008695272639549">"Khác"</string>
     <string name="emailTypeMobile" msgid="119919005321166205">"ĐT di động"</string>
-    <string name="postalTypeCustom" msgid="8903206903060479902">"Tùy chỉnh"</string>
+    <string name="postalTypeCustom" msgid="8903206903060479902">"Tùy chỉnh"</string>
     <string name="postalTypeHome" msgid="8165756977184483097">"Nhà riêng"</string>
     <string name="postalTypeWork" msgid="5268172772387694495">"Cơ quan"</string>
     <string name="postalTypeOther" msgid="2726111966623584341">"Khác"</string>
-    <string name="imTypeCustom" msgid="2074028755527826046">"Tùy chỉnh"</string>
+    <string name="imTypeCustom" msgid="2074028755527826046">"Tùy chỉnh"</string>
     <string name="imTypeHome" msgid="6241181032954263892">"Nhà riêng"</string>
     <string name="imTypeWork" msgid="1371489290242433090">"Cơ quan"</string>
     <string name="imTypeOther" msgid="5377007495735915478">"Khác"</string>
-    <string name="imProtocolCustom" msgid="6919453836618749992">"Tùy chỉnh"</string>
+    <string name="imProtocolCustom" msgid="6919453836618749992">"Tùy chỉnh"</string>
     <string name="imProtocolAim" msgid="7050360612368383417">"AIM"</string>
     <string name="imProtocolMsn" msgid="144556545420769442">"Windows Live"</string>
     <string name="imProtocolYahoo" msgid="8271439408469021273">"Yahoo"</string>
@@ -619,8 +621,8 @@
     <string name="imProtocolNetMeeting" msgid="8287625655986827971">"NetMeeting"</string>
     <string name="orgTypeWork" msgid="29268870505363872">"Cơ quan"</string>
     <string name="orgTypeOther" msgid="3951781131570124082">"Khác"</string>
-    <string name="orgTypeCustom" msgid="225523415372088322">"Tùy chỉnh"</string>
-    <string name="relationTypeCustom" msgid="3542403679827297300">"Tùy chỉnh"</string>
+    <string name="orgTypeCustom" msgid="225523415372088322">"Tùy chỉnh"</string>
+    <string name="relationTypeCustom" msgid="3542403679827297300">"Tùy chỉnh"</string>
     <string name="relationTypeAssistant" msgid="6274334825195379076">"Trợ lý"</string>
     <string name="relationTypeBrother" msgid="8757913506784067713">"Anh em trai"</string>
     <string name="relationTypeChild" msgid="1890746277276881626">"Con cái"</string>
@@ -635,8 +637,8 @@
     <string name="relationTypeRelative" msgid="1799819930085610271">"Họ hàng"</string>
     <string name="relationTypeSister" msgid="1735983554479076481">"Chị em gái"</string>
     <string name="relationTypeSpouse" msgid="394136939428698117">"Vợ/chồng"</string>
-    <string name="sipAddressTypeCustom" msgid="2473580593111590945">"Tùy chỉnh"</string>
-    <string name="sipAddressTypeHome" msgid="6093598181069359295">"Nhà riêng"</string>
+    <string name="sipAddressTypeCustom" msgid="2473580593111590945">"Tùy chỉnh"</string>
+    <string name="sipAddressTypeHome" msgid="6093598181069359295">"Nhà riêng"</string>
     <string name="sipAddressTypeWork" msgid="6920725730797099047">"Cơ quan"</string>
     <string name="sipAddressTypeOther" msgid="4408436162950119849">"Khác"</string>
     <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Nhập mã PIN"</string>
@@ -647,13 +649,13 @@
     <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Nhập mật khẩu để mở khóa"</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Nhập mã PIN để mở khóa"</string>
     <string name="keyguard_password_wrong_pin_code" msgid="1295984114338107718">"Mã PIN không chính xác!"</string>
-    <string name="keyguard_label_text" msgid="861796461028298424">"Để mở khoá, hãy nhấn vào Trình đơn sau đó nhấn 0."</string>
+    <string name="keyguard_label_text" msgid="861796461028298424">"Để mở khóa, hãy nhấn vào Trình đơn sau đó nhấn 0."</string>
     <string name="emergency_call_dialog_number_for_display" msgid="696192103195090970">"Số khẩn cấp"</string>
     <string name="lockscreen_carrier_default" msgid="8963839242565653192">"Không có dịch vụ nào."</string>
-    <string name="lockscreen_screen_locked" msgid="7288443074806832904">"Màn hình đã khoá."</string>
-    <string name="lockscreen_instructions_when_pattern_enabled" msgid="46154051614126049">"Nhấn vào Trình đơn để mở khoá hoặc thực hiện cuộc gọi khẩn cấp."</string>
-    <string name="lockscreen_instructions_when_pattern_disabled" msgid="686260028797158364">"Nhấn vào Trình đơn để mở khoá."</string>
-    <string name="lockscreen_pattern_instructions" msgid="7478703254964810302">"Vẽ hình để mở khoá"</string>
+    <string name="lockscreen_screen_locked" msgid="7288443074806832904">"Màn hình đã khóa."</string>
+    <string name="lockscreen_instructions_when_pattern_enabled" msgid="46154051614126049">"Nhấn vào Trình đơn để mở khóa hoặc thực hiện cuộc gọi khẩn cấp."</string>
+    <string name="lockscreen_instructions_when_pattern_disabled" msgid="686260028797158364">"Nhấn vào Trình đơn để mở khóa."</string>
+    <string name="lockscreen_pattern_instructions" msgid="7478703254964810302">"Vẽ hình để mở khóa"</string>
     <string name="lockscreen_emergency_call" msgid="5347633784401285225">"Cuộc gọi khẩn cấp"</string>
     <string name="lockscreen_return_to_call" msgid="5244259785500040021">"Quay lại cuộc gọi"</string>
     <string name="lockscreen_pattern_correct" msgid="9039008650362261237">"Chính xác!"</string>
@@ -675,11 +677,11 @@
     <string name="lockscreen_transport_play_description" msgid="5888422938351019426">"Nút phát"</string>
     <string name="lockscreen_transport_stop_description" msgid="4562318378766987601">"Nút dừng"</string>
     <string name="emergency_calls_only" msgid="6733978304386365407">"Chỉ cuộc gọi khẩn cấp"</string>
-    <string name="lockscreen_network_locked_message" msgid="143389224986028501">"Mạng đã khoá"</string>
-    <string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"Thẻ SIM đã bị khoá PUK."</string>
+    <string name="lockscreen_network_locked_message" msgid="143389224986028501">"Mạng đã khóa"</string>
+    <string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"Thẻ SIM đã bị khóa PUK."</string>
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Vui lòng xem Hướng dẫn người dùng hoặc liên hệ với Bộ phận chăm sóc khách hàng."</string>
-    <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"Thẻ SIM đã bị khoá."</string>
-    <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"Đang mở khoá thẻ SIM…"</string>
+    <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"Thẻ SIM đã bị khóa."</string>
+    <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"Đang mở khóa thẻ SIM…"</string>
     <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Bạn đã <xliff:g id="NUMBER_0">%d</xliff:g> lần vẽ không chính xác hình mở khóa của mình. "\n\n"Vui lòng thử lại sau <xliff:g id="NUMBER_1">%d</xliff:g> giây."</string>
     <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Bạn đã <xliff:g id="NUMBER_0">%d</xliff:g> lần nhập sai mật khẩu. Hãy "\n\n"thử lại sau <xliff:g id="NUMBER_1">%d</xliff:g> giây."</string>
     <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Bạn đã nhập sai mã PIN <xliff:g id="NUMBER_0">%d</xliff:g> lần. "\n\n"Hãy thử lại sau <xliff:g id="NUMBER_1">%d</xliff:g> giây."</string>
@@ -691,16 +693,16 @@
     <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"Bạn đã mở khóa điện thoại không đúng cách <xliff:g id="NUMBER">%d</xliff:g> lần. Bây giờ, điện thoại sẽ được đặt lại về mặc định ban đầu."</string>
     <string name="lockscreen_too_many_failed_attempts_countdown" msgid="6251480343394389665">"Hãy thử lại sau <xliff:g id="NUMBER">%d</xliff:g> giây."</string>
     <string name="lockscreen_forgot_pattern_button_text" msgid="2626999449610695930">"Đã quên hình?"</string>
-    <string name="lockscreen_glogin_forgot_pattern" msgid="2588521501166032747">"Mở khoá tài khoản"</string>
+    <string name="lockscreen_glogin_forgot_pattern" msgid="2588521501166032747">"Mở khóa tài khoản"</string>
     <string name="lockscreen_glogin_too_many_attempts" msgid="2446246026221678244">"Quá nhiều lần nhập hình!"</string>
-    <string name="lockscreen_glogin_instructions" msgid="1816635201812207709">"Để mở khoá, hãy đăng nhập bằng tài khoản Google của bạn"</string>
+    <string name="lockscreen_glogin_instructions" msgid="1816635201812207709">"Để mở khóa, hãy đăng nhập bằng tài khoản Google của bạn"</string>
     <string name="lockscreen_glogin_username_hint" msgid="8846881424106484447">"Tên người dùng (email)"</string>
     <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Mật khẩu"</string>
     <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Đăng nhập"</string>
     <string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Tên người dùng hoặc mật khẩu không hợp lệ."</string>
     <string name="lockscreen_glogin_account_recovery_hint" msgid="8253152905532900548">"Bạn quên tên người dùng hoặc mật khẩu?"\n"Hãy truy cập "<b>"google.com/accounts/recovery"</b></string>
-    <string name="lockscreen_glogin_checking_password" msgid="6758890536332363322">"Đang kiểm tra..."</string>
-    <string name="lockscreen_unlock_label" msgid="737440483220667054">"Mở khoá"</string>
+    <string name="lockscreen_glogin_checking_password" msgid="6758890536332363322">"Đang kiểm tra..."</string>
+    <string name="lockscreen_unlock_label" msgid="737440483220667054">"Mở khóa"</string>
     <string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Bật âm thanh"</string>
     <string name="lockscreen_sound_off_label" msgid="996822825154319026">"Tắt âm thanh"</string>
     <string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"Đã bắt đầu vẽ hình"</string>
@@ -764,12 +766,12 @@
     <string name="prepend_shortcut_label" msgid="2572214461676015642">"Trình đơn+"</string>
     <string name="menu_space_shortcut_label" msgid="2410328639272162537">"dấu cách"</string>
     <string name="menu_enter_shortcut_label" msgid="2743362785111309668">"nhập"</string>
-    <string name="menu_delete_shortcut_label" msgid="3658178007202748164">"xoá"</string>
+    <string name="menu_delete_shortcut_label" msgid="3658178007202748164">"xóa"</string>
     <string name="search_go" msgid="8298016669822141719">"Tìm kiếm"</string>
     <string name="searchview_description_search" msgid="6749826639098512120">"Tìm kiếm"</string>
     <string name="searchview_description_query" msgid="5911778593125355124">"Truy vấn tìm kiếm"</string>
     <string name="searchview_description_clear" msgid="1330281990951833033">"Xóa truy vấn"</string>
-    <string name="searchview_description_submit" msgid="2688450133297983542">"Gửi truy vấn"</string>
+    <string name="searchview_description_submit" msgid="2688450133297983542">"Gửi truy vấn"</string>
     <string name="searchview_description_voice" msgid="2453203695674994440">"Tìm kiếm bằng giọng nói"</string>
     <string name="oneMonthDurationPast" msgid="7396384508953779925">"1 tháng trước"</string>
     <string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Trước 1 tháng trước"</string>
@@ -779,7 +781,7 @@
   </plurals>
   <plurals name="num_minutes_ago">
     <item quantity="one" msgid="3306787433088810191">"1 phút trước"</item>
-    <item quantity="other" msgid="2176942008915455116">"<xliff:g id="COUNT">%d</xliff:g> phút trước"</item>
+    <item quantity="other" msgid="2176942008915455116">"<xliff:g id="COUNT">%d</xliff:g> phút trước"</item>
   </plurals>
   <plurals name="num_hours_ago">
     <item quantity="one" msgid="9150797944610821849">"1 giờ trước"</item>
@@ -843,7 +845,7 @@
     <item quantity="other" msgid="2973062968038355991">"trong <xliff:g id="COUNT">%d</xliff:g> ngày"</item>
   </plurals>
     <string name="preposition_for_date" msgid="9093949757757445117">"vào <xliff:g id="DATE">%s</xliff:g>"</string>
-    <string name="preposition_for_time" msgid="5506831244263083793">"vào lúc <xliff:g id="TIME">%s</xliff:g>"</string>
+    <string name="preposition_for_time" msgid="5506831244263083793">"vào lúc <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="preposition_for_year" msgid="5040395640711867177">"trong <xliff:g id="YEAR">%s</xliff:g>"</string>
     <string name="day" msgid="8144195776058119424">"ngày"</string>
     <string name="days" msgid="4774547661021344602">"ngày"</string>
@@ -853,7 +855,7 @@
     <string name="minutes" msgid="5646001005827034509">"phút"</string>
     <string name="second" msgid="3184235808021478">"giây"</string>
     <string name="seconds" msgid="3161515347216589235">"giây"</string>
-    <string name="week" msgid="5617961537173061583">"tuần"</string>
+    <string name="week" msgid="5617961537173061583">"tuần"</string>
     <string name="weeks" msgid="6509623834583944518">"tuần"</string>
     <string name="year" msgid="4001118221013892076">"năm"</string>
     <string name="years" msgid="6881577717993213522">"năm"</string>
@@ -868,7 +870,7 @@
     <string name="Midnight" msgid="5630806906897892201">"Nửa đêm"</string>
     <string name="elapsed_time_short_format_mm_ss" msgid="4431555943828711473">"<xliff:g id="MINUTES">%1$02d</xliff:g>:<xliff:g id="SECONDS">%2$02d</xliff:g>"</string>
     <string name="elapsed_time_short_format_h_mm_ss" msgid="1846071997616654124">"<xliff:g id="HOURS">%1$d</xliff:g>:<xliff:g id="MINUTES">%2$02d</xliff:g>:<xliff:g id="SECONDS">%3$02d</xliff:g>"</string>
-    <string name="selectAll" msgid="6876518925844129331">"Chọn tất cả"</string>
+    <string name="selectAll" msgid="6876518925844129331">"Chọn tất cả"</string>
     <string name="cut" msgid="3092569408438626261">"Cắt"</string>
     <string name="copy" msgid="2681946229533511987">"Sao chép"</string>
     <string name="paste" msgid="5629880836805036433">"Dán"</string>
@@ -904,7 +906,7 @@
     <string name="anr_title" msgid="4351948481459135709"></string>
     <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> hiện không phản hồi."\n\n"Bạn có muốn đóng ứng dụng này không?"</string>
     <string name="anr_activity_process" msgid="5776209883299089767">"Hoạt động <xliff:g id="ACTIVITY">%1$s</xliff:g> không phản hồi."\n\n"Bạn có muốn đóng ứng dụng này không?"</string>
-    <string name="anr_application_process" msgid="8941757607340481057">"<xliff:g id="APPLICATION">%1$s</xliff:g> hiện không phản hồi. Bạn có muốn đóng ứng dụng không?"</string>
+    <string name="anr_application_process" msgid="8941757607340481057">"<xliff:g id="APPLICATION">%1$s</xliff:g> hiện không phản hồi. Bạn có muốn đóng ứng dụng không?"</string>
     <string name="anr_process" msgid="6513209874880517125">"Quá trình <xliff:g id="PROCESS">%1$s</xliff:g> hiện không phản hồi."\n\n"Bạn có muốn đóng ứng dụng này không?"</string>
     <string name="force_close" msgid="8346072094521265605">"OK"</string>
     <string name="report" msgid="4060218260984795706">"Báo cáo"</string>
@@ -1058,7 +1060,7 @@
     <string name="gadget_host_error_inflating" msgid="2613287218853846830">"Lỗi khi gia tăng tiện ích"</string>
     <string name="ime_action_go" msgid="8320845651737369027">"Đến"</string>
     <string name="ime_action_search" msgid="658110271822807811">"Tìm kiếm"</string>
-    <string name="ime_action_send" msgid="2316166556349314424">"Gửi"</string>
+    <string name="ime_action_send" msgid="2316166556349314424">"Gửi"</string>
     <string name="ime_action_next" msgid="3138843904009813834">"Tiếp theo"</string>
     <string name="ime_action_done" msgid="8971516117910934605">"Xong"</string>
     <string name="ime_action_previous" msgid="1443550039250105948">"Trước"</string>
@@ -1073,7 +1075,7 @@
     <string name="permission_request_notification_title" msgid="5390555465778213840">"Yêu cầu Quyền"</string>
     <string name="permission_request_notification_with_subtitle" msgid="4325409589686688000">"Yêu cầu Quyền"\n"cho tài khoản <xliff:g id="ACCOUNT">%s</xliff:g>"</string>
     <string name="input_method_binding_label" msgid="1283557179944992649">"Phương thức nhập"</string>
-    <string name="sync_binding_label" msgid="3687969138375092423">"Đồng bộ hoá"</string>
+    <string name="sync_binding_label" msgid="3687969138375092423">"Đồng bộ hóa"</string>
     <string name="accessibility_binding_label" msgid="4148120742096474641">"Khả năng truy cập"</string>
     <string name="wallpaper_binding_label" msgid="1240087844304687662">"Hình nền"</string>
     <string name="chooser_wallpaper" msgid="7873476199295190279">"Thay đổi hình nền"</string>
@@ -1084,7 +1086,7 @@
     <string name="upload_file" msgid="2897957172366730416">"Chọn tệp"</string>
     <string name="no_file_chosen" msgid="6363648562170759465">"Không có tệp nào được chọn"</string>
     <string name="reset" msgid="2448168080964209908">"Đặt lại"</string>
-    <string name="submit" msgid="1602335572089911941">"Gửi"</string>
+    <string name="submit" msgid="1602335572089911941">"Gửi"</string>
     <string name="car_mode_disable_notification_title" msgid="3164768212003864316">"Chế độ trên ô tô đã được bật"</string>
     <string name="car_mode_disable_notification_message" msgid="668663626721675614">"Chọn để thoát khỏi chế độ trên ô tô."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Chức năng điểm truy cập Internet hoặc điểm phát sóng đang hoạt động"</string>
@@ -1219,4 +1221,7 @@
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"Chia sẻ với"</string>
     <string name="status_bar_device_locked" msgid="3092703448690669768">"Thiết bị đã bị khóa."</string>
     <string name="list_delimeter" msgid="3975117572185494152">", "</string>
+    <string name="sending" msgid="8715108995741758718">"Đang gửi..."</string>
+    <string name="launchBrowserDefault" msgid="2057951947297614725">"Khởi chạy trình duyệt?"</string>
+    <string name="SetupCallDefault" msgid="6870275517518479651">"Chấp nhận cuộc gọi?"</string>
 </resources>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index fd938be..7f3c363 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -301,6 +301,8 @@
     <string name="permlab_readLogs" msgid="6615778543198967614">"查阅敏感日志数据"</string>
     <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"允许应用程序从系统的各种日志文件中读取信息。这样,应用程序就可以发现关于您平板电脑使用情况的一般信息,其中可能包含个人信息或隐私信息。"</string>
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"允许应用程序从系统的各个日志文件中读取信息。这样,应用程序就可以发现关于您手机使用情况的一般信息,其中可能包含个人信息或隐私信息。"</string>
+    <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"使用任何媒体解码器进行播放"</string>
+    <string name="permdesc_anyCodecForPlayback" msgid="2101444559995480174">"允许应用程序使用任何已安装的媒体解码器进行解码,以便播放。"</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"读取/写入诊断所拥有的资源"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"允许应用程序读取/写入诊断组拥有的所有资源(例如 /dev 中的文件)。这可能会影响系统的稳定性和安全性。此权限仅供制造商或运营商诊断硬件方面的问题时使用。"</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"启用或停用应用程序组件"</string>
@@ -317,9 +319,9 @@
     <string name="permlab_receiveBootCompleted" msgid="7776779842866993377">"开机时自动启动"</string>
     <string name="permdesc_receiveBootCompleted" product="tablet" msgid="7390304664116880704">"允许应用程序在系统完成引导后立即自动启动。这样可能会延长平板电脑的启动时间,并允许应用程序始终运行,从而导致平板电脑总体运行速度减慢。"</string>
     <string name="permdesc_receiveBootCompleted" product="default" msgid="513950589102617504">"允许应用程序在系统完成引导后立即自动启动。这样可能会延长手机的启动时间,并允许应用程序始终运行,从而导致手机总体运行速度减慢。"</string>
-    <string name="permlab_broadcastSticky" msgid="7919126372606881614">"发送置顶广播"</string>
-    <string name="permdesc_broadcastSticky" product="tablet" msgid="1181582512022829259">"允许应用程序发送置顶广播,此类广播在结束后仍会保留。恶意应用程序可能会导致平板电脑使用过多内存,从而使速度变慢或变得不稳定。"</string>
-    <string name="permdesc_broadcastSticky" product="default" msgid="3287869131621514325">"允许应用程序发送置顶广播,此类广播在结束后仍会保留。恶意应用程序可能会导致手机使用过多内存,从而使速度变慢或变得不稳定。"</string>
+    <string name="permlab_broadcastSticky" msgid="7919126372606881614">"发送持久广播"</string>
+    <string name="permdesc_broadcastSticky" product="tablet" msgid="1181582512022829259">"允许应用程序发送持久广播,此类广播在结束后仍会保留。恶意应用程序可能会导致平板电脑使用过多内存,从而使速度变慢或变得不稳定。"</string>
+    <string name="permdesc_broadcastSticky" product="default" msgid="3287869131621514325">"允许应用程序发送持久广播,此类广播在结束后仍会保留。恶意应用程序可能会导致手机使用过多内存,从而使速度变慢或变得不稳定。"</string>
     <string name="permlab_readContacts" msgid="6219652189510218240">"读取联系人数据"</string>
     <string name="permdesc_readContacts" product="tablet" msgid="4028657556924039119">"允许应用程序读取您平板电脑上存储的所有联系人(地址)数据。恶意应用程序可能借此将您的数据发送给其他人。"</string>
     <string name="permdesc_readContacts" product="default" msgid="2032222056456498547">"允许应用程序读取您手机上存储的所有联系人(地址)数据。恶意应用程序可能借此将您的数据发送给其他人。"</string>
@@ -465,9 +467,9 @@
     <string name="permlab_bluetoothAdmin" msgid="3606576270792236062">"蓝牙管理"</string>
     <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"允许应用程序配置本地蓝牙平板电脑,以及发现远程设备并进行配对。"</string>
     <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"允许应用程序配置本地蓝牙手机,以及发现远程设备并进行配对。"</string>
-    <!-- outdated translation 2800410363171809280 -->     <string name="permlab_accessWimaxState" msgid="1232061307208861588">"查看 WiMAX 状态"</string>
+    <string name="permlab_accessWimaxState" msgid="1232061307208861588">"查看 WiMAX 状态"</string>
     <string name="permdesc_accessWimaxState" msgid="8298035866227524023">"允许应用程序查看有关 WiMAX 状态的信息。"</string>
-    <!-- outdated translation 340465839241528618 -->     <string name="permlab_changeWimaxState" msgid="2405042267131496579">"更改 WiMAX 状态"</string>
+    <string name="permlab_changeWimaxState" msgid="2405042267131496579">"更改 WiMAX 状态"</string>
     <string name="permdesc_changeWimaxState" msgid="474918005058989421">"允许应用程序连接到 WiMAX 网络以及从 WiMAX 网络断开连接。"</string>
     <string name="permlab_bluetooth" msgid="8361038707857018732">"创建蓝牙连接"</string>
     <string name="permdesc_bluetooth" product="tablet" msgid="7007851048416363446">"允许应用程序查看本地蓝牙平板电脑的配置,以及建立和接受与配对设备的连接。"</string>
@@ -902,10 +904,10 @@
     <string name="aerr_application" msgid="932628488013092776">"很抱歉,“<xliff:g id="APPLICATION">%1$s</xliff:g>”已停止运行。"</string>
     <string name="aerr_process" msgid="4507058997035697579">"抱歉,进程“<xliff:g id="PROCESS">%1$s</xliff:g>”已停止运行。"</string>
     <string name="anr_title" msgid="4351948481459135709"></string>
-    <string name="anr_activity_application" msgid="1904477189057199066">"“<xliff:g id="APPLICATION">%2$s</xliff:g>”无响应。"\n\n"要将其关闭吗?"</string>
-    <string name="anr_activity_process" msgid="5776209883299089767">"“<xliff:g id="ACTIVITY">%1$s</xliff:g>”活动无响应。"\n\n"要将其关闭吗?"</string>
-    <string name="anr_application_process" msgid="8941757607340481057">"“<xliff:g id="APPLICATION">%1$s</xliff:g>”无响应。要将其关闭吗?"</string>
-    <string name="anr_process" msgid="6513209874880517125">"“<xliff:g id="PROCESS">%1$s</xliff:g>”进程无响应。"\n\n"要将其关闭吗?"</string>
+    <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> 无响应。"\n\n"要将其关闭吗?"</string>
+    <string name="anr_activity_process" msgid="5776209883299089767">"<xliff:g id="ACTIVITY">%1$s</xliff:g> 活动无响应。"\n\n"要将其关闭吗?"</string>
+    <string name="anr_application_process" msgid="8941757607340481057">"<xliff:g id="APPLICATION">%1$s</xliff:g> 无响应。要将其关闭吗?"</string>
+    <string name="anr_process" msgid="6513209874880517125">"<xliff:g id="PROCESS">%1$s</xliff:g> 进程无响应。"\n\n"要将其关闭吗?"</string>
     <string name="force_close" msgid="8346072094521265605">"确定"</string>
     <string name="report" msgid="4060218260984795706">"报告"</string>
     <string name="wait" msgid="7147118217226317732">"等待"</string>
@@ -1182,7 +1184,7 @@
     <string name="action_bar_home_description" msgid="5293600496601490216">"导航首页"</string>
     <string name="action_bar_up_description" msgid="2237496562952152589">"向上导航"</string>
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"更多选项"</string>
-    <string name="storage_internal" msgid="7556050805474115618">"内存空间"</string>
+    <string name="storage_internal" msgid="7556050805474115618">"内部存储空间"</string>
     <string name="storage_sd_card" msgid="8921771478629812343">"SD 卡"</string>
     <string name="storage_usb" msgid="3017954059538517278">"USB 存储器"</string>
     <string name="extract_edit_menu_button" msgid="302060189057163906">"编辑..."</string>
@@ -1219,4 +1221,7 @@
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"分享对象"</string>
     <string name="status_bar_device_locked" msgid="3092703448690669768">"设备已锁定。"</string>
     <string name="list_delimeter" msgid="3975117572185494152">"、 "</string>
+    <string name="sending" msgid="8715108995741758718">"正在发送..."</string>
+    <string name="launchBrowserDefault" msgid="2057951947297614725">"要启动浏览器吗?"</string>
+    <string name="SetupCallDefault" msgid="6870275517518479651">"要接听电话吗?"</string>
 </resources>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 7284452..908c78c8 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -301,6 +301,8 @@
     <string name="permlab_readLogs" msgid="6615778543198967614">"讀取機密記錄資料"</string>
     <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"允許應用程式讀取系統的各種記錄檔。這會允許應用程式搜尋一般性的平板電腦使用資訊,可能包含您的個人或私人資訊。"</string>
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"允許應用程式讀取系統的各種記錄檔。這會允許應用程式搜尋一般性的手機使用資訊,可能包含您的個人或私人資訊。"</string>
+    <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"使用任何媒體解碼器進行播放"</string>
+    <string name="permdesc_anyCodecForPlayback" msgid="2101444559995480174">"允許應用程式使用任何已安裝的媒體解碼器進行解碼以播放影片。"</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"讀寫 diag 擁有的資源"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"允許應用程式讀取或寫入診斷群組擁有的任何資源,例如 /dev 底下的檔案。這可能會影響系統的穩定性和安全性,因此應由製造商或電信業者操作,且只用在特定硬體診斷。"</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"啟用或停用應用程式元件"</string>
@@ -444,7 +446,7 @@
     <string name="permdesc_manageAccounts" msgid="8698295625488292506">"允許應用程式執行新增、移除帳戶和刪除帳戶密碼等作業。"</string>
     <string name="permlab_useCredentials" msgid="6401886092818819856">"使用帳戶的驗證認證"</string>
     <string name="permdesc_useCredentials" msgid="7984227147403346422">"允許應用程式要求驗證憑證。"</string>
-    <string name="permlab_accessNetworkState" msgid="6865575199464405769">"檢視網路狀態"</string>
+    <string name="permlab_accessNetworkState" msgid="6865575199464405769">"查看網路狀態"</string>
     <string name="permdesc_accessNetworkState" msgid="479772796952547198">"允許應用程式查看所有網路狀態。"</string>
     <string name="permlab_createNetworkSockets" msgid="9121633680349549585">"網際網路完整存取"</string>
     <string name="permdesc_createNetworkSockets" msgid="5963922297444265950">"允許應用程式建立網路通訊端。"</string>
@@ -465,9 +467,9 @@
     <string name="permlab_bluetoothAdmin" msgid="3606576270792236062">"藍牙管理"</string>
     <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"允許應用程式設定本機藍牙平板電腦,以及搜尋遠端裝置並配對連線。"</string>
     <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"允許應用程式設定本機藍牙手機,以及搜尋遠端裝置並配對連線。"</string>
-    <!-- outdated translation 2800410363171809280 -->     <string name="permlab_accessWimaxState" msgid="1232061307208861588">"查看 WiMAX 狀態"</string>
+    <string name="permlab_accessWimaxState" msgid="1232061307208861588">"查看 WiMAX 狀態"</string>
     <string name="permdesc_accessWimaxState" msgid="8298035866227524023">"允許應用程式查看 WiMAX 連線狀態相關資訊。"</string>
-    <!-- outdated translation 340465839241528618 -->     <string name="permlab_changeWimaxState" msgid="2405042267131496579">"變更 WiMAX 狀態"</string>
+    <string name="permlab_changeWimaxState" msgid="2405042267131496579">"變更 WiMAX 狀態"</string>
     <string name="permdesc_changeWimaxState" msgid="474918005058989421">"允許應用程式建立或中斷 WiMAX 網路連線。"</string>
     <string name="permlab_bluetooth" msgid="8361038707857018732">"建立藍牙連線"</string>
     <string name="permdesc_bluetooth" product="tablet" msgid="7007851048416363446">"允許應用程式查看本機藍牙平板電腦設定,並可建立及接受與其他配對裝置的連線。"</string>
@@ -1219,4 +1221,7 @@
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"分享活動"</string>
     <string name="status_bar_device_locked" msgid="3092703448690669768">"裝置已鎖定。"</string>
     <string name="list_delimeter" msgid="3975117572185494152">"、 "</string>
+    <string name="sending" msgid="8715108995741758718">"傳送中..."</string>
+    <string name="launchBrowserDefault" msgid="2057951947297614725">"啟動「瀏覽器」嗎?"</string>
+    <string name="SetupCallDefault" msgid="6870275517518479651">"接聽電話嗎?"</string>
 </resources>
diff --git a/core/res/res/values-zu/donottranslate-cldr.xml b/core/res/res/values-zu/donottranslate-cldr.xml
new file mode 100644
index 0000000..df578ed
--- /dev/null
+++ b/core/res/res/values-zu/donottranslate-cldr.xml
@@ -0,0 +1,149 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="month_long_standalone_january">uJanuwari</string>
+    <string name="month_long_standalone_february">uFebruwari</string>
+    <string name="month_long_standalone_march">uMashi</string>
+    <string name="month_long_standalone_april">u-Apreli</string>
+    <string name="month_long_standalone_may">uMeyi</string>
+    <string name="month_long_standalone_june">uJuni</string>
+    <string name="month_long_standalone_july">uJulayi</string>
+    <string name="month_long_standalone_august">uAgasti</string>
+    <string name="month_long_standalone_september">uSepthemba</string>
+    <string name="month_long_standalone_october">u-Okthoba</string>
+    <string name="month_long_standalone_november">uNovemba</string>
+    <string name="month_long_standalone_december">uDisemba</string>
+
+    <string name="month_long_january">Januwari</string>
+    <string name="month_long_february">Februwari</string>
+    <string name="month_long_march">Mashi</string>
+    <string name="month_long_april">Apreli</string>
+    <string name="month_long_may">Meyi</string>
+    <string name="month_long_june">Juni</string>
+    <string name="month_long_july">Julayi</string>
+    <string name="month_long_august">Agasti</string>
+    <string name="month_long_september">Septhemba</string>
+    <string name="month_long_october">Okthoba</string>
+    <string name="month_long_november">Novemba</string>
+    <string name="month_long_december">Disemba</string>
+
+    <string name="month_medium_january">Jan</string>
+    <string name="month_medium_february">Feb</string>
+    <string name="month_medium_march">Mas</string>
+    <string name="month_medium_april">Apr</string>
+    <string name="month_medium_may">Mey</string>
+    <string name="month_medium_june">Jun</string>
+    <string name="month_medium_july">Jul</string>
+    <string name="month_medium_august">Aga</string>
+    <string name="month_medium_september">Sep</string>
+    <string name="month_medium_october">Okt</string>
+    <string name="month_medium_november">Nov</string>
+    <string name="month_medium_december">Dis</string>
+
+    <string name="month_shortest_january">J</string>
+    <string name="month_shortest_february">F</string>
+    <string name="month_shortest_march">M</string>
+    <string name="month_shortest_april">A</string>
+    <string name="month_shortest_may">M</string>
+    <string name="month_shortest_june">J</string>
+    <string name="month_shortest_july">J</string>
+    <string name="month_shortest_august">A</string>
+    <string name="month_shortest_september">S</string>
+    <string name="month_shortest_october">O</string>
+    <string name="month_shortest_november">N</string>
+    <string name="month_shortest_december">D</string>
+
+    <string name="day_of_week_long_sunday">Sonto</string>
+    <string name="day_of_week_long_monday">Msombuluko</string>
+    <string name="day_of_week_long_tuesday">Lwesibili</string>
+    <string name="day_of_week_long_wednesday">Lwesithathu</string>
+    <string name="day_of_week_long_thursday">uLwesine</string>
+    <string name="day_of_week_long_friday">Lwesihlanu</string>
+    <string name="day_of_week_long_saturday">Mgqibelo</string>
+
+    <string name="day_of_week_medium_sunday">Son</string>
+    <string name="day_of_week_medium_monday">Mso</string>
+    <string name="day_of_week_medium_tuesday">Bil</string>
+    <string name="day_of_week_medium_wednesday">Tha</string>
+    <string name="day_of_week_medium_thursday">Sin</string>
+    <string name="day_of_week_medium_friday">Hla</string>
+    <string name="day_of_week_medium_saturday">Mgq</string>
+
+    <string name="day_of_week_short_sunday">Son</string>
+    <string name="day_of_week_short_monday">Mso</string>
+    <string name="day_of_week_short_tuesday">Bil</string>
+    <string name="day_of_week_short_wednesday">Tha</string>
+    <string name="day_of_week_short_thursday">Sin</string>
+    <string name="day_of_week_short_friday">Hla</string>
+    <string name="day_of_week_short_saturday">Mgq</string>
+
+    <string name="day_of_week_shortest_sunday">S</string>
+    <string name="day_of_week_shortest_monday">M</string>
+    <string name="day_of_week_shortest_tuesday">B</string>
+    <string name="day_of_week_shortest_wednesday">T</string>
+    <string name="day_of_week_shortest_thursday">S</string>
+    <string name="day_of_week_shortest_friday">H</string>
+    <string name="day_of_week_shortest_saturday">M</string>
+
+    <string name="am">AM</string>
+    <string name="pm">PM</string>
+    <string name="yesterday">Yesterday</string>
+    <string name="today">Today</string>
+    <string name="tomorrow">Tomorrow</string>
+
+    <string name="hour_minute_24">%-k:%M</string>
+    <string name="hour_minute_ampm">%-l:%M %p</string>
+    <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
+    <string name="twelve_hour_time_format">h:mm a</string>
+    <string name="twenty_four_hour_time_format">H:mm</string>
+    <string name="numeric_date">%Y-%m-%d</string>
+    <string name="numeric_date_format">yyyy-MM-dd</string>
+    <string name="numeric_date_template">"%s-%s-%s"</string>
+    <string name="month_day_year">%-e %B %Y</string>
+    <string name="time_of_day">%-l:%M:%S %p</string>
+    <string name="date_and_time">%-l:%M:%S %p %-e %b %Y</string>
+    <string name="date_time">%2$s %1$s</string>
+    <string name="time_date">%1$s %3$s</string>
+    <string name="abbrev_month_day_year">%-e %b %Y</string>
+    <string name="month_day">%B %-e</string>
+    <string name="month">%-B</string>
+    <string name="month_year">%Y %B</string>
+    <string name="abbrev_month_day">%b %-e</string>
+    <string name="abbrev_month">%-b</string>
+    <string name="abbrev_month_year">%Y %b</string>
+    <string name="time1_time2">%1$s – %2$s</string>
+    <string name="date1_date2">%2$s – %5$s</string>
+    <string name="numeric_md1_md2">%2$s-%3$s – %7$s-%8$s</string>
+    <string name="numeric_wday1_md1_wday2_md2">%1$s, %2$s-%3$s – %6$s, %7$s-%8$s</string>
+    <string name="numeric_mdy1_mdy2">%4$s-%2$s-%3$s – %9$s-%7$s-%8$s</string>
+    <string name="numeric_wday1_mdy1_wday2_mdy2">%1$s, %4$s-%2$s-%3$s – %6$s, %9$s-%7$s-%8$s</string>
+    <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %4$s-%2$s-%3$s – %10$s %6$s, %9$s-%7$s-%8$s</string>
+    <string name="numeric_md1_time1_md2_time2">%5$s %2$s-%3$s – %10$s %7$s-%8$s</string>
+    <string name="numeric_wday1_md1_time1_wday2_md2_time2">%5$s %1$s, %2$s-%3$s – %10$s %6$s, %7$s-%8$s</string>
+    <string name="numeric_mdy1_time1_mdy2_time2">%5$s %4$s-%2$s-%3$s – %10$s %9$s-%7$s-%8$s</string>
+    <string name="wday1_date1_time1_wday2_date2_time2">%3$s %1$s %2$s – %6$s %4$s %5$s</string>
+    <string name="wday1_date1_wday2_date2">%1$s %2$s – %4$s %5$s</string>
+    <string name="date1_time1_date2_time2">%3$s %2$s – %6$s %5$s</string>
+    <string name="time_wday_date">%1$s %2$s %3$s</string>
+    <string name="wday_date">%2$s %3$s</string>
+    <string name="time_wday">%1$s %2$s</string>
+    <string name="same_year_md1_md2">%2$s %3$s – %7$s %8$s</string>
+    <string name="same_year_wday1_md1_wday2_md2">%1$s %2$s %3$s – %6$s %7$s %8$s</string>
+    <string name="same_year_md1_time1_md2_time2">%5$s %2$s %3$s – %10$s %7$s %8$s</string>
+    <string name="same_month_md1_time1_md2_time2">%5$s %2$s %3$s – %10$s %7$s %8$s</string>
+    <string name="same_year_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %2$s %3$s – %10$s %6$s %7$s %8$s</string>
+    <string name="same_month_wday1_md1_time1_wday2_md2_time2">%5$s %1$s %2$s %3$s – %10$s %6$s %7$s %8$s</string>
+    <string name="same_year_mdy1_time1_mdy2_time2">%5$s %4$s-%2$s-%3$s – %10$s %9$s-%7$s-%8$s</string>
+    <string name="same_month_mdy1_time1_mdy2_time2">%5$s %4$s-%2$s-%3$s – %10$s %9$s-%7$s-%8$s</string>
+    <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %4$s %2$s %3$s – %10$s %6$s, %9$s %7$s %8$s</string>
+    <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">%5$s %1$s, %4$s %2$s %3$s – %10$s %6$s, %9$s %7$s %8$s</string>
+    <string name="same_month_wday1_mdy1_wday2_mdy2">%1$s, %4$s %2$s %3$s – %6$s, %9$s %7$s %8$s</string>
+    <string name="same_month_md1_md2">%2$s-%3$s – %8$s</string>
+    <string name="same_month_wday1_md1_wday2_md2">%1$s %2$s %3$s – %6$s %7$s %8$s</string>
+    <string name="same_year_mdy1_mdy2">%9$s-%2$s-%3$s – %7$s-%8$s</string>
+    <string name="same_month_mdy1_mdy2">%9$s-%2$s-%3$s – %8$s</string>
+    <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s, %9$s-%2$s-%3$s – %6$s, yyyy-%7$s-%8$s</string>
+    <string name="short_format_month">%b</string>
+    <string name="full_wday_month_day_no_year">E MMMM d</string>
+    <string name="abbrev_wday_month_day_year">EEE, y MMM d</string>
+</resources>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index ae1cdae..b1a4162 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -68,16 +68,16 @@
     <string name="CLIRDefaultOffNextCallOn" msgid="6179425182856418465">"I-ID Yomshayeli ishintshela kokungavinjelwe. Ucingo olulandelayo: Luvinjelwe"</string>
     <string name="CLIRDefaultOffNextCallOff" msgid="2567998633124408552">"I-ID Yomshayeli ishintshela kokungavinjelwe. Ucingo olulandelayo: Aluvinjelwe"</string>
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"Isevisi ayilungiselelwe."</string>
-    <string name="CLIRPermanent" msgid="3377371145926835671">"Ngeke ukwazi ukuguqul izisetho zemininingwane yoshayayo."</string>
+    <string name="CLIRPermanent" msgid="3377371145926835671">"Ngeke ukwazi ukuguqul izilungiselelo zemininingwane yoshayayo."</string>
     <string name="RestrictedChangedTitle" msgid="5592189398956187498">"Ukufinyelela okuvinjelwe kushintshiwe"</string>
     <string name="RestrictedOnData" msgid="8653794784690065540">"Insizakalo yedatha ivaliwe."</string>
     <string name="RestrictedOnEmergency" msgid="6581163779072833665">"Insizakalo ephuthumayo ivimbelwe."</string>
     <string name="RestrictedOnNormal" msgid="4953867011389750673">"Insizakalo yezwi ivimbelwe."</string>
-    <string name="RestrictedOnAllVoice" msgid="1459318899842232234">"Zonke izinsizakalo Zezwi zivimbelwe."</string>
+    <string name="RestrictedOnAllVoice" msgid="1459318899842232234">"Wonke amasevisi Wezwi avimbelwe."</string>
     <string name="RestrictedOnSms" msgid="8314352327461638897">"Insizakalo ye-SMS ivaliwe."</string>
-    <string name="RestrictedOnVoiceData" msgid="8244438624660371717">"Izinsizakalo Zezwi/Idatha zivimbelwe."</string>
-    <string name="RestrictedOnVoiceSms" msgid="1888588152792023873">"Izinsizakalo Zezwi/SMS zivimbelwe."</string>
-    <string name="RestrictedOnAll" msgid="2714924667937117304">"Zonke izinsizakalo Zezwi/Idatha/SMS zivimbelwe."</string>
+    <string name="RestrictedOnVoiceData" msgid="8244438624660371717">"Amasevisi Wezwi/Idatha avimbelwe."</string>
+    <string name="RestrictedOnVoiceSms" msgid="1888588152792023873">"Amasevisi Wezwi/SMS avimbelwe."</string>
+    <string name="RestrictedOnAll" msgid="2714924667937117304">"Wonke amasevisi Wezwi/Idatha/SMS avimbelwe."</string>
     <string name="serviceClassVoice" msgid="1258393812335258019">"Izwi"</string>
     <string name="serviceClassData" msgid="872456782077937893">"Idatha"</string>
     <string name="serviceClassFAX" msgid="5566624998840486475">"Ifeksi"</string>
@@ -99,7 +99,7 @@
     <string name="roamingText10" msgid="3992906999815316417">"Iyazulazula - Isici Sensizakalo Eyingxenye"</string>
     <string name="roamingText11" msgid="4154476854426920970">"Ibhena Yokuzulazula Ivuliwe"</string>
     <string name="roamingText12" msgid="1189071119992726320">"Ibhena yokuzulazula ivaliwe"</string>
-    <string name="roamingTextSearching" msgid="8360141885972279963">"Iseshela Izinsizakalo"</string>
+    <string name="roamingTextSearching" msgid="8360141885972279963">"Iseshela Isevisi"</string>
     <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Akudlulisiwe"</string>
     <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
     <string name="cfTemplateForwardedTime" msgid="9206251736527085256">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g> emuva kwamasekhondi angu-<xliff:g id="TIME_DELAY">{2}</xliff:g>"</string>
@@ -136,7 +136,7 @@
     <string name="turn_on_radio" msgid="3912793092339962371">"Vula okungenantambo"</string>
     <string name="turn_off_radio" msgid="8198784949987062346">"Vala okungenantambo"</string>
     <string name="screen_lock" msgid="799094655496098153">"Ukuvala isikrini"</string>
-    <string name="power_off" msgid="4266614107412865048">"Amandla avaliwe"</string>
+    <string name="power_off" msgid="4266614107412865048">"Vala amandla"</string>
     <string name="shutdown_progress" msgid="2281079257329981203">"Ivala shaqa..."</string>
     <string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Ithebhulethi yakho izocima."</string>
     <string name="shutdown_confirm" product="default" msgid="649792175242821353">"Ifoni yakho izocima."</string>
@@ -146,7 +146,7 @@
     <string name="global_actions" product="tablet" msgid="408477140088053665">"Okukhethwa konke kwethebhulethi"</string>
     <string name="global_actions" product="default" msgid="2406416831541615258">"Okukhethwa kukho kwefoni"</string>
     <string name="global_action_lock" msgid="2844945191792119712">"Ukuvala isikrini"</string>
-    <string name="global_action_power_off" msgid="4471879440839879722">"Amandla avaliwe"</string>
+    <string name="global_action_power_off" msgid="4471879440839879722">"Vala amandla"</string>
     <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Imodi ethulile"</string>
     <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Umsindo UVALIWE"</string>
     <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Umsindo UVULIWE"</string>
@@ -301,6 +301,8 @@
     <string name="permlab_readLogs" msgid="6615778543198967614">"funda idatha yefayela lokungena ebucayi"</string>
     <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"Ivumela uhlelo lokusebenza ukufunda umafayela okungena ohlelo oluhlukene. Lokhu kuvumela ukuthola ukwaziswa okuvamile mayelana nokuthi wenzani ngethebhulethi, kodwa akumele kuqukethe ukwaziswa komuntu siqu noma okuyimfihlo."</string>
     <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Ivumela uhlelo lokusebenza ukufunda kumafayela okungena ahlukene esistimu. Lokhu kuvumela ukuthola ukwaziswa okuvamile mayelana nokuthi wenzani ngefoni, kuhlanganise ukwaziswa komuntu siqu noma kwangasese."</string>
+    <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"sebenzisa noma isiphi isiqophi semidiya ukudlala"</string>
+    <string name="permdesc_anyCodecForPlayback" msgid="2101444559995480174">"Ivumela uhlelo ukusebenzisa noma isiphi isiqophi semidiya esifakiwe ukuqopha ukudlala."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"funda/bhalela emithombweni ephethwe idayegi"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Ivumela uhlelo lokusebenza ukufunda nokubhala kunoma yimuphi umthombo weqembu ledayegi; ngokwesibonelo, amafayela akwi/dev. Lokhu kungase kuthinte kakhulu ukuba nokuphepha kohlelo. Lokhu kumele kusebenziselwe KUPHELA ukuhlola ihadiwe okucacile ngumkhiqizi noma u-opheretha."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"vumela noma vimbela izingxenye zensiza"</string>
@@ -372,7 +374,7 @@
     <string name="permlab_mount_unmount_filesystems" msgid="1761023272170956541">"khuphula futhi wehlise izinhlelo zefayela"</string>
     <string name="permdesc_mount_unmount_filesystems" msgid="1829290701658992347">"Ivumela izinhlelo ukugibelisa nokukwehlisa izinhlelo zefayela zokugcina okukhiphekayo."</string>
     <string name="permlab_mount_format_filesystems" msgid="5523285143576718981">"fometha isitoreji sangaphandle"</string>
-    <string name="permdesc_mount_format_filesystems" msgid="8784268246779198627">"Ivumela uhlelo lokusebenza ukufometha ukugcina okukhiphekayo."</string>
+    <string name="permdesc_mount_format_filesystems" msgid="8784268246779198627">"Ivumela uhlelo lokusebenza ukufometha isitoreji esikhiphekayo."</string>
     <string name="permlab_asec_access" msgid="3411338632002193846">"thola ulwazi ngesitoreji sangaphakathi"</string>
     <string name="permdesc_asec_access" msgid="3094563844593878548">"Ivumela uhlelo lokusebenza ukuthola ukwaziswa ekugcineni kwangaphakathi."</string>
     <string name="permlab_asec_create" msgid="6414757234789336327">"dala isitoreji sangaphakathi"</string>
@@ -380,7 +382,7 @@
     <string name="permlab_asec_destroy" msgid="526928328301618022">"yonakalisa isitoreji sangaphakathi"</string>
     <string name="permdesc_asec_destroy" msgid="7218749286145526537">"Ivumela insiza ukuthi ibulale ukulondolozwa kwangaphakathi."</string>
     <string name="permlab_asec_mount_unmount" msgid="8877998101944999386">"khweza / yehlisa isitoreji sangaphakathi"</string>
-    <string name="permdesc_asec_mount_unmount" msgid="3451360114902490929">"Ivumela uhlelo ukukhuphula / ukwehlisa ukugcina kwangaphakathi."</string>
+    <string name="permdesc_asec_mount_unmount" msgid="3451360114902490929">"Ivumela uhlelo ukukhuphula / ukwehlisa isitoreji sangaphakathi."</string>
     <string name="permlab_asec_rename" msgid="7496633954080472417">"yetha kabusha isitoreji sangaphakathi"</string>
     <string name="permdesc_asec_rename" msgid="1794757588472127675">"Ivumela uhlelo lokusebenza ukuqamba kabusha ukugcina kwangaphakathi."</string>
     <string name="permlab_vibrate" msgid="7768356019980849603">"lawula isidlidliza"</string>
@@ -427,7 +429,7 @@
     <string name="permdesc_setWallpaperHints" msgid="8235784384223730091">"Ivumela uhlelo lokusebenza ukuhlela izihlawumbisela zosayizi wephephadonga lohlelo."</string>
     <string name="permlab_masterClear" msgid="2315750423139697397">"setha kabusha kube okumisiwe kwemboni"</string>
     <string name="permdesc_masterClear" msgid="3665380492633910226">"Ivuela insiza ukuthi isethe kabusha isistiu ngokuphelele iyibuyisele ezisethweni eyafika nazo, isusa konke ukumisw kwemininingwane, kanye nezinsiza ezifakiwe."</string>
-    <string name="permlab_setTime" msgid="2021614829591775646">"Hlela isikhathi"</string>
+    <string name="permlab_setTime" msgid="2021614829591775646">"setha isikhathi"</string>
     <string name="permdesc_setTime" product="tablet" msgid="1896341438151152881">"Ivumela insiza ukuthi iguqule isikhathi esisekhompyutheni yepeni."</string>
     <string name="permdesc_setTime" product="default" msgid="1855702730738020">"Ivumela insiza ukuth iguqule isikhathi esisocingweni."</string>
     <string name="permlab_setTimeZone" msgid="2945079801013077340">"setha umkhawulo wesikhathi"</string>
@@ -449,25 +451,25 @@
     <string name="permlab_createNetworkSockets" msgid="9121633680349549585">"Ukufinyelela i-Inthanethi ngokugcwele"</string>
     <string name="permdesc_createNetworkSockets" msgid="5963922297444265950">"Ivumela insiza ukuthi yakhe amsokhethi enethiwekhi."</string>
     <string name="permlab_writeApnSettings" msgid="505660159675751896">"shintsha/ngenelela izilungiselelo kanye nokuhamba kuhleloxhumano"</string>
-    <string name="permdesc_writeApnSettings" msgid="5333798886412714193">"Ivumela insiza ukuthi iguqule izisetho zenethiwekhi kanye nokunciphisa kanye nokuhlola konke ukuphithizela kwenethiwekhi, isibonelo ukushintsha i-proy kanye ne-port yanom iyiphi i-APN. Izinsiza ezinobungozi zingabheka, zithumele kabusha noa ziguqule okuqukethwe enethiwekhini ngaphandle kokwzi kwakho."</string>
+    <string name="permdesc_writeApnSettings" msgid="5333798886412714193">"Ivumela insiza ukuthi iguqule izilungiselelo zenethiwekhi kanye nokunciphisa kanye nokuhlola konke ukuphithizela kwenethiwekhi, isibonelo ukushintsha i-proy kanye ne-port yanom iyiphi i-APN. Izinhlelo zokusebenza ezinobungozi zingabheka, zithumele kabusha noa ziguqule okuqukethwe enethiwekhini ngaphandle kokwazi kwakho."</string>
     <string name="permlab_changeNetworkState" msgid="958884291454327309">"shintsha uxhumano lwenethiwekhi"</string>
     <string name="permdesc_changeNetworkState" msgid="6789123912476416214">"Ivumela insiza ukuthi iguqule isimo sokuxhuaniseka kwenethiwekhi."</string>
     <string name="permlab_changeTetherState" msgid="5952584964373017960">"Shintsha uxhumano lokusebenzisa njengemodemu"</string>
     <string name="permdesc_changeTetherState" msgid="1524441344412319780">"Ivumela insiza ukuthi iguqule isimo sokuxhuaniseka kwenethiwekhi ehunyiwe."</string>
     <string name="permlab_changeBackgroundDataSetting" msgid="1400666012671648741">"shintsha idatha yasemuva yelungiselelo lokusebenzisa"</string>
-    <string name="permdesc_changeBackgroundDataSetting" msgid="5347729578468744379">"Ivumela insiza ukuthi iguqule izisetho zemininingwane yokusetshenziswa kwe-data."</string>
+    <string name="permdesc_changeBackgroundDataSetting" msgid="5347729578468744379">"Ivumela uhlelo lokusebenza ukuthi luguqule izilungiselelo zemininingwane yokusetshenziswa kwedatha."</string>
     <string name="permlab_accessWifiState" msgid="8100926650211034400">"buka isimo se-Wi-Fi"</string>
     <string name="permdesc_accessWifiState" msgid="7770452658226256831">"Ivumela insiza ukuthi ibheke imininingwane emayelana nesimo se-Wi-Fi."</string>
     <string name="permlab_changeWifiState" msgid="7280632711057112137">"shintsha isimo se-WiFi"</string>
     <string name="permdesc_changeWifiState" msgid="7399961004537946240">"Ivumela uhlelo lokusebenza ukuxhuma nokungaxhumeki kumaphoyinti okungena e-Wi-Fi, nokwenza izinguquko ukumisa amanethiwekhi e-Wi-Fi."</string>
     <string name="permlab_changeWifiMulticastState" msgid="1368253871483254784">"ivumela isamukeli se-Wi-Fi Multicast"</string>
-    <string name="permdesc_changeWifiMulticastState" msgid="7633598524564320817">"Ivumela uhlelo lokusebenza ukuthola amaphakhethe ngokungaqondile angewona awedivaysi yakho. Lokhu kungaba usizo lapho uthola izinsizakalo ezinikezwa eduze. Kusebenzisa amandla amaninigi kunemodi yokungajikijeli okuningi."</string>
+    <string name="permdesc_changeWifiMulticastState" msgid="7633598524564320817">"Ivumela uhlelo lokusebenza ukuthola amaphakhethe ngokungaqondile angewona awedivaysi yakho. Lokhu kungaba usizo lapho uthola amasevisi anikezwa eduze. Kusebenzisa amandla amaninigi kunemodi yokungajikijeli okuningi."</string>
     <string name="permlab_bluetoothAdmin" msgid="3606576270792236062">"ukubhalisela i-bluetooth"</string>
     <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"Ivumela uhlelo lokusebenza ukumisa ithebhulethi ye-Bluetooth yasendawni, nokuthola nokubhanqanisa namadivaysi okulawula okukude."</string>
     <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"Ivumela uhlelo lokusebenza ukumisa ifoni ye-Bluetooth yasendawni, nokuthola nokubhanqanisa namadivaysi okulawula okukude."</string>
-    <!-- outdated translation 2800410363171809280 -->     <string name="permlab_accessWimaxState" msgid="1232061307208861588">"Buka isimo se-WiMAX"</string>
+    <string name="permlab_accessWimaxState" msgid="1232061307208861588">"Buka isimo se-WiMAX"</string>
     <string name="permdesc_accessWimaxState" msgid="8298035866227524023">"Ivumela uhlelo lokusebenza ukubuka ulwazi mayelana nesimo se-WiMAX."</string>
-    <!-- outdated translation 340465839241528618 -->     <string name="permlab_changeWimaxState" msgid="2405042267131496579">"shintsha isimo se-WiMAX"</string>
+    <string name="permlab_changeWimaxState" msgid="2405042267131496579">"Shintsha isimo se-WiMAX"</string>
     <string name="permdesc_changeWimaxState" msgid="474918005058989421">"Ivumela uhlelo lokusebenza luxhume futhi likhiphe ukuxhuma kusuka kuhlelo lokusebenza lwe-WiMAX"</string>
     <string name="permlab_bluetooth" msgid="8361038707857018732">"Dala uxhumano lwe-Bluetooth"</string>
     <string name="permdesc_bluetooth" product="tablet" msgid="7007851048416363446">"Ivumela insiza ukuthi ibheke ukumiswa kwe-Bluetooth ekhompyutheni yepeni, kanye nokwenza kanye nokwamukela ukuxhumaniseka nokwenziwa kwamadivayisi ukuthi asebenzisane."</string>
@@ -477,7 +479,7 @@
     <string name="permlab_disableKeyguard" msgid="4977406164311535092">"khubaza ukuvala ukhiye"</string>
     <string name="permdesc_disableKeyguard" msgid="6231611286892232626">"Ivumela uhlelo lokusebenza ukuvimbela ukuvala ukhiye nanoma yikuphi ukuphepha kwephasiwedi okuhlobene. Isibonelo esisemthethweni salokhu ukuba ifoni ivimbele ukuvala ukhiye lapho ithola ikholi engenayo, bese ivumela futhi ukuvala ukhiye lapho ikholi isiqedile."</string>
     <string name="permlab_readSyncSettings" msgid="6201810008230503052">"funda izilungiselelo zokuvumelanisa"</string>
-    <string name="permdesc_readSyncSettings" msgid="5464056785274229278">"Ivumela insiza ukuthi ifunde izisetho zokuvumelanisa njengokuthi ukuvuelanise kuyasebenza yini ensizeni Yabantu."</string>
+    <string name="permdesc_readSyncSettings" msgid="5464056785274229278">"Ivumela uhlelo lokusebenza ukuthi lifunde izilungiselelo zokuvumelanisa njengokuthi ukuvumelanise kuyasebenza yini kuhlelo lokusebenza Abantu."</string>
     <string name="permlab_writeSyncSettings" msgid="6297138566442486462">"bhala izilungiselelo zokuvumelanisa"</string>
     <string name="permdesc_writeSyncSettings" msgid="1466056564502117130">"Ivumela insiza ukuthi iguqule izinsiza zokuvumelanisa, kuze kube ukuthi insiza ivumelanisekela abantu."</string>
     <string name="permlab_readSyncStats" msgid="7396577451360202448">"funda izibalo zokuvumelanisa"</string>
@@ -521,7 +523,7 @@
     <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"Misa ummelelii jikelele yedivaysi"</string>
     <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Misa iphrokzi jikelele yedivaysi ukusebenzisa ngenkathi inqumbomgomo ivunyelwa. Idivaysi yokuqala kuphela yokuphatha emisa ummeleli jikelele esebenzayo."</string>
     <string name="policylab_expirePassword" msgid="885279151847254056">"Hlela ukuphelelwa isikhathi sokuvala-isikrini."</string>
-    <string name="policydesc_expirePassword" msgid="4844430354224822074">"Phatha ukuthi i-password yokuvala isikrini isintshwe kangakanani"</string>
+    <string name="policydesc_expirePassword" msgid="4844430354224822074">"Lawula ukuthi iphasiwedi yokuvala isikrini ishintshwa kangaki"</string>
     <string name="policylab_encryptedStorage" msgid="8901326199909132915">"Setha umbhalo wemfihlo yesitoreji"</string>
     <string name="policydesc_encryptedStorage" msgid="8877192718681120469">"Idinga ukuthi idatha yohlelo lokusebenza olugciniwe ibethelwe"</string>
     <string name="policylab_disableCamera" msgid="6395301023152297826">"Khubaza amakhamera"</string>
@@ -696,9 +698,9 @@
     <string name="lockscreen_glogin_instructions" msgid="1816635201812207709">"Ukuvula, ngena ngemvumekwi-akhawunti ye-Google"</string>
     <string name="lockscreen_glogin_username_hint" msgid="8846881424106484447">"Igama lomsebenzisi (i-imeyli)"</string>
     <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Iphasiwedi"</string>
-    <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Ngena ngemvume"</string>
+    <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Ngena"</string>
     <string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Igama lomsebezisi elingalungile noma iphasiwedi."</string>
-    <string name="lockscreen_glogin_account_recovery_hint" msgid="8253152905532900548">"Ukhohlwe igama lomsebenzisi noma i-password?"\n"Vakashela"<b>"google.com/accounts/recovery"</b></string>
+    <string name="lockscreen_glogin_account_recovery_hint" msgid="8253152905532900548">"Ukhohlwe igama lomsebenzisi noma iphasiwedi?"\n"Vakashela"<b>"google.com/accounts/recovery"</b></string>
     <string name="lockscreen_glogin_checking_password" msgid="6758890536332363322">"Iyahlola..."</string>
     <string name="lockscreen_unlock_label" msgid="737440483220667054">"Vula"</string>
     <string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Umsindo uvuliwe"</string>
@@ -766,11 +768,11 @@
     <string name="menu_enter_shortcut_label" msgid="2743362785111309668">"faka"</string>
     <string name="menu_delete_shortcut_label" msgid="3658178007202748164">"susa"</string>
     <string name="search_go" msgid="8298016669822141719">"Sesha"</string>
-    <string name="searchview_description_search" msgid="6749826639098512120">"Cinga"</string>
-    <string name="searchview_description_query" msgid="5911778593125355124">"Cinga umbuzo"</string>
+    <string name="searchview_description_search" msgid="6749826639098512120">"Sesha"</string>
+    <string name="searchview_description_query" msgid="5911778593125355124">"Umbuzo wosesho"</string>
     <string name="searchview_description_clear" msgid="1330281990951833033">"xazulula umbuzo"</string>
     <string name="searchview_description_submit" msgid="2688450133297983542">"Thumela umbuzo"</string>
-    <string name="searchview_description_voice" msgid="2453203695674994440">"Ukucinga ngezwi"</string>
+    <string name="searchview_description_voice" msgid="2453203695674994440">"Ukusesha ngezwi"</string>
     <string name="oneMonthDurationPast" msgid="7396384508953779925">"inyanga engu-1 edlule"</string>
     <string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Ngaphambi kwenyanga engu-1 edlule"</string>
   <plurals name="num_seconds_ago">
@@ -783,7 +785,7 @@
   </plurals>
   <plurals name="num_hours_ago">
     <item quantity="one" msgid="9150797944610821849">"ihora elingu-1 elidlule"</item>
-    <item quantity="other" msgid="2467273239587587569">"Amahora angu-<xliff:g id="COUNT">%d</xliff:g> edlule."</item>
+    <item quantity="other" msgid="2467273239587587569">"<xliff:g id="COUNT">%d</xliff:g> amahora adlule"</item>
   </plurals>
   <plurals name="last_num_days">
     <item quantity="other" msgid="3069992808164318268">"Izinsuku zokugcina ezingu- <xliff:g id="COUNT">%d</xliff:g>"</item>
@@ -792,7 +794,7 @@
     <string name="older" msgid="5211975022815554840">"Okudala kakhulu"</string>
   <plurals name="num_days_ago">
     <item quantity="one" msgid="861358534398115820">"Izolo"</item>
-    <item quantity="other" msgid="2479586466153314633">"ezinsukwini ezingu-<xliff:g id="COUNT">%d</xliff:g> ezedlule"</item>
+    <item quantity="other" msgid="2479586466153314633">"<xliff:g id="COUNT">%d</xliff:g> izinsuku ezedlule"</item>
   </plurals>
   <plurals name="in_num_seconds">
     <item quantity="one" msgid="2729745560954905102">"esekhondini elingu-1"</item>
@@ -820,11 +822,11 @@
   </plurals>
   <plurals name="abbrev_num_hours_ago">
     <item quantity="one" msgid="4796212039724722116">"ihora elingu-1 elidlule"</item>
-    <item quantity="other" msgid="6889970745748538901">"Amahora angu-<xliff:g id="COUNT">%d</xliff:g> edlule."</item>
+    <item quantity="other" msgid="6889970745748538901">"<xliff:g id="COUNT">%d</xliff:g> amahora adlule"</item>
   </plurals>
   <plurals name="abbrev_num_days_ago">
     <item quantity="one" msgid="8463161711492680309">"Izolo"</item>
-    <item quantity="other" msgid="3453342639616481191">"ezinsukwini ezingu-<xliff:g id="COUNT">%d</xliff:g> ezedlule"</item>
+    <item quantity="other" msgid="3453342639616481191">"<xliff:g id="COUNT">%d</xliff:g> izinsuku ezedlule"</item>
   </plurals>
   <plurals name="abbrev_in_num_seconds">
     <item quantity="one" msgid="5842225370795066299">"esekhondini elingu-1"</item>
@@ -842,7 +844,7 @@
     <item quantity="one" msgid="2178576254385739855">"Kusasa"</item>
     <item quantity="other" msgid="2973062968038355991">"ezinsukwini ezing-<xliff:g id="COUNT">%d</xliff:g>"</item>
   </plurals>
-    <string name="preposition_for_date" msgid="9093949757757445117">"Ngomhla ka <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="preposition_for_date" msgid="9093949757757445117">"ngo-<xliff:g id="DATE">%s</xliff:g>"</string>
     <string name="preposition_for_time" msgid="5506831244263083793">"e-<xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="preposition_for_year" msgid="5040395640711867177">"phakathi- <xliff:g id="YEAR">%s</xliff:g>"</string>
     <string name="day" msgid="8144195776058119424">"usuku"</string>
@@ -850,7 +852,7 @@
     <string name="hour" msgid="2126771916426189481">"ihora"</string>
     <string name="hours" msgid="894424005266852993">"amahora"</string>
     <string name="minute" msgid="9148878657703769868">"Okuncane"</string>
-    <string name="minutes" msgid="5646001005827034509">"imizuzu"</string>
+    <string name="minutes" msgid="5646001005827034509">"amaminithi"</string>
     <string name="second" msgid="3184235808021478">"isekhondi"</string>
     <string name="seconds" msgid="3161515347216589235">"amasekhondi"</string>
     <string name="week" msgid="5617961537173061583">"iviki"</string>
@@ -888,13 +890,13 @@
     <string name="cancel" msgid="6442560571259935130">"Khansela"</string>
     <string name="yes" msgid="5362982303337969312">"KULUNGILE"</string>
     <string name="no" msgid="5141531044935541497">"Khansela"</string>
-    <string name="dialog_alert_title" msgid="2049658708609043103">"Ukunaka"</string>
+    <string name="dialog_alert_title" msgid="2049658708609043103">"Qaphela"</string>
     <string name="loading" msgid="7933681260296021180">"Iyalayisha…"</string>
-    <string name="capital_on" msgid="1544682755514494298">"Ngomhla ka"</string>
+    <string name="capital_on" msgid="1544682755514494298">"VULIWE"</string>
     <string name="capital_off" msgid="6815870386972805832">"VALIWE"</string>
     <string name="whichApplication" msgid="4533185947064773386">"Qedela isenzo usebenzisa"</string>
     <string name="alwaysUse" msgid="4583018368000610438">"Sebenzisa ngokuzenzakalelayo kulesenzo."</string>
-    <string name="clearDefaultHintMsg" msgid="3252584689512077257">"Susa izisetho ozithola zikhona zeSistimu &gt; Apps &gt; Kulayishiwe"</string>
+    <string name="clearDefaultHintMsg" msgid="3252584689512077257">"Susa izilungiselelo ozithola zikhona zeSistimu; Izinhlelo zokusebenzaApps &amp; Okulayishiwe"</string>
     <string name="chooseActivity" msgid="1009246475582238425">"Khetha isenzo"</string>
     <string name="chooseUsbActivity" msgid="6894748416073583509">"Kheth insiza yedivayisi ye-USB"</string>
     <string name="noApplications" msgid="2991814273936504689">"Azikho izinsiza ezingenza lokhu"</string>
@@ -969,7 +971,7 @@
     <string name="wifi_p2p_pin_go_negotiation_request_message" msgid="5177412094633377308">"Isethaphu yoheloxhumano oluqondile lwe-WiFi lwesicelo kusuka ku <xliff:g id="P2P_DEVICE_ADDRESS">%1$s</xliff:g>. Faka i-pin ukuze uqhubeke"</string>
     <string name="wifi_p2p_pin_display_message" msgid="2834049169114922902">"i-pin ye-WPS <xliff:g id="P2P_WPS_PIN">%1$s</xliff:g> idinga ukufakiwa kudivayisi ye-peer <xliff:g id="P2P_CLIENT_ADDRESS">%2$s</xliff:g> ukuze isethaphu yohleloxhumano iqhubeke"</string>
     <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"I-Wi-Fi Direct ivulekile"</string>
-    <string name="wifi_p2p_enabled_notification_message" msgid="1638949953993894335">"Thinta ze uthole izisetho"</string>
+    <string name="wifi_p2p_enabled_notification_message" msgid="1638949953993894335">"Thinta ukuze uthole izilungiselelo"</string>
     <string name="select_character" msgid="3365550120617701745">"Faka uhlamvu"</string>
     <string name="sms_control_default_app_name" msgid="3058577482636640465">"insiza engaziwa"</string>
     <string name="sms_control_title" msgid="7296612781128917719">"Ithumela imiyalezo ye-SMS"</string>
@@ -1137,8 +1139,8 @@
     <string name="number_picker_decrement_button" msgid="2576606679160067262">"Decrement"</string>
     <string name="number_picker_increment_scroll_mode" msgid="1343063395404990189">"<xliff:g id="VALUE">%s</xliff:g> chofoza bese ucindezela."</string>
     <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Shishilizisa kwenyuke kuye ekwenyusweni kwehle kuye ekwehlisweni."</string>
-    <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Umzuzu wokwenyusa."</string>
-    <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Umzuzu wokwehlisa."</string>
+    <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Iminithi wokwenyusa"</string>
+    <string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Iminithi yokwehlisa"</string>
     <string name="time_picker_increment_hour_button" msgid="2484204991937119057">"Ihora lokwenyusa."</string>
     <string name="time_picker_decrement_hour_button" msgid="4659353501775842780">"Ihora lokwehlisa"</string>
     <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"Setha Ntambama"</string>
@@ -1153,7 +1155,7 @@
     <string name="checkbox_not_checked" msgid="5174639551134444056">"akuhloliwe"</string>
     <string name="radiobutton_selected" msgid="8603599808486581511">"Okukhethiwe"</string>
     <string name="radiobutton_not_selected" msgid="2908760184307722393">"akukhethiwe"</string>
-    <string name="switch_on" msgid="551417728476977311">"Ngomhla ka-"</string>
+    <string name="switch_on" msgid="551417728476977311">"vuliwe"</string>
     <string name="switch_off" msgid="7249798614327155088">"valiwe"</string>
     <string name="togglebutton_pressed" msgid="4180411746647422233">"kucindezelwe."</string>
     <string name="togglebutton_not_pressed" msgid="4495147725636134425">"akucindezelwe."</string>
@@ -1219,4 +1221,7 @@
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"Yabelana no"</string>
     <string name="status_bar_device_locked" msgid="3092703448690669768">"Idivayisi ivaliwe."</string>
     <string name="list_delimeter" msgid="3975117572185494152">", "</string>
+    <string name="sending" msgid="8715108995741758718">"Iyathumela..."</string>
+    <string name="launchBrowserDefault" msgid="2057951947297614725">"Qala Isiphequluli?"</string>
+    <string name="SetupCallDefault" msgid="6870275517518479651">"Amukela ucingo?"</string>
 </resources>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index d0ab8b1..af59198 100755
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -1493,6 +1493,10 @@
         <enum name="KEYCODE_LANGUAGE_SWITCH" value="204" />
         <enum name="KEYCODE_MANNER_MODE" value="205" />
         <enum name="KEYCODE_3D_MODE" value="206" />
+        <enum name="KEYCODE_CONTACTS" value="207" />
+        <enum name="KEYCODE_CALENDAR" value="208" />
+        <enum name="KEYCODE_MUSIC" value="209" />
+        <enum name="KEYCODE_CALCULATOR" value="210" />
     </attr>
 
     <!-- ***************************************************************** -->
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 326f186..3ab72f4 100755
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -747,4 +747,9 @@
 
     <!-- Name of screensaver components to look for if none has been chosen by the user -->
     <string name="config_defaultDreamComponent">com.google.android.deskclock/com.android.deskclock.Screensaver</string>
+
+    <!-- Base "touch slop" value used by ViewConfiguration as a
+         movement threshold where scrolling should begin. -->
+    <dimen name="config_viewConfigurationTouchSlop">8dp</dimen>
+
 </resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 8bcf343..f702657 100755
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
 <!--
 /* //device/apps/common/assets/res/any/strings.xml
 **
@@ -143,15 +143,15 @@
     <!-- Displayed to tell the user that normal service is blocked by access control. -->
     <string name="RestrictedOnNormal">Voice service is blocked.</string>
     <!-- Displayed to tell the user that all emergency and normal voice services are blocked by access control. -->
-    <string name="RestrictedOnAllVoice">All Voice services are blocked.</string>
+    <string name="RestrictedOnAllVoice">All voice services are blocked.</string>
     <!-- Displayed to tell the user that sms service is blocked by access control. -->
     <string name="RestrictedOnSms">SMS service is blocked.</string>
     <!-- Displayed to tell the user that voice/data service is blocked by access control. -->
-    <string name="RestrictedOnVoiceData">Voice/Data services are blocked.</string>
+    <string name="RestrictedOnVoiceData">Voice/data services are blocked.</string>
     <!-- Displayed to tell the user that voice and sms service are blocked by access control. -->
     <string name="RestrictedOnVoiceSms">Voice/SMS services are blocked.</string>
     <!-- Displayed to tell the user that all service is blocked by access control. -->
-    <string name="RestrictedOnAll">All Voice/Data/SMS services are blocked.</string>
+    <string name="RestrictedOnAll">All voice/data/SMS services are blocked.</string>
 
     <!-- Mappings between TS 27.007 +CFCC/+CLCK "service classes" and human-readable strings--> <skip />
     <!-- Example: Service was enabled for: Voice, Data -->
@@ -217,19 +217,19 @@
     <!-- Displayed when a web request was successful. -->
     <string name="httpErrorOk">OK</string>
     <!-- Displayed when a web request failed with a generic network error. -->
-    <string name="httpError">A network error occurred.</string>
+    <string name="httpError">There was a network error.</string>
     <!-- Displayed when a web request failed because the URL could not be found. -->
-    <string name="httpErrorLookup">The URL could not be found.</string>
+    <string name="httpErrorLookup">Couldn\'t find the URL.</string>
     <!-- Displayed when a web request failed because the site's authentication scheme is not supported by us. -->
     <string name="httpErrorUnsupportedAuthScheme">The site authentication scheme isn\'t supported.</string>
     <!-- Displayed when a web request failed because the authentication failed. -->
-    <string name="httpErrorAuth">Authentication was unsuccessful.</string>
+    <string name="httpErrorAuth">Couldn\'t authenticate.</string>
     <!-- Displayed when a web request failed because the authentication with the proxy failed. -->
     <string name="httpErrorProxyAuth">Authentication via the proxy server was unsuccessful.</string>
     <!-- Displayed when a web request failed because there was a connection error. -->
-    <string name="httpErrorConnect">The connection to the server was unsuccessful.</string>
+    <string name="httpErrorConnect">Couldn\'t connect to the server.</string>
     <!-- Displayed when a web request failed because there was an input or output error. -->
-    <string name="httpErrorIO">The server couldn\'t communicate. Try again later.</string>
+    <string name="httpErrorIO">Couldn\'t communicate with the server. Try again later.</string>
     <!-- Displayed when a web request failed because the request timed out -->
     <string name="httpErrorTimeout">The connection to the server timed out.</string>
     <!-- Displayed when a web request failed because the site tried to redirect us one too many times -->
@@ -237,13 +237,13 @@
     <!-- Displayed when a web request failed because the protocol of the server is not supported. -->
     <string name="httpErrorUnsupportedScheme">The protocol isn\'t supported.</string>
     <!-- Displayed when a web request failed because the a secure connection couldn't be made to the server.-->
-    <string name="httpErrorFailedSslHandshake">A secure connection could not be established.</string>
+    <string name="httpErrorFailedSslHandshake">Couldn\'t establish a secure connection.</string>
     <!-- Displayed when a web request failed because the URL isn't in a valid form. -->
-    <string name="httpErrorBadUrl">The page could not be opened because the URL is invalid.</string>
+    <string name="httpErrorBadUrl">Couldn\'t open the page because the URL is invalid.</string>
     <!-- Displayed when a request failed because we failed to open the file. -->
-    <string name="httpErrorFile">The file could not be accessed.</string>
+    <string name="httpErrorFile">Couldn\'t access the file.</string>
     <!-- Displayed when a request failed because the file wasn't found. -->
-    <string name="httpErrorFileNotFound">The requested file was not found.</string>
+    <string name="httpErrorFileNotFound">Couldn\'t find the requested file.</string>
     <!-- Displayed when a request failed because there are too many requests right now. -->
     <string name="httpErrorTooManyRequests">Too many requests are being processed. Try again later.</string>
 
@@ -252,7 +252,7 @@
     supply an auth token without prompting the user to re-enter the
     password.  This is the text that will scroll through the
     notification bar (will be seen by the user as he uses another application). -->
-    <string name="notification_title">Sign-in error for <xliff:g id="account" example="foo@gmail.com">%1$s</xliff:g></string>
+    <string name="notification_title">Signin error for <xliff:g id="account" example="foo@gmail.com">%1$s</xliff:g></string>
 
     <!-- Sync notifications --> <skip />
     <!-- A notification is shown when there is a sync error.  This is the text that will scroll through the notification bar (will be seen by the user as he uses another application). -->
@@ -263,9 +263,9 @@
     <string name="contentServiceTooManyDeletesNotificationDesc">Too many <xliff:g id="content_type">%s</xliff:g> deletes.</string>
 
     <!-- If MMS discovers there isn't much space left on the device, it will show a toast with this message. -->
-    <string name="low_memory" product="tablet">Tablet storage is full! Delete some files to free space.</string>
+    <string name="low_memory" product="tablet">Tablet storage is full. Delete some files to free space.</string>
     <!-- If MMS discovers there isn't much space left on the device, it will show a toast with this message. -->
-    <string name="low_memory" product="default">Phone storage is full! Delete some files to free space.</string>
+    <string name="low_memory" product="default">Phone storage is full. Delete some files to free space.</string>
 
 
     <!-- Display name for any time a piece of data refers to the owner of the phone. For example, this could be used in place of the phone's phone number. -->
@@ -286,6 +286,12 @@
     <string name="screen_lock">Screen lock</string>
     <!-- Button to turn off the phone, within the Phone Options dialog -->
     <string name="power_off">Power off</string>
+    <!-- Spoken description for ringer silent option. [CHAR LIMIT=NONE] -->
+    <string name="silent_mode_silent">Ringer off</string>
+    <!-- Spoken description for ringer vibrate option. [CHAR LIMIT=NONE] -->
+    <string name="silent_mode_vibrate">Ringer vibrate</string>
+    <!-- Spoken description for ringer normal option. [CHAR LIMIT=NONE] -->
+    <string name="silent_mode_ring">Ringer on</string>
 
     <!-- Shutdown Progress Dialog. This is shown if the user chooses to power off the phone. -->
     <string name="shutdown_progress">Shutting down\u2026</string>
@@ -359,8 +365,7 @@
     <!-- Title of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permgrouplab_costMoney">Services that cost you money</string>
     <!-- Description of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
-    <string name="permgroupdesc_costMoney">Allow apps to do things
-        that can cost you money.</string>
+    <string name="permgroupdesc_costMoney">Do things that can cost you money.</string>
 
     <!-- Title of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permgrouplab_messages">Your messages</string>
@@ -379,12 +384,12 @@
     <!-- Title of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permgrouplab_location">Your location</string>
     <!-- Description of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
-    <string name="permgroupdesc_location">Monitor your physical location</string>
+    <string name="permgroupdesc_location">Monitor your physical location.</string>
 
     <!-- Title of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permgrouplab_network">Network communication</string>
     <!-- Description of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
-    <string name="permgroupdesc_network">Allow apps to access various network features.</string>
+    <string name="permgroupdesc_network">Access various network features.</string>
 
     <!-- Title of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permgrouplab_accounts">Your accounts</string>
@@ -433,8 +438,7 @@
     <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permlab_expandStatusBar">expand/collapse status bar</string>
     <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
-    <string name="permdesc_expandStatusBar">Allows the app to
-        expand or collapse the status bar.</string>
+    <string name="permdesc_expandStatusBar">Allows the app to expand or collapse the status bar.</string>
 
     <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permlab_processOutgoingCalls">intercept outgoing calls</string>
@@ -524,21 +528,21 @@
     <!-- Title of an application permission, allowing an application to remove/kill tasks -->
     <string name="permlab_removeTasks">stop running apps</string>
     <!-- Description of an application permission, allowing an application to remove/kill tasks -->
-    <string name="permdesc_removeTasks">Allows an app to remove
+    <string name="permdesc_removeTasks">Allows the app to remove
         tasks and kill their apps. Malicious apps may disrupt
         the behavior of other apps.</string>
 
     <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permlab_setDebugApp">enable app debugging</string>
     <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
-    <string name="permdesc_setDebugApp">Allows an app to turn
+    <string name="permdesc_setDebugApp">Allows the app to turn
         on debugging for another app. Malicious apps may use this
         to kill other apps.</string>
 
     <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permlab_changeConfiguration">change your UI settings</string>
     <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
-    <string name="permdesc_changeConfiguration">Allows an app to
+    <string name="permdesc_changeConfiguration">Allows the app to
         change the current configuration, such as the locale or overall font
         size.</string>
 
@@ -659,7 +663,7 @@
     <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permlab_internalSystemWindow">display unauthorized windows</string>
     <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
-    <string name="permdesc_internalSystemWindow">Allows an app to create 
+    <string name="permdesc_internalSystemWindow">Allows the app to create
         windows that are intended to be used by the internal system
         user interface. Not for use by normal apps.</string>
 
@@ -673,7 +677,7 @@
     <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permlab_setAnimationScale">modify global animation speed</string>
     <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
-    <string name="permdesc_setAnimationScale">Allows an app to change
+    <string name="permdesc_setAnimationScale">Allows the app to change
         the global animation speed (faster or slower animations) at any time.</string>
 
     <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
@@ -824,7 +828,7 @@
     <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permlab_anyCodecForPlayback">use any media decoder for playback</string>
     <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
-    <string name="permdesc_anyCodecForPlayback">Allows an application to use any installed
+    <string name="permdesc_anyCodecForPlayback">Allows the app to use any installed
         media decoder to decode for playback.</string>
 
     <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
@@ -1017,26 +1021,22 @@
     <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permlab_accessSurfaceFlinger">access SurfaceFlinger</string>
     <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
-    <string name="permdesc_accessSurfaceFlinger">Allows the app to use
-        SurfaceFlinger low-level features.</string>
+    <string name="permdesc_accessSurfaceFlinger">Allows the app to use SurfaceFlinger low-level features.</string>
 
     <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permlab_readFrameBuffer">read frame buffer</string>
     <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
-    <string name="permdesc_readFrameBuffer">Allows the app to
-        read the content of the frame buffer.</string>
+    <string name="permdesc_readFrameBuffer">Allows the app to read the content of the frame buffer.</string>
 
     <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permlab_modifyAudioSettings">change your audio settings</string>
     <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
-    <string name="permdesc_modifyAudioSettings">Allows the app to modify
-        global audio settings such as volume and routing.</string>
+    <string name="permdesc_modifyAudioSettings">Allows the app to modify global audio settings such as volume and routing.</string>
 
     <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permlab_recordAudio">record audio</string>
     <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
-    <string name="permdesc_recordAudio">Allows the app to access
-        the audio record path.</string>
+    <string name="permdesc_recordAudio">Allows the app to access the audio record path.</string>
 
     <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permlab_camera">take pictures and videos</string>
@@ -1061,11 +1061,9 @@
     <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permlab_reboot" product="default">force phone reboot</string>
     <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
-    <string name="permdesc_reboot" product="tablet">Allows the app to
-        force the tablet to reboot.</string>
+    <string name="permdesc_reboot" product="tablet">Allows the app to force the tablet to reboot.</string>
     <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
-    <string name="permdesc_reboot" product="default">Allows the app to
-        force the phone to reboot.</string>
+    <string name="permdesc_reboot" product="default">Allows the app to force the phone to reboot.</string>
 
     <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permlab_mount_unmount_filesystems">mount and unmount filesystems</string>
@@ -1106,14 +1104,12 @@
     <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permlab_vibrate">control vibrator</string>
     <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
-    <string name="permdesc_vibrate">Allows the app to control
-        the vibrator.</string>
+    <string name="permdesc_vibrate">Allows the app to control the vibrator.</string>
 
     <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permlab_flashlight">control flashlight</string>
     <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
-    <string name="permdesc_flashlight">Allows the app to control
-        the flashlight.</string>
+    <string name="permdesc_flashlight">Allows the app to control the flashlight.</string>
 
     <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permlab_manageUsb">manage preferences and permissions for USB devices</string>
@@ -1197,11 +1193,9 @@
     <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permlab_wakeLock" product="default">prevent phone from sleeping</string>
     <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
-    <string name="permdesc_wakeLock" product="tablet">Allows the app to prevent
-        the tablet from going to sleep.</string>
+    <string name="permdesc_wakeLock" product="tablet">Allows the app to prevent the tablet from going to sleep.</string>
     <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
-    <string name="permdesc_wakeLock" product="default">Allows the app to prevent
-        the phone from going to sleep.</string>
+    <string name="permdesc_wakeLock" product="default">Allows the app to prevent the phone from going to sleep.</string>
 
     <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permlab_devicePower" product="tablet">power tablet on or off</string>
@@ -1211,8 +1205,7 @@
     <string name="permdesc_devicePower" product="tablet">Allows the app to turn the
         tablet on or off.</string>
     <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
-    <string name="permdesc_devicePower" product="default">Allows the app to turn the
-        phone on or off.</string>
+    <string name="permdesc_devicePower" product="default">Allows the app to turn the phone on or off.</string>
 
     <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permlab_factoryTest">run in factory test mode</string>
@@ -1259,16 +1252,14 @@
     <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permlab_accountManagerService">act as the AccountManagerService</string>
     <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
-    <string name="permdesc_accountManagerService">Allows an app to make calls to AccountAuthenticators.</string>
+    <string name="permdesc_accountManagerService">Allows the app to make calls to AccountAuthenticators.</string>
 
     <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permlab_getAccounts">discover known accounts</string>
     <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
-    <string name="permdesc_getAccounts" product="tablet">Allows the app to get
-      the list of accounts known by the tablet.</string>
+    <string name="permdesc_getAccounts" product="tablet">Allows the app to get the list of accounts known by the tablet.</string>
     <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
-    <string name="permdesc_getAccounts" product="default">Allows the app to get
-      the list of accounts known by the phone.</string>
+    <string name="permdesc_getAccounts" product="default">Allows the app to get the list of accounts known by the phone.</string>
 
     <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permlab_authenticateAccounts">act as an account authenticator</string>
@@ -1352,11 +1343,9 @@
       the local Bluetooth phone, and to discover and pair with remote devices.</string>
 
     <string name="permlab_accessWimaxState">View WiMAX state</string>
-    <string name="permdesc_accessWimaxState">Allows an application to view
-      the information about the state of WiMAX.</string>
+    <string name="permdesc_accessWimaxState">Allows the app to view the information about the state of WiMAX.</string>
     <string name="permlab_changeWimaxState">Change WiMAX state</string>
-    <string name="permdesc_changeWimaxState">Allows an application to connect
-      to and disconnect from WiMAX network.</string>
+    <string name="permdesc_changeWimaxState">Allows the app to connect to and disconnect from WiMAX network.</string>
 
     <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permlab_bluetooth">create Bluetooth connections</string>
@@ -1461,14 +1450,14 @@
     <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permlab_modifyNetworkAccounting">modify network usage accounting</string>
     <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
-    <string name="permdesc_modifyNetworkAccounting">Allows an app to modify how network usage is accounted against apps. Not for use by normal apps.</string>
+    <string name="permdesc_modifyNetworkAccounting">Allows the app to modify how network usage is accounted against apps. Not for use by normal apps.</string>
 
     <!-- Policy administration -->
 
     <!-- Title of policy access to limiting the user's password choices -->
     <string name="policylab_limitPassword">Set password rules</string>
     <!-- Description of policy access to limiting the user's password choices -->
-    <string name="policydesc_limitPassword">Control the length and the characters allowed in screen-unlock passwords</string>
+    <string name="policydesc_limitPassword">Control the length and the characters allowed in screen-unlock passwords.</string>
     <!-- Title of policy access to watch user login attempts -->
     <string name="policylab_watchLogin">Monitor screen-unlock attempts</string>
     <!-- Description of policy access to watch user login attempts -->
@@ -1482,19 +1471,17 @@
     <!-- Title of policy access to reset user's password -->
     <string name="policylab_resetPassword">Change the screen-unlock password</string>
     <!-- Description of policy access to reset user's password -->
-    <string name="policydesc_resetPassword">Change the screen-unlock password</string>
+    <string name="policydesc_resetPassword">Change the screen-unlock password.</string>
     <!-- Title of policy access to force lock the device -->
     <string name="policylab_forceLock">Lock the screen</string>
     <!-- Description of policy access to limiting the user's password choices -->
-    <string name="policydesc_forceLock">Control how and when the screen locks</string>
+    <string name="policydesc_forceLock">Control how and when the screen locks.</string>
     <!-- Title of policy access to wipe the user's data -->
     <string name="policylab_wipeData">Erase all data</string>
     <!-- Description of policy access to wipe the user's data -->
-    <string name="policydesc_wipeData" product="tablet">Erase the tablet\'s data without warning,
-    by performing a factory data reset</string>
+    <string name="policydesc_wipeData" product="tablet">Erase the tablet\'s data without warning by performing a factory data reset.</string>
     <!-- Description of policy access to wipe the user's data -->
-    <string name="policydesc_wipeData" product="default">Erase the phone\'s data without warning,
-    by performing a factory data reset</string>
+    <string name="policydesc_wipeData" product="default">Erase the phone\'s data without warning by performing a factory data reset.</string>
     <string name="policylab_setGlobalProxy">Set the device global proxy</string>
     <!-- Description of policy access to wipe the user's data -->
     <string name="policydesc_setGlobalProxy">Set the device global proxy
@@ -1503,17 +1490,15 @@
     <!-- Title of policy access to enforce password expiration [CHAR LIMIT=30]-->
     <string name="policylab_expirePassword">Set lock-screen password expiration</string>
     <!-- Description of policy access to enforce password expiration [CHAR LIMIT=110]-->
-    <string name="policydesc_expirePassword">Control how frequently the lock-screen password must be
-  changed</string>
+    <string name="policydesc_expirePassword">Control how frequently the lock-screen password must be changed.</string>
     <!-- Title of policy access to require encrypted storage [CHAR LIMIT=30]-->
     <string name="policylab_encryptedStorage">Set storage encryption</string>
     <!-- Description of policy access to require encrypted storage [CHAR LIMIT=110]-->
-    <string name="policydesc_encryptedStorage">Require that stored app data be encrypted
-        </string>
+    <string name="policydesc_encryptedStorage">Require that stored app data be encrypted.</string>
     <!-- Title of policy access to disable all device cameras [CHAR LIMIT=30]-->
     <string name="policylab_disableCamera">Disable cameras</string>
     <!-- Description of policy access to disable all device cameras [CHAR LIMIT=110]-->
-    <string name="policydesc_disableCamera">Prevent use of all device cameras</string>
+    <string name="policydesc_disableCamera">Prevent use of all device cameras.</string>
 
     <!-- The order of these is important, don't reorder without changing Contacts.java --> <skip />
     <!-- Phone number types from android.provider.Contacts. This could be used when adding a new phone number for a contact, for example. -->
@@ -1751,7 +1736,7 @@
 
     <!-- Instructions telling the user that they entered the wrong pin while trying
          to unlock the keyguard.  Displayed in one line in a large font.  -->
-    <string name="keyguard_password_wrong_pin_code">Incorrect PIN code!</string>
+    <string name="keyguard_password_wrong_pin_code">Incorrect PIN code.</string>
 
     <!-- Instructions telling the user how to unlock the phone. -->
     <string name="keyguard_label_text">To unlock, press Menu then 0.</string>
@@ -1787,6 +1772,8 @@
     <string name="lockscreen_pattern_wrong">Try again</string>
     <!-- On the unlock password screen, shown when the user enters the wrong lock password and must try again. -->
     <string name="lockscreen_password_wrong">Try again</string>
+    <!-- Shown when face unlock failed multiple times so we're just using the backup -->
+    <string name="faceunlock_multiple_failures">Maximum Face Unlock attempts exceeded</string>
 
     <!-- When the lock screen is showing and the phone plugged in, and the battery
          is not fully charged, show the current charge %.  -->
@@ -1930,9 +1917,9 @@
     <string name="lockscreen_glogin_forgot_pattern">Account unlock</string>
     <!-- Title of the unlock screen that uses your Google login and password when the user attempted
          too many patterns and we are forcing them to use their account instead. -->
-    <string name="lockscreen_glogin_too_many_attempts">Too many pattern attempts!</string>
+    <string name="lockscreen_glogin_too_many_attempts">Too many pattern attempts</string>
     <!-- In the unlock screen, message telling the user that they need to use their Google login and password to unlock the phone -->
-    <string name="lockscreen_glogin_instructions">To unlock, sign in with your Google account</string>
+    <string name="lockscreen_glogin_instructions">To unlock, sign in with your Google account.</string>
     <!-- Hint caption for the username field when unlocking the phone using login and password -->
     <string name="lockscreen_glogin_username_hint">Username (email)</string>
     <!-- Hint caption for the password field when unlocking the phone using login and password -->
@@ -1942,10 +1929,10 @@
     <!-- Displayed to the user when unlocking the phone with a username and password fails. -->
     <string name="lockscreen_glogin_invalid_input">Invalid username or password.</string>
     <!-- Hint displayed on account unlock screen to advise the user on how to recover the account. -->
-    <string name="lockscreen_glogin_account_recovery_hint">Forgot your username or password\?\nVisit <b>google.com/accounts/recovery</b></string>
+    <string name="lockscreen_glogin_account_recovery_hint">Forgot your username or password\?\nVisit <b>google.com/accounts/recovery</b>.</string>
 
     <!-- Displayed in a progress dialog while a username and password are being checked. -->
-    <string name="lockscreen_glogin_checking_password">Checking...</string>
+    <string name="lockscreen_glogin_checking_password">Checking\u2026</string>
     <!-- Displayed on lock screen's left tab - unlock -->
     <string name="lockscreen_unlock_label">Unlock</string>
     <!-- Displayed on lock screen's right tab - turn sound on -->
@@ -1994,7 +1981,7 @@
     <string name="web_user_agent_target_content" translatable="false">"Mobile "</string>
 
     <!-- Title for a JavaScript dialog. "The page at <url of current page> says:" -->
-    <string name="js_dialog_title">The page at \'<xliff:g id="title">%s</xliff:g>\' says:</string>
+    <string name="js_dialog_title">The page at \"<xliff:g id="title">%s</xliff:g>\" says:</string>
     <!-- Default title for a javascript dialog -->
     <string name="js_dialog_title_default">JavaScript</string>
     <!-- Message in a javascript dialog asking if the user wishes to leave the
@@ -2008,9 +1995,9 @@
     <string name="double_tap_toast">Tip: Double-touch to zoom in and out.</string>
 
     <!-- Text to show in the auto complete drop down list on a text view when the WebView can auto fill the entire form, and the user has configured an AutoFill profile [CHAR-LIMIT=8] -->
-    <string name="autofill_this_form">AutoFill</string>
-    <!-- Text to show in the auto complete drop down list on a text view when the WebView can auto fill the entire form but the user has not configured an AutoFill profile [CHAR-LIMIT=16] -->
-    <string name="setup_autofill">Setup AutoFill</string>
+    <string name="autofill_this_form">Autofill</string>
+    <!-- Text to show in the auto complete drop down list on a text view when the WebView can auto fill the entire form but the user has not configured an AutoFill profile [CHAR-LIMIT=19] -->
+    <string name="setup_autofill">Set up Autofill</string>
 
     <!-- String used to separate FirstName and LastName when writing out a local name
          e.g. John<separator>Smith [CHAR-LIMIT=NONE]-->
@@ -2437,11 +2424,11 @@
 
 
     <!-- Title for error alert when a video cannot be played.  it can be used by any app. -->
-    <string name="VideoView_error_title">Can\'t play video</string>
+    <string name="VideoView_error_title">Video problem</string>
     <!-- Text for error alert when a video container is not valid for progressive download/playback. -->
     <string name="VideoView_error_text_invalid_progressive_playback">This video isn\'t valid for streaming to this device.</string>
     <!-- Text for error alert when a video cannot be played. it can be used by any app. -->
-    <string name="VideoView_error_text_unknown">This video can\'t be played.</string>
+    <string name="VideoView_error_text_unknown">Can\'t play this video.</string>
     <!-- Button to close error alert when a video cannot be played -->
     <string name="VideoView_error_button">OK</string>
 
@@ -2552,7 +2539,7 @@
     <!-- Text displayed when the user selects the check box for setting default application.  See the "Use by default for this action" check box. -->
     <string name="clearDefaultHintMsg">Clear default in System settings &gt; Apps &gt; Downloaded.</string>
     <!-- Default title for the activity chooser, when one is not given. Android allows multiple activities to perform an action.  for example, there may be many ringtone pickers installed.  A dialog is shown to the user allowing him to pick which activity should be used.  This is the title. -->
-    <string name="chooseActivity">Select an action</string>
+    <string name="chooseActivity">Choose an action</string>
     <!-- title for the USB activity chooser. -->
     <string name="chooseUsbActivity">Choose an app for the USB device</string>
     <!-- Text to display when there are no activities found to display in the
@@ -2638,7 +2625,7 @@
          is to be sent to another application. For example, I can send
          text through SMS or IM.  A dialog with those choices would be shown,
          and this would be the title. -->
-    <string name="sendText">Select an action for text</string>
+    <string name="sendText">Choose an action for text</string>
 
     <!-- Title of the dialog where the user is adjusting the phone ringer volume -->
     <string name="volume_ringtone">Ringer volume</string>
@@ -2647,7 +2634,7 @@
     <!-- Hint shown in the volume toast to inform the user that the media audio is playing through Bluetooth. -->
     <string name="volume_music_hint_playing_through_bluetooth">Playing through Bluetooth</string>
     <!-- Hint shown in the volume toast to inform the user that the current ringtone is the silent ringtone. -->
-    <string name="volume_music_hint_silent_ringtone_selected">Silent ringtone selected</string>
+    <string name="volume_music_hint_silent_ringtone_selected">Silent ringtone set</string>
     <!-- Title of the dialog where the user is adjusting the phone call volume -->
     <string name="volume_call">In-call volume</string>
     <!-- Title of the dialog where the user is adjusting the phone call volume when connected on bluetooth-->
@@ -2694,7 +2681,7 @@
     </plurals>
 
     <!-- A notification is shown when a captive portal network is detected.  This is the notification's title. -->
-    <string name="wifi_available_sign_in">Sign in to Wi-Fi network</string>
+    <string name="wifi_available_sign_in">Sign into Wi-Fi network</string>
 
     <!-- A notification is shown when a captive portal network is detected.  This is the notification's message. -->
     <string name="wifi_available_sign_in_detailed"><xliff:g id="wifi_network_ssid">%1$s</xliff:g></string>
@@ -2702,18 +2689,26 @@
      <!-- A notification is shown when a user's selected SSID is later disabled due to connectivity problems.  This is the notification's title / ticker. -->
      <string name="wifi_watchdog_network_disabled">Couldn\'t connect to Wi-Fi</string>
      <!-- A notification is shown when a user's selected SSID is later disabled due to connectivity problems.  The complete alert msg is: <hotspot name> + this string, i.e. "Linksys has a poor internet connection" -->
-    <string name="wifi_watchdog_network_disabled_detailed">\u0020has a poor internet connection.</string>
+    <string name="wifi_watchdog_network_disabled_detailed">\u0020has a poor Internet connection.</string>
 
     <!-- Do not translate. Default access point SSID used for tethering -->
     <string name="wifi_tether_configure_ssid_default" translatable="false">AndroidAP</string>
 
     <!-- Wi-Fi p2p dialog title-->
     <string name="wifi_p2p_dialog_title">Wi-Fi Direct</string>
-    <string name="wifi_p2p_turnon_message">Start Wi-Fi Direct operation. This will turn off Wi-Fi client/hotspot operation.</string>
-    <string name="wifi_p2p_failed_message">Couldn\'t start Wi-Fi Direct</string>
-    <string name="wifi_p2p_pbc_go_negotiation_request_message">Wi-Fi Direct connection setup request from <xliff:g id="p2p_device_address">%1$s</xliff:g>. Click OK to accept. </string>
-    <string name="wifi_p2p_pin_go_negotiation_request_message">Wi-Fi Direct connection setup request from <xliff:g id="p2p_device_address">%1$s</xliff:g>. Enter pin to proceed. </string>
-    <string name="wifi_p2p_pin_display_message">WPS pin <xliff:g id="p2p_wps_pin">%1$s</xliff:g> needs to be entered on the peer device <xliff:g id="p2p_client_address">%2$s</xliff:g> for connection setup to proceed </string>
+    <string name="wifi_p2p_turnon_message">Start Wi-Fi Direct. This will turn off Wi-Fi client/hotspot.</string>
+    <string name="wifi_p2p_failed_message">Couldn\'t start Wi-Fi Direct.</string>
+
+    <string name="accept">Accept</string>
+    <string name="decline">Decline</string>
+    <string name="wifi_p2p_invitation_sent_title">Invitation sent</string>
+    <string name="wifi_p2p_invitation_to_connect_title">Invitation to connect</string>
+
+    <string name="wifi_p2p_from_message">From: </string>
+    <string name="wifi_p2p_to_message">To: </string>
+    <string name="wifi_p2p_enter_pin_message">Type the required PIN: </string>
+    <string name="wifi_p2p_show_pin_message">PIN: </string>
+
     <string name="wifi_p2p_enabled_notification_title">Wi-Fi Direct is on</string>
     <string name="wifi_p2p_enabled_notification_message">Touch for settings</string>
 
@@ -2742,7 +2737,7 @@
     <!-- See SIM_ADDED_DIALOG.  This is the title of that dialog. -->
     <string name="sim_added_title">SIM card added</string>
     <!-- See SIM_ADDED_DIALOG.  This is the message of that dialog. -->
-    <string name="sim_added_message">You must restart your device to access the mobile network.</string>
+    <string name="sim_added_message">Restart your device to access the mobile network.</string>
     <!-- See SIM_ADDED_DIALOG.  This is the button of that dialog. -->
     <string name="sim_restart_button">Restart</string>
 
@@ -2769,47 +2764,47 @@
 
     <!-- USB storage dialog strings -->
     <!-- This is the title for the activity's window. -->
-    <string name="usb_storage_activity_title">USB Mass Storage</string>
+    <string name="usb_storage_activity_title">USB mass storage</string>
 
     <!-- See USB_STORAGE.  USB_STORAGE_DIALOG:  After the user selects the notification, a dialog is shown asking if he wants to mount.  This is the title. -->
     <string name="usb_storage_title">USB connected</string>
     <!-- See USB_STORAGE.    This is the message. [CHAR LIMIT=NONE] -->
-    <string name="usb_storage_message" product="nosdcard">You have connected to your computer via USB. Touch the button below if you want to copy files between your computer and your Android\u2018s USB storage.</string>
+    <string name="usb_storage_message" product="nosdcard">You\'ve connected to your computer via USB. Touch the button below if you want to copy files between your computer and your Android\'s USB storage.</string>
     <!-- See USB_STORAGE.    This is the message. [CHAR LIMIT=NONE] -->
-    <string name="usb_storage_message" product="default">You have connected to your computer via USB. Touch the button below if you want to copy files between your computer and your Android\u2018s SD card.</string>
+    <string name="usb_storage_message" product="default">You\'ve connected to your computer via USB. Touch the button below if you want to copy files between your computer and your Android\'s SD card.</string>
     <!-- See USB_STORAGE.    This is the button text to mount the phone on the computer. -->
     <string name="usb_storage_button_mount">Turn on USB storage</string>
     <!-- See USB_STORAGE_DIALOG.  If there was an error mounting, this is the text. [CHAR LIMIT=NONE] -->
-    <string name="usb_storage_error_message" product="nosdcard">There is a problem using your USB storage for USB mass storage.</string>
+    <string name="usb_storage_error_message" product="nosdcard">There\'s a problem using your USB storage for USB mass storage.</string>
     <!-- See USB_STORAGE_DIALOG.  If there was an error mounting, this is the text. -->
-    <string name="usb_storage_error_message" product="default">There is a problem using your SD card for USB mass storage.</string>
+    <string name="usb_storage_error_message" product="default">There\'s a problem using your SD card for USB mass storage.</string>
     <!-- USB_STORAGE: When the user connects the phone to a computer via USB, we show a notification asking if he wants to share files across.  This is the title -->
     <string name="usb_storage_notification_title">USB connected</string>
     <!-- See USB_STORAGE. This is the message. -->
-    <string name="usb_storage_notification_message">Select to copy files to/from your computer.</string>
+    <string name="usb_storage_notification_message">Touch to copy files to/from your computer.</string>
 
     <!-- USB_STORAGE_STOP: While USB storage is enabled, we show a notification dialog asking if he wants to stop. This is the title -->
     <string name="usb_storage_stop_notification_title">Turn off USB storage</string>
     <!-- See USB_STORAGE. This is the message. -->
-    <string name="usb_storage_stop_notification_message">Select to turn off USB storage.</string>
+    <string name="usb_storage_stop_notification_message">Touch to turn off USB storage.</string>
 
     <!-- USB storage stop dialog strings -->
     <!-- This is the label for the activity, and should never be visible to the user. -->
     <!-- See USB_STORAGE_STOP.  USB_STORAGE_STOP_DIALOG:  After the user selects the notification, a dialog is shown asking if he wants to stop usb storage.  This is the title. -->
     <string name="usb_storage_stop_title">USB storage in use</string>
     <!-- See USB_STORAGE_STOP.    This is the message. [CHAR LIMIT=NONE] -->
-    <string name="usb_storage_stop_message" product="nosdcard">Before turning off USB storage, make sure you have unmounted (\u201cejected\u201d) your Android\u2018s USB storage from your computer.</string>
+    <string name="usb_storage_stop_message" product="nosdcard">Before turning off USB storage, unmount (\"eject\") your Android\'s USB storage from your computer.</string>
     <!-- See USB_STORAGE_STOP.    This is the message. -->
-    <string name="usb_storage_stop_message" product="default">Before turning off USB storage, make sure you have unmounted (\u201cejected\u201d) your Android\u2018s SD card from your computer.</string>
+    <string name="usb_storage_stop_message" product="default">Before turning off USB storage, unmount (\"eject\") your Android\'s SD card from your computer.</string>
     <!-- See USB_STORAGE_STOP.    This is the button text to stop usb storage. -->
     <string name="usb_storage_stop_button_mount">Turn off USB storage</string>
     <!-- See USB_STORAGE_STOP_DIALOG.  If there was an error stopping, this is the text. -->
-    <string name="usb_storage_stop_error_message">There was a problem turning off USB storage. Check to make sure you have unmounted the USB host, then try again.</string>
+    <string name="usb_storage_stop_error_message">There was a problem turning off USB storage. Check that you\'ve unmounted the USB host, then try again.</string>
 
     <!-- USB_STORAGE_KILL_STORAGE_USERS dialog  -->
     <string name="dlg_confirm_kill_storage_users_title">Turn on USB storage</string>
     <!-- USB_STORAGE_KILL_STORAGE_USERS dialog message text -->
-    <string name="dlg_confirm_kill_storage_users_text">If you turn on USB storage, some apps you are using will stop and may be unavailable until you turn off USB storage.</string>
+    <string name="dlg_confirm_kill_storage_users_text">If you turn on USB storage, some apps you\'re using will stop and may be unavailable until you turn off USB storage.</string>
     <!-- USB_STORAGE_ERROR dialog  dialog-->
     <string name="dlg_error_title">USB operation unsuccessful</string>
     <!-- USB_STORAGE_ERROR dialog  ok button-->
@@ -2824,7 +2819,7 @@
     <!-- USB_PREFERENCES: Notification for when a USB accessory is attached.  This is the title -->
     <string name="usb_accessory_notification_title">Connected to a USB accessory</string>
     <!-- See USB_PREFERENCES. This is the message. -->
-    <string name="usb_notification_message">Touch for other USB options</string>
+    <string name="usb_notification_message">Touch for other USB options.</string>
 
     <!-- External media format dialog strings -->
     <!-- This is the label for the activity, and should never be visible to the user. -->
@@ -2873,16 +2868,16 @@
     <!-- Shown when external media is blank (or unsupported filesystem) -->
     <string name="ext_media_nofs_notification_title" product="default">Blank SD card</string>
     <!-- Shown when USB storage cannot be read.  [CHAR LIMIT=NONE] -->
-    <string name="ext_media_nofs_notification_message" product="nosdcard">USB storage blank or has unsupported filesystem.</string>
-    <string name="ext_media_nofs_notification_message" product="default">SD card blank or has unsupported filesystem.</string>
+    <string name="ext_media_nofs_notification_message" product="nosdcard">USB storage is blank or has unsupported filesystem.</string>
+    <string name="ext_media_nofs_notification_message" product="default">SD card is blank or has unsupported filesystem.</string>
 
     <!-- Shown when external media is unmountable (corrupt)) [CHAR LIMIT=30] -->
     <string name="ext_media_unmountable_notification_title" product="nosdcard">Damaged USB storage</string>
     <!-- Shown when external media is unmountable (corrupt)) -->
     <string name="ext_media_unmountable_notification_title" product="default">Damaged SD card</string>
     <!-- Shown when USB storage cannot be read.  [CHAR LIMIT=NONE] -->
-    <string name="ext_media_unmountable_notification_message" product="nosdcard">USB storage damaged. You may have to reformat it.</string>
-    <string name="ext_media_unmountable_notification_message" product="default">SD card damaged. You may have to reformat it.</string>
+    <string name="ext_media_unmountable_notification_message" product="nosdcard">USB storage is damaged. Try reformatting it.</string>
+    <string name="ext_media_unmountable_notification_message" product="default">SD card is damaged. Try reformatting it.</string>
 
     <!-- Shown when external media is unsafely removed [CHAR LIMIT=30] -->
     <string name="ext_media_badremoval_notification_title" product="nosdcard">USB storage unexpectedly removed</string>
@@ -2909,7 +2904,7 @@
     <string name="ext_media_nomedia_notification_message" product="default">SD card removed. Insert a new one.</string>
 
     <!-- Shown in LauncherActivity when the requested target Intent didn't return any matching Activities, leaving the list empty. -->
-    <string name="activity_list_empty">No matching activities found</string>
+    <string name="activity_list_empty">No matching activities found.</string>
 
     <!-- permission attributes related to package usage statistics -->
     <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
@@ -2929,7 +2924,7 @@
 
     <!-- Shown in gadget hosts (e.g. the home screen) when there was an error inflating
     the gadget. -->
-    <string name="gadget_host_error_inflating">Error inflating widget</string>
+    <string name="gadget_host_error_inflating">Couldn\'t add widget.</string>
 
     <!-- Long label for a button on a full-screen input method for the "Go" action. -->
     <string name="ime_action_go">Go</string>
@@ -2971,11 +2966,11 @@
 
     <string name="grant_credentials_permission_message_header">The following one or more apps request permission to access your account, now and in the future.</string>
     <string name="grant_credentials_permission_message_footer">Do you want to allow this request?</string>
-    <string name="grant_permissions_header_text">Access Request</string>
+    <string name="grant_permissions_header_text">Access request</string>
     <string name="allow">Allow</string>
     <string name="deny">Deny</string>
-    <string name="permission_request_notification_title">Permission Requested</string>
-    <string name="permission_request_notification_with_subtitle">Permission Requested\nfor account <xliff:g id="account" example="foo@gmail.com">%s</xliff:g></string>
+    <string name="permission_request_notification_title">Permission requested</string>
+    <string name="permission_request_notification_with_subtitle">Permission requested\nfor account <xliff:g id="account" example="foo@gmail.com">%s</xliff:g>.</string>
 
     <!-- Label to show for a service that is running because it is an input method. -->
     <string name="input_method_binding_label">Input method</string>
@@ -2992,13 +2987,13 @@
     <string name="alternate_eri_file">/data/eri.xml</string>
 
     <!-- The title of the notification when VPN is active. -->
-    <string name="vpn_title">VPN is activated.</string>
+    <string name="vpn_title">VPN activated</string>
     <!-- The title of the notification when VPN is active with an application name. -->
     <string name="vpn_title_long">VPN is activated by <xliff:g id="app" example="FooVPN client">%s</xliff:g></string>
     <!-- The text of the notification when VPN is active. -->
-    <string name="vpn_text">Tap to manage the network.</string>
+    <string name="vpn_text">Touch to manage the network.</string>
     <!-- The text of the notification when VPN is active with a session name. -->
-    <string name="vpn_text_long">Connected to <xliff:g id="session" example="office">%s</xliff:g>. Tap to manage the network.</string>
+    <string name="vpn_text_long">Connected to <xliff:g id="session" example="office">%s</xliff:g>. Touch to manage the network.</string>
 
     <!-- Localized strings for WebView -->
     <!-- Label for button in a WebView that will open a chooser to choose a file to upload -->
@@ -3013,12 +3008,12 @@
     <!-- Strings for car mode notification -->
     <!-- Shown when car mode is enabled -->
     <string name="car_mode_disable_notification_title">Car mode enabled</string>
-    <string name="car_mode_disable_notification_message">Select to exit car mode.</string>
+    <string name="car_mode_disable_notification_message">Touch to exit car mode.</string>
 
     <!-- Strings for tethered notification -->
     <!-- Shown when the device is tethered -->
     <string name="tethered_notification_title">Tethering or hotspot active</string>
-    <string name="tethered_notification_message">Touch to configure</string>
+    <string name="tethered_notification_message">Touch to set up.</string>
 
     <!--  Strings for possible PreferenceActivity Back/Next buttons -->
     <string name="back_button_label">Back</string>
@@ -3030,12 +3025,12 @@
     <!-- Strings for throttling notification -->
     <!-- Shown when the user is in danger of being throttled -->
     <string name="throttle_warning_notification_title">High mobile data use</string>
-    <string name="throttle_warning_notification_message">Touch to learn more about mobile data use</string>
+    <string name="throttle_warning_notification_message">Touch to learn more about mobile data use.</string>
 
     <!-- Strings for throttling notification -->
     <!-- Shown when the users bandwidth is reduced because of excessive data use -->
     <string name="throttled_notification_title">Mobile data limit exceeded</string>
-    <string name="throttled_notification_message">Touch to learn more about mobile data use</string>
+    <string name="throttled_notification_message">Touch to learn more about mobile data use.</string>
 
     <!-- Displayed on the Find dialog when there are no matches [CHAR LIMIT=NONE]-->
     <string name="no_matches">No matches</string>
@@ -3057,13 +3052,13 @@
 
     <!-- Strings for ExternalStorageFormatter service. -->
     <!-- Text for progress dialog while unmounting USB storage volume [CHAR LIMIT=NONE] -->
-    <string name="progress_unmounting" product="nosdcard">Unmounting USB storage...</string>
+    <string name="progress_unmounting" product="nosdcard">Unmounting USB storage\u2026</string>
     <!-- Text for progress dialog while unmounting SD card [CHAR LIMIT=NONE] -->
-    <string name="progress_unmounting" product="default">Unmounting SD card...</string>
+    <string name="progress_unmounting" product="default">Unmounting SD card\u2026</string>
     <!-- Text for progress dialog while erasing USB storage volume [CHAR LIMIT=NONE] -->
-    <string name="progress_erasing" product="nosdcard">Erasing USB storage...</string>
+    <string name="progress_erasing" product="nosdcard">Erasing USB storage\u2026</string>
     <!-- Text for progress dialog while erasing SD card [CHAR LIMIT=NONE] -->
-    <string name="progress_erasing" product="default">Erasing SD card...</string>
+    <string name="progress_erasing" product="default">Erasing SD card\u2026</string>
     <!-- Text for message to user that an error happened when formatting USB storage [CHAR LIMIT=NONE] -->
     <string name="format_error" product="nosdcard">Couldn\'t erase USB storage.</string>
     <!-- Text for message to user that an error happened when formatting SD card [CHAR LIMIT=NONE] -->
@@ -3110,19 +3105,19 @@
     <!-- Error message when the sync tried to delete too many things -->
     <string name="sync_too_many_deletes">Delete limit exceeded</string>
     <!-- Dialog message for when there are too many deletes that would take place and we want user confirmation -->
-    <string name="sync_too_many_deletes_desc">There are <xliff:g id="number_of_deleted_items">%1$d</xliff:g> deleted items for <xliff:g id="type_of_sync">%2$s</xliff:g>, account <xliff:g id="account_name">%3$s</xliff:g>. What would you like to do?</string>
+    <string name="sync_too_many_deletes_desc">There are <xliff:g id="number_of_deleted_items">%1$d</xliff:g> deleted items for <xliff:g id="type_of_sync">%2$s</xliff:g>, account <xliff:g id="account_name">%3$s</xliff:g>. What do you want to do?</string>
     <!-- Dialog action for when there are too many deletes that would take place and we want user confirmation, and the user wants to delete the items -->
-    <string name="sync_really_delete">Delete the items.</string>
+    <string name="sync_really_delete">Delete the items</string>
     <!-- Dialog action for when there are too many deletes that would take place and we want user confirmation, and the user wants to undo the deletions -->
-    <string name="sync_undo_deletes">Undo the deletes.</string>
+    <string name="sync_undo_deletes">Undo the deletes</string>
     <!-- Dialog action for when there are too many deletes that would take place and we want user confirmation, and the user wants to do nothing for now -->
-    <string name="sync_do_nothing">Do nothing for now.</string>
+    <string name="sync_do_nothing">Do nothing for now</string>
 
     <!-- Choose Account Activity label -->
     <string name="choose_account_label">Choose an account</string>
 
     <string name="add_account_label">"Add an account"</string>
-    <string name="choose_account_text">"Which account would you like to use?"</string>
+    <string name="choose_account_text">"Which account do you want to use?"</string>
 
     <!-- Button label to add an account [CHAR LIMIT=20] -->
     <string name="add_account_button_label">Add account</string>
@@ -3133,7 +3128,7 @@
     <!-- Description of the button to decrement the NumberPicker value. [CHAR LIMIT=NONE] -->
     <string name="number_picker_decrement_button">Decrement</string>
     <!-- Description of the tap and hold action to get into scroll mode in NumberPicker. [CHAR LIMIT=NONE] -->
-    <string name="number_picker_increment_scroll_mode"><xliff:g id="value" example="3">%s</xliff:g> tap and hold.</string>
+    <string name="number_picker_increment_scroll_mode"><xliff:g id="value" example="3">%s</xliff:g> touch and hold.</string>
     <!-- Description of the scrolling action in NumberPicker. [CHAR LIMIT=NONE] -->
     <string name="number_picker_increment_scroll_action">Slide up to increment and down to decrement.</string>
 
@@ -3242,7 +3237,7 @@
     <string name="description_target_unlock_tablet">Swipe to unlock.</string>
 
     <!-- Announce that a headset is required to hear keyboard keys while typing a password. [CHAR LIMIT=NONE] -->
-    <string name="keyboard_headset_required_to_hear_password">Plug in a headset to hear password keys spoken aloud.</string>
+    <string name="keyboard_headset_required_to_hear_password">Plug in a headset to hear password keys spoken.</string>
     <!-- The value of a keyboard key announced when accessibility is enabled and no headsed is used. [CHAR LIMIT=NONE] -->
     <string name="keyboard_password_character_no_headset">Dot.</string>
 
@@ -3254,21 +3249,21 @@
     <string name="action_menu_overflow_description">More options</string>
 
     <!-- Storage description for internal storage. [CHAR LIMIT=NONE] -->
-    <string name="storage_internal">Internal Storage</string>
+    <string name="storage_internal">Internal storage</string>
 
     <!-- Storage description for the SD card. [CHAR LIMIT=NONE] -->
-    <string name="storage_sd_card">SD Card</string>
+    <string name="storage_sd_card">SD card</string>
 
     <!-- Storage description for USB storage. [CHAR LIMIT=NONE] -->
     <string name="storage_usb">USB storage</string>
 
     <!-- Button text for the edit menu in input method extract mode. [CHAR LIMIT=16] -->
-    <string name="extract_edit_menu_button">Edit...</string>
+    <string name="extract_edit_menu_button">Edit</string>
 
     <!-- Notification title when data usage has exceeded warning threshold. [CHAR LIMIT=32] -->
     <string name="data_usage_warning_title">Data usage warning</string>
     <!-- Notification body when data usage has exceeded warning threshold. [CHAR LIMIT=32] -->
-    <string name="data_usage_warning_body">Touch to view usage and settings</string>
+    <string name="data_usage_warning_body">Touch to view usage and settings.</string>
 
     <!-- Notification title when 2G-3G data usage has exceeded limit threshold, and has been disabled. [CHAR LIMIT=32] -->
     <string name="data_usage_3g_limit_title">2G-3G data disabled</string>
@@ -3279,7 +3274,7 @@
     <!-- Notification title when Wi-Fi data usage has exceeded limit threshold, and has been disabled. [CHAR LIMIT=32] -->
     <string name="data_usage_wifi_limit_title">Wi-Fi data disabled</string>
     <!-- Notification body when data usage has exceeded limit threshold, and has been disabled. [CHAR LIMIT=32] -->
-    <string name="data_usage_limit_body">Touch to enable</string>
+    <string name="data_usage_limit_body">Touch to enable.</string>
 
     <!-- Notification title when 2G-3G data usage has exceeded limit threshold. [CHAR LIMIT=32] -->
     <string name="data_usage_3g_limit_snoozed_title">2G-3G data limit exceeded</string>
@@ -3290,12 +3285,12 @@
     <!-- Notification title when Wi-Fi data usage has exceeded limit threshold. [CHAR LIMIT=32] -->
     <string name="data_usage_wifi_limit_snoozed_title">Wi-Fi data limit exceeded</string>
     <!-- Notification body when data usage has exceeded limit threshold. [CHAR LIMIT=32] -->
-    <string name="data_usage_limit_snoozed_body"><xliff:g id="size" example="3.8GB">%s</xliff:g> over specified limit</string>
+    <string name="data_usage_limit_snoozed_body"><xliff:g id="size" example="3.8GB">%s</xliff:g> over specified limit.</string>
 
     <!-- Notification title when background data usage is limited. [CHAR LIMIT=32] -->
     <string name="data_usage_restricted_title">Background data restricted</string>
     <!-- Notification body when background data usage is limited. [CHAR LIMIT=32] -->
-    <string name="data_usage_restricted_body">Touch to remove restriction</string>
+    <string name="data_usage_restricted_body">Touch to remove restriction.</string>
 
     <!-- SSL Certificate dialogs -->
     <!-- Title for an SSL Certificate dialog -->
@@ -3344,12 +3339,12 @@
     <string name="list_delimeter">", "</string>
 
     <!-- STK sending DTMF, SMS, USSD, SS -->
-    <string name="sending">Sending...</string>
+    <string name="sending">Sending\u2026</string>
 
     <!-- STK launch Browser -->
     <string name="launchBrowserDefault">Launch Browser?</string>
 
     <!-- STK setup Call -->
-    <string name="SetupCallDefault">Accept Call?</string>
+    <string name="SetupCallDefault">Accept call?</string>
 
 </resources>
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 73e1a7c..3b6d6f1 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -2447,4 +2447,37 @@
         <item name="android:pointerIconSpotTouch">@android:drawable/pointer_spot_touch_icon</item>
         <item name="android:pointerIconSpotAnchor">@android:drawable/pointer_spot_anchor_icon</item>
     </style>
+
+    <!-- Wifi dialog styles -->
+    <!-- @hide -->
+    <style name="wifi_item">
+        <item name="android:layout_width">200dip</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:layout_marginTop">8dip</item>
+        <item name="android:layout_marginLeft">16dip</item>
+        <item name="android:layout_marginRight">16dip</item>
+        <item name="android:orientation">vertical</item>
+        <item name="android:gravity">left</item>
+    </style>
+
+    <!-- @hide -->
+    <style name="wifi_item_label">
+        <item name="android:layout_width">wrap_content</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:textSize">14sp</item>
+    </style>
+
+    <!-- @hide -->
+    <style name="wifi_item_content">
+        <item name="android:layout_width">match_parent</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:textSize">18sp</item>
+    </style>
+
+    <!-- @hide -->
+    <style name="wifi_section">
+        <item name="android:layout_width">match_parent</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:orientation">vertical</item>
+    </style>
 </resources>
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerStressTestRunner.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerStressTestRunner.java
index d23dfd3..3ffa085 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerStressTestRunner.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerStressTestRunner.java
@@ -38,7 +38,8 @@
     public int mSoftapIterations = 100;
     public int mScanIterations = 100;
     public int mReconnectIterations = 100;
-    public int mSleepTime = 30 * 1000;  // default sleep time is 30 seconds
+    // sleep time before restart wifi, default is set to 2 minutes
+    public int mSleepTime = 2 * 60 * 1000;
     public String mReconnectSsid = "securenetdhcp";
     public String mReconnectPassword = "androidwifi";
 
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java
index adf1883c8..0580ebc 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java
@@ -62,6 +62,8 @@
     public static final int WIFI_SCAN_TIMEOUT = 50 * 1000;
     public static final int SHORT_TIMEOUT = 5 * 1000;
     public static final long LONG_TIMEOUT = 50 * 1000;
+    // 2 minutes timer between wifi stop and start
+    public static final long  WIFI_STOP_START_INTERVAL = 2 * 60 * 1000;
     public static final int SUCCESS = 0;  // for Wifi tethering state change
     public static final int FAILURE = 1;
     public static final int INIT = -1;
@@ -247,6 +249,8 @@
         sleep(SHORT_TIMEOUT);
         removeConfiguredNetworksAndDisableWifi();
         mWifiRegexs = mCM.getTetherableWifiRegexs();
+        // after wifi is shutdown, wait for 2 minute to enable wifi
+        sleep(WIFI_STOP_START_INTERVAL);
      }
 
     public List<WifiConfiguration> loadNetworkConfigurations() throws Exception {
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/NetworkState.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/NetworkState.java
index d586396..5a4a2d0 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/NetworkState.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/NetworkState.java
@@ -77,10 +77,13 @@
                 mReason = "no state is recorded.";
                 return false;
             } else if (mStateDepository.size() > 1) {
-                Log.v(LOG_TAG, "no broadcast is expected, " +
-                        "instead broadcast is probably received");
-                mReason = "no broadcast is expected, instead broadcast is probably received";
-                return false;
+                for (int i = 0; i < mStateDepository.size(); i++) {
+                    if (mStateDepository.get(i) != mTransitionTarget) {
+                        Log.v(LOG_TAG, "state changed.");
+                        mReason = "Unexpected state change";
+                        return false;
+                    }
+                }
             } else if (mStateDepository.get(0) != mTransitionTarget) {
                 Log.v(LOG_TAG, mTransitionTarget + " is expected, but it is " +
                         mStateDepository.get(0));
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java
index d9b770a..b1f4bf1 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java
@@ -66,7 +66,7 @@
         // Each test case will start with cellular connection
         if (Settings.System.getInt(getInstrumentation().getContext().getContentResolver(),
                 Settings.System.AIRPLANE_MODE_ON) == 1) {
-            Log.v(LOG_TAG, "airplane is not disabled, disable it.");
+            log("airplane is not disabled, disable it.");
             cmActivity.setAirplaneMode(getInstrumentation().getContext(), false);
         }
         if (!UtilHelper.isWifiOnly()) {
@@ -84,13 +84,13 @@
     @Override
     public void tearDown() throws Exception {
         cmActivity.finish();
-        Log.v(LOG_TAG, "tear down ConnectivityManagerTestActivity");
+        log("tear down ConnectivityManagerTestActivity");
         wl.release();
         cmActivity.removeConfiguredNetworksAndDisableWifi();
         // if airplane mode is set, disable it.
         if (Settings.System.getInt(getInstrumentation().getContext().getContentResolver(),
                 Settings.System.AIRPLANE_MODE_ON) == 1) {
-            Log.v(LOG_TAG, "disable airplane mode if it is enabled");
+            log("disable airplane mode if it is enabled");
             cmActivity.setAirplaneMode(getInstrumentation().getContext(), false);
         }
         super.tearDown();
@@ -104,17 +104,24 @@
         assertTrue("not connected to cellular network", extraNetInfo.isConnected());
     }
 
+    private void log(String message) {
+        Log.v(LOG_TAG, message);
+    }
+
+    private void sleep(long sleeptime) {
+        try {
+            Thread.sleep(sleeptime);
+        } catch (InterruptedException e) {}
+    }
+
     // Test case 1: Test enabling Wifi without associating with any AP, no broadcast on network
     //              event should be expected.
     @LargeTest
     public void test3GToWifiNotification() {
         // Enable Wi-Fi to avoid initial UNKNOWN state
         cmActivity.enableWifi();
-        try {
-            Thread.sleep(2 * ConnectivityManagerTestActivity.SHORT_TIMEOUT);
-        } catch (Exception e) {
-            Log.v(LOG_TAG, "exception: " + e.toString());
-        }
+        sleep(2 * ConnectivityManagerTestActivity.SHORT_TIMEOUT);
+
         // Wi-Fi is disabled
         cmActivity.disableWifi();
 
@@ -123,11 +130,8 @@
         assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_MOBILE,
                 State.CONNECTED, ConnectivityManagerTestActivity.LONG_TIMEOUT));
         // Wait for 10 seconds for broadcasts to be sent out
-        try {
-            Thread.sleep(10 * 1000);
-        } catch (Exception e) {
-            fail("thread in sleep is interrupted.");
-        }
+        sleep(10 * 1000);
+
         // As Wifi stays in DISCONNETED, Mobile statys in CONNECTED,
         // the connectivity manager will not broadcast any network connectivity event for Wifi
         NetworkInfo networkInfo = cmActivity.mCM.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
@@ -138,22 +142,18 @@
                 NetworkState.DO_NOTHING, State.DISCONNECTED);
         // Eanble Wifi without associating with any AP
         cmActivity.enableWifi();
-        try {
-            Thread.sleep(2 * ConnectivityManagerTestActivity.SHORT_TIMEOUT);
-        } catch (Exception e) {
-            Log.v(LOG_TAG, "exception: " + e.toString());
-        }
+        sleep(2 * ConnectivityManagerTestActivity.SHORT_TIMEOUT);
 
         // validate state and broadcast
         if (!cmActivity.validateNetworkStates(ConnectivityManager.TYPE_WIFI)) {
-            Log.v(LOG_TAG, "the state for WIFI is changed");
-            Log.v(LOG_TAG, "reason: " +
+            log("the state for WIFI is changed");
+            log("reason: " +
                     cmActivity.getTransitionFailureReason(ConnectivityManager.TYPE_WIFI));
             assertTrue("state validation fail", false);
         }
         if (!cmActivity.validateNetworkStates(ConnectivityManager.TYPE_MOBILE)) {
-            Log.v(LOG_TAG, "the state for MOBILE is changed");
-            Log.v(LOG_TAG, "reason: " +
+            log("the state for MOBILE is changed");
+            log("reason: " +
                     cmActivity.getTransitionFailureReason(ConnectivityManager.TYPE_MOBILE));
             assertTrue("state validation fail", false);
         }
@@ -182,7 +182,7 @@
 
         assertTrue(cmActivity.waitForWifiState(WifiManager.WIFI_STATE_ENABLED,
                 ConnectivityManagerTestActivity.LONG_TIMEOUT));
-        Log.v(LOG_TAG, "wifi state is enabled");
+        log("wifi state is enabled");
         assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
                 ConnectivityManagerTestActivity.LONG_TIMEOUT));
         if (!UtilHelper.isWifiOnly()) {
@@ -192,15 +192,15 @@
 
         // validate states
         if (!cmActivity.validateNetworkStates(ConnectivityManager.TYPE_WIFI)) {
-            Log.v(LOG_TAG, "Wifi state transition validation failed.");
-            Log.v(LOG_TAG, "reason: " +
+            log("Wifi state transition validation failed.");
+            log("reason: " +
                     cmActivity.getTransitionFailureReason(ConnectivityManager.TYPE_WIFI));
             assertTrue(false);
         }
         if (!UtilHelper.isWifiOnly()) {
             if (!cmActivity.validateNetworkStates(ConnectivityManager.TYPE_MOBILE)) {
-                Log.v(LOG_TAG, "Mobile state transition validation failed.");
-                Log.v(LOG_TAG, "reason: " +
+                log("Mobile state transition validation failed.");
+                log("reason: " +
                         cmActivity.getTransitionFailureReason(ConnectivityManager.TYPE_MOBILE));
                 assertTrue(false);
             }
@@ -219,16 +219,11 @@
         assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
                 ConnectivityManagerTestActivity.LONG_TIMEOUT));
 
-        try {
-            Thread.sleep(ConnectivityManagerTestActivity.SHORT_TIMEOUT);
-        } catch (Exception e) {
-            Log.v(LOG_TAG, "exception: " + e.toString());
-        }
-
+        sleep(ConnectivityManagerTestActivity.SHORT_TIMEOUT);
         // Disable Wifi
-        Log.v(LOG_TAG, "Disable Wifi");
+        log("Disable Wifi");
         if (!cmActivity.disableWifi()) {
-            Log.v(LOG_TAG, "disable Wifi failed");
+            log("disable Wifi failed");
             return;
         }
 
@@ -254,8 +249,10 @@
         cmActivity.setStateTransitionCriteria(ConnectivityManager.TYPE_WIFI, networkInfo.getState(),
                 NetworkState.TO_CONNECTION, State.CONNECTED);
 
+        // wait for 2 minutes before restart wifi
+        sleep(ConnectivityManagerTestActivity.WIFI_STOP_START_INTERVAL);
         // Enable Wifi again
-        Log.v(LOG_TAG, "Enable Wifi again");
+        log("Enable Wifi again");
         cmActivity.enableWifi();
 
         // Wait for Wifi to be connected and mobile to be disconnected
@@ -268,8 +265,8 @@
 
         // validate wifi states
         if (!cmActivity.validateNetworkStates(ConnectivityManager.TYPE_WIFI)) {
-            Log.v(LOG_TAG, "Wifi state transition validation failed.");
-            Log.v(LOG_TAG, "reason: " +
+            log("Wifi state transition validation failed.");
+            log("reason: " +
                     cmActivity.getTransitionFailureReason(ConnectivityManager.TYPE_WIFI));
             assertTrue(false);
         }
@@ -288,11 +285,7 @@
             ConnectivityManagerTestActivity.LONG_TIMEOUT));
 
         // Wait for a few seconds to avoid the state that both Mobile and Wifi is connected
-        try {
-            Thread.sleep(ConnectivityManagerTestActivity.SHORT_TIMEOUT);
-        } catch (Exception e) {
-            Log.v(LOG_TAG, "exception: " + e.toString());
-        }
+        sleep(ConnectivityManagerTestActivity.SHORT_TIMEOUT);
 
         NetworkInfo networkInfo;
         if (!UtilHelper.isWifiOnly()) {
@@ -318,15 +311,15 @@
 
         // validate states
         if (!cmActivity.validateNetworkStates(ConnectivityManager.TYPE_WIFI)) {
-            Log.v(LOG_TAG, "Wifi state transition validation failed.");
-            Log.v(LOG_TAG, "reason: " +
+            log("Wifi state transition validation failed.");
+            log("reason: " +
                     cmActivity.getTransitionFailureReason(ConnectivityManager.TYPE_WIFI));
             assertTrue(false);
         }
         if (!UtilHelper.isWifiOnly()) {
             if (!cmActivity.validateNetworkStates(ConnectivityManager.TYPE_MOBILE)) {
-                Log.v(LOG_TAG, "Mobile state transition validation failed.");
-                Log.v(LOG_TAG, "reason: " +
+                log("Mobile state transition validation failed.");
+                log("reason: " +
                         cmActivity.getTransitionFailureReason(ConnectivityManager.TYPE_MOBILE));
                 assertTrue(false);
             }
@@ -346,19 +339,16 @@
         assertEquals(State.DISCONNECTED, networkInfo.getState());
 
         // Enable airplane mode
+        log("Enable airplane mode");
         cmActivity.setAirplaneMode(getInstrumentation().getContext(), true);
-        try {
-            Thread.sleep(ConnectivityManagerTestActivity.SHORT_TIMEOUT);
-        } catch (Exception e) {
-            Log.v(LOG_TAG, "exception: " + e.toString());
-        }
+        sleep(ConnectivityManagerTestActivity.SHORT_TIMEOUT);
 
         networkInfo = cmActivity.mCM.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
         assertEquals(State.DISCONNECTED, networkInfo.getState());
 
         if (!cmActivity.validateNetworkStates(ConnectivityManager.TYPE_MOBILE)) {
-            Log.v(LOG_TAG, "Mobile state transition validation failed.");
-            Log.v(LOG_TAG, "reason: " +
+            log("Mobile state transition validation failed.");
+            log("reason: " +
                     cmActivity.getTransitionFailureReason(ConnectivityManager.TYPE_MOBILE));
             assertTrue(false);
         }
@@ -381,14 +371,14 @@
 
         // Validate the state transition
         if (!cmActivity.validateNetworkStates(ConnectivityManager.TYPE_MOBILE)) {
-            Log.v(LOG_TAG, "Mobile state transition validation failed.");
-            Log.v(LOG_TAG, "reason: " +
+            log("Mobile state transition validation failed.");
+            log("reason: " +
                     cmActivity.getTransitionFailureReason(ConnectivityManager.TYPE_MOBILE));
             assertTrue(false);
         }
         if (!cmActivity.validateNetworkStates(ConnectivityManager.TYPE_WIFI)) {
-          Log.v(LOG_TAG, "Wifi state transition validation failed.");
-          Log.v(LOG_TAG, "reason: " +
+          log("Wifi state transition validation failed.");
+          log("reason: " +
                   cmActivity.getTransitionFailureReason(ConnectivityManager.TYPE_WIFI));
           assertTrue(false);
         }
@@ -399,6 +389,7 @@
     public void testDataConnectionOverAMWithWifi() {
         assertNotNull("SSID is null", TEST_ACCESS_POINT);
         // Eanble airplane mode
+        log("Enable airplane mode");
         cmActivity.setAirplaneMode(getInstrumentation().getContext(), true);
 
         NetworkInfo networkInfo;
@@ -423,15 +414,15 @@
 
         // validate state and broadcast
         if (!cmActivity.validateNetworkStates(ConnectivityManager.TYPE_WIFI)) {
-            Log.v(LOG_TAG, "state validate for Wifi failed");
-            Log.v(LOG_TAG, "reason: " +
+            log("state validate for Wifi failed");
+            log("reason: " +
                     cmActivity.getTransitionFailureReason(ConnectivityManager.TYPE_WIFI));
             assertTrue("State validation failed", false);
         }
         if (!UtilHelper.isWifiOnly()) {
             if (!cmActivity.validateNetworkStates(ConnectivityManager.TYPE_MOBILE)) {
-                Log.v(LOG_TAG, "state validation for Mobile failed");
-                Log.v(LOG_TAG, "reason: " +
+                log("state validation for Mobile failed");
+                log("reason: " +
                         cmActivity.getTransitionFailureReason(ConnectivityManager.TYPE_MOBILE));
                 assertTrue("state validation failed", false);
             }
@@ -454,7 +445,7 @@
         try {
             Thread.sleep(ConnectivityManagerTestActivity.SHORT_TIMEOUT);
         } catch (Exception e) {
-            Log.v(LOG_TAG, "exception: " + e.toString());
+            log("exception: " + e.toString());
         }
 
         // Enable airplane mode without clearing Wifi
@@ -466,7 +457,7 @@
         try {
             Thread.sleep(ConnectivityManagerTestActivity.SHORT_TIMEOUT);
         } catch (Exception e) {
-            Log.v(LOG_TAG, "exception: " + e.toString());
+            log("exception: " + e.toString());
         }
 
         // Prepare for state validation
@@ -487,8 +478,8 @@
 
         // validate the state transition
         if (!cmActivity.validateNetworkStates(ConnectivityManager.TYPE_WIFI)) {
-            Log.v(LOG_TAG, "Wifi state transition validation failed.");
-            Log.v(LOG_TAG, "reason: " +
+            log("Wifi state transition validation failed.");
+            log("reason: " +
                     cmActivity.getTransitionFailureReason(ConnectivityManager.TYPE_WIFI));
             assertTrue(false);
         }
@@ -511,13 +502,13 @@
         try {
             Thread.sleep(ConnectivityManagerTestActivity.SHORT_TIMEOUT);
         } catch (Exception e) {
-            Log.v(LOG_TAG, "exception: " + e.toString());
+            log("exception: " + e.toString());
         }
 
         // Disconnect from the current AP
-        Log.v(LOG_TAG, "disconnect from the AP");
+        log("disconnect from the AP");
         if (!cmActivity.disconnectAP()) {
-            Log.v(LOG_TAG, "failed to disconnect from " + TEST_ACCESS_POINT);
+            log("failed to disconnect from " + TEST_ACCESS_POINT);
         }
 
         // Verify the connectivity state for Wifi is DISCONNECTED
@@ -525,7 +516,7 @@
                 ConnectivityManagerTestActivity.LONG_TIMEOUT));
 
         if (!cmActivity.disableWifi()) {
-            Log.v(LOG_TAG, "disable Wifi failed");
+            log("disable Wifi failed");
             return;
         }
         assertTrue(cmActivity.waitForWifiState(WifiManager.WIFI_STATE_DISABLED,
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/WifiConnectionTest.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/WifiConnectionTest.java
index 22b1759..d33a445 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/WifiConnectionTest.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/WifiConnectionTest.java
@@ -136,7 +136,7 @@
 
         // step 2: verify Wifi state and network state;
         assertTrue(mAct.waitForNetworkState(ConnectivityManager.TYPE_WIFI,
-                State.CONNECTED, 2 * ConnectivityManagerTestActivity.LONG_TIMEOUT));
+                State.CONNECTED, 6 * ConnectivityManagerTestActivity.LONG_TIMEOUT));
 
         // step 3: verify the current connected network is the given SSID
         assertNotNull("Wifi connection returns null", mAct.mWifiManager.getConnectionInfo());
@@ -166,8 +166,9 @@
             String ssid = networks.get(i).SSID;
             log("-- START Wi-Fi connection test to : " + ssid + " --");
             connectToWifi(networks.get(i));
-            sleep(2 * ConnectivityManagerTestActivity.SHORT_TIMEOUT,
-                    "interruped while waiting for wifi disabled.");
+            // wait for 2 minutes between wifi stop and start
+            sleep(ConnectivityManagerTestActivity.WIFI_STOP_START_INTERVAL,
+                  "interruped while connected to wifi");
             log("-- END Wi-Fi connection test to " + ssid + " -- ");
         }
     }
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java
index 7578e67..2069789 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java
@@ -63,10 +63,12 @@
     private final static long WIFI_IDLE_MS = 60 * 1000;
 
     /**
-     * The delay for Wi-Fi to get into idle, after screen off + WIFI_IDEL_MS + WIFI_IDLE_DELAY
-     * the Wi-Fi should be in idle mode and device should be in cellular mode.
+     * Delay after issuing wifi shutdown.
+     * The framework keep driver up for at leat 2 minutes to avoid problems
+     * that a quick shutdown could cause on wext driver and protentially
+     * on cfg based driver
      */
-    private final static long WIFI_IDLE_DELAY = 3 * 1000;
+    private final static long WIFI_SHUTDOWN_DELAY = 2 * 60 * 1000;
 
     private final static String OUTPUT_FILE = "WifiStressTestOutput.txt";
     private ConnectivityManagerTestActivity mAct;
@@ -92,6 +94,9 @@
         mPassword = mRunner.mReconnectPassword;
         mScanIterations = mRunner.mScanIterations;
         mWifiSleepTime = mRunner.mSleepTime;
+        log(String.format("mReconnectIterations(%d), mSsid(%s), mPassword(%s),"
+            + "mScanIterations(%d), mWifiSleepTime(%d)", mReconnectIterations, mSsid,
+            mPassword, mScanIterations, mWifiSleepTime));
         mOutputWriter = new BufferedWriter(new FileWriter(new File(
                 Environment.getExternalStorageDirectory(), OUTPUT_FILE), true));
         mAct.turnScreenOn();
@@ -248,6 +253,7 @@
         assertTrue("Wi-Fi is connected, but no data connection.", mAct.pingTest(null));
 
         int i;
+        long sum = 0;
         for (i = 0; i < mReconnectIterations; i++) {
             // 1. Put device into sleep mode
             // 2. Wait for the device to sleep for sometime, verify wi-fi is off and mobile is on.
@@ -261,7 +267,7 @@
             PowerManager pm =
                 (PowerManager)mRunner.getContext().getSystemService(Context.POWER_SERVICE);
             assertFalse(pm.isScreenOn());
-            sleep(WIFI_IDLE_MS, "Interruped while wait for wifi to be idle");
+            sleep(WIFI_IDLE_MS + WIFI_SHUTDOWN_DELAY, "Interruped while wait for wifi to be idle");
             assertTrue("Wait for Wi-Fi to idle timeout",
                     mAct.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.DISCONNECTED,
                     6 * ConnectivityManagerTestActivity.SHORT_TIMEOUT));
@@ -269,9 +275,9 @@
                 // use long timeout as the pppd startup may take several retries.
                 assertTrue("Wait for cellular connection timeout",
                         mAct.waitForNetworkState(ConnectivityManager.TYPE_MOBILE, State.CONNECTED,
-                        ConnectivityManagerTestActivity.LONG_TIMEOUT));
+                        2 * ConnectivityManagerTestActivity.LONG_TIMEOUT));
             }
-            sleep(mWifiSleepTime + WIFI_IDLE_DELAY, "Interrupted while device is in sleep mode");
+            sleep(mWifiSleepTime, "Interrupted while device is in sleep mode");
             // Verify the wi-fi is still off and data connection is on
             assertEquals("Wi-Fi is reconnected", State.DISCONNECTED,
                     mAct.mCM.getNetworkInfo(ConnectivityManager.TYPE_WIFI).getState());
@@ -284,12 +290,18 @@
 
             // Turn screen on again
             mAct.turnScreenOn();
+            // Measure the time for Wi-Fi to get connected
+            long startTime = System.currentTimeMillis();
             assertTrue("Wait for Wi-Fi enable timeout after wake up",
                     mAct.waitForWifiState(WifiManager.WIFI_STATE_ENABLED,
                     ConnectivityManagerTestActivity.SHORT_TIMEOUT));
             assertTrue("Wait for Wi-Fi connection timeout after wake up",
                     mAct.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
-                    ConnectivityManagerTestActivity.LONG_TIMEOUT));
+                    6 * ConnectivityManagerTestActivity.LONG_TIMEOUT));
+            long connectionTime = System.currentTimeMillis() - startTime;
+            sum += connectionTime;
+            log("average reconnection time is: " + sum/(i+1));
+
             assertTrue("Reconnect to Wi-Fi network, but no data connection.", mAct.pingTest(null));
         }
         if (i == mReconnectIterations) {
diff --git a/core/tests/bluetoothtests/AndroidManifest.xml b/core/tests/bluetoothtests/AndroidManifest.xml
index 58f158c..60b6dc1 100644
--- a/core/tests/bluetoothtests/AndroidManifest.xml
+++ b/core/tests/bluetoothtests/AndroidManifest.xml
@@ -19,6 +19,8 @@
 
     <uses-permission android:name="android.permission.BLUETOOTH" />
     <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
+    <uses-permission android:name="android.permission.BROADCAST_STICKY" />
+    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
     <uses-permission android:name="android.permission.WRITE_SETTINGS" />
     <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
diff --git a/core/tests/bluetoothtests/src/android/bluetooth/BluetoothStressTest.java b/core/tests/bluetoothtests/src/android/bluetooth/BluetoothStressTest.java
index abd7d9a..755e7c4 100644
--- a/core/tests/bluetoothtests/src/android/bluetooth/BluetoothStressTest.java
+++ b/core/tests/bluetoothtests/src/android/bluetooth/BluetoothStressTest.java
@@ -32,6 +32,8 @@
 public class BluetoothStressTest extends InstrumentationTestCase {
     private static final String TAG = "BluetoothStressTest";
     private static final String OUTPUT_FILE = "BluetoothStressTestOutput.txt";
+    /** The amount of time to sleep between issuing start/stop SCO in ms. */
+    private static final long SCO_SLEEP_TIME = 2 * 1000;
 
     private BluetoothTestUtils mTestUtils;
 
@@ -380,11 +382,20 @@
         for (int i = 0; i < iterations; i++) {
             mTestUtils.writeOutput("startStopSco iteration " + (i + 1) + " of " + iterations);
             mTestUtils.startSco(adapter, device);
+            sleep(SCO_SLEEP_TIME);
             mTestUtils.stopSco(adapter, device);
+            sleep(SCO_SLEEP_TIME);
         }
 
         mTestUtils.disconnectProfile(adapter, device, BluetoothProfile.HEADSET, null);
         mTestUtils.unpair(adapter, device);
         mTestUtils.disable(adapter);
     }
+
+    private void sleep(long time) {
+        try {
+            Thread.sleep(time);
+        } catch (InterruptedException e) {
+        }
+    }
 }
diff --git a/core/tests/bluetoothtests/src/android/bluetooth/BluetoothTestUtils.java b/core/tests/bluetoothtests/src/android/bluetooth/BluetoothTestUtils.java
index 42e5cd1..4858be8 100644
--- a/core/tests/bluetoothtests/src/android/bluetooth/BluetoothTestUtils.java
+++ b/core/tests/bluetoothtests/src/android/bluetooth/BluetoothTestUtils.java
@@ -1425,7 +1425,7 @@
     }
 
     private StartStopScoReceiver getStartStopScoReceiver(int expectedFlags) {
-        String[] actions = {AudioManager.ACTION_SCO_AUDIO_STATE_CHANGED};
+        String[] actions = {AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED};
         StartStopScoReceiver receiver = new StartStopScoReceiver(expectedFlags);
         addReceiver(receiver, actions);
         return receiver;
diff --git a/core/tests/coretests/src/android/accessibilityservice/InterrogationActivityTest.java b/core/tests/coretests/src/android/accessibilityservice/InterrogationActivityTest.java
index 1ed54cb..259a094 100644
--- a/core/tests/coretests/src/android/accessibilityservice/InterrogationActivityTest.java
+++ b/core/tests/coretests/src/android/accessibilityservice/InterrogationActivityTest.java
@@ -26,6 +26,7 @@
 import android.test.ActivityInstrumentationTestCase2;
 import android.test.suitebuilder.annotation.LargeTest;
 import android.util.Log;
+import android.view.View;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityInteractionClient;
 import android.view.accessibility.AccessibilityManager;
@@ -54,28 +55,31 @@
     // Timeout before give up wait for the system to process an accessibility setting change.       
     private static final int TIMEOUT_PROPAGATE_ACCESSIBLITY_SETTING = 2000;
 
+    // Timeout for the accessibility state of an Activity to be fully initialized.
+    private static final int TIMEOUT_ACCESSIBLITY_STATE_INITIALIZED_MILLIS = 100;
+
     // Handle to a connection to the AccessibilityManagerService
-    private static IAccessibilityServiceConnection sConnection;
+    private static int sConnectionId = View.NO_ID;
 
     // The last received accessibility event
-    private static volatile AccessibilityEvent sLastFocusAccessibilityEvent;
+    private volatile AccessibilityEvent mLastAccessibilityEvent;
 
     public InterrogationActivityTest() {
         super(InterrogationActivity.class);
     }
 
+    @Override
+    public void setUp() throws Exception {
+        ensureConnection();
+        bringUpActivityWithInitalizedAccessbility();
+    }
+
     @LargeTest
     public void testFindAccessibilityNodeInfoByViewId() throws Exception {
         final long startTimeMillis = SystemClock.uptimeMillis();
         try {
-            // hook into the system first
-            IAccessibilityServiceConnection connection = getConnection();
-
-            // bring up the activity
-            getActivity();
-
             AccessibilityNodeInfo button = AccessibilityInteractionClient.getInstance()
-                .findAccessibilityNodeInfoByViewIdInActiveWindow(connection, R.id.button5);
+                .findAccessibilityNodeInfoByViewIdInActiveWindow(sConnectionId, R.id.button5);
             assertNotNull(button);
             assertEquals(0, button.getChildCount());
 
@@ -120,15 +124,9 @@
     public void testFindAccessibilityNodeInfoByViewText() throws Exception {
         final long startTimeMillis = SystemClock.uptimeMillis();
         try {
-            // hook into the system first
-            IAccessibilityServiceConnection connection = getConnection();
-
-            // bring up the activity
-            getActivity();
-
             // find a view by text
             List<AccessibilityNodeInfo> buttons =  AccessibilityInteractionClient.getInstance()
-                .findAccessibilityNodeInfosByTextInActiveWindow(connection, "butto");
+                .findAccessibilityNodeInfosByTextInActiveWindow(sConnectionId, "butto");
             assertEquals(9, buttons.size());
         } finally {
             if (DEBUG) {
@@ -143,15 +141,11 @@
     public void testFindAccessibilityNodeInfoByViewTextContentDescription() throws Exception {
         final long startTimeMillis = SystemClock.uptimeMillis();
         try {
-            // hook into the system first
-            IAccessibilityServiceConnection connection = getConnection();
-
-            // bring up the activity
-            getActivity();
+            bringUpActivityWithInitalizedAccessbility();
 
             // find a view by text
             List<AccessibilityNodeInfo> buttons =  AccessibilityInteractionClient.getInstance()
-                .findAccessibilityNodeInfosByTextInActiveWindow(connection,
+                .findAccessibilityNodeInfosByTextInActiveWindow(sConnectionId,
                         "contentDescription");
             assertEquals(1, buttons.size());
         } finally {
@@ -167,12 +161,6 @@
     public void testTraverseAllViews() throws Exception {
         final long startTimeMillis = SystemClock.uptimeMillis();
         try {
-            // hook into the system first
-            IAccessibilityServiceConnection connection = getConnection();
-
-            // bring up the activity
-            getActivity();
-
             // make list of expected nodes
             List<String> classNameAndTextList = new ArrayList<String>();
             classNameAndTextList.add("android.widget.LinearLayout");
@@ -190,7 +178,7 @@
             classNameAndTextList.add("android.widget.ButtonButton9");
 
             AccessibilityNodeInfo root = AccessibilityInteractionClient.getInstance()
-                .findAccessibilityNodeInfoByViewIdInActiveWindow(connection, R.id.root);
+                .findAccessibilityNodeInfoByViewIdInActiveWindow(sConnectionId, R.id.root);
             assertNotNull("We must find the existing root.", root);
 
             Queue<AccessibilityNodeInfo> fringe = new LinkedList<AccessibilityNodeInfo>();
@@ -227,23 +215,17 @@
     public void testPerformAccessibilityActionFocus() throws Exception {
         final long startTimeMillis = SystemClock.uptimeMillis();
         try {
-            // hook into the system first
-            IAccessibilityServiceConnection connection = getConnection();
-
-            // bring up the activity
-            getActivity();
-
             // find a view and make sure it is not focused
             AccessibilityNodeInfo button = AccessibilityInteractionClient.getInstance()
-                .findAccessibilityNodeInfoByViewIdInActiveWindow(connection, R.id.button5);
+                .findAccessibilityNodeInfoByViewIdInActiveWindow(sConnectionId, R.id.button5);
             assertFalse(button.isFocused());
 
             // focus the view
             assertTrue(button.performAction(ACTION_FOCUS));
 
             // find the view again and make sure it is focused
-            button =  AccessibilityInteractionClient.getInstance()
-                .findAccessibilityNodeInfoByViewIdInActiveWindow(connection, R.id.button5);
+            button = AccessibilityInteractionClient.getInstance()
+                .findAccessibilityNodeInfoByViewIdInActiveWindow(sConnectionId, R.id.button5);
             assertTrue(button.isFocused());
         } finally {
             if (DEBUG) {
@@ -257,15 +239,9 @@
     public void testPerformAccessibilityActionClearFocus() throws Exception {
         final long startTimeMillis = SystemClock.uptimeMillis();
         try {
-            // hook into the system first
-            IAccessibilityServiceConnection connection = getConnection();
-
-            // bring up the activity
-            getActivity();
-
             // find a view and make sure it is not focused
             AccessibilityNodeInfo button = AccessibilityInteractionClient.getInstance()
-                .findAccessibilityNodeInfoByViewIdInActiveWindow(connection, R.id.button5);
+                .findAccessibilityNodeInfoByViewIdInActiveWindow(sConnectionId, R.id.button5);
             assertFalse(button.isFocused());
 
             // focus the view
@@ -273,7 +249,7 @@
 
             // find the view again and make sure it is focused
             button = AccessibilityInteractionClient.getInstance()
-                .findAccessibilityNodeInfoByViewIdInActiveWindow(connection, R.id.button5);
+                .findAccessibilityNodeInfoByViewIdInActiveWindow(sConnectionId, R.id.button5);
             assertTrue(button.isFocused());
 
             // unfocus the view
@@ -281,7 +257,7 @@
 
             // find the view again and make sure it is not focused
             button = AccessibilityInteractionClient.getInstance()
-                .findAccessibilityNodeInfoByViewIdInActiveWindow(connection, R.id.button5);
+                .findAccessibilityNodeInfoByViewIdInActiveWindow(sConnectionId, R.id.button5);
             assertFalse(button.isFocused());
         } finally {
             if (DEBUG) {
@@ -296,15 +272,9 @@
     public void testPerformAccessibilityActionSelect() throws Exception {
         final long startTimeMillis = SystemClock.uptimeMillis();
         try {
-            // hook into the system first
-            IAccessibilityServiceConnection connection = getConnection();
-
-            // bring up the activity
-            getActivity();
-
             // find a view and make sure it is not selected
             AccessibilityNodeInfo button = AccessibilityInteractionClient.getInstance()
-                .findAccessibilityNodeInfoByViewIdInActiveWindow(connection, R.id.button5);
+                .findAccessibilityNodeInfoByViewIdInActiveWindow(sConnectionId, R.id.button5);
             assertFalse(button.isSelected());
 
             // select the view
@@ -312,7 +282,7 @@
 
             // find the view again and make sure it is selected
             button = AccessibilityInteractionClient.getInstance()
-                .findAccessibilityNodeInfoByViewIdInActiveWindow(connection, R.id.button5);
+                .findAccessibilityNodeInfoByViewIdInActiveWindow(sConnectionId, R.id.button5);
             assertTrue(button.isSelected());
         } finally {
             if (DEBUG) {
@@ -326,15 +296,9 @@
     public void testPerformAccessibilityActionClearSelection() throws Exception {
         final long startTimeMillis = SystemClock.uptimeMillis();
         try {
-            // hook into the system first
-            IAccessibilityServiceConnection connection = getConnection();
-
-            // bring up the activity
-            getActivity();
-
             // find a view and make sure it is not selected
             AccessibilityNodeInfo button = AccessibilityInteractionClient.getInstance()
-                .findAccessibilityNodeInfoByViewIdInActiveWindow(connection, R.id.button5);
+                .findAccessibilityNodeInfoByViewIdInActiveWindow(sConnectionId, R.id.button5);
             assertFalse(button.isSelected());
 
             // select the view
@@ -342,15 +306,15 @@
 
             // find the view again and make sure it is selected
             button = AccessibilityInteractionClient.getInstance()
-                .findAccessibilityNodeInfoByViewIdInActiveWindow(connection, R.id.button5);
+                .findAccessibilityNodeInfoByViewIdInActiveWindow(sConnectionId, R.id.button5);
             assertTrue(button.isSelected());
 
             // unselect the view
             assertTrue(button.performAction(ACTION_CLEAR_SELECTION));
 
             // find the view again and make sure it is not selected
-            button =  AccessibilityInteractionClient.getInstance()
-                .findAccessibilityNodeInfoByViewIdInActiveWindow(connection, R.id.button5);
+            button = AccessibilityInteractionClient.getInstance()
+                .findAccessibilityNodeInfoByViewIdInActiveWindow(sConnectionId, R.id.button5);
             assertFalse(button.isSelected());
         } finally {
             if (DEBUG) {
@@ -365,30 +329,24 @@
     public void testAccessibilityEventGetSource() throws Exception {
         final long startTimeMillis = SystemClock.uptimeMillis();
         try {
-            // hook into the system first
-            IAccessibilityServiceConnection connection = getConnection();
-
-            // bring up the activity
-            getActivity();  
-
             // find a view and make sure it is not focused
             AccessibilityNodeInfo button = AccessibilityInteractionClient.getInstance()
-                .findAccessibilityNodeInfoByViewIdInActiveWindow(connection, R.id.button5);
+                .findAccessibilityNodeInfoByViewIdInActiveWindow(sConnectionId, R.id.button5);
             assertFalse(button.isSelected());
 
             // focus the view
             assertTrue(button.performAction(ACTION_FOCUS));
 
-            synchronized (sConnection) {
+            synchronized (this) {
                 try {
-                    sConnection.wait(500);
+                    wait(TIMEOUT_ACCESSIBLITY_STATE_INITIALIZED_MILLIS);
                 } catch (InterruptedException ie) {
                     /* ignore */
                 }
             }
 
             // check that last event source
-            AccessibilityNodeInfo source = sLastFocusAccessibilityEvent.getSource();
+            AccessibilityNodeInfo source = mLastAccessibilityEvent.getSource();
             assertNotNull(source);
 
             // bounds
@@ -430,15 +388,9 @@
     public void testObjectContract() throws Exception {
         final long startTimeMillis = SystemClock.uptimeMillis();
         try {
-            // hook into the system first
-            IAccessibilityServiceConnection connection = getConnection();
-
-            // bring up the activity
-            getActivity();
-
             // find a view and make sure it is not focused
             AccessibilityNodeInfo button = AccessibilityInteractionClient.getInstance()
-                .findAccessibilityNodeInfoByViewIdInActiveWindow(connection, R.id.button5);
+                .findAccessibilityNodeInfoByViewIdInActiveWindow(sConnectionId, R.id.button5);
             AccessibilityNodeInfo parent = button.getParent();
             final int childCount = parent.getChildCount();
             for (int i = 0; i < childCount; i++) {
@@ -459,24 +411,57 @@
         }
     }
 
-    @Override
-    protected void scrubClass(Class<?> testCaseClass) {
-        /* intentionally do not scrub */
+    private void bringUpActivityWithInitalizedAccessbility() {
+        mLastAccessibilityEvent = null;
+        // bring up the activity
+        getActivity();
+
+        final long startTimeMillis = SystemClock.uptimeMillis();
+        while (true) {
+            if (mLastAccessibilityEvent != null) {
+                final int eventType = mLastAccessibilityEvent.getEventType();
+                if (eventType == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
+                    return;
+                }
+            }
+            final long remainingTimeMillis = TIMEOUT_ACCESSIBLITY_STATE_INITIALIZED_MILLIS
+                    - (SystemClock.uptimeMillis() - startTimeMillis);
+            if (remainingTimeMillis <= 0) {
+                return;
+            }
+            synchronized (this) {
+                try {
+                    wait(remainingTimeMillis);
+                } catch (InterruptedException e) {
+                    /* ignore */
+                }
+            }
+        }
     }
 
-    private IAccessibilityServiceConnection getConnection() throws Exception {
-        if (sConnection == null) {
+    private void ensureConnection() throws Exception {
+        if (sConnectionId == View.NO_ID) {
             IEventListener listener = new IEventListener.Stub() {
-                public void setConnection(IAccessibilityServiceConnection connection) {}
+                public void setConnection(IAccessibilityServiceConnection connection,
+                        int connectionId) {
+                    sConnectionId = connectionId;
+                    if (connection != null) {
+                        AccessibilityInteractionClient.getInstance().addConnection(connectionId,
+                                connection);
+                    } else {
+                        AccessibilityInteractionClient.getInstance().removeConnection(connectionId);
+                    }
+                    synchronized (this) {
+                        notifyAll();
+                    }
+                }
 
                 public void onInterrupt() {}
 
                 public void onAccessibilityEvent(AccessibilityEvent event) {
-                    if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_FOCUSED) {
-                        sLastFocusAccessibilityEvent = AccessibilityEvent.obtain(event);
-                    }
-                    synchronized (sConnection) {
-                        sConnection.notifyAll();
+                    mLastAccessibilityEvent = AccessibilityEvent.obtain(event);
+                    synchronized (this) {
+                        notifyAll();
                     }
                 }
             };
@@ -485,28 +470,11 @@
                 AccessibilityManager.getInstance(getInstrumentation().getContext());
 
             synchronized (this) {
-                if (!accessibilityManager.isEnabled()) {
-                    // Make sure we wake ourselves as the desired state is propagated.
-                    accessibilityManager.addAccessibilityStateChangeListener(
-                            new AccessibilityManager.AccessibilityStateChangeListener() {
-                                public void onAccessibilityStateChanged(boolean enabled) {
-                                    synchronized (this) {
-                                        notifyAll();
-                                    }
-                                }
-                            });
-                    IAccessibilityManager manager = IAccessibilityManager.Stub.asInterface(
+                IAccessibilityManager manager = IAccessibilityManager.Stub.asInterface(
                         ServiceManager.getService(Context.ACCESSIBILITY_SERVICE));
-                    sConnection = manager.registerEventListener(listener);
-
-                    wait(TIMEOUT_PROPAGATE_ACCESSIBLITY_SETTING);
-                } else {
-                    IAccessibilityManager manager = IAccessibilityManager.Stub.asInterface(
-                          ServiceManager.getService(Context.ACCESSIBILITY_SERVICE));
-                    sConnection = manager.registerEventListener(listener);
-                }
+                manager.registerEventListener(listener);
+                wait(TIMEOUT_PROPAGATE_ACCESSIBLITY_SETTING);
             }
         }
-        return sConnection;
     }
 }
diff --git a/data/fonts/DroidSansArmenian.ttf b/data/fonts/DroidSansArmenian.ttf
index 62f67e0..6fafa54 100644
--- a/data/fonts/DroidSansArmenian.ttf
+++ b/data/fonts/DroidSansArmenian.ttf
Binary files differ
diff --git a/data/fonts/DroidSansGeorgian.ttf b/data/fonts/DroidSansGeorgian.ttf
index 743ae66..3a2e9fb 100644
--- a/data/fonts/DroidSansGeorgian.ttf
+++ b/data/fonts/DroidSansGeorgian.ttf
Binary files differ
diff --git a/data/keyboards/Generic.kl b/data/keyboards/Generic.kl
index 10de6ac..fdd9040 100644
--- a/data/keyboards/Generic.kl
+++ b/data/keyboards/Generic.kl
@@ -159,7 +159,7 @@
 # key 137 "KEY_CUT"
 # key 138 "KEY_HELP"
 key 139   MENU              WAKE_DROPPED
-# key 140 "KEY_CALC"
+key 140   CALCULATOR
 # key 141 "KEY_SETUP"
 key 142   POWER             WAKE
 key 143   POWER             WAKE
@@ -190,7 +190,7 @@
 key 168   MEDIA_REWIND
 key 169   CALL
 # key 170 "KEY_ISO"
-# key 171 "KEY_CONFIG"
+key 171   MUSIC
 key 172   HOME
 # key 173 "KEY_REFRESH"
 # key 174 "KEY_EXIT"
@@ -232,7 +232,7 @@
 # key 210 "KEY_PRINT"
 # key 211 "KEY_HP"
 key 212   CAMERA
-# key 213 "KEY_SOUND"
+key 213   MUSIC
 # key 214 "KEY_QUESTION"
 key 215   ENVELOPE
 # key 216 "KEY_CHAT"
@@ -344,7 +344,7 @@
 # key 394 "KEY_DIRECTORY"
 # key 395 "KEY_LIST"
 # key 396 "KEY_MEMO"
-# key 397 "KEY_CALENDAR"
+key 397   CALENDAR
 # key 398 "KEY_RED"
 # key 399 "KEY_GREEN"
 # key 400 "KEY_YELLOW"
@@ -364,6 +364,7 @@
 # key 414 "KEY_TEEN"
 # key 415 "KEY_TWEN"
 
+key 429   CONTACTS
 
 # key 448 "KEY_DEL_EOL"
 # key 449 "KEY_DEL_EOS"
diff --git a/docs/html/guide/market/billing/billing_admin.jd b/docs/html/guide/market/billing/billing_admin.jd
index cbb4b29..a84eb4e 100755
--- a/docs/html/guide/market/billing/billing_admin.jd
+++ b/docs/html/guide/market/billing/billing_admin.jd
@@ -39,12 +39,12 @@
 site, registering test accounts, and handling refunds when necessary.</p>
 
 <p>You must have an Android Market publisher account to register test accounts. And you must have a
-Google Checkout Merchant account to create a product list and issue refunds to your users. If you
+Google Checkout merchant account to create a product list and issue refunds to your users. If you
 already have a publisher account on Android Market, you can use your existing account. You do not
 need to register for a new account to support in-app billing. If you do not have a publisher
 account, you can register as an Android Market developer and set up a publisher account at the
 Android Market <a href="http://market.android.com/publish">publisher site</a>. If you do not have a
-Google Checkout Merchant account, you can register for one at the <a
+Google Checkout merchant account, you can register for one at the <a
 href="http://checkout.google.com">Google Checkout site</a>.</p>
 
 <h2 id="billing-list-setup">Creating a Product List</h2>
@@ -57,7 +57,7 @@
 <p>You can access an application's product list by clicking the <strong>In-App Products</strong>
 link that appears under each of the applications that are listed for your publisher account (see
 figure 1). The <strong>In-App Products</strong> link appears only if you have a Google Checkout
-Merchant account and an application's manifest includes the <code>com.android.vending.BILLING</code>
+merchant account and an application's manifest includes the <code>com.android.vending.BILLING</code>
 permission.</p>
 
 <img src="{@docRoot}images/billing_product_list_entry.png" height="548" id="figure1" />
@@ -71,20 +71,37 @@
 you are selling in your application. It does not store any digital content. You are responsible for
 storing and delivering the digital content that you sell in your applications.</p>
 
-<img src="{@docRoot}images/billing_product_list.png" height="560" id="figure2" />
+<img src="{@docRoot}images/billing_product_list.png" height="658" id="figure2" />
 <p class="img-caption">
   <strong>Figure 2.</strong> An application's product list.
 </p>
 
-<p>You can create a product list for a published application or a draft application that's been
-uploaded and saved to the Android Market site. However, you must have a Google Checkout Merchant
+<p>You can create a product list for any published application or any draft application that's been
+uploaded and saved to the Android Market site. However, you must have a Google Checkout merchant
 account and the application's manifest must include the <code>com.android.vending.BILLING</code>
 permission. If an application's manifest does not include this permission, you will be able to edit
 existing items in the product list but you will not be able to add new items to the list. For more
-information, see <a href="#billing-permission">Modifying your application's AndroidManifest.xml
-file</a>.</p>
+information about this permission, see
+<a href="{@docRoot}guide/market/billing/billing_integrate.html#billing-permission">Updating Your
+Application's Manifest</a>.</p>
 
-<p>To create a product list for an application, follow these steps:</p>
+<p>In addition, an application package can have only one product list. If you create a product
+list for an application, and you use the <a
+href="{@docRoot}guide/market/publishing/multiple-apks.html">multiple APK feature</a> to distribute
+more than one APK for that application, the product list applies to all APK versions that are
+associated with the application listing. You cannot create individual product lists for each APK if
+you are using the multiple APK feature.</p>
+
+<p>You can add items to a product list two ways: you can add items one at a time by using the In-app
+Products UI (see figure 3), or you can add a batch of items by importing the items from a
+comma-separated values (CSV) file (see figure 2). Adding items one at a time is useful if your
+application has only a few in-app items or you are adding only a few items to a
+product list for testing purposes. The CSV file method is useful if your application has a large
+number of in-app items.</p>
+
+<h3 id="billing-form-add">Adding items one at a time to a product list</h3>
+
+<p>To add an item to a product list using the In-app Products UI, follow these steps:</p>
 
 <ol>
   <li><a href="http://market.android.com/publish">Log in</a> to your publisher account.</li>
@@ -92,7 +109,7 @@
   <strong>In-app Products</strong>.</li>
   <li>On the In-app Products List page, click <strong>Add in-app product</strong>.</li>
   <li>On the Create New In-app Product page (see figure 3), provide details about the item you are
-  selling and then click <strong>Save</strong>.</li>
+  selling and then click <strong>Save</strong> or <strong>Publish</strong>.</li>
 </ol>
 
 <img src="{@docRoot}images/billing_list_form.png" height="840" id="figure3" />
@@ -109,25 +126,31 @@
     (0-9), underlines (_), and dots (.). The product ID "android.test" is reserved, as are all
     product IDs that start with "android.test."</p>
     <p>In addition, you cannot modify an item's product ID after it is created, and you cannot reuse
-    a product ID, even if you delete the item previously using the product ID.</p>
+    a product ID.</p>
   </li>
-  <li><strong>Purchase type</strong>
-    <p>The purchase type can be "managed per user account" or "unmanaged." You can specify an item's
-    purchase type only through the publisher site and you can never change an item's purchase type
-    once you specify it. For more information, see <a href="#billing_purchase_type">Choosing a
-    purchase type</a> later in this document.</p>
+  <li><strong>Purchase Type</strong>
+    <p>The purchase type can be <strong>Managed per user account</strong> or <strong>
+    Unmanaged</strong>. You can never change an item's purchase type after you set it. For more
+    information, see <a href="#billing-purchase-type">Choosing a purchase type</a> later in this
+    document.</p>
   </li>
   <li><strong>Publishing State</strong>
-    <p>An item's publishing state can be "published" or "unpublished." However, to be visible to a
-    user during checkout, an item's publishing state must be set to "published" and the item's
-    application must be published on Android Market.</p>
+    <p>An item's publishing state can be <strong>Published</strong> or <strong>Unpublished
+    </strong>. To be visible to a user during checkout, an item's publishing state must be set to
+    <strong>Published</strong> and the item's application must be published on Android Market.</p>
     <p class="note"><strong>Note:</strong> This is not true for test accounts. An item is visible to
     a test account if the application is not published and the item is published. See <a
     href="{@docRoot}guide/market/billing/billing_testing.html#billing-testing-real">Testing In-app
     Billing</a> for more information.</p>
   </li>
   <li><strong>Language</strong>
-    <p>A product list inherits its language from the parent application.</p>
+    <p>The language setting determines which languages are used to display the item title and
+    item description during checkout. A product list inherits its default language from the
+    parent application. You can add more languages by clicking <strong>add language</strong>. You
+    can also choose to have the title and description automatically translated from the default
+    language by selecting the <strong>Fill fields with auto translation</strong> checkbox (see
+    figure 4). If you do not use the auto translation feature, you must provide the translated
+    versions of the title and description.</p>
   </li>
   <li><strong>Title</strong>
     <p>The title is a short descriptor for the item. For example, "Sleeping potion." Titles must be
@@ -141,9 +164,20 @@
     visible to users during checkout. Descriptions can be up to 80 characters in length.</p>
   </li>
   <li><strong>Price</strong>
-    <p>Every item must have a price greater than zero; you cannot set a price of "0" (free).</p>
+    <p>You must provide a default price in your home currency. You can also provide prices in other
+    currencies, but you can do this only if a currency's corresponding country is listed as a
+    target country for your application. You can specify target countries on the Edit Application
+    page in the Android Market developer console.</p>
+    <p>To specify prices in other currencies, you can manually enter the price for each
+    currency or you can click <strong>Auto Fill</strong> and let Android Market do a one-time
+    conversion from your home currency to the currencies you are targeting (see figure 4).</p>
   </li>
 </ul>
+<img src="{@docRoot}images/billing_list_form_2.png" height="1226" id="figure4" />
+<p class="img-caption">
+  <strong>Figure 4.</strong> Specifying additional currencies and additional languages for the
+  item title and description.
+</p>
 
 <p>For more information about product IDs and product lists, see <a
 href="http://market.android.com/support/bin/answer.py?answer=1072599">Creating In-App Product
@@ -154,6 +188,197 @@
 <p class="note"><strong>Note</strong>: Be sure to plan your product ID namespace. You cannot reuse
 or modify product IDs after you save them.</p>
 
+<h3 id="billing-bulk-add">Adding a batch of items to a product list</h3>
+
+<p>To add a batch of items to a product list using a CSV file, you first need to create your CSV
+file. The data values that you specify in the CSV file represent the same data values you specify
+manually through the In-app Products UI (see <a href="#billing-form-add">Adding items one at a time
+to a product list</a>). The CSV file uses commas (,) and semi-colons (;) to separate data values.
+Commas are used to separate primary data values, and semi-colons are used to separate subvalues. For
+example, the syntax for the CSV file is as follows:</p>
+
+<p>"<em>product_id</em>","<em>publish_state</em>","<em>purchase_type</em>","<em>autotranslate</em>
+","<em>locale</em>; <em>title</em>; <em>description</em>","<em>autofill</em>","<em>country</em>;
+<em>price</em>"
+</p>
+
+<p>Descriptions and usage details are provided below.</p>
+
+<ul>
+  <li><em>product_id</em>
+    <p>This is equivalent to the In-app Product ID setting in the In-app Products UI. If you specify
+    a <em>product_id</em> that already exists in a product list, and you choose to overwrite
+    the product list while importing the CSV file, the data for the existing item is overwritten with
+    the values specified in the CSV file. The overwrite feature does not delete items that are on a
+    product list but not present in the CSV file.</p>
+  </li>
+  <li><em>publish_state</em>
+    <p>This is equivalent to the Publishing State setting in the In-app Products UI. Can be <code>
+    published</code> or <code>unpublished</code>.</p>
+  </li>
+  <li><em>purchase_type</em>
+    <p>This is equivalent to the Purchase Type setting in the In-app Products UI. Can be <code>
+    managed_by_android</code>, which is equivalent to <strong>Managed per user account
+    </strong> in the In-app Products UI, or <code>managed_by_publisher</code>, which is equivalent
+    to <strong>Unmanaged</strong> in the In-app Products UI.</p>
+  </li>
+  <li><em>autotranslate</em>
+    <p>This is equivalent to selecting the <strong>Fill fields with auto translation</strong>
+    checkbox in the In-app Products UI. Can be <code>true</code> or <code>false</code>.</p>
+  </li>
+  <li><em>locale</em>
+    <p>This is equivalent to the Language setting in the In-app Products UI. You must have an entry
+    for the default locale. The default locale must be the first entry in the list of
+    locales, and it must include a <em>title</em> and <em>description</em>. If you want to provide
+    translated versions of the <em>title</em> and <em>description</em> in addition to the default,
+    you must use the following syntax rules:</p>
+    <p>If <em>autotranslate</em> is <code>true</code>, you must specify the default locale,
+    default title, default description, and other locales using the following format:</p>
+    <p>"true,"<em>default_locale</em>; <em>default_locale_title</em>;
+    <em>default_locale_description</em>; <em>locale_2</em>;    <em>locale_3</em>, ..."</p>
+    <p>If <em>autotranslate</em> is <code>false</code>, you must specify the default locale,
+    default title, and default description as well as the translated titles and descriptions using
+    the following format:</p>
+    <p>"false,"<em>default_locale</em>; <em>default_locale_title</em>;
+    <em>default_locale_description</em>; <em>locale_2</em>; <em>locale_2_title</em>;
+    <em>local_2_description</em>; <em>locale_3</em>; <em>locale_3_title</em>;
+     <em>locale_3_description</em>; ..."</p>
+    <p>See table 1 for a list of the language codes you can use with the <em>locale</em> field.</p>
+  </li>
+  <li><em>title</em>
+    <p>This is equivalent to the Title setting in the In-app Products UI. If the <em>title</em>
+    contains a semicolon, it must be escaped with a backslash (for example, "\;"). A backslash
+    should also be escaped with a backslash (for example, "\\">.</p>
+  </li>
+  <li><em>description</em>
+    <p>This is equivalent to the Description in the In-app Products UI. If the <em>description</em>
+    contains a semicolon, it must be escaped with a backslash (for example, "\;"). A backslash
+    should also be escaped with a backslash (for example, "\\">.</p>
+  </li>
+  <li><em>autofill</em>
+    <p>This is equivalent to clicking <strong>Auto Fill</strong> in the In-app Products UI. Can be
+    <code>true</code> or <code>false</code>. The syntax for specifying the <em>country</em>
+    and <em>price</em> varies depending on which <em>autofill</em> setting you use.</p>
+    <p>If <em>autofill</em> is set to <code>true</code>, you need to specify only the default
+    price in your home currency and you must use this syntax:</p>
+    <p>"true","<em>default_price_in_home_currency</em>"
+    <p>If <em>autofill</em> is set to <code>false</code>, you need to specify a <em>country</em>
+    and a <em>price</em> for each currency and you must use the following syntax:</p>
+    <p>"false", "<em>home_country</em>; <em>default_price_in_home_currency</em>; <em>country_2</em>;
+    <em>country_2_price</em>; <em>country_3</em>; <em>country_3_price</em>; ..."</p>
+  </li>
+  <li><em>country</em>
+    <p>The country for which you are specifying a price. You can only list countries that your
+    application is targeting. The country codes are two-letter uppercase
+    ISO country codes (such as "US") as defined by
+    <a href="http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2">ISO 3166-2</a>.</p>
+  </li>
+  <li><em>price</em>
+    <p>This is equivalent to the Price in the In-app Products UI. The price must be specified in
+    micro-units. To convert a currency value to micro-units, you multiply the real value by 1,000,000.
+    For example, if you want to sell an in-app item for $1.99 you specify 1990000 in the
+    <em>price</em> field.</p>
+  </li>
+</ul>
+
+<p class="table-caption" id="language-table"><strong>Table 1.</strong> Language codes you can use
+with the <em>locale</em> field.</p>
+
+<table>
+
+<tr>
+<th>Language</th>
+<th>Code</th>
+<th>Language</th>
+<th>Code</th>
+</tr>
+<tr>
+<td>Chinese</td>
+<td>zh_TW</td>
+<td>Italian</td>
+<td>it_IT</td>
+</tr>
+<tr>
+<td>Czech</td>
+<td>cs_CZ</td>
+<td>Japanese</td>
+<td>ja_JP</td>
+</tr>
+<tr>
+<td>Danish</td>
+<td>da_DK</td>
+<td>Korean</td>
+<td>ko_KR</td>
+</tr>
+<tr>
+<td>Dutch</td>
+<td>nl_NL</td>
+<td>Norwegian</td>
+<td>no_NO</td>
+</tr>
+<tr>
+<td>English</td>
+<td>en_US</td>
+<td>Polish</td>
+<td>pl_PL</td>
+</tr>
+<tr>
+<td>French</td>
+<td>fr_FR</td>
+<td>Portuguese</td>
+<td>pt_PT</td>
+</tr>
+<tr>
+<td>Finnish</td>
+<td>fi_FI</td>
+<td>Russian</td>
+<td>ru_RU</td>
+</tr>
+<tr>
+<td>German</td>
+<td>de_DE</td>
+<td>Spanish</td>
+<td>es_ES</td>
+</tr>
+<tr>
+<td>Hebrew</td>
+<td>iw_IL</td>
+<td>Swedish</td>
+<td>sv_SE</td>
+</tr>
+<tr>
+<td>Hindi</td>
+<td>hi_IN</td>
+<td>--</td>
+<td>--</td>
+</tr>
+</table>
+
+<p>To import the items that are specified in your CSV file, do the following:</p>
+
+<ol>
+  <li><a href="http://market.android.com/publish">Log in</a> to your publisher account.</li>
+  <li>In the <strong>All Android Market listings</strong> panel, under the application name, click
+  <strong>In-app Products</strong>.</li>
+  <li>On the In-app Products List page, click <strong>Choose File</strong> and select your CSV
+file.
+    <p>The CSV file must be on your local computer or on a local disk that is connected to your
+    computer.</p>
+  </li>
+  <li>Select the <strong>Overwrite</strong> checkbox if you want to overwrite existing items in
+  your product list.
+    <p>This option overwrites values of existing items only if the value of the <em>product_id</em>
+    in the CSV file matches the In-app Product ID for an existing item in the product list.
+    Overwriting does not delete items that are on a product list but not present in the CSV
+    file.</p>
+  </li>
+  <li>On the In-app Products List page, click <strong>Import from CSV</strong>.</li>
+</ol>
+
+<p>You can also export an existing product list to a CSV file by clicking <strong>Export to CSV
+</strong> on the In-app Product List page. This is useful if you have manually added items to
+a product list and you want to start managing the product list through a CSV file.</p>
+
 <h3 id="billing-purchase-type">Choosing a Purchase Type</h3>
 
 <p>An item's purchase type controls how Android Market manages the purchase of the item. There are
@@ -194,7 +419,7 @@
 
 <p>In-app billing does not allow users to send a refund request to Android Market. Refunds for
 in-app purchases must be directed to you (the application developer). You can then process the
-refund through your Google Checkout Merchant account. When you do this, Android Market receives a
+refund through your Google Checkout merchant account. When you do this, Android Market receives a
 refund notification from Google Checkout, and Android Market sends a refund message to your
 application. For more information, see <a
 href="{@docRoot}guide/market/billing/billing_overview.html#billing-action-notify">Handling
@@ -236,15 +461,15 @@
   <li><a href="http://market.android.com/publish">Log in</a> to your publisher account.</li>
   <li>On the upper left part of the page, under your name, click <strong>Edit profile</strong>.</li>
   <li>On the Edit Profile page, scroll down to the Licensing &amp; In-app Billing panel (see figure
-  4).</li>
+  5).</li>
   <li>In Test Accounts, add the email addresses for the test accounts you want to register,
   separating each account with a comma.</li>
   <li>Click <strong>Save</strong> to save your profile changes.</li>
 </ol>
 
-<img src="{@docRoot}images/billing_public_key.png" height="510" id="figure4" />
+<img src="{@docRoot}images/billing_public_key.png" height="510" id="figure5" />
 <p class="img-caption">
-  <strong>Figure 4.</strong> The Licensing and In-app Billing panel of your account's Edit Profile
+  <strong>Figure 5.</strong> The Licensing and In-app Billing panel of your account's Edit Profile
   page lets you register test accounts.
 </p>
 
diff --git a/docs/html/guide/practices/ui_guidelines/widget_design.jd b/docs/html/guide/practices/ui_guidelines/widget_design.jd
index de20e00..f63f3c4 100644
--- a/docs/html/guide/practices/ui_guidelines/widget_design.jd
+++ b/docs/html/guide/practices/ui_guidelines/widget_design.jd
@@ -250,13 +250,15 @@
 sizes, widget layouts must adapt to different Home screen grid cell sizes.</p>
 
 <p>Below is an example layout that a music widget showing text information and two buttons can use.
-It builds upon the previous discussion of adding margins depending on OS version.</p>
+It builds upon the previous discussion of adding margins depending on OS version. Note that the
+most robust and resilient way to add margins to the widget is to wrap the widget frame and contents
+in a padded {@link android.widget.FrameLayout}.</p>
 
 <pre>
 &lt;FrameLayout
   android:layout_width="match_parent"
   android:layout_height="match_parent"
-  android:layout_margin="@dimen/widget_margin"&gt;
+  android:padding="@dimen/widget_margin"&gt;
 
   &lt;LinearLayout
     android:layout_width="match_parent"
@@ -295,16 +297,16 @@
 
 
 <p>When a user adds the widget to their home screen, on an example Android 4.0 device where each
-grid cell is 80dp &times; 100dp in size and 16dp of margins are automatically applied on all sizes,
+grid cell is 80dp &times; 100dp in size and 8dp of margins are automatically applied on all sizes,
 the widget will be stretched, like so:</p>
 
 
 <img src="{@docRoot}images/widget_design/music_example_stretched.png"
-  alt="Music widget sitting on an example 80dp x 100dp grid with 16dp of automatic margins
+  alt="Music widget sitting on an example 80dp x 100dp grid with 8dp of automatic margins
   added by the system" id="music_example_stretched">
 
 <p class="img-caption"><strong>Figure 7.</strong> Music widget sitting on an example 80dp x 100dp
-grid with 16dp of automatic margins added by the system.</p>
+grid with 8dp of automatic margins added by the system.</p>
 
 
 <h2 id="templates">Using the App Widget Templates Pack</h2>
diff --git a/docs/html/guide/topics/appwidgets/index.jd b/docs/html/guide/topics/appwidgets/index.jd
index 61337b7..2cb23c1 100644
--- a/docs/html/guide/topics/appwidgets/index.jd
+++ b/docs/html/guide/topics/appwidgets/index.jd
@@ -346,7 +346,7 @@
 &lt;FrameLayout
   android:layout_width="match_parent"
   android:layout_height="match_parent"
-  <strong>android:layout_margin="@dimen/widget_margin"&gt;</strong>
+  <strong>android:padding="@dimen/widget_margin"&gt;</strong>
 
   &lt;LinearLayout
     android:layout_width="match_parent"
@@ -363,7 +363,7 @@
   <li>Create two dimensions resources, one in <code>res/values/</code> to provide the pre-Android 4.0 custom margins, and one in <code>res/values-v14/</code> to provide no extra padding for Android 4.0 widgets:
 
     <p><strong>res/values/dimens.xml</strong>:<br>
-    <pre>&lt;dimen name="widget_margin"&gt;15dp&lt;/dimen&gt;</pre></p>
+    <pre>&lt;dimen name="widget_margin"&gt;8dp&lt;/dimen&gt;</pre></p>
 
     <p><strong>res/values-v14/dimens.xml</strong>:<br>
     <pre>&lt;dimen name="widget_margin"&gt;0dp&lt;/dimen&gt;</pre></p>
diff --git a/docs/html/guide/topics/graphics/2d-graphics.jd b/docs/html/guide/topics/graphics/2d-graphics.jd
index 5abffb3..5cf1a59 100644
--- a/docs/html/guide/topics/graphics/2d-graphics.jd
+++ b/docs/html/guide/topics/graphics/2d-graphics.jd
@@ -130,9 +130,8 @@
 <p class="note"><strong>Note: </strong> In order to request an invalidate from a thread other than your main
 Activity's thread, you must call <code>{@link android.view.View#postInvalidate()}</code>.</p>
 
-<p>Also read <a href="{@docRoot}guide/topics/ui/custom-components.html">Building Custom Components</a>
-for a guide to extending a View class, and <a href="2d-graphics.html">2D Graphics: Drawables</a> for
-information on using Drawable objects like images from your resources and other primitive shapes.</p>
+<p>For information about extending the {@link android.view.View} class, read
+<a href="{@docRoot}guide/topics/ui/custom-components.html">Building Custom Components</a>.</p>
 
 <p>For a sample application, see the Snake game, in the SDK samples folder:
 <code>&lt;your-sdk-directory>/samples/Snake/</code>.</p>
@@ -188,7 +187,7 @@
 
 <p>This document discusses the basics of using Drawable objects to draw graphics and how to use a
 couple subclasses of the Drawable class. For information on using Drawables to do frame-by-frame
-animation, see <a href="{@docRoot}guide/topics/animation/drawable-animation.html">Drawable
+animation, see <a href="{@docRoot}guide/topics/graphics/drawable-animation.html">Drawable
 Animation</a>.</p>
 
 <p>A {@link android.graphics.drawable.Drawable} is a general abstraction for "something that can be
diff --git a/docs/html/guide/topics/providers/calendar-provider.jd b/docs/html/guide/topics/providers/calendar-provider.jd
index 3ab5125..d30dda4 100644
--- a/docs/html/guide/topics/providers/calendar-provider.jd
+++ b/docs/html/guide/topics/providers/calendar-provider.jd
@@ -280,11 +280,9 @@
 {@link android.provider.CalendarContract.Calendars#ACCOUNT_TYPE Calendars.ACCOUNT_TYPE}
 in the selection. That is because a given account is
 only considered unique given both its <code>ACCOUNT_NAME</code> and its
-<code>ACCOUNT_TYPE</code>. The <code>ACCOUNT_TYPE</code> refers to the way that
-the account is being  synced. It is often but not always the domain. For
-example, an account could be  synced through a corporate pop3 sync adapter, in which
-case the <code>ACCOUNT_TYPE</code> would not be a domain. There is also a
-special type of account called {@link
+<code>ACCOUNT_TYPE</code>. The <code>ACCOUNT_TYPE</code> is the string corresponding to the
+account authenticator that was used when the account was registered with the
+{@link android.accounts.AccountManager}. There is also a special type of account called {@link
 android.provider.CalendarContract#ACCOUNT_TYPE_LOCAL} for calendars not
 associated with a device account. {@link
 android.provider.CalendarContract#ACCOUNT_TYPE_LOCAL} accounts do not get
diff --git a/docs/html/guide/topics/renderscript/index.jd b/docs/html/guide/topics/renderscript/index.jd
index eb77310..148705c 100644
--- a/docs/html/guide/topics/renderscript/index.jd
+++ b/docs/html/guide/topics/renderscript/index.jd
@@ -151,10 +151,9 @@
     defining two-, three-, or four-vectors.</li>
   </ul>
 
-  <p>The <a href="{@docRoot}guide/topics/renderscript/rs-api/files.html">RenderScript header files</a>
-  and LLVM front-end libraries are located in the <code>include</code> and
-  <code>clang-include</code> directories in the
-  <code>&lt;sdk_root&gt;/platforms/android-11/renderscript</code> directory of the Android SDK. The
+  <p>The RenderScript header files and LLVM front-end libraries are located in the <code>include/</code> and
+  <code>clang-include/</code> directories in the
+  <code>&lt;sdk_root&gt;/platforms/android-11/renderscript/</code> directory of the Android SDK. The
   headers are automatically included for you, except for the RenderScript graphics specific header file, which
   you can include as follows:</p>
   <pre>
diff --git a/docs/html/images/billing_list_form_2.png b/docs/html/images/billing_list_form_2.png
new file mode 100755
index 0000000..d321a20
--- /dev/null
+++ b/docs/html/images/billing_list_form_2.png
Binary files differ
diff --git a/docs/html/images/billing_product_list.png b/docs/html/images/billing_product_list.png
index 49a7e79..a89f21b 100755
--- a/docs/html/images/billing_product_list.png
+++ b/docs/html/images/billing_product_list.png
Binary files differ
diff --git a/docs/html/resources/dashboard/opengl.jd b/docs/html/resources/dashboard/opengl.jd
index 07a0e43..4d0abec 100644
--- a/docs/html/resources/dashboard/opengl.jd
+++ b/docs/html/resources/dashboard/opengl.jd
@@ -57,7 +57,7 @@
 <div class="dashboard-panel">
 
 <img alt="" width="400" height="250"
-src="http://chart.googleapis.com/chart?cht=p&chs=400x250&chco=c4df9b,6fad0c&chl=GL%201.1|GL%202.0%20%26%201.1&chd=t%3A9.8,90.2" />
+src="http://chart.googleapis.com/chart?cht=p&chs=400x250&chco=c4df9b,6fad0c&chl=GL%201.1|GL%202.0%20%26%201.1&chd=t%3A10.1,89.9" />
 
 <table>
 <tr>
@@ -66,14 +66,14 @@
 </tr>
 <tr>
 <td>1.1</th>
-<td>9.8%</td>
+<td>10.1%</td>
 </tr>
 <tr>
 <td>2.0</th>
-<td>90.2%</td>
+<td>89.9%</td>
 </tr>
 </table>
 
-<p><em>Data collected during a 7-day period ending on November 3, 2011</em></p>
+<p><em>Data collected during a 7-day period ending on December 1, 2011</em></p>
 </div>
 
diff --git a/docs/html/resources/dashboard/platform-versions.jd b/docs/html/resources/dashboard/platform-versions.jd
index 8041096..72370bb 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.9,1.4,10.7,40.7,0.5,43.9,0.1,0.9,0.9&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&chco=c4df9b,6fad0c" />
+src="http://chart.apis.google.com/chart?&cht=p&chs=460x250&chd=t:0.8,1.3,9.6,35.3,0.5,50.1,0.1,1.1,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&chco=c4df9b,6fad0c" />
 
 <table>
 <tr>
@@ -61,21 +61,21 @@
   <th>API Level</th>
   <th>Distribution</th>
 </tr>
-<tr><td><a href="{@docRoot}sdk/android-1.5.html">Android 1.5</a></td><td>Cupcake</td>  <td>3</td><td>0.9%</td></tr>
-<tr><td><a href="{@docRoot}sdk/android-1.6.html">Android 1.6</a></td><td>Donut</td>    <td>4</td><td>1.4%</td></tr>
-<tr><td><a href="{@docRoot}sdk/android-2.1.html">Android 2.1</a></td><td>Eclair</td>   <td>7</td><td>10.7%</td></tr>
-<tr><td><a href="{@docRoot}sdk/android-2.2.html">Android 2.2</a></td><td>Froyo</td>    <td>8</td><td>40.7%</td></tr>
+<tr><td><a href="{@docRoot}sdk/android-1.5.html">Android 1.5</a></td><td>Cupcake</td>  <td>3</td><td>0.8%</td></tr>
+<tr><td><a href="{@docRoot}sdk/android-1.6.html">Android 1.6</a></td><td>Donut</td>    <td>4</td><td>1.3%</td></tr>
+<tr><td><a href="{@docRoot}sdk/android-2.1.html">Android 2.1</a></td><td>Eclair</td>   <td>7</td><td>9.6%</td></tr>
+<tr><td><a href="{@docRoot}sdk/android-2.2.html">Android 2.2</a></td><td>Froyo</td>    <td>8</td><td>35.3%</td></tr>
 <tr><td><a href="{@docRoot}sdk/android-2.3.html">Android 2.3 -<br/>
                              Android 2.3.2</a></td><td rowspan="2">Gingerbread</td>    <td>9</td><td>0.5%</td></tr>
 <tr><td><a href="{@docRoot}sdk/android-2.3.3.html">Android 2.3.3 -<br/>
-      Android 2.3.7</a></td><!-- Gingerbread -->                                       <td>10</td><td>43.9%</td></tr>
+      Android 2.3.7</a></td><!-- Gingerbread -->                                       <td>10</td><td>50.1%</td></tr>
 <tr><td><a href="{@docRoot}sdk/android-3.0.html">Android 3.0</a></td>
                                                    <td rowspan="3">Honeycomb</td>      <td>11</td><td>0.1%</td></tr>
-<tr><td><a href="{@docRoot}sdk/android-3.1.html">Android 3.1</a></td><!-- Honeycomb --><td>12</td><td>0.9%</td></tr>
-<tr><td><a href="{@docRoot}sdk/android-3.2.html">Android 3.2</a></td><!-- Honeycomb --><td>13</td><td>0.9%</td></tr> 
+<tr><td><a href="{@docRoot}sdk/android-3.1.html">Android 3.1</a></td><!-- Honeycomb --><td>12</td><td>1.1%</td></tr>
+<tr><td><a href="{@docRoot}sdk/android-3.2.html">Android 3.2</a></td><!-- Honeycomb --><td>13</td><td>1.2%</td></tr> 
 </table>
 
-<p><em>Data collected during a 14-day period ending on November 3, 2011</em></p>
+<p><em>Data collected during a 14-day period ending on December 1, 2011</em></p>
 <!--
 <p style="font-size:.9em">* <em>Other: 0.1% of devices running obsolete versions</em></p>
 -->
@@ -104,9 +104,9 @@
 <div class="dashboard-panel">
 
 <img alt="" height="250" width="660" style="padding:5px;background:#fff"
-src="http://chart.apis.google.com/chart?&cht=lc&chs=660x250&chxt=x,x,y,r&chxr=0,0,12|1,0,12|2,0,100|3,0,100&chxl=0%3A%7C05/01%7C05/15%7C06/01%7C06/15%7C07/01%7C07/15%7C08/01%7C08/15%7C09/01%7C09/15%7C10/01%7C10/15%7C11/01%7C1%3A%7C2011%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C2011%7C2%3A%7C0%25%7C25%25%7C50%25%7C75%25%7C100%25%7C3%3A%7C0%25%7C25%25%7C50%25%7C75%25%7C100%25&chxp=0,0,1,2,3,4,5,6,7,8,9,10,11,12&chxtc=0,5&chd=t:99.6,99.5,99.4,99.3,99.2,99.0,98.8,98.7,98.5,98.5,98.2,98.1,98.0|97.3,97.5,97.5,97.5,97.7,97.6,97.5,97.5,97.5,97.5,97.1,97.1,97.1|94.3,94.8,95.0,95.2,95.5,95.5,95.5,95.6,95.7,95.8,95.6,95.9,95.7|69.8,71.5,73.9,75.4,77.6,79.0,80.2,81.1,82.4,83.3,83.8,84.9,85.0|4.0,6.1,9.5,13.6,17.8,20.6,24.3,27.5,31.2,34.7,38.3,41.3,44.0|3.0,5.1,8.4,12.6,16.8,20.0,23.7,26.9,30.6,34.1,37.8,40.8,43.5&chm=b,c3df9b,0,1,0|b,b4db77,1,2,0|tAndroid 2.1,547a19,2,0,15,,t::-5|b,a5db51,2,3,0|tAndroid 2.2,3f5e0e,3,0,15,,t::-5|b,96dd28,3,4,0|b,83c916,4,5,0|tAndroid 2.3.3,131d02,5,3,15,,t::-5|B,6fad0c,5,6,0&chg=7,25&chdl=Android 1.5|Android 1.6|Android 2.1|Android 2.2|Android 2.3|Android 2.3.3&chco=add274,9dd14f,8ece2a,7ab61c,659b11,507d08" />
+src="http://chart.apis.google.com/chart?&cht=lc&chs=660x250&chxt=x,x,y,r&chxr=0,0,12|1,0,12|2,0,100|3,0,100&chxl=0%3A|06/01|06/15|07/01|07/15|08/01|08/15|09/01|09/15|10/01|10/15|11/01|11/15|12/01|1%3A|2011||||||||||||2011|2%3A|0%25|25%25|50%25|75%25|100%25|3%3A|0%25|25%25|50%25|75%25|100%25&chxp=0,0,1,2,3,4,5,6,7,8,9,10,11,12&chxtc=0,5&chd=t:99.4,99.3,99.2,99.0,98.8,98.7,98.5,98.5,98.2,98.1,98.0,99.9,99.9|97.5,97.5,97.7,97.6,97.5,97.5,97.5,97.5,97.1,97.1,97.0,99.1,99.1|95.0,95.2,95.5,95.5,95.5,95.6,95.7,95.8,95.6,95.9,95.7,97.7,97.8|73.9,75.4,77.6,79.0,80.2,81.1,82.4,83.3,83.8,84.9,85.1,87.5,88.2|9.5,13.6,17.8,20.6,24.3,27.5,31.2,34.7,38.3,41.3,44.0,48.9,52.9|8.4,12.6,16.8,20.0,23.7,26.9,30.6,34.1,37.8,40.8,43.5,48.4,52.4|0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,2.0,2.3|0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,1.2&chm=b,c3df9b,0,1,0|b,b8dc82,1,2,0|tAndroid%202.1,608920,2,0,15,,t::-5|b,addb67,2,3,0|tAndroid%202.2,517617,3,0,15,,t::-5|b,a3db4b,3,4,0|b,98dc2e,4,5,0|tAndroid%202.3.3,334d0a,5,1,15,,t::-5|b,8cd41b,5,6,0|b,7ec113,6,7,0|B,6fad0c,7,8,0&chg=7,25&chdl=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&chco=add274,a2d15a,97d13e,8bcb28,7dba1e,6ea715,5f920e,507d08" />
 
-<p><em>Last historical dataset collected during a 14-day period ending on November 3, 2011</em></p>
+<p><em>Last historical dataset collected during a 14-day period ending on December 1, 2011</em></p>
 
 
 </div><!-- end dashboard-panel -->
diff --git a/docs/html/resources/dashboard/screens.jd b/docs/html/resources/dashboard/screens.jd
index ec3034d..79d59d9 100644
--- a/docs/html/resources/dashboard/screens.jd
+++ b/docs/html/resources/dashboard/screens.jd
@@ -60,7 +60,7 @@
 <div class="dashboard-panel">
 
 <img alt="" width="400" height="250"
-src="http://chart.googleapis.com/chart?cht=p&chs=400x250&chco=c4df9b,6fad0c&chl=Xlarge%20/%20mdpi|Large%20/%20ldpi|Large%20/%20mdpi|Normal%20/%20hdpi|Normal%20/%20ldpi|Normal%20/%20mdpi|Small%20/%20hdpi|Small%20/%20ldpi&chd=t%3A2.9,0.1,3.1,70.8,1.0,17.7,3.0,1.3" />
+src="http://chart.googleapis.com/chart?cht=p&chs=400x250&chco=c4df9b,6fad0c&chl=Xlarge%20/%20mdpi|Large%20/%20ldpi|Large%20/%20mdpi|Normal%20/%20hdpi|Normal%20/%20ldpi|Normal%20/%20mdpi|Small%20/%20hdpi|Small%20/%20ldpi&chd=t%3A3.1,0.1,3.1,71.0,1.0,17.5,2.9,1.3" />
 
 <table>
 <tr>
@@ -73,13 +73,13 @@
 <tr><th scope="row">small</th> 
 <td>1.3%</td>     <!-- small/ldpi -->
 <td></td>     <!-- small/mdpi -->
-<td>3.0%</td> <!-- small/hdpi -->
+<td>2.9%</td> <!-- small/hdpi -->
 <td></td>     <!-- small/xhdpi -->
 </tr> 
 <tr><th scope="row">normal</th> 
 <td>1.0%</td>  <!-- normal/ldpi -->
-<td>17.7%</td> <!-- normal/mdpi -->
-<td>70.8%</td> <!-- normal/hdpi -->
+<td>17.5%</td> <!-- normal/mdpi -->
+<td>71%</td> <!-- normal/hdpi -->
 <td></td>      <!-- normal/xhdpi -->
 </tr> 
 <tr><th scope="row">large</th> 
@@ -90,12 +90,12 @@
 </tr> 
 <tr><th scope="row">xlarge</th> 
 <td></td>     <!-- xlarge/ldpi -->
-<td>2.9%</td> <!-- xlarge/mdpi -->
+<td>3.1%</td> <!-- xlarge/mdpi -->
 <td></td>     <!-- xlarge/hdpi -->
 <td></td>     <!-- xlarge/xhdpi -->
 </tr> 
 </table>
 
-<p><em>Data collected during a 7-day period ending on November 3, 2011</em></p>
+<p><em>Data collected during a 7-day period ending on December 1, 2011</em></p>
 </div>
 
diff --git a/docs/html/resources/resources-data.js b/docs/html/resources/resources-data.js
index a35e684..18f1547 100644
--- a/docs/html/resources/resources-data.js
+++ b/docs/html/resources/resources-data.js
@@ -718,6 +718,16 @@
     }
   },
   {
+    tags: ['sample', 'communication', 'new'],
+    path: 'samples/ToyVpn/index.html',
+    title: {
+      en: 'Toy VPN Client'
+    },
+    description: {
+      en: 'A sample application that illustrates the creation of a custom VPN client.'
+    }
+  },
+  {
     tags: ['sample', 'newfeature'],
     path: 'samples/USB/index.html',
     title: {
diff --git a/docs/html/resources/samples/images/vpn-confirmation.png b/docs/html/resources/samples/images/vpn-confirmation.png
new file mode 100755
index 0000000..ae2e583
--- /dev/null
+++ b/docs/html/resources/samples/images/vpn-confirmation.png
Binary files differ
diff --git a/docs/html/shareables/adl/2011Q3_Android_Market_for_Developers.pdf b/docs/html/shareables/adl/2011Q3_Android_Market_for_Developers.pdf
new file mode 100644
index 0000000..598a27e
--- /dev/null
+++ b/docs/html/shareables/adl/2011Q3_Android_Market_for_Developers.pdf
Binary files differ
diff --git a/docs/html/shareables/adl/2011Q3_Designing_UIs_for_Phones_and_Tablets.pdf b/docs/html/shareables/adl/2011Q3_Designing_UIs_for_Phones_and_Tablets.pdf
new file mode 100644
index 0000000..6ef41dd
--- /dev/null
+++ b/docs/html/shareables/adl/2011Q3_Designing_UIs_for_Phones_and_Tablets.pdf
Binary files differ
diff --git a/docs/html/shareables/adl/2011Q3_Introduction_to_Honeycomb_APIs.pdf b/docs/html/shareables/adl/2011Q3_Introduction_to_Honeycomb_APIs.pdf
new file mode 100755
index 0000000..e56d2377
--- /dev/null
+++ b/docs/html/shareables/adl/2011Q3_Introduction_to_Honeycomb_APIs.pdf
Binary files differ
diff --git a/include/gui/DisplayEventReceiver.h b/include/gui/DisplayEventReceiver.h
new file mode 100644
index 0000000..dccc164
--- /dev/null
+++ b/include/gui/DisplayEventReceiver.h
@@ -0,0 +1,119 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_GUI_DISPLAY_EVENT_H
+#define ANDROID_GUI_DISPLAY_EVENT_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Errors.h>
+#include <utils/RefBase.h>
+#include <utils/Timers.h>
+
+#include <binder/IInterface.h>
+
+// ----------------------------------------------------------------------------
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+class BitTube;
+class IDisplayEventConnection;
+
+// ----------------------------------------------------------------------------
+
+class DisplayEventReceiver {
+public:
+    enum {
+        DISPLAY_EVENT_VSYNC = 'vsyn'
+    };
+
+    struct Event {
+
+        struct Header {
+            uint32_t type;
+            nsecs_t timestamp;
+        };
+
+        struct VSync {
+            uint32_t count;
+        };
+
+        Header header;
+        union {
+            VSync vsync;
+        };
+    };
+
+public:
+    /*
+     * DisplayEventReceiver creates and registers an event connection with
+     * SurfaceFlinger. Events start being delivered immediately.
+     */
+    DisplayEventReceiver();
+
+    /*
+     * ~DisplayEventReceiver severs the connection with SurfaceFlinger, new events
+     * stop being delivered immediately. Note that the queue could have
+     * some events pending. These will be delivered.
+     */
+    ~DisplayEventReceiver();
+
+    /*
+     * initCheck returns the state of DisplayEventReceiver after construction.
+     */
+    status_t initCheck() const;
+
+    /*
+     * getFd returns the file descriptor to use to receive events.
+     * OWNERSHIP IS RETAINED by DisplayEventReceiver. DO NOT CLOSE this
+     * file-descriptor.
+     */
+    int getFd() const;
+
+    /*
+     * getEvents reads event from the queue and returns how many events were
+     * read. Returns 0 if there are no more events or a negative error code.
+     * If NOT_ENOUGH_DATA is returned, the object has become invalid forever, it
+     * should be destroyed and getEvents() shouldn't be called again.
+     */
+    ssize_t getEvents(Event* events, size_t count);
+
+    /*
+     * setVsyncRate() sets the Event::VSync delivery rate. A value of
+     * 1 returns every Event::VSync. A value of 2 returns every other event,
+     * etc... a value of 0 returns no event unless  requestNextVsync() has
+     * been called.
+     */
+    status_t setVsyncRate(uint32_t count);
+
+    /*
+     * requestNextVsync() schedules the next Event::VSync. It has no effect
+     * if the vsync rate is > 0.
+     */
+    status_t requestNextVsync();
+
+private:
+    sp<IDisplayEventConnection> mEventConnection;
+    sp<BitTube> mDataChannel;
+};
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+
+#endif // ANDROID_GUI_DISPLAY_EVENT_H
diff --git a/include/gui/IDisplayEventConnection.h b/include/gui/IDisplayEventConnection.h
new file mode 100644
index 0000000..86247de
--- /dev/null
+++ b/include/gui/IDisplayEventConnection.h
@@ -0,0 +1,73 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_GUI_IDISPLAY_EVENT_CONNECTION_H
+#define ANDROID_GUI_IDISPLAY_EVENT_CONNECTION_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Errors.h>
+#include <utils/RefBase.h>
+
+#include <binder/IInterface.h>
+
+namespace android {
+// ----------------------------------------------------------------------------
+
+class BitTube;
+
+class IDisplayEventConnection : public IInterface
+{
+public:
+
+    DECLARE_META_INTERFACE(DisplayEventConnection);
+
+    /*
+     * getDataChannel() returns a BitTube where to receive the events from
+     */
+    virtual sp<BitTube> getDataChannel() const = 0;
+
+    /*
+     * setVsyncRate() sets the vsync event delivery rate. A value of
+     * 1 returns every vsync events. A value of 2 returns every other events,
+     * etc... a value of 0 returns no event unless  requestNextVsync() has
+     * been called.
+     */
+    virtual void setVsyncRate(uint32_t count) = 0;
+
+    /*
+     * requestNextVsync() schedules the next vsync event. It has no effect
+     * if the vsync rate is > 0.
+     */
+    virtual void requestNextVsync() = 0;    // asynchronous
+};
+
+// ----------------------------------------------------------------------------
+
+class BnDisplayEventConnection : public BnInterface<IDisplayEventConnection>
+{
+public:
+    virtual status_t    onTransact( uint32_t code,
+                                    const Parcel& data,
+                                    Parcel* reply,
+                                    uint32_t flags = 0);
+};
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+
+#endif // ANDROID_GUI_IDISPLAY_EVENT_CONNECTION_H
diff --git a/include/gui/SurfaceTexture.h b/include/gui/SurfaceTexture.h
index 15c2bab..a8c7672 100644
--- a/include/gui/SurfaceTexture.h
+++ b/include/gui/SurfaceTexture.h
@@ -60,10 +60,16 @@
         virtual void onFrameAvailable() = 0;
     };
 
-    // tex indicates the name OpenGL texture to which images are to be streamed.
-    // This texture name cannot be changed once the SurfaceTexture is created.
+    // SurfaceTexture constructs a new SurfaceTexture object. tex indicates the
+    // name of the OpenGL ES texture to which images are to be streamed. This
+    // texture name cannot be changed once the SurfaceTexture is created.
+    // allowSynchronousMode specifies whether or not synchronous mode can be
+    // enabled. texTarget specifies the OpenGL ES texture target to which the
+    // texture will be bound in updateTexImage. useFenceSync specifies whether
+    // fences should be used to synchronize access to buffers if that behavior
+    // is enabled at compile-time.
     SurfaceTexture(GLuint tex, bool allowSynchronousMode = true,
-            GLenum texTarget = GL_TEXTURE_EXTERNAL_OES);
+            GLenum texTarget = GL_TEXTURE_EXTERNAL_OES, bool useFenceSync = true);
 
     virtual ~SurfaceTexture();
 
@@ -276,7 +282,8 @@
               mTransform(0),
               mScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
               mTimestamp(0),
-              mFrameNumber(0) {
+              mFrameNumber(0),
+              mFence(EGL_NO_SYNC_KHR) {
             mCrop.makeInvalid();
         }
 
@@ -349,6 +356,11 @@
         // mFrameNumber is the number of the queued frame for this slot.
         uint64_t mFrameNumber;
 
+        // mFence is the EGL sync object that must signal before the buffer
+        // associated with this buffer slot may be dequeued. It is initialized
+        // to EGL_NO_SYNC_KHR when the buffer is created and (optionally, based
+        // on a compile-time option) set to a new sync object in updateTexImage.
+        EGLSyncKHR mFence;
     };
 
     // mSlots is the array of buffer slots that must be mirrored on the client
@@ -472,6 +484,12 @@
     // It is set by the setName method.
     String8 mName;
 
+    // mUseFenceSync indicates whether creation of the EGL_KHR_fence_sync
+    // extension should be used to prevent buffers from being dequeued before
+    // it's safe for them to be written. It gets set at construction time and
+    // never changes.
+    const bool mUseFenceSync;
+
     // mMutex is the mutex used to prevent concurrent access to the member
     // variables of SurfaceTexture objects. It must be locked whenever the
     // member variables are accessed.
diff --git a/include/media/AudioTrack.h b/include/media/AudioTrack.h
index f71965e..cb3d833 100644
--- a/include/media/AudioTrack.h
+++ b/include/media/AudioTrack.h
@@ -38,7 +38,7 @@
 
 // ----------------------------------------------------------------------------
 
-class AudioTrack
+class AudioTrack : virtual public RefBase
 {
 public:
     enum channel_index {
diff --git a/include/media/IStreamSource.h b/include/media/IStreamSource.h
index cc63356..19646b0 100644
--- a/include/media/IStreamSource.h
+++ b/include/media/IStreamSource.h
@@ -52,15 +52,20 @@
     static const char *const kKeyResumeAtPTS;
 
     // When signalling a discontinuity you can optionally
-    // signal that this is a "hard" discontinuity, i.e. the format
-    // or configuration of subsequent stream data differs from that
-    // currently active. To do so, include a non-zero int32_t value
-    // under the key "kKeyFormatChange" when issuing the DISCONTINUITY
+    // specify the type(s) of discontinuity, i.e. if the
+    // audio format has changed, the video format has changed,
+    // time has jumped or any combination thereof.
+    // To do so, include a non-zero int32_t value
+    // under the key "kKeyDiscontinuityMask" when issuing the DISCONTINUITY
     // command.
-    // The new logical stream must start with proper codec initialization
+    // If there is a change in audio/video format, The new logical stream
+    // must start with proper codec initialization
     // information for playback to continue, i.e. SPS and PPS in the case
     // of AVC video etc.
-    static const char *const kKeyFormatChange;
+    // If this key is not present, only a time discontinuity is assumed.
+    // The value should be a bitmask of values from
+    // ATSParser::DiscontinuityType.
+    static const char *const kKeyDiscontinuityMask;
 
     virtual void issueCommand(
             Command cmd, bool synchronous, const sp<AMessage> &msg = NULL) = 0;
diff --git a/include/media/stagefright/ACodec.h b/include/media/stagefright/ACodec.h
index 5822877..3963d9c 100644
--- a/include/media/stagefright/ACodec.h
+++ b/include/media/stagefright/ACodec.h
@@ -166,6 +166,8 @@
 
     bool allYourBuffersAreBelongToUs();
 
+    size_t countBuffersOwnedByComponent(OMX_U32 portIndex) const;
+
     void deferMessage(const sp<AMessage> &msg);
     void processDeferredMessages();
 
diff --git a/include/private/gui/ComposerService.h b/include/private/gui/ComposerService.h
new file mode 100644
index 0000000..d04491a
--- /dev/null
+++ b/include/private/gui/ComposerService.h
@@ -0,0 +1,53 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_PRIVATE_GUI_COMPOSER_SERVICE_H
+#define ANDROID_PRIVATE_GUI_COMPOSER_SERVICE_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Singleton.h>
+#include <utils/StrongPointer.h>
+
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+class IMemoryHeap;
+class ISurfaceComposer;
+class surface_flinger_cblk_t;
+
+// ---------------------------------------------------------------------------
+
+class ComposerService : public Singleton<ComposerService>
+{
+    // these are constants
+    sp<ISurfaceComposer> mComposerService;
+    sp<IMemoryHeap> mServerCblkMemory;
+    surface_flinger_cblk_t volatile* mServerCblk;
+    ComposerService();
+    friend class Singleton<ComposerService>;
+public:
+    static sp<ISurfaceComposer> getComposerService();
+    static surface_flinger_cblk_t const volatile * getControlBlock();
+};
+
+// ---------------------------------------------------------------------------
+}; // namespace android
+
+#endif // ANDROID_PRIVATE_GUI_COMPOSER_SERVICE_H
diff --git a/include/surfaceflinger/ISurfaceComposer.h b/include/surfaceflinger/ISurfaceComposer.h
index 5eb09c7..58fd89d 100644
--- a/include/surfaceflinger/ISurfaceComposer.h
+++ b/include/surfaceflinger/ISurfaceComposer.h
@@ -33,8 +33,9 @@
 namespace android {
 // ----------------------------------------------------------------------------
 
-class IMemoryHeap;
 class ComposerState;
+class IDisplayEventConnection;
+class IMemoryHeap;
 
 class ISurfaceComposer : public IInterface
 {
@@ -124,13 +125,19 @@
             uint32_t reqWidth, uint32_t reqHeight,
             uint32_t minLayerZ, uint32_t maxLayerZ) = 0;
 
+    /* triggers screen off animation */
     virtual status_t turnElectronBeamOff(int32_t mode) = 0;
+
+    /* triggers screen on animation */
     virtual status_t turnElectronBeamOn(int32_t mode) = 0;
 
     /* verify that an ISurfaceTexture was created by SurfaceFlinger.
      */
     virtual bool authenticateSurfaceTexture(
             const sp<ISurfaceTexture>& surface) const = 0;
+
+    /* return an IDisplayEventConnection */
+    virtual sp<IDisplayEventConnection> createDisplayEventConnection() = 0;
 };
 
 // ----------------------------------------------------------------------------
@@ -151,6 +158,7 @@
         TURN_ELECTRON_BEAM_OFF,
         TURN_ELECTRON_BEAM_ON,
         AUTHENTICATE_SURFACE,
+        CREATE_DISPLAY_EVENT_CONNECTION,
     };
 
     virtual status_t    onTransact( uint32_t code,
diff --git a/include/surfaceflinger/SurfaceComposerClient.h b/include/surfaceflinger/SurfaceComposerClient.h
index 8226abe..99affda 100644
--- a/include/surfaceflinger/SurfaceComposerClient.h
+++ b/include/surfaceflinger/SurfaceComposerClient.h
@@ -28,7 +28,6 @@
 #include <utils/threads.h>
 
 #include <ui/PixelFormat.h>
-#include <ui/Region.h>
 
 #include <surfaceflinger/Surface.h>
 
@@ -39,30 +38,11 @@
 class DisplayInfo;
 class Composer;
 class IMemoryHeap;
-class ISurfaceComposer;
+class ISurfaceComposerClient;
 class Region;
-class surface_flinger_cblk_t;
-struct layer_state_t;
 
 // ---------------------------------------------------------------------------
 
-class ComposerService : public Singleton<ComposerService>
-{
-    // these are constants
-    sp<ISurfaceComposer> mComposerService;
-    sp<IMemoryHeap> mServerCblkMemory;
-    surface_flinger_cblk_t volatile* mServerCblk;
-    ComposerService();
-    friend class Singleton<ComposerService>;
-public:
-    static sp<ISurfaceComposer> getComposerService();
-    static surface_flinger_cblk_t const volatile * getControlBlock();
-};
-
-// ---------------------------------------------------------------------------
-
-class Composer;
-
 class SurfaceComposerClient : public RefBase
 {
     friend class Composer;
diff --git a/include/ui/GraphicBuffer.h b/include/ui/GraphicBuffer.h
index b9deafc..6ab01f4 100644
--- a/include/ui/GraphicBuffer.h
+++ b/include/ui/GraphicBuffer.h
@@ -63,6 +63,7 @@
         USAGE_HW_RENDER         = GRALLOC_USAGE_HW_RENDER,
         USAGE_HW_2D             = GRALLOC_USAGE_HW_2D,
         USAGE_HW_COMPOSER       = GRALLOC_USAGE_HW_COMPOSER,
+        USAGE_HW_VIDEO_ENCODER  = GRALLOC_USAGE_HW_VIDEO_ENCODER,
         USAGE_HW_MASK           = GRALLOC_USAGE_HW_MASK
     };
 
diff --git a/include/ui/KeycodeLabels.h b/include/ui/KeycodeLabels.h
index 2efe8ca..c5bd0c5 100755
--- a/include/ui/KeycodeLabels.h
+++ b/include/ui/KeycodeLabels.h
@@ -231,6 +231,10 @@
     { "LANGUAGE_SWITCH", 204 },
     { "MANNER_MODE", 205 },
     { "3D_MODE", 206 },
+    { "CONTACTS", 207 },
+    { "CALENDAR", 208 },
+    { "MUSIC", 209 },
+    { "CALCULATOR", 210 },
 
     // NOTE: If you add a new keycode here you must also add it to several other files.
     //       Refer to frameworks/base/core/java/android/view/KeyEvent.java for the full list.
diff --git a/include/utils/BasicHashtable.h b/include/utils/BasicHashtable.h
new file mode 100644
index 0000000..fdf9738
--- /dev/null
+++ b/include/utils/BasicHashtable.h
@@ -0,0 +1,393 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_BASIC_HASHTABLE_H
+#define ANDROID_BASIC_HASHTABLE_H
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <utils/SharedBuffer.h>
+#include <utils/TypeHelpers.h>
+
+namespace android {
+
+/* Implementation type.  Nothing to see here. */
+class BasicHashtableImpl {
+protected:
+    struct Bucket {
+        // The collision flag indicates that the bucket is part of a collision chain
+        // such that at least two entries both hash to this bucket.  When true, we
+        // may need to seek further along the chain to find the entry.
+        static const uint32_t COLLISION = 0x80000000UL;
+
+        // The present flag indicates that the bucket contains an initialized entry value.
+        static const uint32_t PRESENT   = 0x40000000UL;
+
+        // Mask for 30 bits worth of the hash code that are stored within the bucket to
+        // speed up lookups and rehashing by eliminating the need to recalculate the
+        // hash code of the entry's key.
+        static const uint32_t HASH_MASK = 0x3fffffffUL;
+
+        // Combined value that stores the collision and present flags as well as
+        // a 30 bit hash code.
+        uint32_t cookie;
+
+        // Storage for the entry begins here.
+        char entry[0];
+    };
+
+    BasicHashtableImpl(size_t entrySize, bool hasTrivialDestructor,
+            size_t minimumInitialCapacity, float loadFactor);
+    BasicHashtableImpl(const BasicHashtableImpl& other);
+
+    void dispose();
+
+    inline void edit() {
+        if (mBuckets && !SharedBuffer::bufferFromData(mBuckets)->onlyOwner()) {
+            clone();
+        }
+    }
+
+    void setTo(const BasicHashtableImpl& other);
+    void clear();
+
+    ssize_t next(ssize_t index) const;
+    ssize_t find(ssize_t index, hash_t hash, const void* __restrict__ key) const;
+    size_t add(hash_t hash, const void* __restrict__ entry);
+    void removeAt(size_t index);
+    void rehash(size_t minimumCapacity, float loadFactor);
+
+    const size_t mBucketSize; // number of bytes per bucket including the entry
+    const bool mHasTrivialDestructor; // true if the entry type does not require destruction
+    size_t mCapacity;         // number of buckets that can be filled before exceeding load factor
+    float mLoadFactor;        // load factor
+    size_t mSize;             // number of elements actually in the table
+    size_t mFilledBuckets;    // number of buckets for which collision or present is true
+    size_t mBucketCount;      // number of slots in the mBuckets array
+    void* mBuckets;           // array of buckets, as a SharedBuffer
+
+    inline const Bucket& bucketAt(const void* __restrict__ buckets, size_t index) const {
+        return *reinterpret_cast<const Bucket*>(
+                static_cast<const uint8_t*>(buckets) + index * mBucketSize);
+    }
+
+    inline Bucket& bucketAt(void* __restrict__ buckets, size_t index) const {
+        return *reinterpret_cast<Bucket*>(static_cast<uint8_t*>(buckets) + index * mBucketSize);
+    }
+
+    virtual bool compareBucketKey(const Bucket& bucket, const void* __restrict__ key) const = 0;
+    virtual void initializeBucketEntry(Bucket& bucket, const void* __restrict__ entry) const = 0;
+    virtual void destroyBucketEntry(Bucket& bucket) const = 0;
+
+private:
+    void clone();
+
+    // Allocates a bucket array as a SharedBuffer.
+    void* allocateBuckets(size_t count) const;
+
+    // Releases a bucket array's associated SharedBuffer.
+    void releaseBuckets(void* __restrict__ buckets, size_t count) const;
+
+    // Destroys the contents of buckets (invokes destroyBucketEntry for each
+    // populated bucket if needed).
+    void destroyBuckets(void* __restrict__ buckets, size_t count) const;
+
+    // Copies the content of buckets (copies the cookie and invokes copyBucketEntry
+    // for each populated bucket if needed).
+    void copyBuckets(const void* __restrict__ fromBuckets,
+            void* __restrict__ toBuckets, size_t count) const;
+
+    // Determines the appropriate size of a bucket array to store a certain minimum
+    // number of entries and returns its effective capacity.
+    static void determineCapacity(size_t minimumCapacity, float loadFactor,
+            size_t* __restrict__ outBucketCount, size_t* __restrict__ outCapacity);
+
+    // Trim a hash code to 30 bits to match what we store in the bucket's cookie.
+    inline static hash_t trimHash(hash_t hash) {
+        return (hash & Bucket::HASH_MASK) ^ (hash >> 30);
+    }
+
+    // Returns the index of the first bucket that is in the collision chain
+    // for the specified hash code, given the total number of buckets.
+    // (Primary hash)
+    inline static size_t chainStart(hash_t hash, size_t count) {
+        return hash % count;
+    }
+
+    // Returns the increment to add to a bucket index to seek to the next bucket
+    // in the collision chain for the specified hash code, given the total number of buckets.
+    // (Secondary hash)
+    inline static size_t chainIncrement(hash_t hash, size_t count) {
+        return ((hash >> 7) | (hash << 25)) % (count - 1) + 1;
+    }
+
+    // Returns the index of the next bucket that is in the collision chain
+    // that is defined by the specified increment, given the total number of buckets.
+    inline static size_t chainSeek(size_t index, size_t increment, size_t count) {
+        return (index + increment) % count;
+    }
+};
+
+/*
+ * A BasicHashtable stores entries that are indexed by hash code in place
+ * within an array.  The basic operations are finding entries by key,
+ * adding new entries and removing existing entries.
+ *
+ * This class provides a very limited set of operations with simple semantics.
+ * It is intended to be used as a building block to construct more complex
+ * and interesting data structures such as HashMap.  Think very hard before
+ * adding anything extra to BasicHashtable, it probably belongs at a
+ * higher level of abstraction.
+ *
+ * TKey: The key type.
+ * TEntry: The entry type which is what is actually stored in the array.
+ *
+ * TKey must support the following contract:
+ *     bool operator==(const TKey& other) const;  // return true if equal
+ *     bool operator!=(const TKey& other) const;  // return true if unequal
+ *
+ * TEntry must support the following contract:
+ *     const TKey& getKey() const;  // get the key from the entry
+ *
+ * This class supports storing entries with duplicate keys.  Of course, it can't
+ * tell them apart during removal so only the first entry will be removed.
+ * We do this because it means that operations like add() can't fail.
+ */
+template <typename TKey, typename TEntry>
+class BasicHashtable : private BasicHashtableImpl {
+public:
+    /* Creates a hashtable with the specified minimum initial capacity.
+     * The underlying array will be created when the first entry is added.
+     *
+     * minimumInitialCapacity: The minimum initial capacity for the hashtable.
+     *     Default is 0.
+     * loadFactor: The desired load factor for the hashtable, between 0 and 1.
+     *     Default is 0.75.
+     */
+    BasicHashtable(size_t minimumInitialCapacity = 0, float loadFactor = 0.75f);
+
+    /* Copies a hashtable.
+     * The underlying storage is shared copy-on-write.
+     */
+    BasicHashtable(const BasicHashtable& other);
+
+    /* Clears and destroys the hashtable.
+     */
+    virtual ~BasicHashtable();
+
+    /* Making this hashtable a copy of the other hashtable.
+     * The underlying storage is shared copy-on-write.
+     *
+     * other: The hashtable to copy.
+     */
+    inline BasicHashtable<TKey, TEntry>& operator =(const BasicHashtable<TKey, TEntry> & other) {
+        setTo(other);
+        return *this;
+    }
+
+    /* Returns the number of entries in the hashtable.
+     */
+    inline size_t size() const {
+        return mSize;
+    }
+
+    /* Returns the capacity of the hashtable, which is the number of elements that can
+     * added to the hashtable without requiring it to be grown.
+     */
+    inline size_t capacity() const {
+        return mCapacity;
+    }
+
+    /* Returns the number of buckets that the hashtable has, which is the size of its
+     * underlying array.
+     */
+    inline size_t bucketCount() const {
+        return mBucketCount;
+    }
+
+    /* Returns the load factor of the hashtable. */
+    inline float loadFactor() const {
+        return mLoadFactor;
+    };
+
+    /* Returns a const reference to the entry at the specified index.
+     *
+     * index:   The index of the entry to retrieve.  Must be a valid index within
+     *          the bounds of the hashtable.
+     */
+    inline const TEntry& entryAt(size_t index) const {
+        return entryFor(bucketAt(mBuckets, index));
+    }
+
+    /* Returns a non-const reference to the entry at the specified index.
+     *
+     * index: The index of the entry to edit.  Must be a valid index within
+     *        the bounds of the hashtable.
+     */
+    inline TEntry& editEntryAt(size_t index) {
+        edit();
+        return entryFor(bucketAt(mBuckets, index));
+    }
+
+    /* Clears the hashtable.
+     * All entries in the hashtable are destroyed immediately.
+     * If you need to do something special with the entries in the hashtable then iterate
+     * over them and do what you need before clearing the hashtable.
+     */
+    inline void clear() {
+        BasicHashtableImpl::clear();
+    }
+
+    /* Returns the index of the next entry in the hashtable given the index of a previous entry.
+     * If the given index is -1, then returns the index of the first entry in the hashtable,
+     * if there is one, or -1 otherwise.
+     * If the given index is not -1, then returns the index of the next entry in the hashtable,
+     * in strictly increasing order, or -1 if there are none left.
+     *
+     * index:   The index of the previous entry that was iterated, or -1 to begin
+     *          iteration at the beginning of the hashtable.
+     */
+    inline ssize_t next(ssize_t index) const {
+        return BasicHashtableImpl::next(index);
+    }
+
+    /* Finds the index of an entry with the specified key.
+     * If the given index is -1, then returns the index of the first matching entry,
+     * otherwise returns the index of the next matching entry.
+     * If the hashtable contains multiple entries with keys that match the requested
+     * key, then the sequence of entries returned is arbitrary.
+     * Returns -1 if no entry was found.
+     *
+     * index:   The index of the previous entry with the specified key, or -1 to
+     *          find the first matching entry.
+     * hash:    The hashcode of the key.
+     * key:     The key.
+     */
+    inline ssize_t find(ssize_t index, hash_t hash, const TKey& key) const {
+        return BasicHashtableImpl::find(index, hash, &key);
+    }
+
+    /* Adds the entry to the hashtable.
+     * Returns the index of the newly added entry.
+     * If an entry with the same key already exists, then a duplicate entry is added.
+     * If the entry will not fit, then the hashtable's capacity is increased and
+     * its contents are rehashed.  See rehash().
+     *
+     * hash:    The hashcode of the key.
+     * entry:   The entry to add.
+     */
+    inline size_t add(hash_t hash, const TEntry& entry) {
+        return BasicHashtableImpl::add(hash, &entry);
+    }
+
+    /* Removes the entry with the specified index from the hashtable.
+     * The entry is destroyed immediately.
+     * The index must be valid.
+     *
+     * The hashtable is not compacted after an item is removed, so it is legal
+     * to continue iterating over the hashtable using next() or find().
+     *
+     * index:   The index of the entry to remove.  Must be a valid index within the
+     *          bounds of the hashtable, and it must refer to an existing entry.
+     */
+    inline void removeAt(size_t index) {
+        BasicHashtableImpl::removeAt(index);
+    }
+
+    /* Rehashes the contents of the hashtable.
+     * Grows the hashtable to at least the specified minimum capacity or the
+     * current number of elements, whichever is larger.
+     *
+     * Rehashing causes all entries to be copied and the entry indices may change.
+     * Although the hash codes are cached by the hashtable, rehashing can be an
+     * expensive operation and should be avoided unless the hashtable's size
+     * needs to be changed.
+     *
+     * Rehashing is the only way to change the capacity or load factor of the
+     * hashtable once it has been created.  It can be used to compact the
+     * hashtable by choosing a minimum capacity that is smaller than the current
+     * capacity (such as 0).
+     *
+     * minimumCapacity: The desired minimum capacity after rehashing.
+     * loadFactor: The desired load factor after rehashing.
+     */
+    inline void rehash(size_t minimumCapacity, float loadFactor) {
+        BasicHashtableImpl::rehash(minimumCapacity, loadFactor);
+    }
+
+protected:
+    static inline const TEntry& entryFor(const Bucket& bucket) {
+        return reinterpret_cast<const TEntry&>(bucket.entry);
+    }
+
+    static inline TEntry& entryFor(Bucket& bucket) {
+        return reinterpret_cast<TEntry&>(bucket.entry);
+    }
+
+    virtual bool compareBucketKey(const Bucket& bucket, const void* __restrict__ key) const;
+    virtual void initializeBucketEntry(Bucket& bucket, const void* __restrict__ entry) const;
+    virtual void destroyBucketEntry(Bucket& bucket) const;
+
+private:
+    // For dumping the raw contents of a hashtable during testing.
+    friend class BasicHashtableTest;
+    inline uint32_t cookieAt(size_t index) const {
+        return bucketAt(mBuckets, index).cookie;
+    }
+};
+
+template <typename TKey, typename TEntry>
+BasicHashtable<TKey, TEntry>::BasicHashtable(size_t minimumInitialCapacity, float loadFactor) :
+        BasicHashtableImpl(sizeof(TEntry), traits<TEntry>::has_trivial_dtor,
+                minimumInitialCapacity, loadFactor) {
+}
+
+template <typename TKey, typename TEntry>
+BasicHashtable<TKey, TEntry>::BasicHashtable(const BasicHashtable<TKey, TEntry>& other) :
+        BasicHashtableImpl(other) {
+}
+
+template <typename TKey, typename TEntry>
+BasicHashtable<TKey, TEntry>::~BasicHashtable() {
+    dispose();
+}
+
+template <typename TKey, typename TEntry>
+bool BasicHashtable<TKey, TEntry>::compareBucketKey(const Bucket& bucket,
+        const void* __restrict__ key) const {
+    return entryFor(bucket).getKey() == *static_cast<const TKey*>(key);
+}
+
+template <typename TKey, typename TEntry>
+void BasicHashtable<TKey, TEntry>::initializeBucketEntry(Bucket& bucket,
+        const void* __restrict__ entry) const {
+    if (!traits<TEntry>::has_trivial_copy) {
+        new (&entryFor(bucket)) TEntry(*(static_cast<const TEntry*>(entry)));
+    } else {
+        memcpy(&entryFor(bucket), entry, sizeof(TEntry));
+    }
+}
+
+template <typename TKey, typename TEntry>
+void BasicHashtable<TKey, TEntry>::destroyBucketEntry(Bucket& bucket) const {
+    if (!traits<TEntry>::has_trivial_dtor) {
+        entryFor(bucket).~TEntry();
+    }
+}
+
+}; // namespace android
+
+#endif // ANDROID_BASIC_HASHTABLE_H
diff --git a/include/utils/GenerationCache.h b/include/utils/GenerationCache.h
index 83cda86..da85a9a 100644
--- a/include/utils/GenerationCache.h
+++ b/include/utils/GenerationCache.h
@@ -88,11 +88,13 @@
 
     void attachToCache(const sp<Entry<K, V> >& entry);
     void detachFromCache(const sp<Entry<K, V> >& entry);
+
+    const V mNullValue;
 }; // class GenerationCache
 
 template<typename K, typename V>
 GenerationCache<K, V>::GenerationCache(uint32_t maxCapacity): mMaxCapacity(maxCapacity),
-    mListener(NULL) {
+    mListener(NULL), mNullValue(NULL) {
 };
 
 template<typename K, typename V>
@@ -154,7 +156,7 @@
         return entry->value;
     }
 
-    return NULL;
+    return mNullValue;
 }
 
 template<typename K, typename V>
diff --git a/include/utils/TypeHelpers.h b/include/utils/TypeHelpers.h
index a1663f3..7b4fb70 100644
--- a/include/utils/TypeHelpers.h
+++ b/include/utils/TypeHelpers.h
@@ -213,6 +213,9 @@
 
 template <typename KEY, typename VALUE>
 struct key_value_pair_t {
+    typedef KEY key_t;
+    typedef VALUE value_t;
+
     KEY     key;
     VALUE   value;
     key_value_pair_t() { }
@@ -222,6 +225,12 @@
     inline bool operator < (const key_value_pair_t& o) const {
         return strictly_order_type(key, o.key);
     }
+    inline const KEY& getKey() const {
+        return key;
+    }
+    inline const VALUE& getValue() const {
+        return value;
+    }
 };
 
 template<>
@@ -243,6 +252,41 @@
 
 // ---------------------------------------------------------------------------
 
+/*
+ * Hash codes.
+ */
+typedef uint32_t hash_t;
+
+template <typename TKey>
+hash_t hash_type(const TKey& key);
+
+/* Built-in hash code specializations.
+ * Assumes pointers are 32bit. */
+#define ANDROID_INT32_HASH(T) \
+        template <> inline hash_t hash_type(const T& value) { return hash_t(value); }
+#define ANDROID_INT64_HASH(T) \
+        template <> inline hash_t hash_type(const T& value) { \
+                return hash_t((value >> 32) ^ value); }
+#define ANDROID_REINTERPRET_HASH(T, R) \
+        template <> inline hash_t hash_type(const T& value) { \
+                return hash_type(*reinterpret_cast<const R*>(&value)); }
+
+ANDROID_INT32_HASH(bool)
+ANDROID_INT32_HASH(int8_t)
+ANDROID_INT32_HASH(uint8_t)
+ANDROID_INT32_HASH(int16_t)
+ANDROID_INT32_HASH(uint16_t)
+ANDROID_INT32_HASH(int32_t)
+ANDROID_INT32_HASH(uint32_t)
+ANDROID_INT64_HASH(int64_t)
+ANDROID_INT64_HASH(uint64_t)
+ANDROID_REINTERPRET_HASH(float, uint32_t)
+ANDROID_REINTERPRET_HASH(double, uint64_t)
+
+template <typename T> inline hash_t hash_type(const T*& value) {
+    return hash_type(uintptr_t(value));
+}
+
 }; // namespace android
 
 // ---------------------------------------------------------------------------
diff --git a/libs/binder/IPCThreadState.cpp b/libs/binder/IPCThreadState.cpp
index 6965702..641134a 100644
--- a/libs/binder/IPCThreadState.cpp
+++ b/libs/binder/IPCThreadState.cpp
@@ -773,6 +773,7 @@
         bwr.read_buffer = (long unsigned int)mIn.data();
     } else {
         bwr.read_size = 0;
+        bwr.read_buffer = 0;
     }
 
     IF_LOG_COMMANDS() {
diff --git a/libs/gui/Android.mk b/libs/gui/Android.mk
index b7e3ee3..b8be67d 100644
--- a/libs/gui/Android.mk
+++ b/libs/gui/Android.mk
@@ -3,6 +3,8 @@
 
 LOCAL_SRC_FILES:= \
 	BitTube.cpp \
+	DisplayEventReceiver.cpp \
+	IDisplayEventConnection.cpp \
 	ISensorEventConnection.cpp \
 	ISensorServer.cpp \
 	ISurfaceTexture.cpp \
diff --git a/libs/gui/BitTube.cpp b/libs/gui/BitTube.cpp
index c632b43..fa8d0ea 100644
--- a/libs/gui/BitTube.cpp
+++ b/libs/gui/BitTube.cpp
@@ -97,6 +97,11 @@
         len = ::read(mReceiveFd, vaddr, size);
         err = len < 0 ? errno : 0;
     } while (err == EINTR);
+    if (err == EAGAIN || err == EWOULDBLOCK) {
+        // EAGAIN means that we have non-blocking I/O but there was
+        // no data to be read. Nothing the client should care about.
+        return 0;
+    }
     return err == 0 ? len : -err;
 }
 
diff --git a/libs/gui/DisplayEventReceiver.cpp b/libs/gui/DisplayEventReceiver.cpp
new file mode 100644
index 0000000..fee1feb
--- /dev/null
+++ b/libs/gui/DisplayEventReceiver.cpp
@@ -0,0 +1,103 @@
+/*
+ * 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.
+ */
+
+#include <string.h>
+
+#include <utils/Errors.h>
+
+#include <gui/BitTube.h>
+#include <gui/DisplayEventReceiver.h>
+#include <gui/IDisplayEventConnection.h>
+
+#include <private/gui/ComposerService.h>
+
+#include <surfaceflinger/ISurfaceComposer.h>
+
+// ---------------------------------------------------------------------------
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+DisplayEventReceiver::DisplayEventReceiver() {
+    sp<ISurfaceComposer> sf(ComposerService::getComposerService());
+    if (sf != NULL) {
+        mEventConnection = sf->createDisplayEventConnection();
+        if (mEventConnection != NULL) {
+            mDataChannel = mEventConnection->getDataChannel();
+        }
+    }
+}
+
+DisplayEventReceiver::~DisplayEventReceiver() {
+}
+
+status_t DisplayEventReceiver::initCheck() const {
+    if (mDataChannel != NULL)
+        return NO_ERROR;
+    return NO_INIT;
+}
+
+int DisplayEventReceiver::getFd() const {
+    if (mDataChannel == NULL)
+        return NO_INIT;
+
+    return mDataChannel->getFd();
+}
+
+status_t DisplayEventReceiver::setVsyncRate(uint32_t count) {
+    if (int32_t(count) < 0)
+        return BAD_VALUE;
+
+    if (mEventConnection != NULL) {
+        mEventConnection->setVsyncRate(count);
+        return NO_ERROR;
+    }
+    return NO_INIT;
+}
+
+status_t DisplayEventReceiver::requestNextVsync() {
+    if (mEventConnection != NULL) {
+        mEventConnection->requestNextVsync();
+        return NO_ERROR;
+    }
+    return NO_INIT;
+}
+
+
+ssize_t DisplayEventReceiver::getEvents(DisplayEventReceiver::Event* events,
+        size_t count) {
+    ssize_t size = mDataChannel->read(events, sizeof(events[0])*count);
+    LOGE_IF(size<0,
+            "DisplayEventReceiver::getEvents error (%s)",
+            strerror(-size));
+    if (size >= 0) {
+        // Note: if (size % sizeof(events[0])) != 0, we've got a
+        // partial read. This can happen if the queue filed up (ie: if we
+        // didn't pull from it fast enough).
+        // We discard the partial event and rely on the sender to
+        // re-send the event if appropriate (some events, like VSYNC
+        // can be lost forever).
+
+        // returns number of events read
+        size /= sizeof(events[0]);
+    }
+    return size;
+}
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
diff --git a/libs/gui/IDisplayEventConnection.cpp b/libs/gui/IDisplayEventConnection.cpp
new file mode 100644
index 0000000..887d176
--- /dev/null
+++ b/libs/gui/IDisplayEventConnection.cpp
@@ -0,0 +1,98 @@
+/*
+ * 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.
+ */
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Errors.h>
+#include <utils/RefBase.h>
+#include <utils/Timers.h>
+
+#include <binder/Parcel.h>
+#include <binder/IInterface.h>
+
+#include <gui/IDisplayEventConnection.h>
+#include <gui/BitTube.h>
+
+namespace android {
+// ----------------------------------------------------------------------------
+
+enum {
+    GET_DATA_CHANNEL = IBinder::FIRST_CALL_TRANSACTION,
+    SET_VSYNC_RATE,
+    REQUEST_NEXT_VSYNC
+};
+
+class BpDisplayEventConnection : public BpInterface<IDisplayEventConnection>
+{
+public:
+    BpDisplayEventConnection(const sp<IBinder>& impl)
+        : BpInterface<IDisplayEventConnection>(impl)
+    {
+    }
+
+    virtual sp<BitTube> getDataChannel() const
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IDisplayEventConnection::getInterfaceDescriptor());
+        remote()->transact(GET_DATA_CHANNEL, data, &reply);
+        return new BitTube(reply);
+    }
+
+    virtual void setVsyncRate(uint32_t count) {
+        Parcel data, reply;
+        data.writeInterfaceToken(IDisplayEventConnection::getInterfaceDescriptor());
+        data.writeInt32(count);
+        remote()->transact(SET_VSYNC_RATE, data, &reply);
+    }
+
+    virtual void requestNextVsync() {
+        Parcel data, reply;
+        data.writeInterfaceToken(IDisplayEventConnection::getInterfaceDescriptor());
+        remote()->transact(REQUEST_NEXT_VSYNC, data, &reply, IBinder::FLAG_ONEWAY);
+    }
+};
+
+IMPLEMENT_META_INTERFACE(DisplayEventConnection, "android.gui.DisplayEventConnection");
+
+// ----------------------------------------------------------------------------
+
+status_t BnDisplayEventConnection::onTransact(
+    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+    switch(code) {
+        case GET_DATA_CHANNEL: {
+            CHECK_INTERFACE(IDisplayEventConnection, data, reply);
+            sp<BitTube> channel(getDataChannel());
+            channel->writeToParcel(reply);
+            return NO_ERROR;
+        } break;
+        case SET_VSYNC_RATE: {
+            CHECK_INTERFACE(IDisplayEventConnection, data, reply);
+            setVsyncRate(data.readInt32());
+            return NO_ERROR;
+        } break;
+        case REQUEST_NEXT_VSYNC: {
+            CHECK_INTERFACE(IDisplayEventConnection, data, reply);
+            requestNextVsync();
+            return NO_ERROR;
+        } break;
+    }
+    return BBinder::onTransact(code, data, reply, flags);
+}
+
+// ----------------------------------------------------------------------------
+}; // namespace android
diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp
index 86bc62a..db32827 100644
--- a/libs/gui/ISurfaceComposer.cpp
+++ b/libs/gui/ISurfaceComposer.cpp
@@ -29,6 +29,9 @@
 
 #include <surfaceflinger/ISurfaceComposer.h>
 
+#include <gui/BitTube.h>
+#include <gui/IDisplayEventConnection.h>
+
 #include <ui/DisplayInfo.h>
 
 #include <gui/ISurfaceTexture.h>
@@ -44,6 +47,8 @@
 
 namespace android {
 
+class IDisplayEventConnection;
+
 class BpSurfaceComposer : public BpInterface<ISurfaceComposer>
 {
 public:
@@ -174,6 +179,27 @@
         }
         return result != 0;
     }
+
+    virtual sp<IDisplayEventConnection> createDisplayEventConnection()
+    {
+        Parcel data, reply;
+        sp<IDisplayEventConnection> result;
+        int err = data.writeInterfaceToken(
+                ISurfaceComposer::getInterfaceDescriptor());
+        if (err != NO_ERROR) {
+            return result;
+        }
+        err = remote()->transact(
+                BnSurfaceComposer::CREATE_DISPLAY_EVENT_CONNECTION,
+                data, &reply);
+        if (err != NO_ERROR) {
+            LOGE("ISurfaceComposer::createDisplayEventConnection: error performing "
+                    "transaction: %s (%d)", strerror(-err), -err);
+            return result;
+        }
+        result = interface_cast<IDisplayEventConnection>(reply.readStrongBinder());
+        return result;
+    }
 };
 
 IMPLEMENT_META_INTERFACE(SurfaceComposer, "android.ui.ISurfaceComposer");
@@ -254,6 +280,12 @@
             int32_t result = authenticateSurfaceTexture(surfaceTexture) ? 1 : 0;
             reply->writeInt32(result);
         } break;
+        case CREATE_DISPLAY_EVENT_CONNECTION: {
+            CHECK_INTERFACE(ISurfaceComposer, data, reply);
+            sp<IDisplayEventConnection> connection(createDisplayEventConnection());
+            reply->writeStrongBinder(connection->asBinder());
+            return NO_ERROR;
+        } break;
         default:
             return BBinder::onTransact(code, data, reply, flags);
     }
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 4ad6c22..699438c 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -39,6 +39,7 @@
 #include <private/surfaceflinger/LayerState.h>
 #include <private/surfaceflinger/SharedBufferStack.h>
 
+#include <private/gui/ComposerService.h>
 
 namespace android {
 // ---------------------------------------------------------------------------
diff --git a/libs/gui/SurfaceTexture.cpp b/libs/gui/SurfaceTexture.cpp
index b4d01a9..6f3051a 100644
--- a/libs/gui/SurfaceTexture.cpp
+++ b/libs/gui/SurfaceTexture.cpp
@@ -29,6 +29,8 @@
 
 #include <hardware/hardware.h>
 
+#include <private/gui/ComposerService.h>
+
 #include <surfaceflinger/ISurfaceComposer.h>
 #include <surfaceflinger/SurfaceComposerClient.h>
 #include <surfaceflinger/IGraphicBufferAlloc.h>
@@ -36,6 +38,12 @@
 #include <utils/Log.h>
 #include <utils/String8.h>
 
+// This compile option causes SurfaceTexture to return the buffer that is currently
+// attached to the GL texture from dequeueBuffer when no other buffers are
+// available.  It requires the drivers (Gralloc, GL, OMX IL, and Camera) to do
+// implicit cross-process synchronization to prevent the buffer from being
+// written to before the buffer has (a) been detached from the GL texture and
+// (b) all GL reads from the buffer have completed.
 #ifdef ALLOW_DEQUEUE_CURRENT_BUFFER
 #define FLAG_ALLOW_DEQUEUE_CURRENT_BUFFER    true
 #warning "ALLOW_DEQUEUE_CURRENT_BUFFER enabled"
@@ -43,6 +51,16 @@
 #define FLAG_ALLOW_DEQUEUE_CURRENT_BUFFER    false
 #endif
 
+// This compile option makes SurfaceTexture use the EGL_KHR_fence_sync extension
+// to synchronize access to the buffers.  It will cause dequeueBuffer to stall,
+// waiting for the GL reads for the buffer being dequeued to complete before
+// allowing the buffer to be dequeued.
+#ifdef USE_FENCE_SYNC
+#ifdef ALLOW_DEQUEUE_CURRENT_BUFFER
+#error "USE_FENCE_SYNC and ALLOW_DEQUEUE_CURRENT_BUFFER are incompatible"
+#endif
+#endif
+
 // Macros for including the SurfaceTexture name in log messages
 #define ST_LOGV(x, ...) ALOGV("[%s] "x, mName.string(), ##__VA_ARGS__)
 #define ST_LOGD(x, ...) LOGD("[%s] "x, mName.string(), ##__VA_ARGS__)
@@ -99,7 +117,7 @@
 }
 
 SurfaceTexture::SurfaceTexture(GLuint tex, bool allowSynchronousMode,
-        GLenum texTarget) :
+        GLenum texTarget, bool useFenceSync) :
     mDefaultWidth(1),
     mDefaultHeight(1),
     mPixelFormat(PIXEL_FORMAT_RGBA_8888),
@@ -116,6 +134,11 @@
     mAllowSynchronousMode(allowSynchronousMode),
     mConnectedApi(NO_CONNECTED_API),
     mAbandoned(false),
+#ifdef USE_FENCE_SYNC
+    mUseFenceSync(useFenceSync),
+#else
+    mUseFenceSync(false),
+#endif
     mTexTarget(texTarget),
     mFrameCounter(0) {
     // Choose a name using the PID and a process-unique ID.
@@ -261,195 +284,225 @@
         return BAD_VALUE;
     }
 
-    Mutex::Autolock lock(mMutex);
-
     status_t returnFlags(OK);
+    EGLDisplay dpy = EGL_NO_DISPLAY;
+    EGLSyncKHR fence = EGL_NO_SYNC_KHR;
 
-    int found = -1;
-    int foundSync = -1;
-    int dequeuedCount = 0;
-    bool tryAgain = true;
-    while (tryAgain) {
-        if (mAbandoned) {
-            ST_LOGE("dequeueBuffer: SurfaceTexture has been abandoned!");
-            return NO_INIT;
-        }
+    { // Scope for the lock
+        Mutex::Autolock lock(mMutex);
 
-        // We need to wait for the FIFO to drain if the number of buffer
-        // needs to change.
-        //
-        // The condition "number of buffers needs to change" is true if
-        // - the client doesn't care about how many buffers there are
-        // - AND the actual number of buffer is different from what was
-        //   set in the last setBufferCountServer()
-        //                         - OR -
-        //   setBufferCountServer() was set to a value incompatible with
-        //   the synchronization mode (for instance because the sync mode
-        //   changed since)
-        //
-        // As long as this condition is true AND the FIFO is not empty, we
-        // wait on mDequeueCondition.
-
-        const int minBufferCountNeeded = mSynchronousMode ?
-                MIN_SYNC_BUFFER_SLOTS : MIN_ASYNC_BUFFER_SLOTS;
-
-        const bool numberOfBuffersNeedsToChange = !mClientBufferCount &&
-                ((mServerBufferCount != mBufferCount) ||
-                        (mServerBufferCount < minBufferCountNeeded));
-
-        if (!mQueue.isEmpty() && numberOfBuffersNeedsToChange) {
-            // wait for the FIFO to drain
-            mDequeueCondition.wait(mMutex);
-            // NOTE: we continue here because we need to reevaluate our
-            // whole state (eg: we could be abandoned or disconnected)
-            continue;
-        }
-
-        if (numberOfBuffersNeedsToChange) {
-            // here we're guaranteed that mQueue is empty
-            freeAllBuffersLocked();
-            mBufferCount = mServerBufferCount;
-            if (mBufferCount < minBufferCountNeeded)
-                mBufferCount = minBufferCountNeeded;
-            mCurrentTexture = INVALID_BUFFER_SLOT;
-            returnFlags |= ISurfaceTexture::RELEASE_ALL_BUFFERS;
-        }
-
-        // look for a free buffer to give to the client
-        found = INVALID_BUFFER_SLOT;
-        foundSync = INVALID_BUFFER_SLOT;
-        dequeuedCount = 0;
-        for (int i = 0; i < mBufferCount; i++) {
-            const int state = mSlots[i].mBufferState;
-            if (state == BufferSlot::DEQUEUED) {
-                dequeuedCount++;
+        int found = -1;
+        int foundSync = -1;
+        int dequeuedCount = 0;
+        bool tryAgain = true;
+        while (tryAgain) {
+            if (mAbandoned) {
+                ST_LOGE("dequeueBuffer: SurfaceTexture has been abandoned!");
+                return NO_INIT;
             }
 
-            // if buffer is FREE it CANNOT be current
-            LOGW_IF((state == BufferSlot::FREE) && (mCurrentTexture==i),
-                    "dequeueBuffer: buffer %d is both FREE and current!", i);
+            // We need to wait for the FIFO to drain if the number of buffer
+            // needs to change.
+            //
+            // The condition "number of buffers needs to change" is true if
+            // - the client doesn't care about how many buffers there are
+            // - AND the actual number of buffer is different from what was
+            //   set in the last setBufferCountServer()
+            //                         - OR -
+            //   setBufferCountServer() was set to a value incompatible with
+            //   the synchronization mode (for instance because the sync mode
+            //   changed since)
+            //
+            // As long as this condition is true AND the FIFO is not empty, we
+            // wait on mDequeueCondition.
 
-            if (FLAG_ALLOW_DEQUEUE_CURRENT_BUFFER) {
-                if (state == BufferSlot::FREE || i == mCurrentTexture) {
-                    foundSync = i;
-                    if (i != mCurrentTexture) {
-                        found = i;
-                        break;
-                    }
+            const int minBufferCountNeeded = mSynchronousMode ?
+                    MIN_SYNC_BUFFER_SLOTS : MIN_ASYNC_BUFFER_SLOTS;
+
+            const bool numberOfBuffersNeedsToChange = !mClientBufferCount &&
+                    ((mServerBufferCount != mBufferCount) ||
+                            (mServerBufferCount < minBufferCountNeeded));
+
+            if (!mQueue.isEmpty() && numberOfBuffersNeedsToChange) {
+                // wait for the FIFO to drain
+                mDequeueCondition.wait(mMutex);
+                // NOTE: we continue here because we need to reevaluate our
+                // whole state (eg: we could be abandoned or disconnected)
+                continue;
+            }
+
+            if (numberOfBuffersNeedsToChange) {
+                // here we're guaranteed that mQueue is empty
+                freeAllBuffersLocked();
+                mBufferCount = mServerBufferCount;
+                if (mBufferCount < minBufferCountNeeded)
+                    mBufferCount = minBufferCountNeeded;
+                mCurrentTexture = INVALID_BUFFER_SLOT;
+                returnFlags |= ISurfaceTexture::RELEASE_ALL_BUFFERS;
+            }
+
+            // look for a free buffer to give to the client
+            found = INVALID_BUFFER_SLOT;
+            foundSync = INVALID_BUFFER_SLOT;
+            dequeuedCount = 0;
+            for (int i = 0; i < mBufferCount; i++) {
+                const int state = mSlots[i].mBufferState;
+                if (state == BufferSlot::DEQUEUED) {
+                    dequeuedCount++;
                 }
-            } else {
-                if (state == BufferSlot::FREE) {
-                    /** For Asynchronous mode, we need to return the oldest of free buffers
-                    * There is only one instance when the Framecounter overflows, this logic
-                    * might return the earlier buffer to client. Which is a negligible impact
-                    **/
-                    if (found < 0 || mSlots[i].mFrameNumber < mSlots[found].mFrameNumber) {
+
+                // if buffer is FREE it CANNOT be current
+                LOGW_IF((state == BufferSlot::FREE) && (mCurrentTexture==i),
+                        "dequeueBuffer: buffer %d is both FREE and current!",
+                        i);
+
+                if (FLAG_ALLOW_DEQUEUE_CURRENT_BUFFER) {
+                    if (state == BufferSlot::FREE || i == mCurrentTexture) {
                         foundSync = i;
-                        found = i;
+                        if (i != mCurrentTexture) {
+                            found = i;
+                            break;
+                        }
+                    }
+                } else {
+                    if (state == BufferSlot::FREE) {
+                        /* We return the oldest of the free buffers to avoid
+                         * stalling the producer if possible.  This is because
+                         * the consumer may still have pending reads of the
+                         * buffers in flight.
+                         */
+                        bool isOlder = mSlots[i].mFrameNumber <
+                                mSlots[found].mFrameNumber;
+                        if (found < 0 || isOlder) {
+                            foundSync = i;
+                            found = i;
+                        }
                     }
                 }
             }
-        }
 
-        // clients are not allowed to dequeue more than one buffer
-        // if they didn't set a buffer count.
-        if (!mClientBufferCount && dequeuedCount) {
-            ST_LOGE("dequeueBuffer: can't dequeue multiple buffers without "
-                    "setting the buffer count");
-            return -EINVAL;
-        }
+            // clients are not allowed to dequeue more than one buffer
+            // if they didn't set a buffer count.
+            if (!mClientBufferCount && dequeuedCount) {
+                ST_LOGE("dequeueBuffer: can't dequeue multiple buffers without "
+                        "setting the buffer count");
+                return -EINVAL;
+            }
 
-        // See whether a buffer has been queued since the last setBufferCount so
-        // we know whether to perform the MIN_UNDEQUEUED_BUFFERS check below.
-        bool bufferHasBeenQueued = mCurrentTexture != INVALID_BUFFER_SLOT;
-        if (bufferHasBeenQueued) {
-            // make sure the client is not trying to dequeue more buffers
-            // than allowed.
-            const int avail = mBufferCount - (dequeuedCount+1);
-            if (avail < (MIN_UNDEQUEUED_BUFFERS-int(mSynchronousMode))) {
-                ST_LOGE("dequeueBuffer: MIN_UNDEQUEUED_BUFFERS=%d exceeded "
-                        "(dequeued=%d)",
-                        MIN_UNDEQUEUED_BUFFERS-int(mSynchronousMode),
-                        dequeuedCount);
-                return -EBUSY;
+            // See whether a buffer has been queued since the last
+            // setBufferCount so we know whether to perform the
+            // MIN_UNDEQUEUED_BUFFERS check below.
+            bool bufferHasBeenQueued = mCurrentTexture != INVALID_BUFFER_SLOT;
+            if (bufferHasBeenQueued) {
+                // make sure the client is not trying to dequeue more buffers
+                // than allowed.
+                const int avail = mBufferCount - (dequeuedCount+1);
+                if (avail < (MIN_UNDEQUEUED_BUFFERS-int(mSynchronousMode))) {
+                    ST_LOGE("dequeueBuffer: MIN_UNDEQUEUED_BUFFERS=%d exceeded "
+                            "(dequeued=%d)",
+                            MIN_UNDEQUEUED_BUFFERS-int(mSynchronousMode),
+                            dequeuedCount);
+                    return -EBUSY;
+                }
+            }
+
+            // 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 (tryAgain) {
+                mDequeueCondition.wait(mMutex);
             }
         }
 
-        // 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 (tryAgain) {
-            mDequeueCondition.wait(mMutex);
+        if (mSynchronousMode && found == INVALID_BUFFER_SLOT) {
+            // foundSync guaranteed to be != INVALID_BUFFER_SLOT
+            found = foundSync;
         }
-    }
 
-    if (mSynchronousMode && found == INVALID_BUFFER_SLOT) {
-        // foundSync guaranteed to be != INVALID_BUFFER_SLOT
-        found = foundSync;
-    }
-
-    if (found == INVALID_BUFFER_SLOT) {
-        // This should not happen.
-        ST_LOGE("dequeueBuffer: no available buffer slots");
-        return -EBUSY;
-    }
-
-    const int buf = found;
-    *outBuf = found;
-
-    const bool useDefaultSize = !w && !h;
-    if (useDefaultSize) {
-        // use the default size
-        w = mDefaultWidth;
-        h = mDefaultHeight;
-    }
-
-    const bool updateFormat = (format != 0);
-    if (!updateFormat) {
-        // keep the current (or default) format
-        format = mPixelFormat;
-    }
-
-    // buffer is now in DEQUEUED (but can also be current at the same time,
-    // if we're in synchronous mode)
-    mSlots[buf].mBufferState = BufferSlot::DEQUEUED;
-
-    const sp<GraphicBuffer>& buffer(mSlots[buf].mGraphicBuffer);
-    if ((buffer == NULL) ||
-        (uint32_t(buffer->width)  != w) ||
-        (uint32_t(buffer->height) != h) ||
-        (uint32_t(buffer->format) != format) ||
-        ((uint32_t(buffer->usage) & usage) != usage))
-    {
-        usage |= GraphicBuffer::USAGE_HW_TEXTURE;
-        status_t error;
-        sp<GraphicBuffer> graphicBuffer(
-                mGraphicBufferAlloc->createGraphicBuffer(
-                        w, h, format, usage, &error));
-        if (graphicBuffer == 0) {
-            ST_LOGE("dequeueBuffer: SurfaceComposer::createGraphicBuffer "
-                    "failed");
-            return error;
+        if (found == INVALID_BUFFER_SLOT) {
+            // This should not happen.
+            ST_LOGE("dequeueBuffer: no available buffer slots");
+            return -EBUSY;
         }
-        if (updateFormat) {
-            mPixelFormat = format;
+
+        const int buf = found;
+        *outBuf = found;
+
+        const bool useDefaultSize = !w && !h;
+        if (useDefaultSize) {
+            // use the default size
+            w = mDefaultWidth;
+            h = mDefaultHeight;
         }
-        mSlots[buf].mGraphicBuffer = graphicBuffer;
-        mSlots[buf].mRequestBufferCalled = false;
-        if (mSlots[buf].mEglImage != EGL_NO_IMAGE_KHR) {
-            eglDestroyImageKHR(mSlots[buf].mEglDisplay, mSlots[buf].mEglImage);
-            mSlots[buf].mEglImage = EGL_NO_IMAGE_KHR;
-            mSlots[buf].mEglDisplay = EGL_NO_DISPLAY;
+
+        const bool updateFormat = (format != 0);
+        if (!updateFormat) {
+            // keep the current (or default) format
+            format = mPixelFormat;
         }
-        if (mCurrentTexture == buf) {
-            // The current texture no longer references the buffer in this slot
-            // since we just allocated a new buffer.
-            mCurrentTexture = INVALID_BUFFER_SLOT;
+
+        // buffer is now in DEQUEUED (but can also be current at the same time,
+        // if we're in synchronous mode)
+        mSlots[buf].mBufferState = BufferSlot::DEQUEUED;
+
+        const sp<GraphicBuffer>& buffer(mSlots[buf].mGraphicBuffer);
+        if ((buffer == NULL) ||
+            (uint32_t(buffer->width)  != w) ||
+            (uint32_t(buffer->height) != h) ||
+            (uint32_t(buffer->format) != format) ||
+            ((uint32_t(buffer->usage) & usage) != usage))
+        {
+            usage |= GraphicBuffer::USAGE_HW_TEXTURE;
+            status_t error;
+            sp<GraphicBuffer> graphicBuffer(
+                    mGraphicBufferAlloc->createGraphicBuffer(
+                            w, h, format, usage, &error));
+            if (graphicBuffer == 0) {
+                ST_LOGE("dequeueBuffer: SurfaceComposer::createGraphicBuffer "
+                        "failed");
+                return error;
+            }
+            if (updateFormat) {
+                mPixelFormat = format;
+            }
+            mSlots[buf].mGraphicBuffer = graphicBuffer;
+            mSlots[buf].mRequestBufferCalled = false;
+            mSlots[buf].mFence = EGL_NO_SYNC_KHR;
+            if (mSlots[buf].mEglImage != EGL_NO_IMAGE_KHR) {
+                eglDestroyImageKHR(mSlots[buf].mEglDisplay,
+                        mSlots[buf].mEglImage);
+                mSlots[buf].mEglImage = EGL_NO_IMAGE_KHR;
+                mSlots[buf].mEglDisplay = EGL_NO_DISPLAY;
+            }
+            if (mCurrentTexture == buf) {
+                // The current texture no longer references the buffer in this slot
+                // since we just allocated a new buffer.
+                mCurrentTexture = INVALID_BUFFER_SLOT;
+            }
+            returnFlags |= ISurfaceTexture::BUFFER_NEEDS_REALLOCATION;
         }
-        returnFlags |= ISurfaceTexture::BUFFER_NEEDS_REALLOCATION;
+
+        dpy = mSlots[buf].mEglDisplay;
+        fence = mSlots[buf].mFence;
+        mSlots[buf].mFence = EGL_NO_SYNC_KHR;
     }
+
+    if (fence != EGL_NO_SYNC_KHR) {
+        EGLint result = eglClientWaitSyncKHR(dpy, fence, 0, 1000000000);
+        // If something goes wrong, log the error, but return the buffer without
+        // synchronizing access to it.  It's too late at this point to abort the
+        // dequeue operation.
+        if (result == EGL_FALSE) {
+            LOGE("dequeueBuffer: error waiting for fence: %#x", eglGetError());
+        } else if (result == EGL_TIMEOUT_EXPIRED_KHR) {
+            LOGE("dequeueBuffer: timeout waiting for fence");
+        }
+        eglDestroySyncKHR(dpy, fence);
+    }
+
     ST_LOGV("dequeueBuffer: returning slot=%d buf=%p flags=%#x", buf,
             mSlots[buf].mGraphicBuffer->handle, returnFlags);
+
     return returnFlags;
 }
 
@@ -712,8 +765,8 @@
 
         // Update the GL texture object.
         EGLImageKHR image = mSlots[buf].mEglImage;
+        EGLDisplay dpy = eglGetCurrentDisplay();
         if (image == EGL_NO_IMAGE_KHR) {
-            EGLDisplay dpy = eglGetCurrentDisplay();
             if (mSlots[buf].mGraphicBuffer == 0) {
                 ST_LOGE("buffer at slot %d is null", buf);
                 return BAD_VALUE;
@@ -746,16 +799,32 @@
             return -EINVAL;
         }
 
-        ST_LOGV("updateTexImage: (slot=%d buf=%p) -> (slot=%d buf=%p)", mCurrentTexture,
-                mCurrentTextureBuf != NULL ? mCurrentTextureBuf->handle : 0, buf,
-                mSlots[buf].mGraphicBuffer->handle);
+        if (mCurrentTexture != INVALID_BUFFER_SLOT) {
+            if (mUseFenceSync) {
+                EGLSyncKHR fence = eglCreateSyncKHR(dpy, EGL_SYNC_FENCE_KHR,
+                        NULL);
+                if (fence == EGL_NO_SYNC_KHR) {
+                    LOGE("updateTexImage: error creating fence: %#x",
+                            eglGetError());
+                    return -EINVAL;
+                }
+                glFlush();
+                mSlots[mCurrentTexture].mFence = fence;
+            }
+        }
+
+        ST_LOGV("updateTexImage: (slot=%d buf=%p) -> (slot=%d buf=%p)",
+                mCurrentTexture,
+                mCurrentTextureBuf != NULL ? mCurrentTextureBuf->handle : 0,
+                buf, mSlots[buf].mGraphicBuffer->handle);
 
         if (mCurrentTexture != INVALID_BUFFER_SLOT) {
             // The current buffer becomes FREE if it was still in the queued
             // state. If it has already been given to the client
             // (synchronous mode), then it stays in DEQUEUED state.
-            if (mSlots[mCurrentTexture].mBufferState == BufferSlot::QUEUED)
+            if (mSlots[mCurrentTexture].mBufferState == BufferSlot::QUEUED) {
                 mSlots[mCurrentTexture].mBufferState = BufferSlot::FREE;
+            }
         }
 
         // Update the SurfaceTexture state.
diff --git a/libs/gui/SurfaceTextureClient.cpp b/libs/gui/SurfaceTextureClient.cpp
index 3d47f05..691b52d 100644
--- a/libs/gui/SurfaceTextureClient.cpp
+++ b/libs/gui/SurfaceTextureClient.cpp
@@ -23,6 +23,8 @@
 
 #include <utils/Log.h>
 
+#include <private/gui/ComposerService.h>
+
 namespace android {
 
 SurfaceTextureClient::SurfaceTextureClient(
diff --git a/libs/gui/tests/SurfaceTexture_test.cpp b/libs/gui/tests/SurfaceTexture_test.cpp
index c79e69a..b18e7b0 100644
--- a/libs/gui/tests/SurfaceTexture_test.cpp
+++ b/libs/gui/tests/SurfaceTexture_test.cpp
@@ -536,6 +536,20 @@
     }
 }
 
+void fillRGBA8BufferSolid(uint8_t* buf, int w, int h, int stride, uint8_t r,
+        uint8_t g, uint8_t b, uint8_t a) {
+    const size_t PIXEL_SIZE = 4;
+    for (int y = 0; y < h; y++) {
+        for (int x = 0; x < h; x++) {
+            off_t offset = (y * stride + x) * PIXEL_SIZE;
+            buf[offset + 0] = r;
+            buf[offset + 1] = g;
+            buf[offset + 2] = b;
+            buf[offset + 3] = a;
+        }
+    }
+}
+
 TEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledYV12BufferNpot) {
     const int texWidth = 64;
     const int texHeight = 66;
@@ -1616,4 +1630,101 @@
     }
 }
 
+class SurfaceTextureFBOTest : public SurfaceTextureGLTest {
+protected:
+
+    virtual void SetUp() {
+        SurfaceTextureGLTest::SetUp();
+
+        glGenFramebuffers(1, &mFbo);
+        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
+
+        glGenTextures(1, &mFboTex);
+        glBindTexture(GL_TEXTURE_2D, mFboTex);
+        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getSurfaceWidth(),
+                getSurfaceHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+        glBindTexture(GL_TEXTURE_2D, 0);
+        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
+
+        glBindFramebuffer(GL_FRAMEBUFFER, mFbo);
+        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+                GL_TEXTURE_2D, mFboTex, 0);
+        glBindFramebuffer(GL_FRAMEBUFFER, 0);
+        ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
+    }
+
+    virtual void TearDown() {
+        SurfaceTextureGLTest::TearDown();
+
+        glDeleteTextures(1, &mFboTex);
+        glDeleteFramebuffers(1, &mFbo);
+    }
+
+    GLuint mFbo;
+    GLuint mFboTex;
+};
+
+// This test is intended to verify that proper synchronization is done when
+// rendering into an FBO.
+TEST_F(SurfaceTextureFBOTest, BlitFromCpuFilledBufferToFbo) {
+    const int texWidth = 64;
+    const int texHeight = 64;
+
+    ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
+            texWidth, texHeight, HAL_PIXEL_FORMAT_RGBA_8888));
+    ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
+            GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
+
+    android_native_buffer_t* anb;
+    ASSERT_EQ(NO_ERROR, mANW->dequeueBuffer(mANW.get(), &anb));
+    ASSERT_TRUE(anb != NULL);
+
+    sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
+    ASSERT_EQ(NO_ERROR, mANW->lockBuffer(mANW.get(), buf->getNativeBuffer()));
+
+    // Fill the buffer with green
+    uint8_t* img = NULL;
+    buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
+    fillRGBA8BufferSolid(img, texWidth, texHeight, buf->getStride(), 0, 255,
+            0, 255);
+    buf->unlock();
+    ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), buf->getNativeBuffer()));
+
+    ASSERT_EQ(NO_ERROR, mST->updateTexImage());
+
+    glBindFramebuffer(GL_FRAMEBUFFER, mFbo);
+    drawTexture();
+    glBindFramebuffer(GL_FRAMEBUFFER, 0);
+
+    for (int i = 0; i < 4; i++) {
+        SCOPED_TRACE(String8::format("frame %d", i).string());
+
+        ASSERT_EQ(NO_ERROR, mANW->dequeueBuffer(mANW.get(), &anb));
+        ASSERT_TRUE(anb != NULL);
+
+        buf = new GraphicBuffer(anb, false);
+        ASSERT_EQ(NO_ERROR, mANW->lockBuffer(mANW.get(),
+                buf->getNativeBuffer()));
+
+        // Fill the buffer with red
+        ASSERT_EQ(NO_ERROR, buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN,
+                (void**)(&img)));
+        fillRGBA8BufferSolid(img, texWidth, texHeight, buf->getStride(), 255, 0,
+                0, 255);
+        ASSERT_EQ(NO_ERROR, buf->unlock());
+        ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(),
+                buf->getNativeBuffer()));
+
+        ASSERT_EQ(NO_ERROR, mST->updateTexImage());
+
+        drawTexture();
+
+        EXPECT_TRUE(checkPixel( 24, 39, 255, 0, 0, 255));
+    }
+
+    glBindFramebuffer(GL_FRAMEBUFFER, mFbo);
+
+    EXPECT_TRUE(checkPixel( 24, 39, 0, 255, 0, 255));
+}
+
 } // namespace android
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index 693b7b8..ea52750 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -22,6 +22,8 @@
 #include <surfaceflinger/SurfaceComposerClient.h>
 #include <utils/String8.h>
 
+#include <private/gui/ComposerService.h>
+
 namespace android {
 
 class SurfaceTest : public ::testing::Test {
diff --git a/libs/hwui/Android.mk b/libs/hwui/Android.mk
index 9bfc94c..95e0a18 100644
--- a/libs/hwui/Android.mk
+++ b/libs/hwui/Android.mk
@@ -38,7 +38,7 @@
 		external/skia/src/ports \
 		external/skia/include/utils
 
-	LOCAL_CFLAGS += -DUSE_OPENGL_RENDERER
+	LOCAL_CFLAGS += -DUSE_OPENGL_RENDERER -DGL_GLEXT_PROTOTYPES
 	LOCAL_CFLAGS += -fvisibility=hidden
 	LOCAL_MODULE_CLASS := SHARED_LIBRARIES
 	LOCAL_SHARED_LIBRARIES := libcutils libutils libGLESv2 libskia libui
diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp
index 3372d1c..5a52464 100644
--- a/libs/hwui/DisplayListRenderer.cpp
+++ b/libs/hwui/DisplayListRenderer.cpp
@@ -477,8 +477,9 @@
                 float x = getFloat();
                 float y = getFloat();
                 SkPaint* paint = getPaint();
-                LOGD("%s%s %s, %d, %d, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
-                    text.text(), text.length(), count, x, y, paint);
+                float length = getFloat();
+                LOGD("%s%s %s, %d, %d, %.2f, %.2f, %p, %.2f", (char*) indent, OP_NAMES[op],
+                    text.text(), text.length(), count, x, y, paint, length);
             }
             break;
             case ResetShader: {
@@ -837,9 +838,10 @@
                 float x = getFloat();
                 float y = getFloat();
                 SkPaint* paint = getPaint();
-                DISPLAY_LIST_LOGD("%s%s %s, %d, %d, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
-                    text.text(), text.length(), count, x, y, paint);
-                renderer.drawText(text.text(), text.length(), count, x, y, paint);
+                float length = getFloat();
+                DISPLAY_LIST_LOGD("%s%s %s, %d, %d, %.2f, %.2f, %p, %.2f", (char*) indent,
+                        OP_NAMES[op], text.text(), text.length(), count, x, y, paint, length);
+                renderer.drawText(text.text(), text.length(), count, x, y, paint, length);
             }
             break;
             case ResetShader: {
@@ -1196,13 +1198,24 @@
 }
 
 void DisplayListRenderer::drawText(const char* text, int bytesCount, int count,
-        float x, float y, SkPaint* paint) {
+        float x, float y, SkPaint* paint, float length) {
     if (count <= 0) return;
     addOp(DisplayList::DrawText);
     addText(text, bytesCount);
     addInt(count);
     addPoint(x, y);
+    // TODO: We should probably make a copy of the paint instead of modifying
+    //       it; modifying the paint will change its generationID the first
+    //       time, which might impact caches. More investigation needed to
+    //       see if it matters.
+    //       If we make a copy, then drawTextDecorations() should *not* make
+    //       its own copy as it does right now.
+    paint->setAntiAlias(true);
+#if RENDER_TEXT_AS_GLYPHS
+    paint->setTextEncoding(SkPaint::kGlyphID_TextEncoding);
+#endif
     addPaint(paint);
+    addFloat(length < 0.0f ? paint->measureText(text, bytesCount) : length);
 }
 
 void DisplayListRenderer::resetShader() {
diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h
index ab475bf..c09760e 100644
--- a/libs/hwui/DisplayListRenderer.h
+++ b/libs/hwui/DisplayListRenderer.h
@@ -290,7 +290,7 @@
     virtual void drawLines(float* points, int count, SkPaint* paint);
     virtual void drawPoints(float* points, int count, SkPaint* paint);
     virtual void drawText(const char* text, int bytesCount, int count, float x, float y,
-            SkPaint* paint);
+            SkPaint* paint, float length = 1.0f);
 
     virtual void resetShader();
     virtual void setupShader(SkiaShader* shader);
diff --git a/libs/hwui/Extensions.h b/libs/hwui/Extensions.h
index 38d1130..48e4247 100644
--- a/libs/hwui/Extensions.h
+++ b/libs/hwui/Extensions.h
@@ -66,6 +66,7 @@
 
         mHasNPot = hasExtension("GL_OES_texture_npot");
         mHasFramebufferFetch = hasExtension("GL_NV_shader_framebuffer_fetch");
+        mHasDiscardFramebuffer = hasExtension("GL_EXT_discard_framebuffer");
 
         const char* vendor = (const char*) glGetString(GL_VENDOR);
         EXT_LOGD("Vendor: %s", vendor);
@@ -80,6 +81,7 @@
     inline bool hasNPot() const { return mHasNPot; }
     inline bool hasFramebufferFetch() const { return mHasFramebufferFetch; }
     inline bool needsHighpTexCoords() const { return mNeedsHighpTexCoords; }
+    inline bool hasDiscardFramebuffer() const { return mHasDiscardFramebuffer; }
 
     bool hasExtension(const char* extension) const {
         const String8 s(extension);
@@ -98,6 +100,7 @@
     bool mHasNPot;
     bool mNeedsHighpTexCoords;
     bool mHasFramebufferFetch;
+    bool mHasDiscardFramebuffer;
 }; // class Extensions
 
 }; // namespace uirenderer
diff --git a/libs/hwui/FontRenderer.cpp b/libs/hwui/FontRenderer.cpp
index a077cbc5..158f785 100644
--- a/libs/hwui/FontRenderer.cpp
+++ b/libs/hwui/FontRenderer.cpp
@@ -163,7 +163,6 @@
         render(paint, text, start, len, numGlyphs, x, y, FRAMEBUFFER, NULL,
                 0, 0, NULL);
     }
-
 }
 
 void Font::measure(SkPaint* paint, const char* text, uint32_t start, uint32_t len,
@@ -615,7 +614,8 @@
 void FontRenderer::appendMeshQuad(float x1, float y1, float z1, float u1, float v1, float x2,
         float y2, float z2, float u2, float v2, float x3, float y3, float z3, float u3, float v3,
         float x4, float y4, float z4, float u4, float v4) {
-    if (x1 > mClip->right || y1 < mClip->top || x2 < mClip->left || y4 > mClip->bottom) {
+    if (mClip &&
+            (x1 > mClip->right || y1 < mClip->top || x2 < mClip->left || y4 > mClip->bottom)) {
         return;
     }
 
@@ -723,11 +723,16 @@
         return image;
     }
 
+    mClip = NULL;
+    mBounds = NULL;
+
     Rect bounds;
     mCurrentFont->measure(paint, text, startIndex, len, numGlyphs, &bounds);
+
     uint32_t paddedWidth = (uint32_t) (bounds.right - bounds.left) + 2 * radius;
     uint32_t paddedHeight = (uint32_t) (bounds.top - bounds.bottom) + 2 * radius;
     uint8_t* dataBuffer = new uint8_t[paddedWidth * paddedHeight];
+
     for (uint32_t i = 0; i < paddedWidth * paddedHeight; i++) {
         dataBuffer[i] = 0;
     }
@@ -765,8 +770,11 @@
     mDrawn = false;
     mBounds = bounds;
     mClip = clip;
+
     mCurrentFont->render(paint, text, startIndex, len, numGlyphs, x, y);
+
     mBounds = NULL;
+    mClip = NULL;
 
     if (mCurrentQuadIndex != 0) {
         issueDrawCommand();
diff --git a/libs/hwui/Layer.h b/libs/hwui/Layer.h
index a8ae5c6..ee6ef1a 100644
--- a/libs/hwui/Layer.h
+++ b/libs/hwui/Layer.h
@@ -147,12 +147,12 @@
         this->renderTarget = renderTarget;
     }
 
-    void setWrap(GLenum wrapS, GLenum wrapT, bool bindTexture = false, bool force = false) {
-        texture.setWrap(wrapS, wrapT, bindTexture, force, renderTarget);
+    void setWrap(GLenum wrap, bool bindTexture = false, bool force = false) {
+        texture.setWrap(wrap, bindTexture, force, renderTarget);
     }
 
-    void setFilter(GLenum min, GLenum mag, bool bindTexture = false, bool force = false) {
-        texture.setFilter(min, mag,bindTexture, force, renderTarget);
+    void setFilter(GLenum filter, bool bindTexture = false, bool force = false) {
+        texture.setFilter(filter, bindTexture, force, renderTarget);
     }
 
     inline bool isCacheable() {
diff --git a/libs/hwui/LayerRenderer.cpp b/libs/hwui/LayerRenderer.cpp
index e38b479..e2d9ea3 100644
--- a/libs/hwui/LayerRenderer.cpp
+++ b/libs/hwui/LayerRenderer.cpp
@@ -294,8 +294,8 @@
         if (renderTarget != layer->getRenderTarget()) {
             layer->setRenderTarget(renderTarget);
             layer->bindTexture();
-            layer->setFilter(GL_NEAREST, GL_NEAREST, false, true);
-            layer->setWrap(GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, false, true);
+            layer->setFilter(GL_NEAREST, false, true);
+            layer->setWrap(GL_CLAMP_TO_EDGE, false, true);
         }
     }
 }
@@ -305,8 +305,10 @@
         LAYER_RENDERER_LOGD("Recycling layer, %dx%d fbo = %d",
                 layer->getWidth(), layer->getHeight(), layer->getFbo());
 
-        if (layer->getFbo()) {
-            Caches::getInstance().fboCache.put(layer->getFbo());
+        GLuint fbo = layer->getFbo();
+        if (fbo) {
+            flushLayer(layer);
+            Caches::getInstance().fboCache.put(fbo);
         }
 
         if (!Caches::getInstance().layerCache.put(layer)) {
@@ -331,6 +333,26 @@
     }
 }
 
+void LayerRenderer::flushLayer(Layer* layer) {
+#ifdef GL_EXT_discard_framebuffer
+    GLuint fbo = layer->getFbo();
+    if (layer && fbo) {
+        // If possible, discard any enqueud operations on deferred
+        // rendering architectures
+        if (Caches::getInstance().extensions.hasDiscardFramebuffer()) {
+            GLuint previousFbo;
+            glGetIntegerv(GL_FRAMEBUFFER_BINDING, (GLint*) &previousFbo);
+
+            GLenum attachments = GL_COLOR_ATTACHMENT0;
+            if (fbo != previousFbo) glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+            glDiscardFramebufferEXT(GL_FRAMEBUFFER, 1, &attachments);
+
+            if (fbo != previousFbo) glBindFramebuffer(GL_FRAMEBUFFER, previousFbo);
+        }
+    }
+#endif
+}
+
 bool LayerRenderer::copyLayer(Layer* layer, SkBitmap* bitmap) {
     Caches& caches = Caches::getInstance();
     if (layer && layer->isTextureLayer() && bitmap->width() <= caches.maxTextureSize &&
diff --git a/libs/hwui/LayerRenderer.h b/libs/hwui/LayerRenderer.h
index 6104301..72d8d81 100644
--- a/libs/hwui/LayerRenderer.h
+++ b/libs/hwui/LayerRenderer.h
@@ -61,6 +61,7 @@
             bool isOpaque, GLenum renderTarget, float* transform);
     ANDROID_API static void destroyLayer(Layer* layer);
     ANDROID_API static void destroyLayerDeferred(Layer* layer);
+    ANDROID_API static void flushLayer(Layer* layer);
     ANDROID_API static bool copyLayer(Layer* layer, SkBitmap* bitmap);
 
 private:
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 70f1b7a..1d7b99d 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -47,6 +47,8 @@
 // TODO: This should be set in properties
 #define ALPHA_THRESHOLD (0x7f / PANEL_BIT_DEPTH)
 
+#define FILTER(paint) (paint && paint->isFilterBitmap() ? GL_LINEAR : GL_NEAREST)
+
 ///////////////////////////////////////////////////////////////////////////////
 // Globals
 ///////////////////////////////////////////////////////////////////////////////
@@ -201,14 +203,16 @@
 }
 
 void OpenGLRenderer::resume() {
-    glViewport(0, 0, mSnapshot->viewport.getWidth(), mSnapshot->viewport.getHeight());
+    sp<Snapshot> snapshot = (mSnapshot != NULL) ? mSnapshot : mFirstSnapshot;
+
+    glViewport(0, 0, snapshot->viewport.getWidth(), snapshot->viewport.getHeight());
 
     glEnable(GL_SCISSOR_TEST);
     dirtyClip();
 
     glDisable(GL_DITHER);
 
-    glBindFramebuffer(GL_FRAMEBUFFER, getTargetFbo());
+    glBindFramebuffer(GL_FRAMEBUFFER, snapshot->fbo);
     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
 
     mCaches.blend = true;
@@ -611,6 +615,11 @@
     }
 
     if (fboLayer) {
+        // Note: No need to use glDiscardFramebufferEXT() since we never
+        //       create/compose layers that are not on screen with this
+        //       code path
+        // See LayerRenderer::destroyLayer(Layer*)
+
         // Detach the texture from the FBO
         glBindFramebuffer(GL_FRAMEBUFFER, current->fbo);
         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
@@ -663,10 +672,10 @@
         const float x = (int) floorf(rect.left + mSnapshot->transform->getTranslateX() + 0.5f);
         const float y = (int) floorf(rect.top + mSnapshot->transform->getTranslateY() + 0.5f);
 
-        layer->setFilter(GL_NEAREST, GL_NEAREST);
+        layer->setFilter(GL_NEAREST);
         setupDrawModelView(x, y, x + rect.getWidth(), y + rect.getHeight(), true);
     } else {
-        layer->setFilter(GL_LINEAR, GL_LINEAR);
+        layer->setFilter(GL_LINEAR);
         setupDrawModelView(rect.left, rect.top, rect.right, rect.bottom);
     }
     setupDrawTextureTransformUniforms(layer->getTexTransform());
@@ -700,9 +709,9 @@
                 y = (int) floorf(rect.top + mSnapshot->transform->getTranslateY() + 0.5f);
             }
 
-            layer->setFilter(GL_NEAREST, GL_NEAREST, true);
+            layer->setFilter(GL_NEAREST, true);
         } else {
-            layer->setFilter(GL_LINEAR, GL_LINEAR, true);
+            layer->setFilter(GL_LINEAR, true);
         }
 
         drawTextureMesh(x, y, x + rect.getWidth(), y + rect.getHeight(),
@@ -758,10 +767,10 @@
             const float x = (int) floorf(rect.left + mSnapshot->transform->getTranslateX() + 0.5f);
             const float y = (int) floorf(rect.top + mSnapshot->transform->getTranslateY() + 0.5f);
 
-            layer->setFilter(GL_NEAREST, GL_NEAREST);
+            layer->setFilter(GL_NEAREST);
             setupDrawModelViewTranslate(x, y, x + rect.getWidth(), y + rect.getHeight(), true);
         } else {
-            layer->setFilter(GL_LINEAR, GL_LINEAR);
+            layer->setFilter(GL_LINEAR);
             setupDrawModelViewTranslate(rect.left, rect.top, rect.right, rect.bottom);
         }
         setupDrawMesh(&mesh[0].position[0], &mesh[0].texture[0]);
@@ -1318,6 +1327,8 @@
         y = (int) floorf(top + mSnapshot->transform->getTranslateY() + 0.5f);
         ignoreTransform = true;
         filter = GL_NEAREST;
+    } else {
+        filter = FILTER(paint);
     }
 
     setupDraw();
@@ -1332,8 +1343,8 @@
     setupDrawModelView(x, y, x + texture->width, y + texture->height, ignoreTransform);
 
     setupDrawTexture(texture->id);
-    texture->setWrap(GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE);
-    texture->setFilter(filter, filter);
+    texture->setWrap(GL_CLAMP_TO_EDGE);
+    texture->setFilter(filter);
 
     setupDrawPureColorUniforms();
     setupDrawColorFilterUniforms();
@@ -1399,8 +1410,8 @@
     if (!texture) return;
     const AutoTexture autoCleanup(texture);
 
-    texture->setWrap(GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, true);
-    texture->setFilter(GL_LINEAR, GL_LINEAR, true);
+    texture->setWrap(GL_CLAMP_TO_EDGE, true);
+    texture->setFilter(FILTER(paint), true);
 
     int alpha;
     SkXfermode::Mode mode;
@@ -1483,7 +1494,6 @@
     Texture* texture = mCaches.textureCache.get(bitmap);
     if (!texture) return;
     const AutoTexture autoCleanup(texture);
-    texture->setWrap(GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, true);
 
     const float width = texture->width;
     const float height = texture->height;
@@ -1500,6 +1510,8 @@
     SkXfermode::Mode mode;
     getAlphaAndMode(paint, &alpha, &mode);
 
+    texture->setWrap(GL_CLAMP_TO_EDGE, true);
+
     if (mSnapshot->transform->isPureTranslate()) {
         const float x = (int) floorf(dstLeft + mSnapshot->transform->getTranslateX() + 0.5f);
         const float y = (int) floorf(dstTop + mSnapshot->transform->getTranslateY() + 0.5f);
@@ -1507,17 +1519,16 @@
         GLenum filter = GL_NEAREST;
         // Enable linear filtering if the source rectangle is scaled
         if (srcRight - srcLeft != dstRight - dstLeft || srcBottom - srcTop != dstBottom - dstTop) {
-            filter = GL_LINEAR;
+            filter = FILTER(paint);
         }
-        texture->setFilter(filter, filter, true);
 
+        texture->setFilter(filter, true);
         drawTextureMesh(x, y, x + (dstRight - dstLeft), y + (dstBottom - dstTop),
                 texture->id, alpha / 255.0f, mode, texture->blend,
                 &mMeshVertices[0].position[0], &mMeshVertices[0].texture[0],
                 GL_TRIANGLE_STRIP, gMeshCount, false, true);
     } else {
-        texture->setFilter(GL_LINEAR, GL_LINEAR, true);
-
+        texture->setFilter(FILTER(paint), true);
         drawTextureMesh(dstLeft, dstTop, dstRight, dstBottom, texture->id, alpha / 255.0f,
                 mode, texture->blend, &mMeshVertices[0].position[0], &mMeshVertices[0].texture[0],
                 GL_TRIANGLE_STRIP, gMeshCount);
@@ -1537,8 +1548,8 @@
     Texture* texture = mCaches.textureCache.get(bitmap);
     if (!texture) return;
     const AutoTexture autoCleanup(texture);
-    texture->setWrap(GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, true);
-    texture->setFilter(GL_LINEAR, GL_LINEAR, true);
+    texture->setWrap(GL_CLAMP_TO_EDGE, true);
+    texture->setFilter(GL_LINEAR, true);
 
     int alpha;
     SkXfermode::Mode mode;
@@ -2057,37 +2068,35 @@
 }
 
 void OpenGLRenderer::drawText(const char* text, int bytesCount, int count,
-        float x, float y, SkPaint* paint) {
+        float x, float y, SkPaint* paint, float length) {
     if (text == NULL || count == 0) {
         return;
     }
     if (mSnapshot->isIgnored()) return;
 
-    // TODO: We should probably make a copy of the paint instead of modifying
-    //       it; modifying the paint will change its generationID the first
-    //       time, which might impact caches. More investigation needed to
-    //       see if it matters.
-    //       If we make a copy, then drawTextDecorations() should *not* make
-    //       its own copy as it does right now.
-    paint->setAntiAlias(true);
-#if RENDER_TEXT_AS_GLYPHS
-    paint->setTextEncoding(SkPaint::kGlyphID_TextEncoding);
-#endif
+    // NOTE: AA and glyph id encoding are set in DisplayListRenderer.cpp
 
-    float length = -1.0f;
     switch (paint->getTextAlign()) {
         case SkPaint::kCenter_Align:
-            length = paint->measureText(text, bytesCount);
+            if (length < 0.0f) length = paint->measureText(text, bytesCount);
             x -= length / 2.0f;
             break;
         case SkPaint::kRight_Align:
-            length = paint->measureText(text, bytesCount);
+            if (length < 0.0f) length = paint->measureText(text, bytesCount);
             x -= length;
             break;
         default:
             break;
     }
 
+    SkPaint::FontMetrics metrics;
+    paint->getFontMetrics(&metrics, 0.0f);
+    // If no length was specified, just perform the hit test on the Y axis
+    if (quickReject(x, y + metrics.fTop,
+            x + (length >= 0.0f ? length : INT_MAX / 2), y + metrics.fBottom)) {
+        return;
+    }
+
     const float oldX = x;
     const float oldY = y;
     const bool pureTranslate = mSnapshot->transform->isPureTranslate();
@@ -2248,11 +2257,11 @@
                 x = (int) floorf(x + mSnapshot->transform->getTranslateX() + 0.5f);
                 y = (int) floorf(y + mSnapshot->transform->getTranslateY() + 0.5f);
 
-                layer->setFilter(GL_NEAREST, GL_NEAREST);
+                layer->setFilter(GL_NEAREST);
                 setupDrawModelViewTranslate(x, y,
                         x + layer->layer.getWidth(), y + layer->layer.getHeight(), true);
             } else {
-                layer->setFilter(GL_LINEAR, GL_LINEAR);
+                layer->setFilter(GL_LINEAR);
                 setupDrawModelViewTranslate(x, y,
                         x + layer->layer.getWidth(), y + layer->layer.getHeight());
             }
@@ -2445,18 +2454,18 @@
     SkXfermode::Mode mode;
     getAlphaAndMode(paint, &alpha, &mode);
 
-    texture->setWrap(GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, true);
+    texture->setWrap(GL_CLAMP_TO_EDGE, true);
 
     if (mSnapshot->transform->isPureTranslate()) {
         const float x = (int) floorf(left + mSnapshot->transform->getTranslateX() + 0.5f);
         const float y = (int) floorf(top + mSnapshot->transform->getTranslateY() + 0.5f);
 
-        texture->setFilter(GL_NEAREST, GL_NEAREST, true);
+        texture->setFilter(GL_NEAREST, true);
         drawTextureMesh(x, y, x + texture->width, y + texture->height, texture->id,
                 alpha / 255.0f, mode, texture->blend, (GLvoid*) NULL,
                 (GLvoid*) gMeshTextureOffset, GL_TRIANGLE_STRIP, gMeshCount, false, true);
     } else {
-        texture->setFilter(GL_LINEAR, GL_LINEAR, true);
+        texture->setFilter(FILTER(paint), true);
         drawTextureMesh(left, top, right, bottom, texture->id, alpha / 255.0f, mode,
                 texture->blend, (GLvoid*) NULL, (GLvoid*) gMeshTextureOffset,
                 GL_TRIANGLE_STRIP, gMeshCount);
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index 2fc88e1..cd9ff93 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -123,7 +123,7 @@
     virtual void drawLines(float* points, int count, SkPaint* paint);
     virtual void drawPoints(float* points, int count, SkPaint* paint);
     virtual void drawText(const char* text, int bytesCount, int count, float x, float y,
-            SkPaint* paint);
+            SkPaint* paint, float length = -1.0f);
 
     virtual void resetShader();
     virtual void setupShader(SkiaShader* shader);
diff --git a/libs/hwui/ShapeCache.h b/libs/hwui/ShapeCache.h
index 0660b69..f64c074 100644
--- a/libs/hwui/ShapeCache.h
+++ b/libs/hwui/ShapeCache.h
@@ -503,7 +503,8 @@
     const uint32_t height = uint32_t(pathHeight + offset * 2.0 + 0.5);
 
     if (width > mMaxTextureSize || height > mMaxTextureSize) {
-        LOGW("Shape %s too large to be rendered into a texture", mName);
+        LOGW("Shape %s too large to be rendered into a texture (%dx%d, max=%dx%d)",
+                mName, width, height, mMaxTextureSize, mMaxTextureSize);
         return NULL;
     }
 
@@ -584,8 +585,8 @@
     glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, texture->width, texture->height, 0,
             GL_ALPHA, GL_UNSIGNED_BYTE, bitmap.getPixels());
 
-    texture->setFilter(GL_LINEAR, GL_LINEAR);
-    texture->setWrap(GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE);
+    texture->setFilter(GL_LINEAR);
+    texture->setWrap(GL_CLAMP_TO_EDGE);
 }
 
 }; // namespace uirenderer
diff --git a/libs/hwui/SkiaShader.cpp b/libs/hwui/SkiaShader.cpp
index 2428295..32e7533 100644
--- a/libs/hwui/SkiaShader.cpp
+++ b/libs/hwui/SkiaShader.cpp
@@ -77,7 +77,7 @@
 
 void SkiaShader::bindTexture(Texture* texture, GLenum wrapS, GLenum wrapT) {
     glBindTexture(GL_TEXTURE_2D, texture->id);
-    texture->setWrap(wrapS, wrapT);
+    texture->setWrapST(wrapS, wrapT);
 }
 
 void SkiaShader::computeScreenSpaceMatrix(mat4& screenSpace, const mat4& modelView) {
@@ -148,7 +148,7 @@
     // ::updateTransforms() but we don't have the texture object
     // available at that point. The optimization is not worth the
     // effort for now.
-    texture->setFilter(GL_LINEAR, GL_LINEAR);
+    texture->setFilter(GL_LINEAR);
 
     glUniform1i(program->getUniform("bitmapSampler"), textureSlot);
     glUniformMatrix4fv(program->getUniform("textureTransform"), 1,
diff --git a/libs/hwui/Snapshot.h b/libs/hwui/Snapshot.h
index d51154d..aff7b93 100644
--- a/libs/hwui/Snapshot.h
+++ b/libs/hwui/Snapshot.h
@@ -213,7 +213,8 @@
     Layer* layer;
 
     /**
-     * Only set when the flag kFlagIsFboLayer is set.
+     * Target FBO used for rendering. Set to 0 when rendering directly
+     * into the framebuffer.
      */
     GLuint fbo;
 
diff --git a/libs/hwui/Texture.h b/libs/hwui/Texture.h
index 48229b6..a4aed07 100644
--- a/libs/hwui/Texture.h
+++ b/libs/hwui/Texture.h
@@ -40,7 +40,12 @@
         firstWrap = true;
     }
 
-    void setWrap(GLenum wrapS, GLenum wrapT, bool bindTexture = false, bool force = false,
+    void setWrap(GLenum wrap, bool bindTexture = false, bool force = false,
+                GLenum renderTarget = GL_TEXTURE_2D) {
+        setWrapST(wrap, wrap, bindTexture, force, renderTarget);
+    }
+
+    void setWrapST(GLenum wrapS, GLenum wrapT, bool bindTexture = false, bool force = false,
             GLenum renderTarget = GL_TEXTURE_2D) {
 
         if (firstWrap || force || wrapS != this->wrapS || wrapT != this->wrapT) {
@@ -58,7 +63,12 @@
         }
     }
 
-    void setFilter(GLenum min, GLenum mag, bool bindTexture = false, bool force = false,
+    void setFilter(GLenum filter, bool bindTexture = false, bool force = false,
+                GLenum renderTarget = GL_TEXTURE_2D) {
+        setFilterMinMag(filter, filter, bindTexture, force, renderTarget);
+    }
+
+    void setFilterMinMag(GLenum min, GLenum mag, bool bindTexture = false, bool force = false,
             GLenum renderTarget = GL_TEXTURE_2D) {
 
         if (firstFilter || force || min != minFilter || mag != magFilter) {
diff --git a/libs/hwui/TextureCache.cpp b/libs/hwui/TextureCache.cpp
index 018ce3e..60f4ca1 100644
--- a/libs/hwui/TextureCache.cpp
+++ b/libs/hwui/TextureCache.cpp
@@ -125,7 +125,8 @@
 
     if (!texture) {
         if (bitmap->width() > mMaxTextureSize || bitmap->height() > mMaxTextureSize) {
-            LOGW("Bitmap too large to be uploaded into a texture");
+            LOGW("Bitmap too large to be uploaded into a texture (%dx%d, max=%dx%d)",
+                    bitmap->width(), bitmap->height(), mMaxTextureSize, mMaxTextureSize);
             return NULL;
         }
 
@@ -217,11 +218,15 @@
     texture->height = bitmap->height();
 
     glBindTexture(GL_TEXTURE_2D, texture->id);
-    glPixelStorei(GL_UNPACK_ALIGNMENT, bitmap->bytesPerPixel());
+    if (!regenerate) {
+        glPixelStorei(GL_UNPACK_ALIGNMENT, bitmap->bytesPerPixel());
+    }
 
     switch (bitmap->getConfig()) {
     case SkBitmap::kA8_Config:
-        glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+        if (!regenerate) {
+            glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+        }
         uploadToTexture(resize, GL_ALPHA, bitmap->rowBytesAsPixels(), texture->height,
                 GL_UNSIGNED_BYTE, bitmap->getPixels());
         texture->blend = true;
@@ -248,8 +253,10 @@
         break;
     }
 
-    texture->setFilter(GL_LINEAR, GL_LINEAR);
-    texture->setWrap(GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE);
+    if (!regenerate) {
+        texture->setFilter(GL_NEAREST);
+        texture->setWrap(GL_CLAMP_TO_EDGE);
+    }
 }
 
 void TextureCache::uploadLoFiTexture(bool resize, SkBitmap* bitmap,
diff --git a/libs/rs/driver/rsdBcc.cpp b/libs/rs/driver/rsdBcc.cpp
index c16091c..917b419 100644
--- a/libs/rs/driver/rsdBcc.cpp
+++ b/libs/rs/driver/rsdBcc.cpp
@@ -72,7 +72,7 @@
     //LOGE("rsdScriptCreate %p %p %p %p %i %i %p", rsc, resName, cacheDir, bitcode, bitcodeSize, flags, lookupFunc);
 
     pthread_mutex_lock(&rsdgInitMutex);
-    char *cachePath = NULL;
+
     size_t exportFuncCount = 0;
     size_t exportVarCount = 0;
     size_t objectSlotCount = 0;
@@ -122,8 +122,6 @@
         goto error;
     }
 
-    free(cachePath);
-
     drv->mRoot = reinterpret_cast<int (*)()>(bccGetFuncAddr(drv->mBccScript, "root"));
     drv->mInit = reinterpret_cast<void (*)()>(bccGetFuncAddr(drv->mBccScript, "init"));
     drv->mFreeChildren = reinterpret_cast<void (*)()>(bccGetFuncAddr(drv->mBccScript, ".rs.dtor"));
diff --git a/libs/rs/rsScript.cpp b/libs/rs/rsScript.cpp
index 16446dd..7fc128e 100644
--- a/libs/rs/rsScript.cpp
+++ b/libs/rs/rsScript.cpp
@@ -26,6 +26,7 @@
 
     mSlots = NULL;
     mTypes = NULL;
+    mInitialized = false;
 }
 
 Script::~Script() {
diff --git a/libs/rs/rsScript.h b/libs/rs/rsScript.h
index abb55b8..99dceaf 100644
--- a/libs/rs/rsScript.h
+++ b/libs/rs/rsScript.h
@@ -67,7 +67,6 @@
     };
     Enviroment_t mEnviroment;
 
-    void initSlots();
     void setSlot(uint32_t slot, Allocation *a);
     void setVar(uint32_t slot, const void *val, size_t len);
     void setVarObj(uint32_t slot, ObjectBase *val);
@@ -85,6 +84,7 @@
     virtual void setupScript(Context *rsc) = 0;
     virtual uint32_t run(Context *) = 0;
 protected:
+    bool mInitialized;
     ObjectBaseRef<Allocation> *mSlots;
     ObjectBaseRef<const Type> *mTypes;
 
diff --git a/libs/rs/rsScriptC.cpp b/libs/rs/rsScriptC.cpp
index b45366b..ce3c643 100644
--- a/libs/rs/rsScriptC.cpp
+++ b/libs/rs/rsScriptC.cpp
@@ -21,6 +21,7 @@
 
 #ifndef ANDROID_RS_SERIALIZE
 #include <bcinfo/BitcodeTranslator.h>
+#include <bcinfo/BitcodeWrapper.h>
 #endif
 
 using namespace android;
@@ -44,8 +45,10 @@
         BT = NULL;
     }
 #endif
-    mRSC->mHal.funcs.script.invokeFreeChildren(mRSC, this);
-    mRSC->mHal.funcs.script.destroy(mRSC, this);
+    if (mInitialized) {
+        mRSC->mHal.funcs.script.invokeFreeChildren(mRSC, this);
+        mRSC->mHal.funcs.script.destroy(mRSC, this);
+    }
 }
 
 void ScriptC::setupScript(Context *rsc) {
@@ -196,7 +199,24 @@
 
     //LOGE("runCompiler %p %p %p %p %p %i", rsc, this, resName, cacheDir, bitcode, bitcodeLen);
 #ifndef ANDROID_RS_SERIALIZE
-    uint32_t sdkVersion = rsc->getTargetSdkVersion();
+    uint32_t sdkVersion = 0;
+    bcinfo::BitcodeWrapper bcWrapper((const char *)bitcode, bitcodeLen);
+    if (!bcWrapper.unwrap()) {
+        LOGE("Bitcode is not in proper container format (raw or wrapper)");
+        return false;
+    }
+
+    rsAssert(bcWrapper.getHeaderVersion() == 0);
+    if (bcWrapper.getBCFileType() == bcinfo::BC_WRAPPER) {
+        sdkVersion = bcWrapper.getTargetAPI();
+    }
+
+    if (sdkVersion == 0) {
+        // This signals that we didn't have a wrapper containing information
+        // about the bitcode.
+        sdkVersion = rsc->getTargetSdkVersion();
+    }
+
     if (BT) {
         delete BT;
     }
@@ -212,8 +232,11 @@
     bitcodeLen = BT->getTranslatedBitcodeSize();
 #endif
 
-    rsc->mHal.funcs.script.init(rsc, this, resName, cacheDir, bitcode, bitcodeLen, 0);
+    if (!rsc->mHal.funcs.script.init(rsc, this, resName, cacheDir, bitcode, bitcodeLen, 0)) {
+        return false;
+    }
 
+    mInitialized = true;
     mEnviroment.mFragment.set(rsc->getDefaultProgramFragment());
     mEnviroment.mVertex.set(rsc->getDefaultProgramVertex());
     mEnviroment.mFragmentStore.set(rsc->getDefaultProgramStore());
diff --git a/libs/rs/scriptc/rs_allocation.rsh b/libs/rs/scriptc/rs_allocation.rsh
index 154a099..1cb3a99 100644
--- a/libs/rs/scriptc/rs_allocation.rsh
+++ b/libs/rs/scriptc/rs_allocation.rsh
@@ -14,6 +14,31 @@
  * limitations under the License.
  */
 
+/*! \mainpage notitle
+ *
+ * Renderscript is a high-performance runtime that provides graphics rendering and
+ * compute operations at the native level. Renderscript code is compiled on devices
+ * at runtime to allow platform-independence as well.
+ * This reference documentation describes the Renderscript runtime APIs, which you
+ * can utilize to write Renderscript code in C99. The Renderscript header
+ * files are automatically included for you, except for the rs_graphics.rsh header. If
+ * you are doing graphics rendering, include the graphics header file like this:
+ *
+ * <code>#include "rs_graphics.rsh"</code>
+ *
+ * To use Renderscript, you need to utilize the Renderscript runtime APIs documented here
+ * as well as the Android framework APIs for Renderscript.
+ * For documentation on the Android framework APIs, see the <a href=
+ * "http://developer.android.com/reference/android/renderscript/package-summary.html">
+ * android.renderscript</a> package reference.
+ * For more information on how to develop with Renderscript and how the runtime and
+ * Android framework APIs interact, see the <a href=
+ * "http://developer.android.com/guide/topics/renderscript/index.html">Renderscript
+ * developer guide</a> and the <a href=
+ * "http://developer.android.com/resources/samples/RenderScript/index.html">
+ * Renderscript samples</a>.
+ */
+
 /** @file rs_allocation.rsh
  *  \brief Allocation routines
  *
diff --git a/libs/rs/scriptc/rs_types.rsh b/libs/rs/scriptc/rs_types.rsh
index e9c3c5e..84bca9c 100644
--- a/libs/rs/scriptc/rs_types.rsh
+++ b/libs/rs/scriptc/rs_types.rsh
@@ -364,7 +364,7 @@
 typedef float4 rs_quaternion;
 
 #define RS_PACKED __attribute__((packed, aligned(4)))
-#define NULL ((const void *)0)
+#define NULL ((void *)0)
 
 #if (defined(RS_VERSION) && (RS_VERSION >= 14))
 
diff --git a/libs/utils/Android.mk b/libs/utils/Android.mk
index d168d19..544ab74 100644
--- a/libs/utils/Android.mk
+++ b/libs/utils/Android.mk
@@ -21,6 +21,7 @@
 	Asset.cpp \
 	AssetDir.cpp \
 	AssetManager.cpp \
+	BasicHashtable.cpp \
 	BlobCache.cpp \
 	BufferedTextOutput.cpp \
 	CallStack.cpp \
diff --git a/libs/utils/BasicHashtable.cpp b/libs/utils/BasicHashtable.cpp
new file mode 100644
index 0000000..fb8ec9f
--- /dev/null
+++ b/libs/utils/BasicHashtable.cpp
@@ -0,0 +1,338 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "BasicHashtable"
+
+#include <math.h>
+
+#include <utils/Log.h>
+#include <utils/BasicHashtable.h>
+#include <utils/misc.h>
+
+namespace android {
+
+BasicHashtableImpl::BasicHashtableImpl(size_t entrySize, bool hasTrivialDestructor,
+        size_t minimumInitialCapacity, float loadFactor) :
+        mBucketSize(entrySize + sizeof(Bucket)), mHasTrivialDestructor(hasTrivialDestructor),
+        mLoadFactor(loadFactor), mSize(0),
+        mFilledBuckets(0), mBuckets(NULL) {
+    determineCapacity(minimumInitialCapacity, mLoadFactor, &mBucketCount, &mCapacity);
+}
+
+BasicHashtableImpl::BasicHashtableImpl(const BasicHashtableImpl& other) :
+        mBucketSize(other.mBucketSize), mHasTrivialDestructor(other.mHasTrivialDestructor),
+        mCapacity(other.mCapacity), mLoadFactor(other.mLoadFactor),
+        mSize(other.mSize), mFilledBuckets(other.mFilledBuckets),
+        mBucketCount(other.mBucketCount), mBuckets(other.mBuckets) {
+    if (mBuckets) {
+        SharedBuffer::bufferFromData(mBuckets)->acquire();
+    }
+}
+
+void BasicHashtableImpl::dispose() {
+    if (mBuckets) {
+        releaseBuckets(mBuckets, mBucketCount);
+    }
+}
+
+void BasicHashtableImpl::clone() {
+    if (mBuckets) {
+        void* newBuckets = allocateBuckets(mBucketCount);
+        copyBuckets(mBuckets, newBuckets, mBucketCount);
+        releaseBuckets(mBuckets, mBucketCount);
+        mBuckets = newBuckets;
+    }
+}
+
+void BasicHashtableImpl::setTo(const BasicHashtableImpl& other) {
+    if (mBuckets) {
+        releaseBuckets(mBuckets, mBucketCount);
+    }
+
+    mCapacity = other.mCapacity;
+    mLoadFactor = other.mLoadFactor;
+    mSize = other.mSize;
+    mFilledBuckets = other.mFilledBuckets;
+    mBucketCount = other.mBucketCount;
+    mBuckets = other.mBuckets;
+
+    if (mBuckets) {
+        SharedBuffer::bufferFromData(mBuckets)->acquire();
+    }
+}
+
+void BasicHashtableImpl::clear() {
+    if (mBuckets) {
+        if (mFilledBuckets) {
+            SharedBuffer* sb = SharedBuffer::bufferFromData(mBuckets);
+            if (sb->onlyOwner()) {
+                destroyBuckets(mBuckets, mBucketCount);
+                for (size_t i = 0; i < mSize; i++) {
+                    Bucket& bucket = bucketAt(mBuckets, i);
+                    bucket.cookie = 0;
+                }
+            } else {
+                releaseBuckets(mBuckets, mBucketCount);
+                mBuckets = NULL;
+            }
+            mFilledBuckets = 0;
+        }
+        mSize = 0;
+    }
+}
+
+ssize_t BasicHashtableImpl::next(ssize_t index) const {
+    if (mSize) {
+        while (size_t(++index) < mBucketCount) {
+            const Bucket& bucket = bucketAt(mBuckets, index);
+            if (bucket.cookie & Bucket::PRESENT) {
+                return index;
+            }
+        }
+    }
+    return -1;
+}
+
+ssize_t BasicHashtableImpl::find(ssize_t index, hash_t hash,
+        const void* __restrict__ key) const {
+    if (!mSize) {
+        return -1;
+    }
+
+    hash = trimHash(hash);
+    if (index < 0) {
+        index = chainStart(hash, mBucketCount);
+
+        const Bucket& bucket = bucketAt(mBuckets, size_t(index));
+        if (bucket.cookie & Bucket::PRESENT) {
+            if (compareBucketKey(bucket, key)) {
+                return index;
+            }
+        } else {
+            if (!(bucket.cookie & Bucket::COLLISION)) {
+                return -1;
+            }
+        }
+    }
+
+    size_t inc = chainIncrement(hash, mBucketCount);
+    for (;;) {
+        index = chainSeek(index, inc, mBucketCount);
+
+        const Bucket& bucket = bucketAt(mBuckets, size_t(index));
+        if (bucket.cookie & Bucket::PRESENT) {
+            if ((bucket.cookie & Bucket::HASH_MASK) == hash
+                    && compareBucketKey(bucket, key)) {
+                return index;
+            }
+        }
+        if (!(bucket.cookie & Bucket::COLLISION)) {
+            return -1;
+        }
+    }
+}
+
+size_t BasicHashtableImpl::add(hash_t hash, const void* entry) {
+    if (!mBuckets) {
+        mBuckets = allocateBuckets(mBucketCount);
+    } else {
+        edit();
+    }
+
+    hash = trimHash(hash);
+    for (;;) {
+        size_t index = chainStart(hash, mBucketCount);
+        Bucket* bucket = &bucketAt(mBuckets, size_t(index));
+        if (bucket->cookie & Bucket::PRESENT) {
+            size_t inc = chainIncrement(hash, mBucketCount);
+            do {
+                bucket->cookie |= Bucket::COLLISION;
+                index = chainSeek(index, inc, mBucketCount);
+                bucket = &bucketAt(mBuckets, size_t(index));
+            } while (bucket->cookie & Bucket::PRESENT);
+        }
+
+        uint32_t collision = bucket->cookie & Bucket::COLLISION;
+        if (!collision) {
+            if (mFilledBuckets >= mCapacity) {
+                rehash(mCapacity * 2, mLoadFactor);
+                continue;
+            }
+            mFilledBuckets += 1;
+        }
+
+        bucket->cookie = collision | Bucket::PRESENT | hash;
+        mSize += 1;
+        initializeBucketEntry(*bucket, entry);
+        return index;
+    }
+}
+
+void BasicHashtableImpl::removeAt(size_t index) {
+    edit();
+
+    Bucket& bucket = bucketAt(mBuckets, index);
+    bucket.cookie &= ~Bucket::PRESENT;
+    if (!(bucket.cookie & Bucket::COLLISION)) {
+        mFilledBuckets -= 1;
+    }
+    mSize -= 1;
+    if (!mHasTrivialDestructor) {
+        destroyBucketEntry(bucket);
+    }
+}
+
+void BasicHashtableImpl::rehash(size_t minimumCapacity, float loadFactor) {
+    if (minimumCapacity < mSize) {
+        minimumCapacity = mSize;
+    }
+    size_t newBucketCount, newCapacity;
+    determineCapacity(minimumCapacity, loadFactor, &newBucketCount, &newCapacity);
+
+    if (newBucketCount != mBucketCount || newCapacity != mCapacity) {
+        if (mBuckets) {
+            void* newBuckets;
+            if (mSize) {
+                newBuckets = allocateBuckets(newBucketCount);
+                for (size_t i = 0; i < mBucketCount; i++) {
+                    const Bucket& fromBucket = bucketAt(mBuckets, i);
+                    if (fromBucket.cookie & Bucket::PRESENT) {
+                        hash_t hash = fromBucket.cookie & Bucket::HASH_MASK;
+                        size_t index = chainStart(hash, newBucketCount);
+                        Bucket* toBucket = &bucketAt(newBuckets, size_t(index));
+                        if (toBucket->cookie & Bucket::PRESENT) {
+                            size_t inc = chainIncrement(hash, newBucketCount);
+                            do {
+                                toBucket->cookie |= Bucket::COLLISION;
+                                index = chainSeek(index, inc, newBucketCount);
+                                toBucket = &bucketAt(newBuckets, size_t(index));
+                            } while (toBucket->cookie & Bucket::PRESENT);
+                        }
+                        toBucket->cookie = Bucket::PRESENT | hash;
+                        initializeBucketEntry(*toBucket, fromBucket.entry);
+                    }
+                }
+            } else {
+                newBuckets = NULL;
+            }
+            releaseBuckets(mBuckets, mBucketCount);
+            mBuckets = newBuckets;
+            mFilledBuckets = mSize;
+        }
+        mBucketCount = newBucketCount;
+        mCapacity = newCapacity;
+    }
+    mLoadFactor = loadFactor;
+}
+
+void* BasicHashtableImpl::allocateBuckets(size_t count) const {
+    size_t bytes = count * mBucketSize;
+    SharedBuffer* sb = SharedBuffer::alloc(bytes);
+    LOG_ALWAYS_FATAL_IF(!sb, "Could not allocate %u bytes for hashtable with %u buckets.",
+            uint32_t(bytes), uint32_t(count));
+    void* buckets = sb->data();
+    for (size_t i = 0; i < count; i++) {
+        Bucket& bucket = bucketAt(buckets, i);
+        bucket.cookie = 0;
+    }
+    return buckets;
+}
+
+void BasicHashtableImpl::releaseBuckets(void* __restrict__ buckets, size_t count) const {
+    SharedBuffer* sb = SharedBuffer::bufferFromData(buckets);
+    if (sb->release(SharedBuffer::eKeepStorage) == 1) {
+        destroyBuckets(buckets, count);
+        SharedBuffer::dealloc(sb);
+    }
+}
+
+void BasicHashtableImpl::destroyBuckets(void* __restrict__ buckets, size_t count) const {
+    if (!mHasTrivialDestructor) {
+        for (size_t i = 0; i < count; i++) {
+            Bucket& bucket = bucketAt(buckets, i);
+            if (bucket.cookie & Bucket::PRESENT) {
+                destroyBucketEntry(bucket);
+            }
+        }
+    }
+}
+
+void BasicHashtableImpl::copyBuckets(const void* __restrict__ fromBuckets,
+        void* __restrict__ toBuckets, size_t count) const {
+    for (size_t i = 0; i < count; i++) {
+        const Bucket& fromBucket = bucketAt(fromBuckets, i);
+        Bucket& toBucket = bucketAt(toBuckets, i);
+        toBucket.cookie = fromBucket.cookie;
+        if (fromBucket.cookie & Bucket::PRESENT) {
+            initializeBucketEntry(toBucket, fromBucket.entry);
+        }
+    }
+}
+
+// Table of 31-bit primes where each prime is no less than twice as large
+// as the previous one.  Generated by "primes.py".
+static size_t PRIMES[] = {
+    5,
+    11,
+    23,
+    47,
+    97,
+    197,
+    397,
+    797,
+    1597,
+    3203,
+    6421,
+    12853,
+    25717,
+    51437,
+    102877,
+    205759,
+    411527,
+    823117,
+    1646237,
+    3292489,
+    6584983,
+    13169977,
+    26339969,
+    52679969,
+    105359939,
+    210719881,
+    421439783,
+    842879579,
+    1685759167,
+    0,
+};
+
+void BasicHashtableImpl::determineCapacity(size_t minimumCapacity, float loadFactor,
+        size_t* __restrict__ outBucketCount, size_t* __restrict__ outCapacity) {
+    LOG_ALWAYS_FATAL_IF(loadFactor <= 0.0f || loadFactor > 1.0f,
+            "Invalid load factor %0.3f.  Must be in the range (0, 1].", loadFactor);
+
+    size_t count = ceilf(minimumCapacity / loadFactor) + 1;
+    size_t i = 0;
+    while (count > PRIMES[i] && i < NELEM(PRIMES)) {
+        i++;
+    }
+    count = PRIMES[i];
+    LOG_ALWAYS_FATAL_IF(!count, "Could not determine required number of buckets for "
+            "hashtable with minimum capacity %u and load factor %0.3f.",
+            uint32_t(minimumCapacity), loadFactor);
+    *outBucketCount = count;
+    *outCapacity = ceilf((count - 1) * loadFactor);
+}
+
+}; // namespace android
diff --git a/libs/utils/CallStack.cpp b/libs/utils/CallStack.cpp
index b4c581b..c2a5e55 100644
--- a/libs/utils/CallStack.cpp
+++ b/libs/utils/CallStack.cpp
@@ -101,17 +101,10 @@
 
     get_backtrace_symbols(mStack, mCount, symbols);
     for (size_t i = 0; i < mCount; i++) {
-        const backtrace_frame_t& frame = mStack[i];
-        const backtrace_symbol_t& symbol = symbols[i];
-        const char* mapName = symbol.map_name ? symbol.map_name : "<unknown>";
-        const char* symbolName = symbol.demangled_name ? symbol.demangled_name : symbol.name;
-        if (symbolName) {
-            LOGD("%s#%02d  pc %08x  %s (%s)\n", prefix,
-                    int(i), uint32_t(symbol.relative_pc), mapName, symbolName);
-        } else {
-            LOGD("%s#%02d  pc %08x  %s\n", prefix,
-                    int(i), uint32_t(symbol.relative_pc), mapName);
-        }
+        char line[MAX_BACKTRACE_LINE_LENGTH];
+        format_backtrace_line(i, &mStack[i], &symbols[i],
+                line, MAX_BACKTRACE_LINE_LENGTH);
+        LOGD("%s%s", prefix, line);
     }
     free_backtrace_symbols(symbols, mCount);
 }
@@ -122,17 +115,12 @@
 
     get_backtrace_symbols(mStack, mCount, symbols);
     for (size_t i = 0; i < mCount; i++) {
-        const backtrace_frame_t& frame = mStack[i];
-        const backtrace_symbol_t& symbol = symbols[i];
-        const char* mapName = symbol.map_name ? symbol.map_name : "<unknown>";
-        const char* symbolName = symbol.demangled_name ? symbol.demangled_name : symbol.name;
-        if (symbolName) {
-            str.appendFormat("%s#%02d  pc %08x  %s (%s)\n", prefix,
-                    int(i), uint32_t(symbol.relative_pc), mapName, symbolName);
-        } else {
-            str.appendFormat("%s#%02d  pc %08x  %s\n", prefix,
-                    int(i), uint32_t(symbol.relative_pc), mapName);
-        }
+        char line[MAX_BACKTRACE_LINE_LENGTH];
+        format_backtrace_line(i, &mStack[i], &symbols[i],
+                line, MAX_BACKTRACE_LINE_LENGTH);
+        str.append(prefix);
+        str.append(line);
+        str.append("\n");
     }
     free_backtrace_symbols(symbols, mCount);
     return str;
diff --git a/libs/utils/primes.py b/libs/utils/primes.py
new file mode 100755
index 0000000..e161dd8
--- /dev/null
+++ b/libs/utils/primes.py
@@ -0,0 +1,47 @@
+#!/usr/bin/env python2.6
+#
+# 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.
+#
+
+#
+# Generates a table of prime numbers for use in BasicHashtable.cpp.
+#
+# Each prime is chosen such that it is a little more than twice as large as
+# the previous prime in the table.  This makes it easier to choose a new
+# hashtable size when the underlying array is grown by as nominal factor
+# of two each time.
+#
+
+def is_odd_prime(n):
+  limit = (n - 1) / 2
+  d = 3
+  while d <= limit:
+    if n % d == 0:
+      return False
+    d += 2
+  return True
+
+print "static size_t PRIMES[] = {"
+
+n = 5
+max = 2**31 - 1
+while n < max:
+  print "    %d," % (n)
+  n = n * 2 + 1
+  while not is_odd_prime(n):
+    n += 2
+
+print "    0,"
+print "};"
diff --git a/libs/utils/tests/Android.mk b/libs/utils/tests/Android.mk
index b97f52f..58230f4 100644
--- a/libs/utils/tests/Android.mk
+++ b/libs/utils/tests/Android.mk
@@ -4,9 +4,10 @@
 
 # Build the unit tests.
 test_src_files := \
+	BasicHashtable_test.cpp \
 	BlobCache_test.cpp \
-	ObbFile_test.cpp \
 	Looper_test.cpp \
+	ObbFile_test.cpp \
 	String8_test.cpp \
 	Unicode_test.cpp \
 	ZipFileRO_test.cpp \
diff --git a/libs/utils/tests/BasicHashtable_test.cpp b/libs/utils/tests/BasicHashtable_test.cpp
new file mode 100644
index 0000000..764082d
--- /dev/null
+++ b/libs/utils/tests/BasicHashtable_test.cpp
@@ -0,0 +1,577 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "BasicHashtable_test"
+
+#include <utils/BasicHashtable.h>
+#include <cutils/log.h>
+#include <gtest/gtest.h>
+#include <unistd.h>
+
+namespace android {
+
+typedef int SimpleKey;
+typedef int SimpleValue;
+typedef key_value_pair_t<SimpleKey, SimpleValue> SimpleEntry;
+typedef BasicHashtable<SimpleKey, SimpleEntry> SimpleHashtable;
+
+struct ComplexKey {
+    int k;
+
+    explicit ComplexKey(int k) : k(k) {
+        instanceCount += 1;
+    }
+
+    ComplexKey(const ComplexKey& other) : k(other.k) {
+        instanceCount += 1;
+    }
+
+    ~ComplexKey() {
+        instanceCount -= 1;
+    }
+
+    bool operator ==(const ComplexKey& other) const {
+        return k == other.k;
+    }
+
+    bool operator !=(const ComplexKey& other) const {
+        return k != other.k;
+    }
+
+    static ssize_t instanceCount;
+};
+
+ssize_t ComplexKey::instanceCount = 0;
+
+template<> inline hash_t hash_type(const ComplexKey& value) {
+    return hash_type(value.k);
+}
+
+struct ComplexValue {
+    int v;
+
+    explicit ComplexValue(int v) : v(v) {
+        instanceCount += 1;
+    }
+
+    ComplexValue(const ComplexValue& other) : v(other.v) {
+        instanceCount += 1;
+    }
+
+    ~ComplexValue() {
+        instanceCount -= 1;
+    }
+
+    static ssize_t instanceCount;
+};
+
+ssize_t ComplexValue::instanceCount = 0;
+
+typedef key_value_pair_t<ComplexKey, ComplexValue> ComplexEntry;
+typedef BasicHashtable<ComplexKey, ComplexEntry> ComplexHashtable;
+
+class BasicHashtableTest : public testing::Test {
+protected:
+    virtual void SetUp() {
+        ComplexKey::instanceCount = 0;
+        ComplexValue::instanceCount = 0;
+    }
+
+    virtual void TearDown() {
+        ASSERT_NO_FATAL_FAILURE(assertInstanceCount(0, 0));
+    }
+
+    void assertInstanceCount(ssize_t keys, ssize_t values) {
+        if (keys != ComplexKey::instanceCount || values != ComplexValue::instanceCount) {
+            FAIL() << "Expected " << keys << " keys and " << values << " values "
+                    "but there were actually " << ComplexKey::instanceCount << " keys and "
+                    << ComplexValue::instanceCount << " values";
+        }
+    }
+
+public:
+    template <typename TKey, typename TEntry>
+    static void cookieAt(const BasicHashtable<TKey, TEntry>& h, size_t index,
+            bool* collision, bool* present, hash_t* hash) {
+        uint32_t cookie = h.cookieAt(index);
+        *collision = cookie & BasicHashtable<TKey, TEntry>::Bucket::COLLISION;
+        *present = cookie & BasicHashtable<TKey, TEntry>::Bucket::PRESENT;
+        *hash = cookie & BasicHashtable<TKey, TEntry>::Bucket::HASH_MASK;
+    }
+
+    template <typename TKey, typename TEntry>
+    static const void* getBuckets(const BasicHashtable<TKey, TEntry>& h) {
+        return h.mBuckets;
+    }
+};
+
+template <typename TKey, typename TValue>
+static size_t add(BasicHashtable<TKey, key_value_pair_t<TKey, TValue> >& h,
+        const TKey& key, const TValue& value) {
+    return h.add(hash_type(key), key_value_pair_t<TKey, TValue>(key, value));
+}
+
+template <typename TKey, typename TValue>
+static ssize_t find(BasicHashtable<TKey, key_value_pair_t<TKey, TValue> >& h,
+        ssize_t index, const TKey& key) {
+    return h.find(index, hash_type(key), key);
+}
+
+template <typename TKey, typename TValue>
+static bool remove(BasicHashtable<TKey, key_value_pair_t<TKey, TValue> >& h,
+        const TKey& key) {
+    ssize_t index = find(h, -1, key);
+    if (index >= 0) {
+        h.removeAt(index);
+        return true;
+    }
+    return false;
+}
+
+template <typename TEntry>
+static void getKeyValue(const TEntry& entry, int* key, int* value);
+
+template <> void getKeyValue(const SimpleEntry& entry, int* key, int* value) {
+    *key = entry.key;
+    *value = entry.value;
+}
+
+template <> void getKeyValue(const ComplexEntry& entry, int* key, int* value) {
+    *key = entry.key.k;
+    *value = entry.value.v;
+}
+
+template <typename TKey, typename TValue>
+static void dump(BasicHashtable<TKey, key_value_pair_t<TKey, TValue> >& h) {
+    LOGD("hashtable %p, size=%u, capacity=%u, bucketCount=%u",
+            &h, h.size(), h.capacity(), h.bucketCount());
+    for (size_t i = 0; i < h.bucketCount(); i++) {
+        bool collision, present;
+        hash_t hash;
+        BasicHashtableTest::cookieAt(h, i, &collision, &present, &hash);
+        if (present) {
+            int key, value;
+            getKeyValue(h.entryAt(i), &key, &value);
+            LOGD("  [%3u] = collision=%d, present=%d, hash=0x%08x, key=%3d, value=%3d, "
+                    "hash_type(key)=0x%08x",
+                    i, collision, present, hash, key, value, hash_type(key));
+        } else {
+            LOGD("  [%3u] = collision=%d, present=%d",
+                    i, collision, present);
+        }
+    }
+}
+
+TEST_F(BasicHashtableTest, DefaultConstructor_WithDefaultProperties) {
+    SimpleHashtable h;
+
+    EXPECT_EQ(0U, h.size());
+    EXPECT_EQ(3U, h.capacity());
+    EXPECT_EQ(5U, h.bucketCount());
+    EXPECT_EQ(0.75f, h.loadFactor());
+}
+
+TEST_F(BasicHashtableTest, Constructor_WithNonUnityLoadFactor) {
+    SimpleHashtable h(52, 0.8f);
+
+    EXPECT_EQ(0U, h.size());
+    EXPECT_EQ(77U, h.capacity());
+    EXPECT_EQ(97U, h.bucketCount());
+    EXPECT_EQ(0.8f, h.loadFactor());
+}
+
+TEST_F(BasicHashtableTest, Constructor_WithUnityLoadFactorAndExactCapacity) {
+    SimpleHashtable h(46, 1.0f);
+
+    EXPECT_EQ(0U, h.size());
+    EXPECT_EQ(46U, h.capacity()); // must be one less than bucketCount because loadFactor == 1.0f
+    EXPECT_EQ(47U, h.bucketCount());
+    EXPECT_EQ(1.0f, h.loadFactor());
+}
+
+TEST_F(BasicHashtableTest, Constructor_WithUnityLoadFactorAndInexactCapacity) {
+    SimpleHashtable h(42, 1.0f);
+
+    EXPECT_EQ(0U, h.size());
+    EXPECT_EQ(46U, h.capacity()); // must be one less than bucketCount because loadFactor == 1.0f
+    EXPECT_EQ(47U, h.bucketCount());
+    EXPECT_EQ(1.0f, h.loadFactor());
+}
+
+TEST_F(BasicHashtableTest, FindAddFindRemoveFind_OneEntry) {
+    SimpleHashtable h;
+    ssize_t index = find(h, -1, 8);
+    ASSERT_EQ(-1, index);
+
+    index = add(h, 8, 1);
+    ASSERT_EQ(1U, h.size());
+
+    ASSERT_EQ(index, find(h, -1, 8));
+    ASSERT_EQ(8, h.entryAt(index).key);
+    ASSERT_EQ(1, h.entryAt(index).value);
+
+    index = find(h, index, 8);
+    ASSERT_EQ(-1, index);
+
+    ASSERT_TRUE(remove(h, 8));
+    ASSERT_EQ(0U, h.size());
+
+    index = find(h, -1, 8);
+    ASSERT_EQ(-1, index);
+}
+
+TEST_F(BasicHashtableTest, FindAddFindRemoveFind_MultipleEntryWithUniqueKey) {
+    const size_t N = 11;
+
+    SimpleHashtable h;
+    for (size_t i = 0; i < N; i++) {
+        ssize_t index = find(h, -1, int(i));
+        ASSERT_EQ(-1, index);
+
+        index = add(h, int(i), int(i * 10));
+        ASSERT_EQ(i + 1, h.size());
+
+        ASSERT_EQ(index, find(h, -1, int(i)));
+        ASSERT_EQ(int(i), h.entryAt(index).key);
+        ASSERT_EQ(int(i * 10), h.entryAt(index).value);
+
+        index = find(h, index, int(i));
+        ASSERT_EQ(-1, index);
+    }
+
+    for (size_t i = N; --i > 0; ) {
+        ASSERT_TRUE(remove(h, int(i))) << "i = " << i;
+        ASSERT_EQ(i, h.size());
+
+        ssize_t index = find(h, -1, int(i));
+        ASSERT_EQ(-1, index);
+    }
+}
+
+TEST_F(BasicHashtableTest, FindAddFindRemoveFind_MultipleEntryWithDuplicateKey) {
+    const size_t N = 11;
+    const int K = 1;
+
+    SimpleHashtable h;
+    for (size_t i = 0; i < N; i++) {
+        ssize_t index = find(h, -1, K);
+        if (i == 0) {
+            ASSERT_EQ(-1, index);
+        } else {
+            ASSERT_NE(-1, index);
+        }
+
+        add(h, K, int(i));
+        ASSERT_EQ(i + 1, h.size());
+
+        index = -1;
+        int values = 0;
+        for (size_t j = 0; j <= i; j++) {
+            index = find(h, index, K);
+            ASSERT_GE(index, 0);
+            ASSERT_EQ(K, h.entryAt(index).key);
+            values |= 1 << h.entryAt(index).value;
+        }
+        ASSERT_EQ(values, (1 << (i + 1)) - 1);
+
+        index = find(h, index, K);
+        ASSERT_EQ(-1, index);
+    }
+
+    for (size_t i = N; --i > 0; ) {
+        ASSERT_TRUE(remove(h, K)) << "i = " << i;
+        ASSERT_EQ(i, h.size());
+
+        ssize_t index = -1;
+        for (size_t j = 0; j < i; j++) {
+            index = find(h, index, K);
+            ASSERT_GE(index, 0);
+            ASSERT_EQ(K, h.entryAt(index).key);
+        }
+
+        index = find(h, index, K);
+        ASSERT_EQ(-1, index);
+    }
+}
+
+TEST_F(BasicHashtableTest, Clear_WhenAlreadyEmpty_DoesNothing) {
+    SimpleHashtable h;
+    h.clear();
+
+    EXPECT_EQ(0U, h.size());
+    EXPECT_EQ(3U, h.capacity());
+    EXPECT_EQ(5U, h.bucketCount());
+    EXPECT_EQ(0.75f, h.loadFactor());
+}
+
+TEST_F(BasicHashtableTest, Clear_AfterElementsAdded_RemovesThem) {
+    SimpleHashtable h;
+    add(h, 0, 0);
+    add(h, 1, 0);
+    h.clear();
+
+    EXPECT_EQ(0U, h.size());
+    EXPECT_EQ(3U, h.capacity());
+    EXPECT_EQ(5U, h.bucketCount());
+    EXPECT_EQ(0.75f, h.loadFactor());
+}
+
+TEST_F(BasicHashtableTest, Clear_AfterElementsAdded_DestroysThem) {
+    ComplexHashtable h;
+    add(h, ComplexKey(0), ComplexValue(0));
+    add(h, ComplexKey(1), ComplexValue(0));
+    ASSERT_NO_FATAL_FAILURE(assertInstanceCount(2, 2));
+
+    h.clear();
+    ASSERT_NO_FATAL_FAILURE(assertInstanceCount(0, 0));
+
+    EXPECT_EQ(0U, h.size());
+    EXPECT_EQ(3U, h.capacity());
+    EXPECT_EQ(5U, h.bucketCount());
+    EXPECT_EQ(0.75f, h.loadFactor());
+}
+
+TEST_F(BasicHashtableTest, Remove_AfterElementsAdded_DestroysThem) {
+    ComplexHashtable h;
+    add(h, ComplexKey(0), ComplexValue(0));
+    add(h, ComplexKey(1), ComplexValue(0));
+    ASSERT_NO_FATAL_FAILURE(assertInstanceCount(2, 2));
+
+    ASSERT_TRUE(remove(h, ComplexKey(0)));
+    ASSERT_NO_FATAL_FAILURE(assertInstanceCount(1, 1));
+
+    ASSERT_TRUE(remove(h, ComplexKey(1)));
+    ASSERT_NO_FATAL_FAILURE(assertInstanceCount(0, 0));
+
+    EXPECT_EQ(0U, h.size());
+    EXPECT_EQ(3U, h.capacity());
+    EXPECT_EQ(5U, h.bucketCount());
+    EXPECT_EQ(0.75f, h.loadFactor());
+}
+
+TEST_F(BasicHashtableTest, Destructor_AfterElementsAdded_DestroysThem) {
+    {
+        ComplexHashtable h;
+        add(h, ComplexKey(0), ComplexValue(0));
+        add(h, ComplexKey(1), ComplexValue(0));
+        ASSERT_NO_FATAL_FAILURE(assertInstanceCount(2, 2));
+    } // h is destroyed here
+
+    ASSERT_NO_FATAL_FAILURE(assertInstanceCount(0, 0));
+}
+
+TEST_F(BasicHashtableTest, Next_WhenEmpty_ReturnsMinusOne) {
+    SimpleHashtable h;
+
+    ASSERT_EQ(-1, h.next(-1));
+}
+
+TEST_F(BasicHashtableTest, Next_WhenNonEmpty_IteratesOverAllEntries) {
+    const int N = 88;
+
+    SimpleHashtable h;
+    for (int i = 0; i < N; i++) {
+        add(h, i, i * 10);
+    }
+
+    bool set[N];
+    memset(set, 0, sizeof(bool) * N);
+    int count = 0;
+    for (ssize_t index = -1; (index = h.next(index)) != -1; ) {
+        ASSERT_GE(index, 0);
+        ASSERT_LT(size_t(index), h.bucketCount());
+
+        const SimpleEntry& entry = h.entryAt(index);
+        ASSERT_GE(entry.key, 0);
+        ASSERT_LT(entry.key, N);
+        ASSERT_EQ(false, set[entry.key]);
+        ASSERT_EQ(entry.key * 10, entry.value);
+
+        set[entry.key] = true;
+        count += 1;
+    }
+    ASSERT_EQ(N, count);
+}
+
+TEST_F(BasicHashtableTest, Add_RehashesOnDemand) {
+    SimpleHashtable h;
+    size_t initialCapacity = h.capacity();
+    size_t initialBucketCount = h.bucketCount();
+
+    for (size_t i = 0; i < initialCapacity; i++) {
+        add(h, int(i), 0);
+    }
+
+    EXPECT_EQ(initialCapacity, h.size());
+    EXPECT_EQ(initialCapacity, h.capacity());
+    EXPECT_EQ(initialBucketCount, h.bucketCount());
+
+    add(h, -1, -1);
+
+    EXPECT_EQ(initialCapacity + 1, h.size());
+    EXPECT_GT(h.capacity(), initialCapacity);
+    EXPECT_GT(h.bucketCount(), initialBucketCount);
+    EXPECT_GT(h.bucketCount(), h.capacity());
+}
+
+TEST_F(BasicHashtableTest, Rehash_WhenCapacityAndBucketCountUnchanged_DoesNothing) {
+    ComplexHashtable h;
+    add(h, ComplexKey(0), ComplexValue(0));
+    const void* oldBuckets = getBuckets(h);
+    ASSERT_NE((void*)NULL, oldBuckets);
+    ASSERT_NO_FATAL_FAILURE(assertInstanceCount(1, 1));
+
+    h.rehash(h.capacity(), h.loadFactor());
+
+    ASSERT_EQ(oldBuckets, getBuckets(h));
+    ASSERT_NO_FATAL_FAILURE(assertInstanceCount(1, 1));
+}
+
+TEST_F(BasicHashtableTest, Rehash_WhenEmptyAndHasNoBuckets_ButDoesNotAllocateBuckets) {
+    ComplexHashtable h;
+    ASSERT_EQ((void*)NULL, getBuckets(h));
+    ASSERT_NO_FATAL_FAILURE(assertInstanceCount(0, 0));
+
+    h.rehash(9, 1.0f);
+
+    EXPECT_EQ(0U, h.size());
+    EXPECT_EQ(10U, h.capacity());
+    EXPECT_EQ(11U, h.bucketCount());
+    EXPECT_EQ(1.0f, h.loadFactor());
+    EXPECT_EQ((void*)NULL, getBuckets(h));
+    ASSERT_NO_FATAL_FAILURE(assertInstanceCount(0, 0));
+}
+
+TEST_F(BasicHashtableTest, Rehash_WhenEmptyAndHasBuckets_ReleasesBucketsAndSetsCapacity) {
+    ComplexHashtable h(10);
+    add(h, ComplexKey(0), ComplexValue(0));
+    ASSERT_TRUE(remove(h, ComplexKey(0)));
+    ASSERT_NE((void*)NULL, getBuckets(h));
+    ASSERT_NO_FATAL_FAILURE(assertInstanceCount(0, 0));
+
+    h.rehash(0, 0.75f);
+
+    EXPECT_EQ(0U, h.size());
+    EXPECT_EQ(3U, h.capacity());
+    EXPECT_EQ(5U, h.bucketCount());
+    EXPECT_EQ(0.75f, h.loadFactor());
+    EXPECT_EQ((void*)NULL, getBuckets(h));
+    ASSERT_NO_FATAL_FAILURE(assertInstanceCount(0, 0));
+}
+
+TEST_F(BasicHashtableTest, Rehash_WhenLessThanCurrentCapacity_ShrinksBuckets) {
+    ComplexHashtable h(10);
+    add(h, ComplexKey(0), ComplexValue(0));
+    add(h, ComplexKey(1), ComplexValue(1));
+    const void* oldBuckets = getBuckets(h);
+    ASSERT_NO_FATAL_FAILURE(assertInstanceCount(2, 2));
+
+    h.rehash(0, 0.75f);
+
+    EXPECT_EQ(2U, h.size());
+    EXPECT_EQ(3U, h.capacity());
+    EXPECT_EQ(5U, h.bucketCount());
+    EXPECT_EQ(0.75f, h.loadFactor());
+    EXPECT_NE(oldBuckets, getBuckets(h));
+    ASSERT_NO_FATAL_FAILURE(assertInstanceCount(2, 2));
+}
+
+TEST_F(BasicHashtableTest, CopyOnWrite) {
+    ComplexHashtable h1;
+    add(h1, ComplexKey(0), ComplexValue(0));
+    add(h1, ComplexKey(1), ComplexValue(1));
+    const void* originalBuckets = getBuckets(h1);
+    ASSERT_NO_FATAL_FAILURE(assertInstanceCount(2, 2));
+    ssize_t index0 = find(h1, -1, ComplexKey(0));
+    EXPECT_GE(index0, 0);
+
+    // copy constructor acquires shared reference
+    ComplexHashtable h2(h1);
+    ASSERT_NO_FATAL_FAILURE(assertInstanceCount(2, 2));
+    ASSERT_EQ(originalBuckets, getBuckets(h2));
+    EXPECT_EQ(h1.size(), h2.size());
+    EXPECT_EQ(h1.capacity(), h2.capacity());
+    EXPECT_EQ(h1.bucketCount(), h2.bucketCount());
+    EXPECT_EQ(h1.loadFactor(), h2.loadFactor());
+    EXPECT_EQ(index0, find(h2, -1, ComplexKey(0)));
+
+    // operator= acquires shared reference
+    ComplexHashtable h3;
+    h3 = h2;
+    ASSERT_NO_FATAL_FAILURE(assertInstanceCount(2, 2));
+    ASSERT_EQ(originalBuckets, getBuckets(h3));
+    EXPECT_EQ(h1.size(), h3.size());
+    EXPECT_EQ(h1.capacity(), h3.capacity());
+    EXPECT_EQ(h1.bucketCount(), h3.bucketCount());
+    EXPECT_EQ(h1.loadFactor(), h3.loadFactor());
+    EXPECT_EQ(index0, find(h3, -1, ComplexKey(0)));
+
+    // editEntryAt copies shared contents
+    h1.editEntryAt(index0).value.v = 42;
+    ASSERT_NO_FATAL_FAILURE(assertInstanceCount(4, 4));
+    ASSERT_NE(originalBuckets, getBuckets(h1));
+    EXPECT_EQ(42, h1.entryAt(index0).value.v);
+    EXPECT_EQ(0, h2.entryAt(index0).value.v);
+    EXPECT_EQ(0, h3.entryAt(index0).value.v);
+
+    // clear releases reference to shared contents
+    h2.clear();
+    ASSERT_NO_FATAL_FAILURE(assertInstanceCount(4, 4));
+    EXPECT_EQ(0U, h2.size());
+    ASSERT_NE(originalBuckets, getBuckets(h2));
+
+    // operator= acquires shared reference, destroys unshared contents
+    h1 = h3;
+    ASSERT_NO_FATAL_FAILURE(assertInstanceCount(2, 2));
+    ASSERT_EQ(originalBuckets, getBuckets(h1));
+    EXPECT_EQ(h3.size(), h1.size());
+    EXPECT_EQ(h3.capacity(), h1.capacity());
+    EXPECT_EQ(h3.bucketCount(), h1.bucketCount());
+    EXPECT_EQ(h3.loadFactor(), h1.loadFactor());
+    EXPECT_EQ(index0, find(h1, -1, ComplexKey(0)));
+
+    // add copies shared contents
+    add(h1, ComplexKey(2), ComplexValue(2));
+    ASSERT_NO_FATAL_FAILURE(assertInstanceCount(5, 5));
+    ASSERT_NE(originalBuckets, getBuckets(h1));
+    EXPECT_EQ(3U, h1.size());
+    EXPECT_EQ(0U, h2.size());
+    EXPECT_EQ(2U, h3.size());
+
+    // remove copies shared contents
+    h1 = h3;
+    ASSERT_NO_FATAL_FAILURE(assertInstanceCount(2, 2));
+    ASSERT_EQ(originalBuckets, getBuckets(h1));
+    h1.removeAt(index0);
+    ASSERT_NO_FATAL_FAILURE(assertInstanceCount(3, 3));
+    ASSERT_NE(originalBuckets, getBuckets(h1));
+    EXPECT_EQ(1U, h1.size());
+    EXPECT_EQ(0U, h2.size());
+    EXPECT_EQ(2U, h3.size());
+
+    // rehash copies shared contents
+    h1 = h3;
+    ASSERT_NO_FATAL_FAILURE(assertInstanceCount(2, 2));
+    ASSERT_EQ(originalBuckets, getBuckets(h1));
+    h1.rehash(10, 1.0f);
+    ASSERT_NO_FATAL_FAILURE(assertInstanceCount(4, 4));
+    ASSERT_NE(originalBuckets, getBuckets(h1));
+    EXPECT_EQ(2U, h1.size());
+    EXPECT_EQ(0U, h2.size());
+    EXPECT_EQ(2U, h3.size());
+}
+
+} // namespace android
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index a0881a7..936ec0f 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -22,8 +22,6 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
-import android.database.ContentObserver;
-import android.graphics.Bitmap;
 import android.os.Binder;
 import android.os.Handler;
 import android.os.IBinder;
@@ -37,7 +35,6 @@
 import android.view.KeyEvent;
 import android.view.VolumePanel;
 
-import java.util.Iterator;
 import java.util.HashMap;
 
 /**
@@ -49,11 +46,9 @@
 public class AudioManager {
 
     private final Context mContext;
-    private final Handler mHandler;
     private long mVolumeKeyUpTime;
     private int  mVolumeControlStream = -1;
     private static String TAG = "AudioManager";
-    private static boolean localLOGV = false;
 
     /**
      * Broadcast intent, a hint for applications that audio is about to become
@@ -359,7 +354,6 @@
      */
     public AudioManager(Context context) {
         mContext = context;
-        mHandler = new Handler(context.getMainLooper());
     }
 
     private static IAudioService getService()
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index f13a6a2..c201417 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -508,8 +508,8 @@
 
         // Play sounds on STREAM_RING only and if lock screen is not on.
         if ((flags & AudioManager.FLAG_PLAY_SOUND) != 0 &&
-                ((STREAM_VOLUME_ALIAS[streamType] != AudioSystem.STREAM_RING) ||
-                 (mKeyguardManager != null && mKeyguardManager.isKeyguardLocked()))) {
+                ((STREAM_VOLUME_ALIAS[streamType] != AudioSystem.STREAM_RING)
+                 || (mKeyguardManager != null && mKeyguardManager.isKeyguardLocked()))) {
             flags &= ~AudioManager.FLAG_PLAY_SOUND;
         }
 
@@ -1572,49 +1572,83 @@
     private BluetoothProfile.ServiceListener mBluetoothProfileServiceListener =
         new BluetoothProfile.ServiceListener() {
         public void onServiceConnected(int profile, BluetoothProfile proxy) {
-            synchronized (mScoClients) {
-                // Discard timeout message
-                mAudioHandler.removeMessages(MSG_BT_HEADSET_CNCT_FAILED);
-                mBluetoothHeadset = (BluetoothHeadset) proxy;
-                List<BluetoothDevice> deviceList = mBluetoothHeadset.getConnectedDevices();
+            BluetoothDevice btDevice;
+            List<BluetoothDevice> deviceList;
+            switch(profile) {
+            case BluetoothProfile.A2DP:
+                BluetoothA2dp a2dp = (BluetoothA2dp) proxy;
+                deviceList = a2dp.getConnectedDevices();
                 if (deviceList.size() > 0) {
-                    mBluetoothHeadsetDevice = deviceList.get(0);
-                } else {
-                    mBluetoothHeadsetDevice = null;
+                    btDevice = deviceList.get(0);
+                    handleA2dpConnectionStateChange(btDevice, a2dp.getConnectionState(btDevice));
                 }
-                // Refresh SCO audio state
-                checkScoAudioState();
-                // Continue pending action if any
-                if (mScoAudioState == SCO_STATE_ACTIVATE_REQ ||
-                        mScoAudioState == SCO_STATE_DEACTIVATE_REQ ||
-                        mScoAudioState == SCO_STATE_DEACTIVATE_EXT_REQ) {
-                    boolean status = false;
-                    if (mBluetoothHeadsetDevice != null) {
-                        switch (mScoAudioState) {
-                        case SCO_STATE_ACTIVATE_REQ:
-                            mScoAudioState = SCO_STATE_ACTIVE_INTERNAL;
-                            status = mBluetoothHeadset.startScoUsingVirtualVoiceCall(
-                                    mBluetoothHeadsetDevice);
-                            break;
-                        case SCO_STATE_DEACTIVATE_REQ:
-                            status = mBluetoothHeadset.stopScoUsingVirtualVoiceCall(
-                                    mBluetoothHeadsetDevice);
-                            break;
-                        case SCO_STATE_DEACTIVATE_EXT_REQ:
-                            status = mBluetoothHeadset.stopVoiceRecognition(
-                                    mBluetoothHeadsetDevice);
+                break;
+
+            case BluetoothProfile.HEADSET:
+                synchronized (mScoClients) {
+                    // Discard timeout message
+                    mAudioHandler.removeMessages(MSG_BT_HEADSET_CNCT_FAILED);
+                    mBluetoothHeadset = (BluetoothHeadset) proxy;
+                    deviceList = mBluetoothHeadset.getConnectedDevices();
+                    if (deviceList.size() > 0) {
+                        mBluetoothHeadsetDevice = deviceList.get(0);
+                    } else {
+                        mBluetoothHeadsetDevice = null;
+                    }
+                    // Refresh SCO audio state
+                    checkScoAudioState();
+                    // Continue pending action if any
+                    if (mScoAudioState == SCO_STATE_ACTIVATE_REQ ||
+                            mScoAudioState == SCO_STATE_DEACTIVATE_REQ ||
+                            mScoAudioState == SCO_STATE_DEACTIVATE_EXT_REQ) {
+                        boolean status = false;
+                        if (mBluetoothHeadsetDevice != null) {
+                            switch (mScoAudioState) {
+                            case SCO_STATE_ACTIVATE_REQ:
+                                mScoAudioState = SCO_STATE_ACTIVE_INTERNAL;
+                                status = mBluetoothHeadset.startScoUsingVirtualVoiceCall(
+                                        mBluetoothHeadsetDevice);
+                                break;
+                            case SCO_STATE_DEACTIVATE_REQ:
+                                status = mBluetoothHeadset.stopScoUsingVirtualVoiceCall(
+                                        mBluetoothHeadsetDevice);
+                                break;
+                            case SCO_STATE_DEACTIVATE_EXT_REQ:
+                                status = mBluetoothHeadset.stopVoiceRecognition(
+                                        mBluetoothHeadsetDevice);
+                            }
+                        }
+                        if (!status) {
+                            sendMsg(mAudioHandler, MSG_BT_HEADSET_CNCT_FAILED, 0,
+                                    SENDMSG_REPLACE, 0, 0, null, 0);
                         }
                     }
-                    if (!status) {
-                        sendMsg(mAudioHandler, MSG_BT_HEADSET_CNCT_FAILED, 0,
-                                SENDMSG_REPLACE, 0, 0, null, 0);
-                    }
                 }
+                break;
+
+            default:
+                break;
             }
         }
         public void onServiceDisconnected(int profile) {
-            synchronized (mScoClients) {
-                mBluetoothHeadset = null;
+            switch(profile) {
+            case BluetoothProfile.A2DP:
+                synchronized (mConnectedDevices) {
+                    if (mConnectedDevices.containsKey(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP)) {
+                        makeA2dpDeviceUnavailableNow(
+                                mConnectedDevices.get(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP));
+                    }
+                }
+                break;
+
+            case BluetoothProfile.HEADSET:
+                synchronized (mScoClients) {
+                    mBluetoothHeadset = null;
+                }
+                break;
+
+            default:
+                break;
             }
         }
     };
@@ -2191,15 +2225,17 @@
                     AudioSystem.setParameters("restarting=true");
 
                     // Restore device connection states
-                    Set set = mConnectedDevices.entrySet();
-                    Iterator i = set.iterator();
-                    while(i.hasNext()){
-                        Map.Entry device = (Map.Entry)i.next();
-                        AudioSystem.setDeviceConnectionState(((Integer)device.getKey()).intValue(),
-                                                             AudioSystem.DEVICE_STATE_AVAILABLE,
-                                                             (String)device.getValue());
+                    synchronized (mConnectedDevices) {
+                        Set set = mConnectedDevices.entrySet();
+                        Iterator i = set.iterator();
+                        while(i.hasNext()){
+                            Map.Entry device = (Map.Entry)i.next();
+                            AudioSystem.setDeviceConnectionState(
+                                                            ((Integer)device.getKey()).intValue(),
+                                                            AudioSystem.DEVICE_STATE_AVAILABLE,
+                                                            (String)device.getValue());
+                        }
                     }
-
                     // Restore call state
                     AudioSystem.setPhoneState(mMode);
 
@@ -2238,7 +2274,9 @@
 
                 case MSG_BTA2DP_DOCK_TIMEOUT:
                     // msg.obj  == address of BTA2DP device
-                    makeA2dpDeviceUnavailableNow( (String) msg.obj );
+                    synchronized (mConnectedDevices) {
+                        makeA2dpDeviceUnavailableNow( (String) msg.obj );
+                    }
                     break;
 
                 case MSG_SET_FORCE_USE:
@@ -2298,6 +2336,7 @@
         }
     }
 
+    // must be called synchronized on mConnectedDevices
     private void makeA2dpDeviceAvailable(String address) {
         AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP,
                 AudioSystem.DEVICE_STATE_AVAILABLE,
@@ -2308,6 +2347,7 @@
                 address);
     }
 
+    // must be called synchronized on mConnectedDevices
     private void makeA2dpDeviceUnavailableNow(String address) {
         Intent noisyIntent = new Intent(AudioManager.ACTION_AUDIO_BECOMING_NOISY);
         mContext.sendBroadcast(noisyIntent);
@@ -2317,6 +2357,7 @@
         mConnectedDevices.remove(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP);
     }
 
+    // must be called synchronized on mConnectedDevices
     private void makeA2dpDeviceUnavailableLater(String address) {
         // prevent any activity on the A2DP audio output to avoid unwanted
         // reconnection of the sink.
@@ -2329,14 +2370,60 @@
 
     }
 
+    // must be called synchronized on mConnectedDevices
     private void cancelA2dpDeviceTimeout() {
         mAudioHandler.removeMessages(MSG_BTA2DP_DOCK_TIMEOUT);
     }
 
+    // must be called synchronized on mConnectedDevices
     private boolean hasScheduledA2dpDockTimeout() {
         return mAudioHandler.hasMessages(MSG_BTA2DP_DOCK_TIMEOUT);
     }
 
+    private void handleA2dpConnectionStateChange(BluetoothDevice btDevice, int state)
+    {
+        if (btDevice == null) {
+            return;
+        }
+        String address = btDevice.getAddress();
+        if (!BluetoothAdapter.checkBluetoothAddress(address)) {
+            address = "";
+        }
+        synchronized (mConnectedDevices) {
+            boolean isConnected =
+                (mConnectedDevices.containsKey(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP) &&
+                 mConnectedDevices.get(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP).equals(address));
+
+            if (isConnected && state != BluetoothProfile.STATE_CONNECTED) {
+                if (btDevice.isBluetoothDock()) {
+                    if (state == BluetoothProfile.STATE_DISCONNECTED) {
+                        // introduction of a delay for transient disconnections of docks when
+                        // power is rapidly turned off/on, this message will be canceled if
+                        // we reconnect the dock under a preset delay
+                        makeA2dpDeviceUnavailableLater(address);
+                        // the next time isConnected is evaluated, it will be false for the dock
+                    }
+                } else {
+                    makeA2dpDeviceUnavailableNow(address);
+                }
+            } else if (!isConnected && state == BluetoothProfile.STATE_CONNECTED) {
+                if (btDevice.isBluetoothDock()) {
+                    // this could be a reconnection after a transient disconnection
+                    cancelA2dpDeviceTimeout();
+                    mDockAddress = address;
+                } else {
+                    // this could be a connection of another A2DP device before the timeout of
+                    // a dock: cancel the dock timeout, and make the dock unavailable now
+                    if(hasScheduledA2dpDockTimeout()) {
+                        cancelA2dpDeviceTimeout();
+                        makeA2dpDeviceUnavailableNow(mDockAddress);
+                    }
+                }
+                makeA2dpDeviceAvailable(address);
+            }
+        }
+    }
+
     /* cache of the address of the last dock the device was connected to */
     private String mDockAddress;
 
@@ -2374,44 +2461,8 @@
                 int state = intent.getIntExtra(BluetoothProfile.EXTRA_STATE,
                                                BluetoothProfile.STATE_DISCONNECTED);
                 BluetoothDevice btDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
-                if (btDevice == null) {
-                    return;
-                }
-                String address = btDevice.getAddress();
-                if (!BluetoothAdapter.checkBluetoothAddress(address)) {
-                    address = "";
-                }
-                boolean isConnected =
-                    (mConnectedDevices.containsKey(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP) &&
-                     mConnectedDevices.get(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP).equals(address));
 
-                if (isConnected && state != BluetoothProfile.STATE_CONNECTED) {
-                    if (btDevice.isBluetoothDock()) {
-                        if (state == BluetoothProfile.STATE_DISCONNECTED) {
-                            // introduction of a delay for transient disconnections of docks when
-                            // power is rapidly turned off/on, this message will be canceled if
-                            // we reconnect the dock under a preset delay
-                            makeA2dpDeviceUnavailableLater(address);
-                            // the next time isConnected is evaluated, it will be false for the dock
-                        }
-                    } else {
-                        makeA2dpDeviceUnavailableNow(address);
-                    }
-                } else if (!isConnected && state == BluetoothProfile.STATE_CONNECTED) {
-                    if (btDevice.isBluetoothDock()) {
-                        // this could be a reconnection after a transient disconnection
-                        cancelA2dpDeviceTimeout();
-                        mDockAddress = address;
-                    } else {
-                        // this could be a connection of another A2DP device before the timeout of
-                        // a dock: cancel the dock timeout, and make the dock unavailable now
-                        if(hasScheduledA2dpDockTimeout()) {
-                            cancelA2dpDeviceTimeout();
-                            makeA2dpDeviceUnavailableNow(mDockAddress);
-                        }
-                    }
-                    makeA2dpDeviceAvailable(address);
-                }
+                handleA2dpConnectionStateChange(btDevice, state);
             } else if (action.equals(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED)) {
                 int state = intent.getIntExtra(BluetoothProfile.EXTRA_STATE,
                                                BluetoothProfile.STATE_DISCONNECTED);
@@ -2440,103 +2491,126 @@
                 if (!BluetoothAdapter.checkBluetoothAddress(address)) {
                     address = "";
                 }
-                boolean isConnected = (mConnectedDevices.containsKey(device) &&
-                                       mConnectedDevices.get(device).equals(address));
 
-                synchronized (mScoClients) {
-                    if (isConnected && state != BluetoothProfile.STATE_CONNECTED) {
-                        AudioSystem.setDeviceConnectionState(device,
+                synchronized (mConnectedDevices) {
+                    boolean isConnected = (mConnectedDevices.containsKey(device) &&
+                                           mConnectedDevices.get(device).equals(address));
+
+                    synchronized (mScoClients) {
+                        if (isConnected && state != BluetoothProfile.STATE_CONNECTED) {
+                            AudioSystem.setDeviceConnectionState(device,
                                                              AudioSystem.DEVICE_STATE_UNAVAILABLE,
                                                              address);
-                        mConnectedDevices.remove(device);
-                        mBluetoothHeadsetDevice = null;
-                        resetBluetoothSco();
-                    } else if (!isConnected && state == BluetoothProfile.STATE_CONNECTED) {
-                        AudioSystem.setDeviceConnectionState(device,
-                                                             AudioSystem.DEVICE_STATE_AVAILABLE,
-                                                             address);
-                        mConnectedDevices.put(new Integer(device), address);
-                        mBluetoothHeadsetDevice = btDevice;
+                            mConnectedDevices.remove(device);
+                            mBluetoothHeadsetDevice = null;
+                            resetBluetoothSco();
+                        } else if (!isConnected && state == BluetoothProfile.STATE_CONNECTED) {
+                            AudioSystem.setDeviceConnectionState(device,
+                                                                 AudioSystem.DEVICE_STATE_AVAILABLE,
+                                                                 address);
+                            mConnectedDevices.put(new Integer(device), address);
+                            mBluetoothHeadsetDevice = btDevice;
+                        }
                     }
                 }
             } else if (action.equals(Intent.ACTION_HEADSET_PLUG)) {
                 int state = intent.getIntExtra("state", 0);
                 int microphone = intent.getIntExtra("microphone", 0);
 
-                if (microphone != 0) {
-                    boolean isConnected =
-                        mConnectedDevices.containsKey(AudioSystem.DEVICE_OUT_WIRED_HEADSET);
-                    if (state == 0 && isConnected) {
-                        AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_WIRED_HEADSET,
-                                AudioSystem.DEVICE_STATE_UNAVAILABLE,
-                                "");
-                        mConnectedDevices.remove(AudioSystem.DEVICE_OUT_WIRED_HEADSET);
-                    } else if (state == 1 && !isConnected)  {
-                        AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_WIRED_HEADSET,
-                                AudioSystem.DEVICE_STATE_AVAILABLE,
-                                "");
-                        mConnectedDevices.put(
-                                new Integer(AudioSystem.DEVICE_OUT_WIRED_HEADSET), "");
-                    }
-                } else {
-                    boolean isConnected =
-                        mConnectedDevices.containsKey(AudioSystem.DEVICE_OUT_WIRED_HEADPHONE);
-                    if (state == 0 && isConnected) {
-                        AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_WIRED_HEADPHONE,
-                                AudioSystem.DEVICE_STATE_UNAVAILABLE,
-                                "");
-                        mConnectedDevices.remove(AudioSystem.DEVICE_OUT_WIRED_HEADPHONE);
-                    } else if (state == 1 && !isConnected)  {
-                        AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_WIRED_HEADPHONE,
-                                AudioSystem.DEVICE_STATE_AVAILABLE,
-                                "");
-                        mConnectedDevices.put(
-                                new Integer(AudioSystem.DEVICE_OUT_WIRED_HEADPHONE), "");
+                synchronized (mConnectedDevices) {
+                    if (microphone != 0) {
+                        boolean isConnected =
+                            mConnectedDevices.containsKey(AudioSystem.DEVICE_OUT_WIRED_HEADSET);
+                        if (state == 0 && isConnected) {
+                            AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_WIRED_HEADSET,
+                                    AudioSystem.DEVICE_STATE_UNAVAILABLE,
+                                    "");
+                            mConnectedDevices.remove(AudioSystem.DEVICE_OUT_WIRED_HEADSET);
+                        } else if (state == 1 && !isConnected)  {
+                            AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_WIRED_HEADSET,
+                                    AudioSystem.DEVICE_STATE_AVAILABLE,
+                                    "");
+                            mConnectedDevices.put(
+                                    new Integer(AudioSystem.DEVICE_OUT_WIRED_HEADSET), "");
+                        }
+                    } else {
+                        boolean isConnected =
+                            mConnectedDevices.containsKey(AudioSystem.DEVICE_OUT_WIRED_HEADPHONE);
+                        if (state == 0 && isConnected) {
+                            AudioSystem.setDeviceConnectionState(
+                                    AudioSystem.DEVICE_OUT_WIRED_HEADPHONE,
+                                    AudioSystem.DEVICE_STATE_UNAVAILABLE,
+                                    "");
+                            mConnectedDevices.remove(AudioSystem.DEVICE_OUT_WIRED_HEADPHONE);
+                        } else if (state == 1 && !isConnected)  {
+                            AudioSystem.setDeviceConnectionState(
+                                    AudioSystem.DEVICE_OUT_WIRED_HEADPHONE,
+                                    AudioSystem.DEVICE_STATE_AVAILABLE,
+                                    "");
+                            mConnectedDevices.put(
+                                    new Integer(AudioSystem.DEVICE_OUT_WIRED_HEADPHONE), "");
+                        }
                     }
                 }
             } else if (action.equals(Intent.ACTION_USB_ANLG_HEADSET_PLUG)) {
                 int state = intent.getIntExtra("state", 0);
                 Log.v(TAG, "Broadcast Receiver: Got ACTION_USB_ANLG_HEADSET_PLUG, state = "+state);
-                boolean isConnected =
-                    mConnectedDevices.containsKey(AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET);
-                if (state == 0 && isConnected) {
-                    AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET,
-                                                         AudioSystem.DEVICE_STATE_UNAVAILABLE, "");
-                    mConnectedDevices.remove(AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET);
-                } else if (state == 1 && !isConnected)  {
-                    AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET,
-                                                         AudioSystem.DEVICE_STATE_AVAILABLE, "");
-                    mConnectedDevices.put(
-                            new Integer(AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET), "");
+                synchronized (mConnectedDevices) {
+                    boolean isConnected =
+                        mConnectedDevices.containsKey(AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET);
+                    if (state == 0 && isConnected) {
+                        AudioSystem.setDeviceConnectionState(
+                                                        AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET,
+                                                        AudioSystem.DEVICE_STATE_UNAVAILABLE,
+                                                        "");
+                        mConnectedDevices.remove(AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET);
+                    } else if (state == 1 && !isConnected)  {
+                        AudioSystem.setDeviceConnectionState(
+                                                        AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET,
+                                                        AudioSystem.DEVICE_STATE_AVAILABLE,
+                                                        "");
+                        mConnectedDevices.put(
+                                new Integer(AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET), "");
+                    }
                 }
             } else if (action.equals(Intent.ACTION_HDMI_AUDIO_PLUG)) {
                 int state = intent.getIntExtra("state", 0);
                 Log.v(TAG, "Broadcast Receiver: Got ACTION_HDMI_AUDIO_PLUG, state = "+state);
-                boolean isConnected =
-                    mConnectedDevices.containsKey(AudioSystem.DEVICE_OUT_AUX_DIGITAL);
-                if (state == 0 && isConnected) {
-                    AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_AUX_DIGITAL,
-                                                         AudioSystem.DEVICE_STATE_UNAVAILABLE, "");
-                    mConnectedDevices.remove(AudioSystem.DEVICE_OUT_AUX_DIGITAL);
-                } else if (state == 1 && !isConnected)  {
-                    AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_AUX_DIGITAL,
-                                                         AudioSystem.DEVICE_STATE_AVAILABLE, "");
-                    mConnectedDevices.put( new Integer(AudioSystem.DEVICE_OUT_AUX_DIGITAL), "");
+                synchronized (mConnectedDevices) {
+                    boolean isConnected =
+                        mConnectedDevices.containsKey(AudioSystem.DEVICE_OUT_AUX_DIGITAL);
+                    if (state == 0 && isConnected) {
+                        AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_AUX_DIGITAL,
+                                                             AudioSystem.DEVICE_STATE_UNAVAILABLE,
+                                                             "");
+                        mConnectedDevices.remove(AudioSystem.DEVICE_OUT_AUX_DIGITAL);
+                    } else if (state == 1 && !isConnected)  {
+                        AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_AUX_DIGITAL,
+                                                             AudioSystem.DEVICE_STATE_AVAILABLE,
+                                                             "");
+                        mConnectedDevices.put( new Integer(AudioSystem.DEVICE_OUT_AUX_DIGITAL), "");
+                    }
                 }
             } else if (action.equals(Intent.ACTION_USB_DGTL_HEADSET_PLUG)) {
                 int state = intent.getIntExtra("state", 0);
                 Log.v(TAG, "Broadcast Receiver: Got ACTION_USB_DGTL_HEADSET_PLUG, state = "+state);
-                boolean isConnected =
-                    mConnectedDevices.containsKey(AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET);
-                if (state == 0 && isConnected) {
-                    AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET,
-                                                         AudioSystem.DEVICE_STATE_UNAVAILABLE, "");
-                    mConnectedDevices.remove(AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET);
-                } else if (state == 1 && !isConnected)  {
-                    AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET,
-                                                         AudioSystem.DEVICE_STATE_AVAILABLE, "");
-                    mConnectedDevices.put(
-                            new Integer(AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET), "");
+                synchronized (mConnectedDevices) {
+                    boolean isConnected =
+                        mConnectedDevices.containsKey(AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET);
+                    if (state == 0 && isConnected) {
+                        AudioSystem.setDeviceConnectionState(
+                                                         AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET,
+                                                         AudioSystem.DEVICE_STATE_UNAVAILABLE,
+                                                         "");
+                        mConnectedDevices.remove(AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET);
+                    } else if (state == 1 && !isConnected)  {
+                        AudioSystem.setDeviceConnectionState(
+                                                         AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET,
+                                                         AudioSystem.DEVICE_STATE_AVAILABLE,
+                                                         "");
+                        mConnectedDevices.put(
+                                new Integer(AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET), "");
+                    }
                 }
             } else if (action.equals(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED)) {
                 boolean broadcast = false;
@@ -2590,7 +2664,7 @@
                         0, 0, null, 0);
 
                 mKeyguardManager =
-                    (KeyguardManager)mContext.getSystemService(Context.KEYGUARD_SERVICE);
+                        (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE);
                 mScoConnectionState = AudioManager.SCO_AUDIO_STATE_ERROR;
                 resetBluetoothSco();
                 getBluetoothHeadset();
@@ -2600,6 +2674,12 @@
                 newIntent.putExtra(AudioManager.EXTRA_SCO_AUDIO_STATE,
                         AudioManager.SCO_AUDIO_STATE_DISCONNECTED);
                 mContext.sendStickyBroadcast(newIntent);
+
+                BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
+                if (adapter != null) {
+                    adapter.getProfileProxy(mContext, mBluetoothProfileServiceListener,
+                                            BluetoothProfile.A2DP);
+                }
             } else if (action.equals(Intent.ACTION_PACKAGE_REMOVED)) {
                 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
                     // a package is being removed, not replaced
@@ -3401,7 +3481,7 @@
         updateRemoteControlDisplay_syncAfRcs(infoChangedFlags);
     }
 
-    /** 
+    /**
      * see AudioManager.registerMediaButtonIntent(PendingIntent pi, ComponentName c)
      * precondition: mediaIntent != null, target != null
      */
@@ -3417,7 +3497,7 @@
         }
     }
 
-    /** 
+    /**
      * see AudioManager.unregisterMediaButtonIntent(PendingIntent mediaIntent)
      * precondition: mediaIntent != null, eventReceiver != null
      */
diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java
index 8d71dcf..4c70e9d 100644
--- a/media/java/android/media/MediaPlayer.java
+++ b/media/java/android/media/MediaPlayer.java
@@ -1735,6 +1735,9 @@
         /**
          * Called to indicate the video size
          *
+         * The video size (width and height) could be 0 if there was no video,
+         * no display surface was set, or the value was not determined yet.
+         *
          * @param mp        the MediaPlayer associated with this callback
          * @param width     the width of the video
          * @param height    the height of the video
diff --git a/media/java/android/media/videoeditor/MediaArtistNativeHelper.java b/media/java/android/media/videoeditor/MediaArtistNativeHelper.java
index 03ae62a..4756078 100644
--- a/media/java/android/media/videoeditor/MediaArtistNativeHelper.java
+++ b/media/java/android/media/videoeditor/MediaArtistNativeHelper.java
@@ -1845,7 +1845,7 @@
 
     @SuppressWarnings("unused")
     private void onPreviewProgressUpdate(int progress, boolean isFinished,
-                  boolean updateOverlay, String filename, int renderingMode) {
+                  boolean updateOverlay, String filename, int renderingMode, int error) {
         if (mPreviewProgressListener != null) {
             if (mIsFirstProgress) {
                 mPreviewProgressListener.onStart(mVideoEditor);
@@ -1870,6 +1870,8 @@
 
             if (isFinished) {
                 mPreviewProgressListener.onStop(mVideoEditor);
+            } else if (error != 0) {
+                mPreviewProgressListener.onError(mVideoEditor, error);
             } else {
                 mPreviewProgressListener.onProgress(mVideoEditor, progress, overlayData);
             }
diff --git a/media/java/android/media/videoeditor/VideoEditor.java b/media/java/android/media/videoeditor/VideoEditor.java
index 424e436..08d27d4 100755
--- a/media/java/android/media/videoeditor/VideoEditor.java
+++ b/media/java/android/media/videoeditor/VideoEditor.java
@@ -107,6 +107,17 @@
          * @param videoEditor The VideoEditor instance
          */
         public void onStop(VideoEditor videoEditor);
+
+        /**
+         * This method notifies the listener when error has occurred during
+         * previewing a project.
+         *
+         * @param videoEditor The VideoEditor instance
+         * @param error The error that has occurred
+         * FIXME: We should pass well-defined error code to the application;
+         * but for now, we just pass whatever error code reported by the native layer.
+         */
+        public void onError(VideoEditor videoEditor, int error);
     }
 
     /**
diff --git a/media/java/android/mtp/MtpDatabase.java b/media/java/android/mtp/MtpDatabase.java
old mode 100644
new mode 100755
index 4e271c7..19db1c0
--- a/media/java/android/mtp/MtpDatabase.java
+++ b/media/java/android/mtp/MtpDatabase.java
@@ -38,6 +38,7 @@
 
 import java.io.File;
 import java.util.HashMap;
+import java.util.Locale;
 
 /**
  * {@hide}
@@ -50,7 +51,15 @@
     private final IContentProvider mMediaProvider;
     private final String mVolumeName;
     private final Uri mObjectsUri;
-    private final String mMediaStoragePath; // path to primary storage
+    // path to primary storage
+    private final String mMediaStoragePath;
+    // if not null, restrict all queries to these subdirectories
+    private final String[] mSubDirectories;
+    // where clause for restricting queries to files in mSubDirectories
+    private String mSubDirectoriesWhere;
+    // where arguments for restricting queries to files in mSubDirectories
+    private String[] mSubDirectoriesWhereArgs;
+
     private final HashMap<String, MtpStorage> mStorageMap = new HashMap<String, MtpStorage>();
 
     // cached property groups for single properties
@@ -111,7 +120,8 @@
         System.loadLibrary("media_jni");
     }
 
-    public MtpDatabase(Context context, String volumeName, String storagePath) {
+    public MtpDatabase(Context context, String volumeName, String storagePath,
+            String[] subDirectories) {
         native_setup();
 
         mContext = context;
@@ -120,6 +130,45 @@
         mMediaStoragePath = storagePath;
         mObjectsUri = Files.getMtpObjectsUri(volumeName);
         mMediaScanner = new MediaScanner(context);
+
+        mSubDirectories = subDirectories;
+        if (subDirectories != null) {
+            // Compute "where" string for restricting queries to subdirectories
+            StringBuilder builder = new StringBuilder();
+            builder.append("(");
+            int count = subDirectories.length;
+            for (int i = 0; i < count; i++) {
+                builder.append(Files.FileColumns.DATA + "=? OR "
+                        + Files.FileColumns.DATA + " LIKE ?");
+                if (i != count - 1) {
+                    builder.append(" OR ");
+                }
+            }
+            builder.append(")");
+            mSubDirectoriesWhere = builder.toString();
+
+            // Compute "where" arguments for restricting queries to subdirectories
+            mSubDirectoriesWhereArgs = new String[count * 2];
+            for (int i = 0, j = 0; i < count; i++) {
+                String path = subDirectories[i];
+                mSubDirectoriesWhereArgs[j++] = path;
+                mSubDirectoriesWhereArgs[j++] = path + "/%";
+            }
+        }
+
+        // Set locale to MediaScanner.
+        Locale locale = context.getResources().getConfiguration().locale;
+        if (locale != null) {
+            String language = locale.getLanguage();
+            String country = locale.getCountry();
+            if (language != null) {
+                if (country != null) {
+                    mMediaScanner.setLocale(language + "_" + country);
+                } else {
+                    mMediaScanner.setLocale(language);
+                }
+            }
+        }
         initDeviceProperties(context);
     }
 
@@ -175,9 +224,44 @@
         }
     }
 
+    // check to see if the path is contained in one of our storage subdirectories
+    // returns true if we have no special subdirectories
+    private boolean inStorageSubDirectory(String path) {
+        if (mSubDirectories == null) return true;
+        if (path == null) return false;
+
+        boolean allowed = false;
+        int pathLength = path.length();
+        for (int i = 0; i < mSubDirectories.length && !allowed; i++) {
+            String subdir = mSubDirectories[i];
+            int subdirLength = subdir.length();
+            if (subdirLength < pathLength &&
+                    path.charAt(subdirLength) == '/' &&
+                    path.startsWith(subdir)) {
+                allowed = true;
+            }
+        }
+        return allowed;
+    }
+
+    // check to see if the path matches one of our storage subdirectories
+    // returns true if we have no special subdirectories
+    private boolean isStorageSubDirectory(String path) {
+    if (mSubDirectories == null) return false;
+        for (int i = 0; i < mSubDirectories.length; i++) {
+            if (path.equals(mSubDirectories[i])) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     private int beginSendObject(String path, int format, int parent,
                          int storageId, long size, long modified) {
-        // first make sure the object does not exist
+        // if mSubDirectories is not null, do not allow copying files to any other locations
+        if (!inStorageSubDirectory(path)) return -1;
+
+        // make sure the object does not exist
         if (path != null) {
             Cursor c = null;
             try {
@@ -254,33 +338,40 @@
     }
 
     private Cursor createObjectQuery(int storageID, int format, int parent) throws RemoteException {
+        String where;
+        String[] whereArgs;
+
         if (storageID == 0xFFFFFFFF) {
             // query all stores
             if (format == 0) {
                 // query all formats
                 if (parent == 0) {
                     // query all objects
-                    return mMediaProvider.query(mObjectsUri, ID_PROJECTION, null, null, null);
+                    where = null;
+                    whereArgs = null;
+                } else {
+                    if (parent == 0xFFFFFFFF) {
+                        // all objects in root of store
+                        parent = 0;
+                    }
+                    where = PARENT_WHERE;
+                    whereArgs = new String[] { Integer.toString(parent) };
                 }
-                if (parent == 0xFFFFFFFF) {
-                    // all objects in root of store
-                    parent = 0;
-                }
-                return mMediaProvider.query(mObjectsUri, ID_PROJECTION, PARENT_WHERE,
-                        new String[] { Integer.toString(parent) }, null);
             } else {
                 // query specific format
                 if (parent == 0) {
                     // query all objects
-                    return mMediaProvider.query(mObjectsUri, ID_PROJECTION, FORMAT_WHERE,
-                            new String[] { Integer.toString(format) }, null);
+                    where = FORMAT_WHERE;
+                    whereArgs = new String[] { Integer.toString(format) };
+                } else {
+                    if (parent == 0xFFFFFFFF) {
+                        // all objects in root of store
+                        parent = 0;
+                    }
+                    where = FORMAT_PARENT_WHERE;
+                    whereArgs = new String[] { Integer.toString(format),
+                                               Integer.toString(parent) };
                 }
-                if (parent == 0xFFFFFFFF) {
-                    // all objects in root of store
-                    parent = 0;
-                }
-                return mMediaProvider.query(mObjectsUri, ID_PROJECTION, FORMAT_PARENT_WHERE,
-                        new String[] { Integer.toString(format), Integer.toString(parent) }, null);
             }
         } else {
             // query specific store
@@ -288,35 +379,61 @@
                 // query all formats
                 if (parent == 0) {
                     // query all objects
-                    return mMediaProvider.query(mObjectsUri, ID_PROJECTION, STORAGE_WHERE,
-                            new String[] { Integer.toString(storageID) }, null);
+                    where = STORAGE_WHERE;
+                    whereArgs = new String[] { Integer.toString(storageID) };
+                } else {
+                    if (parent == 0xFFFFFFFF) {
+                        // all objects in root of store
+                        parent = 0;
+                    }
+                    where = STORAGE_PARENT_WHERE;
+                    whereArgs = new String[] { Integer.toString(storageID),
+                                               Integer.toString(parent) };
                 }
-                if (parent == 0xFFFFFFFF) {
-                    // all objects in root of store
-                    parent = 0;
-                }
-                return mMediaProvider.query(mObjectsUri, ID_PROJECTION, STORAGE_PARENT_WHERE,
-                        new String[] { Integer.toString(storageID), Integer.toString(parent) },
-                        null);
             } else {
                 // query specific format
                 if (parent == 0) {
                     // query all objects
-                    return mMediaProvider.query(mObjectsUri, ID_PROJECTION, STORAGE_FORMAT_WHERE,
-                            new String[] {  Integer.toString(storageID), Integer.toString(format) },
-                            null);
+                    where = STORAGE_FORMAT_WHERE;
+                    whereArgs = new String[] {  Integer.toString(storageID),
+                                                Integer.toString(format) };
+                } else {
+                    if (parent == 0xFFFFFFFF) {
+                        // all objects in root of store
+                        parent = 0;
+                    }
+                    where = STORAGE_FORMAT_PARENT_WHERE;
+                    whereArgs = new String[] { Integer.toString(storageID),
+                                               Integer.toString(format),
+                                               Integer.toString(parent) };
                 }
-                if (parent == 0xFFFFFFFF) {
-                    // all objects in root of store
-                    parent = 0;
-                }
-                return mMediaProvider.query(mObjectsUri, ID_PROJECTION, STORAGE_FORMAT_PARENT_WHERE,
-                        new String[] { Integer.toString(storageID),
-                                       Integer.toString(format),
-                                       Integer.toString(parent) },
-                        null);
             }
         }
+
+        // if we are restricting queries to mSubDirectories, we need to add the restriction
+        // onto our "where" arguments
+        if (mSubDirectoriesWhere != null) {
+            if (where == null) {
+                where = mSubDirectoriesWhere;
+                whereArgs = mSubDirectoriesWhereArgs;
+            } else {
+                where = where + " AND " + mSubDirectoriesWhere;
+
+                // create new array to hold whereArgs and mSubDirectoriesWhereArgs
+                String[] newWhereArgs =
+                        new String[whereArgs.length + mSubDirectoriesWhereArgs.length];
+                int i, j;
+                for (i = 0; i < whereArgs.length; i++) {
+                    newWhereArgs[i] = whereArgs[i];
+                }
+                for (j = 0; j < mSubDirectoriesWhereArgs.length; i++, j++) {
+                    newWhereArgs[i] = mSubDirectoriesWhereArgs[j];
+                }
+                whereArgs = newWhereArgs;
+            }
+        }
+
+        return mMediaProvider.query(mObjectsUri, ID_PROJECTION, where, whereArgs, null);
     }
 
     private int[] getObjectList(int storageID, int format, int parent) {
@@ -598,6 +715,11 @@
             return MtpConstants.RESPONSE_INVALID_OBJECT_HANDLE;
         }
 
+        // do not allow renaming any of the special subdirectories
+        if (isStorageSubDirectory(path)) {
+            return MtpConstants.RESPONSE_OBJECT_WRITE_PROTECTED;
+        }
+
         // now rename the file.  make sure this succeeds before updating database
         File oldFile = new File(path);
         int lastSlash = path.lastIndexOf('/');
@@ -779,6 +901,11 @@
                 return MtpConstants.RESPONSE_GENERAL_ERROR;
             }
 
+            // do not allow deleting any of the special subdirectories
+            if (isStorageSubDirectory(path)) {
+                return MtpConstants.RESPONSE_OBJECT_WRITE_PROTECTED;
+            }
+
             if (format == MtpConstants.FORMAT_ASSOCIATION) {
                 // recursive case - delete all children first
                 Uri uri = Files.getMtpObjectsUri(mVolumeName);
diff --git a/media/jni/mediaeditor/VideoEditorMain.cpp b/media/jni/mediaeditor/VideoEditorMain.cpp
index d8f1587..7083a91c 100755
--- a/media/jni/mediaeditor/VideoEditorMain.cpp
+++ b/media/jni/mediaeditor/VideoEditorMain.cpp
@@ -477,7 +477,7 @@
         pEnv->CallVoidMethod(pContext->engine,
                 pContext->onPreviewProgressUpdateMethodId,
                 currentMs,isFinished, pContext->mIsUpdateOverlay,
-                tmpFileName, pContext->mOverlayRenderingMode);
+                tmpFileName, pContext->mOverlayRenderingMode, error);
 
         if (pContext->mIsUpdateOverlay) {
             pContext->mIsUpdateOverlay = false;
@@ -1630,7 +1630,7 @@
                                      "not initialized");
 
     pContext->onPreviewProgressUpdateMethodId = pEnv->GetMethodID(engineClass,
-            "onPreviewProgressUpdate",     "(IZZLjava/lang/String;I)V");
+            "onPreviewProgressUpdate",     "(IZZLjava/lang/String;II)V");
     // Check if the context is valid (required because the context is dereferenced).
     if (needToBeLoaded) {
         // Make sure that we are in a correct state.
diff --git a/media/libmedia/IStreamSource.cpp b/media/libmedia/IStreamSource.cpp
index b311f35..078be94 100644
--- a/media/libmedia/IStreamSource.cpp
+++ b/media/libmedia/IStreamSource.cpp
@@ -30,7 +30,7 @@
 const char *const IStreamListener::kKeyResumeAtPTS = "resume-at-PTS";
 
 // static
-const char *const IStreamListener::kKeyFormatChange = "format-change";
+const char *const IStreamListener::kKeyDiscontinuityMask = "discontinuity-mask";
 
 enum {
     // IStreamSource
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index 7191175..03aa42e 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -54,6 +54,7 @@
       mVideoEOS(false),
       mScanSourcesPending(false),
       mScanSourcesGeneration(0),
+      mTimeDiscontinuityPending(false),
       mFlushingAudio(NONE),
       mFlushingVideo(NONE),
       mResetInProgress(false),
@@ -462,11 +463,24 @@
         {
             ALOGV("kWhatReset");
 
+            if (mRenderer != NULL) {
+                // There's an edge case where the renderer owns all output
+                // buffers and is paused, therefore the decoder will not read
+                // more input data and will never encounter the matching
+                // discontinuity. To avoid this, we resume the renderer.
+
+                if (mFlushingAudio == AWAITING_DISCONTINUITY
+                        || mFlushingVideo == AWAITING_DISCONTINUITY) {
+                    mRenderer->resume();
+                }
+            }
+
             if (mFlushingAudio != NONE || mFlushingVideo != NONE) {
                 // We're currently flushing, postpone the reset until that's
                 // completed.
 
-                ALOGV("postponing reset");
+                ALOGV("postponing reset mFlushingAudio=%d, mFlushingVideo=%d",
+                      mFlushingAudio, mFlushingVideo);
 
                 mResetPostponed = true;
                 break;
@@ -477,6 +491,8 @@
                 break;
             }
 
+            mTimeDiscontinuityPending = true;
+
             if (mAudioDecoder != NULL) {
                 flushDecoder(true /* audio */, true /* needShutdown */);
             }
@@ -540,7 +556,10 @@
 
     ALOGV("both audio and video are flushed now.");
 
-    mRenderer->signalTimeDiscontinuity();
+    if (mTimeDiscontinuityPending) {
+        mRenderer->signalTimeDiscontinuity();
+        mTimeDiscontinuityPending = false;
+    }
 
     if (mAudioDecoder != NULL) {
         mAudioDecoder->signalResume();
@@ -663,10 +682,15 @@
                 CHECK(accessUnit->meta()->findInt32("discontinuity", &type));
 
                 bool formatChange =
-                    type == ATSParser::DISCONTINUITY_FORMATCHANGE;
+                    (audio &&
+                     (type & ATSParser::DISCONTINUITY_AUDIO_FORMAT))
+                    || (!audio &&
+                            (type & ATSParser::DISCONTINUITY_VIDEO_FORMAT));
 
-                ALOGV("%s discontinuity (formatChange=%d)",
-                     audio ? "audio" : "video", formatChange);
+                bool timeChange = (type & ATSParser::DISCONTINUITY_TIME) != 0;
+
+                LOGI("%s discontinuity (formatChange=%d, time=%d)",
+                     audio ? "audio" : "video", formatChange, timeChange);
 
                 if (audio) {
                     mSkipRenderingAudioUntilMediaTimeUs = -1;
@@ -674,26 +698,45 @@
                     mSkipRenderingVideoUntilMediaTimeUs = -1;
                 }
 
-                sp<AMessage> extra;
-                if (accessUnit->meta()->findMessage("extra", &extra)
-                        && extra != NULL) {
-                    int64_t resumeAtMediaTimeUs;
-                    if (extra->findInt64(
-                                "resume-at-mediatimeUs", &resumeAtMediaTimeUs)) {
-                        LOGI("suppressing rendering of %s until %lld us",
-                                audio ? "audio" : "video", resumeAtMediaTimeUs);
+                if (timeChange) {
+                    sp<AMessage> extra;
+                    if (accessUnit->meta()->findMessage("extra", &extra)
+                            && extra != NULL) {
+                        int64_t resumeAtMediaTimeUs;
+                        if (extra->findInt64(
+                                    "resume-at-mediatimeUs", &resumeAtMediaTimeUs)) {
+                            LOGI("suppressing rendering of %s until %lld us",
+                                    audio ? "audio" : "video", resumeAtMediaTimeUs);
 
-                        if (audio) {
-                            mSkipRenderingAudioUntilMediaTimeUs =
-                                resumeAtMediaTimeUs;
-                        } else {
-                            mSkipRenderingVideoUntilMediaTimeUs =
-                                resumeAtMediaTimeUs;
+                            if (audio) {
+                                mSkipRenderingAudioUntilMediaTimeUs =
+                                    resumeAtMediaTimeUs;
+                            } else {
+                                mSkipRenderingVideoUntilMediaTimeUs =
+                                    resumeAtMediaTimeUs;
+                            }
                         }
                     }
                 }
 
-                flushDecoder(audio, formatChange);
+                mTimeDiscontinuityPending =
+                    mTimeDiscontinuityPending || timeChange;
+
+                if (formatChange || timeChange) {
+                    flushDecoder(audio, formatChange);
+                } else {
+                    // This stream is unaffected by the discontinuity
+
+                    if (audio) {
+                        mFlushingAudio = FLUSHED;
+                    } else {
+                        mFlushingVideo = FLUSHED;
+                    }
+
+                    finishFlushIfPossible();
+
+                    return -EWOULDBLOCK;
+                }
             }
 
             reply->setInt32("err", err);
@@ -794,6 +837,11 @@
 }
 
 void NuPlayer::flushDecoder(bool audio, bool needShutdown) {
+    if ((audio && mAudioDecoder == NULL) || (!audio && mVideoDecoder == NULL)) {
+        LOGI("flushDecoder %s without decoder present",
+             audio ? "audio" : "video");
+    }
+
     // Make sure we don't continue to scan sources until we finish flushing.
     ++mScanSourcesGeneration;
     mScanSourcesPending = false;
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.h b/media/libmediaplayerservice/nuplayer/NuPlayer.h
index f23deea..ffc710e 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.h
@@ -112,6 +112,10 @@
         SHUT_DOWN,
     };
 
+    // Once the current flush is complete this indicates whether the
+    // notion of time has changed.
+    bool mTimeDiscontinuityPending;
+
     FlushStatus mFlushingAudio;
     FlushStatus mFlushingVideo;
     bool mResetInProgress;
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
index 1731728..d0d9ca6 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
@@ -628,11 +628,16 @@
         mAudioSink->pause();
     }
 
+    ALOGV("now paused audio queue has %d entries, video has %d entries",
+          mAudioQueue.size(), mVideoQueue.size());
+
     mPaused = true;
 }
 
 void NuPlayer::Renderer::onResume() {
-    CHECK(mPaused);
+    if (!mPaused) {
+        return;
+    }
 
     if (mHasAudio) {
         mAudioSink->start();
diff --git a/media/libmediaplayerservice/nuplayer/StreamingSource.cpp b/media/libmediaplayerservice/nuplayer/StreamingSource.cpp
index f795654..2e63b3b 100644
--- a/media/libmediaplayerservice/nuplayer/StreamingSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/StreamingSource.cpp
@@ -63,17 +63,22 @@
             mFinalResult = ERROR_END_OF_STREAM;
             break;
         } else if (n == INFO_DISCONTINUITY) {
-            ATSParser::DiscontinuityType type = ATSParser::DISCONTINUITY_SEEK;
+            int32_t type = ATSParser::DISCONTINUITY_SEEK;
 
-            int32_t formatChange;
+            int32_t mask;
             if (extra != NULL
                     && extra->findInt32(
-                        IStreamListener::kKeyFormatChange, &formatChange)
-                    && formatChange != 0) {
-                type = ATSParser::DISCONTINUITY_FORMATCHANGE;
+                        IStreamListener::kKeyDiscontinuityMask, &mask)) {
+                if (mask == 0) {
+                    LOGE("Client specified an illegal discontinuity type.");
+                    return ERROR_UNSUPPORTED;
+                }
+
+                type = mask;
             }
 
-            mTSParser->signalDiscontinuity(type, extra);
+            mTSParser->signalDiscontinuity(
+                    (ATSParser::DiscontinuityType)type, extra);
         } else if (n < 0) {
             CHECK_EQ(n, -EWOULDBLOCK);
             break;
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index 0e8c874..ebf5fab 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -342,6 +342,7 @@
 }
 
 void ACodec::signalFlush() {
+    ALOGV("[%s] signalFlush", mComponentName.c_str());
     (new AMessage(kWhatFlush, id()))->post();
 }
 
@@ -1092,6 +1093,20 @@
     return OK;
 }
 
+size_t ACodec::countBuffersOwnedByComponent(OMX_U32 portIndex) const {
+    size_t n = 0;
+
+    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
+        const BufferInfo &info = mBuffers[portIndex].itemAt(i);
+
+        if (info.mStatus == BufferInfo::OWNED_BY_COMPONENT) {
+            ++n;
+        }
+    }
+
+    return n;
+}
+
 bool ACodec::allYourBuffersAreBelongToUs(
         OMX_U32 portIndex) {
     for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
@@ -2041,6 +2056,14 @@
 
         case kWhatFlush:
         {
+            ALOGV("[%s] ExecutingState flushing now "
+                 "(codec owns %d/%d input, %d/%d output).",
+                    mCodec->mComponentName.c_str(),
+                    mCodec->countBuffersOwnedByComponent(kPortIndexInput),
+                    mCodec->mBuffers[kPortIndexInput].size(),
+                    mCodec->countBuffersOwnedByComponent(kPortIndexOutput),
+                    mCodec->mBuffers[kPortIndexOutput].size());
+
             mActive = false;
 
             CHECK_EQ(mCodec->mOMX->sendCommand(
@@ -2180,6 +2203,12 @@
                          err);
 
                     mCodec->signalError();
+
+                    // This is technically not correct, since we were unable
+                    // to allocate output buffers and therefore the output port
+                    // remains disabled. It is necessary however to allow us
+                    // to shutdown the codec properly.
+                    mCodec->changeState(mCodec->mExecutingState);
                 }
 
                 return true;
@@ -2408,6 +2437,9 @@
 
 bool ACodec::FlushingState::onOMXEvent(
         OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
+    ALOGV("[%s] FlushingState onOMXEvent(%d,%ld)",
+            mCodec->mComponentName.c_str(), event, data1);
+
     switch (event) {
         case OMX_EventCmdComplete:
         {
diff --git a/media/libstagefright/AVIExtractor.cpp b/media/libstagefright/AVIExtractor.cpp
index 058d10c..142fa5b 100644
--- a/media/libstagefright/AVIExtractor.cpp
+++ b/media/libstagefright/AVIExtractor.cpp
@@ -1094,7 +1094,7 @@
     CHECK(meta->findData(kKeyAVCC, &type, &csd, &csdSize));
 
     track->mMeta->setInt32(kKeyWidth, width);
-    track->mMeta->setInt32(kKeyHeight, width);
+    track->mMeta->setInt32(kKeyHeight, height);
     track->mMeta->setData(kKeyAVCC, type, csd, csdSize);
 
     return OK;
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index 1f225a7..964cb1f 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -1949,6 +1949,8 @@
         mUri = newURI;
     }
 
+    AString sniffedMIME;
+
     if (!strncasecmp("http://", mUri.string(), 7)
             || !strncasecmp("https://", mUri.string(), 8)
             || isWidevineStreaming) {
@@ -1998,7 +2000,6 @@
 
         mConnectingDataSource.clear();
 
-
         String8 contentType = dataSource->getMIMEType();
 
         if (strncasecmp(contentType.string(), "audio/", 6)) {
@@ -2020,16 +2021,51 @@
 
                 mLock.unlock();
 
+                // Initially make sure we have at least 192 KB for the sniff
+                // to complete without blocking.
+                static const size_t kMinBytesForSniffing = 192 * 1024;
+
+                off64_t metaDataSize = -1ll;
                 for (;;) {
                     status_t finalStatus;
                     size_t cachedDataRemaining =
                         mCachedSource->approxDataRemaining(&finalStatus);
 
-                    if (finalStatus != OK || cachedDataRemaining >= kHighWaterMarkBytes
+                    if (finalStatus != OK
+                            || (metaDataSize >= 0
+                                && cachedDataRemaining >= metaDataSize)
                             || (mFlags & PREPARE_CANCELLED)) {
                         break;
                     }
 
+                    ALOGV("now cached %d bytes of data", cachedDataRemaining);
+
+                    if (metaDataSize < 0
+                            && cachedDataRemaining >= kMinBytesForSniffing) {
+                        String8 tmp;
+                        float confidence;
+                        sp<AMessage> meta;
+                        if (!dataSource->sniff(&tmp, &confidence, &meta)) {
+                            mLock.lock();
+                            return UNKNOWN_ERROR;
+                        }
+
+                        // We successfully identified the file's extractor to
+                        // be, remember this mime type so we don't have to
+                        // sniff it again when we call MediaExtractor::Create()
+                        // below.
+                        sniffedMIME = tmp.string();
+
+                        if (meta == NULL
+                                || !meta->findInt64(
+                                    "meta-data-size", &metaDataSize)) {
+                            metaDataSize = kHighWaterMarkBytes;
+                        }
+
+                        CHECK_GE(metaDataSize, 0ll);
+                        ALOGV("metaDataSize = %lld bytes", metaDataSize);
+                    }
+
                     usleep(200000);
                 }
 
@@ -2067,7 +2103,8 @@
         mWVMExtractor->setAdaptiveStreamingMode(true);
         extractor = mWVMExtractor;
     } else {
-        extractor = MediaExtractor::Create(dataSource);
+        extractor = MediaExtractor::Create(
+                dataSource, sniffedMIME.empty() ? NULL : sniffedMIME.c_str());
 
         if (extractor == NULL) {
             return UNKNOWN_ERROR;
diff --git a/media/libstagefright/DataSource.cpp b/media/libstagefright/DataSource.cpp
index 70523c1..e471f73 100644
--- a/media/libstagefright/DataSource.cpp
+++ b/media/libstagefright/DataSource.cpp
@@ -16,6 +16,11 @@
 
 #include "include/AMRExtractor.h"
 #include "include/AVIExtractor.h"
+
+#if CHROMIUM_AVAILABLE
+#include "include/DataUriSource.h"
+#endif
+
 #include "include/MP3Extractor.h"
 #include "include/MPEG4Extractor.h"
 #include "include/WAVExtractor.h"
@@ -136,6 +141,10 @@
             return NULL;
         }
         source = new NuCachedSource2(httpSource);
+# if CHROMIUM_AVAILABLE
+    } else if (!strncasecmp("data:", uri, 5)) {
+        source = new DataUriSource(uri);
+#endif
     } else {
         // Assume it's a filename.
         source = new FileSource(uri);
diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp
index 7b6fa38..0a69df4 100644
--- a/media/libstagefright/MPEG4Extractor.cpp
+++ b/media/libstagefright/MPEG4Extractor.cpp
@@ -30,6 +30,7 @@
 #include <string.h>
 
 #include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/foundation/AMessage.h>
 #include <media/stagefright/DataSource.h>
 #include <media/stagefright/MediaBuffer.h>
 #include <media/stagefright/MediaBufferGroup.h>
@@ -2302,51 +2303,121 @@
 
 // Attempt to actually parse the 'ftyp' atom and determine if a suitable
 // compatible brand is present.
+// Also try to identify where this file's metadata ends
+// (end of the 'moov' atom) and report it to the caller as part of
+// the metadata.
 static bool BetterSniffMPEG4(
-        const sp<DataSource> &source, String8 *mimeType, float *confidence) {
-    uint8_t header[12];
-    if (source->readAt(0, header, 12) != 12
-            || memcmp("ftyp", &header[4], 4)) {
-        return false;
-    }
+        const sp<DataSource> &source, String8 *mimeType, float *confidence,
+        sp<AMessage> *meta) {
+    // We scan up to 128 bytes to identify this file as an MP4.
+    static const off64_t kMaxScanOffset = 128ll;
 
-    size_t atomSize = U32_AT(&header[0]);
-    if (atomSize < 16 || (atomSize % 4) != 0) {
-        return false;
-    }
+    off64_t offset = 0ll;
+    bool foundGoodFileType = false;
+    off64_t moovAtomEndOffset = -1ll;
+    bool done = false;
 
-    bool success = false;
-    if (isCompatibleBrand(U32_AT(&header[8]))) {
-        success = true;
-    } else {
-        size_t numCompatibleBrands = (atomSize - 16) / 4;
-        for (size_t i = 0; i < numCompatibleBrands; ++i) {
-            uint8_t tmp[4];
-            if (source->readAt(16 + i * 4, tmp, 4) != 4) {
+    while (!done && offset < kMaxScanOffset) {
+        uint32_t hdr[2];
+        if (source->readAt(offset, hdr, 8) < 8) {
+            return false;
+        }
+
+        uint64_t chunkSize = ntohl(hdr[0]);
+        uint32_t chunkType = ntohl(hdr[1]);
+        off64_t chunkDataOffset = offset + 8;
+
+        if (chunkSize == 1) {
+            if (source->readAt(offset + 8, &chunkSize, 8) < 8) {
                 return false;
             }
 
-            if (isCompatibleBrand(U32_AT(&tmp[0]))) {
-                success = true;
+            chunkSize = ntoh64(chunkSize);
+            chunkDataOffset += 8;
+
+            if (chunkSize < 16) {
+                // The smallest valid chunk is 16 bytes long in this case.
+                return false;
+            }
+        } else if (chunkSize < 8) {
+            // The smallest valid chunk is 8 bytes long.
+            return false;
+        }
+
+        off64_t chunkDataSize = offset + chunkSize - chunkDataOffset;
+
+        switch (chunkType) {
+            case FOURCC('f', 't', 'y', 'p'):
+            {
+                if (chunkDataSize < 8) {
+                    return false;
+                }
+
+                uint32_t numCompatibleBrands = (chunkDataSize - 8) / 4;
+                for (size_t i = 0; i < numCompatibleBrands + 2; ++i) {
+                    if (i == 1) {
+                        // Skip this index, it refers to the minorVersion,
+                        // not a brand.
+                        continue;
+                    }
+
+                    uint32_t brand;
+                    if (source->readAt(
+                                chunkDataOffset + 4 * i, &brand, 4) < 4) {
+                        return false;
+                    }
+
+                    brand = ntohl(brand);
+
+                    if (isCompatibleBrand(brand)) {
+                        foundGoodFileType = true;
+                        break;
+                    }
+                }
+
+                if (!foundGoodFileType) {
+                    return false;
+                }
+
                 break;
             }
+
+            case FOURCC('m', 'o', 'o', 'v'):
+            {
+                moovAtomEndOffset = offset + chunkSize;
+
+                done = true;
+                break;
+            }
+
+            default:
+                break;
         }
+
+        offset += chunkSize;
     }
 
-    if (!success) {
+    if (!foundGoodFileType) {
         return false;
     }
 
     *mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4;
     *confidence = 0.4f;
 
+    if (moovAtomEndOffset >= 0) {
+        *meta = new AMessage;
+        (*meta)->setInt64("meta-data-size", moovAtomEndOffset);
+
+        ALOGV("found metadata size: %lld", moovAtomEndOffset);
+    }
+
     return true;
 }
 
 bool SniffMPEG4(
         const sp<DataSource> &source, String8 *mimeType, float *confidence,
-        sp<AMessage> *) {
-    if (BetterSniffMPEG4(source, mimeType, confidence)) {
+        sp<AMessage> *meta) {
+    if (BetterSniffMPEG4(source, mimeType, confidence, meta)) {
         return true;
     }
 
diff --git a/media/libstagefright/SurfaceMediaSource.cpp b/media/libstagefright/SurfaceMediaSource.cpp
index 210635f..51a7541 100644
--- a/media/libstagefright/SurfaceMediaSource.cpp
+++ b/media/libstagefright/SurfaceMediaSource.cpp
@@ -32,6 +32,8 @@
 #include <utils/Log.h>
 #include <utils/String8.h>
 
+#include <private/gui/ComposerService.h>
+
 namespace android {
 
 SurfaceMediaSource::SurfaceMediaSource(uint32_t bufW, uint32_t bufH) :
@@ -336,7 +338,7 @@
         (uint32_t(buffer->height) != h) ||
         (uint32_t(buffer->format) != format) ||
         ((uint32_t(buffer->usage) & usage) != usage)) {
-            usage |= GraphicBuffer::USAGE_HW_TEXTURE;
+            usage |= GraphicBuffer::USAGE_HW_VIDEO_ENCODER;
             status_t error;
             sp<GraphicBuffer> graphicBuffer(
                     mGraphicBufferAlloc->createGraphicBuffer(
diff --git a/media/libstagefright/chromium_http/Android.mk b/media/libstagefright/chromium_http/Android.mk
index 6573e3c..63775f1 100644
--- a/media/libstagefright/chromium_http/Android.mk
+++ b/media/libstagefright/chromium_http/Android.mk
@@ -3,8 +3,9 @@
 include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES:=       \
-        ChromiumHTTPDataSource.cpp        \
-        support.cpp                     \
+        DataUriSource.cpp \
+        ChromiumHTTPDataSource.cpp \
+        support.cpp
 
 LOCAL_C_INCLUDES:= \
         $(JNI_H_INCLUDE) \
diff --git a/media/libstagefright/chromium_http/DataUriSource.cpp b/media/libstagefright/chromium_http/DataUriSource.cpp
new file mode 100644
index 0000000..ecf3fa1
--- /dev/null
+++ b/media/libstagefright/chromium_http/DataUriSource.cpp
@@ -0,0 +1,68 @@
+/*
+ * 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.
+ */
+
+#include <include/DataUriSource.h>
+
+#include <net/base/data_url.h>
+#include <googleurl/src/gurl.h>
+
+
+namespace android {
+
+DataUriSource::DataUriSource(const char *uri) :
+    mDataUri(uri),
+    mInited(NO_INIT) {
+
+    // Copy1: const char *uri -> String8 mDataUri.
+    std::string mimeTypeStr, unusedCharsetStr, dataStr;
+    // Copy2: String8 mDataUri -> std::string
+    const bool ret = net::DataURL::Parse(
+            GURL(std::string(mDataUri.string())),
+            &mimeTypeStr, &unusedCharsetStr, &dataStr);
+    // Copy3: std::string dataStr -> AString mData
+    mData.setTo(dataStr.data(), dataStr.length());
+    mInited = ret ? OK : UNKNOWN_ERROR;
+
+    // The chromium data url implementation defaults to using "text/plain"
+    // if no mime type is specified. We prefer to leave this unspecified
+    // instead, since the mime type is sniffed in most cases.
+    if (mimeTypeStr != "text/plain") {
+        mMimeType = mimeTypeStr.c_str();
+    }
+}
+
+ssize_t DataUriSource::readAt(off64_t offset, void *out, size_t size) {
+    if (mInited != OK) {
+        return mInited;
+    }
+
+    const off64_t length = mData.size();
+    if (offset >= length) {
+        return UNKNOWN_ERROR;
+    }
+
+    const char *dataBuf = mData.c_str();
+    const size_t bytesToCopy =
+            offset + size >= length ? (length - offset) : size;
+
+    if (bytesToCopy > 0) {
+        memcpy(out, dataBuf + offset, bytesToCopy);
+    }
+
+    return bytesToCopy;
+}
+
+}  // namespace android
diff --git a/media/libstagefright/include/DataUriSource.h b/media/libstagefright/include/DataUriSource.h
new file mode 100644
index 0000000..d223c06
--- /dev/null
+++ b/media/libstagefright/include/DataUriSource.h
@@ -0,0 +1,76 @@
+/*
+ * 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.
+ */
+
+#ifndef DATA_URI_SOURCE_H_
+
+#define DATA_URI_SOURCE_H_
+
+#include <stdio.h>
+
+#include <media/stagefright/DataSource.h>
+#include <media/stagefright/MediaErrors.h>
+#include <media/stagefright/foundation/AString.h>
+
+namespace android {
+
+class DataUriSource : public DataSource {
+public:
+    DataUriSource(const char *uri);
+
+    virtual status_t initCheck() const {
+        return mInited;
+    }
+
+    virtual ssize_t readAt(off64_t offset, void *data, size_t size);
+
+    virtual status_t getSize(off64_t *size) {
+        if (mInited != OK) {
+            return mInited;
+        }
+
+        *size = mData.size();
+        return OK;
+    }
+
+    virtual String8 getUri() {
+        return mDataUri;
+    }
+
+    virtual String8 getMIMEType() const {
+        return mMimeType;
+    }
+
+protected:
+    virtual ~DataUriSource() {
+        // Nothing to delete.
+    }
+
+private:
+    const String8 mDataUri;
+
+    String8 mMimeType;
+    // Use AString because individual bytes may not be valid UTF8 chars.
+    AString mData;
+    status_t mInited;
+
+    // Disallow copy and assign.
+    DataUriSource(const DataUriSource &);
+    DataUriSource &operator=(const DataUriSource &);
+};
+
+}  // namespace android
+
+#endif  // DATA_URI_SOURCE_H_
diff --git a/media/libstagefright/mpeg2ts/ATSParser.cpp b/media/libstagefright/mpeg2ts/ATSParser.cpp
index e18071e..da911e4 100644
--- a/media/libstagefright/mpeg2ts/ATSParser.cpp
+++ b/media/libstagefright/mpeg2ts/ATSParser.cpp
@@ -123,6 +123,9 @@
 
     void extractAACFrames(const sp<ABuffer> &buffer);
 
+    bool isAudio() const;
+    bool isVideo() const;
+
     DISALLOW_EVIL_CONSTRUCTORS(Stream);
 };
 
@@ -401,7 +404,7 @@
         case STREAMTYPE_H264:
             mQueue = new ElementaryStreamQueue(ElementaryStreamQueue::H264);
             break;
-        case STREAMTYPE_MPEG2_AUDIO_ATDS:
+        case STREAMTYPE_MPEG2_AUDIO_ADTS:
             mQueue = new ElementaryStreamQueue(ElementaryStreamQueue::AAC);
             break;
         case STREAMTYPE_MPEG1_AUDIO:
@@ -486,6 +489,31 @@
     return OK;
 }
 
+bool ATSParser::Stream::isVideo() const {
+    switch (mStreamType) {
+        case STREAMTYPE_H264:
+        case STREAMTYPE_MPEG1_VIDEO:
+        case STREAMTYPE_MPEG2_VIDEO:
+        case STREAMTYPE_MPEG4_VIDEO:
+            return true;
+
+        default:
+            return false;
+    }
+}
+
+bool ATSParser::Stream::isAudio() const {
+    switch (mStreamType) {
+        case STREAMTYPE_MPEG1_AUDIO:
+        case STREAMTYPE_MPEG2_AUDIO:
+        case STREAMTYPE_MPEG2_AUDIO_ADTS:
+            return true;
+
+        default:
+            return false;
+    }
+}
+
 void ATSParser::Stream::signalDiscontinuity(
         DiscontinuityType type, const sp<AMessage> &extra) {
     if (mQueue == NULL) {
@@ -495,34 +523,34 @@
     mPayloadStarted = false;
     mBuffer->setRange(0, 0);
 
-    switch (type) {
-        case DISCONTINUITY_SEEK:
-        case DISCONTINUITY_FORMATCHANGE:
-        {
-            bool isASeek = (type == DISCONTINUITY_SEEK);
-
-            mQueue->clear(!isASeek);
-
-            uint64_t resumeAtPTS;
-            if (extra != NULL
-                    && extra->findInt64(
-                        IStreamListener::kKeyResumeAtPTS,
-                        (int64_t *)&resumeAtPTS)) {
-                int64_t resumeAtMediaTimeUs =
-                    mProgram->convertPTSToTimestamp(resumeAtPTS);
-
-                extra->setInt64("resume-at-mediatimeUs", resumeAtMediaTimeUs);
-            }
-
-            if (mSource != NULL) {
-                mSource->queueDiscontinuity(type, extra);
-            }
-            break;
+    bool clearFormat = false;
+    if (isAudio()) {
+        if (type & DISCONTINUITY_AUDIO_FORMAT) {
+            clearFormat = true;
         }
+    } else {
+        if (type & DISCONTINUITY_VIDEO_FORMAT) {
+            clearFormat = true;
+        }
+    }
 
-        default:
-            TRESPASS();
-            break;
+    mQueue->clear(clearFormat);
+
+    if (type & DISCONTINUITY_TIME) {
+        uint64_t resumeAtPTS;
+        if (extra != NULL
+                && extra->findInt64(
+                    IStreamListener::kKeyResumeAtPTS,
+                    (int64_t *)&resumeAtPTS)) {
+            int64_t resumeAtMediaTimeUs =
+                mProgram->convertPTSToTimestamp(resumeAtPTS);
+
+            extra->setInt64("resume-at-mediatimeUs", resumeAtMediaTimeUs);
+        }
+    }
+
+    if (mSource != NULL) {
+        mSource->queueDiscontinuity(type, extra);
     }
 }
 
@@ -764,10 +792,7 @@
     switch (type) {
         case VIDEO:
         {
-            if (mStreamType == STREAMTYPE_H264
-                    || mStreamType == STREAMTYPE_MPEG1_VIDEO
-                    || mStreamType == STREAMTYPE_MPEG2_VIDEO
-                    || mStreamType == STREAMTYPE_MPEG4_VIDEO) {
+            if (isVideo()) {
                 return mSource;
             }
             break;
@@ -775,9 +800,7 @@
 
         case AUDIO:
         {
-            if (mStreamType == STREAMTYPE_MPEG1_AUDIO
-                    || mStreamType == STREAMTYPE_MPEG2_AUDIO
-                    || mStreamType == STREAMTYPE_MPEG2_AUDIO_ATDS) {
+            if (isAudio()) {
                 return mSource;
             }
             break;
diff --git a/media/libstagefright/mpeg2ts/ATSParser.h b/media/libstagefright/mpeg2ts/ATSParser.h
index 878e534..c8038d1 100644
--- a/media/libstagefright/mpeg2ts/ATSParser.h
+++ b/media/libstagefright/mpeg2ts/ATSParser.h
@@ -33,9 +33,18 @@
 
 struct ATSParser : public RefBase {
     enum DiscontinuityType {
-        DISCONTINUITY_NONE,
-        DISCONTINUITY_SEEK,
-        DISCONTINUITY_FORMATCHANGE
+        DISCONTINUITY_NONE              = 0,
+        DISCONTINUITY_TIME              = 1,
+        DISCONTINUITY_AUDIO_FORMAT      = 2,
+        DISCONTINUITY_VIDEO_FORMAT      = 4,
+
+        DISCONTINUITY_SEEK              = DISCONTINUITY_TIME,
+
+        // For legacy reasons this also implies a time discontinuity.
+        DISCONTINUITY_FORMATCHANGE      =
+            DISCONTINUITY_AUDIO_FORMAT
+                | DISCONTINUITY_VIDEO_FORMAT
+                | DISCONTINUITY_TIME,
     };
 
     enum Flags {
@@ -71,7 +80,7 @@
         STREAMTYPE_MPEG2_VIDEO          = 0x02,
         STREAMTYPE_MPEG1_AUDIO          = 0x03,
         STREAMTYPE_MPEG2_AUDIO          = 0x04,
-        STREAMTYPE_MPEG2_AUDIO_ATDS     = 0x0f,
+        STREAMTYPE_MPEG2_AUDIO_ADTS     = 0x0f,
         STREAMTYPE_MPEG4_VIDEO          = 0x10,
         STREAMTYPE_H264                 = 0x1b,
     };
diff --git a/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp b/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp
index 0f614a2..d708ba6 100644
--- a/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp
+++ b/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp
@@ -29,8 +29,17 @@
 namespace android {
 
 AnotherPacketSource::AnotherPacketSource(const sp<MetaData> &meta)
-    : mFormat(meta),
+    : mIsAudio(false),
+      mFormat(meta),
       mEOSResult(OK) {
+    const char *mime;
+    CHECK(meta->findCString(kKeyMIMEType, &mime));
+
+    if (!strncasecmp("audio/", mime, 6)) {
+        mIsAudio = true;
+    } else {
+        CHECK(!strncasecmp("video/", mime, 6));
+    }
 }
 
 void AnotherPacketSource::setFormat(const sp<MetaData> &meta) {
@@ -67,8 +76,7 @@
 
         int32_t discontinuity;
         if ((*buffer)->meta()->findInt32("discontinuity", &discontinuity)) {
-
-            if (discontinuity == ATSParser::DISCONTINUITY_FORMATCHANGE) {
+            if (wasFormatChange(discontinuity)) {
                 mFormat.clear();
             }
 
@@ -96,7 +104,7 @@
 
         int32_t discontinuity;
         if (buffer->meta()->findInt32("discontinuity", &discontinuity)) {
-            if (discontinuity == ATSParser::DISCONTINUITY_FORMATCHANGE) {
+            if (wasFormatChange(discontinuity)) {
                 mFormat.clear();
             }
 
@@ -117,6 +125,15 @@
     return mEOSResult;
 }
 
+bool AnotherPacketSource::wasFormatChange(
+        int32_t discontinuityType) const {
+    if (mIsAudio) {
+        return (discontinuityType & ATSParser::DISCONTINUITY_AUDIO_FORMAT) != 0;
+    }
+
+    return (discontinuityType & ATSParser::DISCONTINUITY_VIDEO_FORMAT) != 0;
+}
+
 void AnotherPacketSource::queueAccessUnit(const sp<ABuffer> &buffer) {
     int32_t damaged;
     if (buffer->meta()->findInt32("damaged", &damaged) && damaged) {
diff --git a/media/libstagefright/mpeg2ts/AnotherPacketSource.h b/media/libstagefright/mpeg2ts/AnotherPacketSource.h
index 439c7853..c99f7f2 100644
--- a/media/libstagefright/mpeg2ts/AnotherPacketSource.h
+++ b/media/libstagefright/mpeg2ts/AnotherPacketSource.h
@@ -61,10 +61,13 @@
     Mutex mLock;
     Condition mCondition;
 
+    bool mIsAudio;
     sp<MetaData> mFormat;
     List<sp<ABuffer> > mBuffers;
     status_t mEOSResult;
 
+    bool wasFormatChange(int32_t discontinuityType) const;
+
     DISALLOW_EVIL_CONSTRUCTORS(AnotherPacketSource);
 };
 
diff --git a/media/libstagefright/mpeg2ts/MPEG2PSExtractor.cpp b/media/libstagefright/mpeg2ts/MPEG2PSExtractor.cpp
index d68e45b..df30a9c 100644
--- a/media/libstagefright/mpeg2ts/MPEG2PSExtractor.cpp
+++ b/media/libstagefright/mpeg2ts/MPEG2PSExtractor.cpp
@@ -543,7 +543,7 @@
         case ATSParser::STREAMTYPE_H264:
             mode = ElementaryStreamQueue::H264;
             break;
-        case ATSParser::STREAMTYPE_MPEG2_AUDIO_ATDS:
+        case ATSParser::STREAMTYPE_MPEG2_AUDIO_ADTS:
             mode = ElementaryStreamQueue::AAC;
             break;
         case ATSParser::STREAMTYPE_MPEG1_AUDIO:
diff --git a/media/libstagefright/timedtext/TimedTextParser.cpp b/media/libstagefright/timedtext/TimedTextParser.cpp
index 0bada16..caea0a4 100644
--- a/media/libstagefright/timedtext/TimedTextParser.cpp
+++ b/media/libstagefright/timedtext/TimedTextParser.cpp
@@ -128,7 +128,7 @@
  *  Subtitle number
  *  Start time --> End time
  *  Text of subtitle (one or more lines)
- *  Blank line
+ *  Blank lines
  *
  * .srt file example:
  *  1
@@ -143,15 +143,20 @@
         off64_t *offset, int64_t *startTimeUs, TextInfo *info) {
     AString data;
     status_t err;
+
+    // To skip blank lines.
+    do {
+        if ((err = readNextLine(offset, &data)) != OK) {
+            return err;
+        }
+        data.trim();
+    } while(data.empty());
+
+    // Just ignore the first non-blank line which is subtitle sequence number.
+
     if ((err = readNextLine(offset, &data)) != OK) {
         return err;
     }
-
-    // to skip the first line
-    if ((err = readNextLine(offset, &data)) != OK) {
-        return err;
-    }
-
     int hour1, hour2, min1, min2, sec1, sec2, msec1, msec2;
     // the start time format is: hours:minutes:seconds,milliseconds
     // 00:00:24,600 --> 00:00:27,800
diff --git a/media/mtp/MtpDataPacket.cpp b/media/mtp/MtpDataPacket.cpp
index 20225ba..cfea7e8 100644
--- a/media/mtp/MtpDataPacket.cpp
+++ b/media/mtp/MtpDataPacket.cpp
@@ -25,10 +25,12 @@
 #include "MtpDataPacket.h"
 #include "MtpStringBuffer.h"
 
+#define MTP_BUFFER_SIZE 16384
+
 namespace android {
 
 MtpDataPacket::MtpDataPacket()
-    :   MtpPacket(16384),   // MAX_USBFS_BUFFER_SIZE
+    :   MtpPacket(MTP_BUFFER_SIZE),   // MAX_USBFS_BUFFER_SIZE
         mOffset(MTP_CONTAINER_HEADER_SIZE)
 {
 }
@@ -345,7 +347,7 @@
 
 #ifdef MTP_DEVICE 
 int MtpDataPacket::read(int fd) {
-    int ret = ::read(fd, mBuffer, mBufferSize);
+    int ret = ::read(fd, mBuffer, MTP_BUFFER_SIZE);
     if (ret < MTP_CONTAINER_HEADER_SIZE)
         return -1;
     mPacketSize = ret;
diff --git a/media/mtp/MtpServer.cpp b/media/mtp/MtpServer.cpp
index 51eb97f..1334e6c 100644
--- a/media/mtp/MtpServer.cpp
+++ b/media/mtp/MtpServer.cpp
@@ -1053,11 +1053,14 @@
     int result = mDatabase->getObjectFilePath(handle, filePath, fileLength, format);
     if (result == MTP_RESPONSE_OK) {
         ALOGV("deleting %s", (const char *)filePath);
-        deletePath((const char *)filePath);
-        return mDatabase->deleteFile(handle);
-    } else {
-        return result;
+        result = mDatabase->deleteFile(handle);
+        // Don't delete the actual files unless the database deletion is allowed
+        if (result == MTP_RESPONSE_OK) {
+            deletePath((const char *)filePath);
+        }
     }
+
+    return result;
 }
 
 MtpResponseCode MtpServer::doGetObjectPropDesc() {
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkTestRunner.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkTestRunner.java
index 3fb2da0..92ac9eb 100755
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkTestRunner.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkTestRunner.java
@@ -39,6 +39,7 @@
 import com.android.mediaframeworktest.functional.videoeditor.VideoEditorPreviewTest;
 import junit.framework.TestSuite;
 
+import android.os.Bundle;
 import android.test.InstrumentationTestRunner;
 import android.test.InstrumentationTestSuite;
 
@@ -54,6 +55,7 @@
 
 public class MediaFrameworkTestRunner extends InstrumentationTestRunner {
 
+    public static int mMinCameraFps = 0;
 
     @Override
     public TestSuite getAllTests() {
@@ -87,4 +89,16 @@
     public ClassLoader getLoader() {
         return MediaFrameworkTestRunner.class.getClassLoader();
     }
+
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+
+        String minCameraFps = (String) icicle.get("min_camera_fps");
+        System.out.print("min_camera_" + minCameraFps);
+
+        if (minCameraFps != null ) {
+            mMinCameraFps = Integer.parseInt(minCameraFps);
+        }
+    }
 }
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaEnvReverbTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaEnvReverbTest.java
index 3c8d05a..e788c17 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaEnvReverbTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaEnvReverbTest.java
@@ -353,6 +353,8 @@
         AudioEffect vc = null;
         MediaPlayer mp = null;
         AudioManager am = (AudioManager) getActivity().getSystemService(Context.AUDIO_SERVICE);
+        int ringerMode = am.getRingerMode();
+        am.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
         int volume = am.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
         am.setStreamVolume(AudioManager.STREAM_MUSIC,
                            am.getStreamMaxVolume(AudioManager.STREAM_MUSIC),
@@ -411,6 +413,7 @@
                 probe.release();
             }
             am.setStreamVolume(AudioManager.STREAM_MUSIC, volume, 0);
+            am.setRingerMode(ringerMode);
         }
         assertTrue(msg, result);
     }
@@ -425,6 +428,8 @@
         MediaPlayer mp = null;
         AudioEffect rvb = null;
         AudioManager am = (AudioManager) getActivity().getSystemService(Context.AUDIO_SERVICE);
+        int ringerMode = am.getRingerMode();
+        am.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
         int volume = am.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
         am.setStreamVolume(AudioManager.STREAM_MUSIC,
                            am.getStreamMaxVolume(AudioManager.STREAM_MUSIC),
@@ -495,6 +500,7 @@
                 probe.release();
             }
             am.setStreamVolume(AudioManager.STREAM_MUSIC, volume, 0);
+            am.setRingerMode(ringerMode);
         }
         assertTrue(msg, result);
     }
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaPresetReverbTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaPresetReverbTest.java
index 757bbc5..bc9c48d 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaPresetReverbTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaPresetReverbTest.java
@@ -198,6 +198,8 @@
         AudioEffect vc = null;
         MediaPlayer mp = null;
         AudioManager am = (AudioManager) getActivity().getSystemService(Context.AUDIO_SERVICE);
+        int ringerMode = am.getRingerMode();
+        am.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
         int volume = am.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
         am.setStreamVolume(AudioManager.STREAM_MUSIC,
                            am.getStreamMaxVolume(AudioManager.STREAM_MUSIC),
@@ -254,6 +256,7 @@
                 probe.release();
             }
             am.setStreamVolume(AudioManager.STREAM_MUSIC, volume, 0);
+            am.setRingerMode(ringerMode);
         }
         assertTrue(msg, result);
     }
@@ -268,6 +271,8 @@
         MediaPlayer mp = null;
         AudioEffect rvb = null;
         AudioManager am = (AudioManager) getActivity().getSystemService(Context.AUDIO_SERVICE);
+        int ringerMode = am.getRingerMode();
+        am.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
         int volume = am.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
         am.setStreamVolume(AudioManager.STREAM_MUSIC,
                            am.getStreamMaxVolume(AudioManager.STREAM_MUSIC),
@@ -336,6 +341,7 @@
                 probe.release();
             }
             am.setStreamVolume(AudioManager.STREAM_MUSIC, volume, 0);
+            am.setRingerMode(ringerMode);
         }
         assertTrue(msg, result);
     }
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaVisualizerTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaVisualizerTest.java
index e0cf51d..b0bf654 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaVisualizerTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/audio/MediaVisualizerTest.java
@@ -200,6 +200,8 @@
         AudioEffect vc = null;
         MediaPlayer mp = null;
         AudioManager am = (AudioManager) getActivity().getSystemService(Context.AUDIO_SERVICE);
+        int ringerMode = am.getRingerMode();
+        am.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
         int volume = am.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
         am.setStreamVolume(AudioManager.STREAM_MUSIC,
                            am.getStreamMaxVolume(AudioManager.STREAM_MUSIC),
@@ -264,6 +266,7 @@
                 vc.release();
             }
             am.setStreamVolume(AudioManager.STREAM_MUSIC, volume, 0);
+            am.setRingerMode(ringerMode);
         }
         assertTrue(msg, result);
     }
@@ -276,6 +279,8 @@
         AudioEffect vc = null;
         MediaPlayer mp = null;
         AudioManager am = (AudioManager) getActivity().getSystemService(Context.AUDIO_SERVICE);
+        int ringerMode = am.getRingerMode();
+        am.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
         int volume = am.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
         am.setStreamVolume(AudioManager.STREAM_MUSIC,
                            am.getStreamMaxVolume(AudioManager.STREAM_MUSIC),
@@ -393,6 +398,7 @@
                 vc.release();
             }
             am.setStreamVolume(AudioManager.STREAM_MUSIC, volume, 0);
+            am.setRingerMode(ringerMode);
         }
         assertTrue(msg, result);
     }
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/mediarecorder/MediaRecorderTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/mediarecorder/MediaRecorderTest.java
index b5c8c8c..0684946 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/mediarecorder/MediaRecorderTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/mediarecorder/MediaRecorderTest.java
@@ -33,6 +33,7 @@
 import android.view.SurfaceHolder;
 import android.view.SurfaceView;
 import com.android.mediaframeworktest.MediaProfileReader;
+import com.android.mediaframeworktest.MediaFrameworkTestRunner;
 
 import android.test.suitebuilder.annotation.LargeTest;
 import android.test.suitebuilder.annotation.Suppress;
@@ -115,9 +116,16 @@
         int audioChannels = highQuality? audioCap.mMaxChannels: audioCap.mMinChannels ;
         int audioSamplingRate = highQuality? audioCap.mMaxSampleRate: audioCap.mMinSampleRate;
 
+        //Overide the fps if the min_camera_fps is set
+        if (MediaFrameworkTestRunner.mMinCameraFps != 0 &&
+            MediaFrameworkTestRunner.mMinCameraFps > videoFps){
+            videoFps = MediaFrameworkTestRunner.mMinCameraFps;
+        }
+
         if (videoFps < MIN_VIDEO_FPS) {
             videoFps = MIN_VIDEO_FPS;
         }
+
         mSurfaceHolder = MediaFrameworkTest.mSurfaceView.getHolder();
         String filename = ("/sdcard/" + videoEncoder + "_" + audioEncoder + "_" + highQuality + ".3gp");
         try {
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/videoeditor/VideoEditorPreviewTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/videoeditor/VideoEditorPreviewTest.java
index e848f5f..4181903 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/videoeditor/VideoEditorPreviewTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/videoeditor/VideoEditorPreviewTest.java
@@ -93,6 +93,7 @@
 
     private boolean previewStart;
     private boolean previewStop;
+    private boolean previewError;
 
     /* Minimum waiting time for Semaphore to wait for release */
     private final long minWaitingTime = 3000;
@@ -141,7 +142,9 @@
     protected void setPreviewStop() {
         previewStop = true;
     }
-
+    protected void setPreviewError() {
+        previewError = true;
+    }
     protected void validatePreviewProgress(int startMs, int endMs,
         boolean loop, long duration) throws Exception {
 
@@ -149,6 +152,7 @@
         final Semaphore blockTillPreviewCompletes = new Semaphore(1);
         previewStart = false;
         previewStop = false;
+        previewError = false;
         mVideoEditor.generatePreview(new MediaProcessingProgressListener() {
             int i = 0;
             public void onProgress(Object item, int action, int progress) {
@@ -187,6 +191,10 @@
                     setPreviewStop();
                     blockTillPreviewCompletes.release();
                 }
+                public void onError(VideoEditor videoEditor, int error) {
+                    setPreviewError();
+                    blockTillPreviewCompletes.release();
+                }
         });
         } catch (Exception e) {
             blockTillPreviewCompletes.release();
@@ -196,6 +204,7 @@
         mVideoEditor.stopPreview();
         assertTrue("Preview Failed to start", previewStart);
         assertTrue("Preview Failed to stop", previewStop);
+        assertFalse("Preview Error occurred", previewError);
 
         blockTillPreviewCompletes.release();
     }
@@ -399,6 +408,7 @@
             "TransitionSpiral_QVGA.jpg";
         previewStart = false;
         previewStop = false;
+        previewError = false;
 
         final Semaphore blockTillPreviewCompletes = new Semaphore(1);
 
@@ -490,6 +500,10 @@
                     setPreviewStop();
                     blockTillPreviewCompletes.release();
                 }
+                public void onError(VideoEditor videoEditor, int error) {
+                    setPreviewError();
+                    blockTillPreviewCompletes.release();
+                }
         });
         } catch (Exception e) {
             blockTillPreviewCompletes.release();
@@ -499,6 +513,7 @@
         blockTillPreviewCompletes.release();
         assertTrue("Preview Failed to start", previewStart);
         assertTrue("Preview Failed to stop", previewStop);
+        assertFalse("Preview Error occurred", previewError);
 
         assertEquals("Removing Transition " + transition1And2CrossFade.getId(),
             transition1And2CrossFade,
@@ -677,6 +692,7 @@
         final Semaphore blockTillPreviewCompletes = new Semaphore(1);
         previewStart = false;
         previewStop = false;
+        previewError = false;
 
         final MediaVideoItem mediaVideoItem1 =
             mVideoEditorHelper.createMediaItem(mVideoEditor, "m1",
@@ -693,7 +709,7 @@
 
 
         blockTillPreviewCompletes.acquire();
-                    final String fileName = mVideoEditor.getPath() + "\test.3gp";
+                    final String fileName = mVideoEditor.getPath() + "/test.3gp";
                     final int height = MediaProperties.HEIGHT_480;
                     final int bitrate = MediaProperties.BITRATE_512K;
 
@@ -727,6 +743,10 @@
                     setPreviewStop();
                     blockTillPreviewCompletes.release();
                 }
+                public void onError(VideoEditor videoEditor, int error) {
+                    setPreviewError();
+                    blockTillPreviewCompletes.release();
+                }
             });
 
         } catch (Exception e) {
@@ -736,6 +756,8 @@
         mVideoEditor.stopPreview();
         assertTrue("Preview Failed to start", previewStart);
         assertTrue("Preview Failed to stop", previewStop);
+        assertFalse("Preview Error occurred", previewError);
+
         blockTillPreviewCompletes.release();
     }
 
@@ -784,6 +806,10 @@
                     setPreviewStop();
                     blockTillPreviewCompletes.release();
                 }
+                public void onError(VideoEditor videoEditor, int error) {
+                    setPreviewError();
+                    blockTillPreviewCompletes.release();
+                }
         });
 
         } catch (IllegalArgumentException e) {
@@ -1023,7 +1049,10 @@
                     }
                     public void onStop(VideoEditor videoEditor) {
                         setPreviewStop();
-                }
+                    }
+                    public void onError(VideoEditor videoEditor, int error) {
+                        setPreviewError();
+                    }
             });
         }catch (IllegalArgumentException e) {
             flagForException = true;
@@ -1089,7 +1118,10 @@
                     }
                     public void onStop(VideoEditor videoEditor) {
                         setPreviewStop();
-                }
+                    }
+                    public void onError(VideoEditor videoEditor, int error) {
+                        setPreviewError();
+                    }
             });
         }catch (IllegalArgumentException e) {
             flagForException = true;
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/MediaPlayerPerformance.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/MediaPlayerPerformance.java
index 0b887b9..4f6e7d2 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/MediaPlayerPerformance.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/MediaPlayerPerformance.java
@@ -37,11 +37,13 @@
 import android.view.SurfaceHolder;
 
 import java.util.List;
+import java.io.BufferedReader;
 import java.io.FileDescriptor;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.InputStreamReader;
 import java.io.Writer;
 import java.io.File;
 import java.io.FileWriter;
@@ -68,6 +70,8 @@
     private static final long MEDIA_STRESS_WAIT_TIME = 5000; //5 seconds
     private static final String MEDIA_MEMORY_OUTPUT =
         "/sdcard/mediaMemOutput.txt";
+    private static final String MEDIA_PROCMEM_OUTPUT =
+        "/sdcard/mediaProcmemOutput.txt";
 
     private static int mStartMemory = 0;
     private static int mEndMemory = 0;
@@ -84,6 +88,9 @@
     private static int DECODER_LIMIT = 150;
     private static int CAMERA_LIMIT = 80;
 
+    private Writer mProcMemWriter;
+    private Writer mMemWriter;
+
     private static List<VideoEncoderCap> videoEncoders = MediaProfileReader.getVideoEncoders();
 
     Camera mCamera;
@@ -97,12 +104,21 @@
         getActivity();
         if (MediaFrameworkPerfTestRunner.mGetNativeHeapDump)
             MediaTestUtil.getNativeHeapDump(this.getName() + "_before");
+
+        mProcMemWriter = new BufferedWriter(new FileWriter
+                (new File(MEDIA_PROCMEM_OUTPUT), true));
+        mProcMemWriter.write(this.getName() + "\n");
+        mMemWriter = new BufferedWriter(new FileWriter
+                (new File(MEDIA_MEMORY_OUTPUT), true));
+
     }
 
     protected void tearDown() throws Exception {
-        super.tearDown();
         if (MediaFrameworkPerfTestRunner.mGetNativeHeapDump)
             MediaTestUtil.getNativeHeapDump(this.getName() + "_after");
+        mProcMemWriter.close();
+        mMemWriter.close();
+        super.tearDown();
     }
 
     private void initializeMessageLooper() {
@@ -247,24 +263,39 @@
     }
 
     //Write the ps output to the file
-    public void getMemoryWriteToLog(Writer output, int writeCount) {
+    public void getMemoryWriteToLog(int writeCount) {
         String memusage = null;
         try {
             if (writeCount == 0) {
                 mStartMemory = getMediaserverVsize();
-                output.write("Start memory : " + mStartMemory + "\n");
+                mMemWriter.write("Start memory : " + mStartMemory + "\n");
             }
             memusage = captureMediaserverInfo();
-            output.write(memusage);
+            mMemWriter.write(memusage);
             if (writeCount == NUM_STRESS_LOOP - 1) {
                 mEndMemory = getMediaserverVsize();
-                output.write("End Memory :" + mEndMemory + "\n");
+                mMemWriter.write("End Memory :" + mEndMemory + "\n");
             }
         } catch (Exception e) {
             e.toString();
         }
     }
 
+    public void writeProcmemInfo() throws Exception{
+        String cmd = "procmem " + getMediaserverPid();
+        Process p = Runtime.getRuntime().exec(cmd);
+
+        InputStream inStream = p.getInputStream();
+        InputStreamReader inReader = new InputStreamReader(inStream);
+        BufferedReader inBuffer = new BufferedReader(inReader);
+        String s;
+        while ((s = inBuffer.readLine()) != null) {
+              mProcMemWriter.write(s);
+              mProcMemWriter.write("\n");
+        }
+        mProcMemWriter.write("\n\n");
+    }
+
     public String captureMediaserverInfo() {
         String cm = "ps mediaserver";
         String memoryUsage = null;
@@ -306,7 +337,7 @@
         return vsizevalue;
     }
 
-    public boolean validateMemoryResult(int startPid, int startMemory, Writer output, int limit)
+    public boolean validateMemoryResult(int startPid, int startMemory, int limit)
             throws Exception {
         // Wait for 10 seconds to make sure the memory settle.
         Thread.sleep(10000);
@@ -315,11 +346,11 @@
         if (memDiff < 0) {
             memDiff = 0;
         }
-        output.write("The total diff = " + memDiff);
-        output.write("\n\n");
+        mMemWriter.write("The total diff = " + memDiff);
+        mMemWriter.write("\n\n");
         // mediaserver crash
         if (startPid != mEndPid) {
-            output.write("mediaserver died. Test failed\n");
+            mMemWriter.write("mediaserver died. Test failed\n");
             return false;
         }
         // memory leak greter than the tolerant
@@ -331,18 +362,16 @@
     @LargeTest
     public void testH263VideoPlaybackMemoryUsage() throws Exception {
         boolean memoryResult = false;
-        mStartPid = getMediaserverPid();
 
-        File h263MemoryOut = new File(MEDIA_MEMORY_OUTPUT);
-        Writer output = new BufferedWriter(new FileWriter(h263MemoryOut, true));
-        output.write("H263 Video Playback Only\n");
+        mStartPid = getMediaserverPid();
+        mMemWriter.write("H263 Video Playback Only\n");
         for (int i = 0; i < NUM_STRESS_LOOP; i++) {
             mediaStressPlayback(MediaNames.VIDEO_HIGHRES_H263);
-            getMemoryWriteToLog(output, i);
+            getMemoryWriteToLog(i);
+            writeProcmemInfo();
         }
-        output.write("\n");
-        memoryResult = validateMemoryResult(mStartPid, mStartMemory, output, DECODER_LIMIT);
-        output.close();
+        mMemWriter.write("\n");
+        memoryResult = validateMemoryResult(mStartPid, mStartMemory, DECODER_LIMIT);
         assertTrue("H263 playback memory test", memoryResult);
     }
 
@@ -350,18 +379,16 @@
     @LargeTest
     public void testH264VideoPlaybackMemoryUsage() throws Exception {
         boolean memoryResult = false;
-        mStartPid = getMediaserverPid();
 
-        File h264MemoryOut = new File(MEDIA_MEMORY_OUTPUT);
-        Writer output = new BufferedWriter(new FileWriter(h264MemoryOut, true));
-        output.write("H264 Video Playback only\n");
+        mStartPid = getMediaserverPid();
+        mMemWriter.write("H264 Video Playback only\n");
         for (int i = 0; i < NUM_STRESS_LOOP; i++) {
             mediaStressPlayback(MediaNames.VIDEO_H264_AMR);
-            getMemoryWriteToLog(output, i);
+            getMemoryWriteToLog(i);
+            writeProcmemInfo();
         }
-        output.write("\n");
-        memoryResult = validateMemoryResult(mStartPid, mStartMemory, output, DECODER_LIMIT);
-        output.close();
+        mMemWriter.write("\n");
+        memoryResult = validateMemoryResult(mStartPid, mStartMemory, DECODER_LIMIT);
         assertTrue("H264 playback memory test", memoryResult);
     }
 
@@ -369,21 +396,19 @@
     @LargeTest
     public void testH263RecordVideoOnlyMemoryUsage() throws Exception {
         boolean memoryResult = false;
-        mStartPid = getMediaserverPid();
 
-        File videoH263RecordOnlyMemoryOut = new File(MEDIA_MEMORY_OUTPUT);
-        Writer output = new BufferedWriter(new FileWriter(videoH263RecordOnlyMemoryOut, true));
-        output.write("H263 video record only\n");
+        mStartPid = getMediaserverPid();
+        mMemWriter.write("H263 video record only\n");
         int frameRate = MediaProfileReader.getMaxFrameRateForCodec(MediaRecorder.VideoEncoder.H263);
         assertTrue("H263 video recording frame rate", frameRate != -1);
         for (int i = 0; i < NUM_STRESS_LOOP; i++) {
             assertTrue(stressVideoRecord(frameRate, 352, 288, MediaRecorder.VideoEncoder.H263,
                     MediaRecorder.OutputFormat.MPEG_4, MediaNames.RECORDED_VIDEO_3GP, true));
-            getMemoryWriteToLog(output, i);
+            getMemoryWriteToLog(i);
+            writeProcmemInfo();
         }
-        output.write("\n");
-        memoryResult = validateMemoryResult(mStartPid, mStartMemory, output, ENCODER_LIMIT);
-        output.close();
+        mMemWriter.write("\n");
+        memoryResult = validateMemoryResult(mStartPid, mStartMemory, ENCODER_LIMIT);
         assertTrue("H263 record only memory test", memoryResult);
     }
 
@@ -391,21 +416,19 @@
     @LargeTest
     public void testMpeg4RecordVideoOnlyMemoryUsage() throws Exception {
         boolean memoryResult = false;
-        mStartPid = getMediaserverPid();
 
-        File videoMp4RecordOnlyMemoryOut = new File(MEDIA_MEMORY_OUTPUT);
-        Writer output = new BufferedWriter(new FileWriter(videoMp4RecordOnlyMemoryOut, true));
-        output.write("MPEG4 video record only\n");
+        mStartPid = getMediaserverPid();
+        mMemWriter.write("MPEG4 video record only\n");
         int frameRate = MediaProfileReader.getMaxFrameRateForCodec(MediaRecorder.VideoEncoder.MPEG_4_SP);
         assertTrue("MPEG4 video recording frame rate", frameRate != -1);
         for (int i = 0; i < NUM_STRESS_LOOP; i++) {
             assertTrue(stressVideoRecord(frameRate, 352, 288, MediaRecorder.VideoEncoder.MPEG_4_SP,
                     MediaRecorder.OutputFormat.MPEG_4, MediaNames.RECORDED_VIDEO_3GP, true));
-            getMemoryWriteToLog(output, i);
+            getMemoryWriteToLog(i);
+            writeProcmemInfo();
         }
-        output.write("\n");
-        memoryResult = validateMemoryResult(mStartPid, mStartMemory, output, ENCODER_LIMIT);
-        output.close();
+        mMemWriter.write("\n");
+        memoryResult = validateMemoryResult(mStartPid, mStartMemory, ENCODER_LIMIT);
         assertTrue("mpeg4 record only memory test", memoryResult);
     }
 
@@ -414,21 +437,19 @@
     @LargeTest
     public void testRecordVideoAudioMemoryUsage() throws Exception {
         boolean memoryResult = false;
-        mStartPid = getMediaserverPid();
 
-        File videoRecordAudioMemoryOut = new File(MEDIA_MEMORY_OUTPUT);
-        Writer output = new BufferedWriter(new FileWriter(videoRecordAudioMemoryOut, true));
+        mStartPid = getMediaserverPid();
         int frameRate = MediaProfileReader.getMaxFrameRateForCodec(MediaRecorder.VideoEncoder.H263);
         assertTrue("H263 video recording frame rate", frameRate != -1);
-        output.write("Audio and h263 video record\n");
+        mMemWriter.write("Audio and h263 video record\n");
         for (int i = 0; i < NUM_STRESS_LOOP; i++) {
             assertTrue(stressVideoRecord(frameRate, 352, 288, MediaRecorder.VideoEncoder.H263,
                     MediaRecorder.OutputFormat.MPEG_4, MediaNames.RECORDED_VIDEO_3GP, false));
-            getMemoryWriteToLog(output, i);
+            getMemoryWriteToLog(i);
+            writeProcmemInfo();
         }
-        output.write("\n");
-        memoryResult = validateMemoryResult(mStartPid, mStartMemory, output, ENCODER_LIMIT);
-        output.close();
+        mMemWriter.write("\n");
+        memoryResult = validateMemoryResult(mStartPid, mStartMemory, ENCODER_LIMIT);
         assertTrue("H263 audio video record memory test", memoryResult);
     }
 
@@ -436,18 +457,16 @@
     @LargeTest
     public void testRecordAudioOnlyMemoryUsage() throws Exception {
         boolean memoryResult = false;
-        mStartPid = getMediaserverPid();
 
-        File audioOnlyMemoryOut = new File(MEDIA_MEMORY_OUTPUT);
-        Writer output = new BufferedWriter(new FileWriter(audioOnlyMemoryOut, true));
-        output.write("Audio record only\n");
+        mStartPid = getMediaserverPid();
+        mMemWriter.write("Audio record only\n");
         for (int i = 0; i < NUM_STRESS_LOOP; i++) {
             stressAudioRecord(MediaNames.RECORDER_OUTPUT);
-            getMemoryWriteToLog(output, i);
+            getMemoryWriteToLog(i);
+            writeProcmemInfo();
         }
-        output.write("\n");
-        memoryResult = validateMemoryResult(mStartPid, mStartMemory, output, ENCODER_LIMIT);
-        output.close();
+        mMemWriter.write("\n");
+        memoryResult = validateMemoryResult(mStartPid, mStartMemory, ENCODER_LIMIT);
         assertTrue("audio record only memory test", memoryResult);
     }
 
@@ -455,18 +474,16 @@
     @LargeTest
     public void testCameraPreviewMemoryUsage() throws Exception {
         boolean memoryResult = false;
-        mStartPid = getMediaserverPid();
 
-        File cameraPreviewMemoryOut = new File(MEDIA_MEMORY_OUTPUT);
-        Writer output = new BufferedWriter(new FileWriter(cameraPreviewMemoryOut, true));
-        output.write("Camera Preview Only\n");
+        mStartPid = getMediaserverPid();
+        mMemWriter.write("Camera Preview Only\n");
         for (int i = 0; i < NUM_STRESS_LOOP; i++) {
             stressCameraPreview();
-            getMemoryWriteToLog(output, i);
+            getMemoryWriteToLog(i);
+            writeProcmemInfo();
         }
-        output.write("\n");
-        memoryResult = validateMemoryResult(mStartPid, mStartMemory, output, CAMERA_LIMIT);
-        output.close();
+        mMemWriter.write("\n");
+        memoryResult = validateMemoryResult(mStartPid, mStartMemory, CAMERA_LIMIT);
         assertTrue("camera preview memory test", memoryResult);
     }
 }
diff --git a/media/tests/README.txt b/media/tests/README.txt
new file mode 100644
index 0000000..e3e1639
--- /dev/null
+++ b/media/tests/README.txt
@@ -0,0 +1,10 @@
+MediaFrameworkTest/
+    Uses instrumentation and so can be run with runtest.
+    It assumes /sdcard/media_api/ has been populated.
+
+contents/media_api/
+    Push to /sdcard/media_api/ for use with MediaFrameworkTest:
+    adb shell mkdir /sdcard/media_api
+    adb push contents/media_api/ /sdcard/media_api/
+
+All other subdirectories are manual tests or sample apps.
diff --git a/native/include/android/keycodes.h b/native/include/android/keycodes.h
index 5d49775..8414ff6 100644
--- a/native/include/android/keycodes.h
+++ b/native/include/android/keycodes.h
@@ -250,6 +250,10 @@
     AKEYCODE_LANGUAGE_SWITCH = 204,
     AKEYCODE_MANNER_MODE     = 205,
     AKEYCODE_3D_MODE         = 206,
+    AKEYCODE_CONTACTS        = 207,
+    AKEYCODE_CALENDAR        = 208,
+    AKEYCODE_MUSIC           = 209,
+    AKEYCODE_CALCULATOR      = 210,
 
     // NOTE: If you add a new keycode here you must also add it to several other files.
     //       Refer to frameworks/base/core/java/android/view/KeyEvent.java for the full list.
diff --git a/opengl/libs/Android.mk b/opengl/libs/Android.mk
index 9c1a10e..66bc64d 100644
--- a/opengl/libs/Android.mk
+++ b/opengl/libs/Android.mk
@@ -18,7 +18,7 @@
 	EGL/Loader.cpp 	       \
 #
 
-LOCAL_SHARED_LIBRARIES += libcutils libutils libGLESv2_dbg
+LOCAL_SHARED_LIBRARIES += libcutils libutils libGLES_trace
 LOCAL_LDLIBS := -lpthread -ldl
 LOCAL_MODULE:= libEGL
 LOCAL_LDFLAGS += -Wl,--exclude-libs=ALL
diff --git a/opengl/libs/EGL/Loader.cpp b/opengl/libs/EGL/Loader.cpp
index 325193c..8a8898b 100644
--- a/opengl/libs/EGL/Loader.cpp
+++ b/opengl/libs/EGL/Loader.cpp
@@ -28,7 +28,7 @@
 #include <EGL/egl.h>
 
 #include "egldefs.h"
-#include "glesv2dbg.h"
+#include "glestrace.h"
 #include "hooks.h"
 #include "Loader.h"
 
@@ -157,7 +157,7 @@
 
 Loader::~Loader()
 {
-    StopDebugServer();
+    GLTrace_stop();
 }
 
 const char* Loader::getTag(int dpy, int impl)
diff --git a/opengl/libs/EGL/egl.cpp b/opengl/libs/EGL/egl.cpp
index 6ad06af..14745b3 100644
--- a/opengl/libs/EGL/egl.cpp
+++ b/opengl/libs/EGL/egl.cpp
@@ -37,7 +37,7 @@
 #include "egldefs.h"
 #include "egl_impl.h"
 #include "egl_tls.h"
-#include "glesv2dbg.h"
+#include "glestrace.h"
 #include "hooks.h"
 #include "Loader.h"
 
@@ -67,7 +67,6 @@
 static int sEGLApplicationTraceLevel;
 
 extern gl_hooks_t gHooksTrace;
-extern gl_hooks_t gHooksDebug;
 
 static inline void setGlTraceThreadSpecific(gl_hooks_t const *value) {
     pthread_setspecific(gGLTraceKey, value);
@@ -89,27 +88,17 @@
     char procPath[128] = {};
     sprintf(procPath, "/proc/%ld/cmdline", pid);
     FILE * file = fopen(procPath, "r");
-    if (file)
-    {
+    if (file) {
         char cmdline[256] = {};
-        if (fgets(cmdline, sizeof(cmdline) - 1, file))
-        {
+        if (fgets(cmdline, sizeof(cmdline) - 1, file)) {
             if (!strcmp(value, cmdline))
                 gEGLDebugLevel = 1;
         }
         fclose(file);
     }
 
-    if (gEGLDebugLevel > 0)
-    {
-        property_get("debug.egl.debug_port", value, "5039");
-        const unsigned short port = (unsigned short)atoi(value);
-        property_get("debug.egl.debug_forceUseFile", value, "0");
-        const bool forceUseFile = (bool)atoi(value);
-        property_get("debug.egl.debug_maxFileSize", value, "8");
-        const unsigned int maxFileSize = atoi(value) << 20;
-        property_get("debug.egl.debug_filePath", value, "/data/local/tmp/dump.gles2dbg");
-        StartDebugServer(port, forceUseFile, maxFileSize, value);
+    if (gEGLDebugLevel > 0) {
+        GLTrace_start();
     }
 }
 
@@ -119,7 +108,7 @@
         setGlThreadSpecific(&gHooksTrace);
     } else if (gEGLDebugLevel > 0 && value != &gHooksNoContext) {
         setGlTraceThreadSpecific(value);
-        setGlThreadSpecific(&gHooksDebug);
+        setGlThreadSpecific(GLTrace_getGLHooks());
     } else {
         setGlThreadSpecific(value);
     }
diff --git a/opengl/libs/EGL/eglApi.cpp b/opengl/libs/EGL/eglApi.cpp
index a63d5b0..1dbba3f 100644
--- a/opengl/libs/EGL/eglApi.cpp
+++ b/opengl/libs/EGL/eglApi.cpp
@@ -37,7 +37,7 @@
 
 #include "egl_impl.h"
 #include "egl_tls.h"
-#include "glesv2dbg.h"
+#include "glestrace.h"
 #include "hooks.h"
 
 #include "egl_display.h"
@@ -49,6 +49,8 @@
 
 // ----------------------------------------------------------------------------
 
+#define EGL_VERSION_HW_ANDROID  0x3143
+
 struct extention_map_t {
     const char* name;
     __eglMustCastToProperFunctionPointerType address;
@@ -110,7 +112,6 @@
 extern const __eglMustCastToProperFunctionPointerType gExtensionForwarders[MAX_NUMBER_OF_GL_EXTENSIONS];
 extern int gEGLDebugLevel;
 extern gl_hooks_t gHooksTrace;
-extern gl_hooks_t gHooksDebug;
 } // namespace android;
 
 // ----------------------------------------------------------------------------
@@ -514,6 +515,10 @@
             }
             egl_context_t* c = new egl_context_t(dpy, context, config,
                     dp->configs[intptr_t(config)].impl, cnx, version);
+#if EGL_TRACE
+            if (gEGLDebugLevel > 0)
+                GLTrace_eglCreateContext(version, c);
+#endif
             return c;
         }
     }
@@ -655,9 +660,10 @@
         if (ctx != EGL_NO_CONTEXT) {
             setGLHooksThreadSpecific(c->cnx->hooks[c->version]);
             egl_tls_t::setContext(ctx);
-            if (gEGLDebugLevel > 0) {
-                CreateDbgContext(c->version, c->cnx->hooks[c->version]);
-            }
+#if EGL_TRACE
+            if (gEGLDebugLevel > 0)
+                GLTrace_eglMakeCurrent(c->version, c->cnx->hooks[c->version]);
+#endif
             _c.acquire();
             _r.acquire();
             _d.acquire();
@@ -884,6 +890,10 @@
                 "no more slots for eglGetProcAddress(\"%s\")",
                 procname);
 
+#if EGL_TRACE
+        gl_hooks_t *debugHooks = GLTrace_getGLHooks();
+#endif
+
         if (!addr && (slot < MAX_NUMBER_OF_GL_EXTENSIONS)) {
             bool found = false;
             for (int i=0 ; i<IMPL_NUM_IMPLEMENTATIONS ; i++) {
@@ -894,7 +904,7 @@
                     cnx->hooks[GLESv1_INDEX]->ext.extensions[slot] =
                     cnx->hooks[GLESv2_INDEX]->ext.extensions[slot] =
 #if EGL_TRACE
-                    gHooksDebug.ext.extensions[slot] = gHooksTrace.ext.extensions[slot] =
+                    debugHooks->ext.extensions[slot] = gHooksTrace.ext.extensions[slot] =
 #endif
                             cnx->egl.eglGetProcAddress(procname);
                 }
@@ -922,10 +932,6 @@
 
 EGLBoolean eglSwapBuffers(EGLDisplay dpy, EGLSurface draw)
 {
-    EGLBoolean Debug_eglSwapBuffers(EGLDisplay dpy, EGLSurface draw);
-    if (gEGLDebugLevel > 0)
-        Debug_eglSwapBuffers(dpy, draw);
-
     clearError();
 
     egl_display_t const * const dp = validate_display(dpy);
@@ -935,6 +941,11 @@
     if (!_s.get())
         return setError(EGL_BAD_SURFACE, EGL_FALSE);
 
+#if EGL_TRACE
+    if (gEGLDebugLevel > 0)
+        GLTrace_eglSwapBuffers(dpy, draw);
+#endif
+
     egl_surface_t const * const s = get_surface(draw);
     return s->cnx->egl.eglSwapBuffers(dp->disp[s->impl].dpy, s->surface);
 }
@@ -972,6 +983,12 @@
             return dp->getExtensionString();
         case EGL_CLIENT_APIS:
             return dp->getClientApiString();
+        case EGL_VERSION_HW_ANDROID: {
+            if (gEGLImpl[IMPL_HARDWARE].dso) {
+                return dp->disp[IMPL_HARDWARE].queryString.version;
+            }
+            return dp->disp[IMPL_SOFTWARE].queryString.version;
+        }
     }
     return setError(EGL_BAD_PARAMETER, (const char *)0);
 }
@@ -1154,7 +1171,10 @@
         }
     }
     egl_tls_t::clearTLS();
-    dbgReleaseThread();
+#if EGL_TRACE
+    if (gEGLDebugLevel > 0)
+        GLTrace_eglReleaseThread();
+#endif
     return EGL_TRUE;
 }
 
diff --git a/opengl/libs/EGL/egl_tls.cpp b/opengl/libs/EGL/egl_tls.cpp
index b341ddb..6946ecd 100644
--- a/opengl/libs/EGL/egl_tls.cpp
+++ b/opengl/libs/EGL/egl_tls.cpp
@@ -33,7 +33,7 @@
 pthread_mutex_t egl_tls_t::sLockKey = PTHREAD_MUTEX_INITIALIZER;
 
 egl_tls_t::egl_tls_t()
-    : error(EGL_SUCCESS), ctx(0), logCallWithNoContext(EGL_TRUE), dbg(0) {
+    : error(EGL_SUCCESS), ctx(0), logCallWithNoContext(EGL_TRUE) {
 }
 
 const char *egl_tls_t::egl_strerror(EGLint err) {
diff --git a/opengl/libs/EGL/egl_tls.h b/opengl/libs/EGL/egl_tls.h
index 78b0b2f..2442ca0 100644
--- a/opengl/libs/EGL/egl_tls.h
+++ b/opengl/libs/EGL/egl_tls.h
@@ -37,7 +37,6 @@
     EGLint      error;
     EGLContext  ctx;
     EGLBoolean  logCallWithNoContext;
-    DbgContext* dbg;
 
     egl_tls_t();
     static void validateTLSKey();
diff --git a/opengl/libs/EGL/trace.cpp b/opengl/libs/EGL/trace.cpp
index 0e934e2..bd6c348 100644
--- a/opengl/libs/EGL/trace.cpp
+++ b/opengl/libs/EGL/trace.cpp
@@ -375,22 +375,6 @@
 #undef TRACE_GL_VOID
 #undef TRACE_GL
 
-// declare all Debug_gl* functions
-#define GL_ENTRY(_r, _api, ...) _r Debug_##_api ( __VA_ARGS__ );
-#include "glesv2dbg_functions.h"
-#undef GL_ENTRY
-
-#define GL_ENTRY(_r, _api, ...) Debug_ ## _api,
-EGLAPI gl_hooks_t gHooksDebug = {
-    {
-        #include "entries.in"
-    },
-    {
-        {0}
-    }
-};
-#undef GL_ENTRY
-
 // ----------------------------------------------------------------------------
 }; // namespace android
 // ----------------------------------------------------------------------------
diff --git a/opengl/libs/GLES_trace/.gitignore b/opengl/libs/GLES_trace/.gitignore
new file mode 100644
index 0000000..8df825e
--- /dev/null
+++ b/opengl/libs/GLES_trace/.gitignore
@@ -0,0 +1,4 @@
+java
+*.pyc
+*.swp
+pyratemp.py
diff --git a/opengl/libs/GLES2_dbg/Android.mk b/opengl/libs/GLES_trace/Android.mk
similarity index 69%
rename from opengl/libs/GLES2_dbg/Android.mk
rename to opengl/libs/GLES_trace/Android.mk
index 70853d8..465b6b2 100644
--- a/opengl/libs/GLES2_dbg/Android.mk
+++ b/opengl/libs/GLES_trace/Android.mk
@@ -3,13 +3,14 @@
 include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES := \
-    src/api.cpp \
-    src/caller.cpp \
-    src/dbgcontext.cpp \
-    src/debugger_message.pb.cpp \
-    src/egl.cpp \
-    src/server.cpp \
-    src/vertex.cpp
+    src/gltrace_api.cpp \
+    src/gltrace_context.cpp \
+    src/gltrace_egl.cpp \
+    src/gltrace_eglapi.cpp \
+    src/gltrace_fixup.cpp \
+    src/gltrace_hooks.cpp \
+    src/gltrace.pb.cpp \
+    src/gltrace_transport.cpp
 
 LOCAL_C_INCLUDES := \
     $(LOCAL_PATH) \
@@ -19,20 +20,15 @@
     external \
     bionic
 
-#LOCAL_CFLAGS += -O0 -g -DDEBUG -UNDEBUG
 LOCAL_CFLAGS := -DGOOGLE_PROTOBUF_NO_RTTI
 LOCAL_STATIC_LIBRARIES := libprotobuf-cpp-2.3.0-lite liblzf
 LOCAL_SHARED_LIBRARIES := libcutils libutils libstlport
-ifeq ($(TARGET_ARCH),arm)
-	LOCAL_CFLAGS += -fstrict-aliasing
-endif
 
 ifeq ($(ARCH_ARM_HAVE_TLS_REGISTER),true)
     LOCAL_CFLAGS += -DHAVE_ARM_TLS_REGISTER
 endif
 
-LOCAL_CFLAGS += -DLOG_TAG=\"libGLES2_dbg\"
-
+LOCAL_CFLAGS += -DLOG_TAG=\"libGLES_trace\"
 
 # we need to access the private Bionic header <bionic_tls.h>
 # on ARM platforms, we need to mirror the ARCH_ARM_HAVE_TLS_REGISTER
@@ -42,9 +38,7 @@
 endif
 LOCAL_C_INCLUDES += bionic/libc/private
 
-LOCAL_MODULE:= libGLESv2_dbg
+LOCAL_MODULE:= libGLES_trace
 LOCAL_MODULE_TAGS := optional
 
 include $(BUILD_SHARED_LIBRARY)
-
-include $(LOCAL_PATH)/test/Android.mk
diff --git a/opengl/libs/GLES_trace/DESIGN.txt b/opengl/libs/GLES_trace/DESIGN.txt
new file mode 100644
index 0000000..a189e1d
--- /dev/null
+++ b/opengl/libs/GLES_trace/DESIGN.txt
@@ -0,0 +1,51 @@
+Design of the GLES Tracing Library
+
+Code Runtime Behavior:
+
+    Initialization:
+    
+    egl_display_t::initialize() calls initEglTraceLevel() to figure out whether tracing should be
+    enabled. Currently, the shell properties "debug.egl.trace" and "debug.egl.debug_proc" together
+    control whether tracing should be enabled for a certain process. If tracing is enabled, this
+    calls GLTrace_start() to start the trace server.
+    
+    Note that initEglTraceLevel() is also called from early_egl_init(), but that happens in the
+    context of the zygote, so that invocation has no effect.
+    
+    egl_display_t::initialize() then calls setGLHooksThreadSpecific() where we set the thread
+    specific gl_hooks structure to point to the trace implementation. From this point on, every
+    GLES call is redirected to the trace implementation.
+    
+    Application runtime:
+
+    While the application is running, all its GLES calls are directly routed to their corresponding
+    trace implementation.
+
+    For EGL calls, the trace library provides a bunch of functions that must be explicitly called
+    from the EGL library. These functions are declared in glestrace.h
+
+    Application shutdown:
+
+    Currently, the application is killed when the user stops tracing from the frontend GUI. We need
+    to explore if a more graceful method of stopping the application, or detaching tracing from the
+    application is required.
+
+Code Structure:
+
+    glestrace.h declares all the hooks exposed by libglestrace. These are used by EGL/egl.cpp and
+    EGL/eglApi.cpp to initialize the trace library, and to inform the library of EGL calls.
+
+    All GL calls are present in GLES_Trace/src/gltrace_api.cpp. This file is generated by the
+    GLES_Trace/src/genapi.py script. The structure of all the functions looks like this:
+
+            void GLTrace_glFunction(args) {
+                // declare a protobuf
+                // copy arguments into the protobuf
+                // call the original GLES function
+                // if there is a return value, save it into the protobuf
+                // fixup the protobuf if necessary
+                // transport the protobuf to the host
+            }
+
+    The fixupGLMessage() call does any custom processing of the protobuf based on the GLES call.
+    This typically amounts to copying the data corresponding to input or output pointers.
diff --git a/opengl/libs/GLES_trace/TODO.txt b/opengl/libs/GLES_trace/TODO.txt
new file mode 100644
index 0000000..f5e6e95
--- /dev/null
+++ b/opengl/libs/GLES_trace/TODO.txt
@@ -0,0 +1,14 @@
+TODO:
+    - Context - Currently, we don't do anything regarding the contexts that are created.
+    Need to maintain more state regarding contexts, and figure out what happens in the
+    presence of multiple contexts.
+
+    - Transport: Each GLMessage is sent via a socket as soon as the message is received.
+    i.e., there is no buffering of messages. Buffering should improve performance.
+
+    - Initialization: On first connection, send some basic information that includes:
+        1. version of the trace library
+        2. implementation dependent GL state variables such as # of vertex arrays etc.
+
+    - eglSwapBuffers: The images are lzf compressed, but there is no mode that transfers
+    only the differences from the previous images.
diff --git a/opengl/libs/GLES_trace/dev.make b/opengl/libs/GLES_trace/dev.make
new file mode 100644
index 0000000..1d89999
--- /dev/null
+++ b/opengl/libs/GLES_trace/dev.make
@@ -0,0 +1,15 @@
+## NOTE
+## This file is used for development purposes only. It is not used by the build system.
+
+# generate protocol buffer files
+genproto: gltrace.proto
+	aprotoc --cpp_out=src --java_out=java gltrace.proto
+	mv src/gltrace.pb.cc src/gltrace.pb.cpp
+
+# NOTE: $OUT should be defined in the shell by doing a "lunch <config>"
+# push updated files to device
+push:
+	adb push $(OUT)/system/lib/libGLESv2.so /system/lib/
+	adb push $(OUT)/system/lib/libGLESv1_CM.so /system/lib/
+	adb push $(OUT)/system/lib/libGLES_trace.so /system/lib/
+	adb push $(OUT)/system/lib/libEGL.so /system/lib/
diff --git a/opengl/libs/GLES_trace/gltrace.proto b/opengl/libs/GLES_trace/gltrace.proto
new file mode 100644
index 0000000..12d8e7c
--- /dev/null
+++ b/opengl/libs/GLES_trace/gltrace.proto
@@ -0,0 +1,488 @@
+/*
+ * 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.gltrace;
+
+option optimize_for = LITE_RUNTIME;
+
+option java_package = "com.android.ide.eclipse.gltrace";
+option java_outer_classname = "GLProtoBuf";
+
+message GLMessage {
+    enum Function {
+        glActiveTexture = 0;
+        glAlphaFunc = 1;
+        glAlphaFuncx = 2;
+        glAlphaFuncxOES = 3;
+        glAttachShader = 4;
+        glBeginPerfMonitorAMD = 5;
+        glBindAttribLocation = 6;
+        glBindBuffer = 7;
+        glBindFramebuffer = 8;
+        glBindFramebufferOES = 9;
+        glBindRenderbuffer = 10;
+        glBindRenderbufferOES = 11;
+        glBindTexture = 12;
+        glBindVertexArrayOES = 13;
+        glBlendColor = 14;
+        glBlendEquation = 15;
+        glBlendEquationOES = 16;
+        glBlendEquationSeparate = 17;
+        glBlendEquationSeparateOES = 18;
+        glBlendFunc = 19;
+        glBlendFuncSeparate = 20;
+        glBlendFuncSeparateOES = 21;
+        glBufferData = 22;
+        glBufferSubData = 23;
+        glCheckFramebufferStatus = 24;
+        glCheckFramebufferStatusOES = 25;
+        glClearColor = 26;
+        glClearColorx = 27;
+        glClearColorxOES = 28;
+        glClearDepthf = 29;
+        glClearDepthfOES = 30;
+        glClearDepthx = 31;
+        glClearDepthxOES = 32;
+        glClear = 33;
+        glClearStencil = 34;
+        glClientActiveTexture = 35;
+        glClipPlanef = 36;
+        glClipPlanefIMG = 37;
+        glClipPlanefOES = 38;
+        glClipPlanex = 39;
+        glClipPlanexIMG = 40;
+        glClipPlanexOES = 41;
+        glColor4f = 42;
+        glColor4ub = 43;
+        glColor4x = 44;
+        glColor4xOES = 45;
+        glColorMask = 46;
+        glColorPointer = 47;
+        glCompileShader = 48;
+        glCompressedTexImage2D = 49;
+        glCompressedTexImage3DOES = 50;
+        glCompressedTexSubImage2D = 51;
+        glCompressedTexSubImage3DOES = 52;
+        glCopyTexImage2D = 53;
+        glCopyTexSubImage2D = 54;
+        glCopyTexSubImage3DOES = 55;
+        glCoverageMaskNV = 56;
+        glCoverageOperationNV = 57;
+        glCreateProgram = 58;
+        glCreateShader = 59;
+        glCullFace = 60;
+        glCurrentPaletteMatrixOES = 61;
+        glDeleteBuffers = 62;
+        glDeleteFencesNV = 63;
+        glDeleteFramebuffers = 64;
+        glDeleteFramebuffersOES = 65;
+        glDeletePerfMonitorsAMD = 66;
+        glDeleteProgram = 67;
+        glDeleteRenderbuffers = 68;
+        glDeleteRenderbuffersOES = 69;
+        glDeleteShader = 70;
+        glDeleteTextures = 71;
+        glDeleteVertexArraysOES = 72;
+        glDepthFunc = 73;
+        glDepthMask = 74;
+        glDepthRangef = 75;
+        glDepthRangefOES = 76;
+        glDepthRangex = 77;
+        glDepthRangexOES = 78;
+        glDetachShader = 79;
+        glDisableClientState = 80;
+        glDisableDriverControlQCOM = 81;
+        glDisable = 82;
+        glDisableVertexAttribArray = 83;
+        glDiscardFramebufferEXT = 84;
+        glDrawArrays = 85;
+        glDrawElements = 86;
+        glDrawTexfOES = 87;
+        glDrawTexfvOES = 88;
+        glDrawTexiOES = 89;
+        glDrawTexivOES = 90;
+        glDrawTexsOES = 91;
+        glDrawTexsvOES = 92;
+        glDrawTexxOES = 93;
+        glDrawTexxvOES = 94;
+        glEGLImageTargetRenderbufferStorageOES = 95;
+        glEGLImageTargetTexture2DOES = 96;
+        glEnableClientState = 97;
+        glEnableDriverControlQCOM = 98;
+        glEnable = 99;
+        glEnableVertexAttribArray = 100;
+        glEndPerfMonitorAMD = 101;
+        glEndTilingQCOM = 102;
+        glExtGetBufferPointervQCOM = 103;
+        glExtGetBuffersQCOM = 104;
+        glExtGetFramebuffersQCOM = 105;
+        glExtGetProgramBinarySourceQCOM = 106;
+        glExtGetProgramsQCOM = 107;
+        glExtGetRenderbuffersQCOM = 108;
+        glExtGetShadersQCOM = 109;
+        glExtGetTexLevelParameterivQCOM = 110;
+        glExtGetTexSubImageQCOM = 111;
+        glExtGetTexturesQCOM = 112;
+        glExtIsProgramBinaryQCOM = 113;
+        glExtTexObjectStateOverrideiQCOM = 114;
+        glFinishFenceNV = 115;
+        glFinish = 116;
+        glFlush = 117;
+        glFogf = 118;
+        glFogfv = 119;
+        glFogx = 120;
+        glFogxOES = 121;
+        glFogxv = 122;
+        glFogxvOES = 123;
+        glFramebufferRenderbuffer = 124;
+        glFramebufferRenderbufferOES = 125;
+        glFramebufferTexture2D = 126;
+        glFramebufferTexture2DMultisampleIMG = 127;
+        glFramebufferTexture2DOES = 128;
+        glFramebufferTexture3DOES = 129;
+        glFrontFace = 130;
+        glFrustumf = 131;
+        glFrustumfOES = 132;
+        glFrustumx = 133;
+        glFrustumxOES = 134;
+        glGenBuffers = 135;
+        glGenerateMipmap = 136;
+        glGenerateMipmapOES = 137;
+        glGenFencesNV = 138;
+        glGenFramebuffers = 139;
+        glGenFramebuffersOES = 140;
+        glGenPerfMonitorsAMD = 141;
+        glGenRenderbuffers = 142;
+        glGenRenderbuffersOES = 143;
+        glGenTextures = 144;
+        glGenVertexArraysOES = 145;
+        glGetActiveAttrib = 146;
+        glGetActiveUniform = 147;
+        glGetAttachedShaders = 148;
+        glGetAttribLocation = 149;
+        glGetBooleanv = 150;
+        glGetBufferParameteriv = 151;
+        glGetBufferPointervOES = 152;
+        glGetClipPlanef = 153;
+        glGetClipPlanefOES = 154;
+        glGetClipPlanex = 155;
+        glGetClipPlanexOES = 156;
+        glGetDriverControlsQCOM = 157;
+        glGetDriverControlStringQCOM = 158;
+        glGetError = 159;
+        glGetFenceivNV = 160;
+        glGetFixedv = 161;
+        glGetFixedvOES = 162;
+        glGetFloatv = 163;
+        glGetFramebufferAttachmentParameteriv = 164;
+        glGetFramebufferAttachmentParameterivOES = 165;
+        glGetIntegerv = 166;
+        glGetLightfv = 167;
+        glGetLightxv = 168;
+        glGetLightxvOES = 169;
+        glGetMaterialfv = 170;
+        glGetMaterialxv = 171;
+        glGetMaterialxvOES = 172;
+        glGetPerfMonitorCounterDataAMD = 173;
+        glGetPerfMonitorCounterInfoAMD = 174;
+        glGetPerfMonitorCountersAMD = 175;
+        glGetPerfMonitorCounterStringAMD = 176;
+        glGetPerfMonitorGroupsAMD = 177;
+        glGetPerfMonitorGroupStringAMD = 178;
+        glGetPointerv = 179;
+        glGetProgramBinaryOES = 180;
+        glGetProgramInfoLog = 181;
+        glGetProgramiv = 182;
+        glGetRenderbufferParameteriv = 183;
+        glGetRenderbufferParameterivOES = 184;
+        glGetShaderInfoLog = 185;
+        glGetShaderiv = 186;
+        glGetShaderPrecisionFormat = 187;
+        glGetShaderSource = 188;
+        glGetString = 189;
+        glGetTexEnvfv = 190;
+        glGetTexEnviv = 191;
+        glGetTexEnvxv = 192;
+        glGetTexEnvxvOES = 193;
+        glGetTexGenfvOES = 194;
+        glGetTexGenivOES = 195;
+        glGetTexGenxvOES = 196;
+        glGetTexParameterfv = 197;
+        glGetTexParameteriv = 198;
+        glGetTexParameterxv = 199;
+        glGetTexParameterxvOES = 200;
+        glGetUniformfv = 201;
+        glGetUniformiv = 202;
+        glGetUniformLocation = 203;
+        glGetVertexAttribfv = 204;
+        glGetVertexAttribiv = 205;
+        glGetVertexAttribPointerv = 206;
+        glHint = 207;
+        glIsBuffer = 208;
+        glIsEnabled = 209;
+        glIsFenceNV = 210;
+        glIsFramebuffer = 211;
+        glIsFramebufferOES = 212;
+        glIsProgram = 213;
+        glIsRenderbuffer = 214;
+        glIsRenderbufferOES = 215;
+        glIsShader = 216;
+        glIsTexture = 217;
+        glIsVertexArrayOES = 218;
+        glLightf = 219;
+        glLightfv = 220;
+        glLightModelf = 221;
+        glLightModelfv = 222;
+        glLightModelx = 223;
+        glLightModelxOES = 224;
+        glLightModelxv = 225;
+        glLightModelxvOES = 226;
+        glLightx = 227;
+        glLightxOES = 228;
+        glLightxv = 229;
+        glLightxvOES = 230;
+        glLineWidth = 231;
+        glLineWidthx = 232;
+        glLineWidthxOES = 233;
+        glLinkProgram = 234;
+        glLoadIdentity = 235;
+        glLoadMatrixf = 236;
+        glLoadMatrixx = 237;
+        glLoadMatrixxOES = 238;
+        glLoadPaletteFromModelViewMatrixOES = 239;
+        glLogicOp = 240;
+        glMapBufferOES = 241;
+        glMaterialf = 242;
+        glMaterialfv = 243;
+        glMaterialx = 244;
+        glMaterialxOES = 245;
+        glMaterialxv = 246;
+        glMaterialxvOES = 247;
+        glMatrixIndexPointerOES = 248;
+        glMatrixMode = 249;
+        glMultiDrawArraysEXT = 250;
+        glMultiDrawElementsEXT = 251;
+        glMultiTexCoord4f = 252;
+        glMultiTexCoord4x = 253;
+        glMultiTexCoord4xOES = 254;
+        glMultMatrixf = 255;
+        glMultMatrixx = 256;
+        glMultMatrixxOES = 257;
+        glNormal3f = 258;
+        glNormal3x = 259;
+        glNormal3xOES = 260;
+        glNormalPointer = 261;
+        glOrthof = 262;
+        glOrthofOES = 263;
+        glOrthox = 264;
+        glOrthoxOES = 265;
+        glPixelStorei = 266;
+        glPointParameterf = 267;
+        glPointParameterfv = 268;
+        glPointParameterx = 269;
+        glPointParameterxOES = 270;
+        glPointParameterxv = 271;
+        glPointParameterxvOES = 272;
+        glPointSize = 273;
+        glPointSizePointerOES = 274;
+        glPointSizex = 275;
+        glPointSizexOES = 276;
+        glPolygonOffset = 277;
+        glPolygonOffsetx = 278;
+        glPolygonOffsetxOES = 279;
+        glPopMatrix = 280;
+        glProgramBinaryOES = 281;
+        glPushMatrix = 282;
+        glQueryMatrixxOES = 283;
+        glReadPixels = 284;
+        glReleaseShaderCompiler = 285;
+        glRenderbufferStorage = 286;
+        glRenderbufferStorageMultisampleIMG = 287;
+        glRenderbufferStorageOES = 288;
+        glRotatef = 289;
+        glRotatex = 290;
+        glRotatexOES = 291;
+        glSampleCoverage = 292;
+        glSampleCoveragex = 293;
+        glSampleCoveragexOES = 294;
+        glScalef = 295;
+        glScalex = 296;
+        glScalexOES = 297;
+        glScissor = 298;
+        glSelectPerfMonitorCountersAMD = 299;
+        glSetFenceNV = 300;
+        glShadeModel = 301;
+        glShaderBinary = 302;
+        glShaderSource = 303;
+        glStartTilingQCOM = 304;
+        glStencilFunc = 305;
+        glStencilFuncSeparate = 306;
+        glStencilMask = 307;
+        glStencilMaskSeparate = 308;
+        glStencilOp = 309;
+        glStencilOpSeparate = 310;
+        glTestFenceNV = 311;
+        glTexCoordPointer = 312;
+        glTexEnvf = 313;
+        glTexEnvfv = 314;
+        glTexEnvi = 315;
+        glTexEnviv = 316;
+        glTexEnvx = 317;
+        glTexEnvxOES = 318;
+        glTexEnvxv = 319;
+        glTexEnvxvOES = 320;
+        glTexGenfOES = 321;
+        glTexGenfvOES = 322;
+        glTexGeniOES = 323;
+        glTexGenivOES = 324;
+        glTexGenxOES = 325;
+        glTexGenxvOES = 326;
+        glTexImage2D = 327;
+        glTexImage3DOES = 328;
+        glTexParameterf = 329;
+        glTexParameterfv = 330;
+        glTexParameteri = 331;
+        glTexParameteriv = 332;
+        glTexParameterx = 333;
+        glTexParameterxOES = 334;
+        glTexParameterxv = 335;
+        glTexParameterxvOES = 336;
+        glTexSubImage2D = 337;
+        glTexSubImage3DOES = 338;
+        glTranslatef = 339;
+        glTranslatex = 340;
+        glTranslatexOES = 341;
+        glUniform1f = 342;
+        glUniform1fv = 343;
+        glUniform1i = 344;
+        glUniform1iv = 345;
+        glUniform2f = 346;
+        glUniform2fv = 347;
+        glUniform2i = 348;
+        glUniform2iv = 349;
+        glUniform3f = 350;
+        glUniform3fv = 351;
+        glUniform3i = 352;
+        glUniform3iv = 353;
+        glUniform4f = 354;
+        glUniform4fv = 355;
+        glUniform4i = 356;
+        glUniform4iv = 357;
+        glUniformMatrix2fv = 358;
+        glUniformMatrix3fv = 359;
+        glUniformMatrix4fv = 360;
+        glUnmapBufferOES = 361;
+        glUseProgram = 362;
+        glValidateProgram = 363;
+        glVertexAttrib1f = 364;
+        glVertexAttrib1fv = 365;
+        glVertexAttrib2f = 366;
+        glVertexAttrib2fv = 367;
+        glVertexAttrib3f = 368;
+        glVertexAttrib3fv = 369;
+        glVertexAttrib4f = 370;
+        glVertexAttrib4fv = 371;
+        glVertexAttribPointer = 372;
+        glVertexPointer = 373;
+        glViewport = 374;
+        glWeightPointerOES = 375;
+
+        eglGetDisplay = 2000;
+        eglInitialize = 2001;
+        eglTerminate = 2002;
+        eglGetConfigs = 2003;
+        eglChooseConfig = 2004;
+        eglGetConfigAttrib = 2005;
+        eglCreateWindowSurface = 2006;
+        eglCreatePixmapSurface = 2007;
+        eglCreatePbufferSurface = 2008;
+        eglDestroySurface = 2009;
+        eglQuerySurface = 2010;
+        eglCreateContext = 2011;
+        eglDestroyContext = 2012;
+        eglMakeCurrent = 2013;
+        eglGetCurrentContext = 2014;
+        eglGetCurrentSurface = 2015;
+        eglGetCurrentDisplay = 2016;
+        eglQueryContext = 2017;
+        eglWaitGL = 2018;
+        eglWaitNative = 2019;
+        eglSwapBuffers = 2020;
+        eglCopyBuffers = 2021;
+        eglGetError = 2022;
+        eglQueryString = 2023;
+        eglGetProcAddress = 2024;
+        eglSurfaceAttrib = 2025;
+        eglBindTexImage = 2026;
+        eglReleaseTexImage = 2027;
+        eglSwapInterval = 2028;
+        eglBindAPI = 2029;
+        eglQueryAPI = 2030;
+        eglWaitClient = 2031;
+        eglReleaseThread = 2032;
+        eglCreatePbufferFromClientBuffer = 2033;
+        eglLockSurfaceKHR = 2034;
+        eglUnlockSurfaceKHR = 2035;
+        eglCreateImageKHR = 2036;
+        eglDestroyImageKHR = 2037;
+        eglCreateSyncKHR = 2038;
+        eglDestroySyncKHR = 2039;
+        eglClientWaitSyncKHR = 2040;
+        eglGetSyncAttribKHR = 2041;
+        eglSetSwapRectangleANDROID = 2042;
+        eglGetRenderBufferANDROID = 2043;
+        eglGetSystemTimeFrequencyNV = 2044;
+        eglGetSystemTimeNV = 2045;
+
+        invalid = 3000;
+        frameBufferContents = 3001;
+    }
+
+    // A GL call's return data and arguments are formatted into this DataType
+    message DataType {
+        enum Type {
+            VOID = 1;       // GLvoid
+            CHAR = 2;       // GLchar
+            BYTE = 3;       // GLbyte, GLubyte
+            INT = 4;        // GLbitfield, GLshort, GLint, GLsizei, GLushort, GLuint, GLfixed
+            FLOAT = 5;      // GLfloat, GLclampf
+            BOOL = 6;       // GLboolean
+            ENUM = 7;       // GLenum
+        };
+
+        required Type   type = 1 [default = VOID];
+        required bool   isArray = 2 [default = false];
+
+        repeated int32  intValue = 3;
+        repeated float  floatValue = 4;
+        repeated bytes  charValue = 5;
+        repeated bytes  rawBytes = 6;
+        repeated bool   boolValue = 7;
+    }
+
+    message FrameBuffer {
+        required int32  width = 1;
+        required int32  height = 2;
+        repeated bytes  contents = 3;
+    }
+
+    required int32      context_id = 1;                     // GL context ID
+    required Function   function = 2 [default = invalid];   // GL function called
+    repeated DataType   args = 3;                           // GL function's arguments
+    optional DataType   returnValue = 4;                    // GL function's return value
+    optional float      duration = 5;                       // duration of GL call
+    optional FrameBuffer fb = 6;                            // contents of the framebuffer
+};
diff --git a/opengl/libs/GLES_trace/src/gltrace.pb.cpp b/opengl/libs/GLES_trace/src/gltrace.pb.cpp
new file mode 100644
index 0000000..6c1bb91
--- /dev/null
+++ b/opengl/libs/GLES_trace/src/gltrace.pb.cpp
@@ -0,0 +1,1888 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+
+#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION
+#include "gltrace.pb.h"
+#include <google/protobuf/stubs/once.h>
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/wire_format_lite_inl.h>
+// @@protoc_insertion_point(includes)
+
+namespace android {
+namespace gltrace {
+
+void protobuf_ShutdownFile_gltrace_2eproto() {
+  delete GLMessage::default_instance_;
+  delete GLMessage_DataType::default_instance_;
+  delete GLMessage_FrameBuffer::default_instance_;
+}
+
+void protobuf_AddDesc_gltrace_2eproto() {
+  static bool already_here = false;
+  if (already_here) return;
+  already_here = true;
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  GLMessage::default_instance_ = new GLMessage();
+  GLMessage_DataType::default_instance_ = new GLMessage_DataType();
+  GLMessage_FrameBuffer::default_instance_ = new GLMessage_FrameBuffer();
+  GLMessage::default_instance_->InitAsDefaultInstance();
+  GLMessage_DataType::default_instance_->InitAsDefaultInstance();
+  GLMessage_FrameBuffer::default_instance_->InitAsDefaultInstance();
+  ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_gltrace_2eproto);
+}
+
+// Force AddDescriptors() to be called at static initialization time.
+struct StaticDescriptorInitializer_gltrace_2eproto {
+  StaticDescriptorInitializer_gltrace_2eproto() {
+    protobuf_AddDesc_gltrace_2eproto();
+  }
+} static_descriptor_initializer_gltrace_2eproto_;
+
+
+// ===================================================================
+
+bool GLMessage_Function_IsValid(int value) {
+  switch(value) {
+    case 0:
+    case 1:
+    case 2:
+    case 3:
+    case 4:
+    case 5:
+    case 6:
+    case 7:
+    case 8:
+    case 9:
+    case 10:
+    case 11:
+    case 12:
+    case 13:
+    case 14:
+    case 15:
+    case 16:
+    case 17:
+    case 18:
+    case 19:
+    case 20:
+    case 21:
+    case 22:
+    case 23:
+    case 24:
+    case 25:
+    case 26:
+    case 27:
+    case 28:
+    case 29:
+    case 30:
+    case 31:
+    case 32:
+    case 33:
+    case 34:
+    case 35:
+    case 36:
+    case 37:
+    case 38:
+    case 39:
+    case 40:
+    case 41:
+    case 42:
+    case 43:
+    case 44:
+    case 45:
+    case 46:
+    case 47:
+    case 48:
+    case 49:
+    case 50:
+    case 51:
+    case 52:
+    case 53:
+    case 54:
+    case 55:
+    case 56:
+    case 57:
+    case 58:
+    case 59:
+    case 60:
+    case 61:
+    case 62:
+    case 63:
+    case 64:
+    case 65:
+    case 66:
+    case 67:
+    case 68:
+    case 69:
+    case 70:
+    case 71:
+    case 72:
+    case 73:
+    case 74:
+    case 75:
+    case 76:
+    case 77:
+    case 78:
+    case 79:
+    case 80:
+    case 81:
+    case 82:
+    case 83:
+    case 84:
+    case 85:
+    case 86:
+    case 87:
+    case 88:
+    case 89:
+    case 90:
+    case 91:
+    case 92:
+    case 93:
+    case 94:
+    case 95:
+    case 96:
+    case 97:
+    case 98:
+    case 99:
+    case 100:
+    case 101:
+    case 102:
+    case 103:
+    case 104:
+    case 105:
+    case 106:
+    case 107:
+    case 108:
+    case 109:
+    case 110:
+    case 111:
+    case 112:
+    case 113:
+    case 114:
+    case 115:
+    case 116:
+    case 117:
+    case 118:
+    case 119:
+    case 120:
+    case 121:
+    case 122:
+    case 123:
+    case 124:
+    case 125:
+    case 126:
+    case 127:
+    case 128:
+    case 129:
+    case 130:
+    case 131:
+    case 132:
+    case 133:
+    case 134:
+    case 135:
+    case 136:
+    case 137:
+    case 138:
+    case 139:
+    case 140:
+    case 141:
+    case 142:
+    case 143:
+    case 144:
+    case 145:
+    case 146:
+    case 147:
+    case 148:
+    case 149:
+    case 150:
+    case 151:
+    case 152:
+    case 153:
+    case 154:
+    case 155:
+    case 156:
+    case 157:
+    case 158:
+    case 159:
+    case 160:
+    case 161:
+    case 162:
+    case 163:
+    case 164:
+    case 165:
+    case 166:
+    case 167:
+    case 168:
+    case 169:
+    case 170:
+    case 171:
+    case 172:
+    case 173:
+    case 174:
+    case 175:
+    case 176:
+    case 177:
+    case 178:
+    case 179:
+    case 180:
+    case 181:
+    case 182:
+    case 183:
+    case 184:
+    case 185:
+    case 186:
+    case 187:
+    case 188:
+    case 189:
+    case 190:
+    case 191:
+    case 192:
+    case 193:
+    case 194:
+    case 195:
+    case 196:
+    case 197:
+    case 198:
+    case 199:
+    case 200:
+    case 201:
+    case 202:
+    case 203:
+    case 204:
+    case 205:
+    case 206:
+    case 207:
+    case 208:
+    case 209:
+    case 210:
+    case 211:
+    case 212:
+    case 213:
+    case 214:
+    case 215:
+    case 216:
+    case 217:
+    case 218:
+    case 219:
+    case 220:
+    case 221:
+    case 222:
+    case 223:
+    case 224:
+    case 225:
+    case 226:
+    case 227:
+    case 228:
+    case 229:
+    case 230:
+    case 231:
+    case 232:
+    case 233:
+    case 234:
+    case 235:
+    case 236:
+    case 237:
+    case 238:
+    case 239:
+    case 240:
+    case 241:
+    case 242:
+    case 243:
+    case 244:
+    case 245:
+    case 246:
+    case 247:
+    case 248:
+    case 249:
+    case 250:
+    case 251:
+    case 252:
+    case 253:
+    case 254:
+    case 255:
+    case 256:
+    case 257:
+    case 258:
+    case 259:
+    case 260:
+    case 261:
+    case 262:
+    case 263:
+    case 264:
+    case 265:
+    case 266:
+    case 267:
+    case 268:
+    case 269:
+    case 270:
+    case 271:
+    case 272:
+    case 273:
+    case 274:
+    case 275:
+    case 276:
+    case 277:
+    case 278:
+    case 279:
+    case 280:
+    case 281:
+    case 282:
+    case 283:
+    case 284:
+    case 285:
+    case 286:
+    case 287:
+    case 288:
+    case 289:
+    case 290:
+    case 291:
+    case 292:
+    case 293:
+    case 294:
+    case 295:
+    case 296:
+    case 297:
+    case 298:
+    case 299:
+    case 300:
+    case 301:
+    case 302:
+    case 303:
+    case 304:
+    case 305:
+    case 306:
+    case 307:
+    case 308:
+    case 309:
+    case 310:
+    case 311:
+    case 312:
+    case 313:
+    case 314:
+    case 315:
+    case 316:
+    case 317:
+    case 318:
+    case 319:
+    case 320:
+    case 321:
+    case 322:
+    case 323:
+    case 324:
+    case 325:
+    case 326:
+    case 327:
+    case 328:
+    case 329:
+    case 330:
+    case 331:
+    case 332:
+    case 333:
+    case 334:
+    case 335:
+    case 336:
+    case 337:
+    case 338:
+    case 339:
+    case 340:
+    case 341:
+    case 342:
+    case 343:
+    case 344:
+    case 345:
+    case 346:
+    case 347:
+    case 348:
+    case 349:
+    case 350:
+    case 351:
+    case 352:
+    case 353:
+    case 354:
+    case 355:
+    case 356:
+    case 357:
+    case 358:
+    case 359:
+    case 360:
+    case 361:
+    case 362:
+    case 363:
+    case 364:
+    case 365:
+    case 366:
+    case 367:
+    case 368:
+    case 369:
+    case 370:
+    case 371:
+    case 372:
+    case 373:
+    case 374:
+    case 375:
+    case 2000:
+    case 2001:
+    case 2002:
+    case 2003:
+    case 2004:
+    case 2005:
+    case 2006:
+    case 2007:
+    case 2008:
+    case 2009:
+    case 2010:
+    case 2011:
+    case 2012:
+    case 2013:
+    case 2014:
+    case 2015:
+    case 2016:
+    case 2017:
+    case 2018:
+    case 2019:
+    case 2020:
+    case 2021:
+    case 2022:
+    case 2023:
+    case 2024:
+    case 2025:
+    case 2026:
+    case 2027:
+    case 2028:
+    case 2029:
+    case 2030:
+    case 2031:
+    case 2032:
+    case 2033:
+    case 2034:
+    case 2035:
+    case 2036:
+    case 2037:
+    case 2038:
+    case 2039:
+    case 2040:
+    case 2041:
+    case 2042:
+    case 2043:
+    case 2044:
+    case 2045:
+    case 3000:
+    case 3001:
+      return true;
+    default:
+      return false;
+  }
+}
+
+#ifndef _MSC_VER
+const GLMessage_Function GLMessage::glActiveTexture;
+const GLMessage_Function GLMessage::glAlphaFunc;
+const GLMessage_Function GLMessage::glAlphaFuncx;
+const GLMessage_Function GLMessage::glAlphaFuncxOES;
+const GLMessage_Function GLMessage::glAttachShader;
+const GLMessage_Function GLMessage::glBeginPerfMonitorAMD;
+const GLMessage_Function GLMessage::glBindAttribLocation;
+const GLMessage_Function GLMessage::glBindBuffer;
+const GLMessage_Function GLMessage::glBindFramebuffer;
+const GLMessage_Function GLMessage::glBindFramebufferOES;
+const GLMessage_Function GLMessage::glBindRenderbuffer;
+const GLMessage_Function GLMessage::glBindRenderbufferOES;
+const GLMessage_Function GLMessage::glBindTexture;
+const GLMessage_Function GLMessage::glBindVertexArrayOES;
+const GLMessage_Function GLMessage::glBlendColor;
+const GLMessage_Function GLMessage::glBlendEquation;
+const GLMessage_Function GLMessage::glBlendEquationOES;
+const GLMessage_Function GLMessage::glBlendEquationSeparate;
+const GLMessage_Function GLMessage::glBlendEquationSeparateOES;
+const GLMessage_Function GLMessage::glBlendFunc;
+const GLMessage_Function GLMessage::glBlendFuncSeparate;
+const GLMessage_Function GLMessage::glBlendFuncSeparateOES;
+const GLMessage_Function GLMessage::glBufferData;
+const GLMessage_Function GLMessage::glBufferSubData;
+const GLMessage_Function GLMessage::glCheckFramebufferStatus;
+const GLMessage_Function GLMessage::glCheckFramebufferStatusOES;
+const GLMessage_Function GLMessage::glClearColor;
+const GLMessage_Function GLMessage::glClearColorx;
+const GLMessage_Function GLMessage::glClearColorxOES;
+const GLMessage_Function GLMessage::glClearDepthf;
+const GLMessage_Function GLMessage::glClearDepthfOES;
+const GLMessage_Function GLMessage::glClearDepthx;
+const GLMessage_Function GLMessage::glClearDepthxOES;
+const GLMessage_Function GLMessage::glClear;
+const GLMessage_Function GLMessage::glClearStencil;
+const GLMessage_Function GLMessage::glClientActiveTexture;
+const GLMessage_Function GLMessage::glClipPlanef;
+const GLMessage_Function GLMessage::glClipPlanefIMG;
+const GLMessage_Function GLMessage::glClipPlanefOES;
+const GLMessage_Function GLMessage::glClipPlanex;
+const GLMessage_Function GLMessage::glClipPlanexIMG;
+const GLMessage_Function GLMessage::glClipPlanexOES;
+const GLMessage_Function GLMessage::glColor4f;
+const GLMessage_Function GLMessage::glColor4ub;
+const GLMessage_Function GLMessage::glColor4x;
+const GLMessage_Function GLMessage::glColor4xOES;
+const GLMessage_Function GLMessage::glColorMask;
+const GLMessage_Function GLMessage::glColorPointer;
+const GLMessage_Function GLMessage::glCompileShader;
+const GLMessage_Function GLMessage::glCompressedTexImage2D;
+const GLMessage_Function GLMessage::glCompressedTexImage3DOES;
+const GLMessage_Function GLMessage::glCompressedTexSubImage2D;
+const GLMessage_Function GLMessage::glCompressedTexSubImage3DOES;
+const GLMessage_Function GLMessage::glCopyTexImage2D;
+const GLMessage_Function GLMessage::glCopyTexSubImage2D;
+const GLMessage_Function GLMessage::glCopyTexSubImage3DOES;
+const GLMessage_Function GLMessage::glCoverageMaskNV;
+const GLMessage_Function GLMessage::glCoverageOperationNV;
+const GLMessage_Function GLMessage::glCreateProgram;
+const GLMessage_Function GLMessage::glCreateShader;
+const GLMessage_Function GLMessage::glCullFace;
+const GLMessage_Function GLMessage::glCurrentPaletteMatrixOES;
+const GLMessage_Function GLMessage::glDeleteBuffers;
+const GLMessage_Function GLMessage::glDeleteFencesNV;
+const GLMessage_Function GLMessage::glDeleteFramebuffers;
+const GLMessage_Function GLMessage::glDeleteFramebuffersOES;
+const GLMessage_Function GLMessage::glDeletePerfMonitorsAMD;
+const GLMessage_Function GLMessage::glDeleteProgram;
+const GLMessage_Function GLMessage::glDeleteRenderbuffers;
+const GLMessage_Function GLMessage::glDeleteRenderbuffersOES;
+const GLMessage_Function GLMessage::glDeleteShader;
+const GLMessage_Function GLMessage::glDeleteTextures;
+const GLMessage_Function GLMessage::glDeleteVertexArraysOES;
+const GLMessage_Function GLMessage::glDepthFunc;
+const GLMessage_Function GLMessage::glDepthMask;
+const GLMessage_Function GLMessage::glDepthRangef;
+const GLMessage_Function GLMessage::glDepthRangefOES;
+const GLMessage_Function GLMessage::glDepthRangex;
+const GLMessage_Function GLMessage::glDepthRangexOES;
+const GLMessage_Function GLMessage::glDetachShader;
+const GLMessage_Function GLMessage::glDisableClientState;
+const GLMessage_Function GLMessage::glDisableDriverControlQCOM;
+const GLMessage_Function GLMessage::glDisable;
+const GLMessage_Function GLMessage::glDisableVertexAttribArray;
+const GLMessage_Function GLMessage::glDiscardFramebufferEXT;
+const GLMessage_Function GLMessage::glDrawArrays;
+const GLMessage_Function GLMessage::glDrawElements;
+const GLMessage_Function GLMessage::glDrawTexfOES;
+const GLMessage_Function GLMessage::glDrawTexfvOES;
+const GLMessage_Function GLMessage::glDrawTexiOES;
+const GLMessage_Function GLMessage::glDrawTexivOES;
+const GLMessage_Function GLMessage::glDrawTexsOES;
+const GLMessage_Function GLMessage::glDrawTexsvOES;
+const GLMessage_Function GLMessage::glDrawTexxOES;
+const GLMessage_Function GLMessage::glDrawTexxvOES;
+const GLMessage_Function GLMessage::glEGLImageTargetRenderbufferStorageOES;
+const GLMessage_Function GLMessage::glEGLImageTargetTexture2DOES;
+const GLMessage_Function GLMessage::glEnableClientState;
+const GLMessage_Function GLMessage::glEnableDriverControlQCOM;
+const GLMessage_Function GLMessage::glEnable;
+const GLMessage_Function GLMessage::glEnableVertexAttribArray;
+const GLMessage_Function GLMessage::glEndPerfMonitorAMD;
+const GLMessage_Function GLMessage::glEndTilingQCOM;
+const GLMessage_Function GLMessage::glExtGetBufferPointervQCOM;
+const GLMessage_Function GLMessage::glExtGetBuffersQCOM;
+const GLMessage_Function GLMessage::glExtGetFramebuffersQCOM;
+const GLMessage_Function GLMessage::glExtGetProgramBinarySourceQCOM;
+const GLMessage_Function GLMessage::glExtGetProgramsQCOM;
+const GLMessage_Function GLMessage::glExtGetRenderbuffersQCOM;
+const GLMessage_Function GLMessage::glExtGetShadersQCOM;
+const GLMessage_Function GLMessage::glExtGetTexLevelParameterivQCOM;
+const GLMessage_Function GLMessage::glExtGetTexSubImageQCOM;
+const GLMessage_Function GLMessage::glExtGetTexturesQCOM;
+const GLMessage_Function GLMessage::glExtIsProgramBinaryQCOM;
+const GLMessage_Function GLMessage::glExtTexObjectStateOverrideiQCOM;
+const GLMessage_Function GLMessage::glFinishFenceNV;
+const GLMessage_Function GLMessage::glFinish;
+const GLMessage_Function GLMessage::glFlush;
+const GLMessage_Function GLMessage::glFogf;
+const GLMessage_Function GLMessage::glFogfv;
+const GLMessage_Function GLMessage::glFogx;
+const GLMessage_Function GLMessage::glFogxOES;
+const GLMessage_Function GLMessage::glFogxv;
+const GLMessage_Function GLMessage::glFogxvOES;
+const GLMessage_Function GLMessage::glFramebufferRenderbuffer;
+const GLMessage_Function GLMessage::glFramebufferRenderbufferOES;
+const GLMessage_Function GLMessage::glFramebufferTexture2D;
+const GLMessage_Function GLMessage::glFramebufferTexture2DMultisampleIMG;
+const GLMessage_Function GLMessage::glFramebufferTexture2DOES;
+const GLMessage_Function GLMessage::glFramebufferTexture3DOES;
+const GLMessage_Function GLMessage::glFrontFace;
+const GLMessage_Function GLMessage::glFrustumf;
+const GLMessage_Function GLMessage::glFrustumfOES;
+const GLMessage_Function GLMessage::glFrustumx;
+const GLMessage_Function GLMessage::glFrustumxOES;
+const GLMessage_Function GLMessage::glGenBuffers;
+const GLMessage_Function GLMessage::glGenerateMipmap;
+const GLMessage_Function GLMessage::glGenerateMipmapOES;
+const GLMessage_Function GLMessage::glGenFencesNV;
+const GLMessage_Function GLMessage::glGenFramebuffers;
+const GLMessage_Function GLMessage::glGenFramebuffersOES;
+const GLMessage_Function GLMessage::glGenPerfMonitorsAMD;
+const GLMessage_Function GLMessage::glGenRenderbuffers;
+const GLMessage_Function GLMessage::glGenRenderbuffersOES;
+const GLMessage_Function GLMessage::glGenTextures;
+const GLMessage_Function GLMessage::glGenVertexArraysOES;
+const GLMessage_Function GLMessage::glGetActiveAttrib;
+const GLMessage_Function GLMessage::glGetActiveUniform;
+const GLMessage_Function GLMessage::glGetAttachedShaders;
+const GLMessage_Function GLMessage::glGetAttribLocation;
+const GLMessage_Function GLMessage::glGetBooleanv;
+const GLMessage_Function GLMessage::glGetBufferParameteriv;
+const GLMessage_Function GLMessage::glGetBufferPointervOES;
+const GLMessage_Function GLMessage::glGetClipPlanef;
+const GLMessage_Function GLMessage::glGetClipPlanefOES;
+const GLMessage_Function GLMessage::glGetClipPlanex;
+const GLMessage_Function GLMessage::glGetClipPlanexOES;
+const GLMessage_Function GLMessage::glGetDriverControlsQCOM;
+const GLMessage_Function GLMessage::glGetDriverControlStringQCOM;
+const GLMessage_Function GLMessage::glGetError;
+const GLMessage_Function GLMessage::glGetFenceivNV;
+const GLMessage_Function GLMessage::glGetFixedv;
+const GLMessage_Function GLMessage::glGetFixedvOES;
+const GLMessage_Function GLMessage::glGetFloatv;
+const GLMessage_Function GLMessage::glGetFramebufferAttachmentParameteriv;
+const GLMessage_Function GLMessage::glGetFramebufferAttachmentParameterivOES;
+const GLMessage_Function GLMessage::glGetIntegerv;
+const GLMessage_Function GLMessage::glGetLightfv;
+const GLMessage_Function GLMessage::glGetLightxv;
+const GLMessage_Function GLMessage::glGetLightxvOES;
+const GLMessage_Function GLMessage::glGetMaterialfv;
+const GLMessage_Function GLMessage::glGetMaterialxv;
+const GLMessage_Function GLMessage::glGetMaterialxvOES;
+const GLMessage_Function GLMessage::glGetPerfMonitorCounterDataAMD;
+const GLMessage_Function GLMessage::glGetPerfMonitorCounterInfoAMD;
+const GLMessage_Function GLMessage::glGetPerfMonitorCountersAMD;
+const GLMessage_Function GLMessage::glGetPerfMonitorCounterStringAMD;
+const GLMessage_Function GLMessage::glGetPerfMonitorGroupsAMD;
+const GLMessage_Function GLMessage::glGetPerfMonitorGroupStringAMD;
+const GLMessage_Function GLMessage::glGetPointerv;
+const GLMessage_Function GLMessage::glGetProgramBinaryOES;
+const GLMessage_Function GLMessage::glGetProgramInfoLog;
+const GLMessage_Function GLMessage::glGetProgramiv;
+const GLMessage_Function GLMessage::glGetRenderbufferParameteriv;
+const GLMessage_Function GLMessage::glGetRenderbufferParameterivOES;
+const GLMessage_Function GLMessage::glGetShaderInfoLog;
+const GLMessage_Function GLMessage::glGetShaderiv;
+const GLMessage_Function GLMessage::glGetShaderPrecisionFormat;
+const GLMessage_Function GLMessage::glGetShaderSource;
+const GLMessage_Function GLMessage::glGetString;
+const GLMessage_Function GLMessage::glGetTexEnvfv;
+const GLMessage_Function GLMessage::glGetTexEnviv;
+const GLMessage_Function GLMessage::glGetTexEnvxv;
+const GLMessage_Function GLMessage::glGetTexEnvxvOES;
+const GLMessage_Function GLMessage::glGetTexGenfvOES;
+const GLMessage_Function GLMessage::glGetTexGenivOES;
+const GLMessage_Function GLMessage::glGetTexGenxvOES;
+const GLMessage_Function GLMessage::glGetTexParameterfv;
+const GLMessage_Function GLMessage::glGetTexParameteriv;
+const GLMessage_Function GLMessage::glGetTexParameterxv;
+const GLMessage_Function GLMessage::glGetTexParameterxvOES;
+const GLMessage_Function GLMessage::glGetUniformfv;
+const GLMessage_Function GLMessage::glGetUniformiv;
+const GLMessage_Function GLMessage::glGetUniformLocation;
+const GLMessage_Function GLMessage::glGetVertexAttribfv;
+const GLMessage_Function GLMessage::glGetVertexAttribiv;
+const GLMessage_Function GLMessage::glGetVertexAttribPointerv;
+const GLMessage_Function GLMessage::glHint;
+const GLMessage_Function GLMessage::glIsBuffer;
+const GLMessage_Function GLMessage::glIsEnabled;
+const GLMessage_Function GLMessage::glIsFenceNV;
+const GLMessage_Function GLMessage::glIsFramebuffer;
+const GLMessage_Function GLMessage::glIsFramebufferOES;
+const GLMessage_Function GLMessage::glIsProgram;
+const GLMessage_Function GLMessage::glIsRenderbuffer;
+const GLMessage_Function GLMessage::glIsRenderbufferOES;
+const GLMessage_Function GLMessage::glIsShader;
+const GLMessage_Function GLMessage::glIsTexture;
+const GLMessage_Function GLMessage::glIsVertexArrayOES;
+const GLMessage_Function GLMessage::glLightf;
+const GLMessage_Function GLMessage::glLightfv;
+const GLMessage_Function GLMessage::glLightModelf;
+const GLMessage_Function GLMessage::glLightModelfv;
+const GLMessage_Function GLMessage::glLightModelx;
+const GLMessage_Function GLMessage::glLightModelxOES;
+const GLMessage_Function GLMessage::glLightModelxv;
+const GLMessage_Function GLMessage::glLightModelxvOES;
+const GLMessage_Function GLMessage::glLightx;
+const GLMessage_Function GLMessage::glLightxOES;
+const GLMessage_Function GLMessage::glLightxv;
+const GLMessage_Function GLMessage::glLightxvOES;
+const GLMessage_Function GLMessage::glLineWidth;
+const GLMessage_Function GLMessage::glLineWidthx;
+const GLMessage_Function GLMessage::glLineWidthxOES;
+const GLMessage_Function GLMessage::glLinkProgram;
+const GLMessage_Function GLMessage::glLoadIdentity;
+const GLMessage_Function GLMessage::glLoadMatrixf;
+const GLMessage_Function GLMessage::glLoadMatrixx;
+const GLMessage_Function GLMessage::glLoadMatrixxOES;
+const GLMessage_Function GLMessage::glLoadPaletteFromModelViewMatrixOES;
+const GLMessage_Function GLMessage::glLogicOp;
+const GLMessage_Function GLMessage::glMapBufferOES;
+const GLMessage_Function GLMessage::glMaterialf;
+const GLMessage_Function GLMessage::glMaterialfv;
+const GLMessage_Function GLMessage::glMaterialx;
+const GLMessage_Function GLMessage::glMaterialxOES;
+const GLMessage_Function GLMessage::glMaterialxv;
+const GLMessage_Function GLMessage::glMaterialxvOES;
+const GLMessage_Function GLMessage::glMatrixIndexPointerOES;
+const GLMessage_Function GLMessage::glMatrixMode;
+const GLMessage_Function GLMessage::glMultiDrawArraysEXT;
+const GLMessage_Function GLMessage::glMultiDrawElementsEXT;
+const GLMessage_Function GLMessage::glMultiTexCoord4f;
+const GLMessage_Function GLMessage::glMultiTexCoord4x;
+const GLMessage_Function GLMessage::glMultiTexCoord4xOES;
+const GLMessage_Function GLMessage::glMultMatrixf;
+const GLMessage_Function GLMessage::glMultMatrixx;
+const GLMessage_Function GLMessage::glMultMatrixxOES;
+const GLMessage_Function GLMessage::glNormal3f;
+const GLMessage_Function GLMessage::glNormal3x;
+const GLMessage_Function GLMessage::glNormal3xOES;
+const GLMessage_Function GLMessage::glNormalPointer;
+const GLMessage_Function GLMessage::glOrthof;
+const GLMessage_Function GLMessage::glOrthofOES;
+const GLMessage_Function GLMessage::glOrthox;
+const GLMessage_Function GLMessage::glOrthoxOES;
+const GLMessage_Function GLMessage::glPixelStorei;
+const GLMessage_Function GLMessage::glPointParameterf;
+const GLMessage_Function GLMessage::glPointParameterfv;
+const GLMessage_Function GLMessage::glPointParameterx;
+const GLMessage_Function GLMessage::glPointParameterxOES;
+const GLMessage_Function GLMessage::glPointParameterxv;
+const GLMessage_Function GLMessage::glPointParameterxvOES;
+const GLMessage_Function GLMessage::glPointSize;
+const GLMessage_Function GLMessage::glPointSizePointerOES;
+const GLMessage_Function GLMessage::glPointSizex;
+const GLMessage_Function GLMessage::glPointSizexOES;
+const GLMessage_Function GLMessage::glPolygonOffset;
+const GLMessage_Function GLMessage::glPolygonOffsetx;
+const GLMessage_Function GLMessage::glPolygonOffsetxOES;
+const GLMessage_Function GLMessage::glPopMatrix;
+const GLMessage_Function GLMessage::glProgramBinaryOES;
+const GLMessage_Function GLMessage::glPushMatrix;
+const GLMessage_Function GLMessage::glQueryMatrixxOES;
+const GLMessage_Function GLMessage::glReadPixels;
+const GLMessage_Function GLMessage::glReleaseShaderCompiler;
+const GLMessage_Function GLMessage::glRenderbufferStorage;
+const GLMessage_Function GLMessage::glRenderbufferStorageMultisampleIMG;
+const GLMessage_Function GLMessage::glRenderbufferStorageOES;
+const GLMessage_Function GLMessage::glRotatef;
+const GLMessage_Function GLMessage::glRotatex;
+const GLMessage_Function GLMessage::glRotatexOES;
+const GLMessage_Function GLMessage::glSampleCoverage;
+const GLMessage_Function GLMessage::glSampleCoveragex;
+const GLMessage_Function GLMessage::glSampleCoveragexOES;
+const GLMessage_Function GLMessage::glScalef;
+const GLMessage_Function GLMessage::glScalex;
+const GLMessage_Function GLMessage::glScalexOES;
+const GLMessage_Function GLMessage::glScissor;
+const GLMessage_Function GLMessage::glSelectPerfMonitorCountersAMD;
+const GLMessage_Function GLMessage::glSetFenceNV;
+const GLMessage_Function GLMessage::glShadeModel;
+const GLMessage_Function GLMessage::glShaderBinary;
+const GLMessage_Function GLMessage::glShaderSource;
+const GLMessage_Function GLMessage::glStartTilingQCOM;
+const GLMessage_Function GLMessage::glStencilFunc;
+const GLMessage_Function GLMessage::glStencilFuncSeparate;
+const GLMessage_Function GLMessage::glStencilMask;
+const GLMessage_Function GLMessage::glStencilMaskSeparate;
+const GLMessage_Function GLMessage::glStencilOp;
+const GLMessage_Function GLMessage::glStencilOpSeparate;
+const GLMessage_Function GLMessage::glTestFenceNV;
+const GLMessage_Function GLMessage::glTexCoordPointer;
+const GLMessage_Function GLMessage::glTexEnvf;
+const GLMessage_Function GLMessage::glTexEnvfv;
+const GLMessage_Function GLMessage::glTexEnvi;
+const GLMessage_Function GLMessage::glTexEnviv;
+const GLMessage_Function GLMessage::glTexEnvx;
+const GLMessage_Function GLMessage::glTexEnvxOES;
+const GLMessage_Function GLMessage::glTexEnvxv;
+const GLMessage_Function GLMessage::glTexEnvxvOES;
+const GLMessage_Function GLMessage::glTexGenfOES;
+const GLMessage_Function GLMessage::glTexGenfvOES;
+const GLMessage_Function GLMessage::glTexGeniOES;
+const GLMessage_Function GLMessage::glTexGenivOES;
+const GLMessage_Function GLMessage::glTexGenxOES;
+const GLMessage_Function GLMessage::glTexGenxvOES;
+const GLMessage_Function GLMessage::glTexImage2D;
+const GLMessage_Function GLMessage::glTexImage3DOES;
+const GLMessage_Function GLMessage::glTexParameterf;
+const GLMessage_Function GLMessage::glTexParameterfv;
+const GLMessage_Function GLMessage::glTexParameteri;
+const GLMessage_Function GLMessage::glTexParameteriv;
+const GLMessage_Function GLMessage::glTexParameterx;
+const GLMessage_Function GLMessage::glTexParameterxOES;
+const GLMessage_Function GLMessage::glTexParameterxv;
+const GLMessage_Function GLMessage::glTexParameterxvOES;
+const GLMessage_Function GLMessage::glTexSubImage2D;
+const GLMessage_Function GLMessage::glTexSubImage3DOES;
+const GLMessage_Function GLMessage::glTranslatef;
+const GLMessage_Function GLMessage::glTranslatex;
+const GLMessage_Function GLMessage::glTranslatexOES;
+const GLMessage_Function GLMessage::glUniform1f;
+const GLMessage_Function GLMessage::glUniform1fv;
+const GLMessage_Function GLMessage::glUniform1i;
+const GLMessage_Function GLMessage::glUniform1iv;
+const GLMessage_Function GLMessage::glUniform2f;
+const GLMessage_Function GLMessage::glUniform2fv;
+const GLMessage_Function GLMessage::glUniform2i;
+const GLMessage_Function GLMessage::glUniform2iv;
+const GLMessage_Function GLMessage::glUniform3f;
+const GLMessage_Function GLMessage::glUniform3fv;
+const GLMessage_Function GLMessage::glUniform3i;
+const GLMessage_Function GLMessage::glUniform3iv;
+const GLMessage_Function GLMessage::glUniform4f;
+const GLMessage_Function GLMessage::glUniform4fv;
+const GLMessage_Function GLMessage::glUniform4i;
+const GLMessage_Function GLMessage::glUniform4iv;
+const GLMessage_Function GLMessage::glUniformMatrix2fv;
+const GLMessage_Function GLMessage::glUniformMatrix3fv;
+const GLMessage_Function GLMessage::glUniformMatrix4fv;
+const GLMessage_Function GLMessage::glUnmapBufferOES;
+const GLMessage_Function GLMessage::glUseProgram;
+const GLMessage_Function GLMessage::glValidateProgram;
+const GLMessage_Function GLMessage::glVertexAttrib1f;
+const GLMessage_Function GLMessage::glVertexAttrib1fv;
+const GLMessage_Function GLMessage::glVertexAttrib2f;
+const GLMessage_Function GLMessage::glVertexAttrib2fv;
+const GLMessage_Function GLMessage::glVertexAttrib3f;
+const GLMessage_Function GLMessage::glVertexAttrib3fv;
+const GLMessage_Function GLMessage::glVertexAttrib4f;
+const GLMessage_Function GLMessage::glVertexAttrib4fv;
+const GLMessage_Function GLMessage::glVertexAttribPointer;
+const GLMessage_Function GLMessage::glVertexPointer;
+const GLMessage_Function GLMessage::glViewport;
+const GLMessage_Function GLMessage::glWeightPointerOES;
+const GLMessage_Function GLMessage::eglGetDisplay;
+const GLMessage_Function GLMessage::eglInitialize;
+const GLMessage_Function GLMessage::eglTerminate;
+const GLMessage_Function GLMessage::eglGetConfigs;
+const GLMessage_Function GLMessage::eglChooseConfig;
+const GLMessage_Function GLMessage::eglGetConfigAttrib;
+const GLMessage_Function GLMessage::eglCreateWindowSurface;
+const GLMessage_Function GLMessage::eglCreatePixmapSurface;
+const GLMessage_Function GLMessage::eglCreatePbufferSurface;
+const GLMessage_Function GLMessage::eglDestroySurface;
+const GLMessage_Function GLMessage::eglQuerySurface;
+const GLMessage_Function GLMessage::eglCreateContext;
+const GLMessage_Function GLMessage::eglDestroyContext;
+const GLMessage_Function GLMessage::eglMakeCurrent;
+const GLMessage_Function GLMessage::eglGetCurrentContext;
+const GLMessage_Function GLMessage::eglGetCurrentSurface;
+const GLMessage_Function GLMessage::eglGetCurrentDisplay;
+const GLMessage_Function GLMessage::eglQueryContext;
+const GLMessage_Function GLMessage::eglWaitGL;
+const GLMessage_Function GLMessage::eglWaitNative;
+const GLMessage_Function GLMessage::eglSwapBuffers;
+const GLMessage_Function GLMessage::eglCopyBuffers;
+const GLMessage_Function GLMessage::eglGetError;
+const GLMessage_Function GLMessage::eglQueryString;
+const GLMessage_Function GLMessage::eglGetProcAddress;
+const GLMessage_Function GLMessage::eglSurfaceAttrib;
+const GLMessage_Function GLMessage::eglBindTexImage;
+const GLMessage_Function GLMessage::eglReleaseTexImage;
+const GLMessage_Function GLMessage::eglSwapInterval;
+const GLMessage_Function GLMessage::eglBindAPI;
+const GLMessage_Function GLMessage::eglQueryAPI;
+const GLMessage_Function GLMessage::eglWaitClient;
+const GLMessage_Function GLMessage::eglReleaseThread;
+const GLMessage_Function GLMessage::eglCreatePbufferFromClientBuffer;
+const GLMessage_Function GLMessage::eglLockSurfaceKHR;
+const GLMessage_Function GLMessage::eglUnlockSurfaceKHR;
+const GLMessage_Function GLMessage::eglCreateImageKHR;
+const GLMessage_Function GLMessage::eglDestroyImageKHR;
+const GLMessage_Function GLMessage::eglCreateSyncKHR;
+const GLMessage_Function GLMessage::eglDestroySyncKHR;
+const GLMessage_Function GLMessage::eglClientWaitSyncKHR;
+const GLMessage_Function GLMessage::eglGetSyncAttribKHR;
+const GLMessage_Function GLMessage::eglSetSwapRectangleANDROID;
+const GLMessage_Function GLMessage::eglGetRenderBufferANDROID;
+const GLMessage_Function GLMessage::eglGetSystemTimeFrequencyNV;
+const GLMessage_Function GLMessage::eglGetSystemTimeNV;
+const GLMessage_Function GLMessage::invalid;
+const GLMessage_Function GLMessage::frameBufferContents;
+const GLMessage_Function GLMessage::Function_MIN;
+const GLMessage_Function GLMessage::Function_MAX;
+const int GLMessage::Function_ARRAYSIZE;
+#endif  // _MSC_VER
+bool GLMessage_DataType_Type_IsValid(int value) {
+  switch(value) {
+    case 1:
+    case 2:
+    case 3:
+    case 4:
+    case 5:
+    case 6:
+    case 7:
+      return true;
+    default:
+      return false;
+  }
+}
+
+#ifndef _MSC_VER
+const GLMessage_DataType_Type GLMessage_DataType::VOID;
+const GLMessage_DataType_Type GLMessage_DataType::CHAR;
+const GLMessage_DataType_Type GLMessage_DataType::BYTE;
+const GLMessage_DataType_Type GLMessage_DataType::INT;
+const GLMessage_DataType_Type GLMessage_DataType::FLOAT;
+const GLMessage_DataType_Type GLMessage_DataType::BOOL;
+const GLMessage_DataType_Type GLMessage_DataType::ENUM;
+const GLMessage_DataType_Type GLMessage_DataType::Type_MIN;
+const GLMessage_DataType_Type GLMessage_DataType::Type_MAX;
+const int GLMessage_DataType::Type_ARRAYSIZE;
+#endif  // _MSC_VER
+#ifndef _MSC_VER
+const int GLMessage_DataType::kTypeFieldNumber;
+const int GLMessage_DataType::kIsArrayFieldNumber;
+const int GLMessage_DataType::kIntValueFieldNumber;
+const int GLMessage_DataType::kFloatValueFieldNumber;
+const int GLMessage_DataType::kCharValueFieldNumber;
+const int GLMessage_DataType::kRawBytesFieldNumber;
+const int GLMessage_DataType::kBoolValueFieldNumber;
+#endif  // !_MSC_VER
+
+GLMessage_DataType::GLMessage_DataType()
+  : ::google::protobuf::MessageLite() {
+  SharedCtor();
+}
+
+void GLMessage_DataType::InitAsDefaultInstance() {
+}
+
+GLMessage_DataType::GLMessage_DataType(const GLMessage_DataType& from)
+  : ::google::protobuf::MessageLite() {
+  SharedCtor();
+  MergeFrom(from);
+}
+
+void GLMessage_DataType::SharedCtor() {
+  _cached_size_ = 0;
+  type_ = 1;
+  isarray_ = false;
+  ::memset(_has_bits_, 0, sizeof(_has_bits_));
+}
+
+GLMessage_DataType::~GLMessage_DataType() {
+  SharedDtor();
+}
+
+void GLMessage_DataType::SharedDtor() {
+  if (this != default_instance_) {
+  }
+}
+
+void GLMessage_DataType::SetCachedSize(int size) const {
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const GLMessage_DataType& GLMessage_DataType::default_instance() {
+  if (default_instance_ == NULL) protobuf_AddDesc_gltrace_2eproto();  return *default_instance_;
+}
+
+GLMessage_DataType* GLMessage_DataType::default_instance_ = NULL;
+
+GLMessage_DataType* GLMessage_DataType::New() const {
+  return new GLMessage_DataType;
+}
+
+void GLMessage_DataType::Clear() {
+  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+    type_ = 1;
+    isarray_ = false;
+  }
+  intvalue_.Clear();
+  floatvalue_.Clear();
+  charvalue_.Clear();
+  rawbytes_.Clear();
+  boolvalue_.Clear();
+  ::memset(_has_bits_, 0, sizeof(_has_bits_));
+}
+
+bool GLMessage_DataType::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
+  ::google::protobuf::uint32 tag;
+  while ((tag = input->ReadTag()) != 0) {
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // required .android.gltrace.GLMessage.DataType.Type type = 1 [default = VOID];
+      case 1: {
+        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+            ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
+          int value;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          if (::android::gltrace::GLMessage_DataType_Type_IsValid(value)) {
+            set_type(static_cast< ::android::gltrace::GLMessage_DataType_Type >(value));
+          }
+        } else {
+          goto handle_uninterpreted;
+        }
+        if (input->ExpectTag(16)) goto parse_isArray;
+        break;
+      }
+      
+      // required bool isArray = 2 [default = false];
+      case 2: {
+        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+            ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
+         parse_isArray:
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
+                 input, &isarray_)));
+          _set_bit(1);
+        } else {
+          goto handle_uninterpreted;
+        }
+        if (input->ExpectTag(24)) goto parse_intValue;
+        break;
+      }
+      
+      // repeated int32 intValue = 3;
+      case 3: {
+        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+            ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
+         parse_intValue:
+          DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitive<
+                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
+                 1, 24, input, this->mutable_intvalue())));
+        } else if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag)
+                   == ::google::protobuf::internal::WireFormatLite::
+                      WIRETYPE_LENGTH_DELIMITED) {
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitiveNoInline<
+                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
+                 input, this->mutable_intvalue())));
+        } else {
+          goto handle_uninterpreted;
+        }
+        if (input->ExpectTag(24)) goto parse_intValue;
+        if (input->ExpectTag(37)) goto parse_floatValue;
+        break;
+      }
+      
+      // repeated float floatValue = 4;
+      case 4: {
+        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+            ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED32) {
+         parse_floatValue:
+          DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitive<
+                   float, ::google::protobuf::internal::WireFormatLite::TYPE_FLOAT>(
+                 1, 37, input, this->mutable_floatvalue())));
+        } else if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag)
+                   == ::google::protobuf::internal::WireFormatLite::
+                      WIRETYPE_LENGTH_DELIMITED) {
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitiveNoInline<
+                   float, ::google::protobuf::internal::WireFormatLite::TYPE_FLOAT>(
+                 input, this->mutable_floatvalue())));
+        } else {
+          goto handle_uninterpreted;
+        }
+        if (input->ExpectTag(37)) goto parse_floatValue;
+        if (input->ExpectTag(42)) goto parse_charValue;
+        break;
+      }
+      
+      // repeated bytes charValue = 5;
+      case 5: {
+        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+         parse_charValue:
+          DO_(::google::protobuf::internal::WireFormatLite::ReadBytes(
+                input, this->add_charvalue()));
+        } else {
+          goto handle_uninterpreted;
+        }
+        if (input->ExpectTag(42)) goto parse_charValue;
+        if (input->ExpectTag(50)) goto parse_rawBytes;
+        break;
+      }
+      
+      // repeated bytes rawBytes = 6;
+      case 6: {
+        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+         parse_rawBytes:
+          DO_(::google::protobuf::internal::WireFormatLite::ReadBytes(
+                input, this->add_rawbytes()));
+        } else {
+          goto handle_uninterpreted;
+        }
+        if (input->ExpectTag(50)) goto parse_rawBytes;
+        if (input->ExpectTag(56)) goto parse_boolValue;
+        break;
+      }
+      
+      // repeated bool boolValue = 7;
+      case 7: {
+        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+            ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
+         parse_boolValue:
+          DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitive<
+                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
+                 1, 56, input, this->mutable_boolvalue())));
+        } else if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag)
+                   == ::google::protobuf::internal::WireFormatLite::
+                      WIRETYPE_LENGTH_DELIMITED) {
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitiveNoInline<
+                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
+                 input, this->mutable_boolvalue())));
+        } else {
+          goto handle_uninterpreted;
+        }
+        if (input->ExpectTag(56)) goto parse_boolValue;
+        if (input->ExpectAtEnd()) return true;
+        break;
+      }
+      
+      default: {
+      handle_uninterpreted:
+        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
+          return true;
+        }
+        DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag));
+        break;
+      }
+    }
+  }
+  return true;
+#undef DO_
+}
+
+void GLMessage_DataType::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // required .android.gltrace.GLMessage.DataType.Type type = 1 [default = VOID];
+  if (_has_bit(0)) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      1, this->type(), output);
+  }
+  
+  // required bool isArray = 2 [default = false];
+  if (_has_bit(1)) {
+    ::google::protobuf::internal::WireFormatLite::WriteBool(2, this->isarray(), output);
+  }
+  
+  // repeated int32 intValue = 3;
+  for (int i = 0; i < this->intvalue_size(); i++) {
+    ::google::protobuf::internal::WireFormatLite::WriteInt32(
+      3, this->intvalue(i), output);
+  }
+  
+  // repeated float floatValue = 4;
+  for (int i = 0; i < this->floatvalue_size(); i++) {
+    ::google::protobuf::internal::WireFormatLite::WriteFloat(
+      4, this->floatvalue(i), output);
+  }
+  
+  // repeated bytes charValue = 5;
+  for (int i = 0; i < this->charvalue_size(); i++) {
+    ::google::protobuf::internal::WireFormatLite::WriteBytes(
+      5, this->charvalue(i), output);
+  }
+  
+  // repeated bytes rawBytes = 6;
+  for (int i = 0; i < this->rawbytes_size(); i++) {
+    ::google::protobuf::internal::WireFormatLite::WriteBytes(
+      6, this->rawbytes(i), output);
+  }
+  
+  // repeated bool boolValue = 7;
+  for (int i = 0; i < this->boolvalue_size(); i++) {
+    ::google::protobuf::internal::WireFormatLite::WriteBool(
+      7, this->boolvalue(i), output);
+  }
+  
+}
+
+int GLMessage_DataType::ByteSize() const {
+  int total_size = 0;
+  
+  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+    // required .android.gltrace.GLMessage.DataType.Type type = 1 [default = VOID];
+    if (has_type()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::EnumSize(this->type());
+    }
+    
+    // required bool isArray = 2 [default = false];
+    if (has_isarray()) {
+      total_size += 1 + 1;
+    }
+    
+  }
+  // repeated int32 intValue = 3;
+  {
+    int data_size = 0;
+    for (int i = 0; i < this->intvalue_size(); i++) {
+      data_size += ::google::protobuf::internal::WireFormatLite::
+        Int32Size(this->intvalue(i));
+    }
+    total_size += 1 * this->intvalue_size() + data_size;
+  }
+  
+  // repeated float floatValue = 4;
+  {
+    int data_size = 0;
+    data_size = 4 * this->floatvalue_size();
+    total_size += 1 * this->floatvalue_size() + data_size;
+  }
+  
+  // repeated bytes charValue = 5;
+  total_size += 1 * this->charvalue_size();
+  for (int i = 0; i < this->charvalue_size(); i++) {
+    total_size += ::google::protobuf::internal::WireFormatLite::BytesSize(
+      this->charvalue(i));
+  }
+  
+  // repeated bytes rawBytes = 6;
+  total_size += 1 * this->rawbytes_size();
+  for (int i = 0; i < this->rawbytes_size(); i++) {
+    total_size += ::google::protobuf::internal::WireFormatLite::BytesSize(
+      this->rawbytes(i));
+  }
+  
+  // repeated bool boolValue = 7;
+  {
+    int data_size = 0;
+    data_size = 1 * this->boolvalue_size();
+    total_size += 1 * this->boolvalue_size() + data_size;
+  }
+  
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = total_size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+  return total_size;
+}
+
+void GLMessage_DataType::CheckTypeAndMergeFrom(
+    const ::google::protobuf::MessageLite& from) {
+  MergeFrom(*::google::protobuf::down_cast<const GLMessage_DataType*>(&from));
+}
+
+void GLMessage_DataType::MergeFrom(const GLMessage_DataType& from) {
+  GOOGLE_CHECK_NE(&from, this);
+  intvalue_.MergeFrom(from.intvalue_);
+  floatvalue_.MergeFrom(from.floatvalue_);
+  charvalue_.MergeFrom(from.charvalue_);
+  rawbytes_.MergeFrom(from.rawbytes_);
+  boolvalue_.MergeFrom(from.boolvalue_);
+  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+    if (from._has_bit(0)) {
+      set_type(from.type());
+    }
+    if (from._has_bit(1)) {
+      set_isarray(from.isarray());
+    }
+  }
+}
+
+void GLMessage_DataType::CopyFrom(const GLMessage_DataType& from) {
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool GLMessage_DataType::IsInitialized() const {
+  if ((_has_bits_[0] & 0x00000003) != 0x00000003) return false;
+  
+  return true;
+}
+
+void GLMessage_DataType::Swap(GLMessage_DataType* other) {
+  if (other != this) {
+    std::swap(type_, other->type_);
+    std::swap(isarray_, other->isarray_);
+    intvalue_.Swap(&other->intvalue_);
+    floatvalue_.Swap(&other->floatvalue_);
+    charvalue_.Swap(&other->charvalue_);
+    rawbytes_.Swap(&other->rawbytes_);
+    boolvalue_.Swap(&other->boolvalue_);
+    std::swap(_has_bits_[0], other->_has_bits_[0]);
+    std::swap(_cached_size_, other->_cached_size_);
+  }
+}
+
+::std::string GLMessage_DataType::GetTypeName() const {
+  return "android.gltrace.GLMessage.DataType";
+}
+
+
+// -------------------------------------------------------------------
+
+#ifndef _MSC_VER
+const int GLMessage_FrameBuffer::kWidthFieldNumber;
+const int GLMessage_FrameBuffer::kHeightFieldNumber;
+const int GLMessage_FrameBuffer::kContentsFieldNumber;
+#endif  // !_MSC_VER
+
+GLMessage_FrameBuffer::GLMessage_FrameBuffer()
+  : ::google::protobuf::MessageLite() {
+  SharedCtor();
+}
+
+void GLMessage_FrameBuffer::InitAsDefaultInstance() {
+}
+
+GLMessage_FrameBuffer::GLMessage_FrameBuffer(const GLMessage_FrameBuffer& from)
+  : ::google::protobuf::MessageLite() {
+  SharedCtor();
+  MergeFrom(from);
+}
+
+void GLMessage_FrameBuffer::SharedCtor() {
+  _cached_size_ = 0;
+  width_ = 0;
+  height_ = 0;
+  ::memset(_has_bits_, 0, sizeof(_has_bits_));
+}
+
+GLMessage_FrameBuffer::~GLMessage_FrameBuffer() {
+  SharedDtor();
+}
+
+void GLMessage_FrameBuffer::SharedDtor() {
+  if (this != default_instance_) {
+  }
+}
+
+void GLMessage_FrameBuffer::SetCachedSize(int size) const {
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const GLMessage_FrameBuffer& GLMessage_FrameBuffer::default_instance() {
+  if (default_instance_ == NULL) protobuf_AddDesc_gltrace_2eproto();  return *default_instance_;
+}
+
+GLMessage_FrameBuffer* GLMessage_FrameBuffer::default_instance_ = NULL;
+
+GLMessage_FrameBuffer* GLMessage_FrameBuffer::New() const {
+  return new GLMessage_FrameBuffer;
+}
+
+void GLMessage_FrameBuffer::Clear() {
+  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+    width_ = 0;
+    height_ = 0;
+  }
+  contents_.Clear();
+  ::memset(_has_bits_, 0, sizeof(_has_bits_));
+}
+
+bool GLMessage_FrameBuffer::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
+  ::google::protobuf::uint32 tag;
+  while ((tag = input->ReadTag()) != 0) {
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // required int32 width = 1;
+      case 1: {
+        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+            ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
+                 input, &width_)));
+          _set_bit(0);
+        } else {
+          goto handle_uninterpreted;
+        }
+        if (input->ExpectTag(16)) goto parse_height;
+        break;
+      }
+      
+      // required int32 height = 2;
+      case 2: {
+        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+            ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
+         parse_height:
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
+                 input, &height_)));
+          _set_bit(1);
+        } else {
+          goto handle_uninterpreted;
+        }
+        if (input->ExpectTag(26)) goto parse_contents;
+        break;
+      }
+      
+      // repeated bytes contents = 3;
+      case 3: {
+        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+         parse_contents:
+          DO_(::google::protobuf::internal::WireFormatLite::ReadBytes(
+                input, this->add_contents()));
+        } else {
+          goto handle_uninterpreted;
+        }
+        if (input->ExpectTag(26)) goto parse_contents;
+        if (input->ExpectAtEnd()) return true;
+        break;
+      }
+      
+      default: {
+      handle_uninterpreted:
+        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
+          return true;
+        }
+        DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag));
+        break;
+      }
+    }
+  }
+  return true;
+#undef DO_
+}
+
+void GLMessage_FrameBuffer::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // required int32 width = 1;
+  if (_has_bit(0)) {
+    ::google::protobuf::internal::WireFormatLite::WriteInt32(1, this->width(), output);
+  }
+  
+  // required int32 height = 2;
+  if (_has_bit(1)) {
+    ::google::protobuf::internal::WireFormatLite::WriteInt32(2, this->height(), output);
+  }
+  
+  // repeated bytes contents = 3;
+  for (int i = 0; i < this->contents_size(); i++) {
+    ::google::protobuf::internal::WireFormatLite::WriteBytes(
+      3, this->contents(i), output);
+  }
+  
+}
+
+int GLMessage_FrameBuffer::ByteSize() const {
+  int total_size = 0;
+  
+  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+    // required int32 width = 1;
+    if (has_width()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::Int32Size(
+          this->width());
+    }
+    
+    // required int32 height = 2;
+    if (has_height()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::Int32Size(
+          this->height());
+    }
+    
+  }
+  // repeated bytes contents = 3;
+  total_size += 1 * this->contents_size();
+  for (int i = 0; i < this->contents_size(); i++) {
+    total_size += ::google::protobuf::internal::WireFormatLite::BytesSize(
+      this->contents(i));
+  }
+  
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = total_size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+  return total_size;
+}
+
+void GLMessage_FrameBuffer::CheckTypeAndMergeFrom(
+    const ::google::protobuf::MessageLite& from) {
+  MergeFrom(*::google::protobuf::down_cast<const GLMessage_FrameBuffer*>(&from));
+}
+
+void GLMessage_FrameBuffer::MergeFrom(const GLMessage_FrameBuffer& from) {
+  GOOGLE_CHECK_NE(&from, this);
+  contents_.MergeFrom(from.contents_);
+  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+    if (from._has_bit(0)) {
+      set_width(from.width());
+    }
+    if (from._has_bit(1)) {
+      set_height(from.height());
+    }
+  }
+}
+
+void GLMessage_FrameBuffer::CopyFrom(const GLMessage_FrameBuffer& from) {
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool GLMessage_FrameBuffer::IsInitialized() const {
+  if ((_has_bits_[0] & 0x00000003) != 0x00000003) return false;
+  
+  return true;
+}
+
+void GLMessage_FrameBuffer::Swap(GLMessage_FrameBuffer* other) {
+  if (other != this) {
+    std::swap(width_, other->width_);
+    std::swap(height_, other->height_);
+    contents_.Swap(&other->contents_);
+    std::swap(_has_bits_[0], other->_has_bits_[0]);
+    std::swap(_cached_size_, other->_cached_size_);
+  }
+}
+
+::std::string GLMessage_FrameBuffer::GetTypeName() const {
+  return "android.gltrace.GLMessage.FrameBuffer";
+}
+
+
+// -------------------------------------------------------------------
+
+#ifndef _MSC_VER
+const int GLMessage::kContextIdFieldNumber;
+const int GLMessage::kFunctionFieldNumber;
+const int GLMessage::kArgsFieldNumber;
+const int GLMessage::kReturnValueFieldNumber;
+const int GLMessage::kDurationFieldNumber;
+const int GLMessage::kFbFieldNumber;
+#endif  // !_MSC_VER
+
+GLMessage::GLMessage()
+  : ::google::protobuf::MessageLite() {
+  SharedCtor();
+}
+
+void GLMessage::InitAsDefaultInstance() {
+  returnvalue_ = const_cast< ::android::gltrace::GLMessage_DataType*>(&::android::gltrace::GLMessage_DataType::default_instance());
+  fb_ = const_cast< ::android::gltrace::GLMessage_FrameBuffer*>(&::android::gltrace::GLMessage_FrameBuffer::default_instance());
+}
+
+GLMessage::GLMessage(const GLMessage& from)
+  : ::google::protobuf::MessageLite() {
+  SharedCtor();
+  MergeFrom(from);
+}
+
+void GLMessage::SharedCtor() {
+  _cached_size_ = 0;
+  context_id_ = 0;
+  function_ = 3000;
+  returnvalue_ = NULL;
+  duration_ = 0;
+  fb_ = NULL;
+  ::memset(_has_bits_, 0, sizeof(_has_bits_));
+}
+
+GLMessage::~GLMessage() {
+  SharedDtor();
+}
+
+void GLMessage::SharedDtor() {
+  if (this != default_instance_) {
+    delete returnvalue_;
+    delete fb_;
+  }
+}
+
+void GLMessage::SetCachedSize(int size) const {
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const GLMessage& GLMessage::default_instance() {
+  if (default_instance_ == NULL) protobuf_AddDesc_gltrace_2eproto();  return *default_instance_;
+}
+
+GLMessage* GLMessage::default_instance_ = NULL;
+
+GLMessage* GLMessage::New() const {
+  return new GLMessage;
+}
+
+void GLMessage::Clear() {
+  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+    context_id_ = 0;
+    function_ = 3000;
+    if (_has_bit(3)) {
+      if (returnvalue_ != NULL) returnvalue_->::android::gltrace::GLMessage_DataType::Clear();
+    }
+    duration_ = 0;
+    if (_has_bit(5)) {
+      if (fb_ != NULL) fb_->::android::gltrace::GLMessage_FrameBuffer::Clear();
+    }
+  }
+  args_.Clear();
+  ::memset(_has_bits_, 0, sizeof(_has_bits_));
+}
+
+bool GLMessage::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
+  ::google::protobuf::uint32 tag;
+  while ((tag = input->ReadTag()) != 0) {
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // required int32 context_id = 1;
+      case 1: {
+        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+            ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
+                 input, &context_id_)));
+          _set_bit(0);
+        } else {
+          goto handle_uninterpreted;
+        }
+        if (input->ExpectTag(16)) goto parse_function;
+        break;
+      }
+      
+      // required .android.gltrace.GLMessage.Function function = 2 [default = invalid];
+      case 2: {
+        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+            ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
+         parse_function:
+          int value;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          if (::android::gltrace::GLMessage_Function_IsValid(value)) {
+            set_function(static_cast< ::android::gltrace::GLMessage_Function >(value));
+          }
+        } else {
+          goto handle_uninterpreted;
+        }
+        if (input->ExpectTag(26)) goto parse_args;
+        break;
+      }
+      
+      // repeated .android.gltrace.GLMessage.DataType args = 3;
+      case 3: {
+        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+         parse_args:
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+                input, add_args()));
+        } else {
+          goto handle_uninterpreted;
+        }
+        if (input->ExpectTag(26)) goto parse_args;
+        if (input->ExpectTag(34)) goto parse_returnValue;
+        break;
+      }
+      
+      // optional .android.gltrace.GLMessage.DataType returnValue = 4;
+      case 4: {
+        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+         parse_returnValue:
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+               input, mutable_returnvalue()));
+        } else {
+          goto handle_uninterpreted;
+        }
+        if (input->ExpectTag(45)) goto parse_duration;
+        break;
+      }
+      
+      // optional float duration = 5;
+      case 5: {
+        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+            ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED32) {
+         parse_duration:
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   float, ::google::protobuf::internal::WireFormatLite::TYPE_FLOAT>(
+                 input, &duration_)));
+          _set_bit(4);
+        } else {
+          goto handle_uninterpreted;
+        }
+        if (input->ExpectTag(50)) goto parse_fb;
+        break;
+      }
+      
+      // optional .android.gltrace.GLMessage.FrameBuffer fb = 6;
+      case 6: {
+        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+         parse_fb:
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+               input, mutable_fb()));
+        } else {
+          goto handle_uninterpreted;
+        }
+        if (input->ExpectAtEnd()) return true;
+        break;
+      }
+      
+      default: {
+      handle_uninterpreted:
+        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
+          return true;
+        }
+        DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag));
+        break;
+      }
+    }
+  }
+  return true;
+#undef DO_
+}
+
+void GLMessage::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // required int32 context_id = 1;
+  if (_has_bit(0)) {
+    ::google::protobuf::internal::WireFormatLite::WriteInt32(1, this->context_id(), output);
+  }
+  
+  // required .android.gltrace.GLMessage.Function function = 2 [default = invalid];
+  if (_has_bit(1)) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      2, this->function(), output);
+  }
+  
+  // repeated .android.gltrace.GLMessage.DataType args = 3;
+  for (int i = 0; i < this->args_size(); i++) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessage(
+      3, this->args(i), output);
+  }
+  
+  // optional .android.gltrace.GLMessage.DataType returnValue = 4;
+  if (_has_bit(3)) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessage(
+      4, this->returnvalue(), output);
+  }
+  
+  // optional float duration = 5;
+  if (_has_bit(4)) {
+    ::google::protobuf::internal::WireFormatLite::WriteFloat(5, this->duration(), output);
+  }
+  
+  // optional .android.gltrace.GLMessage.FrameBuffer fb = 6;
+  if (_has_bit(5)) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessage(
+      6, this->fb(), output);
+  }
+  
+}
+
+int GLMessage::ByteSize() const {
+  int total_size = 0;
+  
+  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+    // required int32 context_id = 1;
+    if (has_context_id()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::Int32Size(
+          this->context_id());
+    }
+    
+    // required .android.gltrace.GLMessage.Function function = 2 [default = invalid];
+    if (has_function()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::EnumSize(this->function());
+    }
+    
+    // optional .android.gltrace.GLMessage.DataType returnValue = 4;
+    if (has_returnvalue()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+          this->returnvalue());
+    }
+    
+    // optional float duration = 5;
+    if (has_duration()) {
+      total_size += 1 + 4;
+    }
+    
+    // optional .android.gltrace.GLMessage.FrameBuffer fb = 6;
+    if (has_fb()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+          this->fb());
+    }
+    
+  }
+  // repeated .android.gltrace.GLMessage.DataType args = 3;
+  total_size += 1 * this->args_size();
+  for (int i = 0; i < this->args_size(); i++) {
+    total_size +=
+      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+        this->args(i));
+  }
+  
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = total_size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+  return total_size;
+}
+
+void GLMessage::CheckTypeAndMergeFrom(
+    const ::google::protobuf::MessageLite& from) {
+  MergeFrom(*::google::protobuf::down_cast<const GLMessage*>(&from));
+}
+
+void GLMessage::MergeFrom(const GLMessage& from) {
+  GOOGLE_CHECK_NE(&from, this);
+  args_.MergeFrom(from.args_);
+  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+    if (from._has_bit(0)) {
+      set_context_id(from.context_id());
+    }
+    if (from._has_bit(1)) {
+      set_function(from.function());
+    }
+    if (from._has_bit(3)) {
+      mutable_returnvalue()->::android::gltrace::GLMessage_DataType::MergeFrom(from.returnvalue());
+    }
+    if (from._has_bit(4)) {
+      set_duration(from.duration());
+    }
+    if (from._has_bit(5)) {
+      mutable_fb()->::android::gltrace::GLMessage_FrameBuffer::MergeFrom(from.fb());
+    }
+  }
+}
+
+void GLMessage::CopyFrom(const GLMessage& from) {
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool GLMessage::IsInitialized() const {
+  if ((_has_bits_[0] & 0x00000003) != 0x00000003) return false;
+  
+  for (int i = 0; i < args_size(); i++) {
+    if (!this->args(i).IsInitialized()) return false;
+  }
+  if (has_returnvalue()) {
+    if (!this->returnvalue().IsInitialized()) return false;
+  }
+  if (has_fb()) {
+    if (!this->fb().IsInitialized()) return false;
+  }
+  return true;
+}
+
+void GLMessage::Swap(GLMessage* other) {
+  if (other != this) {
+    std::swap(context_id_, other->context_id_);
+    std::swap(function_, other->function_);
+    args_.Swap(&other->args_);
+    std::swap(returnvalue_, other->returnvalue_);
+    std::swap(duration_, other->duration_);
+    std::swap(fb_, other->fb_);
+    std::swap(_has_bits_[0], other->_has_bits_[0]);
+    std::swap(_cached_size_, other->_cached_size_);
+  }
+}
+
+::std::string GLMessage::GetTypeName() const {
+  return "android.gltrace.GLMessage";
+}
+
+
+// @@protoc_insertion_point(namespace_scope)
+
+}  // namespace gltrace
+}  // namespace android
+
+// @@protoc_insertion_point(global_scope)
diff --git a/opengl/libs/GLES_trace/src/gltrace.pb.h b/opengl/libs/GLES_trace/src/gltrace.pb.h
new file mode 100644
index 0000000..c39e1b2
--- /dev/null
+++ b/opengl/libs/GLES_trace/src/gltrace.pb.h
@@ -0,0 +1,1725 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: gltrace.proto
+
+#ifndef PROTOBUF_gltrace_2eproto__INCLUDED
+#define PROTOBUF_gltrace_2eproto__INCLUDED
+
+#include <string>
+
+#include <google/protobuf/stubs/common.h>
+
+#if GOOGLE_PROTOBUF_VERSION < 2003000
+#error This file was generated by a newer version of protoc which is
+#error incompatible with your Protocol Buffer headers.  Please update
+#error your headers.
+#endif
+#if 2003000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION
+#error This file was generated by an older version of protoc which is
+#error incompatible with your Protocol Buffer headers.  Please
+#error regenerate this file with a newer version of protoc.
+#endif
+
+#include <google/protobuf/generated_message_util.h>
+#include <google/protobuf/repeated_field.h>
+#include <google/protobuf/extension_set.h>
+// @@protoc_insertion_point(includes)
+
+namespace android {
+namespace gltrace {
+
+// Internal implementation detail -- do not call these.
+void  protobuf_AddDesc_gltrace_2eproto();
+void protobuf_AssignDesc_gltrace_2eproto();
+void protobuf_ShutdownFile_gltrace_2eproto();
+
+class GLMessage;
+class GLMessage_DataType;
+class GLMessage_FrameBuffer;
+
+enum GLMessage_DataType_Type {
+  GLMessage_DataType_Type_VOID = 1,
+  GLMessage_DataType_Type_CHAR = 2,
+  GLMessage_DataType_Type_BYTE = 3,
+  GLMessage_DataType_Type_INT = 4,
+  GLMessage_DataType_Type_FLOAT = 5,
+  GLMessage_DataType_Type_BOOL = 6,
+  GLMessage_DataType_Type_ENUM = 7
+};
+bool GLMessage_DataType_Type_IsValid(int value);
+const GLMessage_DataType_Type GLMessage_DataType_Type_Type_MIN = GLMessage_DataType_Type_VOID;
+const GLMessage_DataType_Type GLMessage_DataType_Type_Type_MAX = GLMessage_DataType_Type_ENUM;
+const int GLMessage_DataType_Type_Type_ARRAYSIZE = GLMessage_DataType_Type_Type_MAX + 1;
+
+enum GLMessage_Function {
+  GLMessage_Function_glActiveTexture = 0,
+  GLMessage_Function_glAlphaFunc = 1,
+  GLMessage_Function_glAlphaFuncx = 2,
+  GLMessage_Function_glAlphaFuncxOES = 3,
+  GLMessage_Function_glAttachShader = 4,
+  GLMessage_Function_glBeginPerfMonitorAMD = 5,
+  GLMessage_Function_glBindAttribLocation = 6,
+  GLMessage_Function_glBindBuffer = 7,
+  GLMessage_Function_glBindFramebuffer = 8,
+  GLMessage_Function_glBindFramebufferOES = 9,
+  GLMessage_Function_glBindRenderbuffer = 10,
+  GLMessage_Function_glBindRenderbufferOES = 11,
+  GLMessage_Function_glBindTexture = 12,
+  GLMessage_Function_glBindVertexArrayOES = 13,
+  GLMessage_Function_glBlendColor = 14,
+  GLMessage_Function_glBlendEquation = 15,
+  GLMessage_Function_glBlendEquationOES = 16,
+  GLMessage_Function_glBlendEquationSeparate = 17,
+  GLMessage_Function_glBlendEquationSeparateOES = 18,
+  GLMessage_Function_glBlendFunc = 19,
+  GLMessage_Function_glBlendFuncSeparate = 20,
+  GLMessage_Function_glBlendFuncSeparateOES = 21,
+  GLMessage_Function_glBufferData = 22,
+  GLMessage_Function_glBufferSubData = 23,
+  GLMessage_Function_glCheckFramebufferStatus = 24,
+  GLMessage_Function_glCheckFramebufferStatusOES = 25,
+  GLMessage_Function_glClearColor = 26,
+  GLMessage_Function_glClearColorx = 27,
+  GLMessage_Function_glClearColorxOES = 28,
+  GLMessage_Function_glClearDepthf = 29,
+  GLMessage_Function_glClearDepthfOES = 30,
+  GLMessage_Function_glClearDepthx = 31,
+  GLMessage_Function_glClearDepthxOES = 32,
+  GLMessage_Function_glClear = 33,
+  GLMessage_Function_glClearStencil = 34,
+  GLMessage_Function_glClientActiveTexture = 35,
+  GLMessage_Function_glClipPlanef = 36,
+  GLMessage_Function_glClipPlanefIMG = 37,
+  GLMessage_Function_glClipPlanefOES = 38,
+  GLMessage_Function_glClipPlanex = 39,
+  GLMessage_Function_glClipPlanexIMG = 40,
+  GLMessage_Function_glClipPlanexOES = 41,
+  GLMessage_Function_glColor4f = 42,
+  GLMessage_Function_glColor4ub = 43,
+  GLMessage_Function_glColor4x = 44,
+  GLMessage_Function_glColor4xOES = 45,
+  GLMessage_Function_glColorMask = 46,
+  GLMessage_Function_glColorPointer = 47,
+  GLMessage_Function_glCompileShader = 48,
+  GLMessage_Function_glCompressedTexImage2D = 49,
+  GLMessage_Function_glCompressedTexImage3DOES = 50,
+  GLMessage_Function_glCompressedTexSubImage2D = 51,
+  GLMessage_Function_glCompressedTexSubImage3DOES = 52,
+  GLMessage_Function_glCopyTexImage2D = 53,
+  GLMessage_Function_glCopyTexSubImage2D = 54,
+  GLMessage_Function_glCopyTexSubImage3DOES = 55,
+  GLMessage_Function_glCoverageMaskNV = 56,
+  GLMessage_Function_glCoverageOperationNV = 57,
+  GLMessage_Function_glCreateProgram = 58,
+  GLMessage_Function_glCreateShader = 59,
+  GLMessage_Function_glCullFace = 60,
+  GLMessage_Function_glCurrentPaletteMatrixOES = 61,
+  GLMessage_Function_glDeleteBuffers = 62,
+  GLMessage_Function_glDeleteFencesNV = 63,
+  GLMessage_Function_glDeleteFramebuffers = 64,
+  GLMessage_Function_glDeleteFramebuffersOES = 65,
+  GLMessage_Function_glDeletePerfMonitorsAMD = 66,
+  GLMessage_Function_glDeleteProgram = 67,
+  GLMessage_Function_glDeleteRenderbuffers = 68,
+  GLMessage_Function_glDeleteRenderbuffersOES = 69,
+  GLMessage_Function_glDeleteShader = 70,
+  GLMessage_Function_glDeleteTextures = 71,
+  GLMessage_Function_glDeleteVertexArraysOES = 72,
+  GLMessage_Function_glDepthFunc = 73,
+  GLMessage_Function_glDepthMask = 74,
+  GLMessage_Function_glDepthRangef = 75,
+  GLMessage_Function_glDepthRangefOES = 76,
+  GLMessage_Function_glDepthRangex = 77,
+  GLMessage_Function_glDepthRangexOES = 78,
+  GLMessage_Function_glDetachShader = 79,
+  GLMessage_Function_glDisableClientState = 80,
+  GLMessage_Function_glDisableDriverControlQCOM = 81,
+  GLMessage_Function_glDisable = 82,
+  GLMessage_Function_glDisableVertexAttribArray = 83,
+  GLMessage_Function_glDiscardFramebufferEXT = 84,
+  GLMessage_Function_glDrawArrays = 85,
+  GLMessage_Function_glDrawElements = 86,
+  GLMessage_Function_glDrawTexfOES = 87,
+  GLMessage_Function_glDrawTexfvOES = 88,
+  GLMessage_Function_glDrawTexiOES = 89,
+  GLMessage_Function_glDrawTexivOES = 90,
+  GLMessage_Function_glDrawTexsOES = 91,
+  GLMessage_Function_glDrawTexsvOES = 92,
+  GLMessage_Function_glDrawTexxOES = 93,
+  GLMessage_Function_glDrawTexxvOES = 94,
+  GLMessage_Function_glEGLImageTargetRenderbufferStorageOES = 95,
+  GLMessage_Function_glEGLImageTargetTexture2DOES = 96,
+  GLMessage_Function_glEnableClientState = 97,
+  GLMessage_Function_glEnableDriverControlQCOM = 98,
+  GLMessage_Function_glEnable = 99,
+  GLMessage_Function_glEnableVertexAttribArray = 100,
+  GLMessage_Function_glEndPerfMonitorAMD = 101,
+  GLMessage_Function_glEndTilingQCOM = 102,
+  GLMessage_Function_glExtGetBufferPointervQCOM = 103,
+  GLMessage_Function_glExtGetBuffersQCOM = 104,
+  GLMessage_Function_glExtGetFramebuffersQCOM = 105,
+  GLMessage_Function_glExtGetProgramBinarySourceQCOM = 106,
+  GLMessage_Function_glExtGetProgramsQCOM = 107,
+  GLMessage_Function_glExtGetRenderbuffersQCOM = 108,
+  GLMessage_Function_glExtGetShadersQCOM = 109,
+  GLMessage_Function_glExtGetTexLevelParameterivQCOM = 110,
+  GLMessage_Function_glExtGetTexSubImageQCOM = 111,
+  GLMessage_Function_glExtGetTexturesQCOM = 112,
+  GLMessage_Function_glExtIsProgramBinaryQCOM = 113,
+  GLMessage_Function_glExtTexObjectStateOverrideiQCOM = 114,
+  GLMessage_Function_glFinishFenceNV = 115,
+  GLMessage_Function_glFinish = 116,
+  GLMessage_Function_glFlush = 117,
+  GLMessage_Function_glFogf = 118,
+  GLMessage_Function_glFogfv = 119,
+  GLMessage_Function_glFogx = 120,
+  GLMessage_Function_glFogxOES = 121,
+  GLMessage_Function_glFogxv = 122,
+  GLMessage_Function_glFogxvOES = 123,
+  GLMessage_Function_glFramebufferRenderbuffer = 124,
+  GLMessage_Function_glFramebufferRenderbufferOES = 125,
+  GLMessage_Function_glFramebufferTexture2D = 126,
+  GLMessage_Function_glFramebufferTexture2DMultisampleIMG = 127,
+  GLMessage_Function_glFramebufferTexture2DOES = 128,
+  GLMessage_Function_glFramebufferTexture3DOES = 129,
+  GLMessage_Function_glFrontFace = 130,
+  GLMessage_Function_glFrustumf = 131,
+  GLMessage_Function_glFrustumfOES = 132,
+  GLMessage_Function_glFrustumx = 133,
+  GLMessage_Function_glFrustumxOES = 134,
+  GLMessage_Function_glGenBuffers = 135,
+  GLMessage_Function_glGenerateMipmap = 136,
+  GLMessage_Function_glGenerateMipmapOES = 137,
+  GLMessage_Function_glGenFencesNV = 138,
+  GLMessage_Function_glGenFramebuffers = 139,
+  GLMessage_Function_glGenFramebuffersOES = 140,
+  GLMessage_Function_glGenPerfMonitorsAMD = 141,
+  GLMessage_Function_glGenRenderbuffers = 142,
+  GLMessage_Function_glGenRenderbuffersOES = 143,
+  GLMessage_Function_glGenTextures = 144,
+  GLMessage_Function_glGenVertexArraysOES = 145,
+  GLMessage_Function_glGetActiveAttrib = 146,
+  GLMessage_Function_glGetActiveUniform = 147,
+  GLMessage_Function_glGetAttachedShaders = 148,
+  GLMessage_Function_glGetAttribLocation = 149,
+  GLMessage_Function_glGetBooleanv = 150,
+  GLMessage_Function_glGetBufferParameteriv = 151,
+  GLMessage_Function_glGetBufferPointervOES = 152,
+  GLMessage_Function_glGetClipPlanef = 153,
+  GLMessage_Function_glGetClipPlanefOES = 154,
+  GLMessage_Function_glGetClipPlanex = 155,
+  GLMessage_Function_glGetClipPlanexOES = 156,
+  GLMessage_Function_glGetDriverControlsQCOM = 157,
+  GLMessage_Function_glGetDriverControlStringQCOM = 158,
+  GLMessage_Function_glGetError = 159,
+  GLMessage_Function_glGetFenceivNV = 160,
+  GLMessage_Function_glGetFixedv = 161,
+  GLMessage_Function_glGetFixedvOES = 162,
+  GLMessage_Function_glGetFloatv = 163,
+  GLMessage_Function_glGetFramebufferAttachmentParameteriv = 164,
+  GLMessage_Function_glGetFramebufferAttachmentParameterivOES = 165,
+  GLMessage_Function_glGetIntegerv = 166,
+  GLMessage_Function_glGetLightfv = 167,
+  GLMessage_Function_glGetLightxv = 168,
+  GLMessage_Function_glGetLightxvOES = 169,
+  GLMessage_Function_glGetMaterialfv = 170,
+  GLMessage_Function_glGetMaterialxv = 171,
+  GLMessage_Function_glGetMaterialxvOES = 172,
+  GLMessage_Function_glGetPerfMonitorCounterDataAMD = 173,
+  GLMessage_Function_glGetPerfMonitorCounterInfoAMD = 174,
+  GLMessage_Function_glGetPerfMonitorCountersAMD = 175,
+  GLMessage_Function_glGetPerfMonitorCounterStringAMD = 176,
+  GLMessage_Function_glGetPerfMonitorGroupsAMD = 177,
+  GLMessage_Function_glGetPerfMonitorGroupStringAMD = 178,
+  GLMessage_Function_glGetPointerv = 179,
+  GLMessage_Function_glGetProgramBinaryOES = 180,
+  GLMessage_Function_glGetProgramInfoLog = 181,
+  GLMessage_Function_glGetProgramiv = 182,
+  GLMessage_Function_glGetRenderbufferParameteriv = 183,
+  GLMessage_Function_glGetRenderbufferParameterivOES = 184,
+  GLMessage_Function_glGetShaderInfoLog = 185,
+  GLMessage_Function_glGetShaderiv = 186,
+  GLMessage_Function_glGetShaderPrecisionFormat = 187,
+  GLMessage_Function_glGetShaderSource = 188,
+  GLMessage_Function_glGetString = 189,
+  GLMessage_Function_glGetTexEnvfv = 190,
+  GLMessage_Function_glGetTexEnviv = 191,
+  GLMessage_Function_glGetTexEnvxv = 192,
+  GLMessage_Function_glGetTexEnvxvOES = 193,
+  GLMessage_Function_glGetTexGenfvOES = 194,
+  GLMessage_Function_glGetTexGenivOES = 195,
+  GLMessage_Function_glGetTexGenxvOES = 196,
+  GLMessage_Function_glGetTexParameterfv = 197,
+  GLMessage_Function_glGetTexParameteriv = 198,
+  GLMessage_Function_glGetTexParameterxv = 199,
+  GLMessage_Function_glGetTexParameterxvOES = 200,
+  GLMessage_Function_glGetUniformfv = 201,
+  GLMessage_Function_glGetUniformiv = 202,
+  GLMessage_Function_glGetUniformLocation = 203,
+  GLMessage_Function_glGetVertexAttribfv = 204,
+  GLMessage_Function_glGetVertexAttribiv = 205,
+  GLMessage_Function_glGetVertexAttribPointerv = 206,
+  GLMessage_Function_glHint = 207,
+  GLMessage_Function_glIsBuffer = 208,
+  GLMessage_Function_glIsEnabled = 209,
+  GLMessage_Function_glIsFenceNV = 210,
+  GLMessage_Function_glIsFramebuffer = 211,
+  GLMessage_Function_glIsFramebufferOES = 212,
+  GLMessage_Function_glIsProgram = 213,
+  GLMessage_Function_glIsRenderbuffer = 214,
+  GLMessage_Function_glIsRenderbufferOES = 215,
+  GLMessage_Function_glIsShader = 216,
+  GLMessage_Function_glIsTexture = 217,
+  GLMessage_Function_glIsVertexArrayOES = 218,
+  GLMessage_Function_glLightf = 219,
+  GLMessage_Function_glLightfv = 220,
+  GLMessage_Function_glLightModelf = 221,
+  GLMessage_Function_glLightModelfv = 222,
+  GLMessage_Function_glLightModelx = 223,
+  GLMessage_Function_glLightModelxOES = 224,
+  GLMessage_Function_glLightModelxv = 225,
+  GLMessage_Function_glLightModelxvOES = 226,
+  GLMessage_Function_glLightx = 227,
+  GLMessage_Function_glLightxOES = 228,
+  GLMessage_Function_glLightxv = 229,
+  GLMessage_Function_glLightxvOES = 230,
+  GLMessage_Function_glLineWidth = 231,
+  GLMessage_Function_glLineWidthx = 232,
+  GLMessage_Function_glLineWidthxOES = 233,
+  GLMessage_Function_glLinkProgram = 234,
+  GLMessage_Function_glLoadIdentity = 235,
+  GLMessage_Function_glLoadMatrixf = 236,
+  GLMessage_Function_glLoadMatrixx = 237,
+  GLMessage_Function_glLoadMatrixxOES = 238,
+  GLMessage_Function_glLoadPaletteFromModelViewMatrixOES = 239,
+  GLMessage_Function_glLogicOp = 240,
+  GLMessage_Function_glMapBufferOES = 241,
+  GLMessage_Function_glMaterialf = 242,
+  GLMessage_Function_glMaterialfv = 243,
+  GLMessage_Function_glMaterialx = 244,
+  GLMessage_Function_glMaterialxOES = 245,
+  GLMessage_Function_glMaterialxv = 246,
+  GLMessage_Function_glMaterialxvOES = 247,
+  GLMessage_Function_glMatrixIndexPointerOES = 248,
+  GLMessage_Function_glMatrixMode = 249,
+  GLMessage_Function_glMultiDrawArraysEXT = 250,
+  GLMessage_Function_glMultiDrawElementsEXT = 251,
+  GLMessage_Function_glMultiTexCoord4f = 252,
+  GLMessage_Function_glMultiTexCoord4x = 253,
+  GLMessage_Function_glMultiTexCoord4xOES = 254,
+  GLMessage_Function_glMultMatrixf = 255,
+  GLMessage_Function_glMultMatrixx = 256,
+  GLMessage_Function_glMultMatrixxOES = 257,
+  GLMessage_Function_glNormal3f = 258,
+  GLMessage_Function_glNormal3x = 259,
+  GLMessage_Function_glNormal3xOES = 260,
+  GLMessage_Function_glNormalPointer = 261,
+  GLMessage_Function_glOrthof = 262,
+  GLMessage_Function_glOrthofOES = 263,
+  GLMessage_Function_glOrthox = 264,
+  GLMessage_Function_glOrthoxOES = 265,
+  GLMessage_Function_glPixelStorei = 266,
+  GLMessage_Function_glPointParameterf = 267,
+  GLMessage_Function_glPointParameterfv = 268,
+  GLMessage_Function_glPointParameterx = 269,
+  GLMessage_Function_glPointParameterxOES = 270,
+  GLMessage_Function_glPointParameterxv = 271,
+  GLMessage_Function_glPointParameterxvOES = 272,
+  GLMessage_Function_glPointSize = 273,
+  GLMessage_Function_glPointSizePointerOES = 274,
+  GLMessage_Function_glPointSizex = 275,
+  GLMessage_Function_glPointSizexOES = 276,
+  GLMessage_Function_glPolygonOffset = 277,
+  GLMessage_Function_glPolygonOffsetx = 278,
+  GLMessage_Function_glPolygonOffsetxOES = 279,
+  GLMessage_Function_glPopMatrix = 280,
+  GLMessage_Function_glProgramBinaryOES = 281,
+  GLMessage_Function_glPushMatrix = 282,
+  GLMessage_Function_glQueryMatrixxOES = 283,
+  GLMessage_Function_glReadPixels = 284,
+  GLMessage_Function_glReleaseShaderCompiler = 285,
+  GLMessage_Function_glRenderbufferStorage = 286,
+  GLMessage_Function_glRenderbufferStorageMultisampleIMG = 287,
+  GLMessage_Function_glRenderbufferStorageOES = 288,
+  GLMessage_Function_glRotatef = 289,
+  GLMessage_Function_glRotatex = 290,
+  GLMessage_Function_glRotatexOES = 291,
+  GLMessage_Function_glSampleCoverage = 292,
+  GLMessage_Function_glSampleCoveragex = 293,
+  GLMessage_Function_glSampleCoveragexOES = 294,
+  GLMessage_Function_glScalef = 295,
+  GLMessage_Function_glScalex = 296,
+  GLMessage_Function_glScalexOES = 297,
+  GLMessage_Function_glScissor = 298,
+  GLMessage_Function_glSelectPerfMonitorCountersAMD = 299,
+  GLMessage_Function_glSetFenceNV = 300,
+  GLMessage_Function_glShadeModel = 301,
+  GLMessage_Function_glShaderBinary = 302,
+  GLMessage_Function_glShaderSource = 303,
+  GLMessage_Function_glStartTilingQCOM = 304,
+  GLMessage_Function_glStencilFunc = 305,
+  GLMessage_Function_glStencilFuncSeparate = 306,
+  GLMessage_Function_glStencilMask = 307,
+  GLMessage_Function_glStencilMaskSeparate = 308,
+  GLMessage_Function_glStencilOp = 309,
+  GLMessage_Function_glStencilOpSeparate = 310,
+  GLMessage_Function_glTestFenceNV = 311,
+  GLMessage_Function_glTexCoordPointer = 312,
+  GLMessage_Function_glTexEnvf = 313,
+  GLMessage_Function_glTexEnvfv = 314,
+  GLMessage_Function_glTexEnvi = 315,
+  GLMessage_Function_glTexEnviv = 316,
+  GLMessage_Function_glTexEnvx = 317,
+  GLMessage_Function_glTexEnvxOES = 318,
+  GLMessage_Function_glTexEnvxv = 319,
+  GLMessage_Function_glTexEnvxvOES = 320,
+  GLMessage_Function_glTexGenfOES = 321,
+  GLMessage_Function_glTexGenfvOES = 322,
+  GLMessage_Function_glTexGeniOES = 323,
+  GLMessage_Function_glTexGenivOES = 324,
+  GLMessage_Function_glTexGenxOES = 325,
+  GLMessage_Function_glTexGenxvOES = 326,
+  GLMessage_Function_glTexImage2D = 327,
+  GLMessage_Function_glTexImage3DOES = 328,
+  GLMessage_Function_glTexParameterf = 329,
+  GLMessage_Function_glTexParameterfv = 330,
+  GLMessage_Function_glTexParameteri = 331,
+  GLMessage_Function_glTexParameteriv = 332,
+  GLMessage_Function_glTexParameterx = 333,
+  GLMessage_Function_glTexParameterxOES = 334,
+  GLMessage_Function_glTexParameterxv = 335,
+  GLMessage_Function_glTexParameterxvOES = 336,
+  GLMessage_Function_glTexSubImage2D = 337,
+  GLMessage_Function_glTexSubImage3DOES = 338,
+  GLMessage_Function_glTranslatef = 339,
+  GLMessage_Function_glTranslatex = 340,
+  GLMessage_Function_glTranslatexOES = 341,
+  GLMessage_Function_glUniform1f = 342,
+  GLMessage_Function_glUniform1fv = 343,
+  GLMessage_Function_glUniform1i = 344,
+  GLMessage_Function_glUniform1iv = 345,
+  GLMessage_Function_glUniform2f = 346,
+  GLMessage_Function_glUniform2fv = 347,
+  GLMessage_Function_glUniform2i = 348,
+  GLMessage_Function_glUniform2iv = 349,
+  GLMessage_Function_glUniform3f = 350,
+  GLMessage_Function_glUniform3fv = 351,
+  GLMessage_Function_glUniform3i = 352,
+  GLMessage_Function_glUniform3iv = 353,
+  GLMessage_Function_glUniform4f = 354,
+  GLMessage_Function_glUniform4fv = 355,
+  GLMessage_Function_glUniform4i = 356,
+  GLMessage_Function_glUniform4iv = 357,
+  GLMessage_Function_glUniformMatrix2fv = 358,
+  GLMessage_Function_glUniformMatrix3fv = 359,
+  GLMessage_Function_glUniformMatrix4fv = 360,
+  GLMessage_Function_glUnmapBufferOES = 361,
+  GLMessage_Function_glUseProgram = 362,
+  GLMessage_Function_glValidateProgram = 363,
+  GLMessage_Function_glVertexAttrib1f = 364,
+  GLMessage_Function_glVertexAttrib1fv = 365,
+  GLMessage_Function_glVertexAttrib2f = 366,
+  GLMessage_Function_glVertexAttrib2fv = 367,
+  GLMessage_Function_glVertexAttrib3f = 368,
+  GLMessage_Function_glVertexAttrib3fv = 369,
+  GLMessage_Function_glVertexAttrib4f = 370,
+  GLMessage_Function_glVertexAttrib4fv = 371,
+  GLMessage_Function_glVertexAttribPointer = 372,
+  GLMessage_Function_glVertexPointer = 373,
+  GLMessage_Function_glViewport = 374,
+  GLMessage_Function_glWeightPointerOES = 375,
+  GLMessage_Function_eglGetDisplay = 2000,
+  GLMessage_Function_eglInitialize = 2001,
+  GLMessage_Function_eglTerminate = 2002,
+  GLMessage_Function_eglGetConfigs = 2003,
+  GLMessage_Function_eglChooseConfig = 2004,
+  GLMessage_Function_eglGetConfigAttrib = 2005,
+  GLMessage_Function_eglCreateWindowSurface = 2006,
+  GLMessage_Function_eglCreatePixmapSurface = 2007,
+  GLMessage_Function_eglCreatePbufferSurface = 2008,
+  GLMessage_Function_eglDestroySurface = 2009,
+  GLMessage_Function_eglQuerySurface = 2010,
+  GLMessage_Function_eglCreateContext = 2011,
+  GLMessage_Function_eglDestroyContext = 2012,
+  GLMessage_Function_eglMakeCurrent = 2013,
+  GLMessage_Function_eglGetCurrentContext = 2014,
+  GLMessage_Function_eglGetCurrentSurface = 2015,
+  GLMessage_Function_eglGetCurrentDisplay = 2016,
+  GLMessage_Function_eglQueryContext = 2017,
+  GLMessage_Function_eglWaitGL = 2018,
+  GLMessage_Function_eglWaitNative = 2019,
+  GLMessage_Function_eglSwapBuffers = 2020,
+  GLMessage_Function_eglCopyBuffers = 2021,
+  GLMessage_Function_eglGetError = 2022,
+  GLMessage_Function_eglQueryString = 2023,
+  GLMessage_Function_eglGetProcAddress = 2024,
+  GLMessage_Function_eglSurfaceAttrib = 2025,
+  GLMessage_Function_eglBindTexImage = 2026,
+  GLMessage_Function_eglReleaseTexImage = 2027,
+  GLMessage_Function_eglSwapInterval = 2028,
+  GLMessage_Function_eglBindAPI = 2029,
+  GLMessage_Function_eglQueryAPI = 2030,
+  GLMessage_Function_eglWaitClient = 2031,
+  GLMessage_Function_eglReleaseThread = 2032,
+  GLMessage_Function_eglCreatePbufferFromClientBuffer = 2033,
+  GLMessage_Function_eglLockSurfaceKHR = 2034,
+  GLMessage_Function_eglUnlockSurfaceKHR = 2035,
+  GLMessage_Function_eglCreateImageKHR = 2036,
+  GLMessage_Function_eglDestroyImageKHR = 2037,
+  GLMessage_Function_eglCreateSyncKHR = 2038,
+  GLMessage_Function_eglDestroySyncKHR = 2039,
+  GLMessage_Function_eglClientWaitSyncKHR = 2040,
+  GLMessage_Function_eglGetSyncAttribKHR = 2041,
+  GLMessage_Function_eglSetSwapRectangleANDROID = 2042,
+  GLMessage_Function_eglGetRenderBufferANDROID = 2043,
+  GLMessage_Function_eglGetSystemTimeFrequencyNV = 2044,
+  GLMessage_Function_eglGetSystemTimeNV = 2045,
+  GLMessage_Function_invalid = 3000,
+  GLMessage_Function_frameBufferContents = 3001
+};
+bool GLMessage_Function_IsValid(int value);
+const GLMessage_Function GLMessage_Function_Function_MIN = GLMessage_Function_glActiveTexture;
+const GLMessage_Function GLMessage_Function_Function_MAX = GLMessage_Function_frameBufferContents;
+const int GLMessage_Function_Function_ARRAYSIZE = GLMessage_Function_Function_MAX + 1;
+
+// ===================================================================
+
+class GLMessage_DataType : public ::google::protobuf::MessageLite {
+ public:
+  GLMessage_DataType();
+  virtual ~GLMessage_DataType();
+  
+  GLMessage_DataType(const GLMessage_DataType& from);
+  
+  inline GLMessage_DataType& operator=(const GLMessage_DataType& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  
+  static const GLMessage_DataType& default_instance();
+  
+  void Swap(GLMessage_DataType* other);
+  
+  // implements Message ----------------------------------------------
+  
+  GLMessage_DataType* New() const;
+  void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
+  void CopyFrom(const GLMessage_DataType& from);
+  void MergeFrom(const GLMessage_DataType& from);
+  void Clear();
+  bool IsInitialized() const;
+  
+  int ByteSize() const;
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input);
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const;
+  int GetCachedSize() const { return _cached_size_; }
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const;
+  public:
+  
+  ::std::string GetTypeName() const;
+  
+  // nested types ----------------------------------------------------
+  
+  typedef GLMessage_DataType_Type Type;
+  static const Type VOID = GLMessage_DataType_Type_VOID;
+  static const Type CHAR = GLMessage_DataType_Type_CHAR;
+  static const Type BYTE = GLMessage_DataType_Type_BYTE;
+  static const Type INT = GLMessage_DataType_Type_INT;
+  static const Type FLOAT = GLMessage_DataType_Type_FLOAT;
+  static const Type BOOL = GLMessage_DataType_Type_BOOL;
+  static const Type ENUM = GLMessage_DataType_Type_ENUM;
+  static inline bool Type_IsValid(int value) {
+    return GLMessage_DataType_Type_IsValid(value);
+  }
+  static const Type Type_MIN =
+    GLMessage_DataType_Type_Type_MIN;
+  static const Type Type_MAX =
+    GLMessage_DataType_Type_Type_MAX;
+  static const int Type_ARRAYSIZE =
+    GLMessage_DataType_Type_Type_ARRAYSIZE;
+  
+  // accessors -------------------------------------------------------
+  
+  // required .android.gltrace.GLMessage.DataType.Type type = 1 [default = VOID];
+  inline bool has_type() const;
+  inline void clear_type();
+  static const int kTypeFieldNumber = 1;
+  inline ::android::gltrace::GLMessage_DataType_Type type() const;
+  inline void set_type(::android::gltrace::GLMessage_DataType_Type value);
+  
+  // required bool isArray = 2 [default = false];
+  inline bool has_isarray() const;
+  inline void clear_isarray();
+  static const int kIsArrayFieldNumber = 2;
+  inline bool isarray() const;
+  inline void set_isarray(bool value);
+  
+  // repeated int32 intValue = 3;
+  inline int intvalue_size() const;
+  inline void clear_intvalue();
+  static const int kIntValueFieldNumber = 3;
+  inline ::google::protobuf::int32 intvalue(int index) const;
+  inline void set_intvalue(int index, ::google::protobuf::int32 value);
+  inline void add_intvalue(::google::protobuf::int32 value);
+  inline const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >&
+      intvalue() const;
+  inline ::google::protobuf::RepeatedField< ::google::protobuf::int32 >*
+      mutable_intvalue();
+  
+  // repeated float floatValue = 4;
+  inline int floatvalue_size() const;
+  inline void clear_floatvalue();
+  static const int kFloatValueFieldNumber = 4;
+  inline float floatvalue(int index) const;
+  inline void set_floatvalue(int index, float value);
+  inline void add_floatvalue(float value);
+  inline const ::google::protobuf::RepeatedField< float >&
+      floatvalue() const;
+  inline ::google::protobuf::RepeatedField< float >*
+      mutable_floatvalue();
+  
+  // repeated bytes charValue = 5;
+  inline int charvalue_size() const;
+  inline void clear_charvalue();
+  static const int kCharValueFieldNumber = 5;
+  inline const ::std::string& charvalue(int index) const;
+  inline ::std::string* mutable_charvalue(int index);
+  inline void set_charvalue(int index, const ::std::string& value);
+  inline void set_charvalue(int index, const char* value);
+  inline void set_charvalue(int index, const void* value, size_t size);
+  inline ::std::string* add_charvalue();
+  inline void add_charvalue(const ::std::string& value);
+  inline void add_charvalue(const char* value);
+  inline void add_charvalue(const void* value, size_t size);
+  inline const ::google::protobuf::RepeatedPtrField< ::std::string>& charvalue() const;
+  inline ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_charvalue();
+  
+  // repeated bytes rawBytes = 6;
+  inline int rawbytes_size() const;
+  inline void clear_rawbytes();
+  static const int kRawBytesFieldNumber = 6;
+  inline const ::std::string& rawbytes(int index) const;
+  inline ::std::string* mutable_rawbytes(int index);
+  inline void set_rawbytes(int index, const ::std::string& value);
+  inline void set_rawbytes(int index, const char* value);
+  inline void set_rawbytes(int index, const void* value, size_t size);
+  inline ::std::string* add_rawbytes();
+  inline void add_rawbytes(const ::std::string& value);
+  inline void add_rawbytes(const char* value);
+  inline void add_rawbytes(const void* value, size_t size);
+  inline const ::google::protobuf::RepeatedPtrField< ::std::string>& rawbytes() const;
+  inline ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_rawbytes();
+  
+  // repeated bool boolValue = 7;
+  inline int boolvalue_size() const;
+  inline void clear_boolvalue();
+  static const int kBoolValueFieldNumber = 7;
+  inline bool boolvalue(int index) const;
+  inline void set_boolvalue(int index, bool value);
+  inline void add_boolvalue(bool value);
+  inline const ::google::protobuf::RepeatedField< bool >&
+      boolvalue() const;
+  inline ::google::protobuf::RepeatedField< bool >*
+      mutable_boolvalue();
+  
+  // @@protoc_insertion_point(class_scope:android.gltrace.GLMessage.DataType)
+ private:
+  mutable int _cached_size_;
+  
+  int type_;
+  bool isarray_;
+  ::google::protobuf::RepeatedField< ::google::protobuf::int32 > intvalue_;
+  ::google::protobuf::RepeatedField< float > floatvalue_;
+  ::google::protobuf::RepeatedPtrField< ::std::string> charvalue_;
+  ::google::protobuf::RepeatedPtrField< ::std::string> rawbytes_;
+  ::google::protobuf::RepeatedField< bool > boolvalue_;
+  friend void  protobuf_AddDesc_gltrace_2eproto();
+  friend void protobuf_AssignDesc_gltrace_2eproto();
+  friend void protobuf_ShutdownFile_gltrace_2eproto();
+  
+  ::google::protobuf::uint32 _has_bits_[(7 + 31) / 32];
+  
+  // WHY DOES & HAVE LOWER PRECEDENCE THAN != !?
+  inline bool _has_bit(int index) const {
+    return (_has_bits_[index / 32] & (1u << (index % 32))) != 0;
+  }
+  inline void _set_bit(int index) {
+    _has_bits_[index / 32] |= (1u << (index % 32));
+  }
+  inline void _clear_bit(int index) {
+    _has_bits_[index / 32] &= ~(1u << (index % 32));
+  }
+  
+  void InitAsDefaultInstance();
+  static GLMessage_DataType* default_instance_;
+};
+// -------------------------------------------------------------------
+
+class GLMessage_FrameBuffer : public ::google::protobuf::MessageLite {
+ public:
+  GLMessage_FrameBuffer();
+  virtual ~GLMessage_FrameBuffer();
+  
+  GLMessage_FrameBuffer(const GLMessage_FrameBuffer& from);
+  
+  inline GLMessage_FrameBuffer& operator=(const GLMessage_FrameBuffer& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  
+  static const GLMessage_FrameBuffer& default_instance();
+  
+  void Swap(GLMessage_FrameBuffer* other);
+  
+  // implements Message ----------------------------------------------
+  
+  GLMessage_FrameBuffer* New() const;
+  void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
+  void CopyFrom(const GLMessage_FrameBuffer& from);
+  void MergeFrom(const GLMessage_FrameBuffer& from);
+  void Clear();
+  bool IsInitialized() const;
+  
+  int ByteSize() const;
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input);
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const;
+  int GetCachedSize() const { return _cached_size_; }
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const;
+  public:
+  
+  ::std::string GetTypeName() const;
+  
+  // nested types ----------------------------------------------------
+  
+  // accessors -------------------------------------------------------
+  
+  // required int32 width = 1;
+  inline bool has_width() const;
+  inline void clear_width();
+  static const int kWidthFieldNumber = 1;
+  inline ::google::protobuf::int32 width() const;
+  inline void set_width(::google::protobuf::int32 value);
+  
+  // required int32 height = 2;
+  inline bool has_height() const;
+  inline void clear_height();
+  static const int kHeightFieldNumber = 2;
+  inline ::google::protobuf::int32 height() const;
+  inline void set_height(::google::protobuf::int32 value);
+  
+  // repeated bytes contents = 3;
+  inline int contents_size() const;
+  inline void clear_contents();
+  static const int kContentsFieldNumber = 3;
+  inline const ::std::string& contents(int index) const;
+  inline ::std::string* mutable_contents(int index);
+  inline void set_contents(int index, const ::std::string& value);
+  inline void set_contents(int index, const char* value);
+  inline void set_contents(int index, const void* value, size_t size);
+  inline ::std::string* add_contents();
+  inline void add_contents(const ::std::string& value);
+  inline void add_contents(const char* value);
+  inline void add_contents(const void* value, size_t size);
+  inline const ::google::protobuf::RepeatedPtrField< ::std::string>& contents() const;
+  inline ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_contents();
+  
+  // @@protoc_insertion_point(class_scope:android.gltrace.GLMessage.FrameBuffer)
+ private:
+  mutable int _cached_size_;
+  
+  ::google::protobuf::int32 width_;
+  ::google::protobuf::int32 height_;
+  ::google::protobuf::RepeatedPtrField< ::std::string> contents_;
+  friend void  protobuf_AddDesc_gltrace_2eproto();
+  friend void protobuf_AssignDesc_gltrace_2eproto();
+  friend void protobuf_ShutdownFile_gltrace_2eproto();
+  
+  ::google::protobuf::uint32 _has_bits_[(3 + 31) / 32];
+  
+  // WHY DOES & HAVE LOWER PRECEDENCE THAN != !?
+  inline bool _has_bit(int index) const {
+    return (_has_bits_[index / 32] & (1u << (index % 32))) != 0;
+  }
+  inline void _set_bit(int index) {
+    _has_bits_[index / 32] |= (1u << (index % 32));
+  }
+  inline void _clear_bit(int index) {
+    _has_bits_[index / 32] &= ~(1u << (index % 32));
+  }
+  
+  void InitAsDefaultInstance();
+  static GLMessage_FrameBuffer* default_instance_;
+};
+// -------------------------------------------------------------------
+
+class GLMessage : public ::google::protobuf::MessageLite {
+ public:
+  GLMessage();
+  virtual ~GLMessage();
+  
+  GLMessage(const GLMessage& from);
+  
+  inline GLMessage& operator=(const GLMessage& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  
+  static const GLMessage& default_instance();
+  
+  void Swap(GLMessage* other);
+  
+  // implements Message ----------------------------------------------
+  
+  GLMessage* New() const;
+  void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
+  void CopyFrom(const GLMessage& from);
+  void MergeFrom(const GLMessage& from);
+  void Clear();
+  bool IsInitialized() const;
+  
+  int ByteSize() const;
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input);
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const;
+  int GetCachedSize() const { return _cached_size_; }
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const;
+  public:
+  
+  ::std::string GetTypeName() const;
+  
+  // nested types ----------------------------------------------------
+  
+  typedef GLMessage_DataType DataType;
+  typedef GLMessage_FrameBuffer FrameBuffer;
+  
+  typedef GLMessage_Function Function;
+  static const Function glActiveTexture = GLMessage_Function_glActiveTexture;
+  static const Function glAlphaFunc = GLMessage_Function_glAlphaFunc;
+  static const Function glAlphaFuncx = GLMessage_Function_glAlphaFuncx;
+  static const Function glAlphaFuncxOES = GLMessage_Function_glAlphaFuncxOES;
+  static const Function glAttachShader = GLMessage_Function_glAttachShader;
+  static const Function glBeginPerfMonitorAMD = GLMessage_Function_glBeginPerfMonitorAMD;
+  static const Function glBindAttribLocation = GLMessage_Function_glBindAttribLocation;
+  static const Function glBindBuffer = GLMessage_Function_glBindBuffer;
+  static const Function glBindFramebuffer = GLMessage_Function_glBindFramebuffer;
+  static const Function glBindFramebufferOES = GLMessage_Function_glBindFramebufferOES;
+  static const Function glBindRenderbuffer = GLMessage_Function_glBindRenderbuffer;
+  static const Function glBindRenderbufferOES = GLMessage_Function_glBindRenderbufferOES;
+  static const Function glBindTexture = GLMessage_Function_glBindTexture;
+  static const Function glBindVertexArrayOES = GLMessage_Function_glBindVertexArrayOES;
+  static const Function glBlendColor = GLMessage_Function_glBlendColor;
+  static const Function glBlendEquation = GLMessage_Function_glBlendEquation;
+  static const Function glBlendEquationOES = GLMessage_Function_glBlendEquationOES;
+  static const Function glBlendEquationSeparate = GLMessage_Function_glBlendEquationSeparate;
+  static const Function glBlendEquationSeparateOES = GLMessage_Function_glBlendEquationSeparateOES;
+  static const Function glBlendFunc = GLMessage_Function_glBlendFunc;
+  static const Function glBlendFuncSeparate = GLMessage_Function_glBlendFuncSeparate;
+  static const Function glBlendFuncSeparateOES = GLMessage_Function_glBlendFuncSeparateOES;
+  static const Function glBufferData = GLMessage_Function_glBufferData;
+  static const Function glBufferSubData = GLMessage_Function_glBufferSubData;
+  static const Function glCheckFramebufferStatus = GLMessage_Function_glCheckFramebufferStatus;
+  static const Function glCheckFramebufferStatusOES = GLMessage_Function_glCheckFramebufferStatusOES;
+  static const Function glClearColor = GLMessage_Function_glClearColor;
+  static const Function glClearColorx = GLMessage_Function_glClearColorx;
+  static const Function glClearColorxOES = GLMessage_Function_glClearColorxOES;
+  static const Function glClearDepthf = GLMessage_Function_glClearDepthf;
+  static const Function glClearDepthfOES = GLMessage_Function_glClearDepthfOES;
+  static const Function glClearDepthx = GLMessage_Function_glClearDepthx;
+  static const Function glClearDepthxOES = GLMessage_Function_glClearDepthxOES;
+  static const Function glClear = GLMessage_Function_glClear;
+  static const Function glClearStencil = GLMessage_Function_glClearStencil;
+  static const Function glClientActiveTexture = GLMessage_Function_glClientActiveTexture;
+  static const Function glClipPlanef = GLMessage_Function_glClipPlanef;
+  static const Function glClipPlanefIMG = GLMessage_Function_glClipPlanefIMG;
+  static const Function glClipPlanefOES = GLMessage_Function_glClipPlanefOES;
+  static const Function glClipPlanex = GLMessage_Function_glClipPlanex;
+  static const Function glClipPlanexIMG = GLMessage_Function_glClipPlanexIMG;
+  static const Function glClipPlanexOES = GLMessage_Function_glClipPlanexOES;
+  static const Function glColor4f = GLMessage_Function_glColor4f;
+  static const Function glColor4ub = GLMessage_Function_glColor4ub;
+  static const Function glColor4x = GLMessage_Function_glColor4x;
+  static const Function glColor4xOES = GLMessage_Function_glColor4xOES;
+  static const Function glColorMask = GLMessage_Function_glColorMask;
+  static const Function glColorPointer = GLMessage_Function_glColorPointer;
+  static const Function glCompileShader = GLMessage_Function_glCompileShader;
+  static const Function glCompressedTexImage2D = GLMessage_Function_glCompressedTexImage2D;
+  static const Function glCompressedTexImage3DOES = GLMessage_Function_glCompressedTexImage3DOES;
+  static const Function glCompressedTexSubImage2D = GLMessage_Function_glCompressedTexSubImage2D;
+  static const Function glCompressedTexSubImage3DOES = GLMessage_Function_glCompressedTexSubImage3DOES;
+  static const Function glCopyTexImage2D = GLMessage_Function_glCopyTexImage2D;
+  static const Function glCopyTexSubImage2D = GLMessage_Function_glCopyTexSubImage2D;
+  static const Function glCopyTexSubImage3DOES = GLMessage_Function_glCopyTexSubImage3DOES;
+  static const Function glCoverageMaskNV = GLMessage_Function_glCoverageMaskNV;
+  static const Function glCoverageOperationNV = GLMessage_Function_glCoverageOperationNV;
+  static const Function glCreateProgram = GLMessage_Function_glCreateProgram;
+  static const Function glCreateShader = GLMessage_Function_glCreateShader;
+  static const Function glCullFace = GLMessage_Function_glCullFace;
+  static const Function glCurrentPaletteMatrixOES = GLMessage_Function_glCurrentPaletteMatrixOES;
+  static const Function glDeleteBuffers = GLMessage_Function_glDeleteBuffers;
+  static const Function glDeleteFencesNV = GLMessage_Function_glDeleteFencesNV;
+  static const Function glDeleteFramebuffers = GLMessage_Function_glDeleteFramebuffers;
+  static const Function glDeleteFramebuffersOES = GLMessage_Function_glDeleteFramebuffersOES;
+  static const Function glDeletePerfMonitorsAMD = GLMessage_Function_glDeletePerfMonitorsAMD;
+  static const Function glDeleteProgram = GLMessage_Function_glDeleteProgram;
+  static const Function glDeleteRenderbuffers = GLMessage_Function_glDeleteRenderbuffers;
+  static const Function glDeleteRenderbuffersOES = GLMessage_Function_glDeleteRenderbuffersOES;
+  static const Function glDeleteShader = GLMessage_Function_glDeleteShader;
+  static const Function glDeleteTextures = GLMessage_Function_glDeleteTextures;
+  static const Function glDeleteVertexArraysOES = GLMessage_Function_glDeleteVertexArraysOES;
+  static const Function glDepthFunc = GLMessage_Function_glDepthFunc;
+  static const Function glDepthMask = GLMessage_Function_glDepthMask;
+  static const Function glDepthRangef = GLMessage_Function_glDepthRangef;
+  static const Function glDepthRangefOES = GLMessage_Function_glDepthRangefOES;
+  static const Function glDepthRangex = GLMessage_Function_glDepthRangex;
+  static const Function glDepthRangexOES = GLMessage_Function_glDepthRangexOES;
+  static const Function glDetachShader = GLMessage_Function_glDetachShader;
+  static const Function glDisableClientState = GLMessage_Function_glDisableClientState;
+  static const Function glDisableDriverControlQCOM = GLMessage_Function_glDisableDriverControlQCOM;
+  static const Function glDisable = GLMessage_Function_glDisable;
+  static const Function glDisableVertexAttribArray = GLMessage_Function_glDisableVertexAttribArray;
+  static const Function glDiscardFramebufferEXT = GLMessage_Function_glDiscardFramebufferEXT;
+  static const Function glDrawArrays = GLMessage_Function_glDrawArrays;
+  static const Function glDrawElements = GLMessage_Function_glDrawElements;
+  static const Function glDrawTexfOES = GLMessage_Function_glDrawTexfOES;
+  static const Function glDrawTexfvOES = GLMessage_Function_glDrawTexfvOES;
+  static const Function glDrawTexiOES = GLMessage_Function_glDrawTexiOES;
+  static const Function glDrawTexivOES = GLMessage_Function_glDrawTexivOES;
+  static const Function glDrawTexsOES = GLMessage_Function_glDrawTexsOES;
+  static const Function glDrawTexsvOES = GLMessage_Function_glDrawTexsvOES;
+  static const Function glDrawTexxOES = GLMessage_Function_glDrawTexxOES;
+  static const Function glDrawTexxvOES = GLMessage_Function_glDrawTexxvOES;
+  static const Function glEGLImageTargetRenderbufferStorageOES = GLMessage_Function_glEGLImageTargetRenderbufferStorageOES;
+  static const Function glEGLImageTargetTexture2DOES = GLMessage_Function_glEGLImageTargetTexture2DOES;
+  static const Function glEnableClientState = GLMessage_Function_glEnableClientState;
+  static const Function glEnableDriverControlQCOM = GLMessage_Function_glEnableDriverControlQCOM;
+  static const Function glEnable = GLMessage_Function_glEnable;
+  static const Function glEnableVertexAttribArray = GLMessage_Function_glEnableVertexAttribArray;
+  static const Function glEndPerfMonitorAMD = GLMessage_Function_glEndPerfMonitorAMD;
+  static const Function glEndTilingQCOM = GLMessage_Function_glEndTilingQCOM;
+  static const Function glExtGetBufferPointervQCOM = GLMessage_Function_glExtGetBufferPointervQCOM;
+  static const Function glExtGetBuffersQCOM = GLMessage_Function_glExtGetBuffersQCOM;
+  static const Function glExtGetFramebuffersQCOM = GLMessage_Function_glExtGetFramebuffersQCOM;
+  static const Function glExtGetProgramBinarySourceQCOM = GLMessage_Function_glExtGetProgramBinarySourceQCOM;
+  static const Function glExtGetProgramsQCOM = GLMessage_Function_glExtGetProgramsQCOM;
+  static const Function glExtGetRenderbuffersQCOM = GLMessage_Function_glExtGetRenderbuffersQCOM;
+  static const Function glExtGetShadersQCOM = GLMessage_Function_glExtGetShadersQCOM;
+  static const Function glExtGetTexLevelParameterivQCOM = GLMessage_Function_glExtGetTexLevelParameterivQCOM;
+  static const Function glExtGetTexSubImageQCOM = GLMessage_Function_glExtGetTexSubImageQCOM;
+  static const Function glExtGetTexturesQCOM = GLMessage_Function_glExtGetTexturesQCOM;
+  static const Function glExtIsProgramBinaryQCOM = GLMessage_Function_glExtIsProgramBinaryQCOM;
+  static const Function glExtTexObjectStateOverrideiQCOM = GLMessage_Function_glExtTexObjectStateOverrideiQCOM;
+  static const Function glFinishFenceNV = GLMessage_Function_glFinishFenceNV;
+  static const Function glFinish = GLMessage_Function_glFinish;
+  static const Function glFlush = GLMessage_Function_glFlush;
+  static const Function glFogf = GLMessage_Function_glFogf;
+  static const Function glFogfv = GLMessage_Function_glFogfv;
+  static const Function glFogx = GLMessage_Function_glFogx;
+  static const Function glFogxOES = GLMessage_Function_glFogxOES;
+  static const Function glFogxv = GLMessage_Function_glFogxv;
+  static const Function glFogxvOES = GLMessage_Function_glFogxvOES;
+  static const Function glFramebufferRenderbuffer = GLMessage_Function_glFramebufferRenderbuffer;
+  static const Function glFramebufferRenderbufferOES = GLMessage_Function_glFramebufferRenderbufferOES;
+  static const Function glFramebufferTexture2D = GLMessage_Function_glFramebufferTexture2D;
+  static const Function glFramebufferTexture2DMultisampleIMG = GLMessage_Function_glFramebufferTexture2DMultisampleIMG;
+  static const Function glFramebufferTexture2DOES = GLMessage_Function_glFramebufferTexture2DOES;
+  static const Function glFramebufferTexture3DOES = GLMessage_Function_glFramebufferTexture3DOES;
+  static const Function glFrontFace = GLMessage_Function_glFrontFace;
+  static const Function glFrustumf = GLMessage_Function_glFrustumf;
+  static const Function glFrustumfOES = GLMessage_Function_glFrustumfOES;
+  static const Function glFrustumx = GLMessage_Function_glFrustumx;
+  static const Function glFrustumxOES = GLMessage_Function_glFrustumxOES;
+  static const Function glGenBuffers = GLMessage_Function_glGenBuffers;
+  static const Function glGenerateMipmap = GLMessage_Function_glGenerateMipmap;
+  static const Function glGenerateMipmapOES = GLMessage_Function_glGenerateMipmapOES;
+  static const Function glGenFencesNV = GLMessage_Function_glGenFencesNV;
+  static const Function glGenFramebuffers = GLMessage_Function_glGenFramebuffers;
+  static const Function glGenFramebuffersOES = GLMessage_Function_glGenFramebuffersOES;
+  static const Function glGenPerfMonitorsAMD = GLMessage_Function_glGenPerfMonitorsAMD;
+  static const Function glGenRenderbuffers = GLMessage_Function_glGenRenderbuffers;
+  static const Function glGenRenderbuffersOES = GLMessage_Function_glGenRenderbuffersOES;
+  static const Function glGenTextures = GLMessage_Function_glGenTextures;
+  static const Function glGenVertexArraysOES = GLMessage_Function_glGenVertexArraysOES;
+  static const Function glGetActiveAttrib = GLMessage_Function_glGetActiveAttrib;
+  static const Function glGetActiveUniform = GLMessage_Function_glGetActiveUniform;
+  static const Function glGetAttachedShaders = GLMessage_Function_glGetAttachedShaders;
+  static const Function glGetAttribLocation = GLMessage_Function_glGetAttribLocation;
+  static const Function glGetBooleanv = GLMessage_Function_glGetBooleanv;
+  static const Function glGetBufferParameteriv = GLMessage_Function_glGetBufferParameteriv;
+  static const Function glGetBufferPointervOES = GLMessage_Function_glGetBufferPointervOES;
+  static const Function glGetClipPlanef = GLMessage_Function_glGetClipPlanef;
+  static const Function glGetClipPlanefOES = GLMessage_Function_glGetClipPlanefOES;
+  static const Function glGetClipPlanex = GLMessage_Function_glGetClipPlanex;
+  static const Function glGetClipPlanexOES = GLMessage_Function_glGetClipPlanexOES;
+  static const Function glGetDriverControlsQCOM = GLMessage_Function_glGetDriverControlsQCOM;
+  static const Function glGetDriverControlStringQCOM = GLMessage_Function_glGetDriverControlStringQCOM;
+  static const Function glGetError = GLMessage_Function_glGetError;
+  static const Function glGetFenceivNV = GLMessage_Function_glGetFenceivNV;
+  static const Function glGetFixedv = GLMessage_Function_glGetFixedv;
+  static const Function glGetFixedvOES = GLMessage_Function_glGetFixedvOES;
+  static const Function glGetFloatv = GLMessage_Function_glGetFloatv;
+  static const Function glGetFramebufferAttachmentParameteriv = GLMessage_Function_glGetFramebufferAttachmentParameteriv;
+  static const Function glGetFramebufferAttachmentParameterivOES = GLMessage_Function_glGetFramebufferAttachmentParameterivOES;
+  static const Function glGetIntegerv = GLMessage_Function_glGetIntegerv;
+  static const Function glGetLightfv = GLMessage_Function_glGetLightfv;
+  static const Function glGetLightxv = GLMessage_Function_glGetLightxv;
+  static const Function glGetLightxvOES = GLMessage_Function_glGetLightxvOES;
+  static const Function glGetMaterialfv = GLMessage_Function_glGetMaterialfv;
+  static const Function glGetMaterialxv = GLMessage_Function_glGetMaterialxv;
+  static const Function glGetMaterialxvOES = GLMessage_Function_glGetMaterialxvOES;
+  static const Function glGetPerfMonitorCounterDataAMD = GLMessage_Function_glGetPerfMonitorCounterDataAMD;
+  static const Function glGetPerfMonitorCounterInfoAMD = GLMessage_Function_glGetPerfMonitorCounterInfoAMD;
+  static const Function glGetPerfMonitorCountersAMD = GLMessage_Function_glGetPerfMonitorCountersAMD;
+  static const Function glGetPerfMonitorCounterStringAMD = GLMessage_Function_glGetPerfMonitorCounterStringAMD;
+  static const Function glGetPerfMonitorGroupsAMD = GLMessage_Function_glGetPerfMonitorGroupsAMD;
+  static const Function glGetPerfMonitorGroupStringAMD = GLMessage_Function_glGetPerfMonitorGroupStringAMD;
+  static const Function glGetPointerv = GLMessage_Function_glGetPointerv;
+  static const Function glGetProgramBinaryOES = GLMessage_Function_glGetProgramBinaryOES;
+  static const Function glGetProgramInfoLog = GLMessage_Function_glGetProgramInfoLog;
+  static const Function glGetProgramiv = GLMessage_Function_glGetProgramiv;
+  static const Function glGetRenderbufferParameteriv = GLMessage_Function_glGetRenderbufferParameteriv;
+  static const Function glGetRenderbufferParameterivOES = GLMessage_Function_glGetRenderbufferParameterivOES;
+  static const Function glGetShaderInfoLog = GLMessage_Function_glGetShaderInfoLog;
+  static const Function glGetShaderiv = GLMessage_Function_glGetShaderiv;
+  static const Function glGetShaderPrecisionFormat = GLMessage_Function_glGetShaderPrecisionFormat;
+  static const Function glGetShaderSource = GLMessage_Function_glGetShaderSource;
+  static const Function glGetString = GLMessage_Function_glGetString;
+  static const Function glGetTexEnvfv = GLMessage_Function_glGetTexEnvfv;
+  static const Function glGetTexEnviv = GLMessage_Function_glGetTexEnviv;
+  static const Function glGetTexEnvxv = GLMessage_Function_glGetTexEnvxv;
+  static const Function glGetTexEnvxvOES = GLMessage_Function_glGetTexEnvxvOES;
+  static const Function glGetTexGenfvOES = GLMessage_Function_glGetTexGenfvOES;
+  static const Function glGetTexGenivOES = GLMessage_Function_glGetTexGenivOES;
+  static const Function glGetTexGenxvOES = GLMessage_Function_glGetTexGenxvOES;
+  static const Function glGetTexParameterfv = GLMessage_Function_glGetTexParameterfv;
+  static const Function glGetTexParameteriv = GLMessage_Function_glGetTexParameteriv;
+  static const Function glGetTexParameterxv = GLMessage_Function_glGetTexParameterxv;
+  static const Function glGetTexParameterxvOES = GLMessage_Function_glGetTexParameterxvOES;
+  static const Function glGetUniformfv = GLMessage_Function_glGetUniformfv;
+  static const Function glGetUniformiv = GLMessage_Function_glGetUniformiv;
+  static const Function glGetUniformLocation = GLMessage_Function_glGetUniformLocation;
+  static const Function glGetVertexAttribfv = GLMessage_Function_glGetVertexAttribfv;
+  static const Function glGetVertexAttribiv = GLMessage_Function_glGetVertexAttribiv;
+  static const Function glGetVertexAttribPointerv = GLMessage_Function_glGetVertexAttribPointerv;
+  static const Function glHint = GLMessage_Function_glHint;
+  static const Function glIsBuffer = GLMessage_Function_glIsBuffer;
+  static const Function glIsEnabled = GLMessage_Function_glIsEnabled;
+  static const Function glIsFenceNV = GLMessage_Function_glIsFenceNV;
+  static const Function glIsFramebuffer = GLMessage_Function_glIsFramebuffer;
+  static const Function glIsFramebufferOES = GLMessage_Function_glIsFramebufferOES;
+  static const Function glIsProgram = GLMessage_Function_glIsProgram;
+  static const Function glIsRenderbuffer = GLMessage_Function_glIsRenderbuffer;
+  static const Function glIsRenderbufferOES = GLMessage_Function_glIsRenderbufferOES;
+  static const Function glIsShader = GLMessage_Function_glIsShader;
+  static const Function glIsTexture = GLMessage_Function_glIsTexture;
+  static const Function glIsVertexArrayOES = GLMessage_Function_glIsVertexArrayOES;
+  static const Function glLightf = GLMessage_Function_glLightf;
+  static const Function glLightfv = GLMessage_Function_glLightfv;
+  static const Function glLightModelf = GLMessage_Function_glLightModelf;
+  static const Function glLightModelfv = GLMessage_Function_glLightModelfv;
+  static const Function glLightModelx = GLMessage_Function_glLightModelx;
+  static const Function glLightModelxOES = GLMessage_Function_glLightModelxOES;
+  static const Function glLightModelxv = GLMessage_Function_glLightModelxv;
+  static const Function glLightModelxvOES = GLMessage_Function_glLightModelxvOES;
+  static const Function glLightx = GLMessage_Function_glLightx;
+  static const Function glLightxOES = GLMessage_Function_glLightxOES;
+  static const Function glLightxv = GLMessage_Function_glLightxv;
+  static const Function glLightxvOES = GLMessage_Function_glLightxvOES;
+  static const Function glLineWidth = GLMessage_Function_glLineWidth;
+  static const Function glLineWidthx = GLMessage_Function_glLineWidthx;
+  static const Function glLineWidthxOES = GLMessage_Function_glLineWidthxOES;
+  static const Function glLinkProgram = GLMessage_Function_glLinkProgram;
+  static const Function glLoadIdentity = GLMessage_Function_glLoadIdentity;
+  static const Function glLoadMatrixf = GLMessage_Function_glLoadMatrixf;
+  static const Function glLoadMatrixx = GLMessage_Function_glLoadMatrixx;
+  static const Function glLoadMatrixxOES = GLMessage_Function_glLoadMatrixxOES;
+  static const Function glLoadPaletteFromModelViewMatrixOES = GLMessage_Function_glLoadPaletteFromModelViewMatrixOES;
+  static const Function glLogicOp = GLMessage_Function_glLogicOp;
+  static const Function glMapBufferOES = GLMessage_Function_glMapBufferOES;
+  static const Function glMaterialf = GLMessage_Function_glMaterialf;
+  static const Function glMaterialfv = GLMessage_Function_glMaterialfv;
+  static const Function glMaterialx = GLMessage_Function_glMaterialx;
+  static const Function glMaterialxOES = GLMessage_Function_glMaterialxOES;
+  static const Function glMaterialxv = GLMessage_Function_glMaterialxv;
+  static const Function glMaterialxvOES = GLMessage_Function_glMaterialxvOES;
+  static const Function glMatrixIndexPointerOES = GLMessage_Function_glMatrixIndexPointerOES;
+  static const Function glMatrixMode = GLMessage_Function_glMatrixMode;
+  static const Function glMultiDrawArraysEXT = GLMessage_Function_glMultiDrawArraysEXT;
+  static const Function glMultiDrawElementsEXT = GLMessage_Function_glMultiDrawElementsEXT;
+  static const Function glMultiTexCoord4f = GLMessage_Function_glMultiTexCoord4f;
+  static const Function glMultiTexCoord4x = GLMessage_Function_glMultiTexCoord4x;
+  static const Function glMultiTexCoord4xOES = GLMessage_Function_glMultiTexCoord4xOES;
+  static const Function glMultMatrixf = GLMessage_Function_glMultMatrixf;
+  static const Function glMultMatrixx = GLMessage_Function_glMultMatrixx;
+  static const Function glMultMatrixxOES = GLMessage_Function_glMultMatrixxOES;
+  static const Function glNormal3f = GLMessage_Function_glNormal3f;
+  static const Function glNormal3x = GLMessage_Function_glNormal3x;
+  static const Function glNormal3xOES = GLMessage_Function_glNormal3xOES;
+  static const Function glNormalPointer = GLMessage_Function_glNormalPointer;
+  static const Function glOrthof = GLMessage_Function_glOrthof;
+  static const Function glOrthofOES = GLMessage_Function_glOrthofOES;
+  static const Function glOrthox = GLMessage_Function_glOrthox;
+  static const Function glOrthoxOES = GLMessage_Function_glOrthoxOES;
+  static const Function glPixelStorei = GLMessage_Function_glPixelStorei;
+  static const Function glPointParameterf = GLMessage_Function_glPointParameterf;
+  static const Function glPointParameterfv = GLMessage_Function_glPointParameterfv;
+  static const Function glPointParameterx = GLMessage_Function_glPointParameterx;
+  static const Function glPointParameterxOES = GLMessage_Function_glPointParameterxOES;
+  static const Function glPointParameterxv = GLMessage_Function_glPointParameterxv;
+  static const Function glPointParameterxvOES = GLMessage_Function_glPointParameterxvOES;
+  static const Function glPointSize = GLMessage_Function_glPointSize;
+  static const Function glPointSizePointerOES = GLMessage_Function_glPointSizePointerOES;
+  static const Function glPointSizex = GLMessage_Function_glPointSizex;
+  static const Function glPointSizexOES = GLMessage_Function_glPointSizexOES;
+  static const Function glPolygonOffset = GLMessage_Function_glPolygonOffset;
+  static const Function glPolygonOffsetx = GLMessage_Function_glPolygonOffsetx;
+  static const Function glPolygonOffsetxOES = GLMessage_Function_glPolygonOffsetxOES;
+  static const Function glPopMatrix = GLMessage_Function_glPopMatrix;
+  static const Function glProgramBinaryOES = GLMessage_Function_glProgramBinaryOES;
+  static const Function glPushMatrix = GLMessage_Function_glPushMatrix;
+  static const Function glQueryMatrixxOES = GLMessage_Function_glQueryMatrixxOES;
+  static const Function glReadPixels = GLMessage_Function_glReadPixels;
+  static const Function glReleaseShaderCompiler = GLMessage_Function_glReleaseShaderCompiler;
+  static const Function glRenderbufferStorage = GLMessage_Function_glRenderbufferStorage;
+  static const Function glRenderbufferStorageMultisampleIMG = GLMessage_Function_glRenderbufferStorageMultisampleIMG;
+  static const Function glRenderbufferStorageOES = GLMessage_Function_glRenderbufferStorageOES;
+  static const Function glRotatef = GLMessage_Function_glRotatef;
+  static const Function glRotatex = GLMessage_Function_glRotatex;
+  static const Function glRotatexOES = GLMessage_Function_glRotatexOES;
+  static const Function glSampleCoverage = GLMessage_Function_glSampleCoverage;
+  static const Function glSampleCoveragex = GLMessage_Function_glSampleCoveragex;
+  static const Function glSampleCoveragexOES = GLMessage_Function_glSampleCoveragexOES;
+  static const Function glScalef = GLMessage_Function_glScalef;
+  static const Function glScalex = GLMessage_Function_glScalex;
+  static const Function glScalexOES = GLMessage_Function_glScalexOES;
+  static const Function glScissor = GLMessage_Function_glScissor;
+  static const Function glSelectPerfMonitorCountersAMD = GLMessage_Function_glSelectPerfMonitorCountersAMD;
+  static const Function glSetFenceNV = GLMessage_Function_glSetFenceNV;
+  static const Function glShadeModel = GLMessage_Function_glShadeModel;
+  static const Function glShaderBinary = GLMessage_Function_glShaderBinary;
+  static const Function glShaderSource = GLMessage_Function_glShaderSource;
+  static const Function glStartTilingQCOM = GLMessage_Function_glStartTilingQCOM;
+  static const Function glStencilFunc = GLMessage_Function_glStencilFunc;
+  static const Function glStencilFuncSeparate = GLMessage_Function_glStencilFuncSeparate;
+  static const Function glStencilMask = GLMessage_Function_glStencilMask;
+  static const Function glStencilMaskSeparate = GLMessage_Function_glStencilMaskSeparate;
+  static const Function glStencilOp = GLMessage_Function_glStencilOp;
+  static const Function glStencilOpSeparate = GLMessage_Function_glStencilOpSeparate;
+  static const Function glTestFenceNV = GLMessage_Function_glTestFenceNV;
+  static const Function glTexCoordPointer = GLMessage_Function_glTexCoordPointer;
+  static const Function glTexEnvf = GLMessage_Function_glTexEnvf;
+  static const Function glTexEnvfv = GLMessage_Function_glTexEnvfv;
+  static const Function glTexEnvi = GLMessage_Function_glTexEnvi;
+  static const Function glTexEnviv = GLMessage_Function_glTexEnviv;
+  static const Function glTexEnvx = GLMessage_Function_glTexEnvx;
+  static const Function glTexEnvxOES = GLMessage_Function_glTexEnvxOES;
+  static const Function glTexEnvxv = GLMessage_Function_glTexEnvxv;
+  static const Function glTexEnvxvOES = GLMessage_Function_glTexEnvxvOES;
+  static const Function glTexGenfOES = GLMessage_Function_glTexGenfOES;
+  static const Function glTexGenfvOES = GLMessage_Function_glTexGenfvOES;
+  static const Function glTexGeniOES = GLMessage_Function_glTexGeniOES;
+  static const Function glTexGenivOES = GLMessage_Function_glTexGenivOES;
+  static const Function glTexGenxOES = GLMessage_Function_glTexGenxOES;
+  static const Function glTexGenxvOES = GLMessage_Function_glTexGenxvOES;
+  static const Function glTexImage2D = GLMessage_Function_glTexImage2D;
+  static const Function glTexImage3DOES = GLMessage_Function_glTexImage3DOES;
+  static const Function glTexParameterf = GLMessage_Function_glTexParameterf;
+  static const Function glTexParameterfv = GLMessage_Function_glTexParameterfv;
+  static const Function glTexParameteri = GLMessage_Function_glTexParameteri;
+  static const Function glTexParameteriv = GLMessage_Function_glTexParameteriv;
+  static const Function glTexParameterx = GLMessage_Function_glTexParameterx;
+  static const Function glTexParameterxOES = GLMessage_Function_glTexParameterxOES;
+  static const Function glTexParameterxv = GLMessage_Function_glTexParameterxv;
+  static const Function glTexParameterxvOES = GLMessage_Function_glTexParameterxvOES;
+  static const Function glTexSubImage2D = GLMessage_Function_glTexSubImage2D;
+  static const Function glTexSubImage3DOES = GLMessage_Function_glTexSubImage3DOES;
+  static const Function glTranslatef = GLMessage_Function_glTranslatef;
+  static const Function glTranslatex = GLMessage_Function_glTranslatex;
+  static const Function glTranslatexOES = GLMessage_Function_glTranslatexOES;
+  static const Function glUniform1f = GLMessage_Function_glUniform1f;
+  static const Function glUniform1fv = GLMessage_Function_glUniform1fv;
+  static const Function glUniform1i = GLMessage_Function_glUniform1i;
+  static const Function glUniform1iv = GLMessage_Function_glUniform1iv;
+  static const Function glUniform2f = GLMessage_Function_glUniform2f;
+  static const Function glUniform2fv = GLMessage_Function_glUniform2fv;
+  static const Function glUniform2i = GLMessage_Function_glUniform2i;
+  static const Function glUniform2iv = GLMessage_Function_glUniform2iv;
+  static const Function glUniform3f = GLMessage_Function_glUniform3f;
+  static const Function glUniform3fv = GLMessage_Function_glUniform3fv;
+  static const Function glUniform3i = GLMessage_Function_glUniform3i;
+  static const Function glUniform3iv = GLMessage_Function_glUniform3iv;
+  static const Function glUniform4f = GLMessage_Function_glUniform4f;
+  static const Function glUniform4fv = GLMessage_Function_glUniform4fv;
+  static const Function glUniform4i = GLMessage_Function_glUniform4i;
+  static const Function glUniform4iv = GLMessage_Function_glUniform4iv;
+  static const Function glUniformMatrix2fv = GLMessage_Function_glUniformMatrix2fv;
+  static const Function glUniformMatrix3fv = GLMessage_Function_glUniformMatrix3fv;
+  static const Function glUniformMatrix4fv = GLMessage_Function_glUniformMatrix4fv;
+  static const Function glUnmapBufferOES = GLMessage_Function_glUnmapBufferOES;
+  static const Function glUseProgram = GLMessage_Function_glUseProgram;
+  static const Function glValidateProgram = GLMessage_Function_glValidateProgram;
+  static const Function glVertexAttrib1f = GLMessage_Function_glVertexAttrib1f;
+  static const Function glVertexAttrib1fv = GLMessage_Function_glVertexAttrib1fv;
+  static const Function glVertexAttrib2f = GLMessage_Function_glVertexAttrib2f;
+  static const Function glVertexAttrib2fv = GLMessage_Function_glVertexAttrib2fv;
+  static const Function glVertexAttrib3f = GLMessage_Function_glVertexAttrib3f;
+  static const Function glVertexAttrib3fv = GLMessage_Function_glVertexAttrib3fv;
+  static const Function glVertexAttrib4f = GLMessage_Function_glVertexAttrib4f;
+  static const Function glVertexAttrib4fv = GLMessage_Function_glVertexAttrib4fv;
+  static const Function glVertexAttribPointer = GLMessage_Function_glVertexAttribPointer;
+  static const Function glVertexPointer = GLMessage_Function_glVertexPointer;
+  static const Function glViewport = GLMessage_Function_glViewport;
+  static const Function glWeightPointerOES = GLMessage_Function_glWeightPointerOES;
+  static const Function eglGetDisplay = GLMessage_Function_eglGetDisplay;
+  static const Function eglInitialize = GLMessage_Function_eglInitialize;
+  static const Function eglTerminate = GLMessage_Function_eglTerminate;
+  static const Function eglGetConfigs = GLMessage_Function_eglGetConfigs;
+  static const Function eglChooseConfig = GLMessage_Function_eglChooseConfig;
+  static const Function eglGetConfigAttrib = GLMessage_Function_eglGetConfigAttrib;
+  static const Function eglCreateWindowSurface = GLMessage_Function_eglCreateWindowSurface;
+  static const Function eglCreatePixmapSurface = GLMessage_Function_eglCreatePixmapSurface;
+  static const Function eglCreatePbufferSurface = GLMessage_Function_eglCreatePbufferSurface;
+  static const Function eglDestroySurface = GLMessage_Function_eglDestroySurface;
+  static const Function eglQuerySurface = GLMessage_Function_eglQuerySurface;
+  static const Function eglCreateContext = GLMessage_Function_eglCreateContext;
+  static const Function eglDestroyContext = GLMessage_Function_eglDestroyContext;
+  static const Function eglMakeCurrent = GLMessage_Function_eglMakeCurrent;
+  static const Function eglGetCurrentContext = GLMessage_Function_eglGetCurrentContext;
+  static const Function eglGetCurrentSurface = GLMessage_Function_eglGetCurrentSurface;
+  static const Function eglGetCurrentDisplay = GLMessage_Function_eglGetCurrentDisplay;
+  static const Function eglQueryContext = GLMessage_Function_eglQueryContext;
+  static const Function eglWaitGL = GLMessage_Function_eglWaitGL;
+  static const Function eglWaitNative = GLMessage_Function_eglWaitNative;
+  static const Function eglSwapBuffers = GLMessage_Function_eglSwapBuffers;
+  static const Function eglCopyBuffers = GLMessage_Function_eglCopyBuffers;
+  static const Function eglGetError = GLMessage_Function_eglGetError;
+  static const Function eglQueryString = GLMessage_Function_eglQueryString;
+  static const Function eglGetProcAddress = GLMessage_Function_eglGetProcAddress;
+  static const Function eglSurfaceAttrib = GLMessage_Function_eglSurfaceAttrib;
+  static const Function eglBindTexImage = GLMessage_Function_eglBindTexImage;
+  static const Function eglReleaseTexImage = GLMessage_Function_eglReleaseTexImage;
+  static const Function eglSwapInterval = GLMessage_Function_eglSwapInterval;
+  static const Function eglBindAPI = GLMessage_Function_eglBindAPI;
+  static const Function eglQueryAPI = GLMessage_Function_eglQueryAPI;
+  static const Function eglWaitClient = GLMessage_Function_eglWaitClient;
+  static const Function eglReleaseThread = GLMessage_Function_eglReleaseThread;
+  static const Function eglCreatePbufferFromClientBuffer = GLMessage_Function_eglCreatePbufferFromClientBuffer;
+  static const Function eglLockSurfaceKHR = GLMessage_Function_eglLockSurfaceKHR;
+  static const Function eglUnlockSurfaceKHR = GLMessage_Function_eglUnlockSurfaceKHR;
+  static const Function eglCreateImageKHR = GLMessage_Function_eglCreateImageKHR;
+  static const Function eglDestroyImageKHR = GLMessage_Function_eglDestroyImageKHR;
+  static const Function eglCreateSyncKHR = GLMessage_Function_eglCreateSyncKHR;
+  static const Function eglDestroySyncKHR = GLMessage_Function_eglDestroySyncKHR;
+  static const Function eglClientWaitSyncKHR = GLMessage_Function_eglClientWaitSyncKHR;
+  static const Function eglGetSyncAttribKHR = GLMessage_Function_eglGetSyncAttribKHR;
+  static const Function eglSetSwapRectangleANDROID = GLMessage_Function_eglSetSwapRectangleANDROID;
+  static const Function eglGetRenderBufferANDROID = GLMessage_Function_eglGetRenderBufferANDROID;
+  static const Function eglGetSystemTimeFrequencyNV = GLMessage_Function_eglGetSystemTimeFrequencyNV;
+  static const Function eglGetSystemTimeNV = GLMessage_Function_eglGetSystemTimeNV;
+  static const Function invalid = GLMessage_Function_invalid;
+  static const Function frameBufferContents = GLMessage_Function_frameBufferContents;
+  static inline bool Function_IsValid(int value) {
+    return GLMessage_Function_IsValid(value);
+  }
+  static const Function Function_MIN =
+    GLMessage_Function_Function_MIN;
+  static const Function Function_MAX =
+    GLMessage_Function_Function_MAX;
+  static const int Function_ARRAYSIZE =
+    GLMessage_Function_Function_ARRAYSIZE;
+  
+  // accessors -------------------------------------------------------
+  
+  // required int32 context_id = 1;
+  inline bool has_context_id() const;
+  inline void clear_context_id();
+  static const int kContextIdFieldNumber = 1;
+  inline ::google::protobuf::int32 context_id() const;
+  inline void set_context_id(::google::protobuf::int32 value);
+  
+  // required .android.gltrace.GLMessage.Function function = 2 [default = invalid];
+  inline bool has_function() const;
+  inline void clear_function();
+  static const int kFunctionFieldNumber = 2;
+  inline ::android::gltrace::GLMessage_Function function() const;
+  inline void set_function(::android::gltrace::GLMessage_Function value);
+  
+  // repeated .android.gltrace.GLMessage.DataType args = 3;
+  inline int args_size() const;
+  inline void clear_args();
+  static const int kArgsFieldNumber = 3;
+  inline const ::android::gltrace::GLMessage_DataType& args(int index) const;
+  inline ::android::gltrace::GLMessage_DataType* mutable_args(int index);
+  inline ::android::gltrace::GLMessage_DataType* add_args();
+  inline const ::google::protobuf::RepeatedPtrField< ::android::gltrace::GLMessage_DataType >&
+      args() const;
+  inline ::google::protobuf::RepeatedPtrField< ::android::gltrace::GLMessage_DataType >*
+      mutable_args();
+  
+  // optional .android.gltrace.GLMessage.DataType returnValue = 4;
+  inline bool has_returnvalue() const;
+  inline void clear_returnvalue();
+  static const int kReturnValueFieldNumber = 4;
+  inline const ::android::gltrace::GLMessage_DataType& returnvalue() const;
+  inline ::android::gltrace::GLMessage_DataType* mutable_returnvalue();
+  
+  // optional float duration = 5;
+  inline bool has_duration() const;
+  inline void clear_duration();
+  static const int kDurationFieldNumber = 5;
+  inline float duration() const;
+  inline void set_duration(float value);
+  
+  // optional .android.gltrace.GLMessage.FrameBuffer fb = 6;
+  inline bool has_fb() const;
+  inline void clear_fb();
+  static const int kFbFieldNumber = 6;
+  inline const ::android::gltrace::GLMessage_FrameBuffer& fb() const;
+  inline ::android::gltrace::GLMessage_FrameBuffer* mutable_fb();
+  
+  // @@protoc_insertion_point(class_scope:android.gltrace.GLMessage)
+ private:
+  mutable int _cached_size_;
+  
+  ::google::protobuf::int32 context_id_;
+  int function_;
+  ::google::protobuf::RepeatedPtrField< ::android::gltrace::GLMessage_DataType > args_;
+  ::android::gltrace::GLMessage_DataType* returnvalue_;
+  float duration_;
+  ::android::gltrace::GLMessage_FrameBuffer* fb_;
+  friend void  protobuf_AddDesc_gltrace_2eproto();
+  friend void protobuf_AssignDesc_gltrace_2eproto();
+  friend void protobuf_ShutdownFile_gltrace_2eproto();
+  
+  ::google::protobuf::uint32 _has_bits_[(6 + 31) / 32];
+  
+  // WHY DOES & HAVE LOWER PRECEDENCE THAN != !?
+  inline bool _has_bit(int index) const {
+    return (_has_bits_[index / 32] & (1u << (index % 32))) != 0;
+  }
+  inline void _set_bit(int index) {
+    _has_bits_[index / 32] |= (1u << (index % 32));
+  }
+  inline void _clear_bit(int index) {
+    _has_bits_[index / 32] &= ~(1u << (index % 32));
+  }
+  
+  void InitAsDefaultInstance();
+  static GLMessage* default_instance_;
+};
+// ===================================================================
+
+
+// ===================================================================
+
+// GLMessage_DataType
+
+// required .android.gltrace.GLMessage.DataType.Type type = 1 [default = VOID];
+inline bool GLMessage_DataType::has_type() const {
+  return _has_bit(0);
+}
+inline void GLMessage_DataType::clear_type() {
+  type_ = 1;
+  _clear_bit(0);
+}
+inline ::android::gltrace::GLMessage_DataType_Type GLMessage_DataType::type() const {
+  return static_cast< ::android::gltrace::GLMessage_DataType_Type >(type_);
+}
+inline void GLMessage_DataType::set_type(::android::gltrace::GLMessage_DataType_Type value) {
+  GOOGLE_DCHECK(::android::gltrace::GLMessage_DataType_Type_IsValid(value));
+  _set_bit(0);
+  type_ = value;
+}
+
+// required bool isArray = 2 [default = false];
+inline bool GLMessage_DataType::has_isarray() const {
+  return _has_bit(1);
+}
+inline void GLMessage_DataType::clear_isarray() {
+  isarray_ = false;
+  _clear_bit(1);
+}
+inline bool GLMessage_DataType::isarray() const {
+  return isarray_;
+}
+inline void GLMessage_DataType::set_isarray(bool value) {
+  _set_bit(1);
+  isarray_ = value;
+}
+
+// repeated int32 intValue = 3;
+inline int GLMessage_DataType::intvalue_size() const {
+  return intvalue_.size();
+}
+inline void GLMessage_DataType::clear_intvalue() {
+  intvalue_.Clear();
+}
+inline ::google::protobuf::int32 GLMessage_DataType::intvalue(int index) const {
+  return intvalue_.Get(index);
+}
+inline void GLMessage_DataType::set_intvalue(int index, ::google::protobuf::int32 value) {
+  intvalue_.Set(index, value);
+}
+inline void GLMessage_DataType::add_intvalue(::google::protobuf::int32 value) {
+  intvalue_.Add(value);
+}
+inline const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >&
+GLMessage_DataType::intvalue() const {
+  return intvalue_;
+}
+inline ::google::protobuf::RepeatedField< ::google::protobuf::int32 >*
+GLMessage_DataType::mutable_intvalue() {
+  return &intvalue_;
+}
+
+// repeated float floatValue = 4;
+inline int GLMessage_DataType::floatvalue_size() const {
+  return floatvalue_.size();
+}
+inline void GLMessage_DataType::clear_floatvalue() {
+  floatvalue_.Clear();
+}
+inline float GLMessage_DataType::floatvalue(int index) const {
+  return floatvalue_.Get(index);
+}
+inline void GLMessage_DataType::set_floatvalue(int index, float value) {
+  floatvalue_.Set(index, value);
+}
+inline void GLMessage_DataType::add_floatvalue(float value) {
+  floatvalue_.Add(value);
+}
+inline const ::google::protobuf::RepeatedField< float >&
+GLMessage_DataType::floatvalue() const {
+  return floatvalue_;
+}
+inline ::google::protobuf::RepeatedField< float >*
+GLMessage_DataType::mutable_floatvalue() {
+  return &floatvalue_;
+}
+
+// repeated bytes charValue = 5;
+inline int GLMessage_DataType::charvalue_size() const {
+  return charvalue_.size();
+}
+inline void GLMessage_DataType::clear_charvalue() {
+  charvalue_.Clear();
+}
+inline const ::std::string& GLMessage_DataType::charvalue(int index) const {
+  return charvalue_.Get(index);
+}
+inline ::std::string* GLMessage_DataType::mutable_charvalue(int index) {
+  return charvalue_.Mutable(index);
+}
+inline void GLMessage_DataType::set_charvalue(int index, const ::std::string& value) {
+  charvalue_.Mutable(index)->assign(value);
+}
+inline void GLMessage_DataType::set_charvalue(int index, const char* value) {
+  charvalue_.Mutable(index)->assign(value);
+}
+inline void GLMessage_DataType::set_charvalue(int index, const void* value, size_t size) {
+  charvalue_.Mutable(index)->assign(
+    reinterpret_cast<const char*>(value), size);
+}
+inline ::std::string* GLMessage_DataType::add_charvalue() {
+  return charvalue_.Add();
+}
+inline void GLMessage_DataType::add_charvalue(const ::std::string& value) {
+  charvalue_.Add()->assign(value);
+}
+inline void GLMessage_DataType::add_charvalue(const char* value) {
+  charvalue_.Add()->assign(value);
+}
+inline void GLMessage_DataType::add_charvalue(const void* value, size_t size) {
+  charvalue_.Add()->assign(reinterpret_cast<const char*>(value), size);
+}
+inline const ::google::protobuf::RepeatedPtrField< ::std::string>&
+GLMessage_DataType::charvalue() const {
+  return charvalue_;
+}
+inline ::google::protobuf::RepeatedPtrField< ::std::string>*
+GLMessage_DataType::mutable_charvalue() {
+  return &charvalue_;
+}
+
+// repeated bytes rawBytes = 6;
+inline int GLMessage_DataType::rawbytes_size() const {
+  return rawbytes_.size();
+}
+inline void GLMessage_DataType::clear_rawbytes() {
+  rawbytes_.Clear();
+}
+inline const ::std::string& GLMessage_DataType::rawbytes(int index) const {
+  return rawbytes_.Get(index);
+}
+inline ::std::string* GLMessage_DataType::mutable_rawbytes(int index) {
+  return rawbytes_.Mutable(index);
+}
+inline void GLMessage_DataType::set_rawbytes(int index, const ::std::string& value) {
+  rawbytes_.Mutable(index)->assign(value);
+}
+inline void GLMessage_DataType::set_rawbytes(int index, const char* value) {
+  rawbytes_.Mutable(index)->assign(value);
+}
+inline void GLMessage_DataType::set_rawbytes(int index, const void* value, size_t size) {
+  rawbytes_.Mutable(index)->assign(
+    reinterpret_cast<const char*>(value), size);
+}
+inline ::std::string* GLMessage_DataType::add_rawbytes() {
+  return rawbytes_.Add();
+}
+inline void GLMessage_DataType::add_rawbytes(const ::std::string& value) {
+  rawbytes_.Add()->assign(value);
+}
+inline void GLMessage_DataType::add_rawbytes(const char* value) {
+  rawbytes_.Add()->assign(value);
+}
+inline void GLMessage_DataType::add_rawbytes(const void* value, size_t size) {
+  rawbytes_.Add()->assign(reinterpret_cast<const char*>(value), size);
+}
+inline const ::google::protobuf::RepeatedPtrField< ::std::string>&
+GLMessage_DataType::rawbytes() const {
+  return rawbytes_;
+}
+inline ::google::protobuf::RepeatedPtrField< ::std::string>*
+GLMessage_DataType::mutable_rawbytes() {
+  return &rawbytes_;
+}
+
+// repeated bool boolValue = 7;
+inline int GLMessage_DataType::boolvalue_size() const {
+  return boolvalue_.size();
+}
+inline void GLMessage_DataType::clear_boolvalue() {
+  boolvalue_.Clear();
+}
+inline bool GLMessage_DataType::boolvalue(int index) const {
+  return boolvalue_.Get(index);
+}
+inline void GLMessage_DataType::set_boolvalue(int index, bool value) {
+  boolvalue_.Set(index, value);
+}
+inline void GLMessage_DataType::add_boolvalue(bool value) {
+  boolvalue_.Add(value);
+}
+inline const ::google::protobuf::RepeatedField< bool >&
+GLMessage_DataType::boolvalue() const {
+  return boolvalue_;
+}
+inline ::google::protobuf::RepeatedField< bool >*
+GLMessage_DataType::mutable_boolvalue() {
+  return &boolvalue_;
+}
+
+// -------------------------------------------------------------------
+
+// GLMessage_FrameBuffer
+
+// required int32 width = 1;
+inline bool GLMessage_FrameBuffer::has_width() const {
+  return _has_bit(0);
+}
+inline void GLMessage_FrameBuffer::clear_width() {
+  width_ = 0;
+  _clear_bit(0);
+}
+inline ::google::protobuf::int32 GLMessage_FrameBuffer::width() const {
+  return width_;
+}
+inline void GLMessage_FrameBuffer::set_width(::google::protobuf::int32 value) {
+  _set_bit(0);
+  width_ = value;
+}
+
+// required int32 height = 2;
+inline bool GLMessage_FrameBuffer::has_height() const {
+  return _has_bit(1);
+}
+inline void GLMessage_FrameBuffer::clear_height() {
+  height_ = 0;
+  _clear_bit(1);
+}
+inline ::google::protobuf::int32 GLMessage_FrameBuffer::height() const {
+  return height_;
+}
+inline void GLMessage_FrameBuffer::set_height(::google::protobuf::int32 value) {
+  _set_bit(1);
+  height_ = value;
+}
+
+// repeated bytes contents = 3;
+inline int GLMessage_FrameBuffer::contents_size() const {
+  return contents_.size();
+}
+inline void GLMessage_FrameBuffer::clear_contents() {
+  contents_.Clear();
+}
+inline const ::std::string& GLMessage_FrameBuffer::contents(int index) const {
+  return contents_.Get(index);
+}
+inline ::std::string* GLMessage_FrameBuffer::mutable_contents(int index) {
+  return contents_.Mutable(index);
+}
+inline void GLMessage_FrameBuffer::set_contents(int index, const ::std::string& value) {
+  contents_.Mutable(index)->assign(value);
+}
+inline void GLMessage_FrameBuffer::set_contents(int index, const char* value) {
+  contents_.Mutable(index)->assign(value);
+}
+inline void GLMessage_FrameBuffer::set_contents(int index, const void* value, size_t size) {
+  contents_.Mutable(index)->assign(
+    reinterpret_cast<const char*>(value), size);
+}
+inline ::std::string* GLMessage_FrameBuffer::add_contents() {
+  return contents_.Add();
+}
+inline void GLMessage_FrameBuffer::add_contents(const ::std::string& value) {
+  contents_.Add()->assign(value);
+}
+inline void GLMessage_FrameBuffer::add_contents(const char* value) {
+  contents_.Add()->assign(value);
+}
+inline void GLMessage_FrameBuffer::add_contents(const void* value, size_t size) {
+  contents_.Add()->assign(reinterpret_cast<const char*>(value), size);
+}
+inline const ::google::protobuf::RepeatedPtrField< ::std::string>&
+GLMessage_FrameBuffer::contents() const {
+  return contents_;
+}
+inline ::google::protobuf::RepeatedPtrField< ::std::string>*
+GLMessage_FrameBuffer::mutable_contents() {
+  return &contents_;
+}
+
+// -------------------------------------------------------------------
+
+// GLMessage
+
+// required int32 context_id = 1;
+inline bool GLMessage::has_context_id() const {
+  return _has_bit(0);
+}
+inline void GLMessage::clear_context_id() {
+  context_id_ = 0;
+  _clear_bit(0);
+}
+inline ::google::protobuf::int32 GLMessage::context_id() const {
+  return context_id_;
+}
+inline void GLMessage::set_context_id(::google::protobuf::int32 value) {
+  _set_bit(0);
+  context_id_ = value;
+}
+
+// required .android.gltrace.GLMessage.Function function = 2 [default = invalid];
+inline bool GLMessage::has_function() const {
+  return _has_bit(1);
+}
+inline void GLMessage::clear_function() {
+  function_ = 3000;
+  _clear_bit(1);
+}
+inline ::android::gltrace::GLMessage_Function GLMessage::function() const {
+  return static_cast< ::android::gltrace::GLMessage_Function >(function_);
+}
+inline void GLMessage::set_function(::android::gltrace::GLMessage_Function value) {
+  GOOGLE_DCHECK(::android::gltrace::GLMessage_Function_IsValid(value));
+  _set_bit(1);
+  function_ = value;
+}
+
+// repeated .android.gltrace.GLMessage.DataType args = 3;
+inline int GLMessage::args_size() const {
+  return args_.size();
+}
+inline void GLMessage::clear_args() {
+  args_.Clear();
+}
+inline const ::android::gltrace::GLMessage_DataType& GLMessage::args(int index) const {
+  return args_.Get(index);
+}
+inline ::android::gltrace::GLMessage_DataType* GLMessage::mutable_args(int index) {
+  return args_.Mutable(index);
+}
+inline ::android::gltrace::GLMessage_DataType* GLMessage::add_args() {
+  return args_.Add();
+}
+inline const ::google::protobuf::RepeatedPtrField< ::android::gltrace::GLMessage_DataType >&
+GLMessage::args() const {
+  return args_;
+}
+inline ::google::protobuf::RepeatedPtrField< ::android::gltrace::GLMessage_DataType >*
+GLMessage::mutable_args() {
+  return &args_;
+}
+
+// optional .android.gltrace.GLMessage.DataType returnValue = 4;
+inline bool GLMessage::has_returnvalue() const {
+  return _has_bit(3);
+}
+inline void GLMessage::clear_returnvalue() {
+  if (returnvalue_ != NULL) returnvalue_->::android::gltrace::GLMessage_DataType::Clear();
+  _clear_bit(3);
+}
+inline const ::android::gltrace::GLMessage_DataType& GLMessage::returnvalue() const {
+  return returnvalue_ != NULL ? *returnvalue_ : *default_instance_->returnvalue_;
+}
+inline ::android::gltrace::GLMessage_DataType* GLMessage::mutable_returnvalue() {
+  _set_bit(3);
+  if (returnvalue_ == NULL) returnvalue_ = new ::android::gltrace::GLMessage_DataType;
+  return returnvalue_;
+}
+
+// optional float duration = 5;
+inline bool GLMessage::has_duration() const {
+  return _has_bit(4);
+}
+inline void GLMessage::clear_duration() {
+  duration_ = 0;
+  _clear_bit(4);
+}
+inline float GLMessage::duration() const {
+  return duration_;
+}
+inline void GLMessage::set_duration(float value) {
+  _set_bit(4);
+  duration_ = value;
+}
+
+// optional .android.gltrace.GLMessage.FrameBuffer fb = 6;
+inline bool GLMessage::has_fb() const {
+  return _has_bit(5);
+}
+inline void GLMessage::clear_fb() {
+  if (fb_ != NULL) fb_->::android::gltrace::GLMessage_FrameBuffer::Clear();
+  _clear_bit(5);
+}
+inline const ::android::gltrace::GLMessage_FrameBuffer& GLMessage::fb() const {
+  return fb_ != NULL ? *fb_ : *default_instance_->fb_;
+}
+inline ::android::gltrace::GLMessage_FrameBuffer* GLMessage::mutable_fb() {
+  _set_bit(5);
+  if (fb_ == NULL) fb_ = new ::android::gltrace::GLMessage_FrameBuffer;
+  return fb_;
+}
+
+
+// @@protoc_insertion_point(namespace_scope)
+
+}  // namespace gltrace
+}  // namespace android
+
+// @@protoc_insertion_point(global_scope)
+
+#endif  // PROTOBUF_gltrace_2eproto__INCLUDED
diff --git a/opengl/libs/GLES_trace/src/gltrace_api.cpp b/opengl/libs/GLES_trace/src/gltrace_api.cpp
new file mode 100644
index 0000000..91929f3
--- /dev/null
+++ b/opengl/libs/GLES_trace/src/gltrace_api.cpp
@@ -0,0 +1,11921 @@
+/*
+ * Copyright 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.
+ *
+ * THIS FILE WAS GENERATED BY A SCRIPT. DO NOT EDIT.
+ */
+
+#include <cutils/log.h>
+#include <GLES2/gl2.h>
+
+#include "gltrace.pb.h"
+#include "gltrace_context.h"
+#include "gltrace_fixup.h"
+#include "gltrace_transport.h"
+
+namespace android {
+namespace gltrace {
+
+
+// Definitions for GL2 APIs
+
+void GLTrace_glActiveTexture(GLenum texture) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glActiveTexture);
+
+    // copy argument texture
+    GLMessage_DataType *arg_texture = glmsg.add_args();
+    arg_texture->set_isarray(false);
+    arg_texture->set_type(GLMessage::DataType::ENUM);
+    arg_texture->add_intvalue((int)texture);
+
+    // call function
+    glContext->hooks->gl.glActiveTexture(texture);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glAttachShader(GLuint program, GLuint shader) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glAttachShader);
+
+    // copy argument program
+    GLMessage_DataType *arg_program = glmsg.add_args();
+    arg_program->set_isarray(false);
+    arg_program->set_type(GLMessage::DataType::INT);
+    arg_program->add_intvalue(program);
+
+    // copy argument shader
+    GLMessage_DataType *arg_shader = glmsg.add_args();
+    arg_shader->set_isarray(false);
+    arg_shader->set_type(GLMessage::DataType::INT);
+    arg_shader->add_intvalue(shader);
+
+    // call function
+    glContext->hooks->gl.glAttachShader(program, shader);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glBindAttribLocation(GLuint program, GLuint index, const GLchar* name) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glBindAttribLocation);
+
+    // copy argument program
+    GLMessage_DataType *arg_program = glmsg.add_args();
+    arg_program->set_isarray(false);
+    arg_program->set_type(GLMessage::DataType::INT);
+    arg_program->add_intvalue(program);
+
+    // copy argument index
+    GLMessage_DataType *arg_index = glmsg.add_args();
+    arg_index->set_isarray(false);
+    arg_index->set_type(GLMessage::DataType::INT);
+    arg_index->add_intvalue(index);
+
+    // copy argument name
+    GLMessage_DataType *arg_name = glmsg.add_args();
+    arg_name->set_isarray(false);
+    arg_name->set_type(GLMessage::DataType::INT);
+    arg_name->add_intvalue((int)name);
+
+    // call function
+    glContext->hooks->gl.glBindAttribLocation(program, index, name);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glBindBuffer(GLenum target, GLuint buffer) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glBindBuffer);
+
+    // copy argument target
+    GLMessage_DataType *arg_target = glmsg.add_args();
+    arg_target->set_isarray(false);
+    arg_target->set_type(GLMessage::DataType::ENUM);
+    arg_target->add_intvalue((int)target);
+
+    // copy argument buffer
+    GLMessage_DataType *arg_buffer = glmsg.add_args();
+    arg_buffer->set_isarray(false);
+    arg_buffer->set_type(GLMessage::DataType::INT);
+    arg_buffer->add_intvalue(buffer);
+
+    // call function
+    glContext->hooks->gl.glBindBuffer(target, buffer);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glBindFramebuffer(GLenum target, GLuint framebuffer) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glBindFramebuffer);
+
+    // copy argument target
+    GLMessage_DataType *arg_target = glmsg.add_args();
+    arg_target->set_isarray(false);
+    arg_target->set_type(GLMessage::DataType::ENUM);
+    arg_target->add_intvalue((int)target);
+
+    // copy argument framebuffer
+    GLMessage_DataType *arg_framebuffer = glmsg.add_args();
+    arg_framebuffer->set_isarray(false);
+    arg_framebuffer->set_type(GLMessage::DataType::INT);
+    arg_framebuffer->add_intvalue(framebuffer);
+
+    // call function
+    glContext->hooks->gl.glBindFramebuffer(target, framebuffer);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glBindRenderbuffer(GLenum target, GLuint renderbuffer) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glBindRenderbuffer);
+
+    // copy argument target
+    GLMessage_DataType *arg_target = glmsg.add_args();
+    arg_target->set_isarray(false);
+    arg_target->set_type(GLMessage::DataType::ENUM);
+    arg_target->add_intvalue((int)target);
+
+    // copy argument renderbuffer
+    GLMessage_DataType *arg_renderbuffer = glmsg.add_args();
+    arg_renderbuffer->set_isarray(false);
+    arg_renderbuffer->set_type(GLMessage::DataType::INT);
+    arg_renderbuffer->add_intvalue(renderbuffer);
+
+    // call function
+    glContext->hooks->gl.glBindRenderbuffer(target, renderbuffer);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glBindTexture(GLenum target, GLuint texture) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glBindTexture);
+
+    // copy argument target
+    GLMessage_DataType *arg_target = glmsg.add_args();
+    arg_target->set_isarray(false);
+    arg_target->set_type(GLMessage::DataType::ENUM);
+    arg_target->add_intvalue((int)target);
+
+    // copy argument texture
+    GLMessage_DataType *arg_texture = glmsg.add_args();
+    arg_texture->set_isarray(false);
+    arg_texture->set_type(GLMessage::DataType::INT);
+    arg_texture->add_intvalue(texture);
+
+    // call function
+    glContext->hooks->gl.glBindTexture(target, texture);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glBlendColor);
+
+    // copy argument red
+    GLMessage_DataType *arg_red = glmsg.add_args();
+    arg_red->set_isarray(false);
+    arg_red->set_type(GLMessage::DataType::FLOAT);
+    arg_red->add_floatvalue(red);
+
+    // copy argument green
+    GLMessage_DataType *arg_green = glmsg.add_args();
+    arg_green->set_isarray(false);
+    arg_green->set_type(GLMessage::DataType::FLOAT);
+    arg_green->add_floatvalue(green);
+
+    // copy argument blue
+    GLMessage_DataType *arg_blue = glmsg.add_args();
+    arg_blue->set_isarray(false);
+    arg_blue->set_type(GLMessage::DataType::FLOAT);
+    arg_blue->add_floatvalue(blue);
+
+    // copy argument alpha
+    GLMessage_DataType *arg_alpha = glmsg.add_args();
+    arg_alpha->set_isarray(false);
+    arg_alpha->set_type(GLMessage::DataType::FLOAT);
+    arg_alpha->add_floatvalue(alpha);
+
+    // call function
+    glContext->hooks->gl.glBlendColor(red, green, blue, alpha);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glBlendEquation(GLenum mode) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glBlendEquation);
+
+    // copy argument mode
+    GLMessage_DataType *arg_mode = glmsg.add_args();
+    arg_mode->set_isarray(false);
+    arg_mode->set_type(GLMessage::DataType::ENUM);
+    arg_mode->add_intvalue((int)mode);
+
+    // call function
+    glContext->hooks->gl.glBlendEquation(mode);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glBlendEquationSeparate);
+
+    // copy argument modeRGB
+    GLMessage_DataType *arg_modeRGB = glmsg.add_args();
+    arg_modeRGB->set_isarray(false);
+    arg_modeRGB->set_type(GLMessage::DataType::ENUM);
+    arg_modeRGB->add_intvalue((int)modeRGB);
+
+    // copy argument modeAlpha
+    GLMessage_DataType *arg_modeAlpha = glmsg.add_args();
+    arg_modeAlpha->set_isarray(false);
+    arg_modeAlpha->set_type(GLMessage::DataType::ENUM);
+    arg_modeAlpha->add_intvalue((int)modeAlpha);
+
+    // call function
+    glContext->hooks->gl.glBlendEquationSeparate(modeRGB, modeAlpha);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glBlendFunc(GLenum sfactor, GLenum dfactor) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glBlendFunc);
+
+    // copy argument sfactor
+    GLMessage_DataType *arg_sfactor = glmsg.add_args();
+    arg_sfactor->set_isarray(false);
+    arg_sfactor->set_type(GLMessage::DataType::ENUM);
+    arg_sfactor->add_intvalue((int)sfactor);
+
+    // copy argument dfactor
+    GLMessage_DataType *arg_dfactor = glmsg.add_args();
+    arg_dfactor->set_isarray(false);
+    arg_dfactor->set_type(GLMessage::DataType::ENUM);
+    arg_dfactor->add_intvalue((int)dfactor);
+
+    // call function
+    glContext->hooks->gl.glBlendFunc(sfactor, dfactor);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glBlendFuncSeparate);
+
+    // copy argument srcRGB
+    GLMessage_DataType *arg_srcRGB = glmsg.add_args();
+    arg_srcRGB->set_isarray(false);
+    arg_srcRGB->set_type(GLMessage::DataType::ENUM);
+    arg_srcRGB->add_intvalue((int)srcRGB);
+
+    // copy argument dstRGB
+    GLMessage_DataType *arg_dstRGB = glmsg.add_args();
+    arg_dstRGB->set_isarray(false);
+    arg_dstRGB->set_type(GLMessage::DataType::ENUM);
+    arg_dstRGB->add_intvalue((int)dstRGB);
+
+    // copy argument srcAlpha
+    GLMessage_DataType *arg_srcAlpha = glmsg.add_args();
+    arg_srcAlpha->set_isarray(false);
+    arg_srcAlpha->set_type(GLMessage::DataType::ENUM);
+    arg_srcAlpha->add_intvalue((int)srcAlpha);
+
+    // copy argument dstAlpha
+    GLMessage_DataType *arg_dstAlpha = glmsg.add_args();
+    arg_dstAlpha->set_isarray(false);
+    arg_dstAlpha->set_type(GLMessage::DataType::ENUM);
+    arg_dstAlpha->add_intvalue((int)dstAlpha);
+
+    // call function
+    glContext->hooks->gl.glBlendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glBufferData);
+
+    // copy argument target
+    GLMessage_DataType *arg_target = glmsg.add_args();
+    arg_target->set_isarray(false);
+    arg_target->set_type(GLMessage::DataType::ENUM);
+    arg_target->add_intvalue((int)target);
+
+    // copy argument size
+    GLMessage_DataType *arg_size = glmsg.add_args();
+    arg_size->set_isarray(false);
+    arg_size->set_type(GLMessage::DataType::INT);
+    arg_size->add_intvalue((int)size);
+
+    // copy argument data
+    GLMessage_DataType *arg_data = glmsg.add_args();
+    arg_data->set_isarray(false);
+    arg_data->set_type(GLMessage::DataType::INT);
+    arg_data->add_intvalue((int)data);
+
+    // copy argument usage
+    GLMessage_DataType *arg_usage = glmsg.add_args();
+    arg_usage->set_isarray(false);
+    arg_usage->set_type(GLMessage::DataType::ENUM);
+    arg_usage->add_intvalue((int)usage);
+
+    // call function
+    glContext->hooks->gl.glBufferData(target, size, data, usage);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glBufferSubData);
+
+    // copy argument target
+    GLMessage_DataType *arg_target = glmsg.add_args();
+    arg_target->set_isarray(false);
+    arg_target->set_type(GLMessage::DataType::ENUM);
+    arg_target->add_intvalue((int)target);
+
+    // copy argument offset
+    GLMessage_DataType *arg_offset = glmsg.add_args();
+    arg_offset->set_isarray(false);
+    arg_offset->set_type(GLMessage::DataType::INT);
+    arg_offset->add_intvalue((int)offset);
+
+    // copy argument size
+    GLMessage_DataType *arg_size = glmsg.add_args();
+    arg_size->set_isarray(false);
+    arg_size->set_type(GLMessage::DataType::INT);
+    arg_size->add_intvalue((int)size);
+
+    // copy argument data
+    GLMessage_DataType *arg_data = glmsg.add_args();
+    arg_data->set_isarray(false);
+    arg_data->set_type(GLMessage::DataType::INT);
+    arg_data->add_intvalue((int)data);
+
+    // call function
+    glContext->hooks->gl.glBufferSubData(target, offset, size, data);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+GLenum GLTrace_glCheckFramebufferStatus(GLenum target) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glCheckFramebufferStatus);
+
+    // copy argument target
+    GLMessage_DataType *arg_target = glmsg.add_args();
+    arg_target->set_isarray(false);
+    arg_target->set_type(GLMessage::DataType::ENUM);
+    arg_target->add_intvalue((int)target);
+
+    // call function
+    GLenum retValue = glContext->hooks->gl.glCheckFramebufferStatus(target);
+
+    // set return value
+    GLMessage_DataType *rt = glmsg.mutable_returnvalue();
+    rt->set_isarray(false);
+    rt->set_type(GLMessage::DataType::ENUM);
+    rt->add_intvalue((int)retValue);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+
+    return retValue;
+}
+
+void GLTrace_glClear(GLbitfield mask) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glClear);
+
+    // copy argument mask
+    GLMessage_DataType *arg_mask = glmsg.add_args();
+    arg_mask->set_isarray(false);
+    arg_mask->set_type(GLMessage::DataType::INT);
+    arg_mask->add_intvalue(mask);
+
+    // call function
+    glContext->hooks->gl.glClear(mask);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glClearColor);
+
+    // copy argument red
+    GLMessage_DataType *arg_red = glmsg.add_args();
+    arg_red->set_isarray(false);
+    arg_red->set_type(GLMessage::DataType::FLOAT);
+    arg_red->add_floatvalue(red);
+
+    // copy argument green
+    GLMessage_DataType *arg_green = glmsg.add_args();
+    arg_green->set_isarray(false);
+    arg_green->set_type(GLMessage::DataType::FLOAT);
+    arg_green->add_floatvalue(green);
+
+    // copy argument blue
+    GLMessage_DataType *arg_blue = glmsg.add_args();
+    arg_blue->set_isarray(false);
+    arg_blue->set_type(GLMessage::DataType::FLOAT);
+    arg_blue->add_floatvalue(blue);
+
+    // copy argument alpha
+    GLMessage_DataType *arg_alpha = glmsg.add_args();
+    arg_alpha->set_isarray(false);
+    arg_alpha->set_type(GLMessage::DataType::FLOAT);
+    arg_alpha->add_floatvalue(alpha);
+
+    // call function
+    glContext->hooks->gl.glClearColor(red, green, blue, alpha);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glClearDepthf(GLclampf depth) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glClearDepthf);
+
+    // copy argument depth
+    GLMessage_DataType *arg_depth = glmsg.add_args();
+    arg_depth->set_isarray(false);
+    arg_depth->set_type(GLMessage::DataType::FLOAT);
+    arg_depth->add_floatvalue(depth);
+
+    // call function
+    glContext->hooks->gl.glClearDepthf(depth);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glClearStencil(GLint s) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glClearStencil);
+
+    // copy argument s
+    GLMessage_DataType *arg_s = glmsg.add_args();
+    arg_s->set_isarray(false);
+    arg_s->set_type(GLMessage::DataType::INT);
+    arg_s->add_intvalue(s);
+
+    // call function
+    glContext->hooks->gl.glClearStencil(s);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glColorMask);
+
+    // copy argument red
+    GLMessage_DataType *arg_red = glmsg.add_args();
+    arg_red->set_isarray(false);
+    arg_red->set_type(GLMessage::DataType::BOOL);
+    arg_red->add_boolvalue(red);
+
+    // copy argument green
+    GLMessage_DataType *arg_green = glmsg.add_args();
+    arg_green->set_isarray(false);
+    arg_green->set_type(GLMessage::DataType::BOOL);
+    arg_green->add_boolvalue(green);
+
+    // copy argument blue
+    GLMessage_DataType *arg_blue = glmsg.add_args();
+    arg_blue->set_isarray(false);
+    arg_blue->set_type(GLMessage::DataType::BOOL);
+    arg_blue->add_boolvalue(blue);
+
+    // copy argument alpha
+    GLMessage_DataType *arg_alpha = glmsg.add_args();
+    arg_alpha->set_isarray(false);
+    arg_alpha->set_type(GLMessage::DataType::BOOL);
+    arg_alpha->add_boolvalue(alpha);
+
+    // call function
+    glContext->hooks->gl.glColorMask(red, green, blue, alpha);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glCompileShader(GLuint shader) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glCompileShader);
+
+    // copy argument shader
+    GLMessage_DataType *arg_shader = glmsg.add_args();
+    arg_shader->set_isarray(false);
+    arg_shader->set_type(GLMessage::DataType::INT);
+    arg_shader->add_intvalue(shader);
+
+    // call function
+    glContext->hooks->gl.glCompileShader(shader);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid* data) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glCompressedTexImage2D);
+
+    // copy argument target
+    GLMessage_DataType *arg_target = glmsg.add_args();
+    arg_target->set_isarray(false);
+    arg_target->set_type(GLMessage::DataType::ENUM);
+    arg_target->add_intvalue((int)target);
+
+    // copy argument level
+    GLMessage_DataType *arg_level = glmsg.add_args();
+    arg_level->set_isarray(false);
+    arg_level->set_type(GLMessage::DataType::INT);
+    arg_level->add_intvalue(level);
+
+    // copy argument internalformat
+    GLMessage_DataType *arg_internalformat = glmsg.add_args();
+    arg_internalformat->set_isarray(false);
+    arg_internalformat->set_type(GLMessage::DataType::ENUM);
+    arg_internalformat->add_intvalue((int)internalformat);
+
+    // copy argument width
+    GLMessage_DataType *arg_width = glmsg.add_args();
+    arg_width->set_isarray(false);
+    arg_width->set_type(GLMessage::DataType::INT);
+    arg_width->add_intvalue(width);
+
+    // copy argument height
+    GLMessage_DataType *arg_height = glmsg.add_args();
+    arg_height->set_isarray(false);
+    arg_height->set_type(GLMessage::DataType::INT);
+    arg_height->add_intvalue(height);
+
+    // copy argument border
+    GLMessage_DataType *arg_border = glmsg.add_args();
+    arg_border->set_isarray(false);
+    arg_border->set_type(GLMessage::DataType::INT);
+    arg_border->add_intvalue(border);
+
+    // copy argument imageSize
+    GLMessage_DataType *arg_imageSize = glmsg.add_args();
+    arg_imageSize->set_isarray(false);
+    arg_imageSize->set_type(GLMessage::DataType::INT);
+    arg_imageSize->add_intvalue(imageSize);
+
+    // copy argument data
+    GLMessage_DataType *arg_data = glmsg.add_args();
+    arg_data->set_isarray(false);
+    arg_data->set_type(GLMessage::DataType::INT);
+    arg_data->add_intvalue((int)data);
+
+    // call function
+    glContext->hooks->gl.glCompressedTexImage2D(target, level, internalformat, width, height, border, imageSize, data);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid* data) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glCompressedTexSubImage2D);
+
+    // copy argument target
+    GLMessage_DataType *arg_target = glmsg.add_args();
+    arg_target->set_isarray(false);
+    arg_target->set_type(GLMessage::DataType::ENUM);
+    arg_target->add_intvalue((int)target);
+
+    // copy argument level
+    GLMessage_DataType *arg_level = glmsg.add_args();
+    arg_level->set_isarray(false);
+    arg_level->set_type(GLMessage::DataType::INT);
+    arg_level->add_intvalue(level);
+
+    // copy argument xoffset
+    GLMessage_DataType *arg_xoffset = glmsg.add_args();
+    arg_xoffset->set_isarray(false);
+    arg_xoffset->set_type(GLMessage::DataType::INT);
+    arg_xoffset->add_intvalue(xoffset);
+
+    // copy argument yoffset
+    GLMessage_DataType *arg_yoffset = glmsg.add_args();
+    arg_yoffset->set_isarray(false);
+    arg_yoffset->set_type(GLMessage::DataType::INT);
+    arg_yoffset->add_intvalue(yoffset);
+
+    // copy argument width
+    GLMessage_DataType *arg_width = glmsg.add_args();
+    arg_width->set_isarray(false);
+    arg_width->set_type(GLMessage::DataType::INT);
+    arg_width->add_intvalue(width);
+
+    // copy argument height
+    GLMessage_DataType *arg_height = glmsg.add_args();
+    arg_height->set_isarray(false);
+    arg_height->set_type(GLMessage::DataType::INT);
+    arg_height->add_intvalue(height);
+
+    // copy argument format
+    GLMessage_DataType *arg_format = glmsg.add_args();
+    arg_format->set_isarray(false);
+    arg_format->set_type(GLMessage::DataType::ENUM);
+    arg_format->add_intvalue((int)format);
+
+    // copy argument imageSize
+    GLMessage_DataType *arg_imageSize = glmsg.add_args();
+    arg_imageSize->set_isarray(false);
+    arg_imageSize->set_type(GLMessage::DataType::INT);
+    arg_imageSize->add_intvalue(imageSize);
+
+    // copy argument data
+    GLMessage_DataType *arg_data = glmsg.add_args();
+    arg_data->set_isarray(false);
+    arg_data->set_type(GLMessage::DataType::INT);
+    arg_data->add_intvalue((int)data);
+
+    // call function
+    glContext->hooks->gl.glCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, imageSize, data);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glCopyTexImage2D);
+
+    // copy argument target
+    GLMessage_DataType *arg_target = glmsg.add_args();
+    arg_target->set_isarray(false);
+    arg_target->set_type(GLMessage::DataType::ENUM);
+    arg_target->add_intvalue((int)target);
+
+    // copy argument level
+    GLMessage_DataType *arg_level = glmsg.add_args();
+    arg_level->set_isarray(false);
+    arg_level->set_type(GLMessage::DataType::INT);
+    arg_level->add_intvalue(level);
+
+    // copy argument internalformat
+    GLMessage_DataType *arg_internalformat = glmsg.add_args();
+    arg_internalformat->set_isarray(false);
+    arg_internalformat->set_type(GLMessage::DataType::ENUM);
+    arg_internalformat->add_intvalue((int)internalformat);
+
+    // copy argument x
+    GLMessage_DataType *arg_x = glmsg.add_args();
+    arg_x->set_isarray(false);
+    arg_x->set_type(GLMessage::DataType::INT);
+    arg_x->add_intvalue(x);
+
+    // copy argument y
+    GLMessage_DataType *arg_y = glmsg.add_args();
+    arg_y->set_isarray(false);
+    arg_y->set_type(GLMessage::DataType::INT);
+    arg_y->add_intvalue(y);
+
+    // copy argument width
+    GLMessage_DataType *arg_width = glmsg.add_args();
+    arg_width->set_isarray(false);
+    arg_width->set_type(GLMessage::DataType::INT);
+    arg_width->add_intvalue(width);
+
+    // copy argument height
+    GLMessage_DataType *arg_height = glmsg.add_args();
+    arg_height->set_isarray(false);
+    arg_height->set_type(GLMessage::DataType::INT);
+    arg_height->add_intvalue(height);
+
+    // copy argument border
+    GLMessage_DataType *arg_border = glmsg.add_args();
+    arg_border->set_isarray(false);
+    arg_border->set_type(GLMessage::DataType::INT);
+    arg_border->add_intvalue(border);
+
+    // call function
+    glContext->hooks->gl.glCopyTexImage2D(target, level, internalformat, x, y, width, height, border);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glCopyTexSubImage2D);
+
+    // copy argument target
+    GLMessage_DataType *arg_target = glmsg.add_args();
+    arg_target->set_isarray(false);
+    arg_target->set_type(GLMessage::DataType::ENUM);
+    arg_target->add_intvalue((int)target);
+
+    // copy argument level
+    GLMessage_DataType *arg_level = glmsg.add_args();
+    arg_level->set_isarray(false);
+    arg_level->set_type(GLMessage::DataType::INT);
+    arg_level->add_intvalue(level);
+
+    // copy argument xoffset
+    GLMessage_DataType *arg_xoffset = glmsg.add_args();
+    arg_xoffset->set_isarray(false);
+    arg_xoffset->set_type(GLMessage::DataType::INT);
+    arg_xoffset->add_intvalue(xoffset);
+
+    // copy argument yoffset
+    GLMessage_DataType *arg_yoffset = glmsg.add_args();
+    arg_yoffset->set_isarray(false);
+    arg_yoffset->set_type(GLMessage::DataType::INT);
+    arg_yoffset->add_intvalue(yoffset);
+
+    // copy argument x
+    GLMessage_DataType *arg_x = glmsg.add_args();
+    arg_x->set_isarray(false);
+    arg_x->set_type(GLMessage::DataType::INT);
+    arg_x->add_intvalue(x);
+
+    // copy argument y
+    GLMessage_DataType *arg_y = glmsg.add_args();
+    arg_y->set_isarray(false);
+    arg_y->set_type(GLMessage::DataType::INT);
+    arg_y->add_intvalue(y);
+
+    // copy argument width
+    GLMessage_DataType *arg_width = glmsg.add_args();
+    arg_width->set_isarray(false);
+    arg_width->set_type(GLMessage::DataType::INT);
+    arg_width->add_intvalue(width);
+
+    // copy argument height
+    GLMessage_DataType *arg_height = glmsg.add_args();
+    arg_height->set_isarray(false);
+    arg_height->set_type(GLMessage::DataType::INT);
+    arg_height->add_intvalue(height);
+
+    // call function
+    glContext->hooks->gl.glCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+GLuint GLTrace_glCreateProgram(void) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glCreateProgram);
+
+    // call function
+    GLuint retValue = glContext->hooks->gl.glCreateProgram();
+
+    // set return value
+    GLMessage_DataType *rt = glmsg.mutable_returnvalue();
+    rt->set_isarray(false);
+    rt->set_type(GLMessage::DataType::INT);
+    rt->add_intvalue(retValue);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+
+    return retValue;
+}
+
+GLuint GLTrace_glCreateShader(GLenum type) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glCreateShader);
+
+    // copy argument type
+    GLMessage_DataType *arg_type = glmsg.add_args();
+    arg_type->set_isarray(false);
+    arg_type->set_type(GLMessage::DataType::ENUM);
+    arg_type->add_intvalue((int)type);
+
+    // call function
+    GLuint retValue = glContext->hooks->gl.glCreateShader(type);
+
+    // set return value
+    GLMessage_DataType *rt = glmsg.mutable_returnvalue();
+    rt->set_isarray(false);
+    rt->set_type(GLMessage::DataType::INT);
+    rt->add_intvalue(retValue);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+
+    return retValue;
+}
+
+void GLTrace_glCullFace(GLenum mode) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glCullFace);
+
+    // copy argument mode
+    GLMessage_DataType *arg_mode = glmsg.add_args();
+    arg_mode->set_isarray(false);
+    arg_mode->set_type(GLMessage::DataType::ENUM);
+    arg_mode->add_intvalue((int)mode);
+
+    // call function
+    glContext->hooks->gl.glCullFace(mode);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glDeleteBuffers(GLsizei n, const GLuint* buffers) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glDeleteBuffers);
+
+    // copy argument n
+    GLMessage_DataType *arg_n = glmsg.add_args();
+    arg_n->set_isarray(false);
+    arg_n->set_type(GLMessage::DataType::INT);
+    arg_n->add_intvalue(n);
+
+    // copy argument buffers
+    GLMessage_DataType *arg_buffers = glmsg.add_args();
+    arg_buffers->set_isarray(false);
+    arg_buffers->set_type(GLMessage::DataType::INT);
+    arg_buffers->add_intvalue((int)buffers);
+
+    // call function
+    glContext->hooks->gl.glDeleteBuffers(n, buffers);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glDeleteFramebuffers);
+
+    // copy argument n
+    GLMessage_DataType *arg_n = glmsg.add_args();
+    arg_n->set_isarray(false);
+    arg_n->set_type(GLMessage::DataType::INT);
+    arg_n->add_intvalue(n);
+
+    // copy argument framebuffers
+    GLMessage_DataType *arg_framebuffers = glmsg.add_args();
+    arg_framebuffers->set_isarray(false);
+    arg_framebuffers->set_type(GLMessage::DataType::INT);
+    arg_framebuffers->add_intvalue((int)framebuffers);
+
+    // call function
+    glContext->hooks->gl.glDeleteFramebuffers(n, framebuffers);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glDeleteProgram(GLuint program) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glDeleteProgram);
+
+    // copy argument program
+    GLMessage_DataType *arg_program = glmsg.add_args();
+    arg_program->set_isarray(false);
+    arg_program->set_type(GLMessage::DataType::INT);
+    arg_program->add_intvalue(program);
+
+    // call function
+    glContext->hooks->gl.glDeleteProgram(program);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glDeleteRenderbuffers);
+
+    // copy argument n
+    GLMessage_DataType *arg_n = glmsg.add_args();
+    arg_n->set_isarray(false);
+    arg_n->set_type(GLMessage::DataType::INT);
+    arg_n->add_intvalue(n);
+
+    // copy argument renderbuffers
+    GLMessage_DataType *arg_renderbuffers = glmsg.add_args();
+    arg_renderbuffers->set_isarray(false);
+    arg_renderbuffers->set_type(GLMessage::DataType::INT);
+    arg_renderbuffers->add_intvalue((int)renderbuffers);
+
+    // call function
+    glContext->hooks->gl.glDeleteRenderbuffers(n, renderbuffers);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glDeleteShader(GLuint shader) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glDeleteShader);
+
+    // copy argument shader
+    GLMessage_DataType *arg_shader = glmsg.add_args();
+    arg_shader->set_isarray(false);
+    arg_shader->set_type(GLMessage::DataType::INT);
+    arg_shader->add_intvalue(shader);
+
+    // call function
+    glContext->hooks->gl.glDeleteShader(shader);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glDeleteTextures(GLsizei n, const GLuint* textures) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glDeleteTextures);
+
+    // copy argument n
+    GLMessage_DataType *arg_n = glmsg.add_args();
+    arg_n->set_isarray(false);
+    arg_n->set_type(GLMessage::DataType::INT);
+    arg_n->add_intvalue(n);
+
+    // copy argument textures
+    GLMessage_DataType *arg_textures = glmsg.add_args();
+    arg_textures->set_isarray(false);
+    arg_textures->set_type(GLMessage::DataType::INT);
+    arg_textures->add_intvalue((int)textures);
+
+    // call function
+    glContext->hooks->gl.glDeleteTextures(n, textures);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glDepthFunc(GLenum func) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glDepthFunc);
+
+    // copy argument func
+    GLMessage_DataType *arg_func = glmsg.add_args();
+    arg_func->set_isarray(false);
+    arg_func->set_type(GLMessage::DataType::ENUM);
+    arg_func->add_intvalue((int)func);
+
+    // call function
+    glContext->hooks->gl.glDepthFunc(func);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glDepthMask(GLboolean flag) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glDepthMask);
+
+    // copy argument flag
+    GLMessage_DataType *arg_flag = glmsg.add_args();
+    arg_flag->set_isarray(false);
+    arg_flag->set_type(GLMessage::DataType::BOOL);
+    arg_flag->add_boolvalue(flag);
+
+    // call function
+    glContext->hooks->gl.glDepthMask(flag);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glDepthRangef(GLclampf zNear, GLclampf zFar) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glDepthRangef);
+
+    // copy argument zNear
+    GLMessage_DataType *arg_zNear = glmsg.add_args();
+    arg_zNear->set_isarray(false);
+    arg_zNear->set_type(GLMessage::DataType::FLOAT);
+    arg_zNear->add_floatvalue(zNear);
+
+    // copy argument zFar
+    GLMessage_DataType *arg_zFar = glmsg.add_args();
+    arg_zFar->set_isarray(false);
+    arg_zFar->set_type(GLMessage::DataType::FLOAT);
+    arg_zFar->add_floatvalue(zFar);
+
+    // call function
+    glContext->hooks->gl.glDepthRangef(zNear, zFar);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glDetachShader(GLuint program, GLuint shader) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glDetachShader);
+
+    // copy argument program
+    GLMessage_DataType *arg_program = glmsg.add_args();
+    arg_program->set_isarray(false);
+    arg_program->set_type(GLMessage::DataType::INT);
+    arg_program->add_intvalue(program);
+
+    // copy argument shader
+    GLMessage_DataType *arg_shader = glmsg.add_args();
+    arg_shader->set_isarray(false);
+    arg_shader->set_type(GLMessage::DataType::INT);
+    arg_shader->add_intvalue(shader);
+
+    // call function
+    glContext->hooks->gl.glDetachShader(program, shader);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glDisable(GLenum cap) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glDisable);
+
+    // copy argument cap
+    GLMessage_DataType *arg_cap = glmsg.add_args();
+    arg_cap->set_isarray(false);
+    arg_cap->set_type(GLMessage::DataType::ENUM);
+    arg_cap->add_intvalue((int)cap);
+
+    // call function
+    glContext->hooks->gl.glDisable(cap);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glDisableVertexAttribArray(GLuint index) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glDisableVertexAttribArray);
+
+    // copy argument index
+    GLMessage_DataType *arg_index = glmsg.add_args();
+    arg_index->set_isarray(false);
+    arg_index->set_type(GLMessage::DataType::INT);
+    arg_index->add_intvalue(index);
+
+    // call function
+    glContext->hooks->gl.glDisableVertexAttribArray(index);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glDrawArrays(GLenum mode, GLint first, GLsizei count) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glDrawArrays);
+
+    // copy argument mode
+    GLMessage_DataType *arg_mode = glmsg.add_args();
+    arg_mode->set_isarray(false);
+    arg_mode->set_type(GLMessage::DataType::ENUM);
+    arg_mode->add_intvalue((int)mode);
+
+    // copy argument first
+    GLMessage_DataType *arg_first = glmsg.add_args();
+    arg_first->set_isarray(false);
+    arg_first->set_type(GLMessage::DataType::INT);
+    arg_first->add_intvalue(first);
+
+    // copy argument count
+    GLMessage_DataType *arg_count = glmsg.add_args();
+    arg_count->set_isarray(false);
+    arg_count->set_type(GLMessage::DataType::INT);
+    arg_count->add_intvalue(count);
+
+    // call function
+    glContext->hooks->gl.glDrawArrays(mode, first, count);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glDrawElements);
+
+    // copy argument mode
+    GLMessage_DataType *arg_mode = glmsg.add_args();
+    arg_mode->set_isarray(false);
+    arg_mode->set_type(GLMessage::DataType::ENUM);
+    arg_mode->add_intvalue((int)mode);
+
+    // copy argument count
+    GLMessage_DataType *arg_count = glmsg.add_args();
+    arg_count->set_isarray(false);
+    arg_count->set_type(GLMessage::DataType::INT);
+    arg_count->add_intvalue(count);
+
+    // copy argument type
+    GLMessage_DataType *arg_type = glmsg.add_args();
+    arg_type->set_isarray(false);
+    arg_type->set_type(GLMessage::DataType::ENUM);
+    arg_type->add_intvalue((int)type);
+
+    // copy argument indices
+    GLMessage_DataType *arg_indices = glmsg.add_args();
+    arg_indices->set_isarray(false);
+    arg_indices->set_type(GLMessage::DataType::INT);
+    arg_indices->add_intvalue((int)indices);
+
+    // call function
+    glContext->hooks->gl.glDrawElements(mode, count, type, indices);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glEnable(GLenum cap) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glEnable);
+
+    // copy argument cap
+    GLMessage_DataType *arg_cap = glmsg.add_args();
+    arg_cap->set_isarray(false);
+    arg_cap->set_type(GLMessage::DataType::ENUM);
+    arg_cap->add_intvalue((int)cap);
+
+    // call function
+    glContext->hooks->gl.glEnable(cap);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glEnableVertexAttribArray(GLuint index) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glEnableVertexAttribArray);
+
+    // copy argument index
+    GLMessage_DataType *arg_index = glmsg.add_args();
+    arg_index->set_isarray(false);
+    arg_index->set_type(GLMessage::DataType::INT);
+    arg_index->add_intvalue(index);
+
+    // call function
+    glContext->hooks->gl.glEnableVertexAttribArray(index);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glFinish(void) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glFinish);
+
+    // call function
+    glContext->hooks->gl.glFinish();
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glFlush(void) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glFlush);
+
+    // call function
+    glContext->hooks->gl.glFlush();
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glFramebufferRenderbuffer);
+
+    // copy argument target
+    GLMessage_DataType *arg_target = glmsg.add_args();
+    arg_target->set_isarray(false);
+    arg_target->set_type(GLMessage::DataType::ENUM);
+    arg_target->add_intvalue((int)target);
+
+    // copy argument attachment
+    GLMessage_DataType *arg_attachment = glmsg.add_args();
+    arg_attachment->set_isarray(false);
+    arg_attachment->set_type(GLMessage::DataType::ENUM);
+    arg_attachment->add_intvalue((int)attachment);
+
+    // copy argument renderbuffertarget
+    GLMessage_DataType *arg_renderbuffertarget = glmsg.add_args();
+    arg_renderbuffertarget->set_isarray(false);
+    arg_renderbuffertarget->set_type(GLMessage::DataType::ENUM);
+    arg_renderbuffertarget->add_intvalue((int)renderbuffertarget);
+
+    // copy argument renderbuffer
+    GLMessage_DataType *arg_renderbuffer = glmsg.add_args();
+    arg_renderbuffer->set_isarray(false);
+    arg_renderbuffer->set_type(GLMessage::DataType::INT);
+    arg_renderbuffer->add_intvalue(renderbuffer);
+
+    // call function
+    glContext->hooks->gl.glFramebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glFramebufferTexture2D);
+
+    // copy argument target
+    GLMessage_DataType *arg_target = glmsg.add_args();
+    arg_target->set_isarray(false);
+    arg_target->set_type(GLMessage::DataType::ENUM);
+    arg_target->add_intvalue((int)target);
+
+    // copy argument attachment
+    GLMessage_DataType *arg_attachment = glmsg.add_args();
+    arg_attachment->set_isarray(false);
+    arg_attachment->set_type(GLMessage::DataType::ENUM);
+    arg_attachment->add_intvalue((int)attachment);
+
+    // copy argument textarget
+    GLMessage_DataType *arg_textarget = glmsg.add_args();
+    arg_textarget->set_isarray(false);
+    arg_textarget->set_type(GLMessage::DataType::ENUM);
+    arg_textarget->add_intvalue((int)textarget);
+
+    // copy argument texture
+    GLMessage_DataType *arg_texture = glmsg.add_args();
+    arg_texture->set_isarray(false);
+    arg_texture->set_type(GLMessage::DataType::INT);
+    arg_texture->add_intvalue(texture);
+
+    // copy argument level
+    GLMessage_DataType *arg_level = glmsg.add_args();
+    arg_level->set_isarray(false);
+    arg_level->set_type(GLMessage::DataType::INT);
+    arg_level->add_intvalue(level);
+
+    // call function
+    glContext->hooks->gl.glFramebufferTexture2D(target, attachment, textarget, texture, level);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glFrontFace(GLenum mode) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glFrontFace);
+
+    // copy argument mode
+    GLMessage_DataType *arg_mode = glmsg.add_args();
+    arg_mode->set_isarray(false);
+    arg_mode->set_type(GLMessage::DataType::ENUM);
+    arg_mode->add_intvalue((int)mode);
+
+    // call function
+    glContext->hooks->gl.glFrontFace(mode);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glGenBuffers(GLsizei n, GLuint* buffers) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glGenBuffers);
+
+    // copy argument n
+    GLMessage_DataType *arg_n = glmsg.add_args();
+    arg_n->set_isarray(false);
+    arg_n->set_type(GLMessage::DataType::INT);
+    arg_n->add_intvalue(n);
+
+    // copy argument buffers
+    GLMessage_DataType *arg_buffers = glmsg.add_args();
+    arg_buffers->set_isarray(false);
+    arg_buffers->set_type(GLMessage::DataType::INT);
+    arg_buffers->add_intvalue((int)buffers);
+
+    // call function
+    glContext->hooks->gl.glGenBuffers(n, buffers);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glGenerateMipmap(GLenum target) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glGenerateMipmap);
+
+    // copy argument target
+    GLMessage_DataType *arg_target = glmsg.add_args();
+    arg_target->set_isarray(false);
+    arg_target->set_type(GLMessage::DataType::ENUM);
+    arg_target->add_intvalue((int)target);
+
+    // call function
+    glContext->hooks->gl.glGenerateMipmap(target);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glGenFramebuffers(GLsizei n, GLuint* framebuffers) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glGenFramebuffers);
+
+    // copy argument n
+    GLMessage_DataType *arg_n = glmsg.add_args();
+    arg_n->set_isarray(false);
+    arg_n->set_type(GLMessage::DataType::INT);
+    arg_n->add_intvalue(n);
+
+    // copy argument framebuffers
+    GLMessage_DataType *arg_framebuffers = glmsg.add_args();
+    arg_framebuffers->set_isarray(false);
+    arg_framebuffers->set_type(GLMessage::DataType::INT);
+    arg_framebuffers->add_intvalue((int)framebuffers);
+
+    // call function
+    glContext->hooks->gl.glGenFramebuffers(n, framebuffers);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glGenRenderbuffers(GLsizei n, GLuint* renderbuffers) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glGenRenderbuffers);
+
+    // copy argument n
+    GLMessage_DataType *arg_n = glmsg.add_args();
+    arg_n->set_isarray(false);
+    arg_n->set_type(GLMessage::DataType::INT);
+    arg_n->add_intvalue(n);
+
+    // copy argument renderbuffers
+    GLMessage_DataType *arg_renderbuffers = glmsg.add_args();
+    arg_renderbuffers->set_isarray(false);
+    arg_renderbuffers->set_type(GLMessage::DataType::INT);
+    arg_renderbuffers->add_intvalue((int)renderbuffers);
+
+    // call function
+    glContext->hooks->gl.glGenRenderbuffers(n, renderbuffers);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glGenTextures(GLsizei n, GLuint* textures) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glGenTextures);
+
+    // copy argument n
+    GLMessage_DataType *arg_n = glmsg.add_args();
+    arg_n->set_isarray(false);
+    arg_n->set_type(GLMessage::DataType::INT);
+    arg_n->add_intvalue(n);
+
+    // copy argument textures
+    GLMessage_DataType *arg_textures = glmsg.add_args();
+    arg_textures->set_isarray(false);
+    arg_textures->set_type(GLMessage::DataType::INT);
+    arg_textures->add_intvalue((int)textures);
+
+    // call function
+    glContext->hooks->gl.glGenTextures(n, textures);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glGetActiveAttrib);
+
+    // copy argument program
+    GLMessage_DataType *arg_program = glmsg.add_args();
+    arg_program->set_isarray(false);
+    arg_program->set_type(GLMessage::DataType::INT);
+    arg_program->add_intvalue(program);
+
+    // copy argument index
+    GLMessage_DataType *arg_index = glmsg.add_args();
+    arg_index->set_isarray(false);
+    arg_index->set_type(GLMessage::DataType::INT);
+    arg_index->add_intvalue(index);
+
+    // copy argument bufsize
+    GLMessage_DataType *arg_bufsize = glmsg.add_args();
+    arg_bufsize->set_isarray(false);
+    arg_bufsize->set_type(GLMessage::DataType::INT);
+    arg_bufsize->add_intvalue(bufsize);
+
+    // copy argument length
+    GLMessage_DataType *arg_length = glmsg.add_args();
+    arg_length->set_isarray(false);
+    arg_length->set_type(GLMessage::DataType::INT);
+    arg_length->add_intvalue((int)length);
+
+    // copy argument size
+    GLMessage_DataType *arg_size = glmsg.add_args();
+    arg_size->set_isarray(false);
+    arg_size->set_type(GLMessage::DataType::INT);
+    arg_size->add_intvalue((int)size);
+
+    // copy argument type
+    GLMessage_DataType *arg_type = glmsg.add_args();
+    arg_type->set_isarray(false);
+    arg_type->set_type(GLMessage::DataType::INT);
+    arg_type->add_intvalue((int)type);
+
+    // copy argument name
+    GLMessage_DataType *arg_name = glmsg.add_args();
+    arg_name->set_isarray(false);
+    arg_name->set_type(GLMessage::DataType::INT);
+    arg_name->add_intvalue((int)name);
+
+    // call function
+    glContext->hooks->gl.glGetActiveAttrib(program, index, bufsize, length, size, type, name);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glGetActiveUniform);
+
+    // copy argument program
+    GLMessage_DataType *arg_program = glmsg.add_args();
+    arg_program->set_isarray(false);
+    arg_program->set_type(GLMessage::DataType::INT);
+    arg_program->add_intvalue(program);
+
+    // copy argument index
+    GLMessage_DataType *arg_index = glmsg.add_args();
+    arg_index->set_isarray(false);
+    arg_index->set_type(GLMessage::DataType::INT);
+    arg_index->add_intvalue(index);
+
+    // copy argument bufsize
+    GLMessage_DataType *arg_bufsize = glmsg.add_args();
+    arg_bufsize->set_isarray(false);
+    arg_bufsize->set_type(GLMessage::DataType::INT);
+    arg_bufsize->add_intvalue(bufsize);
+
+    // copy argument length
+    GLMessage_DataType *arg_length = glmsg.add_args();
+    arg_length->set_isarray(false);
+    arg_length->set_type(GLMessage::DataType::INT);
+    arg_length->add_intvalue((int)length);
+
+    // copy argument size
+    GLMessage_DataType *arg_size = glmsg.add_args();
+    arg_size->set_isarray(false);
+    arg_size->set_type(GLMessage::DataType::INT);
+    arg_size->add_intvalue((int)size);
+
+    // copy argument type
+    GLMessage_DataType *arg_type = glmsg.add_args();
+    arg_type->set_isarray(false);
+    arg_type->set_type(GLMessage::DataType::INT);
+    arg_type->add_intvalue((int)type);
+
+    // copy argument name
+    GLMessage_DataType *arg_name = glmsg.add_args();
+    arg_name->set_isarray(false);
+    arg_name->set_type(GLMessage::DataType::INT);
+    arg_name->add_intvalue((int)name);
+
+    // call function
+    glContext->hooks->gl.glGetActiveUniform(program, index, bufsize, length, size, type, name);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glGetAttachedShaders);
+
+    // copy argument program
+    GLMessage_DataType *arg_program = glmsg.add_args();
+    arg_program->set_isarray(false);
+    arg_program->set_type(GLMessage::DataType::INT);
+    arg_program->add_intvalue(program);
+
+    // copy argument maxcount
+    GLMessage_DataType *arg_maxcount = glmsg.add_args();
+    arg_maxcount->set_isarray(false);
+    arg_maxcount->set_type(GLMessage::DataType::INT);
+    arg_maxcount->add_intvalue(maxcount);
+
+    // copy argument count
+    GLMessage_DataType *arg_count = glmsg.add_args();
+    arg_count->set_isarray(false);
+    arg_count->set_type(GLMessage::DataType::INT);
+    arg_count->add_intvalue((int)count);
+
+    // copy argument shaders
+    GLMessage_DataType *arg_shaders = glmsg.add_args();
+    arg_shaders->set_isarray(false);
+    arg_shaders->set_type(GLMessage::DataType::INT);
+    arg_shaders->add_intvalue((int)shaders);
+
+    // call function
+    glContext->hooks->gl.glGetAttachedShaders(program, maxcount, count, shaders);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+int GLTrace_glGetAttribLocation(GLuint program, const GLchar* name) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glGetAttribLocation);
+
+    // copy argument program
+    GLMessage_DataType *arg_program = glmsg.add_args();
+    arg_program->set_isarray(false);
+    arg_program->set_type(GLMessage::DataType::INT);
+    arg_program->add_intvalue(program);
+
+    // copy argument name
+    GLMessage_DataType *arg_name = glmsg.add_args();
+    arg_name->set_isarray(false);
+    arg_name->set_type(GLMessage::DataType::INT);
+    arg_name->add_intvalue((int)name);
+
+    // call function
+    int retValue = glContext->hooks->gl.glGetAttribLocation(program, name);
+
+    // set return value
+    GLMessage_DataType *rt = glmsg.mutable_returnvalue();
+    rt->set_isarray(false);
+    rt->set_type(GLMessage::DataType::INT);
+    rt->add_intvalue(retValue);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+
+    return retValue;
+}
+
+void GLTrace_glGetBooleanv(GLenum pname, GLboolean* params) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glGetBooleanv);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument params
+    GLMessage_DataType *arg_params = glmsg.add_args();
+    arg_params->set_isarray(false);
+    arg_params->set_type(GLMessage::DataType::INT);
+    arg_params->add_intvalue((int)params);
+
+    // call function
+    glContext->hooks->gl.glGetBooleanv(pname, params);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glGetBufferParameteriv);
+
+    // copy argument target
+    GLMessage_DataType *arg_target = glmsg.add_args();
+    arg_target->set_isarray(false);
+    arg_target->set_type(GLMessage::DataType::ENUM);
+    arg_target->add_intvalue((int)target);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument params
+    GLMessage_DataType *arg_params = glmsg.add_args();
+    arg_params->set_isarray(false);
+    arg_params->set_type(GLMessage::DataType::INT);
+    arg_params->add_intvalue((int)params);
+
+    // call function
+    glContext->hooks->gl.glGetBufferParameteriv(target, pname, params);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+GLenum GLTrace_glGetError(void) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glGetError);
+
+    // call function
+    GLenum retValue = glContext->hooks->gl.glGetError();
+
+    // set return value
+    GLMessage_DataType *rt = glmsg.mutable_returnvalue();
+    rt->set_isarray(false);
+    rt->set_type(GLMessage::DataType::ENUM);
+    rt->add_intvalue((int)retValue);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+
+    return retValue;
+}
+
+void GLTrace_glGetFloatv(GLenum pname, GLfloat* params) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glGetFloatv);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument params
+    GLMessage_DataType *arg_params = glmsg.add_args();
+    arg_params->set_isarray(false);
+    arg_params->set_type(GLMessage::DataType::INT);
+    arg_params->add_intvalue((int)params);
+
+    // call function
+    glContext->hooks->gl.glGetFloatv(pname, params);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glGetFramebufferAttachmentParameteriv);
+
+    // copy argument target
+    GLMessage_DataType *arg_target = glmsg.add_args();
+    arg_target->set_isarray(false);
+    arg_target->set_type(GLMessage::DataType::ENUM);
+    arg_target->add_intvalue((int)target);
+
+    // copy argument attachment
+    GLMessage_DataType *arg_attachment = glmsg.add_args();
+    arg_attachment->set_isarray(false);
+    arg_attachment->set_type(GLMessage::DataType::ENUM);
+    arg_attachment->add_intvalue((int)attachment);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument params
+    GLMessage_DataType *arg_params = glmsg.add_args();
+    arg_params->set_isarray(false);
+    arg_params->set_type(GLMessage::DataType::INT);
+    arg_params->add_intvalue((int)params);
+
+    // call function
+    glContext->hooks->gl.glGetFramebufferAttachmentParameteriv(target, attachment, pname, params);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glGetIntegerv(GLenum pname, GLint* params) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glGetIntegerv);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument params
+    GLMessage_DataType *arg_params = glmsg.add_args();
+    arg_params->set_isarray(false);
+    arg_params->set_type(GLMessage::DataType::INT);
+    arg_params->add_intvalue((int)params);
+
+    // call function
+    glContext->hooks->gl.glGetIntegerv(pname, params);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glGetProgramiv(GLuint program, GLenum pname, GLint* params) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glGetProgramiv);
+
+    // copy argument program
+    GLMessage_DataType *arg_program = glmsg.add_args();
+    arg_program->set_isarray(false);
+    arg_program->set_type(GLMessage::DataType::INT);
+    arg_program->add_intvalue(program);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument params
+    GLMessage_DataType *arg_params = glmsg.add_args();
+    arg_params->set_isarray(false);
+    arg_params->set_type(GLMessage::DataType::INT);
+    arg_params->add_intvalue((int)params);
+
+    // call function
+    glContext->hooks->gl.glGetProgramiv(program, pname, params);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glGetProgramInfoLog);
+
+    // copy argument program
+    GLMessage_DataType *arg_program = glmsg.add_args();
+    arg_program->set_isarray(false);
+    arg_program->set_type(GLMessage::DataType::INT);
+    arg_program->add_intvalue(program);
+
+    // copy argument bufsize
+    GLMessage_DataType *arg_bufsize = glmsg.add_args();
+    arg_bufsize->set_isarray(false);
+    arg_bufsize->set_type(GLMessage::DataType::INT);
+    arg_bufsize->add_intvalue(bufsize);
+
+    // copy argument length
+    GLMessage_DataType *arg_length = glmsg.add_args();
+    arg_length->set_isarray(false);
+    arg_length->set_type(GLMessage::DataType::INT);
+    arg_length->add_intvalue((int)length);
+
+    // copy argument infolog
+    GLMessage_DataType *arg_infolog = glmsg.add_args();
+    arg_infolog->set_isarray(false);
+    arg_infolog->set_type(GLMessage::DataType::INT);
+    arg_infolog->add_intvalue((int)infolog);
+
+    // call function
+    glContext->hooks->gl.glGetProgramInfoLog(program, bufsize, length, infolog);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glGetRenderbufferParameteriv);
+
+    // copy argument target
+    GLMessage_DataType *arg_target = glmsg.add_args();
+    arg_target->set_isarray(false);
+    arg_target->set_type(GLMessage::DataType::ENUM);
+    arg_target->add_intvalue((int)target);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument params
+    GLMessage_DataType *arg_params = glmsg.add_args();
+    arg_params->set_isarray(false);
+    arg_params->set_type(GLMessage::DataType::INT);
+    arg_params->add_intvalue((int)params);
+
+    // call function
+    glContext->hooks->gl.glGetRenderbufferParameteriv(target, pname, params);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glGetShaderiv(GLuint shader, GLenum pname, GLint* params) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glGetShaderiv);
+
+    // copy argument shader
+    GLMessage_DataType *arg_shader = glmsg.add_args();
+    arg_shader->set_isarray(false);
+    arg_shader->set_type(GLMessage::DataType::INT);
+    arg_shader->add_intvalue(shader);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument params
+    GLMessage_DataType *arg_params = glmsg.add_args();
+    arg_params->set_isarray(false);
+    arg_params->set_type(GLMessage::DataType::INT);
+    arg_params->add_intvalue((int)params);
+
+    // call function
+    glContext->hooks->gl.glGetShaderiv(shader, pname, params);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glGetShaderInfoLog);
+
+    // copy argument shader
+    GLMessage_DataType *arg_shader = glmsg.add_args();
+    arg_shader->set_isarray(false);
+    arg_shader->set_type(GLMessage::DataType::INT);
+    arg_shader->add_intvalue(shader);
+
+    // copy argument bufsize
+    GLMessage_DataType *arg_bufsize = glmsg.add_args();
+    arg_bufsize->set_isarray(false);
+    arg_bufsize->set_type(GLMessage::DataType::INT);
+    arg_bufsize->add_intvalue(bufsize);
+
+    // copy argument length
+    GLMessage_DataType *arg_length = glmsg.add_args();
+    arg_length->set_isarray(false);
+    arg_length->set_type(GLMessage::DataType::INT);
+    arg_length->add_intvalue((int)length);
+
+    // copy argument infolog
+    GLMessage_DataType *arg_infolog = glmsg.add_args();
+    arg_infolog->set_isarray(false);
+    arg_infolog->set_type(GLMessage::DataType::INT);
+    arg_infolog->add_intvalue((int)infolog);
+
+    // call function
+    glContext->hooks->gl.glGetShaderInfoLog(shader, bufsize, length, infolog);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glGetShaderPrecisionFormat);
+
+    // copy argument shadertype
+    GLMessage_DataType *arg_shadertype = glmsg.add_args();
+    arg_shadertype->set_isarray(false);
+    arg_shadertype->set_type(GLMessage::DataType::ENUM);
+    arg_shadertype->add_intvalue((int)shadertype);
+
+    // copy argument precisiontype
+    GLMessage_DataType *arg_precisiontype = glmsg.add_args();
+    arg_precisiontype->set_isarray(false);
+    arg_precisiontype->set_type(GLMessage::DataType::ENUM);
+    arg_precisiontype->add_intvalue((int)precisiontype);
+
+    // copy argument range
+    GLMessage_DataType *arg_range = glmsg.add_args();
+    arg_range->set_isarray(false);
+    arg_range->set_type(GLMessage::DataType::INT);
+    arg_range->add_intvalue((int)range);
+
+    // copy argument precision
+    GLMessage_DataType *arg_precision = glmsg.add_args();
+    arg_precision->set_isarray(false);
+    arg_precision->set_type(GLMessage::DataType::INT);
+    arg_precision->add_intvalue((int)precision);
+
+    // call function
+    glContext->hooks->gl.glGetShaderPrecisionFormat(shadertype, precisiontype, range, precision);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glGetShaderSource);
+
+    // copy argument shader
+    GLMessage_DataType *arg_shader = glmsg.add_args();
+    arg_shader->set_isarray(false);
+    arg_shader->set_type(GLMessage::DataType::INT);
+    arg_shader->add_intvalue(shader);
+
+    // copy argument bufsize
+    GLMessage_DataType *arg_bufsize = glmsg.add_args();
+    arg_bufsize->set_isarray(false);
+    arg_bufsize->set_type(GLMessage::DataType::INT);
+    arg_bufsize->add_intvalue(bufsize);
+
+    // copy argument length
+    GLMessage_DataType *arg_length = glmsg.add_args();
+    arg_length->set_isarray(false);
+    arg_length->set_type(GLMessage::DataType::INT);
+    arg_length->add_intvalue((int)length);
+
+    // copy argument source
+    GLMessage_DataType *arg_source = glmsg.add_args();
+    arg_source->set_isarray(false);
+    arg_source->set_type(GLMessage::DataType::INT);
+    arg_source->add_intvalue((int)source);
+
+    // call function
+    glContext->hooks->gl.glGetShaderSource(shader, bufsize, length, source);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+const GLubyte* GLTrace_glGetString(GLenum name) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glGetString);
+
+    // copy argument name
+    GLMessage_DataType *arg_name = glmsg.add_args();
+    arg_name->set_isarray(false);
+    arg_name->set_type(GLMessage::DataType::ENUM);
+    arg_name->add_intvalue((int)name);
+
+    // call function
+    const GLubyte* retValue = glContext->hooks->gl.glGetString(name);
+
+    // set return value
+    GLMessage_DataType *rt = glmsg.mutable_returnvalue();
+    rt->set_isarray(false);
+    rt->set_type(GLMessage::DataType::INT);
+    rt->add_intvalue((int)retValue);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+
+    return retValue;
+}
+
+void GLTrace_glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glGetTexParameterfv);
+
+    // copy argument target
+    GLMessage_DataType *arg_target = glmsg.add_args();
+    arg_target->set_isarray(false);
+    arg_target->set_type(GLMessage::DataType::ENUM);
+    arg_target->add_intvalue((int)target);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument params
+    GLMessage_DataType *arg_params = glmsg.add_args();
+    arg_params->set_isarray(false);
+    arg_params->set_type(GLMessage::DataType::INT);
+    arg_params->add_intvalue((int)params);
+
+    // call function
+    glContext->hooks->gl.glGetTexParameterfv(target, pname, params);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glGetTexParameteriv(GLenum target, GLenum pname, GLint* params) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glGetTexParameteriv);
+
+    // copy argument target
+    GLMessage_DataType *arg_target = glmsg.add_args();
+    arg_target->set_isarray(false);
+    arg_target->set_type(GLMessage::DataType::ENUM);
+    arg_target->add_intvalue((int)target);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument params
+    GLMessage_DataType *arg_params = glmsg.add_args();
+    arg_params->set_isarray(false);
+    arg_params->set_type(GLMessage::DataType::INT);
+    arg_params->add_intvalue((int)params);
+
+    // call function
+    glContext->hooks->gl.glGetTexParameteriv(target, pname, params);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glGetUniformfv(GLuint program, GLint location, GLfloat* params) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glGetUniformfv);
+
+    // copy argument program
+    GLMessage_DataType *arg_program = glmsg.add_args();
+    arg_program->set_isarray(false);
+    arg_program->set_type(GLMessage::DataType::INT);
+    arg_program->add_intvalue(program);
+
+    // copy argument location
+    GLMessage_DataType *arg_location = glmsg.add_args();
+    arg_location->set_isarray(false);
+    arg_location->set_type(GLMessage::DataType::INT);
+    arg_location->add_intvalue(location);
+
+    // copy argument params
+    GLMessage_DataType *arg_params = glmsg.add_args();
+    arg_params->set_isarray(false);
+    arg_params->set_type(GLMessage::DataType::INT);
+    arg_params->add_intvalue((int)params);
+
+    // call function
+    glContext->hooks->gl.glGetUniformfv(program, location, params);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glGetUniformiv(GLuint program, GLint location, GLint* params) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glGetUniformiv);
+
+    // copy argument program
+    GLMessage_DataType *arg_program = glmsg.add_args();
+    arg_program->set_isarray(false);
+    arg_program->set_type(GLMessage::DataType::INT);
+    arg_program->add_intvalue(program);
+
+    // copy argument location
+    GLMessage_DataType *arg_location = glmsg.add_args();
+    arg_location->set_isarray(false);
+    arg_location->set_type(GLMessage::DataType::INT);
+    arg_location->add_intvalue(location);
+
+    // copy argument params
+    GLMessage_DataType *arg_params = glmsg.add_args();
+    arg_params->set_isarray(false);
+    arg_params->set_type(GLMessage::DataType::INT);
+    arg_params->add_intvalue((int)params);
+
+    // call function
+    glContext->hooks->gl.glGetUniformiv(program, location, params);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+int GLTrace_glGetUniformLocation(GLuint program, const GLchar* name) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glGetUniformLocation);
+
+    // copy argument program
+    GLMessage_DataType *arg_program = glmsg.add_args();
+    arg_program->set_isarray(false);
+    arg_program->set_type(GLMessage::DataType::INT);
+    arg_program->add_intvalue(program);
+
+    // copy argument name
+    GLMessage_DataType *arg_name = glmsg.add_args();
+    arg_name->set_isarray(false);
+    arg_name->set_type(GLMessage::DataType::INT);
+    arg_name->add_intvalue((int)name);
+
+    // call function
+    int retValue = glContext->hooks->gl.glGetUniformLocation(program, name);
+
+    // set return value
+    GLMessage_DataType *rt = glmsg.mutable_returnvalue();
+    rt->set_isarray(false);
+    rt->set_type(GLMessage::DataType::INT);
+    rt->add_intvalue(retValue);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+
+    return retValue;
+}
+
+void GLTrace_glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glGetVertexAttribfv);
+
+    // copy argument index
+    GLMessage_DataType *arg_index = glmsg.add_args();
+    arg_index->set_isarray(false);
+    arg_index->set_type(GLMessage::DataType::INT);
+    arg_index->add_intvalue(index);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument params
+    GLMessage_DataType *arg_params = glmsg.add_args();
+    arg_params->set_isarray(false);
+    arg_params->set_type(GLMessage::DataType::INT);
+    arg_params->add_intvalue((int)params);
+
+    // call function
+    glContext->hooks->gl.glGetVertexAttribfv(index, pname, params);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glGetVertexAttribiv);
+
+    // copy argument index
+    GLMessage_DataType *arg_index = glmsg.add_args();
+    arg_index->set_isarray(false);
+    arg_index->set_type(GLMessage::DataType::INT);
+    arg_index->add_intvalue(index);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument params
+    GLMessage_DataType *arg_params = glmsg.add_args();
+    arg_params->set_isarray(false);
+    arg_params->set_type(GLMessage::DataType::INT);
+    arg_params->add_intvalue((int)params);
+
+    // call function
+    glContext->hooks->gl.glGetVertexAttribiv(index, pname, params);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glGetVertexAttribPointerv);
+
+    // copy argument index
+    GLMessage_DataType *arg_index = glmsg.add_args();
+    arg_index->set_isarray(false);
+    arg_index->set_type(GLMessage::DataType::INT);
+    arg_index->add_intvalue(index);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument pointer
+    GLMessage_DataType *arg_pointer = glmsg.add_args();
+    arg_pointer->set_isarray(false);
+    arg_pointer->set_type(GLMessage::DataType::INT);
+    arg_pointer->add_intvalue((int)pointer);
+
+    // call function
+    glContext->hooks->gl.glGetVertexAttribPointerv(index, pname, pointer);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glHint(GLenum target, GLenum mode) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glHint);
+
+    // copy argument target
+    GLMessage_DataType *arg_target = glmsg.add_args();
+    arg_target->set_isarray(false);
+    arg_target->set_type(GLMessage::DataType::ENUM);
+    arg_target->add_intvalue((int)target);
+
+    // copy argument mode
+    GLMessage_DataType *arg_mode = glmsg.add_args();
+    arg_mode->set_isarray(false);
+    arg_mode->set_type(GLMessage::DataType::ENUM);
+    arg_mode->add_intvalue((int)mode);
+
+    // call function
+    glContext->hooks->gl.glHint(target, mode);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+GLboolean GLTrace_glIsBuffer(GLuint buffer) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glIsBuffer);
+
+    // copy argument buffer
+    GLMessage_DataType *arg_buffer = glmsg.add_args();
+    arg_buffer->set_isarray(false);
+    arg_buffer->set_type(GLMessage::DataType::INT);
+    arg_buffer->add_intvalue(buffer);
+
+    // call function
+    GLboolean retValue = glContext->hooks->gl.glIsBuffer(buffer);
+
+    // set return value
+    GLMessage_DataType *rt = glmsg.mutable_returnvalue();
+    rt->set_isarray(false);
+    rt->set_type(GLMessage::DataType::BOOL);
+    rt->add_boolvalue(retValue);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+
+    return retValue;
+}
+
+GLboolean GLTrace_glIsEnabled(GLenum cap) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glIsEnabled);
+
+    // copy argument cap
+    GLMessage_DataType *arg_cap = glmsg.add_args();
+    arg_cap->set_isarray(false);
+    arg_cap->set_type(GLMessage::DataType::ENUM);
+    arg_cap->add_intvalue((int)cap);
+
+    // call function
+    GLboolean retValue = glContext->hooks->gl.glIsEnabled(cap);
+
+    // set return value
+    GLMessage_DataType *rt = glmsg.mutable_returnvalue();
+    rt->set_isarray(false);
+    rt->set_type(GLMessage::DataType::BOOL);
+    rt->add_boolvalue(retValue);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+
+    return retValue;
+}
+
+GLboolean GLTrace_glIsFramebuffer(GLuint framebuffer) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glIsFramebuffer);
+
+    // copy argument framebuffer
+    GLMessage_DataType *arg_framebuffer = glmsg.add_args();
+    arg_framebuffer->set_isarray(false);
+    arg_framebuffer->set_type(GLMessage::DataType::INT);
+    arg_framebuffer->add_intvalue(framebuffer);
+
+    // call function
+    GLboolean retValue = glContext->hooks->gl.glIsFramebuffer(framebuffer);
+
+    // set return value
+    GLMessage_DataType *rt = glmsg.mutable_returnvalue();
+    rt->set_isarray(false);
+    rt->set_type(GLMessage::DataType::BOOL);
+    rt->add_boolvalue(retValue);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+
+    return retValue;
+}
+
+GLboolean GLTrace_glIsProgram(GLuint program) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glIsProgram);
+
+    // copy argument program
+    GLMessage_DataType *arg_program = glmsg.add_args();
+    arg_program->set_isarray(false);
+    arg_program->set_type(GLMessage::DataType::INT);
+    arg_program->add_intvalue(program);
+
+    // call function
+    GLboolean retValue = glContext->hooks->gl.glIsProgram(program);
+
+    // set return value
+    GLMessage_DataType *rt = glmsg.mutable_returnvalue();
+    rt->set_isarray(false);
+    rt->set_type(GLMessage::DataType::BOOL);
+    rt->add_boolvalue(retValue);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+
+    return retValue;
+}
+
+GLboolean GLTrace_glIsRenderbuffer(GLuint renderbuffer) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glIsRenderbuffer);
+
+    // copy argument renderbuffer
+    GLMessage_DataType *arg_renderbuffer = glmsg.add_args();
+    arg_renderbuffer->set_isarray(false);
+    arg_renderbuffer->set_type(GLMessage::DataType::INT);
+    arg_renderbuffer->add_intvalue(renderbuffer);
+
+    // call function
+    GLboolean retValue = glContext->hooks->gl.glIsRenderbuffer(renderbuffer);
+
+    // set return value
+    GLMessage_DataType *rt = glmsg.mutable_returnvalue();
+    rt->set_isarray(false);
+    rt->set_type(GLMessage::DataType::BOOL);
+    rt->add_boolvalue(retValue);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+
+    return retValue;
+}
+
+GLboolean GLTrace_glIsShader(GLuint shader) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glIsShader);
+
+    // copy argument shader
+    GLMessage_DataType *arg_shader = glmsg.add_args();
+    arg_shader->set_isarray(false);
+    arg_shader->set_type(GLMessage::DataType::INT);
+    arg_shader->add_intvalue(shader);
+
+    // call function
+    GLboolean retValue = glContext->hooks->gl.glIsShader(shader);
+
+    // set return value
+    GLMessage_DataType *rt = glmsg.mutable_returnvalue();
+    rt->set_isarray(false);
+    rt->set_type(GLMessage::DataType::BOOL);
+    rt->add_boolvalue(retValue);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+
+    return retValue;
+}
+
+GLboolean GLTrace_glIsTexture(GLuint texture) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glIsTexture);
+
+    // copy argument texture
+    GLMessage_DataType *arg_texture = glmsg.add_args();
+    arg_texture->set_isarray(false);
+    arg_texture->set_type(GLMessage::DataType::INT);
+    arg_texture->add_intvalue(texture);
+
+    // call function
+    GLboolean retValue = glContext->hooks->gl.glIsTexture(texture);
+
+    // set return value
+    GLMessage_DataType *rt = glmsg.mutable_returnvalue();
+    rt->set_isarray(false);
+    rt->set_type(GLMessage::DataType::BOOL);
+    rt->add_boolvalue(retValue);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+
+    return retValue;
+}
+
+void GLTrace_glLineWidth(GLfloat width) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glLineWidth);
+
+    // copy argument width
+    GLMessage_DataType *arg_width = glmsg.add_args();
+    arg_width->set_isarray(false);
+    arg_width->set_type(GLMessage::DataType::FLOAT);
+    arg_width->add_floatvalue(width);
+
+    // call function
+    glContext->hooks->gl.glLineWidth(width);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glLinkProgram(GLuint program) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glLinkProgram);
+
+    // copy argument program
+    GLMessage_DataType *arg_program = glmsg.add_args();
+    arg_program->set_isarray(false);
+    arg_program->set_type(GLMessage::DataType::INT);
+    arg_program->add_intvalue(program);
+
+    // call function
+    glContext->hooks->gl.glLinkProgram(program);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glPixelStorei(GLenum pname, GLint param) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glPixelStorei);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument param
+    GLMessage_DataType *arg_param = glmsg.add_args();
+    arg_param->set_isarray(false);
+    arg_param->set_type(GLMessage::DataType::INT);
+    arg_param->add_intvalue(param);
+
+    // call function
+    glContext->hooks->gl.glPixelStorei(pname, param);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glPolygonOffset(GLfloat factor, GLfloat units) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glPolygonOffset);
+
+    // copy argument factor
+    GLMessage_DataType *arg_factor = glmsg.add_args();
+    arg_factor->set_isarray(false);
+    arg_factor->set_type(GLMessage::DataType::FLOAT);
+    arg_factor->add_floatvalue(factor);
+
+    // copy argument units
+    GLMessage_DataType *arg_units = glmsg.add_args();
+    arg_units->set_isarray(false);
+    arg_units->set_type(GLMessage::DataType::FLOAT);
+    arg_units->add_floatvalue(units);
+
+    // call function
+    glContext->hooks->gl.glPolygonOffset(factor, units);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glReadPixels);
+
+    // copy argument x
+    GLMessage_DataType *arg_x = glmsg.add_args();
+    arg_x->set_isarray(false);
+    arg_x->set_type(GLMessage::DataType::INT);
+    arg_x->add_intvalue(x);
+
+    // copy argument y
+    GLMessage_DataType *arg_y = glmsg.add_args();
+    arg_y->set_isarray(false);
+    arg_y->set_type(GLMessage::DataType::INT);
+    arg_y->add_intvalue(y);
+
+    // copy argument width
+    GLMessage_DataType *arg_width = glmsg.add_args();
+    arg_width->set_isarray(false);
+    arg_width->set_type(GLMessage::DataType::INT);
+    arg_width->add_intvalue(width);
+
+    // copy argument height
+    GLMessage_DataType *arg_height = glmsg.add_args();
+    arg_height->set_isarray(false);
+    arg_height->set_type(GLMessage::DataType::INT);
+    arg_height->add_intvalue(height);
+
+    // copy argument format
+    GLMessage_DataType *arg_format = glmsg.add_args();
+    arg_format->set_isarray(false);
+    arg_format->set_type(GLMessage::DataType::ENUM);
+    arg_format->add_intvalue((int)format);
+
+    // copy argument type
+    GLMessage_DataType *arg_type = glmsg.add_args();
+    arg_type->set_isarray(false);
+    arg_type->set_type(GLMessage::DataType::ENUM);
+    arg_type->add_intvalue((int)type);
+
+    // copy argument pixels
+    GLMessage_DataType *arg_pixels = glmsg.add_args();
+    arg_pixels->set_isarray(false);
+    arg_pixels->set_type(GLMessage::DataType::INT);
+    arg_pixels->add_intvalue((int)pixels);
+
+    // call function
+    glContext->hooks->gl.glReadPixels(x, y, width, height, format, type, pixels);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glReleaseShaderCompiler(void) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glReleaseShaderCompiler);
+
+    // call function
+    glContext->hooks->gl.glReleaseShaderCompiler();
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glRenderbufferStorage);
+
+    // copy argument target
+    GLMessage_DataType *arg_target = glmsg.add_args();
+    arg_target->set_isarray(false);
+    arg_target->set_type(GLMessage::DataType::ENUM);
+    arg_target->add_intvalue((int)target);
+
+    // copy argument internalformat
+    GLMessage_DataType *arg_internalformat = glmsg.add_args();
+    arg_internalformat->set_isarray(false);
+    arg_internalformat->set_type(GLMessage::DataType::ENUM);
+    arg_internalformat->add_intvalue((int)internalformat);
+
+    // copy argument width
+    GLMessage_DataType *arg_width = glmsg.add_args();
+    arg_width->set_isarray(false);
+    arg_width->set_type(GLMessage::DataType::INT);
+    arg_width->add_intvalue(width);
+
+    // copy argument height
+    GLMessage_DataType *arg_height = glmsg.add_args();
+    arg_height->set_isarray(false);
+    arg_height->set_type(GLMessage::DataType::INT);
+    arg_height->add_intvalue(height);
+
+    // call function
+    glContext->hooks->gl.glRenderbufferStorage(target, internalformat, width, height);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glSampleCoverage(GLclampf value, GLboolean invert) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glSampleCoverage);
+
+    // copy argument value
+    GLMessage_DataType *arg_value = glmsg.add_args();
+    arg_value->set_isarray(false);
+    arg_value->set_type(GLMessage::DataType::FLOAT);
+    arg_value->add_floatvalue(value);
+
+    // copy argument invert
+    GLMessage_DataType *arg_invert = glmsg.add_args();
+    arg_invert->set_isarray(false);
+    arg_invert->set_type(GLMessage::DataType::BOOL);
+    arg_invert->add_boolvalue(invert);
+
+    // call function
+    glContext->hooks->gl.glSampleCoverage(value, invert);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glScissor(GLint x, GLint y, GLsizei width, GLsizei height) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glScissor);
+
+    // copy argument x
+    GLMessage_DataType *arg_x = glmsg.add_args();
+    arg_x->set_isarray(false);
+    arg_x->set_type(GLMessage::DataType::INT);
+    arg_x->add_intvalue(x);
+
+    // copy argument y
+    GLMessage_DataType *arg_y = glmsg.add_args();
+    arg_y->set_isarray(false);
+    arg_y->set_type(GLMessage::DataType::INT);
+    arg_y->add_intvalue(y);
+
+    // copy argument width
+    GLMessage_DataType *arg_width = glmsg.add_args();
+    arg_width->set_isarray(false);
+    arg_width->set_type(GLMessage::DataType::INT);
+    arg_width->add_intvalue(width);
+
+    // copy argument height
+    GLMessage_DataType *arg_height = glmsg.add_args();
+    arg_height->set_isarray(false);
+    arg_height->set_type(GLMessage::DataType::INT);
+    arg_height->add_intvalue(height);
+
+    // call function
+    glContext->hooks->gl.glScissor(x, y, width, height);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glShaderBinary);
+
+    // copy argument n
+    GLMessage_DataType *arg_n = glmsg.add_args();
+    arg_n->set_isarray(false);
+    arg_n->set_type(GLMessage::DataType::INT);
+    arg_n->add_intvalue(n);
+
+    // copy argument shaders
+    GLMessage_DataType *arg_shaders = glmsg.add_args();
+    arg_shaders->set_isarray(false);
+    arg_shaders->set_type(GLMessage::DataType::INT);
+    arg_shaders->add_intvalue((int)shaders);
+
+    // copy argument binaryformat
+    GLMessage_DataType *arg_binaryformat = glmsg.add_args();
+    arg_binaryformat->set_isarray(false);
+    arg_binaryformat->set_type(GLMessage::DataType::ENUM);
+    arg_binaryformat->add_intvalue((int)binaryformat);
+
+    // copy argument binary
+    GLMessage_DataType *arg_binary = glmsg.add_args();
+    arg_binary->set_isarray(false);
+    arg_binary->set_type(GLMessage::DataType::INT);
+    arg_binary->add_intvalue((int)binary);
+
+    // copy argument length
+    GLMessage_DataType *arg_length = glmsg.add_args();
+    arg_length->set_isarray(false);
+    arg_length->set_type(GLMessage::DataType::INT);
+    arg_length->add_intvalue(length);
+
+    // call function
+    glContext->hooks->gl.glShaderBinary(n, shaders, binaryformat, binary, length);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glShaderSource(GLuint shader, GLsizei count, const GLchar** string, const GLint* length) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glShaderSource);
+
+    // copy argument shader
+    GLMessage_DataType *arg_shader = glmsg.add_args();
+    arg_shader->set_isarray(false);
+    arg_shader->set_type(GLMessage::DataType::INT);
+    arg_shader->add_intvalue(shader);
+
+    // copy argument count
+    GLMessage_DataType *arg_count = glmsg.add_args();
+    arg_count->set_isarray(false);
+    arg_count->set_type(GLMessage::DataType::INT);
+    arg_count->add_intvalue(count);
+
+    // copy argument string
+    GLMessage_DataType *arg_string = glmsg.add_args();
+    arg_string->set_isarray(false);
+    arg_string->set_type(GLMessage::DataType::INT);
+    arg_string->add_intvalue((int)string);
+
+    // copy argument length
+    GLMessage_DataType *arg_length = glmsg.add_args();
+    arg_length->set_isarray(false);
+    arg_length->set_type(GLMessage::DataType::INT);
+    arg_length->add_intvalue((int)length);
+
+    // call function
+    glContext->hooks->gl.glShaderSource(shader, count, string, length);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glStencilFunc(GLenum func, GLint ref, GLuint mask) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glStencilFunc);
+
+    // copy argument func
+    GLMessage_DataType *arg_func = glmsg.add_args();
+    arg_func->set_isarray(false);
+    arg_func->set_type(GLMessage::DataType::ENUM);
+    arg_func->add_intvalue((int)func);
+
+    // copy argument ref
+    GLMessage_DataType *arg_ref = glmsg.add_args();
+    arg_ref->set_isarray(false);
+    arg_ref->set_type(GLMessage::DataType::INT);
+    arg_ref->add_intvalue(ref);
+
+    // copy argument mask
+    GLMessage_DataType *arg_mask = glmsg.add_args();
+    arg_mask->set_isarray(false);
+    arg_mask->set_type(GLMessage::DataType::INT);
+    arg_mask->add_intvalue(mask);
+
+    // call function
+    glContext->hooks->gl.glStencilFunc(func, ref, mask);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glStencilFuncSeparate);
+
+    // copy argument face
+    GLMessage_DataType *arg_face = glmsg.add_args();
+    arg_face->set_isarray(false);
+    arg_face->set_type(GLMessage::DataType::ENUM);
+    arg_face->add_intvalue((int)face);
+
+    // copy argument func
+    GLMessage_DataType *arg_func = glmsg.add_args();
+    arg_func->set_isarray(false);
+    arg_func->set_type(GLMessage::DataType::ENUM);
+    arg_func->add_intvalue((int)func);
+
+    // copy argument ref
+    GLMessage_DataType *arg_ref = glmsg.add_args();
+    arg_ref->set_isarray(false);
+    arg_ref->set_type(GLMessage::DataType::INT);
+    arg_ref->add_intvalue(ref);
+
+    // copy argument mask
+    GLMessage_DataType *arg_mask = glmsg.add_args();
+    arg_mask->set_isarray(false);
+    arg_mask->set_type(GLMessage::DataType::INT);
+    arg_mask->add_intvalue(mask);
+
+    // call function
+    glContext->hooks->gl.glStencilFuncSeparate(face, func, ref, mask);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glStencilMask(GLuint mask) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glStencilMask);
+
+    // copy argument mask
+    GLMessage_DataType *arg_mask = glmsg.add_args();
+    arg_mask->set_isarray(false);
+    arg_mask->set_type(GLMessage::DataType::INT);
+    arg_mask->add_intvalue(mask);
+
+    // call function
+    glContext->hooks->gl.glStencilMask(mask);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glStencilMaskSeparate(GLenum face, GLuint mask) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glStencilMaskSeparate);
+
+    // copy argument face
+    GLMessage_DataType *arg_face = glmsg.add_args();
+    arg_face->set_isarray(false);
+    arg_face->set_type(GLMessage::DataType::ENUM);
+    arg_face->add_intvalue((int)face);
+
+    // copy argument mask
+    GLMessage_DataType *arg_mask = glmsg.add_args();
+    arg_mask->set_isarray(false);
+    arg_mask->set_type(GLMessage::DataType::INT);
+    arg_mask->add_intvalue(mask);
+
+    // call function
+    glContext->hooks->gl.glStencilMaskSeparate(face, mask);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glStencilOp(GLenum fail, GLenum zfail, GLenum zpass) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glStencilOp);
+
+    // copy argument fail
+    GLMessage_DataType *arg_fail = glmsg.add_args();
+    arg_fail->set_isarray(false);
+    arg_fail->set_type(GLMessage::DataType::ENUM);
+    arg_fail->add_intvalue((int)fail);
+
+    // copy argument zfail
+    GLMessage_DataType *arg_zfail = glmsg.add_args();
+    arg_zfail->set_isarray(false);
+    arg_zfail->set_type(GLMessage::DataType::ENUM);
+    arg_zfail->add_intvalue((int)zfail);
+
+    // copy argument zpass
+    GLMessage_DataType *arg_zpass = glmsg.add_args();
+    arg_zpass->set_isarray(false);
+    arg_zpass->set_type(GLMessage::DataType::ENUM);
+    arg_zpass->add_intvalue((int)zpass);
+
+    // call function
+    glContext->hooks->gl.glStencilOp(fail, zfail, zpass);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glStencilOpSeparate);
+
+    // copy argument face
+    GLMessage_DataType *arg_face = glmsg.add_args();
+    arg_face->set_isarray(false);
+    arg_face->set_type(GLMessage::DataType::ENUM);
+    arg_face->add_intvalue((int)face);
+
+    // copy argument fail
+    GLMessage_DataType *arg_fail = glmsg.add_args();
+    arg_fail->set_isarray(false);
+    arg_fail->set_type(GLMessage::DataType::ENUM);
+    arg_fail->add_intvalue((int)fail);
+
+    // copy argument zfail
+    GLMessage_DataType *arg_zfail = glmsg.add_args();
+    arg_zfail->set_isarray(false);
+    arg_zfail->set_type(GLMessage::DataType::ENUM);
+    arg_zfail->add_intvalue((int)zfail);
+
+    // copy argument zpass
+    GLMessage_DataType *arg_zpass = glmsg.add_args();
+    arg_zpass->set_isarray(false);
+    arg_zpass->set_type(GLMessage::DataType::ENUM);
+    arg_zpass->add_intvalue((int)zpass);
+
+    // call function
+    glContext->hooks->gl.glStencilOpSeparate(face, fail, zfail, zpass);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid* pixels) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glTexImage2D);
+
+    // copy argument target
+    GLMessage_DataType *arg_target = glmsg.add_args();
+    arg_target->set_isarray(false);
+    arg_target->set_type(GLMessage::DataType::ENUM);
+    arg_target->add_intvalue((int)target);
+
+    // copy argument level
+    GLMessage_DataType *arg_level = glmsg.add_args();
+    arg_level->set_isarray(false);
+    arg_level->set_type(GLMessage::DataType::INT);
+    arg_level->add_intvalue(level);
+
+    // copy argument internalformat
+    GLMessage_DataType *arg_internalformat = glmsg.add_args();
+    arg_internalformat->set_isarray(false);
+    arg_internalformat->set_type(GLMessage::DataType::INT);
+    arg_internalformat->add_intvalue(internalformat);
+
+    // copy argument width
+    GLMessage_DataType *arg_width = glmsg.add_args();
+    arg_width->set_isarray(false);
+    arg_width->set_type(GLMessage::DataType::INT);
+    arg_width->add_intvalue(width);
+
+    // copy argument height
+    GLMessage_DataType *arg_height = glmsg.add_args();
+    arg_height->set_isarray(false);
+    arg_height->set_type(GLMessage::DataType::INT);
+    arg_height->add_intvalue(height);
+
+    // copy argument border
+    GLMessage_DataType *arg_border = glmsg.add_args();
+    arg_border->set_isarray(false);
+    arg_border->set_type(GLMessage::DataType::INT);
+    arg_border->add_intvalue(border);
+
+    // copy argument format
+    GLMessage_DataType *arg_format = glmsg.add_args();
+    arg_format->set_isarray(false);
+    arg_format->set_type(GLMessage::DataType::ENUM);
+    arg_format->add_intvalue((int)format);
+
+    // copy argument type
+    GLMessage_DataType *arg_type = glmsg.add_args();
+    arg_type->set_isarray(false);
+    arg_type->set_type(GLMessage::DataType::ENUM);
+    arg_type->add_intvalue((int)type);
+
+    // copy argument pixels
+    GLMessage_DataType *arg_pixels = glmsg.add_args();
+    arg_pixels->set_isarray(false);
+    arg_pixels->set_type(GLMessage::DataType::INT);
+    arg_pixels->add_intvalue((int)pixels);
+
+    // call function
+    glContext->hooks->gl.glTexImage2D(target, level, internalformat, width, height, border, format, type, pixels);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glTexParameterf(GLenum target, GLenum pname, GLfloat param) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glTexParameterf);
+
+    // copy argument target
+    GLMessage_DataType *arg_target = glmsg.add_args();
+    arg_target->set_isarray(false);
+    arg_target->set_type(GLMessage::DataType::ENUM);
+    arg_target->add_intvalue((int)target);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument param
+    GLMessage_DataType *arg_param = glmsg.add_args();
+    arg_param->set_isarray(false);
+    arg_param->set_type(GLMessage::DataType::FLOAT);
+    arg_param->add_floatvalue(param);
+
+    // call function
+    glContext->hooks->gl.glTexParameterf(target, pname, param);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glTexParameterfv);
+
+    // copy argument target
+    GLMessage_DataType *arg_target = glmsg.add_args();
+    arg_target->set_isarray(false);
+    arg_target->set_type(GLMessage::DataType::ENUM);
+    arg_target->add_intvalue((int)target);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument params
+    GLMessage_DataType *arg_params = glmsg.add_args();
+    arg_params->set_isarray(false);
+    arg_params->set_type(GLMessage::DataType::INT);
+    arg_params->add_intvalue((int)params);
+
+    // call function
+    glContext->hooks->gl.glTexParameterfv(target, pname, params);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glTexParameteri(GLenum target, GLenum pname, GLint param) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glTexParameteri);
+
+    // copy argument target
+    GLMessage_DataType *arg_target = glmsg.add_args();
+    arg_target->set_isarray(false);
+    arg_target->set_type(GLMessage::DataType::ENUM);
+    arg_target->add_intvalue((int)target);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument param
+    GLMessage_DataType *arg_param = glmsg.add_args();
+    arg_param->set_isarray(false);
+    arg_param->set_type(GLMessage::DataType::INT);
+    arg_param->add_intvalue(param);
+
+    // call function
+    glContext->hooks->gl.glTexParameteri(target, pname, param);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glTexParameteriv(GLenum target, GLenum pname, const GLint* params) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glTexParameteriv);
+
+    // copy argument target
+    GLMessage_DataType *arg_target = glmsg.add_args();
+    arg_target->set_isarray(false);
+    arg_target->set_type(GLMessage::DataType::ENUM);
+    arg_target->add_intvalue((int)target);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument params
+    GLMessage_DataType *arg_params = glmsg.add_args();
+    arg_params->set_isarray(false);
+    arg_params->set_type(GLMessage::DataType::INT);
+    arg_params->add_intvalue((int)params);
+
+    // call function
+    glContext->hooks->gl.glTexParameteriv(target, pname, params);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid* pixels) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glTexSubImage2D);
+
+    // copy argument target
+    GLMessage_DataType *arg_target = glmsg.add_args();
+    arg_target->set_isarray(false);
+    arg_target->set_type(GLMessage::DataType::ENUM);
+    arg_target->add_intvalue((int)target);
+
+    // copy argument level
+    GLMessage_DataType *arg_level = glmsg.add_args();
+    arg_level->set_isarray(false);
+    arg_level->set_type(GLMessage::DataType::INT);
+    arg_level->add_intvalue(level);
+
+    // copy argument xoffset
+    GLMessage_DataType *arg_xoffset = glmsg.add_args();
+    arg_xoffset->set_isarray(false);
+    arg_xoffset->set_type(GLMessage::DataType::INT);
+    arg_xoffset->add_intvalue(xoffset);
+
+    // copy argument yoffset
+    GLMessage_DataType *arg_yoffset = glmsg.add_args();
+    arg_yoffset->set_isarray(false);
+    arg_yoffset->set_type(GLMessage::DataType::INT);
+    arg_yoffset->add_intvalue(yoffset);
+
+    // copy argument width
+    GLMessage_DataType *arg_width = glmsg.add_args();
+    arg_width->set_isarray(false);
+    arg_width->set_type(GLMessage::DataType::INT);
+    arg_width->add_intvalue(width);
+
+    // copy argument height
+    GLMessage_DataType *arg_height = glmsg.add_args();
+    arg_height->set_isarray(false);
+    arg_height->set_type(GLMessage::DataType::INT);
+    arg_height->add_intvalue(height);
+
+    // copy argument format
+    GLMessage_DataType *arg_format = glmsg.add_args();
+    arg_format->set_isarray(false);
+    arg_format->set_type(GLMessage::DataType::ENUM);
+    arg_format->add_intvalue((int)format);
+
+    // copy argument type
+    GLMessage_DataType *arg_type = glmsg.add_args();
+    arg_type->set_isarray(false);
+    arg_type->set_type(GLMessage::DataType::ENUM);
+    arg_type->add_intvalue((int)type);
+
+    // copy argument pixels
+    GLMessage_DataType *arg_pixels = glmsg.add_args();
+    arg_pixels->set_isarray(false);
+    arg_pixels->set_type(GLMessage::DataType::INT);
+    arg_pixels->add_intvalue((int)pixels);
+
+    // call function
+    glContext->hooks->gl.glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glUniform1f(GLint location, GLfloat x) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glUniform1f);
+
+    // copy argument location
+    GLMessage_DataType *arg_location = glmsg.add_args();
+    arg_location->set_isarray(false);
+    arg_location->set_type(GLMessage::DataType::INT);
+    arg_location->add_intvalue(location);
+
+    // copy argument x
+    GLMessage_DataType *arg_x = glmsg.add_args();
+    arg_x->set_isarray(false);
+    arg_x->set_type(GLMessage::DataType::FLOAT);
+    arg_x->add_floatvalue(x);
+
+    // call function
+    glContext->hooks->gl.glUniform1f(location, x);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glUniform1fv(GLint location, GLsizei count, const GLfloat* v) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glUniform1fv);
+
+    // copy argument location
+    GLMessage_DataType *arg_location = glmsg.add_args();
+    arg_location->set_isarray(false);
+    arg_location->set_type(GLMessage::DataType::INT);
+    arg_location->add_intvalue(location);
+
+    // copy argument count
+    GLMessage_DataType *arg_count = glmsg.add_args();
+    arg_count->set_isarray(false);
+    arg_count->set_type(GLMessage::DataType::INT);
+    arg_count->add_intvalue(count);
+
+    // copy argument v
+    GLMessage_DataType *arg_v = glmsg.add_args();
+    arg_v->set_isarray(false);
+    arg_v->set_type(GLMessage::DataType::INT);
+    arg_v->add_intvalue((int)v);
+
+    // call function
+    glContext->hooks->gl.glUniform1fv(location, count, v);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glUniform1i(GLint location, GLint x) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glUniform1i);
+
+    // copy argument location
+    GLMessage_DataType *arg_location = glmsg.add_args();
+    arg_location->set_isarray(false);
+    arg_location->set_type(GLMessage::DataType::INT);
+    arg_location->add_intvalue(location);
+
+    // copy argument x
+    GLMessage_DataType *arg_x = glmsg.add_args();
+    arg_x->set_isarray(false);
+    arg_x->set_type(GLMessage::DataType::INT);
+    arg_x->add_intvalue(x);
+
+    // call function
+    glContext->hooks->gl.glUniform1i(location, x);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glUniform1iv(GLint location, GLsizei count, const GLint* v) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glUniform1iv);
+
+    // copy argument location
+    GLMessage_DataType *arg_location = glmsg.add_args();
+    arg_location->set_isarray(false);
+    arg_location->set_type(GLMessage::DataType::INT);
+    arg_location->add_intvalue(location);
+
+    // copy argument count
+    GLMessage_DataType *arg_count = glmsg.add_args();
+    arg_count->set_isarray(false);
+    arg_count->set_type(GLMessage::DataType::INT);
+    arg_count->add_intvalue(count);
+
+    // copy argument v
+    GLMessage_DataType *arg_v = glmsg.add_args();
+    arg_v->set_isarray(false);
+    arg_v->set_type(GLMessage::DataType::INT);
+    arg_v->add_intvalue((int)v);
+
+    // call function
+    glContext->hooks->gl.glUniform1iv(location, count, v);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glUniform2f(GLint location, GLfloat x, GLfloat y) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glUniform2f);
+
+    // copy argument location
+    GLMessage_DataType *arg_location = glmsg.add_args();
+    arg_location->set_isarray(false);
+    arg_location->set_type(GLMessage::DataType::INT);
+    arg_location->add_intvalue(location);
+
+    // copy argument x
+    GLMessage_DataType *arg_x = glmsg.add_args();
+    arg_x->set_isarray(false);
+    arg_x->set_type(GLMessage::DataType::FLOAT);
+    arg_x->add_floatvalue(x);
+
+    // copy argument y
+    GLMessage_DataType *arg_y = glmsg.add_args();
+    arg_y->set_isarray(false);
+    arg_y->set_type(GLMessage::DataType::FLOAT);
+    arg_y->add_floatvalue(y);
+
+    // call function
+    glContext->hooks->gl.glUniform2f(location, x, y);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glUniform2fv(GLint location, GLsizei count, const GLfloat* v) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glUniform2fv);
+
+    // copy argument location
+    GLMessage_DataType *arg_location = glmsg.add_args();
+    arg_location->set_isarray(false);
+    arg_location->set_type(GLMessage::DataType::INT);
+    arg_location->add_intvalue(location);
+
+    // copy argument count
+    GLMessage_DataType *arg_count = glmsg.add_args();
+    arg_count->set_isarray(false);
+    arg_count->set_type(GLMessage::DataType::INT);
+    arg_count->add_intvalue(count);
+
+    // copy argument v
+    GLMessage_DataType *arg_v = glmsg.add_args();
+    arg_v->set_isarray(false);
+    arg_v->set_type(GLMessage::DataType::INT);
+    arg_v->add_intvalue((int)v);
+
+    // call function
+    glContext->hooks->gl.glUniform2fv(location, count, v);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glUniform2i(GLint location, GLint x, GLint y) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glUniform2i);
+
+    // copy argument location
+    GLMessage_DataType *arg_location = glmsg.add_args();
+    arg_location->set_isarray(false);
+    arg_location->set_type(GLMessage::DataType::INT);
+    arg_location->add_intvalue(location);
+
+    // copy argument x
+    GLMessage_DataType *arg_x = glmsg.add_args();
+    arg_x->set_isarray(false);
+    arg_x->set_type(GLMessage::DataType::INT);
+    arg_x->add_intvalue(x);
+
+    // copy argument y
+    GLMessage_DataType *arg_y = glmsg.add_args();
+    arg_y->set_isarray(false);
+    arg_y->set_type(GLMessage::DataType::INT);
+    arg_y->add_intvalue(y);
+
+    // call function
+    glContext->hooks->gl.glUniform2i(location, x, y);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glUniform2iv(GLint location, GLsizei count, const GLint* v) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glUniform2iv);
+
+    // copy argument location
+    GLMessage_DataType *arg_location = glmsg.add_args();
+    arg_location->set_isarray(false);
+    arg_location->set_type(GLMessage::DataType::INT);
+    arg_location->add_intvalue(location);
+
+    // copy argument count
+    GLMessage_DataType *arg_count = glmsg.add_args();
+    arg_count->set_isarray(false);
+    arg_count->set_type(GLMessage::DataType::INT);
+    arg_count->add_intvalue(count);
+
+    // copy argument v
+    GLMessage_DataType *arg_v = glmsg.add_args();
+    arg_v->set_isarray(false);
+    arg_v->set_type(GLMessage::DataType::INT);
+    arg_v->add_intvalue((int)v);
+
+    // call function
+    glContext->hooks->gl.glUniform2iv(location, count, v);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glUniform3f);
+
+    // copy argument location
+    GLMessage_DataType *arg_location = glmsg.add_args();
+    arg_location->set_isarray(false);
+    arg_location->set_type(GLMessage::DataType::INT);
+    arg_location->add_intvalue(location);
+
+    // copy argument x
+    GLMessage_DataType *arg_x = glmsg.add_args();
+    arg_x->set_isarray(false);
+    arg_x->set_type(GLMessage::DataType::FLOAT);
+    arg_x->add_floatvalue(x);
+
+    // copy argument y
+    GLMessage_DataType *arg_y = glmsg.add_args();
+    arg_y->set_isarray(false);
+    arg_y->set_type(GLMessage::DataType::FLOAT);
+    arg_y->add_floatvalue(y);
+
+    // copy argument z
+    GLMessage_DataType *arg_z = glmsg.add_args();
+    arg_z->set_isarray(false);
+    arg_z->set_type(GLMessage::DataType::FLOAT);
+    arg_z->add_floatvalue(z);
+
+    // call function
+    glContext->hooks->gl.glUniform3f(location, x, y, z);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glUniform3fv(GLint location, GLsizei count, const GLfloat* v) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glUniform3fv);
+
+    // copy argument location
+    GLMessage_DataType *arg_location = glmsg.add_args();
+    arg_location->set_isarray(false);
+    arg_location->set_type(GLMessage::DataType::INT);
+    arg_location->add_intvalue(location);
+
+    // copy argument count
+    GLMessage_DataType *arg_count = glmsg.add_args();
+    arg_count->set_isarray(false);
+    arg_count->set_type(GLMessage::DataType::INT);
+    arg_count->add_intvalue(count);
+
+    // copy argument v
+    GLMessage_DataType *arg_v = glmsg.add_args();
+    arg_v->set_isarray(false);
+    arg_v->set_type(GLMessage::DataType::INT);
+    arg_v->add_intvalue((int)v);
+
+    // call function
+    glContext->hooks->gl.glUniform3fv(location, count, v);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glUniform3i(GLint location, GLint x, GLint y, GLint z) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glUniform3i);
+
+    // copy argument location
+    GLMessage_DataType *arg_location = glmsg.add_args();
+    arg_location->set_isarray(false);
+    arg_location->set_type(GLMessage::DataType::INT);
+    arg_location->add_intvalue(location);
+
+    // copy argument x
+    GLMessage_DataType *arg_x = glmsg.add_args();
+    arg_x->set_isarray(false);
+    arg_x->set_type(GLMessage::DataType::INT);
+    arg_x->add_intvalue(x);
+
+    // copy argument y
+    GLMessage_DataType *arg_y = glmsg.add_args();
+    arg_y->set_isarray(false);
+    arg_y->set_type(GLMessage::DataType::INT);
+    arg_y->add_intvalue(y);
+
+    // copy argument z
+    GLMessage_DataType *arg_z = glmsg.add_args();
+    arg_z->set_isarray(false);
+    arg_z->set_type(GLMessage::DataType::INT);
+    arg_z->add_intvalue(z);
+
+    // call function
+    glContext->hooks->gl.glUniform3i(location, x, y, z);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glUniform3iv(GLint location, GLsizei count, const GLint* v) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glUniform3iv);
+
+    // copy argument location
+    GLMessage_DataType *arg_location = glmsg.add_args();
+    arg_location->set_isarray(false);
+    arg_location->set_type(GLMessage::DataType::INT);
+    arg_location->add_intvalue(location);
+
+    // copy argument count
+    GLMessage_DataType *arg_count = glmsg.add_args();
+    arg_count->set_isarray(false);
+    arg_count->set_type(GLMessage::DataType::INT);
+    arg_count->add_intvalue(count);
+
+    // copy argument v
+    GLMessage_DataType *arg_v = glmsg.add_args();
+    arg_v->set_isarray(false);
+    arg_v->set_type(GLMessage::DataType::INT);
+    arg_v->add_intvalue((int)v);
+
+    // call function
+    glContext->hooks->gl.glUniform3iv(location, count, v);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glUniform4f);
+
+    // copy argument location
+    GLMessage_DataType *arg_location = glmsg.add_args();
+    arg_location->set_isarray(false);
+    arg_location->set_type(GLMessage::DataType::INT);
+    arg_location->add_intvalue(location);
+
+    // copy argument x
+    GLMessage_DataType *arg_x = glmsg.add_args();
+    arg_x->set_isarray(false);
+    arg_x->set_type(GLMessage::DataType::FLOAT);
+    arg_x->add_floatvalue(x);
+
+    // copy argument y
+    GLMessage_DataType *arg_y = glmsg.add_args();
+    arg_y->set_isarray(false);
+    arg_y->set_type(GLMessage::DataType::FLOAT);
+    arg_y->add_floatvalue(y);
+
+    // copy argument z
+    GLMessage_DataType *arg_z = glmsg.add_args();
+    arg_z->set_isarray(false);
+    arg_z->set_type(GLMessage::DataType::FLOAT);
+    arg_z->add_floatvalue(z);
+
+    // copy argument w
+    GLMessage_DataType *arg_w = glmsg.add_args();
+    arg_w->set_isarray(false);
+    arg_w->set_type(GLMessage::DataType::FLOAT);
+    arg_w->add_floatvalue(w);
+
+    // call function
+    glContext->hooks->gl.glUniform4f(location, x, y, z, w);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glUniform4fv(GLint location, GLsizei count, const GLfloat* v) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glUniform4fv);
+
+    // copy argument location
+    GLMessage_DataType *arg_location = glmsg.add_args();
+    arg_location->set_isarray(false);
+    arg_location->set_type(GLMessage::DataType::INT);
+    arg_location->add_intvalue(location);
+
+    // copy argument count
+    GLMessage_DataType *arg_count = glmsg.add_args();
+    arg_count->set_isarray(false);
+    arg_count->set_type(GLMessage::DataType::INT);
+    arg_count->add_intvalue(count);
+
+    // copy argument v
+    GLMessage_DataType *arg_v = glmsg.add_args();
+    arg_v->set_isarray(false);
+    arg_v->set_type(GLMessage::DataType::INT);
+    arg_v->add_intvalue((int)v);
+
+    // call function
+    glContext->hooks->gl.glUniform4fv(location, count, v);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glUniform4i);
+
+    // copy argument location
+    GLMessage_DataType *arg_location = glmsg.add_args();
+    arg_location->set_isarray(false);
+    arg_location->set_type(GLMessage::DataType::INT);
+    arg_location->add_intvalue(location);
+
+    // copy argument x
+    GLMessage_DataType *arg_x = glmsg.add_args();
+    arg_x->set_isarray(false);
+    arg_x->set_type(GLMessage::DataType::INT);
+    arg_x->add_intvalue(x);
+
+    // copy argument y
+    GLMessage_DataType *arg_y = glmsg.add_args();
+    arg_y->set_isarray(false);
+    arg_y->set_type(GLMessage::DataType::INT);
+    arg_y->add_intvalue(y);
+
+    // copy argument z
+    GLMessage_DataType *arg_z = glmsg.add_args();
+    arg_z->set_isarray(false);
+    arg_z->set_type(GLMessage::DataType::INT);
+    arg_z->add_intvalue(z);
+
+    // copy argument w
+    GLMessage_DataType *arg_w = glmsg.add_args();
+    arg_w->set_isarray(false);
+    arg_w->set_type(GLMessage::DataType::INT);
+    arg_w->add_intvalue(w);
+
+    // call function
+    glContext->hooks->gl.glUniform4i(location, x, y, z, w);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glUniform4iv(GLint location, GLsizei count, const GLint* v) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glUniform4iv);
+
+    // copy argument location
+    GLMessage_DataType *arg_location = glmsg.add_args();
+    arg_location->set_isarray(false);
+    arg_location->set_type(GLMessage::DataType::INT);
+    arg_location->add_intvalue(location);
+
+    // copy argument count
+    GLMessage_DataType *arg_count = glmsg.add_args();
+    arg_count->set_isarray(false);
+    arg_count->set_type(GLMessage::DataType::INT);
+    arg_count->add_intvalue(count);
+
+    // copy argument v
+    GLMessage_DataType *arg_v = glmsg.add_args();
+    arg_v->set_isarray(false);
+    arg_v->set_type(GLMessage::DataType::INT);
+    arg_v->add_intvalue((int)v);
+
+    // call function
+    glContext->hooks->gl.glUniform4iv(location, count, v);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glUniformMatrix2fv);
+
+    // copy argument location
+    GLMessage_DataType *arg_location = glmsg.add_args();
+    arg_location->set_isarray(false);
+    arg_location->set_type(GLMessage::DataType::INT);
+    arg_location->add_intvalue(location);
+
+    // copy argument count
+    GLMessage_DataType *arg_count = glmsg.add_args();
+    arg_count->set_isarray(false);
+    arg_count->set_type(GLMessage::DataType::INT);
+    arg_count->add_intvalue(count);
+
+    // copy argument transpose
+    GLMessage_DataType *arg_transpose = glmsg.add_args();
+    arg_transpose->set_isarray(false);
+    arg_transpose->set_type(GLMessage::DataType::BOOL);
+    arg_transpose->add_boolvalue(transpose);
+
+    // copy argument value
+    GLMessage_DataType *arg_value = glmsg.add_args();
+    arg_value->set_isarray(false);
+    arg_value->set_type(GLMessage::DataType::INT);
+    arg_value->add_intvalue((int)value);
+
+    // call function
+    glContext->hooks->gl.glUniformMatrix2fv(location, count, transpose, value);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glUniformMatrix3fv);
+
+    // copy argument location
+    GLMessage_DataType *arg_location = glmsg.add_args();
+    arg_location->set_isarray(false);
+    arg_location->set_type(GLMessage::DataType::INT);
+    arg_location->add_intvalue(location);
+
+    // copy argument count
+    GLMessage_DataType *arg_count = glmsg.add_args();
+    arg_count->set_isarray(false);
+    arg_count->set_type(GLMessage::DataType::INT);
+    arg_count->add_intvalue(count);
+
+    // copy argument transpose
+    GLMessage_DataType *arg_transpose = glmsg.add_args();
+    arg_transpose->set_isarray(false);
+    arg_transpose->set_type(GLMessage::DataType::BOOL);
+    arg_transpose->add_boolvalue(transpose);
+
+    // copy argument value
+    GLMessage_DataType *arg_value = glmsg.add_args();
+    arg_value->set_isarray(false);
+    arg_value->set_type(GLMessage::DataType::INT);
+    arg_value->add_intvalue((int)value);
+
+    // call function
+    glContext->hooks->gl.glUniformMatrix3fv(location, count, transpose, value);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glUniformMatrix4fv);
+
+    // copy argument location
+    GLMessage_DataType *arg_location = glmsg.add_args();
+    arg_location->set_isarray(false);
+    arg_location->set_type(GLMessage::DataType::INT);
+    arg_location->add_intvalue(location);
+
+    // copy argument count
+    GLMessage_DataType *arg_count = glmsg.add_args();
+    arg_count->set_isarray(false);
+    arg_count->set_type(GLMessage::DataType::INT);
+    arg_count->add_intvalue(count);
+
+    // copy argument transpose
+    GLMessage_DataType *arg_transpose = glmsg.add_args();
+    arg_transpose->set_isarray(false);
+    arg_transpose->set_type(GLMessage::DataType::BOOL);
+    arg_transpose->add_boolvalue(transpose);
+
+    // copy argument value
+    GLMessage_DataType *arg_value = glmsg.add_args();
+    arg_value->set_isarray(false);
+    arg_value->set_type(GLMessage::DataType::INT);
+    arg_value->add_intvalue((int)value);
+
+    // call function
+    glContext->hooks->gl.glUniformMatrix4fv(location, count, transpose, value);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glUseProgram(GLuint program) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glUseProgram);
+
+    // copy argument program
+    GLMessage_DataType *arg_program = glmsg.add_args();
+    arg_program->set_isarray(false);
+    arg_program->set_type(GLMessage::DataType::INT);
+    arg_program->add_intvalue(program);
+
+    // call function
+    glContext->hooks->gl.glUseProgram(program);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glValidateProgram(GLuint program) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glValidateProgram);
+
+    // copy argument program
+    GLMessage_DataType *arg_program = glmsg.add_args();
+    arg_program->set_isarray(false);
+    arg_program->set_type(GLMessage::DataType::INT);
+    arg_program->add_intvalue(program);
+
+    // call function
+    glContext->hooks->gl.glValidateProgram(program);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glVertexAttrib1f(GLuint indx, GLfloat x) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glVertexAttrib1f);
+
+    // copy argument indx
+    GLMessage_DataType *arg_indx = glmsg.add_args();
+    arg_indx->set_isarray(false);
+    arg_indx->set_type(GLMessage::DataType::INT);
+    arg_indx->add_intvalue(indx);
+
+    // copy argument x
+    GLMessage_DataType *arg_x = glmsg.add_args();
+    arg_x->set_isarray(false);
+    arg_x->set_type(GLMessage::DataType::FLOAT);
+    arg_x->add_floatvalue(x);
+
+    // call function
+    glContext->hooks->gl.glVertexAttrib1f(indx, x);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glVertexAttrib1fv(GLuint indx, const GLfloat* values) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glVertexAttrib1fv);
+
+    // copy argument indx
+    GLMessage_DataType *arg_indx = glmsg.add_args();
+    arg_indx->set_isarray(false);
+    arg_indx->set_type(GLMessage::DataType::INT);
+    arg_indx->add_intvalue(indx);
+
+    // copy argument values
+    GLMessage_DataType *arg_values = glmsg.add_args();
+    arg_values->set_isarray(false);
+    arg_values->set_type(GLMessage::DataType::INT);
+    arg_values->add_intvalue((int)values);
+
+    // call function
+    glContext->hooks->gl.glVertexAttrib1fv(indx, values);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glVertexAttrib2f(GLuint indx, GLfloat x, GLfloat y) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glVertexAttrib2f);
+
+    // copy argument indx
+    GLMessage_DataType *arg_indx = glmsg.add_args();
+    arg_indx->set_isarray(false);
+    arg_indx->set_type(GLMessage::DataType::INT);
+    arg_indx->add_intvalue(indx);
+
+    // copy argument x
+    GLMessage_DataType *arg_x = glmsg.add_args();
+    arg_x->set_isarray(false);
+    arg_x->set_type(GLMessage::DataType::FLOAT);
+    arg_x->add_floatvalue(x);
+
+    // copy argument y
+    GLMessage_DataType *arg_y = glmsg.add_args();
+    arg_y->set_isarray(false);
+    arg_y->set_type(GLMessage::DataType::FLOAT);
+    arg_y->add_floatvalue(y);
+
+    // call function
+    glContext->hooks->gl.glVertexAttrib2f(indx, x, y);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glVertexAttrib2fv(GLuint indx, const GLfloat* values) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glVertexAttrib2fv);
+
+    // copy argument indx
+    GLMessage_DataType *arg_indx = glmsg.add_args();
+    arg_indx->set_isarray(false);
+    arg_indx->set_type(GLMessage::DataType::INT);
+    arg_indx->add_intvalue(indx);
+
+    // copy argument values
+    GLMessage_DataType *arg_values = glmsg.add_args();
+    arg_values->set_isarray(false);
+    arg_values->set_type(GLMessage::DataType::INT);
+    arg_values->add_intvalue((int)values);
+
+    // call function
+    glContext->hooks->gl.glVertexAttrib2fv(indx, values);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glVertexAttrib3f(GLuint indx, GLfloat x, GLfloat y, GLfloat z) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glVertexAttrib3f);
+
+    // copy argument indx
+    GLMessage_DataType *arg_indx = glmsg.add_args();
+    arg_indx->set_isarray(false);
+    arg_indx->set_type(GLMessage::DataType::INT);
+    arg_indx->add_intvalue(indx);
+
+    // copy argument x
+    GLMessage_DataType *arg_x = glmsg.add_args();
+    arg_x->set_isarray(false);
+    arg_x->set_type(GLMessage::DataType::FLOAT);
+    arg_x->add_floatvalue(x);
+
+    // copy argument y
+    GLMessage_DataType *arg_y = glmsg.add_args();
+    arg_y->set_isarray(false);
+    arg_y->set_type(GLMessage::DataType::FLOAT);
+    arg_y->add_floatvalue(y);
+
+    // copy argument z
+    GLMessage_DataType *arg_z = glmsg.add_args();
+    arg_z->set_isarray(false);
+    arg_z->set_type(GLMessage::DataType::FLOAT);
+    arg_z->add_floatvalue(z);
+
+    // call function
+    glContext->hooks->gl.glVertexAttrib3f(indx, x, y, z);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glVertexAttrib3fv(GLuint indx, const GLfloat* values) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glVertexAttrib3fv);
+
+    // copy argument indx
+    GLMessage_DataType *arg_indx = glmsg.add_args();
+    arg_indx->set_isarray(false);
+    arg_indx->set_type(GLMessage::DataType::INT);
+    arg_indx->add_intvalue(indx);
+
+    // copy argument values
+    GLMessage_DataType *arg_values = glmsg.add_args();
+    arg_values->set_isarray(false);
+    arg_values->set_type(GLMessage::DataType::INT);
+    arg_values->add_intvalue((int)values);
+
+    // call function
+    glContext->hooks->gl.glVertexAttrib3fv(indx, values);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glVertexAttrib4f(GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glVertexAttrib4f);
+
+    // copy argument indx
+    GLMessage_DataType *arg_indx = glmsg.add_args();
+    arg_indx->set_isarray(false);
+    arg_indx->set_type(GLMessage::DataType::INT);
+    arg_indx->add_intvalue(indx);
+
+    // copy argument x
+    GLMessage_DataType *arg_x = glmsg.add_args();
+    arg_x->set_isarray(false);
+    arg_x->set_type(GLMessage::DataType::FLOAT);
+    arg_x->add_floatvalue(x);
+
+    // copy argument y
+    GLMessage_DataType *arg_y = glmsg.add_args();
+    arg_y->set_isarray(false);
+    arg_y->set_type(GLMessage::DataType::FLOAT);
+    arg_y->add_floatvalue(y);
+
+    // copy argument z
+    GLMessage_DataType *arg_z = glmsg.add_args();
+    arg_z->set_isarray(false);
+    arg_z->set_type(GLMessage::DataType::FLOAT);
+    arg_z->add_floatvalue(z);
+
+    // copy argument w
+    GLMessage_DataType *arg_w = glmsg.add_args();
+    arg_w->set_isarray(false);
+    arg_w->set_type(GLMessage::DataType::FLOAT);
+    arg_w->add_floatvalue(w);
+
+    // call function
+    glContext->hooks->gl.glVertexAttrib4f(indx, x, y, z, w);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glVertexAttrib4fv(GLuint indx, const GLfloat* values) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glVertexAttrib4fv);
+
+    // copy argument indx
+    GLMessage_DataType *arg_indx = glmsg.add_args();
+    arg_indx->set_isarray(false);
+    arg_indx->set_type(GLMessage::DataType::INT);
+    arg_indx->add_intvalue(indx);
+
+    // copy argument values
+    GLMessage_DataType *arg_values = glmsg.add_args();
+    arg_values->set_isarray(false);
+    arg_values->set_type(GLMessage::DataType::INT);
+    arg_values->add_intvalue((int)values);
+
+    // call function
+    glContext->hooks->gl.glVertexAttrib4fv(indx, values);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glVertexAttribPointer(GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glVertexAttribPointer);
+
+    // copy argument indx
+    GLMessage_DataType *arg_indx = glmsg.add_args();
+    arg_indx->set_isarray(false);
+    arg_indx->set_type(GLMessage::DataType::INT);
+    arg_indx->add_intvalue(indx);
+
+    // copy argument size
+    GLMessage_DataType *arg_size = glmsg.add_args();
+    arg_size->set_isarray(false);
+    arg_size->set_type(GLMessage::DataType::INT);
+    arg_size->add_intvalue(size);
+
+    // copy argument type
+    GLMessage_DataType *arg_type = glmsg.add_args();
+    arg_type->set_isarray(false);
+    arg_type->set_type(GLMessage::DataType::ENUM);
+    arg_type->add_intvalue((int)type);
+
+    // copy argument normalized
+    GLMessage_DataType *arg_normalized = glmsg.add_args();
+    arg_normalized->set_isarray(false);
+    arg_normalized->set_type(GLMessage::DataType::BOOL);
+    arg_normalized->add_boolvalue(normalized);
+
+    // copy argument stride
+    GLMessage_DataType *arg_stride = glmsg.add_args();
+    arg_stride->set_isarray(false);
+    arg_stride->set_type(GLMessage::DataType::INT);
+    arg_stride->add_intvalue(stride);
+
+    // copy argument ptr
+    GLMessage_DataType *arg_ptr = glmsg.add_args();
+    arg_ptr->set_isarray(false);
+    arg_ptr->set_type(GLMessage::DataType::INT);
+    arg_ptr->add_intvalue((int)ptr);
+
+    // call function
+    glContext->hooks->gl.glVertexAttribPointer(indx, size, type, normalized, stride, ptr);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glViewport(GLint x, GLint y, GLsizei width, GLsizei height) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glViewport);
+
+    // copy argument x
+    GLMessage_DataType *arg_x = glmsg.add_args();
+    arg_x->set_isarray(false);
+    arg_x->set_type(GLMessage::DataType::INT);
+    arg_x->add_intvalue(x);
+
+    // copy argument y
+    GLMessage_DataType *arg_y = glmsg.add_args();
+    arg_y->set_isarray(false);
+    arg_y->set_type(GLMessage::DataType::INT);
+    arg_y->add_intvalue(y);
+
+    // copy argument width
+    GLMessage_DataType *arg_width = glmsg.add_args();
+    arg_width->set_isarray(false);
+    arg_width->set_type(GLMessage::DataType::INT);
+    arg_width->add_intvalue(width);
+
+    // copy argument height
+    GLMessage_DataType *arg_height = glmsg.add_args();
+    arg_height->set_isarray(false);
+    arg_height->set_type(GLMessage::DataType::INT);
+    arg_height->add_intvalue(height);
+
+    // call function
+    glContext->hooks->gl.glViewport(x, y, width, height);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+
+// Definitions for GL2Ext APIs
+
+void GLTrace_glEGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glEGLImageTargetTexture2DOES);
+
+    // copy argument target
+    GLMessage_DataType *arg_target = glmsg.add_args();
+    arg_target->set_isarray(false);
+    arg_target->set_type(GLMessage::DataType::ENUM);
+    arg_target->add_intvalue((int)target);
+
+    // copy argument image
+    GLMessage_DataType *arg_image = glmsg.add_args();
+    arg_image->set_isarray(false);
+    arg_image->set_type(GLMessage::DataType::INT);
+    arg_image->add_intvalue((int)image);
+
+    // call function
+    glContext->hooks->gl.glEGLImageTargetTexture2DOES(target, image);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glEGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glEGLImageTargetRenderbufferStorageOES);
+
+    // copy argument target
+    GLMessage_DataType *arg_target = glmsg.add_args();
+    arg_target->set_isarray(false);
+    arg_target->set_type(GLMessage::DataType::ENUM);
+    arg_target->add_intvalue((int)target);
+
+    // copy argument image
+    GLMessage_DataType *arg_image = glmsg.add_args();
+    arg_image->set_isarray(false);
+    arg_image->set_type(GLMessage::DataType::INT);
+    arg_image->add_intvalue((int)image);
+
+    // call function
+    glContext->hooks->gl.glEGLImageTargetRenderbufferStorageOES(target, image);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glGetProgramBinaryOES(GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, GLvoid *binary) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glGetProgramBinaryOES);
+
+    // copy argument program
+    GLMessage_DataType *arg_program = glmsg.add_args();
+    arg_program->set_isarray(false);
+    arg_program->set_type(GLMessage::DataType::INT);
+    arg_program->add_intvalue(program);
+
+    // copy argument bufSize
+    GLMessage_DataType *arg_bufSize = glmsg.add_args();
+    arg_bufSize->set_isarray(false);
+    arg_bufSize->set_type(GLMessage::DataType::INT);
+    arg_bufSize->add_intvalue(bufSize);
+
+    // copy argument length
+    GLMessage_DataType *arg_length = glmsg.add_args();
+    arg_length->set_isarray(false);
+    arg_length->set_type(GLMessage::DataType::INT);
+    arg_length->add_intvalue((int)length);
+
+    // copy argument binaryFormat
+    GLMessage_DataType *arg_binaryFormat = glmsg.add_args();
+    arg_binaryFormat->set_isarray(false);
+    arg_binaryFormat->set_type(GLMessage::DataType::INT);
+    arg_binaryFormat->add_intvalue((int)binaryFormat);
+
+    // copy argument binary
+    GLMessage_DataType *arg_binary = glmsg.add_args();
+    arg_binary->set_isarray(false);
+    arg_binary->set_type(GLMessage::DataType::INT);
+    arg_binary->add_intvalue((int)binary);
+
+    // call function
+    glContext->hooks->gl.glGetProgramBinaryOES(program, bufSize, length, binaryFormat, binary);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glProgramBinaryOES(GLuint program, GLenum binaryFormat, const GLvoid *binary, GLint length) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glProgramBinaryOES);
+
+    // copy argument program
+    GLMessage_DataType *arg_program = glmsg.add_args();
+    arg_program->set_isarray(false);
+    arg_program->set_type(GLMessage::DataType::INT);
+    arg_program->add_intvalue(program);
+
+    // copy argument binaryFormat
+    GLMessage_DataType *arg_binaryFormat = glmsg.add_args();
+    arg_binaryFormat->set_isarray(false);
+    arg_binaryFormat->set_type(GLMessage::DataType::ENUM);
+    arg_binaryFormat->add_intvalue((int)binaryFormat);
+
+    // copy argument binary
+    GLMessage_DataType *arg_binary = glmsg.add_args();
+    arg_binary->set_isarray(false);
+    arg_binary->set_type(GLMessage::DataType::INT);
+    arg_binary->add_intvalue((int)binary);
+
+    // copy argument length
+    GLMessage_DataType *arg_length = glmsg.add_args();
+    arg_length->set_isarray(false);
+    arg_length->set_type(GLMessage::DataType::INT);
+    arg_length->add_intvalue(length);
+
+    // call function
+    glContext->hooks->gl.glProgramBinaryOES(program, binaryFormat, binary, length);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void* GLTrace_glMapBufferOES(GLenum target, GLenum access) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glMapBufferOES);
+
+    // copy argument target
+    GLMessage_DataType *arg_target = glmsg.add_args();
+    arg_target->set_isarray(false);
+    arg_target->set_type(GLMessage::DataType::ENUM);
+    arg_target->add_intvalue((int)target);
+
+    // copy argument access
+    GLMessage_DataType *arg_access = glmsg.add_args();
+    arg_access->set_isarray(false);
+    arg_access->set_type(GLMessage::DataType::ENUM);
+    arg_access->add_intvalue((int)access);
+
+    // call function
+    void* retValue = glContext->hooks->gl.glMapBufferOES(target, access);
+
+    // set return value
+    GLMessage_DataType *rt = glmsg.mutable_returnvalue();
+    rt->set_isarray(false);
+    rt->set_type(GLMessage::DataType::INT);
+    rt->add_intvalue((int)retValue);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+
+    return retValue;
+}
+
+GLboolean GLTrace_glUnmapBufferOES(GLenum target) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glUnmapBufferOES);
+
+    // copy argument target
+    GLMessage_DataType *arg_target = glmsg.add_args();
+    arg_target->set_isarray(false);
+    arg_target->set_type(GLMessage::DataType::ENUM);
+    arg_target->add_intvalue((int)target);
+
+    // call function
+    GLboolean retValue = glContext->hooks->gl.glUnmapBufferOES(target);
+
+    // set return value
+    GLMessage_DataType *rt = glmsg.mutable_returnvalue();
+    rt->set_isarray(false);
+    rt->set_type(GLMessage::DataType::BOOL);
+    rt->add_boolvalue(retValue);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+
+    return retValue;
+}
+
+void GLTrace_glGetBufferPointervOES(GLenum target, GLenum pname, GLvoid** params) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glGetBufferPointervOES);
+
+    // copy argument target
+    GLMessage_DataType *arg_target = glmsg.add_args();
+    arg_target->set_isarray(false);
+    arg_target->set_type(GLMessage::DataType::ENUM);
+    arg_target->add_intvalue((int)target);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument params
+    GLMessage_DataType *arg_params = glmsg.add_args();
+    arg_params->set_isarray(false);
+    arg_params->set_type(GLMessage::DataType::INT);
+    arg_params->add_intvalue((int)params);
+
+    // call function
+    glContext->hooks->gl.glGetBufferPointervOES(target, pname, params);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid* pixels) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glTexImage3DOES);
+
+    // copy argument target
+    GLMessage_DataType *arg_target = glmsg.add_args();
+    arg_target->set_isarray(false);
+    arg_target->set_type(GLMessage::DataType::ENUM);
+    arg_target->add_intvalue((int)target);
+
+    // copy argument level
+    GLMessage_DataType *arg_level = glmsg.add_args();
+    arg_level->set_isarray(false);
+    arg_level->set_type(GLMessage::DataType::INT);
+    arg_level->add_intvalue(level);
+
+    // copy argument internalformat
+    GLMessage_DataType *arg_internalformat = glmsg.add_args();
+    arg_internalformat->set_isarray(false);
+    arg_internalformat->set_type(GLMessage::DataType::ENUM);
+    arg_internalformat->add_intvalue((int)internalformat);
+
+    // copy argument width
+    GLMessage_DataType *arg_width = glmsg.add_args();
+    arg_width->set_isarray(false);
+    arg_width->set_type(GLMessage::DataType::INT);
+    arg_width->add_intvalue(width);
+
+    // copy argument height
+    GLMessage_DataType *arg_height = glmsg.add_args();
+    arg_height->set_isarray(false);
+    arg_height->set_type(GLMessage::DataType::INT);
+    arg_height->add_intvalue(height);
+
+    // copy argument depth
+    GLMessage_DataType *arg_depth = glmsg.add_args();
+    arg_depth->set_isarray(false);
+    arg_depth->set_type(GLMessage::DataType::INT);
+    arg_depth->add_intvalue(depth);
+
+    // copy argument border
+    GLMessage_DataType *arg_border = glmsg.add_args();
+    arg_border->set_isarray(false);
+    arg_border->set_type(GLMessage::DataType::INT);
+    arg_border->add_intvalue(border);
+
+    // copy argument format
+    GLMessage_DataType *arg_format = glmsg.add_args();
+    arg_format->set_isarray(false);
+    arg_format->set_type(GLMessage::DataType::ENUM);
+    arg_format->add_intvalue((int)format);
+
+    // copy argument type
+    GLMessage_DataType *arg_type = glmsg.add_args();
+    arg_type->set_isarray(false);
+    arg_type->set_type(GLMessage::DataType::ENUM);
+    arg_type->add_intvalue((int)type);
+
+    // copy argument pixels
+    GLMessage_DataType *arg_pixels = glmsg.add_args();
+    arg_pixels->set_isarray(false);
+    arg_pixels->set_type(GLMessage::DataType::INT);
+    arg_pixels->add_intvalue((int)pixels);
+
+    // call function
+    glContext->hooks->gl.glTexImage3DOES(target, level, internalformat, width, height, depth, border, format, type, pixels);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glTexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid* pixels) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glTexSubImage3DOES);
+
+    // copy argument target
+    GLMessage_DataType *arg_target = glmsg.add_args();
+    arg_target->set_isarray(false);
+    arg_target->set_type(GLMessage::DataType::ENUM);
+    arg_target->add_intvalue((int)target);
+
+    // copy argument level
+    GLMessage_DataType *arg_level = glmsg.add_args();
+    arg_level->set_isarray(false);
+    arg_level->set_type(GLMessage::DataType::INT);
+    arg_level->add_intvalue(level);
+
+    // copy argument xoffset
+    GLMessage_DataType *arg_xoffset = glmsg.add_args();
+    arg_xoffset->set_isarray(false);
+    arg_xoffset->set_type(GLMessage::DataType::INT);
+    arg_xoffset->add_intvalue(xoffset);
+
+    // copy argument yoffset
+    GLMessage_DataType *arg_yoffset = glmsg.add_args();
+    arg_yoffset->set_isarray(false);
+    arg_yoffset->set_type(GLMessage::DataType::INT);
+    arg_yoffset->add_intvalue(yoffset);
+
+    // copy argument zoffset
+    GLMessage_DataType *arg_zoffset = glmsg.add_args();
+    arg_zoffset->set_isarray(false);
+    arg_zoffset->set_type(GLMessage::DataType::INT);
+    arg_zoffset->add_intvalue(zoffset);
+
+    // copy argument width
+    GLMessage_DataType *arg_width = glmsg.add_args();
+    arg_width->set_isarray(false);
+    arg_width->set_type(GLMessage::DataType::INT);
+    arg_width->add_intvalue(width);
+
+    // copy argument height
+    GLMessage_DataType *arg_height = glmsg.add_args();
+    arg_height->set_isarray(false);
+    arg_height->set_type(GLMessage::DataType::INT);
+    arg_height->add_intvalue(height);
+
+    // copy argument depth
+    GLMessage_DataType *arg_depth = glmsg.add_args();
+    arg_depth->set_isarray(false);
+    arg_depth->set_type(GLMessage::DataType::INT);
+    arg_depth->add_intvalue(depth);
+
+    // copy argument format
+    GLMessage_DataType *arg_format = glmsg.add_args();
+    arg_format->set_isarray(false);
+    arg_format->set_type(GLMessage::DataType::ENUM);
+    arg_format->add_intvalue((int)format);
+
+    // copy argument type
+    GLMessage_DataType *arg_type = glmsg.add_args();
+    arg_type->set_isarray(false);
+    arg_type->set_type(GLMessage::DataType::ENUM);
+    arg_type->add_intvalue((int)type);
+
+    // copy argument pixels
+    GLMessage_DataType *arg_pixels = glmsg.add_args();
+    arg_pixels->set_isarray(false);
+    arg_pixels->set_type(GLMessage::DataType::INT);
+    arg_pixels->add_intvalue((int)pixels);
+
+    // call function
+    glContext->hooks->gl.glTexSubImage3DOES(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glCopyTexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glCopyTexSubImage3DOES);
+
+    // copy argument target
+    GLMessage_DataType *arg_target = glmsg.add_args();
+    arg_target->set_isarray(false);
+    arg_target->set_type(GLMessage::DataType::ENUM);
+    arg_target->add_intvalue((int)target);
+
+    // copy argument level
+    GLMessage_DataType *arg_level = glmsg.add_args();
+    arg_level->set_isarray(false);
+    arg_level->set_type(GLMessage::DataType::INT);
+    arg_level->add_intvalue(level);
+
+    // copy argument xoffset
+    GLMessage_DataType *arg_xoffset = glmsg.add_args();
+    arg_xoffset->set_isarray(false);
+    arg_xoffset->set_type(GLMessage::DataType::INT);
+    arg_xoffset->add_intvalue(xoffset);
+
+    // copy argument yoffset
+    GLMessage_DataType *arg_yoffset = glmsg.add_args();
+    arg_yoffset->set_isarray(false);
+    arg_yoffset->set_type(GLMessage::DataType::INT);
+    arg_yoffset->add_intvalue(yoffset);
+
+    // copy argument zoffset
+    GLMessage_DataType *arg_zoffset = glmsg.add_args();
+    arg_zoffset->set_isarray(false);
+    arg_zoffset->set_type(GLMessage::DataType::INT);
+    arg_zoffset->add_intvalue(zoffset);
+
+    // copy argument x
+    GLMessage_DataType *arg_x = glmsg.add_args();
+    arg_x->set_isarray(false);
+    arg_x->set_type(GLMessage::DataType::INT);
+    arg_x->add_intvalue(x);
+
+    // copy argument y
+    GLMessage_DataType *arg_y = glmsg.add_args();
+    arg_y->set_isarray(false);
+    arg_y->set_type(GLMessage::DataType::INT);
+    arg_y->add_intvalue(y);
+
+    // copy argument width
+    GLMessage_DataType *arg_width = glmsg.add_args();
+    arg_width->set_isarray(false);
+    arg_width->set_type(GLMessage::DataType::INT);
+    arg_width->add_intvalue(width);
+
+    // copy argument height
+    GLMessage_DataType *arg_height = glmsg.add_args();
+    arg_height->set_isarray(false);
+    arg_height->set_type(GLMessage::DataType::INT);
+    arg_height->add_intvalue(height);
+
+    // call function
+    glContext->hooks->gl.glCopyTexSubImage3DOES(target, level, xoffset, yoffset, zoffset, x, y, width, height);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glCompressedTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid* data) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glCompressedTexImage3DOES);
+
+    // copy argument target
+    GLMessage_DataType *arg_target = glmsg.add_args();
+    arg_target->set_isarray(false);
+    arg_target->set_type(GLMessage::DataType::ENUM);
+    arg_target->add_intvalue((int)target);
+
+    // copy argument level
+    GLMessage_DataType *arg_level = glmsg.add_args();
+    arg_level->set_isarray(false);
+    arg_level->set_type(GLMessage::DataType::INT);
+    arg_level->add_intvalue(level);
+
+    // copy argument internalformat
+    GLMessage_DataType *arg_internalformat = glmsg.add_args();
+    arg_internalformat->set_isarray(false);
+    arg_internalformat->set_type(GLMessage::DataType::ENUM);
+    arg_internalformat->add_intvalue((int)internalformat);
+
+    // copy argument width
+    GLMessage_DataType *arg_width = glmsg.add_args();
+    arg_width->set_isarray(false);
+    arg_width->set_type(GLMessage::DataType::INT);
+    arg_width->add_intvalue(width);
+
+    // copy argument height
+    GLMessage_DataType *arg_height = glmsg.add_args();
+    arg_height->set_isarray(false);
+    arg_height->set_type(GLMessage::DataType::INT);
+    arg_height->add_intvalue(height);
+
+    // copy argument depth
+    GLMessage_DataType *arg_depth = glmsg.add_args();
+    arg_depth->set_isarray(false);
+    arg_depth->set_type(GLMessage::DataType::INT);
+    arg_depth->add_intvalue(depth);
+
+    // copy argument border
+    GLMessage_DataType *arg_border = glmsg.add_args();
+    arg_border->set_isarray(false);
+    arg_border->set_type(GLMessage::DataType::INT);
+    arg_border->add_intvalue(border);
+
+    // copy argument imageSize
+    GLMessage_DataType *arg_imageSize = glmsg.add_args();
+    arg_imageSize->set_isarray(false);
+    arg_imageSize->set_type(GLMessage::DataType::INT);
+    arg_imageSize->add_intvalue(imageSize);
+
+    // copy argument data
+    GLMessage_DataType *arg_data = glmsg.add_args();
+    arg_data->set_isarray(false);
+    arg_data->set_type(GLMessage::DataType::INT);
+    arg_data->add_intvalue((int)data);
+
+    // call function
+    glContext->hooks->gl.glCompressedTexImage3DOES(target, level, internalformat, width, height, depth, border, imageSize, data);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glCompressedTexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid* data) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glCompressedTexSubImage3DOES);
+
+    // copy argument target
+    GLMessage_DataType *arg_target = glmsg.add_args();
+    arg_target->set_isarray(false);
+    arg_target->set_type(GLMessage::DataType::ENUM);
+    arg_target->add_intvalue((int)target);
+
+    // copy argument level
+    GLMessage_DataType *arg_level = glmsg.add_args();
+    arg_level->set_isarray(false);
+    arg_level->set_type(GLMessage::DataType::INT);
+    arg_level->add_intvalue(level);
+
+    // copy argument xoffset
+    GLMessage_DataType *arg_xoffset = glmsg.add_args();
+    arg_xoffset->set_isarray(false);
+    arg_xoffset->set_type(GLMessage::DataType::INT);
+    arg_xoffset->add_intvalue(xoffset);
+
+    // copy argument yoffset
+    GLMessage_DataType *arg_yoffset = glmsg.add_args();
+    arg_yoffset->set_isarray(false);
+    arg_yoffset->set_type(GLMessage::DataType::INT);
+    arg_yoffset->add_intvalue(yoffset);
+
+    // copy argument zoffset
+    GLMessage_DataType *arg_zoffset = glmsg.add_args();
+    arg_zoffset->set_isarray(false);
+    arg_zoffset->set_type(GLMessage::DataType::INT);
+    arg_zoffset->add_intvalue(zoffset);
+
+    // copy argument width
+    GLMessage_DataType *arg_width = glmsg.add_args();
+    arg_width->set_isarray(false);
+    arg_width->set_type(GLMessage::DataType::INT);
+    arg_width->add_intvalue(width);
+
+    // copy argument height
+    GLMessage_DataType *arg_height = glmsg.add_args();
+    arg_height->set_isarray(false);
+    arg_height->set_type(GLMessage::DataType::INT);
+    arg_height->add_intvalue(height);
+
+    // copy argument depth
+    GLMessage_DataType *arg_depth = glmsg.add_args();
+    arg_depth->set_isarray(false);
+    arg_depth->set_type(GLMessage::DataType::INT);
+    arg_depth->add_intvalue(depth);
+
+    // copy argument format
+    GLMessage_DataType *arg_format = glmsg.add_args();
+    arg_format->set_isarray(false);
+    arg_format->set_type(GLMessage::DataType::ENUM);
+    arg_format->add_intvalue((int)format);
+
+    // copy argument imageSize
+    GLMessage_DataType *arg_imageSize = glmsg.add_args();
+    arg_imageSize->set_isarray(false);
+    arg_imageSize->set_type(GLMessage::DataType::INT);
+    arg_imageSize->add_intvalue(imageSize);
+
+    // copy argument data
+    GLMessage_DataType *arg_data = glmsg.add_args();
+    arg_data->set_isarray(false);
+    arg_data->set_type(GLMessage::DataType::INT);
+    arg_data->add_intvalue((int)data);
+
+    // call function
+    glContext->hooks->gl.glCompressedTexSubImage3DOES(target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glFramebufferTexture3DOES(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glFramebufferTexture3DOES);
+
+    // copy argument target
+    GLMessage_DataType *arg_target = glmsg.add_args();
+    arg_target->set_isarray(false);
+    arg_target->set_type(GLMessage::DataType::ENUM);
+    arg_target->add_intvalue((int)target);
+
+    // copy argument attachment
+    GLMessage_DataType *arg_attachment = glmsg.add_args();
+    arg_attachment->set_isarray(false);
+    arg_attachment->set_type(GLMessage::DataType::ENUM);
+    arg_attachment->add_intvalue((int)attachment);
+
+    // copy argument textarget
+    GLMessage_DataType *arg_textarget = glmsg.add_args();
+    arg_textarget->set_isarray(false);
+    arg_textarget->set_type(GLMessage::DataType::ENUM);
+    arg_textarget->add_intvalue((int)textarget);
+
+    // copy argument texture
+    GLMessage_DataType *arg_texture = glmsg.add_args();
+    arg_texture->set_isarray(false);
+    arg_texture->set_type(GLMessage::DataType::INT);
+    arg_texture->add_intvalue(texture);
+
+    // copy argument level
+    GLMessage_DataType *arg_level = glmsg.add_args();
+    arg_level->set_isarray(false);
+    arg_level->set_type(GLMessage::DataType::INT);
+    arg_level->add_intvalue(level);
+
+    // copy argument zoffset
+    GLMessage_DataType *arg_zoffset = glmsg.add_args();
+    arg_zoffset->set_isarray(false);
+    arg_zoffset->set_type(GLMessage::DataType::INT);
+    arg_zoffset->add_intvalue(zoffset);
+
+    // call function
+    glContext->hooks->gl.glFramebufferTexture3DOES(target, attachment, textarget, texture, level, zoffset);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glBindVertexArrayOES(GLuint array) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glBindVertexArrayOES);
+
+    // copy argument array
+    GLMessage_DataType *arg_array = glmsg.add_args();
+    arg_array->set_isarray(false);
+    arg_array->set_type(GLMessage::DataType::INT);
+    arg_array->add_intvalue(array);
+
+    // call function
+    glContext->hooks->gl.glBindVertexArrayOES(array);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glDeleteVertexArraysOES(GLsizei n, const GLuint *arrays) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glDeleteVertexArraysOES);
+
+    // copy argument n
+    GLMessage_DataType *arg_n = glmsg.add_args();
+    arg_n->set_isarray(false);
+    arg_n->set_type(GLMessage::DataType::INT);
+    arg_n->add_intvalue(n);
+
+    // copy argument arrays
+    GLMessage_DataType *arg_arrays = glmsg.add_args();
+    arg_arrays->set_isarray(false);
+    arg_arrays->set_type(GLMessage::DataType::INT);
+    arg_arrays->add_intvalue((int)arrays);
+
+    // call function
+    glContext->hooks->gl.glDeleteVertexArraysOES(n, arrays);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glGenVertexArraysOES(GLsizei n, GLuint *arrays) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glGenVertexArraysOES);
+
+    // copy argument n
+    GLMessage_DataType *arg_n = glmsg.add_args();
+    arg_n->set_isarray(false);
+    arg_n->set_type(GLMessage::DataType::INT);
+    arg_n->add_intvalue(n);
+
+    // copy argument arrays
+    GLMessage_DataType *arg_arrays = glmsg.add_args();
+    arg_arrays->set_isarray(false);
+    arg_arrays->set_type(GLMessage::DataType::INT);
+    arg_arrays->add_intvalue((int)arrays);
+
+    // call function
+    glContext->hooks->gl.glGenVertexArraysOES(n, arrays);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+GLboolean GLTrace_glIsVertexArrayOES(GLuint array) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glIsVertexArrayOES);
+
+    // copy argument array
+    GLMessage_DataType *arg_array = glmsg.add_args();
+    arg_array->set_isarray(false);
+    arg_array->set_type(GLMessage::DataType::INT);
+    arg_array->add_intvalue(array);
+
+    // call function
+    GLboolean retValue = glContext->hooks->gl.glIsVertexArrayOES(array);
+
+    // set return value
+    GLMessage_DataType *rt = glmsg.mutable_returnvalue();
+    rt->set_isarray(false);
+    rt->set_type(GLMessage::DataType::BOOL);
+    rt->add_boolvalue(retValue);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+
+    return retValue;
+}
+
+void GLTrace_glGetPerfMonitorGroupsAMD(GLint *numGroups, GLsizei groupsSize, GLuint *groups) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glGetPerfMonitorGroupsAMD);
+
+    // copy argument numGroups
+    GLMessage_DataType *arg_numGroups = glmsg.add_args();
+    arg_numGroups->set_isarray(false);
+    arg_numGroups->set_type(GLMessage::DataType::INT);
+    arg_numGroups->add_intvalue((int)numGroups);
+
+    // copy argument groupsSize
+    GLMessage_DataType *arg_groupsSize = glmsg.add_args();
+    arg_groupsSize->set_isarray(false);
+    arg_groupsSize->set_type(GLMessage::DataType::INT);
+    arg_groupsSize->add_intvalue(groupsSize);
+
+    // copy argument groups
+    GLMessage_DataType *arg_groups = glmsg.add_args();
+    arg_groups->set_isarray(false);
+    arg_groups->set_type(GLMessage::DataType::INT);
+    arg_groups->add_intvalue((int)groups);
+
+    // call function
+    glContext->hooks->gl.glGetPerfMonitorGroupsAMD(numGroups, groupsSize, groups);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glGetPerfMonitorCountersAMD(GLuint group, GLint *numCounters, GLint *maxActiveCounters, GLsizei counterSize, GLuint *counters) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glGetPerfMonitorCountersAMD);
+
+    // copy argument group
+    GLMessage_DataType *arg_group = glmsg.add_args();
+    arg_group->set_isarray(false);
+    arg_group->set_type(GLMessage::DataType::INT);
+    arg_group->add_intvalue(group);
+
+    // copy argument numCounters
+    GLMessage_DataType *arg_numCounters = glmsg.add_args();
+    arg_numCounters->set_isarray(false);
+    arg_numCounters->set_type(GLMessage::DataType::INT);
+    arg_numCounters->add_intvalue((int)numCounters);
+
+    // copy argument maxActiveCounters
+    GLMessage_DataType *arg_maxActiveCounters = glmsg.add_args();
+    arg_maxActiveCounters->set_isarray(false);
+    arg_maxActiveCounters->set_type(GLMessage::DataType::INT);
+    arg_maxActiveCounters->add_intvalue((int)maxActiveCounters);
+
+    // copy argument counterSize
+    GLMessage_DataType *arg_counterSize = glmsg.add_args();
+    arg_counterSize->set_isarray(false);
+    arg_counterSize->set_type(GLMessage::DataType::INT);
+    arg_counterSize->add_intvalue(counterSize);
+
+    // copy argument counters
+    GLMessage_DataType *arg_counters = glmsg.add_args();
+    arg_counters->set_isarray(false);
+    arg_counters->set_type(GLMessage::DataType::INT);
+    arg_counters->add_intvalue((int)counters);
+
+    // call function
+    glContext->hooks->gl.glGetPerfMonitorCountersAMD(group, numCounters, maxActiveCounters, counterSize, counters);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glGetPerfMonitorGroupStringAMD(GLuint group, GLsizei bufSize, GLsizei *length, GLchar *groupString) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glGetPerfMonitorGroupStringAMD);
+
+    // copy argument group
+    GLMessage_DataType *arg_group = glmsg.add_args();
+    arg_group->set_isarray(false);
+    arg_group->set_type(GLMessage::DataType::INT);
+    arg_group->add_intvalue(group);
+
+    // copy argument bufSize
+    GLMessage_DataType *arg_bufSize = glmsg.add_args();
+    arg_bufSize->set_isarray(false);
+    arg_bufSize->set_type(GLMessage::DataType::INT);
+    arg_bufSize->add_intvalue(bufSize);
+
+    // copy argument length
+    GLMessage_DataType *arg_length = glmsg.add_args();
+    arg_length->set_isarray(false);
+    arg_length->set_type(GLMessage::DataType::INT);
+    arg_length->add_intvalue((int)length);
+
+    // copy argument groupString
+    GLMessage_DataType *arg_groupString = glmsg.add_args();
+    arg_groupString->set_isarray(false);
+    arg_groupString->set_type(GLMessage::DataType::INT);
+    arg_groupString->add_intvalue((int)groupString);
+
+    // call function
+    glContext->hooks->gl.glGetPerfMonitorGroupStringAMD(group, bufSize, length, groupString);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glGetPerfMonitorCounterStringAMD(GLuint group, GLuint counter, GLsizei bufSize, GLsizei *length, GLchar *counterString) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glGetPerfMonitorCounterStringAMD);
+
+    // copy argument group
+    GLMessage_DataType *arg_group = glmsg.add_args();
+    arg_group->set_isarray(false);
+    arg_group->set_type(GLMessage::DataType::INT);
+    arg_group->add_intvalue(group);
+
+    // copy argument counter
+    GLMessage_DataType *arg_counter = glmsg.add_args();
+    arg_counter->set_isarray(false);
+    arg_counter->set_type(GLMessage::DataType::INT);
+    arg_counter->add_intvalue(counter);
+
+    // copy argument bufSize
+    GLMessage_DataType *arg_bufSize = glmsg.add_args();
+    arg_bufSize->set_isarray(false);
+    arg_bufSize->set_type(GLMessage::DataType::INT);
+    arg_bufSize->add_intvalue(bufSize);
+
+    // copy argument length
+    GLMessage_DataType *arg_length = glmsg.add_args();
+    arg_length->set_isarray(false);
+    arg_length->set_type(GLMessage::DataType::INT);
+    arg_length->add_intvalue((int)length);
+
+    // copy argument counterString
+    GLMessage_DataType *arg_counterString = glmsg.add_args();
+    arg_counterString->set_isarray(false);
+    arg_counterString->set_type(GLMessage::DataType::INT);
+    arg_counterString->add_intvalue((int)counterString);
+
+    // call function
+    glContext->hooks->gl.glGetPerfMonitorCounterStringAMD(group, counter, bufSize, length, counterString);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glGetPerfMonitorCounterInfoAMD(GLuint group, GLuint counter, GLenum pname, GLvoid *data) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glGetPerfMonitorCounterInfoAMD);
+
+    // copy argument group
+    GLMessage_DataType *arg_group = glmsg.add_args();
+    arg_group->set_isarray(false);
+    arg_group->set_type(GLMessage::DataType::INT);
+    arg_group->add_intvalue(group);
+
+    // copy argument counter
+    GLMessage_DataType *arg_counter = glmsg.add_args();
+    arg_counter->set_isarray(false);
+    arg_counter->set_type(GLMessage::DataType::INT);
+    arg_counter->add_intvalue(counter);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument data
+    GLMessage_DataType *arg_data = glmsg.add_args();
+    arg_data->set_isarray(false);
+    arg_data->set_type(GLMessage::DataType::INT);
+    arg_data->add_intvalue((int)data);
+
+    // call function
+    glContext->hooks->gl.glGetPerfMonitorCounterInfoAMD(group, counter, pname, data);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glGenPerfMonitorsAMD(GLsizei n, GLuint *monitors) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glGenPerfMonitorsAMD);
+
+    // copy argument n
+    GLMessage_DataType *arg_n = glmsg.add_args();
+    arg_n->set_isarray(false);
+    arg_n->set_type(GLMessage::DataType::INT);
+    arg_n->add_intvalue(n);
+
+    // copy argument monitors
+    GLMessage_DataType *arg_monitors = glmsg.add_args();
+    arg_monitors->set_isarray(false);
+    arg_monitors->set_type(GLMessage::DataType::INT);
+    arg_monitors->add_intvalue((int)monitors);
+
+    // call function
+    glContext->hooks->gl.glGenPerfMonitorsAMD(n, monitors);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glDeletePerfMonitorsAMD(GLsizei n, GLuint *monitors) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glDeletePerfMonitorsAMD);
+
+    // copy argument n
+    GLMessage_DataType *arg_n = glmsg.add_args();
+    arg_n->set_isarray(false);
+    arg_n->set_type(GLMessage::DataType::INT);
+    arg_n->add_intvalue(n);
+
+    // copy argument monitors
+    GLMessage_DataType *arg_monitors = glmsg.add_args();
+    arg_monitors->set_isarray(false);
+    arg_monitors->set_type(GLMessage::DataType::INT);
+    arg_monitors->add_intvalue((int)monitors);
+
+    // call function
+    glContext->hooks->gl.glDeletePerfMonitorsAMD(n, monitors);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glSelectPerfMonitorCountersAMD(GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint *countersList) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glSelectPerfMonitorCountersAMD);
+
+    // copy argument monitor
+    GLMessage_DataType *arg_monitor = glmsg.add_args();
+    arg_monitor->set_isarray(false);
+    arg_monitor->set_type(GLMessage::DataType::INT);
+    arg_monitor->add_intvalue(monitor);
+
+    // copy argument enable
+    GLMessage_DataType *arg_enable = glmsg.add_args();
+    arg_enable->set_isarray(false);
+    arg_enable->set_type(GLMessage::DataType::BOOL);
+    arg_enable->add_boolvalue(enable);
+
+    // copy argument group
+    GLMessage_DataType *arg_group = glmsg.add_args();
+    arg_group->set_isarray(false);
+    arg_group->set_type(GLMessage::DataType::INT);
+    arg_group->add_intvalue(group);
+
+    // copy argument numCounters
+    GLMessage_DataType *arg_numCounters = glmsg.add_args();
+    arg_numCounters->set_isarray(false);
+    arg_numCounters->set_type(GLMessage::DataType::INT);
+    arg_numCounters->add_intvalue(numCounters);
+
+    // copy argument countersList
+    GLMessage_DataType *arg_countersList = glmsg.add_args();
+    arg_countersList->set_isarray(false);
+    arg_countersList->set_type(GLMessage::DataType::INT);
+    arg_countersList->add_intvalue((int)countersList);
+
+    // call function
+    glContext->hooks->gl.glSelectPerfMonitorCountersAMD(monitor, enable, group, numCounters, countersList);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glBeginPerfMonitorAMD(GLuint monitor) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glBeginPerfMonitorAMD);
+
+    // copy argument monitor
+    GLMessage_DataType *arg_monitor = glmsg.add_args();
+    arg_monitor->set_isarray(false);
+    arg_monitor->set_type(GLMessage::DataType::INT);
+    arg_monitor->add_intvalue(monitor);
+
+    // call function
+    glContext->hooks->gl.glBeginPerfMonitorAMD(monitor);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glEndPerfMonitorAMD(GLuint monitor) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glEndPerfMonitorAMD);
+
+    // copy argument monitor
+    GLMessage_DataType *arg_monitor = glmsg.add_args();
+    arg_monitor->set_isarray(false);
+    arg_monitor->set_type(GLMessage::DataType::INT);
+    arg_monitor->add_intvalue(monitor);
+
+    // call function
+    glContext->hooks->gl.glEndPerfMonitorAMD(monitor);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glGetPerfMonitorCounterDataAMD(GLuint monitor, GLenum pname, GLsizei dataSize, GLuint *data, GLint *bytesWritten) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glGetPerfMonitorCounterDataAMD);
+
+    // copy argument monitor
+    GLMessage_DataType *arg_monitor = glmsg.add_args();
+    arg_monitor->set_isarray(false);
+    arg_monitor->set_type(GLMessage::DataType::INT);
+    arg_monitor->add_intvalue(monitor);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument dataSize
+    GLMessage_DataType *arg_dataSize = glmsg.add_args();
+    arg_dataSize->set_isarray(false);
+    arg_dataSize->set_type(GLMessage::DataType::INT);
+    arg_dataSize->add_intvalue(dataSize);
+
+    // copy argument data
+    GLMessage_DataType *arg_data = glmsg.add_args();
+    arg_data->set_isarray(false);
+    arg_data->set_type(GLMessage::DataType::INT);
+    arg_data->add_intvalue((int)data);
+
+    // copy argument bytesWritten
+    GLMessage_DataType *arg_bytesWritten = glmsg.add_args();
+    arg_bytesWritten->set_isarray(false);
+    arg_bytesWritten->set_type(GLMessage::DataType::INT);
+    arg_bytesWritten->add_intvalue((int)bytesWritten);
+
+    // call function
+    glContext->hooks->gl.glGetPerfMonitorCounterDataAMD(monitor, pname, dataSize, data, bytesWritten);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glDiscardFramebufferEXT(GLenum target, GLsizei numAttachments, const GLenum *attachments) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glDiscardFramebufferEXT);
+
+    // copy argument target
+    GLMessage_DataType *arg_target = glmsg.add_args();
+    arg_target->set_isarray(false);
+    arg_target->set_type(GLMessage::DataType::ENUM);
+    arg_target->add_intvalue((int)target);
+
+    // copy argument numAttachments
+    GLMessage_DataType *arg_numAttachments = glmsg.add_args();
+    arg_numAttachments->set_isarray(false);
+    arg_numAttachments->set_type(GLMessage::DataType::INT);
+    arg_numAttachments->add_intvalue(numAttachments);
+
+    // copy argument attachments
+    GLMessage_DataType *arg_attachments = glmsg.add_args();
+    arg_attachments->set_isarray(false);
+    arg_attachments->set_type(GLMessage::DataType::INT);
+    arg_attachments->add_intvalue((int)attachments);
+
+    // call function
+    glContext->hooks->gl.glDiscardFramebufferEXT(target, numAttachments, attachments);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glMultiDrawArraysEXT(GLenum mode, GLint *first, GLsizei *count, GLsizei primcount) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glMultiDrawArraysEXT);
+
+    // copy argument mode
+    GLMessage_DataType *arg_mode = glmsg.add_args();
+    arg_mode->set_isarray(false);
+    arg_mode->set_type(GLMessage::DataType::ENUM);
+    arg_mode->add_intvalue((int)mode);
+
+    // copy argument first
+    GLMessage_DataType *arg_first = glmsg.add_args();
+    arg_first->set_isarray(false);
+    arg_first->set_type(GLMessage::DataType::INT);
+    arg_first->add_intvalue((int)first);
+
+    // copy argument count
+    GLMessage_DataType *arg_count = glmsg.add_args();
+    arg_count->set_isarray(false);
+    arg_count->set_type(GLMessage::DataType::INT);
+    arg_count->add_intvalue((int)count);
+
+    // copy argument primcount
+    GLMessage_DataType *arg_primcount = glmsg.add_args();
+    arg_primcount->set_isarray(false);
+    arg_primcount->set_type(GLMessage::DataType::INT);
+    arg_primcount->add_intvalue(primcount);
+
+    // call function
+    glContext->hooks->gl.glMultiDrawArraysEXT(mode, first, count, primcount);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glMultiDrawElementsEXT(GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glMultiDrawElementsEXT);
+
+    // copy argument mode
+    GLMessage_DataType *arg_mode = glmsg.add_args();
+    arg_mode->set_isarray(false);
+    arg_mode->set_type(GLMessage::DataType::ENUM);
+    arg_mode->add_intvalue((int)mode);
+
+    // copy argument count
+    GLMessage_DataType *arg_count = glmsg.add_args();
+    arg_count->set_isarray(false);
+    arg_count->set_type(GLMessage::DataType::INT);
+    arg_count->add_intvalue((int)count);
+
+    // copy argument type
+    GLMessage_DataType *arg_type = glmsg.add_args();
+    arg_type->set_isarray(false);
+    arg_type->set_type(GLMessage::DataType::ENUM);
+    arg_type->add_intvalue((int)type);
+
+    // copy argument indices
+    GLMessage_DataType *arg_indices = glmsg.add_args();
+    arg_indices->set_isarray(false);
+    arg_indices->set_type(GLMessage::DataType::INT);
+    arg_indices->add_intvalue((int)indices);
+
+    // copy argument primcount
+    GLMessage_DataType *arg_primcount = glmsg.add_args();
+    arg_primcount->set_isarray(false);
+    arg_primcount->set_type(GLMessage::DataType::INT);
+    arg_primcount->add_intvalue(primcount);
+
+    // call function
+    glContext->hooks->gl.glMultiDrawElementsEXT(mode, count, type, indices, primcount);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glRenderbufferStorageMultisampleIMG(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glRenderbufferStorageMultisampleIMG);
+
+    // copy argument target
+    GLMessage_DataType *arg_target = glmsg.add_args();
+    arg_target->set_isarray(false);
+    arg_target->set_type(GLMessage::DataType::ENUM);
+    arg_target->add_intvalue((int)target);
+
+    // copy argument samples
+    GLMessage_DataType *arg_samples = glmsg.add_args();
+    arg_samples->set_isarray(false);
+    arg_samples->set_type(GLMessage::DataType::INT);
+    arg_samples->add_intvalue(samples);
+
+    // copy argument internalformat
+    GLMessage_DataType *arg_internalformat = glmsg.add_args();
+    arg_internalformat->set_isarray(false);
+    arg_internalformat->set_type(GLMessage::DataType::ENUM);
+    arg_internalformat->add_intvalue((int)internalformat);
+
+    // copy argument width
+    GLMessage_DataType *arg_width = glmsg.add_args();
+    arg_width->set_isarray(false);
+    arg_width->set_type(GLMessage::DataType::INT);
+    arg_width->add_intvalue(width);
+
+    // copy argument height
+    GLMessage_DataType *arg_height = glmsg.add_args();
+    arg_height->set_isarray(false);
+    arg_height->set_type(GLMessage::DataType::INT);
+    arg_height->add_intvalue(height);
+
+    // call function
+    glContext->hooks->gl.glRenderbufferStorageMultisampleIMG(target, samples, internalformat, width, height);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glFramebufferTexture2DMultisampleIMG(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glFramebufferTexture2DMultisampleIMG);
+
+    // copy argument target
+    GLMessage_DataType *arg_target = glmsg.add_args();
+    arg_target->set_isarray(false);
+    arg_target->set_type(GLMessage::DataType::ENUM);
+    arg_target->add_intvalue((int)target);
+
+    // copy argument attachment
+    GLMessage_DataType *arg_attachment = glmsg.add_args();
+    arg_attachment->set_isarray(false);
+    arg_attachment->set_type(GLMessage::DataType::ENUM);
+    arg_attachment->add_intvalue((int)attachment);
+
+    // copy argument textarget
+    GLMessage_DataType *arg_textarget = glmsg.add_args();
+    arg_textarget->set_isarray(false);
+    arg_textarget->set_type(GLMessage::DataType::ENUM);
+    arg_textarget->add_intvalue((int)textarget);
+
+    // copy argument texture
+    GLMessage_DataType *arg_texture = glmsg.add_args();
+    arg_texture->set_isarray(false);
+    arg_texture->set_type(GLMessage::DataType::INT);
+    arg_texture->add_intvalue(texture);
+
+    // copy argument level
+    GLMessage_DataType *arg_level = glmsg.add_args();
+    arg_level->set_isarray(false);
+    arg_level->set_type(GLMessage::DataType::INT);
+    arg_level->add_intvalue(level);
+
+    // copy argument samples
+    GLMessage_DataType *arg_samples = glmsg.add_args();
+    arg_samples->set_isarray(false);
+    arg_samples->set_type(GLMessage::DataType::INT);
+    arg_samples->add_intvalue(samples);
+
+    // call function
+    glContext->hooks->gl.glFramebufferTexture2DMultisampleIMG(target, attachment, textarget, texture, level, samples);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glDeleteFencesNV(GLsizei n, const GLuint *fences) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glDeleteFencesNV);
+
+    // copy argument n
+    GLMessage_DataType *arg_n = glmsg.add_args();
+    arg_n->set_isarray(false);
+    arg_n->set_type(GLMessage::DataType::INT);
+    arg_n->add_intvalue(n);
+
+    // copy argument fences
+    GLMessage_DataType *arg_fences = glmsg.add_args();
+    arg_fences->set_isarray(false);
+    arg_fences->set_type(GLMessage::DataType::INT);
+    arg_fences->add_intvalue((int)fences);
+
+    // call function
+    glContext->hooks->gl.glDeleteFencesNV(n, fences);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glGenFencesNV(GLsizei n, GLuint *fences) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glGenFencesNV);
+
+    // copy argument n
+    GLMessage_DataType *arg_n = glmsg.add_args();
+    arg_n->set_isarray(false);
+    arg_n->set_type(GLMessage::DataType::INT);
+    arg_n->add_intvalue(n);
+
+    // copy argument fences
+    GLMessage_DataType *arg_fences = glmsg.add_args();
+    arg_fences->set_isarray(false);
+    arg_fences->set_type(GLMessage::DataType::INT);
+    arg_fences->add_intvalue((int)fences);
+
+    // call function
+    glContext->hooks->gl.glGenFencesNV(n, fences);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+GLboolean GLTrace_glIsFenceNV(GLuint fence) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glIsFenceNV);
+
+    // copy argument fence
+    GLMessage_DataType *arg_fence = glmsg.add_args();
+    arg_fence->set_isarray(false);
+    arg_fence->set_type(GLMessage::DataType::INT);
+    arg_fence->add_intvalue(fence);
+
+    // call function
+    GLboolean retValue = glContext->hooks->gl.glIsFenceNV(fence);
+
+    // set return value
+    GLMessage_DataType *rt = glmsg.mutable_returnvalue();
+    rt->set_isarray(false);
+    rt->set_type(GLMessage::DataType::BOOL);
+    rt->add_boolvalue(retValue);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+
+    return retValue;
+}
+
+GLboolean GLTrace_glTestFenceNV(GLuint fence) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glTestFenceNV);
+
+    // copy argument fence
+    GLMessage_DataType *arg_fence = glmsg.add_args();
+    arg_fence->set_isarray(false);
+    arg_fence->set_type(GLMessage::DataType::INT);
+    arg_fence->add_intvalue(fence);
+
+    // call function
+    GLboolean retValue = glContext->hooks->gl.glTestFenceNV(fence);
+
+    // set return value
+    GLMessage_DataType *rt = glmsg.mutable_returnvalue();
+    rt->set_isarray(false);
+    rt->set_type(GLMessage::DataType::BOOL);
+    rt->add_boolvalue(retValue);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+
+    return retValue;
+}
+
+void GLTrace_glGetFenceivNV(GLuint fence, GLenum pname, GLint *params) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glGetFenceivNV);
+
+    // copy argument fence
+    GLMessage_DataType *arg_fence = glmsg.add_args();
+    arg_fence->set_isarray(false);
+    arg_fence->set_type(GLMessage::DataType::INT);
+    arg_fence->add_intvalue(fence);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument params
+    GLMessage_DataType *arg_params = glmsg.add_args();
+    arg_params->set_isarray(false);
+    arg_params->set_type(GLMessage::DataType::INT);
+    arg_params->add_intvalue((int)params);
+
+    // call function
+    glContext->hooks->gl.glGetFenceivNV(fence, pname, params);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glFinishFenceNV(GLuint fence) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glFinishFenceNV);
+
+    // copy argument fence
+    GLMessage_DataType *arg_fence = glmsg.add_args();
+    arg_fence->set_isarray(false);
+    arg_fence->set_type(GLMessage::DataType::INT);
+    arg_fence->add_intvalue(fence);
+
+    // call function
+    glContext->hooks->gl.glFinishFenceNV(fence);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glSetFenceNV(GLuint fence, GLenum condition) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glSetFenceNV);
+
+    // copy argument fence
+    GLMessage_DataType *arg_fence = glmsg.add_args();
+    arg_fence->set_isarray(false);
+    arg_fence->set_type(GLMessage::DataType::INT);
+    arg_fence->add_intvalue(fence);
+
+    // copy argument condition
+    GLMessage_DataType *arg_condition = glmsg.add_args();
+    arg_condition->set_isarray(false);
+    arg_condition->set_type(GLMessage::DataType::ENUM);
+    arg_condition->add_intvalue((int)condition);
+
+    // call function
+    glContext->hooks->gl.glSetFenceNV(fence, condition);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glCoverageMaskNV(GLboolean mask) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glCoverageMaskNV);
+
+    // copy argument mask
+    GLMessage_DataType *arg_mask = glmsg.add_args();
+    arg_mask->set_isarray(false);
+    arg_mask->set_type(GLMessage::DataType::BOOL);
+    arg_mask->add_boolvalue(mask);
+
+    // call function
+    glContext->hooks->gl.glCoverageMaskNV(mask);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glCoverageOperationNV(GLenum operation) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glCoverageOperationNV);
+
+    // copy argument operation
+    GLMessage_DataType *arg_operation = glmsg.add_args();
+    arg_operation->set_isarray(false);
+    arg_operation->set_type(GLMessage::DataType::ENUM);
+    arg_operation->add_intvalue((int)operation);
+
+    // call function
+    glContext->hooks->gl.glCoverageOperationNV(operation);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glGetDriverControlsQCOM(GLint *num, GLsizei size, GLuint *driverControls) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glGetDriverControlsQCOM);
+
+    // copy argument num
+    GLMessage_DataType *arg_num = glmsg.add_args();
+    arg_num->set_isarray(false);
+    arg_num->set_type(GLMessage::DataType::INT);
+    arg_num->add_intvalue((int)num);
+
+    // copy argument size
+    GLMessage_DataType *arg_size = glmsg.add_args();
+    arg_size->set_isarray(false);
+    arg_size->set_type(GLMessage::DataType::INT);
+    arg_size->add_intvalue(size);
+
+    // copy argument driverControls
+    GLMessage_DataType *arg_driverControls = glmsg.add_args();
+    arg_driverControls->set_isarray(false);
+    arg_driverControls->set_type(GLMessage::DataType::INT);
+    arg_driverControls->add_intvalue((int)driverControls);
+
+    // call function
+    glContext->hooks->gl.glGetDriverControlsQCOM(num, size, driverControls);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glGetDriverControlStringQCOM(GLuint driverControl, GLsizei bufSize, GLsizei *length, GLchar *driverControlString) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glGetDriverControlStringQCOM);
+
+    // copy argument driverControl
+    GLMessage_DataType *arg_driverControl = glmsg.add_args();
+    arg_driverControl->set_isarray(false);
+    arg_driverControl->set_type(GLMessage::DataType::INT);
+    arg_driverControl->add_intvalue(driverControl);
+
+    // copy argument bufSize
+    GLMessage_DataType *arg_bufSize = glmsg.add_args();
+    arg_bufSize->set_isarray(false);
+    arg_bufSize->set_type(GLMessage::DataType::INT);
+    arg_bufSize->add_intvalue(bufSize);
+
+    // copy argument length
+    GLMessage_DataType *arg_length = glmsg.add_args();
+    arg_length->set_isarray(false);
+    arg_length->set_type(GLMessage::DataType::INT);
+    arg_length->add_intvalue((int)length);
+
+    // copy argument driverControlString
+    GLMessage_DataType *arg_driverControlString = glmsg.add_args();
+    arg_driverControlString->set_isarray(false);
+    arg_driverControlString->set_type(GLMessage::DataType::INT);
+    arg_driverControlString->add_intvalue((int)driverControlString);
+
+    // call function
+    glContext->hooks->gl.glGetDriverControlStringQCOM(driverControl, bufSize, length, driverControlString);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glEnableDriverControlQCOM(GLuint driverControl) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glEnableDriverControlQCOM);
+
+    // copy argument driverControl
+    GLMessage_DataType *arg_driverControl = glmsg.add_args();
+    arg_driverControl->set_isarray(false);
+    arg_driverControl->set_type(GLMessage::DataType::INT);
+    arg_driverControl->add_intvalue(driverControl);
+
+    // call function
+    glContext->hooks->gl.glEnableDriverControlQCOM(driverControl);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glDisableDriverControlQCOM(GLuint driverControl) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glDisableDriverControlQCOM);
+
+    // copy argument driverControl
+    GLMessage_DataType *arg_driverControl = glmsg.add_args();
+    arg_driverControl->set_isarray(false);
+    arg_driverControl->set_type(GLMessage::DataType::INT);
+    arg_driverControl->add_intvalue(driverControl);
+
+    // call function
+    glContext->hooks->gl.glDisableDriverControlQCOM(driverControl);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glExtGetTexturesQCOM(GLuint *textures, GLint maxTextures, GLint *numTextures) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glExtGetTexturesQCOM);
+
+    // copy argument textures
+    GLMessage_DataType *arg_textures = glmsg.add_args();
+    arg_textures->set_isarray(false);
+    arg_textures->set_type(GLMessage::DataType::INT);
+    arg_textures->add_intvalue((int)textures);
+
+    // copy argument maxTextures
+    GLMessage_DataType *arg_maxTextures = glmsg.add_args();
+    arg_maxTextures->set_isarray(false);
+    arg_maxTextures->set_type(GLMessage::DataType::INT);
+    arg_maxTextures->add_intvalue(maxTextures);
+
+    // copy argument numTextures
+    GLMessage_DataType *arg_numTextures = glmsg.add_args();
+    arg_numTextures->set_isarray(false);
+    arg_numTextures->set_type(GLMessage::DataType::INT);
+    arg_numTextures->add_intvalue((int)numTextures);
+
+    // call function
+    glContext->hooks->gl.glExtGetTexturesQCOM(textures, maxTextures, numTextures);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glExtGetBuffersQCOM(GLuint *buffers, GLint maxBuffers, GLint *numBuffers) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glExtGetBuffersQCOM);
+
+    // copy argument buffers
+    GLMessage_DataType *arg_buffers = glmsg.add_args();
+    arg_buffers->set_isarray(false);
+    arg_buffers->set_type(GLMessage::DataType::INT);
+    arg_buffers->add_intvalue((int)buffers);
+
+    // copy argument maxBuffers
+    GLMessage_DataType *arg_maxBuffers = glmsg.add_args();
+    arg_maxBuffers->set_isarray(false);
+    arg_maxBuffers->set_type(GLMessage::DataType::INT);
+    arg_maxBuffers->add_intvalue(maxBuffers);
+
+    // copy argument numBuffers
+    GLMessage_DataType *arg_numBuffers = glmsg.add_args();
+    arg_numBuffers->set_isarray(false);
+    arg_numBuffers->set_type(GLMessage::DataType::INT);
+    arg_numBuffers->add_intvalue((int)numBuffers);
+
+    // call function
+    glContext->hooks->gl.glExtGetBuffersQCOM(buffers, maxBuffers, numBuffers);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glExtGetRenderbuffersQCOM(GLuint *renderbuffers, GLint maxRenderbuffers, GLint *numRenderbuffers) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glExtGetRenderbuffersQCOM);
+
+    // copy argument renderbuffers
+    GLMessage_DataType *arg_renderbuffers = glmsg.add_args();
+    arg_renderbuffers->set_isarray(false);
+    arg_renderbuffers->set_type(GLMessage::DataType::INT);
+    arg_renderbuffers->add_intvalue((int)renderbuffers);
+
+    // copy argument maxRenderbuffers
+    GLMessage_DataType *arg_maxRenderbuffers = glmsg.add_args();
+    arg_maxRenderbuffers->set_isarray(false);
+    arg_maxRenderbuffers->set_type(GLMessage::DataType::INT);
+    arg_maxRenderbuffers->add_intvalue(maxRenderbuffers);
+
+    // copy argument numRenderbuffers
+    GLMessage_DataType *arg_numRenderbuffers = glmsg.add_args();
+    arg_numRenderbuffers->set_isarray(false);
+    arg_numRenderbuffers->set_type(GLMessage::DataType::INT);
+    arg_numRenderbuffers->add_intvalue((int)numRenderbuffers);
+
+    // call function
+    glContext->hooks->gl.glExtGetRenderbuffersQCOM(renderbuffers, maxRenderbuffers, numRenderbuffers);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glExtGetFramebuffersQCOM(GLuint *framebuffers, GLint maxFramebuffers, GLint *numFramebuffers) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glExtGetFramebuffersQCOM);
+
+    // copy argument framebuffers
+    GLMessage_DataType *arg_framebuffers = glmsg.add_args();
+    arg_framebuffers->set_isarray(false);
+    arg_framebuffers->set_type(GLMessage::DataType::INT);
+    arg_framebuffers->add_intvalue((int)framebuffers);
+
+    // copy argument maxFramebuffers
+    GLMessage_DataType *arg_maxFramebuffers = glmsg.add_args();
+    arg_maxFramebuffers->set_isarray(false);
+    arg_maxFramebuffers->set_type(GLMessage::DataType::INT);
+    arg_maxFramebuffers->add_intvalue(maxFramebuffers);
+
+    // copy argument numFramebuffers
+    GLMessage_DataType *arg_numFramebuffers = glmsg.add_args();
+    arg_numFramebuffers->set_isarray(false);
+    arg_numFramebuffers->set_type(GLMessage::DataType::INT);
+    arg_numFramebuffers->add_intvalue((int)numFramebuffers);
+
+    // call function
+    glContext->hooks->gl.glExtGetFramebuffersQCOM(framebuffers, maxFramebuffers, numFramebuffers);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glExtGetTexLevelParameterivQCOM(GLuint texture, GLenum face, GLint level, GLenum pname, GLint *params) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glExtGetTexLevelParameterivQCOM);
+
+    // copy argument texture
+    GLMessage_DataType *arg_texture = glmsg.add_args();
+    arg_texture->set_isarray(false);
+    arg_texture->set_type(GLMessage::DataType::INT);
+    arg_texture->add_intvalue(texture);
+
+    // copy argument face
+    GLMessage_DataType *arg_face = glmsg.add_args();
+    arg_face->set_isarray(false);
+    arg_face->set_type(GLMessage::DataType::ENUM);
+    arg_face->add_intvalue((int)face);
+
+    // copy argument level
+    GLMessage_DataType *arg_level = glmsg.add_args();
+    arg_level->set_isarray(false);
+    arg_level->set_type(GLMessage::DataType::INT);
+    arg_level->add_intvalue(level);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument params
+    GLMessage_DataType *arg_params = glmsg.add_args();
+    arg_params->set_isarray(false);
+    arg_params->set_type(GLMessage::DataType::INT);
+    arg_params->add_intvalue((int)params);
+
+    // call function
+    glContext->hooks->gl.glExtGetTexLevelParameterivQCOM(texture, face, level, pname, params);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glExtTexObjectStateOverrideiQCOM(GLenum target, GLenum pname, GLint param) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glExtTexObjectStateOverrideiQCOM);
+
+    // copy argument target
+    GLMessage_DataType *arg_target = glmsg.add_args();
+    arg_target->set_isarray(false);
+    arg_target->set_type(GLMessage::DataType::ENUM);
+    arg_target->add_intvalue((int)target);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument param
+    GLMessage_DataType *arg_param = glmsg.add_args();
+    arg_param->set_isarray(false);
+    arg_param->set_type(GLMessage::DataType::INT);
+    arg_param->add_intvalue(param);
+
+    // call function
+    glContext->hooks->gl.glExtTexObjectStateOverrideiQCOM(target, pname, param);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glExtGetTexSubImageQCOM(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLvoid *texels) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glExtGetTexSubImageQCOM);
+
+    // copy argument target
+    GLMessage_DataType *arg_target = glmsg.add_args();
+    arg_target->set_isarray(false);
+    arg_target->set_type(GLMessage::DataType::ENUM);
+    arg_target->add_intvalue((int)target);
+
+    // copy argument level
+    GLMessage_DataType *arg_level = glmsg.add_args();
+    arg_level->set_isarray(false);
+    arg_level->set_type(GLMessage::DataType::INT);
+    arg_level->add_intvalue(level);
+
+    // copy argument xoffset
+    GLMessage_DataType *arg_xoffset = glmsg.add_args();
+    arg_xoffset->set_isarray(false);
+    arg_xoffset->set_type(GLMessage::DataType::INT);
+    arg_xoffset->add_intvalue(xoffset);
+
+    // copy argument yoffset
+    GLMessage_DataType *arg_yoffset = glmsg.add_args();
+    arg_yoffset->set_isarray(false);
+    arg_yoffset->set_type(GLMessage::DataType::INT);
+    arg_yoffset->add_intvalue(yoffset);
+
+    // copy argument zoffset
+    GLMessage_DataType *arg_zoffset = glmsg.add_args();
+    arg_zoffset->set_isarray(false);
+    arg_zoffset->set_type(GLMessage::DataType::INT);
+    arg_zoffset->add_intvalue(zoffset);
+
+    // copy argument width
+    GLMessage_DataType *arg_width = glmsg.add_args();
+    arg_width->set_isarray(false);
+    arg_width->set_type(GLMessage::DataType::INT);
+    arg_width->add_intvalue(width);
+
+    // copy argument height
+    GLMessage_DataType *arg_height = glmsg.add_args();
+    arg_height->set_isarray(false);
+    arg_height->set_type(GLMessage::DataType::INT);
+    arg_height->add_intvalue(height);
+
+    // copy argument depth
+    GLMessage_DataType *arg_depth = glmsg.add_args();
+    arg_depth->set_isarray(false);
+    arg_depth->set_type(GLMessage::DataType::INT);
+    arg_depth->add_intvalue(depth);
+
+    // copy argument format
+    GLMessage_DataType *arg_format = glmsg.add_args();
+    arg_format->set_isarray(false);
+    arg_format->set_type(GLMessage::DataType::ENUM);
+    arg_format->add_intvalue((int)format);
+
+    // copy argument type
+    GLMessage_DataType *arg_type = glmsg.add_args();
+    arg_type->set_isarray(false);
+    arg_type->set_type(GLMessage::DataType::ENUM);
+    arg_type->add_intvalue((int)type);
+
+    // copy argument texels
+    GLMessage_DataType *arg_texels = glmsg.add_args();
+    arg_texels->set_isarray(false);
+    arg_texels->set_type(GLMessage::DataType::INT);
+    arg_texels->add_intvalue((int)texels);
+
+    // call function
+    glContext->hooks->gl.glExtGetTexSubImageQCOM(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, texels);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glExtGetBufferPointervQCOM(GLenum target, GLvoid **params) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glExtGetBufferPointervQCOM);
+
+    // copy argument target
+    GLMessage_DataType *arg_target = glmsg.add_args();
+    arg_target->set_isarray(false);
+    arg_target->set_type(GLMessage::DataType::ENUM);
+    arg_target->add_intvalue((int)target);
+
+    // copy argument params
+    GLMessage_DataType *arg_params = glmsg.add_args();
+    arg_params->set_isarray(false);
+    arg_params->set_type(GLMessage::DataType::INT);
+    arg_params->add_intvalue((int)params);
+
+    // call function
+    glContext->hooks->gl.glExtGetBufferPointervQCOM(target, params);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glExtGetShadersQCOM(GLuint *shaders, GLint maxShaders, GLint *numShaders) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glExtGetShadersQCOM);
+
+    // copy argument shaders
+    GLMessage_DataType *arg_shaders = glmsg.add_args();
+    arg_shaders->set_isarray(false);
+    arg_shaders->set_type(GLMessage::DataType::INT);
+    arg_shaders->add_intvalue((int)shaders);
+
+    // copy argument maxShaders
+    GLMessage_DataType *arg_maxShaders = glmsg.add_args();
+    arg_maxShaders->set_isarray(false);
+    arg_maxShaders->set_type(GLMessage::DataType::INT);
+    arg_maxShaders->add_intvalue(maxShaders);
+
+    // copy argument numShaders
+    GLMessage_DataType *arg_numShaders = glmsg.add_args();
+    arg_numShaders->set_isarray(false);
+    arg_numShaders->set_type(GLMessage::DataType::INT);
+    arg_numShaders->add_intvalue((int)numShaders);
+
+    // call function
+    glContext->hooks->gl.glExtGetShadersQCOM(shaders, maxShaders, numShaders);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glExtGetProgramsQCOM(GLuint *programs, GLint maxPrograms, GLint *numPrograms) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glExtGetProgramsQCOM);
+
+    // copy argument programs
+    GLMessage_DataType *arg_programs = glmsg.add_args();
+    arg_programs->set_isarray(false);
+    arg_programs->set_type(GLMessage::DataType::INT);
+    arg_programs->add_intvalue((int)programs);
+
+    // copy argument maxPrograms
+    GLMessage_DataType *arg_maxPrograms = glmsg.add_args();
+    arg_maxPrograms->set_isarray(false);
+    arg_maxPrograms->set_type(GLMessage::DataType::INT);
+    arg_maxPrograms->add_intvalue(maxPrograms);
+
+    // copy argument numPrograms
+    GLMessage_DataType *arg_numPrograms = glmsg.add_args();
+    arg_numPrograms->set_isarray(false);
+    arg_numPrograms->set_type(GLMessage::DataType::INT);
+    arg_numPrograms->add_intvalue((int)numPrograms);
+
+    // call function
+    glContext->hooks->gl.glExtGetProgramsQCOM(programs, maxPrograms, numPrograms);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+GLboolean GLTrace_glExtIsProgramBinaryQCOM(GLuint program) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glExtIsProgramBinaryQCOM);
+
+    // copy argument program
+    GLMessage_DataType *arg_program = glmsg.add_args();
+    arg_program->set_isarray(false);
+    arg_program->set_type(GLMessage::DataType::INT);
+    arg_program->add_intvalue(program);
+
+    // call function
+    GLboolean retValue = glContext->hooks->gl.glExtIsProgramBinaryQCOM(program);
+
+    // set return value
+    GLMessage_DataType *rt = glmsg.mutable_returnvalue();
+    rt->set_isarray(false);
+    rt->set_type(GLMessage::DataType::BOOL);
+    rt->add_boolvalue(retValue);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+
+    return retValue;
+}
+
+void GLTrace_glExtGetProgramBinarySourceQCOM(GLuint program, GLenum shadertype, GLchar *source, GLint *length) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glExtGetProgramBinarySourceQCOM);
+
+    // copy argument program
+    GLMessage_DataType *arg_program = glmsg.add_args();
+    arg_program->set_isarray(false);
+    arg_program->set_type(GLMessage::DataType::INT);
+    arg_program->add_intvalue(program);
+
+    // copy argument shadertype
+    GLMessage_DataType *arg_shadertype = glmsg.add_args();
+    arg_shadertype->set_isarray(false);
+    arg_shadertype->set_type(GLMessage::DataType::ENUM);
+    arg_shadertype->add_intvalue((int)shadertype);
+
+    // copy argument source
+    GLMessage_DataType *arg_source = glmsg.add_args();
+    arg_source->set_isarray(false);
+    arg_source->set_type(GLMessage::DataType::INT);
+    arg_source->add_intvalue((int)source);
+
+    // copy argument length
+    GLMessage_DataType *arg_length = glmsg.add_args();
+    arg_length->set_isarray(false);
+    arg_length->set_type(GLMessage::DataType::INT);
+    arg_length->add_intvalue((int)length);
+
+    // call function
+    glContext->hooks->gl.glExtGetProgramBinarySourceQCOM(program, shadertype, source, length);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glStartTilingQCOM(GLuint x, GLuint y, GLuint width, GLuint height, GLbitfield preserveMask) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glStartTilingQCOM);
+
+    // copy argument x
+    GLMessage_DataType *arg_x = glmsg.add_args();
+    arg_x->set_isarray(false);
+    arg_x->set_type(GLMessage::DataType::INT);
+    arg_x->add_intvalue(x);
+
+    // copy argument y
+    GLMessage_DataType *arg_y = glmsg.add_args();
+    arg_y->set_isarray(false);
+    arg_y->set_type(GLMessage::DataType::INT);
+    arg_y->add_intvalue(y);
+
+    // copy argument width
+    GLMessage_DataType *arg_width = glmsg.add_args();
+    arg_width->set_isarray(false);
+    arg_width->set_type(GLMessage::DataType::INT);
+    arg_width->add_intvalue(width);
+
+    // copy argument height
+    GLMessage_DataType *arg_height = glmsg.add_args();
+    arg_height->set_isarray(false);
+    arg_height->set_type(GLMessage::DataType::INT);
+    arg_height->add_intvalue(height);
+
+    // copy argument preserveMask
+    GLMessage_DataType *arg_preserveMask = glmsg.add_args();
+    arg_preserveMask->set_isarray(false);
+    arg_preserveMask->set_type(GLMessage::DataType::INT);
+    arg_preserveMask->add_intvalue(preserveMask);
+
+    // call function
+    glContext->hooks->gl.glStartTilingQCOM(x, y, width, height, preserveMask);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glEndTilingQCOM(GLbitfield preserveMask) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glEndTilingQCOM);
+
+    // copy argument preserveMask
+    GLMessage_DataType *arg_preserveMask = glmsg.add_args();
+    arg_preserveMask->set_isarray(false);
+    arg_preserveMask->set_type(GLMessage::DataType::INT);
+    arg_preserveMask->add_intvalue(preserveMask);
+
+    // call function
+    glContext->hooks->gl.glEndTilingQCOM(preserveMask);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+
+// Definitions for GL1 APIs
+
+void GLTrace_glAlphaFunc(GLenum func, GLclampf ref) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glAlphaFunc);
+
+    // copy argument func
+    GLMessage_DataType *arg_func = glmsg.add_args();
+    arg_func->set_isarray(false);
+    arg_func->set_type(GLMessage::DataType::ENUM);
+    arg_func->add_intvalue((int)func);
+
+    // copy argument ref
+    GLMessage_DataType *arg_ref = glmsg.add_args();
+    arg_ref->set_isarray(false);
+    arg_ref->set_type(GLMessage::DataType::FLOAT);
+    arg_ref->add_floatvalue(ref);
+
+    // call function
+    glContext->hooks->gl.glAlphaFunc(func, ref);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glClipPlanef(GLenum plane, const GLfloat *equation) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glClipPlanef);
+
+    // copy argument plane
+    GLMessage_DataType *arg_plane = glmsg.add_args();
+    arg_plane->set_isarray(false);
+    arg_plane->set_type(GLMessage::DataType::ENUM);
+    arg_plane->add_intvalue((int)plane);
+
+    // copy argument equation
+    GLMessage_DataType *arg_equation = glmsg.add_args();
+    arg_equation->set_isarray(false);
+    arg_equation->set_type(GLMessage::DataType::INT);
+    arg_equation->add_intvalue((int)equation);
+
+    // call function
+    glContext->hooks->gl.glClipPlanef(plane, equation);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glColor4f);
+
+    // copy argument red
+    GLMessage_DataType *arg_red = glmsg.add_args();
+    arg_red->set_isarray(false);
+    arg_red->set_type(GLMessage::DataType::FLOAT);
+    arg_red->add_floatvalue(red);
+
+    // copy argument green
+    GLMessage_DataType *arg_green = glmsg.add_args();
+    arg_green->set_isarray(false);
+    arg_green->set_type(GLMessage::DataType::FLOAT);
+    arg_green->add_floatvalue(green);
+
+    // copy argument blue
+    GLMessage_DataType *arg_blue = glmsg.add_args();
+    arg_blue->set_isarray(false);
+    arg_blue->set_type(GLMessage::DataType::FLOAT);
+    arg_blue->add_floatvalue(blue);
+
+    // copy argument alpha
+    GLMessage_DataType *arg_alpha = glmsg.add_args();
+    arg_alpha->set_isarray(false);
+    arg_alpha->set_type(GLMessage::DataType::FLOAT);
+    arg_alpha->add_floatvalue(alpha);
+
+    // call function
+    glContext->hooks->gl.glColor4f(red, green, blue, alpha);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glFogf(GLenum pname, GLfloat param) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glFogf);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument param
+    GLMessage_DataType *arg_param = glmsg.add_args();
+    arg_param->set_isarray(false);
+    arg_param->set_type(GLMessage::DataType::FLOAT);
+    arg_param->add_floatvalue(param);
+
+    // call function
+    glContext->hooks->gl.glFogf(pname, param);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glFogfv(GLenum pname, const GLfloat *params) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glFogfv);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument params
+    GLMessage_DataType *arg_params = glmsg.add_args();
+    arg_params->set_isarray(false);
+    arg_params->set_type(GLMessage::DataType::INT);
+    arg_params->add_intvalue((int)params);
+
+    // call function
+    glContext->hooks->gl.glFogfv(pname, params);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glFrustumf(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glFrustumf);
+
+    // copy argument left
+    GLMessage_DataType *arg_left = glmsg.add_args();
+    arg_left->set_isarray(false);
+    arg_left->set_type(GLMessage::DataType::FLOAT);
+    arg_left->add_floatvalue(left);
+
+    // copy argument right
+    GLMessage_DataType *arg_right = glmsg.add_args();
+    arg_right->set_isarray(false);
+    arg_right->set_type(GLMessage::DataType::FLOAT);
+    arg_right->add_floatvalue(right);
+
+    // copy argument bottom
+    GLMessage_DataType *arg_bottom = glmsg.add_args();
+    arg_bottom->set_isarray(false);
+    arg_bottom->set_type(GLMessage::DataType::FLOAT);
+    arg_bottom->add_floatvalue(bottom);
+
+    // copy argument top
+    GLMessage_DataType *arg_top = glmsg.add_args();
+    arg_top->set_isarray(false);
+    arg_top->set_type(GLMessage::DataType::FLOAT);
+    arg_top->add_floatvalue(top);
+
+    // copy argument zNear
+    GLMessage_DataType *arg_zNear = glmsg.add_args();
+    arg_zNear->set_isarray(false);
+    arg_zNear->set_type(GLMessage::DataType::FLOAT);
+    arg_zNear->add_floatvalue(zNear);
+
+    // copy argument zFar
+    GLMessage_DataType *arg_zFar = glmsg.add_args();
+    arg_zFar->set_isarray(false);
+    arg_zFar->set_type(GLMessage::DataType::FLOAT);
+    arg_zFar->add_floatvalue(zFar);
+
+    // call function
+    glContext->hooks->gl.glFrustumf(left, right, bottom, top, zNear, zFar);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glGetClipPlanef(GLenum pname, GLfloat eqn[4]) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glGetClipPlanef);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument eqn
+    GLMessage_DataType *arg_eqn = glmsg.add_args();
+    arg_eqn->set_isarray(false);
+    arg_eqn->set_type(GLMessage::DataType::INT);
+    arg_eqn->add_intvalue((int)eqn);
+
+    // call function
+    glContext->hooks->gl.glGetClipPlanef(pname, eqn);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glGetLightfv(GLenum light, GLenum pname, GLfloat *params) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glGetLightfv);
+
+    // copy argument light
+    GLMessage_DataType *arg_light = glmsg.add_args();
+    arg_light->set_isarray(false);
+    arg_light->set_type(GLMessage::DataType::ENUM);
+    arg_light->add_intvalue((int)light);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument params
+    GLMessage_DataType *arg_params = glmsg.add_args();
+    arg_params->set_isarray(false);
+    arg_params->set_type(GLMessage::DataType::INT);
+    arg_params->add_intvalue((int)params);
+
+    // call function
+    glContext->hooks->gl.glGetLightfv(light, pname, params);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glGetMaterialfv(GLenum face, GLenum pname, GLfloat *params) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glGetMaterialfv);
+
+    // copy argument face
+    GLMessage_DataType *arg_face = glmsg.add_args();
+    arg_face->set_isarray(false);
+    arg_face->set_type(GLMessage::DataType::ENUM);
+    arg_face->add_intvalue((int)face);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument params
+    GLMessage_DataType *arg_params = glmsg.add_args();
+    arg_params->set_isarray(false);
+    arg_params->set_type(GLMessage::DataType::INT);
+    arg_params->add_intvalue((int)params);
+
+    // call function
+    glContext->hooks->gl.glGetMaterialfv(face, pname, params);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glGetTexEnvfv(GLenum env, GLenum pname, GLfloat *params) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glGetTexEnvfv);
+
+    // copy argument env
+    GLMessage_DataType *arg_env = glmsg.add_args();
+    arg_env->set_isarray(false);
+    arg_env->set_type(GLMessage::DataType::ENUM);
+    arg_env->add_intvalue((int)env);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument params
+    GLMessage_DataType *arg_params = glmsg.add_args();
+    arg_params->set_isarray(false);
+    arg_params->set_type(GLMessage::DataType::INT);
+    arg_params->add_intvalue((int)params);
+
+    // call function
+    glContext->hooks->gl.glGetTexEnvfv(env, pname, params);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glLightModelf(GLenum pname, GLfloat param) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glLightModelf);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument param
+    GLMessage_DataType *arg_param = glmsg.add_args();
+    arg_param->set_isarray(false);
+    arg_param->set_type(GLMessage::DataType::FLOAT);
+    arg_param->add_floatvalue(param);
+
+    // call function
+    glContext->hooks->gl.glLightModelf(pname, param);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glLightModelfv(GLenum pname, const GLfloat *params) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glLightModelfv);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument params
+    GLMessage_DataType *arg_params = glmsg.add_args();
+    arg_params->set_isarray(false);
+    arg_params->set_type(GLMessage::DataType::INT);
+    arg_params->add_intvalue((int)params);
+
+    // call function
+    glContext->hooks->gl.glLightModelfv(pname, params);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glLightf(GLenum light, GLenum pname, GLfloat param) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glLightf);
+
+    // copy argument light
+    GLMessage_DataType *arg_light = glmsg.add_args();
+    arg_light->set_isarray(false);
+    arg_light->set_type(GLMessage::DataType::ENUM);
+    arg_light->add_intvalue((int)light);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument param
+    GLMessage_DataType *arg_param = glmsg.add_args();
+    arg_param->set_isarray(false);
+    arg_param->set_type(GLMessage::DataType::FLOAT);
+    arg_param->add_floatvalue(param);
+
+    // call function
+    glContext->hooks->gl.glLightf(light, pname, param);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glLightfv(GLenum light, GLenum pname, const GLfloat *params) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glLightfv);
+
+    // copy argument light
+    GLMessage_DataType *arg_light = glmsg.add_args();
+    arg_light->set_isarray(false);
+    arg_light->set_type(GLMessage::DataType::ENUM);
+    arg_light->add_intvalue((int)light);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument params
+    GLMessage_DataType *arg_params = glmsg.add_args();
+    arg_params->set_isarray(false);
+    arg_params->set_type(GLMessage::DataType::INT);
+    arg_params->add_intvalue((int)params);
+
+    // call function
+    glContext->hooks->gl.glLightfv(light, pname, params);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glLoadMatrixf(const GLfloat *m) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glLoadMatrixf);
+
+    // copy argument m
+    GLMessage_DataType *arg_m = glmsg.add_args();
+    arg_m->set_isarray(false);
+    arg_m->set_type(GLMessage::DataType::INT);
+    arg_m->add_intvalue((int)m);
+
+    // call function
+    glContext->hooks->gl.glLoadMatrixf(m);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glMaterialf(GLenum face, GLenum pname, GLfloat param) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glMaterialf);
+
+    // copy argument face
+    GLMessage_DataType *arg_face = glmsg.add_args();
+    arg_face->set_isarray(false);
+    arg_face->set_type(GLMessage::DataType::ENUM);
+    arg_face->add_intvalue((int)face);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument param
+    GLMessage_DataType *arg_param = glmsg.add_args();
+    arg_param->set_isarray(false);
+    arg_param->set_type(GLMessage::DataType::FLOAT);
+    arg_param->add_floatvalue(param);
+
+    // call function
+    glContext->hooks->gl.glMaterialf(face, pname, param);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glMaterialfv(GLenum face, GLenum pname, const GLfloat *params) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glMaterialfv);
+
+    // copy argument face
+    GLMessage_DataType *arg_face = glmsg.add_args();
+    arg_face->set_isarray(false);
+    arg_face->set_type(GLMessage::DataType::ENUM);
+    arg_face->add_intvalue((int)face);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument params
+    GLMessage_DataType *arg_params = glmsg.add_args();
+    arg_params->set_isarray(false);
+    arg_params->set_type(GLMessage::DataType::INT);
+    arg_params->add_intvalue((int)params);
+
+    // call function
+    glContext->hooks->gl.glMaterialfv(face, pname, params);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glMultMatrixf(const GLfloat *m) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glMultMatrixf);
+
+    // copy argument m
+    GLMessage_DataType *arg_m = glmsg.add_args();
+    arg_m->set_isarray(false);
+    arg_m->set_type(GLMessage::DataType::INT);
+    arg_m->add_intvalue((int)m);
+
+    // call function
+    glContext->hooks->gl.glMultMatrixf(m);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glMultiTexCoord4f(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glMultiTexCoord4f);
+
+    // copy argument target
+    GLMessage_DataType *arg_target = glmsg.add_args();
+    arg_target->set_isarray(false);
+    arg_target->set_type(GLMessage::DataType::ENUM);
+    arg_target->add_intvalue((int)target);
+
+    // copy argument s
+    GLMessage_DataType *arg_s = glmsg.add_args();
+    arg_s->set_isarray(false);
+    arg_s->set_type(GLMessage::DataType::FLOAT);
+    arg_s->add_floatvalue(s);
+
+    // copy argument t
+    GLMessage_DataType *arg_t = glmsg.add_args();
+    arg_t->set_isarray(false);
+    arg_t->set_type(GLMessage::DataType::FLOAT);
+    arg_t->add_floatvalue(t);
+
+    // copy argument r
+    GLMessage_DataType *arg_r = glmsg.add_args();
+    arg_r->set_isarray(false);
+    arg_r->set_type(GLMessage::DataType::FLOAT);
+    arg_r->add_floatvalue(r);
+
+    // copy argument q
+    GLMessage_DataType *arg_q = glmsg.add_args();
+    arg_q->set_isarray(false);
+    arg_q->set_type(GLMessage::DataType::FLOAT);
+    arg_q->add_floatvalue(q);
+
+    // call function
+    glContext->hooks->gl.glMultiTexCoord4f(target, s, t, r, q);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glNormal3f(GLfloat nx, GLfloat ny, GLfloat nz) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glNormal3f);
+
+    // copy argument nx
+    GLMessage_DataType *arg_nx = glmsg.add_args();
+    arg_nx->set_isarray(false);
+    arg_nx->set_type(GLMessage::DataType::FLOAT);
+    arg_nx->add_floatvalue(nx);
+
+    // copy argument ny
+    GLMessage_DataType *arg_ny = glmsg.add_args();
+    arg_ny->set_isarray(false);
+    arg_ny->set_type(GLMessage::DataType::FLOAT);
+    arg_ny->add_floatvalue(ny);
+
+    // copy argument nz
+    GLMessage_DataType *arg_nz = glmsg.add_args();
+    arg_nz->set_isarray(false);
+    arg_nz->set_type(GLMessage::DataType::FLOAT);
+    arg_nz->add_floatvalue(nz);
+
+    // call function
+    glContext->hooks->gl.glNormal3f(nx, ny, nz);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glOrthof(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glOrthof);
+
+    // copy argument left
+    GLMessage_DataType *arg_left = glmsg.add_args();
+    arg_left->set_isarray(false);
+    arg_left->set_type(GLMessage::DataType::FLOAT);
+    arg_left->add_floatvalue(left);
+
+    // copy argument right
+    GLMessage_DataType *arg_right = glmsg.add_args();
+    arg_right->set_isarray(false);
+    arg_right->set_type(GLMessage::DataType::FLOAT);
+    arg_right->add_floatvalue(right);
+
+    // copy argument bottom
+    GLMessage_DataType *arg_bottom = glmsg.add_args();
+    arg_bottom->set_isarray(false);
+    arg_bottom->set_type(GLMessage::DataType::FLOAT);
+    arg_bottom->add_floatvalue(bottom);
+
+    // copy argument top
+    GLMessage_DataType *arg_top = glmsg.add_args();
+    arg_top->set_isarray(false);
+    arg_top->set_type(GLMessage::DataType::FLOAT);
+    arg_top->add_floatvalue(top);
+
+    // copy argument zNear
+    GLMessage_DataType *arg_zNear = glmsg.add_args();
+    arg_zNear->set_isarray(false);
+    arg_zNear->set_type(GLMessage::DataType::FLOAT);
+    arg_zNear->add_floatvalue(zNear);
+
+    // copy argument zFar
+    GLMessage_DataType *arg_zFar = glmsg.add_args();
+    arg_zFar->set_isarray(false);
+    arg_zFar->set_type(GLMessage::DataType::FLOAT);
+    arg_zFar->add_floatvalue(zFar);
+
+    // call function
+    glContext->hooks->gl.glOrthof(left, right, bottom, top, zNear, zFar);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glPointParameterf(GLenum pname, GLfloat param) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glPointParameterf);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument param
+    GLMessage_DataType *arg_param = glmsg.add_args();
+    arg_param->set_isarray(false);
+    arg_param->set_type(GLMessage::DataType::FLOAT);
+    arg_param->add_floatvalue(param);
+
+    // call function
+    glContext->hooks->gl.glPointParameterf(pname, param);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glPointParameterfv(GLenum pname, const GLfloat *params) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glPointParameterfv);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument params
+    GLMessage_DataType *arg_params = glmsg.add_args();
+    arg_params->set_isarray(false);
+    arg_params->set_type(GLMessage::DataType::INT);
+    arg_params->add_intvalue((int)params);
+
+    // call function
+    glContext->hooks->gl.glPointParameterfv(pname, params);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glPointSize(GLfloat size) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glPointSize);
+
+    // copy argument size
+    GLMessage_DataType *arg_size = glmsg.add_args();
+    arg_size->set_isarray(false);
+    arg_size->set_type(GLMessage::DataType::FLOAT);
+    arg_size->add_floatvalue(size);
+
+    // call function
+    glContext->hooks->gl.glPointSize(size);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glRotatef);
+
+    // copy argument angle
+    GLMessage_DataType *arg_angle = glmsg.add_args();
+    arg_angle->set_isarray(false);
+    arg_angle->set_type(GLMessage::DataType::FLOAT);
+    arg_angle->add_floatvalue(angle);
+
+    // copy argument x
+    GLMessage_DataType *arg_x = glmsg.add_args();
+    arg_x->set_isarray(false);
+    arg_x->set_type(GLMessage::DataType::FLOAT);
+    arg_x->add_floatvalue(x);
+
+    // copy argument y
+    GLMessage_DataType *arg_y = glmsg.add_args();
+    arg_y->set_isarray(false);
+    arg_y->set_type(GLMessage::DataType::FLOAT);
+    arg_y->add_floatvalue(y);
+
+    // copy argument z
+    GLMessage_DataType *arg_z = glmsg.add_args();
+    arg_z->set_isarray(false);
+    arg_z->set_type(GLMessage::DataType::FLOAT);
+    arg_z->add_floatvalue(z);
+
+    // call function
+    glContext->hooks->gl.glRotatef(angle, x, y, z);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glScalef(GLfloat x, GLfloat y, GLfloat z) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glScalef);
+
+    // copy argument x
+    GLMessage_DataType *arg_x = glmsg.add_args();
+    arg_x->set_isarray(false);
+    arg_x->set_type(GLMessage::DataType::FLOAT);
+    arg_x->add_floatvalue(x);
+
+    // copy argument y
+    GLMessage_DataType *arg_y = glmsg.add_args();
+    arg_y->set_isarray(false);
+    arg_y->set_type(GLMessage::DataType::FLOAT);
+    arg_y->add_floatvalue(y);
+
+    // copy argument z
+    GLMessage_DataType *arg_z = glmsg.add_args();
+    arg_z->set_isarray(false);
+    arg_z->set_type(GLMessage::DataType::FLOAT);
+    arg_z->add_floatvalue(z);
+
+    // call function
+    glContext->hooks->gl.glScalef(x, y, z);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glTexEnvf(GLenum target, GLenum pname, GLfloat param) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glTexEnvf);
+
+    // copy argument target
+    GLMessage_DataType *arg_target = glmsg.add_args();
+    arg_target->set_isarray(false);
+    arg_target->set_type(GLMessage::DataType::ENUM);
+    arg_target->add_intvalue((int)target);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument param
+    GLMessage_DataType *arg_param = glmsg.add_args();
+    arg_param->set_isarray(false);
+    arg_param->set_type(GLMessage::DataType::FLOAT);
+    arg_param->add_floatvalue(param);
+
+    // call function
+    glContext->hooks->gl.glTexEnvf(target, pname, param);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glTexEnvfv(GLenum target, GLenum pname, const GLfloat *params) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glTexEnvfv);
+
+    // copy argument target
+    GLMessage_DataType *arg_target = glmsg.add_args();
+    arg_target->set_isarray(false);
+    arg_target->set_type(GLMessage::DataType::ENUM);
+    arg_target->add_intvalue((int)target);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument params
+    GLMessage_DataType *arg_params = glmsg.add_args();
+    arg_params->set_isarray(false);
+    arg_params->set_type(GLMessage::DataType::INT);
+    arg_params->add_intvalue((int)params);
+
+    // call function
+    glContext->hooks->gl.glTexEnvfv(target, pname, params);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glTranslatef(GLfloat x, GLfloat y, GLfloat z) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glTranslatef);
+
+    // copy argument x
+    GLMessage_DataType *arg_x = glmsg.add_args();
+    arg_x->set_isarray(false);
+    arg_x->set_type(GLMessage::DataType::FLOAT);
+    arg_x->add_floatvalue(x);
+
+    // copy argument y
+    GLMessage_DataType *arg_y = glmsg.add_args();
+    arg_y->set_isarray(false);
+    arg_y->set_type(GLMessage::DataType::FLOAT);
+    arg_y->add_floatvalue(y);
+
+    // copy argument z
+    GLMessage_DataType *arg_z = glmsg.add_args();
+    arg_z->set_isarray(false);
+    arg_z->set_type(GLMessage::DataType::FLOAT);
+    arg_z->add_floatvalue(z);
+
+    // call function
+    glContext->hooks->gl.glTranslatef(x, y, z);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glAlphaFuncx(GLenum func, GLclampx ref) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glAlphaFuncx);
+
+    // copy argument func
+    GLMessage_DataType *arg_func = glmsg.add_args();
+    arg_func->set_isarray(false);
+    arg_func->set_type(GLMessage::DataType::ENUM);
+    arg_func->add_intvalue((int)func);
+
+    // copy argument ref
+    GLMessage_DataType *arg_ref = glmsg.add_args();
+    arg_ref->set_isarray(false);
+    arg_ref->set_type(GLMessage::DataType::INT);
+    arg_ref->add_intvalue(ref);
+
+    // call function
+    glContext->hooks->gl.glAlphaFuncx(func, ref);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glClearColorx(GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glClearColorx);
+
+    // copy argument red
+    GLMessage_DataType *arg_red = glmsg.add_args();
+    arg_red->set_isarray(false);
+    arg_red->set_type(GLMessage::DataType::INT);
+    arg_red->add_intvalue(red);
+
+    // copy argument green
+    GLMessage_DataType *arg_green = glmsg.add_args();
+    arg_green->set_isarray(false);
+    arg_green->set_type(GLMessage::DataType::INT);
+    arg_green->add_intvalue(green);
+
+    // copy argument blue
+    GLMessage_DataType *arg_blue = glmsg.add_args();
+    arg_blue->set_isarray(false);
+    arg_blue->set_type(GLMessage::DataType::INT);
+    arg_blue->add_intvalue(blue);
+
+    // copy argument alpha
+    GLMessage_DataType *arg_alpha = glmsg.add_args();
+    arg_alpha->set_isarray(false);
+    arg_alpha->set_type(GLMessage::DataType::INT);
+    arg_alpha->add_intvalue(alpha);
+
+    // call function
+    glContext->hooks->gl.glClearColorx(red, green, blue, alpha);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glClearDepthx(GLclampx depth) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glClearDepthx);
+
+    // copy argument depth
+    GLMessage_DataType *arg_depth = glmsg.add_args();
+    arg_depth->set_isarray(false);
+    arg_depth->set_type(GLMessage::DataType::INT);
+    arg_depth->add_intvalue(depth);
+
+    // call function
+    glContext->hooks->gl.glClearDepthx(depth);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glClientActiveTexture(GLenum texture) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glClientActiveTexture);
+
+    // copy argument texture
+    GLMessage_DataType *arg_texture = glmsg.add_args();
+    arg_texture->set_isarray(false);
+    arg_texture->set_type(GLMessage::DataType::ENUM);
+    arg_texture->add_intvalue((int)texture);
+
+    // call function
+    glContext->hooks->gl.glClientActiveTexture(texture);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glClipPlanex(GLenum plane, const GLfixed *equation) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glClipPlanex);
+
+    // copy argument plane
+    GLMessage_DataType *arg_plane = glmsg.add_args();
+    arg_plane->set_isarray(false);
+    arg_plane->set_type(GLMessage::DataType::ENUM);
+    arg_plane->add_intvalue((int)plane);
+
+    // copy argument equation
+    GLMessage_DataType *arg_equation = glmsg.add_args();
+    arg_equation->set_isarray(false);
+    arg_equation->set_type(GLMessage::DataType::INT);
+    arg_equation->add_intvalue((int)equation);
+
+    // call function
+    glContext->hooks->gl.glClipPlanex(plane, equation);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glColor4ub(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glColor4ub);
+
+    // copy argument red
+    GLMessage_DataType *arg_red = glmsg.add_args();
+    arg_red->set_isarray(false);
+    arg_red->set_type(GLMessage::DataType::BYTE);
+    arg_red->add_intvalue((int)red);
+
+    // copy argument green
+    GLMessage_DataType *arg_green = glmsg.add_args();
+    arg_green->set_isarray(false);
+    arg_green->set_type(GLMessage::DataType::BYTE);
+    arg_green->add_intvalue((int)green);
+
+    // copy argument blue
+    GLMessage_DataType *arg_blue = glmsg.add_args();
+    arg_blue->set_isarray(false);
+    arg_blue->set_type(GLMessage::DataType::BYTE);
+    arg_blue->add_intvalue((int)blue);
+
+    // copy argument alpha
+    GLMessage_DataType *arg_alpha = glmsg.add_args();
+    arg_alpha->set_isarray(false);
+    arg_alpha->set_type(GLMessage::DataType::BYTE);
+    arg_alpha->add_intvalue((int)alpha);
+
+    // call function
+    glContext->hooks->gl.glColor4ub(red, green, blue, alpha);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glColor4x(GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glColor4x);
+
+    // copy argument red
+    GLMessage_DataType *arg_red = glmsg.add_args();
+    arg_red->set_isarray(false);
+    arg_red->set_type(GLMessage::DataType::INT);
+    arg_red->add_intvalue(red);
+
+    // copy argument green
+    GLMessage_DataType *arg_green = glmsg.add_args();
+    arg_green->set_isarray(false);
+    arg_green->set_type(GLMessage::DataType::INT);
+    arg_green->add_intvalue(green);
+
+    // copy argument blue
+    GLMessage_DataType *arg_blue = glmsg.add_args();
+    arg_blue->set_isarray(false);
+    arg_blue->set_type(GLMessage::DataType::INT);
+    arg_blue->add_intvalue(blue);
+
+    // copy argument alpha
+    GLMessage_DataType *arg_alpha = glmsg.add_args();
+    arg_alpha->set_isarray(false);
+    arg_alpha->set_type(GLMessage::DataType::INT);
+    arg_alpha->add_intvalue(alpha);
+
+    // call function
+    glContext->hooks->gl.glColor4x(red, green, blue, alpha);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glColorPointer);
+
+    // copy argument size
+    GLMessage_DataType *arg_size = glmsg.add_args();
+    arg_size->set_isarray(false);
+    arg_size->set_type(GLMessage::DataType::INT);
+    arg_size->add_intvalue(size);
+
+    // copy argument type
+    GLMessage_DataType *arg_type = glmsg.add_args();
+    arg_type->set_isarray(false);
+    arg_type->set_type(GLMessage::DataType::ENUM);
+    arg_type->add_intvalue((int)type);
+
+    // copy argument stride
+    GLMessage_DataType *arg_stride = glmsg.add_args();
+    arg_stride->set_isarray(false);
+    arg_stride->set_type(GLMessage::DataType::INT);
+    arg_stride->add_intvalue(stride);
+
+    // copy argument pointer
+    GLMessage_DataType *arg_pointer = glmsg.add_args();
+    arg_pointer->set_isarray(false);
+    arg_pointer->set_type(GLMessage::DataType::INT);
+    arg_pointer->add_intvalue((int)pointer);
+
+    // call function
+    glContext->hooks->gl.glColorPointer(size, type, stride, pointer);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glDepthRangex(GLclampx zNear, GLclampx zFar) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glDepthRangex);
+
+    // copy argument zNear
+    GLMessage_DataType *arg_zNear = glmsg.add_args();
+    arg_zNear->set_isarray(false);
+    arg_zNear->set_type(GLMessage::DataType::INT);
+    arg_zNear->add_intvalue(zNear);
+
+    // copy argument zFar
+    GLMessage_DataType *arg_zFar = glmsg.add_args();
+    arg_zFar->set_isarray(false);
+    arg_zFar->set_type(GLMessage::DataType::INT);
+    arg_zFar->add_intvalue(zFar);
+
+    // call function
+    glContext->hooks->gl.glDepthRangex(zNear, zFar);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glDisableClientState(GLenum array) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glDisableClientState);
+
+    // copy argument array
+    GLMessage_DataType *arg_array = glmsg.add_args();
+    arg_array->set_isarray(false);
+    arg_array->set_type(GLMessage::DataType::ENUM);
+    arg_array->add_intvalue((int)array);
+
+    // call function
+    glContext->hooks->gl.glDisableClientState(array);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glEnableClientState(GLenum array) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glEnableClientState);
+
+    // copy argument array
+    GLMessage_DataType *arg_array = glmsg.add_args();
+    arg_array->set_isarray(false);
+    arg_array->set_type(GLMessage::DataType::ENUM);
+    arg_array->add_intvalue((int)array);
+
+    // call function
+    glContext->hooks->gl.glEnableClientState(array);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glFogx(GLenum pname, GLfixed param) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glFogx);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument param
+    GLMessage_DataType *arg_param = glmsg.add_args();
+    arg_param->set_isarray(false);
+    arg_param->set_type(GLMessage::DataType::INT);
+    arg_param->add_intvalue(param);
+
+    // call function
+    glContext->hooks->gl.glFogx(pname, param);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glFogxv(GLenum pname, const GLfixed *params) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glFogxv);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument params
+    GLMessage_DataType *arg_params = glmsg.add_args();
+    arg_params->set_isarray(false);
+    arg_params->set_type(GLMessage::DataType::INT);
+    arg_params->add_intvalue((int)params);
+
+    // call function
+    glContext->hooks->gl.glFogxv(pname, params);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glFrustumx(GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glFrustumx);
+
+    // copy argument left
+    GLMessage_DataType *arg_left = glmsg.add_args();
+    arg_left->set_isarray(false);
+    arg_left->set_type(GLMessage::DataType::INT);
+    arg_left->add_intvalue(left);
+
+    // copy argument right
+    GLMessage_DataType *arg_right = glmsg.add_args();
+    arg_right->set_isarray(false);
+    arg_right->set_type(GLMessage::DataType::INT);
+    arg_right->add_intvalue(right);
+
+    // copy argument bottom
+    GLMessage_DataType *arg_bottom = glmsg.add_args();
+    arg_bottom->set_isarray(false);
+    arg_bottom->set_type(GLMessage::DataType::INT);
+    arg_bottom->add_intvalue(bottom);
+
+    // copy argument top
+    GLMessage_DataType *arg_top = glmsg.add_args();
+    arg_top->set_isarray(false);
+    arg_top->set_type(GLMessage::DataType::INT);
+    arg_top->add_intvalue(top);
+
+    // copy argument zNear
+    GLMessage_DataType *arg_zNear = glmsg.add_args();
+    arg_zNear->set_isarray(false);
+    arg_zNear->set_type(GLMessage::DataType::INT);
+    arg_zNear->add_intvalue(zNear);
+
+    // copy argument zFar
+    GLMessage_DataType *arg_zFar = glmsg.add_args();
+    arg_zFar->set_isarray(false);
+    arg_zFar->set_type(GLMessage::DataType::INT);
+    arg_zFar->add_intvalue(zFar);
+
+    // call function
+    glContext->hooks->gl.glFrustumx(left, right, bottom, top, zNear, zFar);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glGetClipPlanex(GLenum pname, GLfixed eqn[4]) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glGetClipPlanex);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument eqn
+    GLMessage_DataType *arg_eqn = glmsg.add_args();
+    arg_eqn->set_isarray(false);
+    arg_eqn->set_type(GLMessage::DataType::INT);
+    arg_eqn->add_intvalue((int)eqn);
+
+    // call function
+    glContext->hooks->gl.glGetClipPlanex(pname, eqn);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glGetFixedv(GLenum pname, GLfixed *params) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glGetFixedv);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument params
+    GLMessage_DataType *arg_params = glmsg.add_args();
+    arg_params->set_isarray(false);
+    arg_params->set_type(GLMessage::DataType::INT);
+    arg_params->add_intvalue((int)params);
+
+    // call function
+    glContext->hooks->gl.glGetFixedv(pname, params);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glGetLightxv(GLenum light, GLenum pname, GLfixed *params) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glGetLightxv);
+
+    // copy argument light
+    GLMessage_DataType *arg_light = glmsg.add_args();
+    arg_light->set_isarray(false);
+    arg_light->set_type(GLMessage::DataType::ENUM);
+    arg_light->add_intvalue((int)light);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument params
+    GLMessage_DataType *arg_params = glmsg.add_args();
+    arg_params->set_isarray(false);
+    arg_params->set_type(GLMessage::DataType::INT);
+    arg_params->add_intvalue((int)params);
+
+    // call function
+    glContext->hooks->gl.glGetLightxv(light, pname, params);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glGetMaterialxv(GLenum face, GLenum pname, GLfixed *params) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glGetMaterialxv);
+
+    // copy argument face
+    GLMessage_DataType *arg_face = glmsg.add_args();
+    arg_face->set_isarray(false);
+    arg_face->set_type(GLMessage::DataType::ENUM);
+    arg_face->add_intvalue((int)face);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument params
+    GLMessage_DataType *arg_params = glmsg.add_args();
+    arg_params->set_isarray(false);
+    arg_params->set_type(GLMessage::DataType::INT);
+    arg_params->add_intvalue((int)params);
+
+    // call function
+    glContext->hooks->gl.glGetMaterialxv(face, pname, params);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glGetPointerv(GLenum pname, GLvoid **params) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glGetPointerv);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument params
+    GLMessage_DataType *arg_params = glmsg.add_args();
+    arg_params->set_isarray(false);
+    arg_params->set_type(GLMessage::DataType::INT);
+    arg_params->add_intvalue((int)params);
+
+    // call function
+    glContext->hooks->gl.glGetPointerv(pname, params);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glGetTexEnviv(GLenum env, GLenum pname, GLint *params) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glGetTexEnviv);
+
+    // copy argument env
+    GLMessage_DataType *arg_env = glmsg.add_args();
+    arg_env->set_isarray(false);
+    arg_env->set_type(GLMessage::DataType::ENUM);
+    arg_env->add_intvalue((int)env);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument params
+    GLMessage_DataType *arg_params = glmsg.add_args();
+    arg_params->set_isarray(false);
+    arg_params->set_type(GLMessage::DataType::INT);
+    arg_params->add_intvalue((int)params);
+
+    // call function
+    glContext->hooks->gl.glGetTexEnviv(env, pname, params);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glGetTexEnvxv(GLenum env, GLenum pname, GLfixed *params) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glGetTexEnvxv);
+
+    // copy argument env
+    GLMessage_DataType *arg_env = glmsg.add_args();
+    arg_env->set_isarray(false);
+    arg_env->set_type(GLMessage::DataType::ENUM);
+    arg_env->add_intvalue((int)env);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument params
+    GLMessage_DataType *arg_params = glmsg.add_args();
+    arg_params->set_isarray(false);
+    arg_params->set_type(GLMessage::DataType::INT);
+    arg_params->add_intvalue((int)params);
+
+    // call function
+    glContext->hooks->gl.glGetTexEnvxv(env, pname, params);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glGetTexParameterxv(GLenum target, GLenum pname, GLfixed *params) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glGetTexParameterxv);
+
+    // copy argument target
+    GLMessage_DataType *arg_target = glmsg.add_args();
+    arg_target->set_isarray(false);
+    arg_target->set_type(GLMessage::DataType::ENUM);
+    arg_target->add_intvalue((int)target);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument params
+    GLMessage_DataType *arg_params = glmsg.add_args();
+    arg_params->set_isarray(false);
+    arg_params->set_type(GLMessage::DataType::INT);
+    arg_params->add_intvalue((int)params);
+
+    // call function
+    glContext->hooks->gl.glGetTexParameterxv(target, pname, params);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glLightModelx(GLenum pname, GLfixed param) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glLightModelx);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument param
+    GLMessage_DataType *arg_param = glmsg.add_args();
+    arg_param->set_isarray(false);
+    arg_param->set_type(GLMessage::DataType::INT);
+    arg_param->add_intvalue(param);
+
+    // call function
+    glContext->hooks->gl.glLightModelx(pname, param);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glLightModelxv(GLenum pname, const GLfixed *params) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glLightModelxv);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument params
+    GLMessage_DataType *arg_params = glmsg.add_args();
+    arg_params->set_isarray(false);
+    arg_params->set_type(GLMessage::DataType::INT);
+    arg_params->add_intvalue((int)params);
+
+    // call function
+    glContext->hooks->gl.glLightModelxv(pname, params);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glLightx(GLenum light, GLenum pname, GLfixed param) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glLightx);
+
+    // copy argument light
+    GLMessage_DataType *arg_light = glmsg.add_args();
+    arg_light->set_isarray(false);
+    arg_light->set_type(GLMessage::DataType::ENUM);
+    arg_light->add_intvalue((int)light);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument param
+    GLMessage_DataType *arg_param = glmsg.add_args();
+    arg_param->set_isarray(false);
+    arg_param->set_type(GLMessage::DataType::INT);
+    arg_param->add_intvalue(param);
+
+    // call function
+    glContext->hooks->gl.glLightx(light, pname, param);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glLightxv(GLenum light, GLenum pname, const GLfixed *params) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glLightxv);
+
+    // copy argument light
+    GLMessage_DataType *arg_light = glmsg.add_args();
+    arg_light->set_isarray(false);
+    arg_light->set_type(GLMessage::DataType::ENUM);
+    arg_light->add_intvalue((int)light);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument params
+    GLMessage_DataType *arg_params = glmsg.add_args();
+    arg_params->set_isarray(false);
+    arg_params->set_type(GLMessage::DataType::INT);
+    arg_params->add_intvalue((int)params);
+
+    // call function
+    glContext->hooks->gl.glLightxv(light, pname, params);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glLineWidthx(GLfixed width) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glLineWidthx);
+
+    // copy argument width
+    GLMessage_DataType *arg_width = glmsg.add_args();
+    arg_width->set_isarray(false);
+    arg_width->set_type(GLMessage::DataType::INT);
+    arg_width->add_intvalue(width);
+
+    // call function
+    glContext->hooks->gl.glLineWidthx(width);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glLoadIdentity(void) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glLoadIdentity);
+
+    // call function
+    glContext->hooks->gl.glLoadIdentity();
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glLoadMatrixx(const GLfixed *m) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glLoadMatrixx);
+
+    // copy argument m
+    GLMessage_DataType *arg_m = glmsg.add_args();
+    arg_m->set_isarray(false);
+    arg_m->set_type(GLMessage::DataType::INT);
+    arg_m->add_intvalue((int)m);
+
+    // call function
+    glContext->hooks->gl.glLoadMatrixx(m);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glLogicOp(GLenum opcode) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glLogicOp);
+
+    // copy argument opcode
+    GLMessage_DataType *arg_opcode = glmsg.add_args();
+    arg_opcode->set_isarray(false);
+    arg_opcode->set_type(GLMessage::DataType::ENUM);
+    arg_opcode->add_intvalue((int)opcode);
+
+    // call function
+    glContext->hooks->gl.glLogicOp(opcode);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glMaterialx(GLenum face, GLenum pname, GLfixed param) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glMaterialx);
+
+    // copy argument face
+    GLMessage_DataType *arg_face = glmsg.add_args();
+    arg_face->set_isarray(false);
+    arg_face->set_type(GLMessage::DataType::ENUM);
+    arg_face->add_intvalue((int)face);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument param
+    GLMessage_DataType *arg_param = glmsg.add_args();
+    arg_param->set_isarray(false);
+    arg_param->set_type(GLMessage::DataType::INT);
+    arg_param->add_intvalue(param);
+
+    // call function
+    glContext->hooks->gl.glMaterialx(face, pname, param);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glMaterialxv(GLenum face, GLenum pname, const GLfixed *params) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glMaterialxv);
+
+    // copy argument face
+    GLMessage_DataType *arg_face = glmsg.add_args();
+    arg_face->set_isarray(false);
+    arg_face->set_type(GLMessage::DataType::ENUM);
+    arg_face->add_intvalue((int)face);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument params
+    GLMessage_DataType *arg_params = glmsg.add_args();
+    arg_params->set_isarray(false);
+    arg_params->set_type(GLMessage::DataType::INT);
+    arg_params->add_intvalue((int)params);
+
+    // call function
+    glContext->hooks->gl.glMaterialxv(face, pname, params);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glMatrixMode(GLenum mode) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glMatrixMode);
+
+    // copy argument mode
+    GLMessage_DataType *arg_mode = glmsg.add_args();
+    arg_mode->set_isarray(false);
+    arg_mode->set_type(GLMessage::DataType::ENUM);
+    arg_mode->add_intvalue((int)mode);
+
+    // call function
+    glContext->hooks->gl.glMatrixMode(mode);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glMultMatrixx(const GLfixed *m) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glMultMatrixx);
+
+    // copy argument m
+    GLMessage_DataType *arg_m = glmsg.add_args();
+    arg_m->set_isarray(false);
+    arg_m->set_type(GLMessage::DataType::INT);
+    arg_m->add_intvalue((int)m);
+
+    // call function
+    glContext->hooks->gl.glMultMatrixx(m);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glMultiTexCoord4x(GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glMultiTexCoord4x);
+
+    // copy argument target
+    GLMessage_DataType *arg_target = glmsg.add_args();
+    arg_target->set_isarray(false);
+    arg_target->set_type(GLMessage::DataType::ENUM);
+    arg_target->add_intvalue((int)target);
+
+    // copy argument s
+    GLMessage_DataType *arg_s = glmsg.add_args();
+    arg_s->set_isarray(false);
+    arg_s->set_type(GLMessage::DataType::INT);
+    arg_s->add_intvalue(s);
+
+    // copy argument t
+    GLMessage_DataType *arg_t = glmsg.add_args();
+    arg_t->set_isarray(false);
+    arg_t->set_type(GLMessage::DataType::INT);
+    arg_t->add_intvalue(t);
+
+    // copy argument r
+    GLMessage_DataType *arg_r = glmsg.add_args();
+    arg_r->set_isarray(false);
+    arg_r->set_type(GLMessage::DataType::INT);
+    arg_r->add_intvalue(r);
+
+    // copy argument q
+    GLMessage_DataType *arg_q = glmsg.add_args();
+    arg_q->set_isarray(false);
+    arg_q->set_type(GLMessage::DataType::INT);
+    arg_q->add_intvalue(q);
+
+    // call function
+    glContext->hooks->gl.glMultiTexCoord4x(target, s, t, r, q);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glNormal3x(GLfixed nx, GLfixed ny, GLfixed nz) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glNormal3x);
+
+    // copy argument nx
+    GLMessage_DataType *arg_nx = glmsg.add_args();
+    arg_nx->set_isarray(false);
+    arg_nx->set_type(GLMessage::DataType::INT);
+    arg_nx->add_intvalue(nx);
+
+    // copy argument ny
+    GLMessage_DataType *arg_ny = glmsg.add_args();
+    arg_ny->set_isarray(false);
+    arg_ny->set_type(GLMessage::DataType::INT);
+    arg_ny->add_intvalue(ny);
+
+    // copy argument nz
+    GLMessage_DataType *arg_nz = glmsg.add_args();
+    arg_nz->set_isarray(false);
+    arg_nz->set_type(GLMessage::DataType::INT);
+    arg_nz->add_intvalue(nz);
+
+    // call function
+    glContext->hooks->gl.glNormal3x(nx, ny, nz);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glNormalPointer(GLenum type, GLsizei stride, const GLvoid *pointer) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glNormalPointer);
+
+    // copy argument type
+    GLMessage_DataType *arg_type = glmsg.add_args();
+    arg_type->set_isarray(false);
+    arg_type->set_type(GLMessage::DataType::ENUM);
+    arg_type->add_intvalue((int)type);
+
+    // copy argument stride
+    GLMessage_DataType *arg_stride = glmsg.add_args();
+    arg_stride->set_isarray(false);
+    arg_stride->set_type(GLMessage::DataType::INT);
+    arg_stride->add_intvalue(stride);
+
+    // copy argument pointer
+    GLMessage_DataType *arg_pointer = glmsg.add_args();
+    arg_pointer->set_isarray(false);
+    arg_pointer->set_type(GLMessage::DataType::INT);
+    arg_pointer->add_intvalue((int)pointer);
+
+    // call function
+    glContext->hooks->gl.glNormalPointer(type, stride, pointer);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glOrthox(GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glOrthox);
+
+    // copy argument left
+    GLMessage_DataType *arg_left = glmsg.add_args();
+    arg_left->set_isarray(false);
+    arg_left->set_type(GLMessage::DataType::INT);
+    arg_left->add_intvalue(left);
+
+    // copy argument right
+    GLMessage_DataType *arg_right = glmsg.add_args();
+    arg_right->set_isarray(false);
+    arg_right->set_type(GLMessage::DataType::INT);
+    arg_right->add_intvalue(right);
+
+    // copy argument bottom
+    GLMessage_DataType *arg_bottom = glmsg.add_args();
+    arg_bottom->set_isarray(false);
+    arg_bottom->set_type(GLMessage::DataType::INT);
+    arg_bottom->add_intvalue(bottom);
+
+    // copy argument top
+    GLMessage_DataType *arg_top = glmsg.add_args();
+    arg_top->set_isarray(false);
+    arg_top->set_type(GLMessage::DataType::INT);
+    arg_top->add_intvalue(top);
+
+    // copy argument zNear
+    GLMessage_DataType *arg_zNear = glmsg.add_args();
+    arg_zNear->set_isarray(false);
+    arg_zNear->set_type(GLMessage::DataType::INT);
+    arg_zNear->add_intvalue(zNear);
+
+    // copy argument zFar
+    GLMessage_DataType *arg_zFar = glmsg.add_args();
+    arg_zFar->set_isarray(false);
+    arg_zFar->set_type(GLMessage::DataType::INT);
+    arg_zFar->add_intvalue(zFar);
+
+    // call function
+    glContext->hooks->gl.glOrthox(left, right, bottom, top, zNear, zFar);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glPointParameterx(GLenum pname, GLfixed param) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glPointParameterx);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument param
+    GLMessage_DataType *arg_param = glmsg.add_args();
+    arg_param->set_isarray(false);
+    arg_param->set_type(GLMessage::DataType::INT);
+    arg_param->add_intvalue(param);
+
+    // call function
+    glContext->hooks->gl.glPointParameterx(pname, param);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glPointParameterxv(GLenum pname, const GLfixed *params) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glPointParameterxv);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument params
+    GLMessage_DataType *arg_params = glmsg.add_args();
+    arg_params->set_isarray(false);
+    arg_params->set_type(GLMessage::DataType::INT);
+    arg_params->add_intvalue((int)params);
+
+    // call function
+    glContext->hooks->gl.glPointParameterxv(pname, params);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glPointSizex(GLfixed size) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glPointSizex);
+
+    // copy argument size
+    GLMessage_DataType *arg_size = glmsg.add_args();
+    arg_size->set_isarray(false);
+    arg_size->set_type(GLMessage::DataType::INT);
+    arg_size->add_intvalue(size);
+
+    // call function
+    glContext->hooks->gl.glPointSizex(size);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glPolygonOffsetx(GLfixed factor, GLfixed units) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glPolygonOffsetx);
+
+    // copy argument factor
+    GLMessage_DataType *arg_factor = glmsg.add_args();
+    arg_factor->set_isarray(false);
+    arg_factor->set_type(GLMessage::DataType::INT);
+    arg_factor->add_intvalue(factor);
+
+    // copy argument units
+    GLMessage_DataType *arg_units = glmsg.add_args();
+    arg_units->set_isarray(false);
+    arg_units->set_type(GLMessage::DataType::INT);
+    arg_units->add_intvalue(units);
+
+    // call function
+    glContext->hooks->gl.glPolygonOffsetx(factor, units);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glPopMatrix(void) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glPopMatrix);
+
+    // call function
+    glContext->hooks->gl.glPopMatrix();
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glPushMatrix(void) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glPushMatrix);
+
+    // call function
+    glContext->hooks->gl.glPushMatrix();
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glRotatex(GLfixed angle, GLfixed x, GLfixed y, GLfixed z) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glRotatex);
+
+    // copy argument angle
+    GLMessage_DataType *arg_angle = glmsg.add_args();
+    arg_angle->set_isarray(false);
+    arg_angle->set_type(GLMessage::DataType::INT);
+    arg_angle->add_intvalue(angle);
+
+    // copy argument x
+    GLMessage_DataType *arg_x = glmsg.add_args();
+    arg_x->set_isarray(false);
+    arg_x->set_type(GLMessage::DataType::INT);
+    arg_x->add_intvalue(x);
+
+    // copy argument y
+    GLMessage_DataType *arg_y = glmsg.add_args();
+    arg_y->set_isarray(false);
+    arg_y->set_type(GLMessage::DataType::INT);
+    arg_y->add_intvalue(y);
+
+    // copy argument z
+    GLMessage_DataType *arg_z = glmsg.add_args();
+    arg_z->set_isarray(false);
+    arg_z->set_type(GLMessage::DataType::INT);
+    arg_z->add_intvalue(z);
+
+    // call function
+    glContext->hooks->gl.glRotatex(angle, x, y, z);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glSampleCoveragex(GLclampx value, GLboolean invert) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glSampleCoveragex);
+
+    // copy argument value
+    GLMessage_DataType *arg_value = glmsg.add_args();
+    arg_value->set_isarray(false);
+    arg_value->set_type(GLMessage::DataType::INT);
+    arg_value->add_intvalue(value);
+
+    // copy argument invert
+    GLMessage_DataType *arg_invert = glmsg.add_args();
+    arg_invert->set_isarray(false);
+    arg_invert->set_type(GLMessage::DataType::BOOL);
+    arg_invert->add_boolvalue(invert);
+
+    // call function
+    glContext->hooks->gl.glSampleCoveragex(value, invert);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glScalex(GLfixed x, GLfixed y, GLfixed z) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glScalex);
+
+    // copy argument x
+    GLMessage_DataType *arg_x = glmsg.add_args();
+    arg_x->set_isarray(false);
+    arg_x->set_type(GLMessage::DataType::INT);
+    arg_x->add_intvalue(x);
+
+    // copy argument y
+    GLMessage_DataType *arg_y = glmsg.add_args();
+    arg_y->set_isarray(false);
+    arg_y->set_type(GLMessage::DataType::INT);
+    arg_y->add_intvalue(y);
+
+    // copy argument z
+    GLMessage_DataType *arg_z = glmsg.add_args();
+    arg_z->set_isarray(false);
+    arg_z->set_type(GLMessage::DataType::INT);
+    arg_z->add_intvalue(z);
+
+    // call function
+    glContext->hooks->gl.glScalex(x, y, z);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glShadeModel(GLenum mode) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glShadeModel);
+
+    // copy argument mode
+    GLMessage_DataType *arg_mode = glmsg.add_args();
+    arg_mode->set_isarray(false);
+    arg_mode->set_type(GLMessage::DataType::ENUM);
+    arg_mode->add_intvalue((int)mode);
+
+    // call function
+    glContext->hooks->gl.glShadeModel(mode);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glTexCoordPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glTexCoordPointer);
+
+    // copy argument size
+    GLMessage_DataType *arg_size = glmsg.add_args();
+    arg_size->set_isarray(false);
+    arg_size->set_type(GLMessage::DataType::INT);
+    arg_size->add_intvalue(size);
+
+    // copy argument type
+    GLMessage_DataType *arg_type = glmsg.add_args();
+    arg_type->set_isarray(false);
+    arg_type->set_type(GLMessage::DataType::ENUM);
+    arg_type->add_intvalue((int)type);
+
+    // copy argument stride
+    GLMessage_DataType *arg_stride = glmsg.add_args();
+    arg_stride->set_isarray(false);
+    arg_stride->set_type(GLMessage::DataType::INT);
+    arg_stride->add_intvalue(stride);
+
+    // copy argument pointer
+    GLMessage_DataType *arg_pointer = glmsg.add_args();
+    arg_pointer->set_isarray(false);
+    arg_pointer->set_type(GLMessage::DataType::INT);
+    arg_pointer->add_intvalue((int)pointer);
+
+    // call function
+    glContext->hooks->gl.glTexCoordPointer(size, type, stride, pointer);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glTexEnvi(GLenum target, GLenum pname, GLint param) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glTexEnvi);
+
+    // copy argument target
+    GLMessage_DataType *arg_target = glmsg.add_args();
+    arg_target->set_isarray(false);
+    arg_target->set_type(GLMessage::DataType::ENUM);
+    arg_target->add_intvalue((int)target);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument param
+    GLMessage_DataType *arg_param = glmsg.add_args();
+    arg_param->set_isarray(false);
+    arg_param->set_type(GLMessage::DataType::INT);
+    arg_param->add_intvalue(param);
+
+    // call function
+    glContext->hooks->gl.glTexEnvi(target, pname, param);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glTexEnvx(GLenum target, GLenum pname, GLfixed param) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glTexEnvx);
+
+    // copy argument target
+    GLMessage_DataType *arg_target = glmsg.add_args();
+    arg_target->set_isarray(false);
+    arg_target->set_type(GLMessage::DataType::ENUM);
+    arg_target->add_intvalue((int)target);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument param
+    GLMessage_DataType *arg_param = glmsg.add_args();
+    arg_param->set_isarray(false);
+    arg_param->set_type(GLMessage::DataType::INT);
+    arg_param->add_intvalue(param);
+
+    // call function
+    glContext->hooks->gl.glTexEnvx(target, pname, param);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glTexEnviv(GLenum target, GLenum pname, const GLint *params) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glTexEnviv);
+
+    // copy argument target
+    GLMessage_DataType *arg_target = glmsg.add_args();
+    arg_target->set_isarray(false);
+    arg_target->set_type(GLMessage::DataType::ENUM);
+    arg_target->add_intvalue((int)target);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument params
+    GLMessage_DataType *arg_params = glmsg.add_args();
+    arg_params->set_isarray(false);
+    arg_params->set_type(GLMessage::DataType::INT);
+    arg_params->add_intvalue((int)params);
+
+    // call function
+    glContext->hooks->gl.glTexEnviv(target, pname, params);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glTexEnvxv(GLenum target, GLenum pname, const GLfixed *params) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glTexEnvxv);
+
+    // copy argument target
+    GLMessage_DataType *arg_target = glmsg.add_args();
+    arg_target->set_isarray(false);
+    arg_target->set_type(GLMessage::DataType::ENUM);
+    arg_target->add_intvalue((int)target);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument params
+    GLMessage_DataType *arg_params = glmsg.add_args();
+    arg_params->set_isarray(false);
+    arg_params->set_type(GLMessage::DataType::INT);
+    arg_params->add_intvalue((int)params);
+
+    // call function
+    glContext->hooks->gl.glTexEnvxv(target, pname, params);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glTexParameterx(GLenum target, GLenum pname, GLfixed param) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glTexParameterx);
+
+    // copy argument target
+    GLMessage_DataType *arg_target = glmsg.add_args();
+    arg_target->set_isarray(false);
+    arg_target->set_type(GLMessage::DataType::ENUM);
+    arg_target->add_intvalue((int)target);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument param
+    GLMessage_DataType *arg_param = glmsg.add_args();
+    arg_param->set_isarray(false);
+    arg_param->set_type(GLMessage::DataType::INT);
+    arg_param->add_intvalue(param);
+
+    // call function
+    glContext->hooks->gl.glTexParameterx(target, pname, param);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glTexParameterxv(GLenum target, GLenum pname, const GLfixed *params) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glTexParameterxv);
+
+    // copy argument target
+    GLMessage_DataType *arg_target = glmsg.add_args();
+    arg_target->set_isarray(false);
+    arg_target->set_type(GLMessage::DataType::ENUM);
+    arg_target->add_intvalue((int)target);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument params
+    GLMessage_DataType *arg_params = glmsg.add_args();
+    arg_params->set_isarray(false);
+    arg_params->set_type(GLMessage::DataType::INT);
+    arg_params->add_intvalue((int)params);
+
+    // call function
+    glContext->hooks->gl.glTexParameterxv(target, pname, params);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glTranslatex(GLfixed x, GLfixed y, GLfixed z) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glTranslatex);
+
+    // copy argument x
+    GLMessage_DataType *arg_x = glmsg.add_args();
+    arg_x->set_isarray(false);
+    arg_x->set_type(GLMessage::DataType::INT);
+    arg_x->add_intvalue(x);
+
+    // copy argument y
+    GLMessage_DataType *arg_y = glmsg.add_args();
+    arg_y->set_isarray(false);
+    arg_y->set_type(GLMessage::DataType::INT);
+    arg_y->add_intvalue(y);
+
+    // copy argument z
+    GLMessage_DataType *arg_z = glmsg.add_args();
+    arg_z->set_isarray(false);
+    arg_z->set_type(GLMessage::DataType::INT);
+    arg_z->add_intvalue(z);
+
+    // call function
+    glContext->hooks->gl.glTranslatex(x, y, z);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glVertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glVertexPointer);
+
+    // copy argument size
+    GLMessage_DataType *arg_size = glmsg.add_args();
+    arg_size->set_isarray(false);
+    arg_size->set_type(GLMessage::DataType::INT);
+    arg_size->add_intvalue(size);
+
+    // copy argument type
+    GLMessage_DataType *arg_type = glmsg.add_args();
+    arg_type->set_isarray(false);
+    arg_type->set_type(GLMessage::DataType::ENUM);
+    arg_type->add_intvalue((int)type);
+
+    // copy argument stride
+    GLMessage_DataType *arg_stride = glmsg.add_args();
+    arg_stride->set_isarray(false);
+    arg_stride->set_type(GLMessage::DataType::INT);
+    arg_stride->add_intvalue(stride);
+
+    // copy argument pointer
+    GLMessage_DataType *arg_pointer = glmsg.add_args();
+    arg_pointer->set_isarray(false);
+    arg_pointer->set_type(GLMessage::DataType::INT);
+    arg_pointer->add_intvalue((int)pointer);
+
+    // call function
+    glContext->hooks->gl.glVertexPointer(size, type, stride, pointer);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glPointSizePointerOES(GLenum type, GLsizei stride, const GLvoid *pointer) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glPointSizePointerOES);
+
+    // copy argument type
+    GLMessage_DataType *arg_type = glmsg.add_args();
+    arg_type->set_isarray(false);
+    arg_type->set_type(GLMessage::DataType::ENUM);
+    arg_type->add_intvalue((int)type);
+
+    // copy argument stride
+    GLMessage_DataType *arg_stride = glmsg.add_args();
+    arg_stride->set_isarray(false);
+    arg_stride->set_type(GLMessage::DataType::INT);
+    arg_stride->add_intvalue(stride);
+
+    // copy argument pointer
+    GLMessage_DataType *arg_pointer = glmsg.add_args();
+    arg_pointer->set_isarray(false);
+    arg_pointer->set_type(GLMessage::DataType::INT);
+    arg_pointer->add_intvalue((int)pointer);
+
+    // call function
+    glContext->hooks->gl.glPointSizePointerOES(type, stride, pointer);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+
+// Definitions for GL1Ext APIs
+
+void GLTrace_glBlendEquationSeparateOES(GLenum modeRGB, GLenum modeAlpha) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glBlendEquationSeparateOES);
+
+    // copy argument modeRGB
+    GLMessage_DataType *arg_modeRGB = glmsg.add_args();
+    arg_modeRGB->set_isarray(false);
+    arg_modeRGB->set_type(GLMessage::DataType::ENUM);
+    arg_modeRGB->add_intvalue((int)modeRGB);
+
+    // copy argument modeAlpha
+    GLMessage_DataType *arg_modeAlpha = glmsg.add_args();
+    arg_modeAlpha->set_isarray(false);
+    arg_modeAlpha->set_type(GLMessage::DataType::ENUM);
+    arg_modeAlpha->add_intvalue((int)modeAlpha);
+
+    // call function
+    glContext->hooks->gl.glBlendEquationSeparateOES(modeRGB, modeAlpha);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glBlendFuncSeparateOES(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glBlendFuncSeparateOES);
+
+    // copy argument srcRGB
+    GLMessage_DataType *arg_srcRGB = glmsg.add_args();
+    arg_srcRGB->set_isarray(false);
+    arg_srcRGB->set_type(GLMessage::DataType::ENUM);
+    arg_srcRGB->add_intvalue((int)srcRGB);
+
+    // copy argument dstRGB
+    GLMessage_DataType *arg_dstRGB = glmsg.add_args();
+    arg_dstRGB->set_isarray(false);
+    arg_dstRGB->set_type(GLMessage::DataType::ENUM);
+    arg_dstRGB->add_intvalue((int)dstRGB);
+
+    // copy argument srcAlpha
+    GLMessage_DataType *arg_srcAlpha = glmsg.add_args();
+    arg_srcAlpha->set_isarray(false);
+    arg_srcAlpha->set_type(GLMessage::DataType::ENUM);
+    arg_srcAlpha->add_intvalue((int)srcAlpha);
+
+    // copy argument dstAlpha
+    GLMessage_DataType *arg_dstAlpha = glmsg.add_args();
+    arg_dstAlpha->set_isarray(false);
+    arg_dstAlpha->set_type(GLMessage::DataType::ENUM);
+    arg_dstAlpha->add_intvalue((int)dstAlpha);
+
+    // call function
+    glContext->hooks->gl.glBlendFuncSeparateOES(srcRGB, dstRGB, srcAlpha, dstAlpha);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glBlendEquationOES(GLenum mode) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glBlendEquationOES);
+
+    // copy argument mode
+    GLMessage_DataType *arg_mode = glmsg.add_args();
+    arg_mode->set_isarray(false);
+    arg_mode->set_type(GLMessage::DataType::ENUM);
+    arg_mode->add_intvalue((int)mode);
+
+    // call function
+    glContext->hooks->gl.glBlendEquationOES(mode);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glDrawTexsOES(GLshort x, GLshort y, GLshort z, GLshort width, GLshort height) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glDrawTexsOES);
+
+    // copy argument x
+    GLMessage_DataType *arg_x = glmsg.add_args();
+    arg_x->set_isarray(false);
+    arg_x->set_type(GLMessage::DataType::INT);
+    arg_x->add_intvalue(x);
+
+    // copy argument y
+    GLMessage_DataType *arg_y = glmsg.add_args();
+    arg_y->set_isarray(false);
+    arg_y->set_type(GLMessage::DataType::INT);
+    arg_y->add_intvalue(y);
+
+    // copy argument z
+    GLMessage_DataType *arg_z = glmsg.add_args();
+    arg_z->set_isarray(false);
+    arg_z->set_type(GLMessage::DataType::INT);
+    arg_z->add_intvalue(z);
+
+    // copy argument width
+    GLMessage_DataType *arg_width = glmsg.add_args();
+    arg_width->set_isarray(false);
+    arg_width->set_type(GLMessage::DataType::INT);
+    arg_width->add_intvalue(width);
+
+    // copy argument height
+    GLMessage_DataType *arg_height = glmsg.add_args();
+    arg_height->set_isarray(false);
+    arg_height->set_type(GLMessage::DataType::INT);
+    arg_height->add_intvalue(height);
+
+    // call function
+    glContext->hooks->gl.glDrawTexsOES(x, y, z, width, height);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glDrawTexiOES(GLint x, GLint y, GLint z, GLint width, GLint height) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glDrawTexiOES);
+
+    // copy argument x
+    GLMessage_DataType *arg_x = glmsg.add_args();
+    arg_x->set_isarray(false);
+    arg_x->set_type(GLMessage::DataType::INT);
+    arg_x->add_intvalue(x);
+
+    // copy argument y
+    GLMessage_DataType *arg_y = glmsg.add_args();
+    arg_y->set_isarray(false);
+    arg_y->set_type(GLMessage::DataType::INT);
+    arg_y->add_intvalue(y);
+
+    // copy argument z
+    GLMessage_DataType *arg_z = glmsg.add_args();
+    arg_z->set_isarray(false);
+    arg_z->set_type(GLMessage::DataType::INT);
+    arg_z->add_intvalue(z);
+
+    // copy argument width
+    GLMessage_DataType *arg_width = glmsg.add_args();
+    arg_width->set_isarray(false);
+    arg_width->set_type(GLMessage::DataType::INT);
+    arg_width->add_intvalue(width);
+
+    // copy argument height
+    GLMessage_DataType *arg_height = glmsg.add_args();
+    arg_height->set_isarray(false);
+    arg_height->set_type(GLMessage::DataType::INT);
+    arg_height->add_intvalue(height);
+
+    // call function
+    glContext->hooks->gl.glDrawTexiOES(x, y, z, width, height);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glDrawTexxOES(GLfixed x, GLfixed y, GLfixed z, GLfixed width, GLfixed height) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glDrawTexxOES);
+
+    // copy argument x
+    GLMessage_DataType *arg_x = glmsg.add_args();
+    arg_x->set_isarray(false);
+    arg_x->set_type(GLMessage::DataType::INT);
+    arg_x->add_intvalue(x);
+
+    // copy argument y
+    GLMessage_DataType *arg_y = glmsg.add_args();
+    arg_y->set_isarray(false);
+    arg_y->set_type(GLMessage::DataType::INT);
+    arg_y->add_intvalue(y);
+
+    // copy argument z
+    GLMessage_DataType *arg_z = glmsg.add_args();
+    arg_z->set_isarray(false);
+    arg_z->set_type(GLMessage::DataType::INT);
+    arg_z->add_intvalue(z);
+
+    // copy argument width
+    GLMessage_DataType *arg_width = glmsg.add_args();
+    arg_width->set_isarray(false);
+    arg_width->set_type(GLMessage::DataType::INT);
+    arg_width->add_intvalue(width);
+
+    // copy argument height
+    GLMessage_DataType *arg_height = glmsg.add_args();
+    arg_height->set_isarray(false);
+    arg_height->set_type(GLMessage::DataType::INT);
+    arg_height->add_intvalue(height);
+
+    // call function
+    glContext->hooks->gl.glDrawTexxOES(x, y, z, width, height);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glDrawTexsvOES(const GLshort *coords) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glDrawTexsvOES);
+
+    // copy argument coords
+    GLMessage_DataType *arg_coords = glmsg.add_args();
+    arg_coords->set_isarray(false);
+    arg_coords->set_type(GLMessage::DataType::INT);
+    arg_coords->add_intvalue((int)coords);
+
+    // call function
+    glContext->hooks->gl.glDrawTexsvOES(coords);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glDrawTexivOES(const GLint *coords) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glDrawTexivOES);
+
+    // copy argument coords
+    GLMessage_DataType *arg_coords = glmsg.add_args();
+    arg_coords->set_isarray(false);
+    arg_coords->set_type(GLMessage::DataType::INT);
+    arg_coords->add_intvalue((int)coords);
+
+    // call function
+    glContext->hooks->gl.glDrawTexivOES(coords);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glDrawTexxvOES(const GLfixed *coords) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glDrawTexxvOES);
+
+    // copy argument coords
+    GLMessage_DataType *arg_coords = glmsg.add_args();
+    arg_coords->set_isarray(false);
+    arg_coords->set_type(GLMessage::DataType::INT);
+    arg_coords->add_intvalue((int)coords);
+
+    // call function
+    glContext->hooks->gl.glDrawTexxvOES(coords);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glDrawTexfOES(GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glDrawTexfOES);
+
+    // copy argument x
+    GLMessage_DataType *arg_x = glmsg.add_args();
+    arg_x->set_isarray(false);
+    arg_x->set_type(GLMessage::DataType::FLOAT);
+    arg_x->add_floatvalue(x);
+
+    // copy argument y
+    GLMessage_DataType *arg_y = glmsg.add_args();
+    arg_y->set_isarray(false);
+    arg_y->set_type(GLMessage::DataType::FLOAT);
+    arg_y->add_floatvalue(y);
+
+    // copy argument z
+    GLMessage_DataType *arg_z = glmsg.add_args();
+    arg_z->set_isarray(false);
+    arg_z->set_type(GLMessage::DataType::FLOAT);
+    arg_z->add_floatvalue(z);
+
+    // copy argument width
+    GLMessage_DataType *arg_width = glmsg.add_args();
+    arg_width->set_isarray(false);
+    arg_width->set_type(GLMessage::DataType::FLOAT);
+    arg_width->add_floatvalue(width);
+
+    // copy argument height
+    GLMessage_DataType *arg_height = glmsg.add_args();
+    arg_height->set_isarray(false);
+    arg_height->set_type(GLMessage::DataType::FLOAT);
+    arg_height->add_floatvalue(height);
+
+    // call function
+    glContext->hooks->gl.glDrawTexfOES(x, y, z, width, height);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glDrawTexfvOES(const GLfloat *coords) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glDrawTexfvOES);
+
+    // copy argument coords
+    GLMessage_DataType *arg_coords = glmsg.add_args();
+    arg_coords->set_isarray(false);
+    arg_coords->set_type(GLMessage::DataType::INT);
+    arg_coords->add_intvalue((int)coords);
+
+    // call function
+    glContext->hooks->gl.glDrawTexfvOES(coords);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glAlphaFuncxOES(GLenum func, GLclampx ref) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glAlphaFuncxOES);
+
+    // copy argument func
+    GLMessage_DataType *arg_func = glmsg.add_args();
+    arg_func->set_isarray(false);
+    arg_func->set_type(GLMessage::DataType::ENUM);
+    arg_func->add_intvalue((int)func);
+
+    // copy argument ref
+    GLMessage_DataType *arg_ref = glmsg.add_args();
+    arg_ref->set_isarray(false);
+    arg_ref->set_type(GLMessage::DataType::INT);
+    arg_ref->add_intvalue(ref);
+
+    // call function
+    glContext->hooks->gl.glAlphaFuncxOES(func, ref);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glClearColorxOES(GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glClearColorxOES);
+
+    // copy argument red
+    GLMessage_DataType *arg_red = glmsg.add_args();
+    arg_red->set_isarray(false);
+    arg_red->set_type(GLMessage::DataType::INT);
+    arg_red->add_intvalue(red);
+
+    // copy argument green
+    GLMessage_DataType *arg_green = glmsg.add_args();
+    arg_green->set_isarray(false);
+    arg_green->set_type(GLMessage::DataType::INT);
+    arg_green->add_intvalue(green);
+
+    // copy argument blue
+    GLMessage_DataType *arg_blue = glmsg.add_args();
+    arg_blue->set_isarray(false);
+    arg_blue->set_type(GLMessage::DataType::INT);
+    arg_blue->add_intvalue(blue);
+
+    // copy argument alpha
+    GLMessage_DataType *arg_alpha = glmsg.add_args();
+    arg_alpha->set_isarray(false);
+    arg_alpha->set_type(GLMessage::DataType::INT);
+    arg_alpha->add_intvalue(alpha);
+
+    // call function
+    glContext->hooks->gl.glClearColorxOES(red, green, blue, alpha);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glClearDepthxOES(GLclampx depth) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glClearDepthxOES);
+
+    // copy argument depth
+    GLMessage_DataType *arg_depth = glmsg.add_args();
+    arg_depth->set_isarray(false);
+    arg_depth->set_type(GLMessage::DataType::INT);
+    arg_depth->add_intvalue(depth);
+
+    // call function
+    glContext->hooks->gl.glClearDepthxOES(depth);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glClipPlanexOES(GLenum plane, const GLfixed *equation) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glClipPlanexOES);
+
+    // copy argument plane
+    GLMessage_DataType *arg_plane = glmsg.add_args();
+    arg_plane->set_isarray(false);
+    arg_plane->set_type(GLMessage::DataType::ENUM);
+    arg_plane->add_intvalue((int)plane);
+
+    // copy argument equation
+    GLMessage_DataType *arg_equation = glmsg.add_args();
+    arg_equation->set_isarray(false);
+    arg_equation->set_type(GLMessage::DataType::INT);
+    arg_equation->add_intvalue((int)equation);
+
+    // call function
+    glContext->hooks->gl.glClipPlanexOES(plane, equation);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glColor4xOES(GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glColor4xOES);
+
+    // copy argument red
+    GLMessage_DataType *arg_red = glmsg.add_args();
+    arg_red->set_isarray(false);
+    arg_red->set_type(GLMessage::DataType::INT);
+    arg_red->add_intvalue(red);
+
+    // copy argument green
+    GLMessage_DataType *arg_green = glmsg.add_args();
+    arg_green->set_isarray(false);
+    arg_green->set_type(GLMessage::DataType::INT);
+    arg_green->add_intvalue(green);
+
+    // copy argument blue
+    GLMessage_DataType *arg_blue = glmsg.add_args();
+    arg_blue->set_isarray(false);
+    arg_blue->set_type(GLMessage::DataType::INT);
+    arg_blue->add_intvalue(blue);
+
+    // copy argument alpha
+    GLMessage_DataType *arg_alpha = glmsg.add_args();
+    arg_alpha->set_isarray(false);
+    arg_alpha->set_type(GLMessage::DataType::INT);
+    arg_alpha->add_intvalue(alpha);
+
+    // call function
+    glContext->hooks->gl.glColor4xOES(red, green, blue, alpha);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glDepthRangexOES(GLclampx zNear, GLclampx zFar) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glDepthRangexOES);
+
+    // copy argument zNear
+    GLMessage_DataType *arg_zNear = glmsg.add_args();
+    arg_zNear->set_isarray(false);
+    arg_zNear->set_type(GLMessage::DataType::INT);
+    arg_zNear->add_intvalue(zNear);
+
+    // copy argument zFar
+    GLMessage_DataType *arg_zFar = glmsg.add_args();
+    arg_zFar->set_isarray(false);
+    arg_zFar->set_type(GLMessage::DataType::INT);
+    arg_zFar->add_intvalue(zFar);
+
+    // call function
+    glContext->hooks->gl.glDepthRangexOES(zNear, zFar);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glFogxOES(GLenum pname, GLfixed param) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glFogxOES);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument param
+    GLMessage_DataType *arg_param = glmsg.add_args();
+    arg_param->set_isarray(false);
+    arg_param->set_type(GLMessage::DataType::INT);
+    arg_param->add_intvalue(param);
+
+    // call function
+    glContext->hooks->gl.glFogxOES(pname, param);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glFogxvOES(GLenum pname, const GLfixed *params) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glFogxvOES);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument params
+    GLMessage_DataType *arg_params = glmsg.add_args();
+    arg_params->set_isarray(false);
+    arg_params->set_type(GLMessage::DataType::INT);
+    arg_params->add_intvalue((int)params);
+
+    // call function
+    glContext->hooks->gl.glFogxvOES(pname, params);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glFrustumxOES(GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glFrustumxOES);
+
+    // copy argument left
+    GLMessage_DataType *arg_left = glmsg.add_args();
+    arg_left->set_isarray(false);
+    arg_left->set_type(GLMessage::DataType::INT);
+    arg_left->add_intvalue(left);
+
+    // copy argument right
+    GLMessage_DataType *arg_right = glmsg.add_args();
+    arg_right->set_isarray(false);
+    arg_right->set_type(GLMessage::DataType::INT);
+    arg_right->add_intvalue(right);
+
+    // copy argument bottom
+    GLMessage_DataType *arg_bottom = glmsg.add_args();
+    arg_bottom->set_isarray(false);
+    arg_bottom->set_type(GLMessage::DataType::INT);
+    arg_bottom->add_intvalue(bottom);
+
+    // copy argument top
+    GLMessage_DataType *arg_top = glmsg.add_args();
+    arg_top->set_isarray(false);
+    arg_top->set_type(GLMessage::DataType::INT);
+    arg_top->add_intvalue(top);
+
+    // copy argument zNear
+    GLMessage_DataType *arg_zNear = glmsg.add_args();
+    arg_zNear->set_isarray(false);
+    arg_zNear->set_type(GLMessage::DataType::INT);
+    arg_zNear->add_intvalue(zNear);
+
+    // copy argument zFar
+    GLMessage_DataType *arg_zFar = glmsg.add_args();
+    arg_zFar->set_isarray(false);
+    arg_zFar->set_type(GLMessage::DataType::INT);
+    arg_zFar->add_intvalue(zFar);
+
+    // call function
+    glContext->hooks->gl.glFrustumxOES(left, right, bottom, top, zNear, zFar);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glGetClipPlanexOES(GLenum pname, GLfixed eqn[4]) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glGetClipPlanexOES);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument eqn
+    GLMessage_DataType *arg_eqn = glmsg.add_args();
+    arg_eqn->set_isarray(false);
+    arg_eqn->set_type(GLMessage::DataType::INT);
+    arg_eqn->add_intvalue((int)eqn);
+
+    // call function
+    glContext->hooks->gl.glGetClipPlanexOES(pname, eqn);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glGetFixedvOES(GLenum pname, GLfixed *params) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glGetFixedvOES);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument params
+    GLMessage_DataType *arg_params = glmsg.add_args();
+    arg_params->set_isarray(false);
+    arg_params->set_type(GLMessage::DataType::INT);
+    arg_params->add_intvalue((int)params);
+
+    // call function
+    glContext->hooks->gl.glGetFixedvOES(pname, params);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glGetLightxvOES(GLenum light, GLenum pname, GLfixed *params) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glGetLightxvOES);
+
+    // copy argument light
+    GLMessage_DataType *arg_light = glmsg.add_args();
+    arg_light->set_isarray(false);
+    arg_light->set_type(GLMessage::DataType::ENUM);
+    arg_light->add_intvalue((int)light);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument params
+    GLMessage_DataType *arg_params = glmsg.add_args();
+    arg_params->set_isarray(false);
+    arg_params->set_type(GLMessage::DataType::INT);
+    arg_params->add_intvalue((int)params);
+
+    // call function
+    glContext->hooks->gl.glGetLightxvOES(light, pname, params);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glGetMaterialxvOES(GLenum face, GLenum pname, GLfixed *params) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glGetMaterialxvOES);
+
+    // copy argument face
+    GLMessage_DataType *arg_face = glmsg.add_args();
+    arg_face->set_isarray(false);
+    arg_face->set_type(GLMessage::DataType::ENUM);
+    arg_face->add_intvalue((int)face);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument params
+    GLMessage_DataType *arg_params = glmsg.add_args();
+    arg_params->set_isarray(false);
+    arg_params->set_type(GLMessage::DataType::INT);
+    arg_params->add_intvalue((int)params);
+
+    // call function
+    glContext->hooks->gl.glGetMaterialxvOES(face, pname, params);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glGetTexEnvxvOES(GLenum env, GLenum pname, GLfixed *params) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glGetTexEnvxvOES);
+
+    // copy argument env
+    GLMessage_DataType *arg_env = glmsg.add_args();
+    arg_env->set_isarray(false);
+    arg_env->set_type(GLMessage::DataType::ENUM);
+    arg_env->add_intvalue((int)env);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument params
+    GLMessage_DataType *arg_params = glmsg.add_args();
+    arg_params->set_isarray(false);
+    arg_params->set_type(GLMessage::DataType::INT);
+    arg_params->add_intvalue((int)params);
+
+    // call function
+    glContext->hooks->gl.glGetTexEnvxvOES(env, pname, params);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glGetTexParameterxvOES(GLenum target, GLenum pname, GLfixed *params) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glGetTexParameterxvOES);
+
+    // copy argument target
+    GLMessage_DataType *arg_target = glmsg.add_args();
+    arg_target->set_isarray(false);
+    arg_target->set_type(GLMessage::DataType::ENUM);
+    arg_target->add_intvalue((int)target);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument params
+    GLMessage_DataType *arg_params = glmsg.add_args();
+    arg_params->set_isarray(false);
+    arg_params->set_type(GLMessage::DataType::INT);
+    arg_params->add_intvalue((int)params);
+
+    // call function
+    glContext->hooks->gl.glGetTexParameterxvOES(target, pname, params);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glLightModelxOES(GLenum pname, GLfixed param) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glLightModelxOES);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument param
+    GLMessage_DataType *arg_param = glmsg.add_args();
+    arg_param->set_isarray(false);
+    arg_param->set_type(GLMessage::DataType::INT);
+    arg_param->add_intvalue(param);
+
+    // call function
+    glContext->hooks->gl.glLightModelxOES(pname, param);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glLightModelxvOES(GLenum pname, const GLfixed *params) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glLightModelxvOES);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument params
+    GLMessage_DataType *arg_params = glmsg.add_args();
+    arg_params->set_isarray(false);
+    arg_params->set_type(GLMessage::DataType::INT);
+    arg_params->add_intvalue((int)params);
+
+    // call function
+    glContext->hooks->gl.glLightModelxvOES(pname, params);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glLightxOES(GLenum light, GLenum pname, GLfixed param) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glLightxOES);
+
+    // copy argument light
+    GLMessage_DataType *arg_light = glmsg.add_args();
+    arg_light->set_isarray(false);
+    arg_light->set_type(GLMessage::DataType::ENUM);
+    arg_light->add_intvalue((int)light);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument param
+    GLMessage_DataType *arg_param = glmsg.add_args();
+    arg_param->set_isarray(false);
+    arg_param->set_type(GLMessage::DataType::INT);
+    arg_param->add_intvalue(param);
+
+    // call function
+    glContext->hooks->gl.glLightxOES(light, pname, param);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glLightxvOES(GLenum light, GLenum pname, const GLfixed *params) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glLightxvOES);
+
+    // copy argument light
+    GLMessage_DataType *arg_light = glmsg.add_args();
+    arg_light->set_isarray(false);
+    arg_light->set_type(GLMessage::DataType::ENUM);
+    arg_light->add_intvalue((int)light);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument params
+    GLMessage_DataType *arg_params = glmsg.add_args();
+    arg_params->set_isarray(false);
+    arg_params->set_type(GLMessage::DataType::INT);
+    arg_params->add_intvalue((int)params);
+
+    // call function
+    glContext->hooks->gl.glLightxvOES(light, pname, params);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glLineWidthxOES(GLfixed width) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glLineWidthxOES);
+
+    // copy argument width
+    GLMessage_DataType *arg_width = glmsg.add_args();
+    arg_width->set_isarray(false);
+    arg_width->set_type(GLMessage::DataType::INT);
+    arg_width->add_intvalue(width);
+
+    // call function
+    glContext->hooks->gl.glLineWidthxOES(width);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glLoadMatrixxOES(const GLfixed *m) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glLoadMatrixxOES);
+
+    // copy argument m
+    GLMessage_DataType *arg_m = glmsg.add_args();
+    arg_m->set_isarray(false);
+    arg_m->set_type(GLMessage::DataType::INT);
+    arg_m->add_intvalue((int)m);
+
+    // call function
+    glContext->hooks->gl.glLoadMatrixxOES(m);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glMaterialxOES(GLenum face, GLenum pname, GLfixed param) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glMaterialxOES);
+
+    // copy argument face
+    GLMessage_DataType *arg_face = glmsg.add_args();
+    arg_face->set_isarray(false);
+    arg_face->set_type(GLMessage::DataType::ENUM);
+    arg_face->add_intvalue((int)face);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument param
+    GLMessage_DataType *arg_param = glmsg.add_args();
+    arg_param->set_isarray(false);
+    arg_param->set_type(GLMessage::DataType::INT);
+    arg_param->add_intvalue(param);
+
+    // call function
+    glContext->hooks->gl.glMaterialxOES(face, pname, param);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glMaterialxvOES(GLenum face, GLenum pname, const GLfixed *params) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glMaterialxvOES);
+
+    // copy argument face
+    GLMessage_DataType *arg_face = glmsg.add_args();
+    arg_face->set_isarray(false);
+    arg_face->set_type(GLMessage::DataType::ENUM);
+    arg_face->add_intvalue((int)face);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument params
+    GLMessage_DataType *arg_params = glmsg.add_args();
+    arg_params->set_isarray(false);
+    arg_params->set_type(GLMessage::DataType::INT);
+    arg_params->add_intvalue((int)params);
+
+    // call function
+    glContext->hooks->gl.glMaterialxvOES(face, pname, params);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glMultMatrixxOES(const GLfixed *m) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glMultMatrixxOES);
+
+    // copy argument m
+    GLMessage_DataType *arg_m = glmsg.add_args();
+    arg_m->set_isarray(false);
+    arg_m->set_type(GLMessage::DataType::INT);
+    arg_m->add_intvalue((int)m);
+
+    // call function
+    glContext->hooks->gl.glMultMatrixxOES(m);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glMultiTexCoord4xOES(GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glMultiTexCoord4xOES);
+
+    // copy argument target
+    GLMessage_DataType *arg_target = glmsg.add_args();
+    arg_target->set_isarray(false);
+    arg_target->set_type(GLMessage::DataType::ENUM);
+    arg_target->add_intvalue((int)target);
+
+    // copy argument s
+    GLMessage_DataType *arg_s = glmsg.add_args();
+    arg_s->set_isarray(false);
+    arg_s->set_type(GLMessage::DataType::INT);
+    arg_s->add_intvalue(s);
+
+    // copy argument t
+    GLMessage_DataType *arg_t = glmsg.add_args();
+    arg_t->set_isarray(false);
+    arg_t->set_type(GLMessage::DataType::INT);
+    arg_t->add_intvalue(t);
+
+    // copy argument r
+    GLMessage_DataType *arg_r = glmsg.add_args();
+    arg_r->set_isarray(false);
+    arg_r->set_type(GLMessage::DataType::INT);
+    arg_r->add_intvalue(r);
+
+    // copy argument q
+    GLMessage_DataType *arg_q = glmsg.add_args();
+    arg_q->set_isarray(false);
+    arg_q->set_type(GLMessage::DataType::INT);
+    arg_q->add_intvalue(q);
+
+    // call function
+    glContext->hooks->gl.glMultiTexCoord4xOES(target, s, t, r, q);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glNormal3xOES(GLfixed nx, GLfixed ny, GLfixed nz) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glNormal3xOES);
+
+    // copy argument nx
+    GLMessage_DataType *arg_nx = glmsg.add_args();
+    arg_nx->set_isarray(false);
+    arg_nx->set_type(GLMessage::DataType::INT);
+    arg_nx->add_intvalue(nx);
+
+    // copy argument ny
+    GLMessage_DataType *arg_ny = glmsg.add_args();
+    arg_ny->set_isarray(false);
+    arg_ny->set_type(GLMessage::DataType::INT);
+    arg_ny->add_intvalue(ny);
+
+    // copy argument nz
+    GLMessage_DataType *arg_nz = glmsg.add_args();
+    arg_nz->set_isarray(false);
+    arg_nz->set_type(GLMessage::DataType::INT);
+    arg_nz->add_intvalue(nz);
+
+    // call function
+    glContext->hooks->gl.glNormal3xOES(nx, ny, nz);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glOrthoxOES(GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glOrthoxOES);
+
+    // copy argument left
+    GLMessage_DataType *arg_left = glmsg.add_args();
+    arg_left->set_isarray(false);
+    arg_left->set_type(GLMessage::DataType::INT);
+    arg_left->add_intvalue(left);
+
+    // copy argument right
+    GLMessage_DataType *arg_right = glmsg.add_args();
+    arg_right->set_isarray(false);
+    arg_right->set_type(GLMessage::DataType::INT);
+    arg_right->add_intvalue(right);
+
+    // copy argument bottom
+    GLMessage_DataType *arg_bottom = glmsg.add_args();
+    arg_bottom->set_isarray(false);
+    arg_bottom->set_type(GLMessage::DataType::INT);
+    arg_bottom->add_intvalue(bottom);
+
+    // copy argument top
+    GLMessage_DataType *arg_top = glmsg.add_args();
+    arg_top->set_isarray(false);
+    arg_top->set_type(GLMessage::DataType::INT);
+    arg_top->add_intvalue(top);
+
+    // copy argument zNear
+    GLMessage_DataType *arg_zNear = glmsg.add_args();
+    arg_zNear->set_isarray(false);
+    arg_zNear->set_type(GLMessage::DataType::INT);
+    arg_zNear->add_intvalue(zNear);
+
+    // copy argument zFar
+    GLMessage_DataType *arg_zFar = glmsg.add_args();
+    arg_zFar->set_isarray(false);
+    arg_zFar->set_type(GLMessage::DataType::INT);
+    arg_zFar->add_intvalue(zFar);
+
+    // call function
+    glContext->hooks->gl.glOrthoxOES(left, right, bottom, top, zNear, zFar);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glPointParameterxOES(GLenum pname, GLfixed param) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glPointParameterxOES);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument param
+    GLMessage_DataType *arg_param = glmsg.add_args();
+    arg_param->set_isarray(false);
+    arg_param->set_type(GLMessage::DataType::INT);
+    arg_param->add_intvalue(param);
+
+    // call function
+    glContext->hooks->gl.glPointParameterxOES(pname, param);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glPointParameterxvOES(GLenum pname, const GLfixed *params) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glPointParameterxvOES);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument params
+    GLMessage_DataType *arg_params = glmsg.add_args();
+    arg_params->set_isarray(false);
+    arg_params->set_type(GLMessage::DataType::INT);
+    arg_params->add_intvalue((int)params);
+
+    // call function
+    glContext->hooks->gl.glPointParameterxvOES(pname, params);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glPointSizexOES(GLfixed size) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glPointSizexOES);
+
+    // copy argument size
+    GLMessage_DataType *arg_size = glmsg.add_args();
+    arg_size->set_isarray(false);
+    arg_size->set_type(GLMessage::DataType::INT);
+    arg_size->add_intvalue(size);
+
+    // call function
+    glContext->hooks->gl.glPointSizexOES(size);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glPolygonOffsetxOES(GLfixed factor, GLfixed units) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glPolygonOffsetxOES);
+
+    // copy argument factor
+    GLMessage_DataType *arg_factor = glmsg.add_args();
+    arg_factor->set_isarray(false);
+    arg_factor->set_type(GLMessage::DataType::INT);
+    arg_factor->add_intvalue(factor);
+
+    // copy argument units
+    GLMessage_DataType *arg_units = glmsg.add_args();
+    arg_units->set_isarray(false);
+    arg_units->set_type(GLMessage::DataType::INT);
+    arg_units->add_intvalue(units);
+
+    // call function
+    glContext->hooks->gl.glPolygonOffsetxOES(factor, units);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glRotatexOES(GLfixed angle, GLfixed x, GLfixed y, GLfixed z) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glRotatexOES);
+
+    // copy argument angle
+    GLMessage_DataType *arg_angle = glmsg.add_args();
+    arg_angle->set_isarray(false);
+    arg_angle->set_type(GLMessage::DataType::INT);
+    arg_angle->add_intvalue(angle);
+
+    // copy argument x
+    GLMessage_DataType *arg_x = glmsg.add_args();
+    arg_x->set_isarray(false);
+    arg_x->set_type(GLMessage::DataType::INT);
+    arg_x->add_intvalue(x);
+
+    // copy argument y
+    GLMessage_DataType *arg_y = glmsg.add_args();
+    arg_y->set_isarray(false);
+    arg_y->set_type(GLMessage::DataType::INT);
+    arg_y->add_intvalue(y);
+
+    // copy argument z
+    GLMessage_DataType *arg_z = glmsg.add_args();
+    arg_z->set_isarray(false);
+    arg_z->set_type(GLMessage::DataType::INT);
+    arg_z->add_intvalue(z);
+
+    // call function
+    glContext->hooks->gl.glRotatexOES(angle, x, y, z);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glSampleCoveragexOES(GLclampx value, GLboolean invert) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glSampleCoveragexOES);
+
+    // copy argument value
+    GLMessage_DataType *arg_value = glmsg.add_args();
+    arg_value->set_isarray(false);
+    arg_value->set_type(GLMessage::DataType::INT);
+    arg_value->add_intvalue(value);
+
+    // copy argument invert
+    GLMessage_DataType *arg_invert = glmsg.add_args();
+    arg_invert->set_isarray(false);
+    arg_invert->set_type(GLMessage::DataType::BOOL);
+    arg_invert->add_boolvalue(invert);
+
+    // call function
+    glContext->hooks->gl.glSampleCoveragexOES(value, invert);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glScalexOES(GLfixed x, GLfixed y, GLfixed z) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glScalexOES);
+
+    // copy argument x
+    GLMessage_DataType *arg_x = glmsg.add_args();
+    arg_x->set_isarray(false);
+    arg_x->set_type(GLMessage::DataType::INT);
+    arg_x->add_intvalue(x);
+
+    // copy argument y
+    GLMessage_DataType *arg_y = glmsg.add_args();
+    arg_y->set_isarray(false);
+    arg_y->set_type(GLMessage::DataType::INT);
+    arg_y->add_intvalue(y);
+
+    // copy argument z
+    GLMessage_DataType *arg_z = glmsg.add_args();
+    arg_z->set_isarray(false);
+    arg_z->set_type(GLMessage::DataType::INT);
+    arg_z->add_intvalue(z);
+
+    // call function
+    glContext->hooks->gl.glScalexOES(x, y, z);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glTexEnvxOES(GLenum target, GLenum pname, GLfixed param) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glTexEnvxOES);
+
+    // copy argument target
+    GLMessage_DataType *arg_target = glmsg.add_args();
+    arg_target->set_isarray(false);
+    arg_target->set_type(GLMessage::DataType::ENUM);
+    arg_target->add_intvalue((int)target);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument param
+    GLMessage_DataType *arg_param = glmsg.add_args();
+    arg_param->set_isarray(false);
+    arg_param->set_type(GLMessage::DataType::INT);
+    arg_param->add_intvalue(param);
+
+    // call function
+    glContext->hooks->gl.glTexEnvxOES(target, pname, param);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glTexEnvxvOES(GLenum target, GLenum pname, const GLfixed *params) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glTexEnvxvOES);
+
+    // copy argument target
+    GLMessage_DataType *arg_target = glmsg.add_args();
+    arg_target->set_isarray(false);
+    arg_target->set_type(GLMessage::DataType::ENUM);
+    arg_target->add_intvalue((int)target);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument params
+    GLMessage_DataType *arg_params = glmsg.add_args();
+    arg_params->set_isarray(false);
+    arg_params->set_type(GLMessage::DataType::INT);
+    arg_params->add_intvalue((int)params);
+
+    // call function
+    glContext->hooks->gl.glTexEnvxvOES(target, pname, params);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glTexParameterxOES(GLenum target, GLenum pname, GLfixed param) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glTexParameterxOES);
+
+    // copy argument target
+    GLMessage_DataType *arg_target = glmsg.add_args();
+    arg_target->set_isarray(false);
+    arg_target->set_type(GLMessage::DataType::ENUM);
+    arg_target->add_intvalue((int)target);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument param
+    GLMessage_DataType *arg_param = glmsg.add_args();
+    arg_param->set_isarray(false);
+    arg_param->set_type(GLMessage::DataType::INT);
+    arg_param->add_intvalue(param);
+
+    // call function
+    glContext->hooks->gl.glTexParameterxOES(target, pname, param);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glTexParameterxvOES(GLenum target, GLenum pname, const GLfixed *params) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glTexParameterxvOES);
+
+    // copy argument target
+    GLMessage_DataType *arg_target = glmsg.add_args();
+    arg_target->set_isarray(false);
+    arg_target->set_type(GLMessage::DataType::ENUM);
+    arg_target->add_intvalue((int)target);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument params
+    GLMessage_DataType *arg_params = glmsg.add_args();
+    arg_params->set_isarray(false);
+    arg_params->set_type(GLMessage::DataType::INT);
+    arg_params->add_intvalue((int)params);
+
+    // call function
+    glContext->hooks->gl.glTexParameterxvOES(target, pname, params);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glTranslatexOES(GLfixed x, GLfixed y, GLfixed z) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glTranslatexOES);
+
+    // copy argument x
+    GLMessage_DataType *arg_x = glmsg.add_args();
+    arg_x->set_isarray(false);
+    arg_x->set_type(GLMessage::DataType::INT);
+    arg_x->add_intvalue(x);
+
+    // copy argument y
+    GLMessage_DataType *arg_y = glmsg.add_args();
+    arg_y->set_isarray(false);
+    arg_y->set_type(GLMessage::DataType::INT);
+    arg_y->add_intvalue(y);
+
+    // copy argument z
+    GLMessage_DataType *arg_z = glmsg.add_args();
+    arg_z->set_isarray(false);
+    arg_z->set_type(GLMessage::DataType::INT);
+    arg_z->add_intvalue(z);
+
+    // call function
+    glContext->hooks->gl.glTranslatexOES(x, y, z);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+GLboolean GLTrace_glIsRenderbufferOES(GLuint renderbuffer) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glIsRenderbufferOES);
+
+    // copy argument renderbuffer
+    GLMessage_DataType *arg_renderbuffer = glmsg.add_args();
+    arg_renderbuffer->set_isarray(false);
+    arg_renderbuffer->set_type(GLMessage::DataType::INT);
+    arg_renderbuffer->add_intvalue(renderbuffer);
+
+    // call function
+    GLboolean retValue = glContext->hooks->gl.glIsRenderbufferOES(renderbuffer);
+
+    // set return value
+    GLMessage_DataType *rt = glmsg.mutable_returnvalue();
+    rt->set_isarray(false);
+    rt->set_type(GLMessage::DataType::BOOL);
+    rt->add_boolvalue(retValue);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+
+    return retValue;
+}
+
+void GLTrace_glBindRenderbufferOES(GLenum target, GLuint renderbuffer) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glBindRenderbufferOES);
+
+    // copy argument target
+    GLMessage_DataType *arg_target = glmsg.add_args();
+    arg_target->set_isarray(false);
+    arg_target->set_type(GLMessage::DataType::ENUM);
+    arg_target->add_intvalue((int)target);
+
+    // copy argument renderbuffer
+    GLMessage_DataType *arg_renderbuffer = glmsg.add_args();
+    arg_renderbuffer->set_isarray(false);
+    arg_renderbuffer->set_type(GLMessage::DataType::INT);
+    arg_renderbuffer->add_intvalue(renderbuffer);
+
+    // call function
+    glContext->hooks->gl.glBindRenderbufferOES(target, renderbuffer);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glDeleteRenderbuffersOES(GLsizei n, const GLuint* renderbuffers) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glDeleteRenderbuffersOES);
+
+    // copy argument n
+    GLMessage_DataType *arg_n = glmsg.add_args();
+    arg_n->set_isarray(false);
+    arg_n->set_type(GLMessage::DataType::INT);
+    arg_n->add_intvalue(n);
+
+    // copy argument renderbuffers
+    GLMessage_DataType *arg_renderbuffers = glmsg.add_args();
+    arg_renderbuffers->set_isarray(false);
+    arg_renderbuffers->set_type(GLMessage::DataType::INT);
+    arg_renderbuffers->add_intvalue((int)renderbuffers);
+
+    // call function
+    glContext->hooks->gl.glDeleteRenderbuffersOES(n, renderbuffers);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glGenRenderbuffersOES(GLsizei n, GLuint* renderbuffers) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glGenRenderbuffersOES);
+
+    // copy argument n
+    GLMessage_DataType *arg_n = glmsg.add_args();
+    arg_n->set_isarray(false);
+    arg_n->set_type(GLMessage::DataType::INT);
+    arg_n->add_intvalue(n);
+
+    // copy argument renderbuffers
+    GLMessage_DataType *arg_renderbuffers = glmsg.add_args();
+    arg_renderbuffers->set_isarray(false);
+    arg_renderbuffers->set_type(GLMessage::DataType::INT);
+    arg_renderbuffers->add_intvalue((int)renderbuffers);
+
+    // call function
+    glContext->hooks->gl.glGenRenderbuffersOES(n, renderbuffers);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glRenderbufferStorageOES(GLenum target, GLenum internalformat, GLsizei width, GLsizei height) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glRenderbufferStorageOES);
+
+    // copy argument target
+    GLMessage_DataType *arg_target = glmsg.add_args();
+    arg_target->set_isarray(false);
+    arg_target->set_type(GLMessage::DataType::ENUM);
+    arg_target->add_intvalue((int)target);
+
+    // copy argument internalformat
+    GLMessage_DataType *arg_internalformat = glmsg.add_args();
+    arg_internalformat->set_isarray(false);
+    arg_internalformat->set_type(GLMessage::DataType::ENUM);
+    arg_internalformat->add_intvalue((int)internalformat);
+
+    // copy argument width
+    GLMessage_DataType *arg_width = glmsg.add_args();
+    arg_width->set_isarray(false);
+    arg_width->set_type(GLMessage::DataType::INT);
+    arg_width->add_intvalue(width);
+
+    // copy argument height
+    GLMessage_DataType *arg_height = glmsg.add_args();
+    arg_height->set_isarray(false);
+    arg_height->set_type(GLMessage::DataType::INT);
+    arg_height->add_intvalue(height);
+
+    // call function
+    glContext->hooks->gl.glRenderbufferStorageOES(target, internalformat, width, height);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glGetRenderbufferParameterivOES(GLenum target, GLenum pname, GLint* params) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glGetRenderbufferParameterivOES);
+
+    // copy argument target
+    GLMessage_DataType *arg_target = glmsg.add_args();
+    arg_target->set_isarray(false);
+    arg_target->set_type(GLMessage::DataType::ENUM);
+    arg_target->add_intvalue((int)target);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument params
+    GLMessage_DataType *arg_params = glmsg.add_args();
+    arg_params->set_isarray(false);
+    arg_params->set_type(GLMessage::DataType::INT);
+    arg_params->add_intvalue((int)params);
+
+    // call function
+    glContext->hooks->gl.glGetRenderbufferParameterivOES(target, pname, params);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+GLboolean GLTrace_glIsFramebufferOES(GLuint framebuffer) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glIsFramebufferOES);
+
+    // copy argument framebuffer
+    GLMessage_DataType *arg_framebuffer = glmsg.add_args();
+    arg_framebuffer->set_isarray(false);
+    arg_framebuffer->set_type(GLMessage::DataType::INT);
+    arg_framebuffer->add_intvalue(framebuffer);
+
+    // call function
+    GLboolean retValue = glContext->hooks->gl.glIsFramebufferOES(framebuffer);
+
+    // set return value
+    GLMessage_DataType *rt = glmsg.mutable_returnvalue();
+    rt->set_isarray(false);
+    rt->set_type(GLMessage::DataType::BOOL);
+    rt->add_boolvalue(retValue);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+
+    return retValue;
+}
+
+void GLTrace_glBindFramebufferOES(GLenum target, GLuint framebuffer) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glBindFramebufferOES);
+
+    // copy argument target
+    GLMessage_DataType *arg_target = glmsg.add_args();
+    arg_target->set_isarray(false);
+    arg_target->set_type(GLMessage::DataType::ENUM);
+    arg_target->add_intvalue((int)target);
+
+    // copy argument framebuffer
+    GLMessage_DataType *arg_framebuffer = glmsg.add_args();
+    arg_framebuffer->set_isarray(false);
+    arg_framebuffer->set_type(GLMessage::DataType::INT);
+    arg_framebuffer->add_intvalue(framebuffer);
+
+    // call function
+    glContext->hooks->gl.glBindFramebufferOES(target, framebuffer);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glDeleteFramebuffersOES(GLsizei n, const GLuint* framebuffers) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glDeleteFramebuffersOES);
+
+    // copy argument n
+    GLMessage_DataType *arg_n = glmsg.add_args();
+    arg_n->set_isarray(false);
+    arg_n->set_type(GLMessage::DataType::INT);
+    arg_n->add_intvalue(n);
+
+    // copy argument framebuffers
+    GLMessage_DataType *arg_framebuffers = glmsg.add_args();
+    arg_framebuffers->set_isarray(false);
+    arg_framebuffers->set_type(GLMessage::DataType::INT);
+    arg_framebuffers->add_intvalue((int)framebuffers);
+
+    // call function
+    glContext->hooks->gl.glDeleteFramebuffersOES(n, framebuffers);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glGenFramebuffersOES(GLsizei n, GLuint* framebuffers) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glGenFramebuffersOES);
+
+    // copy argument n
+    GLMessage_DataType *arg_n = glmsg.add_args();
+    arg_n->set_isarray(false);
+    arg_n->set_type(GLMessage::DataType::INT);
+    arg_n->add_intvalue(n);
+
+    // copy argument framebuffers
+    GLMessage_DataType *arg_framebuffers = glmsg.add_args();
+    arg_framebuffers->set_isarray(false);
+    arg_framebuffers->set_type(GLMessage::DataType::INT);
+    arg_framebuffers->add_intvalue((int)framebuffers);
+
+    // call function
+    glContext->hooks->gl.glGenFramebuffersOES(n, framebuffers);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+GLenum GLTrace_glCheckFramebufferStatusOES(GLenum target) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glCheckFramebufferStatusOES);
+
+    // copy argument target
+    GLMessage_DataType *arg_target = glmsg.add_args();
+    arg_target->set_isarray(false);
+    arg_target->set_type(GLMessage::DataType::ENUM);
+    arg_target->add_intvalue((int)target);
+
+    // call function
+    GLenum retValue = glContext->hooks->gl.glCheckFramebufferStatusOES(target);
+
+    // set return value
+    GLMessage_DataType *rt = glmsg.mutable_returnvalue();
+    rt->set_isarray(false);
+    rt->set_type(GLMessage::DataType::ENUM);
+    rt->add_intvalue((int)retValue);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+
+    return retValue;
+}
+
+void GLTrace_glFramebufferRenderbufferOES(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glFramebufferRenderbufferOES);
+
+    // copy argument target
+    GLMessage_DataType *arg_target = glmsg.add_args();
+    arg_target->set_isarray(false);
+    arg_target->set_type(GLMessage::DataType::ENUM);
+    arg_target->add_intvalue((int)target);
+
+    // copy argument attachment
+    GLMessage_DataType *arg_attachment = glmsg.add_args();
+    arg_attachment->set_isarray(false);
+    arg_attachment->set_type(GLMessage::DataType::ENUM);
+    arg_attachment->add_intvalue((int)attachment);
+
+    // copy argument renderbuffertarget
+    GLMessage_DataType *arg_renderbuffertarget = glmsg.add_args();
+    arg_renderbuffertarget->set_isarray(false);
+    arg_renderbuffertarget->set_type(GLMessage::DataType::ENUM);
+    arg_renderbuffertarget->add_intvalue((int)renderbuffertarget);
+
+    // copy argument renderbuffer
+    GLMessage_DataType *arg_renderbuffer = glmsg.add_args();
+    arg_renderbuffer->set_isarray(false);
+    arg_renderbuffer->set_type(GLMessage::DataType::INT);
+    arg_renderbuffer->add_intvalue(renderbuffer);
+
+    // call function
+    glContext->hooks->gl.glFramebufferRenderbufferOES(target, attachment, renderbuffertarget, renderbuffer);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glFramebufferTexture2DOES(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glFramebufferTexture2DOES);
+
+    // copy argument target
+    GLMessage_DataType *arg_target = glmsg.add_args();
+    arg_target->set_isarray(false);
+    arg_target->set_type(GLMessage::DataType::ENUM);
+    arg_target->add_intvalue((int)target);
+
+    // copy argument attachment
+    GLMessage_DataType *arg_attachment = glmsg.add_args();
+    arg_attachment->set_isarray(false);
+    arg_attachment->set_type(GLMessage::DataType::ENUM);
+    arg_attachment->add_intvalue((int)attachment);
+
+    // copy argument textarget
+    GLMessage_DataType *arg_textarget = glmsg.add_args();
+    arg_textarget->set_isarray(false);
+    arg_textarget->set_type(GLMessage::DataType::ENUM);
+    arg_textarget->add_intvalue((int)textarget);
+
+    // copy argument texture
+    GLMessage_DataType *arg_texture = glmsg.add_args();
+    arg_texture->set_isarray(false);
+    arg_texture->set_type(GLMessage::DataType::INT);
+    arg_texture->add_intvalue(texture);
+
+    // copy argument level
+    GLMessage_DataType *arg_level = glmsg.add_args();
+    arg_level->set_isarray(false);
+    arg_level->set_type(GLMessage::DataType::INT);
+    arg_level->add_intvalue(level);
+
+    // call function
+    glContext->hooks->gl.glFramebufferTexture2DOES(target, attachment, textarget, texture, level);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glGetFramebufferAttachmentParameterivOES(GLenum target, GLenum attachment, GLenum pname, GLint* params) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glGetFramebufferAttachmentParameterivOES);
+
+    // copy argument target
+    GLMessage_DataType *arg_target = glmsg.add_args();
+    arg_target->set_isarray(false);
+    arg_target->set_type(GLMessage::DataType::ENUM);
+    arg_target->add_intvalue((int)target);
+
+    // copy argument attachment
+    GLMessage_DataType *arg_attachment = glmsg.add_args();
+    arg_attachment->set_isarray(false);
+    arg_attachment->set_type(GLMessage::DataType::ENUM);
+    arg_attachment->add_intvalue((int)attachment);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument params
+    GLMessage_DataType *arg_params = glmsg.add_args();
+    arg_params->set_isarray(false);
+    arg_params->set_type(GLMessage::DataType::INT);
+    arg_params->add_intvalue((int)params);
+
+    // call function
+    glContext->hooks->gl.glGetFramebufferAttachmentParameterivOES(target, attachment, pname, params);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glGenerateMipmapOES(GLenum target) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glGenerateMipmapOES);
+
+    // copy argument target
+    GLMessage_DataType *arg_target = glmsg.add_args();
+    arg_target->set_isarray(false);
+    arg_target->set_type(GLMessage::DataType::ENUM);
+    arg_target->add_intvalue((int)target);
+
+    // call function
+    glContext->hooks->gl.glGenerateMipmapOES(target);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glCurrentPaletteMatrixOES(GLuint matrixpaletteindex) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glCurrentPaletteMatrixOES);
+
+    // copy argument matrixpaletteindex
+    GLMessage_DataType *arg_matrixpaletteindex = glmsg.add_args();
+    arg_matrixpaletteindex->set_isarray(false);
+    arg_matrixpaletteindex->set_type(GLMessage::DataType::INT);
+    arg_matrixpaletteindex->add_intvalue(matrixpaletteindex);
+
+    // call function
+    glContext->hooks->gl.glCurrentPaletteMatrixOES(matrixpaletteindex);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glLoadPaletteFromModelViewMatrixOES(void) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glLoadPaletteFromModelViewMatrixOES);
+
+    // call function
+    glContext->hooks->gl.glLoadPaletteFromModelViewMatrixOES();
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glMatrixIndexPointerOES(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glMatrixIndexPointerOES);
+
+    // copy argument size
+    GLMessage_DataType *arg_size = glmsg.add_args();
+    arg_size->set_isarray(false);
+    arg_size->set_type(GLMessage::DataType::INT);
+    arg_size->add_intvalue(size);
+
+    // copy argument type
+    GLMessage_DataType *arg_type = glmsg.add_args();
+    arg_type->set_isarray(false);
+    arg_type->set_type(GLMessage::DataType::ENUM);
+    arg_type->add_intvalue((int)type);
+
+    // copy argument stride
+    GLMessage_DataType *arg_stride = glmsg.add_args();
+    arg_stride->set_isarray(false);
+    arg_stride->set_type(GLMessage::DataType::INT);
+    arg_stride->add_intvalue(stride);
+
+    // copy argument pointer
+    GLMessage_DataType *arg_pointer = glmsg.add_args();
+    arg_pointer->set_isarray(false);
+    arg_pointer->set_type(GLMessage::DataType::INT);
+    arg_pointer->add_intvalue((int)pointer);
+
+    // call function
+    glContext->hooks->gl.glMatrixIndexPointerOES(size, type, stride, pointer);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glWeightPointerOES(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glWeightPointerOES);
+
+    // copy argument size
+    GLMessage_DataType *arg_size = glmsg.add_args();
+    arg_size->set_isarray(false);
+    arg_size->set_type(GLMessage::DataType::INT);
+    arg_size->add_intvalue(size);
+
+    // copy argument type
+    GLMessage_DataType *arg_type = glmsg.add_args();
+    arg_type->set_isarray(false);
+    arg_type->set_type(GLMessage::DataType::ENUM);
+    arg_type->add_intvalue((int)type);
+
+    // copy argument stride
+    GLMessage_DataType *arg_stride = glmsg.add_args();
+    arg_stride->set_isarray(false);
+    arg_stride->set_type(GLMessage::DataType::INT);
+    arg_stride->add_intvalue(stride);
+
+    // copy argument pointer
+    GLMessage_DataType *arg_pointer = glmsg.add_args();
+    arg_pointer->set_isarray(false);
+    arg_pointer->set_type(GLMessage::DataType::INT);
+    arg_pointer->add_intvalue((int)pointer);
+
+    // call function
+    glContext->hooks->gl.glWeightPointerOES(size, type, stride, pointer);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+GLbitfield GLTrace_glQueryMatrixxOES(GLfixed mantissa[16], GLint exponent[16]) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glQueryMatrixxOES);
+
+    // copy argument mantissa
+    GLMessage_DataType *arg_mantissa = glmsg.add_args();
+    arg_mantissa->set_isarray(false);
+    arg_mantissa->set_type(GLMessage::DataType::INT);
+    arg_mantissa->add_intvalue((int)mantissa);
+
+    // copy argument exponent
+    GLMessage_DataType *arg_exponent = glmsg.add_args();
+    arg_exponent->set_isarray(false);
+    arg_exponent->set_type(GLMessage::DataType::INT);
+    arg_exponent->add_intvalue((int)exponent);
+
+    // call function
+    GLbitfield retValue = glContext->hooks->gl.glQueryMatrixxOES(mantissa, exponent);
+
+    // set return value
+    GLMessage_DataType *rt = glmsg.mutable_returnvalue();
+    rt->set_isarray(false);
+    rt->set_type(GLMessage::DataType::INT);
+    rt->add_intvalue(retValue);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+
+    return retValue;
+}
+
+void GLTrace_glDepthRangefOES(GLclampf zNear, GLclampf zFar) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glDepthRangefOES);
+
+    // copy argument zNear
+    GLMessage_DataType *arg_zNear = glmsg.add_args();
+    arg_zNear->set_isarray(false);
+    arg_zNear->set_type(GLMessage::DataType::FLOAT);
+    arg_zNear->add_floatvalue(zNear);
+
+    // copy argument zFar
+    GLMessage_DataType *arg_zFar = glmsg.add_args();
+    arg_zFar->set_isarray(false);
+    arg_zFar->set_type(GLMessage::DataType::FLOAT);
+    arg_zFar->add_floatvalue(zFar);
+
+    // call function
+    glContext->hooks->gl.glDepthRangefOES(zNear, zFar);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glFrustumfOES(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glFrustumfOES);
+
+    // copy argument left
+    GLMessage_DataType *arg_left = glmsg.add_args();
+    arg_left->set_isarray(false);
+    arg_left->set_type(GLMessage::DataType::FLOAT);
+    arg_left->add_floatvalue(left);
+
+    // copy argument right
+    GLMessage_DataType *arg_right = glmsg.add_args();
+    arg_right->set_isarray(false);
+    arg_right->set_type(GLMessage::DataType::FLOAT);
+    arg_right->add_floatvalue(right);
+
+    // copy argument bottom
+    GLMessage_DataType *arg_bottom = glmsg.add_args();
+    arg_bottom->set_isarray(false);
+    arg_bottom->set_type(GLMessage::DataType::FLOAT);
+    arg_bottom->add_floatvalue(bottom);
+
+    // copy argument top
+    GLMessage_DataType *arg_top = glmsg.add_args();
+    arg_top->set_isarray(false);
+    arg_top->set_type(GLMessage::DataType::FLOAT);
+    arg_top->add_floatvalue(top);
+
+    // copy argument zNear
+    GLMessage_DataType *arg_zNear = glmsg.add_args();
+    arg_zNear->set_isarray(false);
+    arg_zNear->set_type(GLMessage::DataType::FLOAT);
+    arg_zNear->add_floatvalue(zNear);
+
+    // copy argument zFar
+    GLMessage_DataType *arg_zFar = glmsg.add_args();
+    arg_zFar->set_isarray(false);
+    arg_zFar->set_type(GLMessage::DataType::FLOAT);
+    arg_zFar->add_floatvalue(zFar);
+
+    // call function
+    glContext->hooks->gl.glFrustumfOES(left, right, bottom, top, zNear, zFar);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glOrthofOES(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glOrthofOES);
+
+    // copy argument left
+    GLMessage_DataType *arg_left = glmsg.add_args();
+    arg_left->set_isarray(false);
+    arg_left->set_type(GLMessage::DataType::FLOAT);
+    arg_left->add_floatvalue(left);
+
+    // copy argument right
+    GLMessage_DataType *arg_right = glmsg.add_args();
+    arg_right->set_isarray(false);
+    arg_right->set_type(GLMessage::DataType::FLOAT);
+    arg_right->add_floatvalue(right);
+
+    // copy argument bottom
+    GLMessage_DataType *arg_bottom = glmsg.add_args();
+    arg_bottom->set_isarray(false);
+    arg_bottom->set_type(GLMessage::DataType::FLOAT);
+    arg_bottom->add_floatvalue(bottom);
+
+    // copy argument top
+    GLMessage_DataType *arg_top = glmsg.add_args();
+    arg_top->set_isarray(false);
+    arg_top->set_type(GLMessage::DataType::FLOAT);
+    arg_top->add_floatvalue(top);
+
+    // copy argument zNear
+    GLMessage_DataType *arg_zNear = glmsg.add_args();
+    arg_zNear->set_isarray(false);
+    arg_zNear->set_type(GLMessage::DataType::FLOAT);
+    arg_zNear->add_floatvalue(zNear);
+
+    // copy argument zFar
+    GLMessage_DataType *arg_zFar = glmsg.add_args();
+    arg_zFar->set_isarray(false);
+    arg_zFar->set_type(GLMessage::DataType::FLOAT);
+    arg_zFar->add_floatvalue(zFar);
+
+    // call function
+    glContext->hooks->gl.glOrthofOES(left, right, bottom, top, zNear, zFar);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glClipPlanefOES(GLenum plane, const GLfloat *equation) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glClipPlanefOES);
+
+    // copy argument plane
+    GLMessage_DataType *arg_plane = glmsg.add_args();
+    arg_plane->set_isarray(false);
+    arg_plane->set_type(GLMessage::DataType::ENUM);
+    arg_plane->add_intvalue((int)plane);
+
+    // copy argument equation
+    GLMessage_DataType *arg_equation = glmsg.add_args();
+    arg_equation->set_isarray(false);
+    arg_equation->set_type(GLMessage::DataType::INT);
+    arg_equation->add_intvalue((int)equation);
+
+    // call function
+    glContext->hooks->gl.glClipPlanefOES(plane, equation);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glGetClipPlanefOES(GLenum pname, GLfloat eqn[4]) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glGetClipPlanefOES);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument eqn
+    GLMessage_DataType *arg_eqn = glmsg.add_args();
+    arg_eqn->set_isarray(false);
+    arg_eqn->set_type(GLMessage::DataType::INT);
+    arg_eqn->add_intvalue((int)eqn);
+
+    // call function
+    glContext->hooks->gl.glGetClipPlanefOES(pname, eqn);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glClearDepthfOES(GLclampf depth) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glClearDepthfOES);
+
+    // copy argument depth
+    GLMessage_DataType *arg_depth = glmsg.add_args();
+    arg_depth->set_isarray(false);
+    arg_depth->set_type(GLMessage::DataType::FLOAT);
+    arg_depth->add_floatvalue(depth);
+
+    // call function
+    glContext->hooks->gl.glClearDepthfOES(depth);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glTexGenfOES(GLenum coord, GLenum pname, GLfloat param) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glTexGenfOES);
+
+    // copy argument coord
+    GLMessage_DataType *arg_coord = glmsg.add_args();
+    arg_coord->set_isarray(false);
+    arg_coord->set_type(GLMessage::DataType::ENUM);
+    arg_coord->add_intvalue((int)coord);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument param
+    GLMessage_DataType *arg_param = glmsg.add_args();
+    arg_param->set_isarray(false);
+    arg_param->set_type(GLMessage::DataType::FLOAT);
+    arg_param->add_floatvalue(param);
+
+    // call function
+    glContext->hooks->gl.glTexGenfOES(coord, pname, param);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glTexGenfvOES(GLenum coord, GLenum pname, const GLfloat *params) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glTexGenfvOES);
+
+    // copy argument coord
+    GLMessage_DataType *arg_coord = glmsg.add_args();
+    arg_coord->set_isarray(false);
+    arg_coord->set_type(GLMessage::DataType::ENUM);
+    arg_coord->add_intvalue((int)coord);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument params
+    GLMessage_DataType *arg_params = glmsg.add_args();
+    arg_params->set_isarray(false);
+    arg_params->set_type(GLMessage::DataType::INT);
+    arg_params->add_intvalue((int)params);
+
+    // call function
+    glContext->hooks->gl.glTexGenfvOES(coord, pname, params);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glTexGeniOES(GLenum coord, GLenum pname, GLint param) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glTexGeniOES);
+
+    // copy argument coord
+    GLMessage_DataType *arg_coord = glmsg.add_args();
+    arg_coord->set_isarray(false);
+    arg_coord->set_type(GLMessage::DataType::ENUM);
+    arg_coord->add_intvalue((int)coord);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument param
+    GLMessage_DataType *arg_param = glmsg.add_args();
+    arg_param->set_isarray(false);
+    arg_param->set_type(GLMessage::DataType::INT);
+    arg_param->add_intvalue(param);
+
+    // call function
+    glContext->hooks->gl.glTexGeniOES(coord, pname, param);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glTexGenivOES(GLenum coord, GLenum pname, const GLint *params) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glTexGenivOES);
+
+    // copy argument coord
+    GLMessage_DataType *arg_coord = glmsg.add_args();
+    arg_coord->set_isarray(false);
+    arg_coord->set_type(GLMessage::DataType::ENUM);
+    arg_coord->add_intvalue((int)coord);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument params
+    GLMessage_DataType *arg_params = glmsg.add_args();
+    arg_params->set_isarray(false);
+    arg_params->set_type(GLMessage::DataType::INT);
+    arg_params->add_intvalue((int)params);
+
+    // call function
+    glContext->hooks->gl.glTexGenivOES(coord, pname, params);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glTexGenxOES(GLenum coord, GLenum pname, GLfixed param) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glTexGenxOES);
+
+    // copy argument coord
+    GLMessage_DataType *arg_coord = glmsg.add_args();
+    arg_coord->set_isarray(false);
+    arg_coord->set_type(GLMessage::DataType::ENUM);
+    arg_coord->add_intvalue((int)coord);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument param
+    GLMessage_DataType *arg_param = glmsg.add_args();
+    arg_param->set_isarray(false);
+    arg_param->set_type(GLMessage::DataType::INT);
+    arg_param->add_intvalue(param);
+
+    // call function
+    glContext->hooks->gl.glTexGenxOES(coord, pname, param);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glTexGenxvOES(GLenum coord, GLenum pname, const GLfixed *params) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glTexGenxvOES);
+
+    // copy argument coord
+    GLMessage_DataType *arg_coord = glmsg.add_args();
+    arg_coord->set_isarray(false);
+    arg_coord->set_type(GLMessage::DataType::ENUM);
+    arg_coord->add_intvalue((int)coord);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument params
+    GLMessage_DataType *arg_params = glmsg.add_args();
+    arg_params->set_isarray(false);
+    arg_params->set_type(GLMessage::DataType::INT);
+    arg_params->add_intvalue((int)params);
+
+    // call function
+    glContext->hooks->gl.glTexGenxvOES(coord, pname, params);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glGetTexGenfvOES(GLenum coord, GLenum pname, GLfloat *params) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glGetTexGenfvOES);
+
+    // copy argument coord
+    GLMessage_DataType *arg_coord = glmsg.add_args();
+    arg_coord->set_isarray(false);
+    arg_coord->set_type(GLMessage::DataType::ENUM);
+    arg_coord->add_intvalue((int)coord);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument params
+    GLMessage_DataType *arg_params = glmsg.add_args();
+    arg_params->set_isarray(false);
+    arg_params->set_type(GLMessage::DataType::INT);
+    arg_params->add_intvalue((int)params);
+
+    // call function
+    glContext->hooks->gl.glGetTexGenfvOES(coord, pname, params);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glGetTexGenivOES(GLenum coord, GLenum pname, GLint *params) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glGetTexGenivOES);
+
+    // copy argument coord
+    GLMessage_DataType *arg_coord = glmsg.add_args();
+    arg_coord->set_isarray(false);
+    arg_coord->set_type(GLMessage::DataType::ENUM);
+    arg_coord->add_intvalue((int)coord);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument params
+    GLMessage_DataType *arg_params = glmsg.add_args();
+    arg_params->set_isarray(false);
+    arg_params->set_type(GLMessage::DataType::INT);
+    arg_params->add_intvalue((int)params);
+
+    // call function
+    glContext->hooks->gl.glGetTexGenivOES(coord, pname, params);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glGetTexGenxvOES(GLenum coord, GLenum pname, GLfixed *params) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glGetTexGenxvOES);
+
+    // copy argument coord
+    GLMessage_DataType *arg_coord = glmsg.add_args();
+    arg_coord->set_isarray(false);
+    arg_coord->set_type(GLMessage::DataType::ENUM);
+    arg_coord->add_intvalue((int)coord);
+
+    // copy argument pname
+    GLMessage_DataType *arg_pname = glmsg.add_args();
+    arg_pname->set_isarray(false);
+    arg_pname->set_type(GLMessage::DataType::ENUM);
+    arg_pname->add_intvalue((int)pname);
+
+    // copy argument params
+    GLMessage_DataType *arg_params = glmsg.add_args();
+    arg_params->set_isarray(false);
+    arg_params->set_type(GLMessage::DataType::INT);
+    arg_params->add_intvalue((int)params);
+
+    // call function
+    glContext->hooks->gl.glGetTexGenxvOES(coord, pname, params);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glClipPlanefIMG(GLenum p, const GLfloat *eqn) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glClipPlanefIMG);
+
+    // copy argument p
+    GLMessage_DataType *arg_p = glmsg.add_args();
+    arg_p->set_isarray(false);
+    arg_p->set_type(GLMessage::DataType::ENUM);
+    arg_p->add_intvalue((int)p);
+
+    // copy argument eqn
+    GLMessage_DataType *arg_eqn = glmsg.add_args();
+    arg_eqn->set_isarray(false);
+    arg_eqn->set_type(GLMessage::DataType::INT);
+    arg_eqn->add_intvalue((int)eqn);
+
+    // call function
+    glContext->hooks->gl.glClipPlanefIMG(p, eqn);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+void GLTrace_glClipPlanexIMG(GLenum p, const GLfixed *eqn) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::glClipPlanexIMG);
+
+    // copy argument p
+    GLMessage_DataType *arg_p = glmsg.add_args();
+    arg_p->set_isarray(false);
+    arg_p->set_type(GLMessage::DataType::ENUM);
+    arg_p->add_intvalue((int)p);
+
+    // copy argument eqn
+    GLMessage_DataType *arg_eqn = glmsg.add_args();
+    arg_eqn->set_isarray(false);
+    arg_eqn->set_type(GLMessage::DataType::INT);
+    arg_eqn->add_intvalue((int)eqn);
+
+    // call function
+    glContext->hooks->gl.glClipPlanexIMG(p, eqn);
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+}
+
+
+
+}; // namespace gltrace
+}; // namespace android
diff --git a/opengl/libs/GLES_trace/src/gltrace_api.h b/opengl/libs/GLES_trace/src/gltrace_api.h
new file mode 100644
index 0000000..a13ede3
--- /dev/null
+++ b/opengl/libs/GLES_trace/src/gltrace_api.h
@@ -0,0 +1,421 @@
+/*
+ * Copyright 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.
+ *
+ * THIS FILE WAS GENERATED BY A SCRIPT. DO NOT EDIT.
+ */
+
+#include <cutils/log.h>
+#include <GLES2/gl2.h>
+
+#include "gltrace.pb.h"
+#include "gltrace_context.h"
+#include "gltrace_fixup.h"
+#include "gltrace_transport.h"
+
+namespace android {
+namespace gltrace {
+
+
+// Declarations for GL2 APIs
+
+void GLTrace_glActiveTexture(GLenum texture);
+void GLTrace_glAttachShader(GLuint program, GLuint shader);
+void GLTrace_glBindAttribLocation(GLuint program, GLuint index, const GLchar* name);
+void GLTrace_glBindBuffer(GLenum target, GLuint buffer);
+void GLTrace_glBindFramebuffer(GLenum target, GLuint framebuffer);
+void GLTrace_glBindRenderbuffer(GLenum target, GLuint renderbuffer);
+void GLTrace_glBindTexture(GLenum target, GLuint texture);
+void GLTrace_glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
+void GLTrace_glBlendEquation(GLenum mode);
+void GLTrace_glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha);
+void GLTrace_glBlendFunc(GLenum sfactor, GLenum dfactor);
+void GLTrace_glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+void GLTrace_glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage);
+void GLTrace_glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data);
+GLenum GLTrace_glCheckFramebufferStatus(GLenum target);
+void GLTrace_glClear(GLbitfield mask);
+void GLTrace_glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
+void GLTrace_glClearDepthf(GLclampf depth);
+void GLTrace_glClearStencil(GLint s);
+void GLTrace_glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
+void GLTrace_glCompileShader(GLuint shader);
+void GLTrace_glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid* data);
+void GLTrace_glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid* data);
+void GLTrace_glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
+void GLTrace_glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+GLuint GLTrace_glCreateProgram(void);
+GLuint GLTrace_glCreateShader(GLenum type);
+void GLTrace_glCullFace(GLenum mode);
+void GLTrace_glDeleteBuffers(GLsizei n, const GLuint* buffers);
+void GLTrace_glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers);
+void GLTrace_glDeleteProgram(GLuint program);
+void GLTrace_glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers);
+void GLTrace_glDeleteShader(GLuint shader);
+void GLTrace_glDeleteTextures(GLsizei n, const GLuint* textures);
+void GLTrace_glDepthFunc(GLenum func);
+void GLTrace_glDepthMask(GLboolean flag);
+void GLTrace_glDepthRangef(GLclampf zNear, GLclampf zFar);
+void GLTrace_glDetachShader(GLuint program, GLuint shader);
+void GLTrace_glDisable(GLenum cap);
+void GLTrace_glDisableVertexAttribArray(GLuint index);
+void GLTrace_glDrawArrays(GLenum mode, GLint first, GLsizei count);
+void GLTrace_glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices);
+void GLTrace_glEnable(GLenum cap);
+void GLTrace_glEnableVertexAttribArray(GLuint index);
+void GLTrace_glFinish(void);
+void GLTrace_glFlush(void);
+void GLTrace_glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
+void GLTrace_glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+void GLTrace_glFrontFace(GLenum mode);
+void GLTrace_glGenBuffers(GLsizei n, GLuint* buffers);
+void GLTrace_glGenerateMipmap(GLenum target);
+void GLTrace_glGenFramebuffers(GLsizei n, GLuint* framebuffers);
+void GLTrace_glGenRenderbuffers(GLsizei n, GLuint* renderbuffers);
+void GLTrace_glGenTextures(GLsizei n, GLuint* textures);
+void GLTrace_glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name);
+void GLTrace_glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name);
+void GLTrace_glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders);
+int GLTrace_glGetAttribLocation(GLuint program, const GLchar* name);
+void GLTrace_glGetBooleanv(GLenum pname, GLboolean* params);
+void GLTrace_glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params);
+GLenum GLTrace_glGetError(void);
+void GLTrace_glGetFloatv(GLenum pname, GLfloat* params);
+void GLTrace_glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params);
+void GLTrace_glGetIntegerv(GLenum pname, GLint* params);
+void GLTrace_glGetProgramiv(GLuint program, GLenum pname, GLint* params);
+void GLTrace_glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog);
+void GLTrace_glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params);
+void GLTrace_glGetShaderiv(GLuint shader, GLenum pname, GLint* params);
+void GLTrace_glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog);
+void GLTrace_glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision);
+void GLTrace_glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source);
+const GLubyte* GLTrace_glGetString(GLenum name);
+void GLTrace_glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params);
+void GLTrace_glGetTexParameteriv(GLenum target, GLenum pname, GLint* params);
+void GLTrace_glGetUniformfv(GLuint program, GLint location, GLfloat* params);
+void GLTrace_glGetUniformiv(GLuint program, GLint location, GLint* params);
+int GLTrace_glGetUniformLocation(GLuint program, const GLchar* name);
+void GLTrace_glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params);
+void GLTrace_glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params);
+void GLTrace_glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer);
+void GLTrace_glHint(GLenum target, GLenum mode);
+GLboolean GLTrace_glIsBuffer(GLuint buffer);
+GLboolean GLTrace_glIsEnabled(GLenum cap);
+GLboolean GLTrace_glIsFramebuffer(GLuint framebuffer);
+GLboolean GLTrace_glIsProgram(GLuint program);
+GLboolean GLTrace_glIsRenderbuffer(GLuint renderbuffer);
+GLboolean GLTrace_glIsShader(GLuint shader);
+GLboolean GLTrace_glIsTexture(GLuint texture);
+void GLTrace_glLineWidth(GLfloat width);
+void GLTrace_glLinkProgram(GLuint program);
+void GLTrace_glPixelStorei(GLenum pname, GLint param);
+void GLTrace_glPolygonOffset(GLfloat factor, GLfloat units);
+void GLTrace_glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels);
+void GLTrace_glReleaseShaderCompiler(void);
+void GLTrace_glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
+void GLTrace_glSampleCoverage(GLclampf value, GLboolean invert);
+void GLTrace_glScissor(GLint x, GLint y, GLsizei width, GLsizei height);
+void GLTrace_glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length);
+void GLTrace_glShaderSource(GLuint shader, GLsizei count, const GLchar** string, const GLint* length);
+void GLTrace_glStencilFunc(GLenum func, GLint ref, GLuint mask);
+void GLTrace_glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask);
+void GLTrace_glStencilMask(GLuint mask);
+void GLTrace_glStencilMaskSeparate(GLenum face, GLuint mask);
+void GLTrace_glStencilOp(GLenum fail, GLenum zfail, GLenum zpass);
+void GLTrace_glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass);
+void GLTrace_glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid* pixels);
+void GLTrace_glTexParameterf(GLenum target, GLenum pname, GLfloat param);
+void GLTrace_glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params);
+void GLTrace_glTexParameteri(GLenum target, GLenum pname, GLint param);
+void GLTrace_glTexParameteriv(GLenum target, GLenum pname, const GLint* params);
+void GLTrace_glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid* pixels);
+void GLTrace_glUniform1f(GLint location, GLfloat x);
+void GLTrace_glUniform1fv(GLint location, GLsizei count, const GLfloat* v);
+void GLTrace_glUniform1i(GLint location, GLint x);
+void GLTrace_glUniform1iv(GLint location, GLsizei count, const GLint* v);
+void GLTrace_glUniform2f(GLint location, GLfloat x, GLfloat y);
+void GLTrace_glUniform2fv(GLint location, GLsizei count, const GLfloat* v);
+void GLTrace_glUniform2i(GLint location, GLint x, GLint y);
+void GLTrace_glUniform2iv(GLint location, GLsizei count, const GLint* v);
+void GLTrace_glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z);
+void GLTrace_glUniform3fv(GLint location, GLsizei count, const GLfloat* v);
+void GLTrace_glUniform3i(GLint location, GLint x, GLint y, GLint z);
+void GLTrace_glUniform3iv(GLint location, GLsizei count, const GLint* v);
+void GLTrace_glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+void GLTrace_glUniform4fv(GLint location, GLsizei count, const GLfloat* v);
+void GLTrace_glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w);
+void GLTrace_glUniform4iv(GLint location, GLsizei count, const GLint* v);
+void GLTrace_glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+void GLTrace_glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+void GLTrace_glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+void GLTrace_glUseProgram(GLuint program);
+void GLTrace_glValidateProgram(GLuint program);
+void GLTrace_glVertexAttrib1f(GLuint indx, GLfloat x);
+void GLTrace_glVertexAttrib1fv(GLuint indx, const GLfloat* values);
+void GLTrace_glVertexAttrib2f(GLuint indx, GLfloat x, GLfloat y);
+void GLTrace_glVertexAttrib2fv(GLuint indx, const GLfloat* values);
+void GLTrace_glVertexAttrib3f(GLuint indx, GLfloat x, GLfloat y, GLfloat z);
+void GLTrace_glVertexAttrib3fv(GLuint indx, const GLfloat* values);
+void GLTrace_glVertexAttrib4f(GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+void GLTrace_glVertexAttrib4fv(GLuint indx, const GLfloat* values);
+void GLTrace_glVertexAttribPointer(GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr);
+void GLTrace_glViewport(GLint x, GLint y, GLsizei width, GLsizei height);
+
+// Declarations for GL2Ext APIs
+
+void GLTrace_glEGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image);
+void GLTrace_glEGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image);
+void GLTrace_glGetProgramBinaryOES(GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, GLvoid *binary);
+void GLTrace_glProgramBinaryOES(GLuint program, GLenum binaryFormat, const GLvoid *binary, GLint length);
+void* GLTrace_glMapBufferOES(GLenum target, GLenum access);
+GLboolean GLTrace_glUnmapBufferOES(GLenum target);
+void GLTrace_glGetBufferPointervOES(GLenum target, GLenum pname, GLvoid** params);
+void GLTrace_glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid* pixels);
+void GLTrace_glTexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid* pixels);
+void GLTrace_glCopyTexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+void GLTrace_glCompressedTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid* data);
+void GLTrace_glCompressedTexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid* data);
+void GLTrace_glFramebufferTexture3DOES(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset);
+void GLTrace_glBindVertexArrayOES(GLuint array);
+void GLTrace_glDeleteVertexArraysOES(GLsizei n, const GLuint *arrays);
+void GLTrace_glGenVertexArraysOES(GLsizei n, GLuint *arrays);
+GLboolean GLTrace_glIsVertexArrayOES(GLuint array);
+void GLTrace_glGetPerfMonitorGroupsAMD(GLint *numGroups, GLsizei groupsSize, GLuint *groups);
+void GLTrace_glGetPerfMonitorCountersAMD(GLuint group, GLint *numCounters, GLint *maxActiveCounters, GLsizei counterSize, GLuint *counters);
+void GLTrace_glGetPerfMonitorGroupStringAMD(GLuint group, GLsizei bufSize, GLsizei *length, GLchar *groupString);
+void GLTrace_glGetPerfMonitorCounterStringAMD(GLuint group, GLuint counter, GLsizei bufSize, GLsizei *length, GLchar *counterString);
+void GLTrace_glGetPerfMonitorCounterInfoAMD(GLuint group, GLuint counter, GLenum pname, GLvoid *data);
+void GLTrace_glGenPerfMonitorsAMD(GLsizei n, GLuint *monitors);
+void GLTrace_glDeletePerfMonitorsAMD(GLsizei n, GLuint *monitors);
+void GLTrace_glSelectPerfMonitorCountersAMD(GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint *countersList);
+void GLTrace_glBeginPerfMonitorAMD(GLuint monitor);
+void GLTrace_glEndPerfMonitorAMD(GLuint monitor);
+void GLTrace_glGetPerfMonitorCounterDataAMD(GLuint monitor, GLenum pname, GLsizei dataSize, GLuint *data, GLint *bytesWritten);
+void GLTrace_glDiscardFramebufferEXT(GLenum target, GLsizei numAttachments, const GLenum *attachments);
+void GLTrace_glMultiDrawArraysEXT(GLenum mode, GLint *first, GLsizei *count, GLsizei primcount);
+void GLTrace_glMultiDrawElementsEXT(GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount);
+void GLTrace_glRenderbufferStorageMultisampleIMG(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+void GLTrace_glFramebufferTexture2DMultisampleIMG(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples);
+void GLTrace_glDeleteFencesNV(GLsizei n, const GLuint *fences);
+void GLTrace_glGenFencesNV(GLsizei n, GLuint *fences);
+GLboolean GLTrace_glIsFenceNV(GLuint fence);
+GLboolean GLTrace_glTestFenceNV(GLuint fence);
+void GLTrace_glGetFenceivNV(GLuint fence, GLenum pname, GLint *params);
+void GLTrace_glFinishFenceNV(GLuint fence);
+void GLTrace_glSetFenceNV(GLuint fence, GLenum condition);
+void GLTrace_glCoverageMaskNV(GLboolean mask);
+void GLTrace_glCoverageOperationNV(GLenum operation);
+void GLTrace_glGetDriverControlsQCOM(GLint *num, GLsizei size, GLuint *driverControls);
+void GLTrace_glGetDriverControlStringQCOM(GLuint driverControl, GLsizei bufSize, GLsizei *length, GLchar *driverControlString);
+void GLTrace_glEnableDriverControlQCOM(GLuint driverControl);
+void GLTrace_glDisableDriverControlQCOM(GLuint driverControl);
+void GLTrace_glExtGetTexturesQCOM(GLuint *textures, GLint maxTextures, GLint *numTextures);
+void GLTrace_glExtGetBuffersQCOM(GLuint *buffers, GLint maxBuffers, GLint *numBuffers);
+void GLTrace_glExtGetRenderbuffersQCOM(GLuint *renderbuffers, GLint maxRenderbuffers, GLint *numRenderbuffers);
+void GLTrace_glExtGetFramebuffersQCOM(GLuint *framebuffers, GLint maxFramebuffers, GLint *numFramebuffers);
+void GLTrace_glExtGetTexLevelParameterivQCOM(GLuint texture, GLenum face, GLint level, GLenum pname, GLint *params);
+void GLTrace_glExtTexObjectStateOverrideiQCOM(GLenum target, GLenum pname, GLint param);
+void GLTrace_glExtGetTexSubImageQCOM(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLvoid *texels);
+void GLTrace_glExtGetBufferPointervQCOM(GLenum target, GLvoid **params);
+void GLTrace_glExtGetShadersQCOM(GLuint *shaders, GLint maxShaders, GLint *numShaders);
+void GLTrace_glExtGetProgramsQCOM(GLuint *programs, GLint maxPrograms, GLint *numPrograms);
+GLboolean GLTrace_glExtIsProgramBinaryQCOM(GLuint program);
+void GLTrace_glExtGetProgramBinarySourceQCOM(GLuint program, GLenum shadertype, GLchar *source, GLint *length);
+void GLTrace_glStartTilingQCOM(GLuint x, GLuint y, GLuint width, GLuint height, GLbitfield preserveMask);
+void GLTrace_glEndTilingQCOM(GLbitfield preserveMask);
+
+// Declarations for GL1 APIs
+
+void GLTrace_glAlphaFunc(GLenum func, GLclampf ref);
+void GLTrace_glClipPlanef(GLenum plane, const GLfloat *equation);
+void GLTrace_glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
+void GLTrace_glFogf(GLenum pname, GLfloat param);
+void GLTrace_glFogfv(GLenum pname, const GLfloat *params);
+void GLTrace_glFrustumf(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar);
+void GLTrace_glGetClipPlanef(GLenum pname, GLfloat eqn[4]);
+void GLTrace_glGetLightfv(GLenum light, GLenum pname, GLfloat *params);
+void GLTrace_glGetMaterialfv(GLenum face, GLenum pname, GLfloat *params);
+void GLTrace_glGetTexEnvfv(GLenum env, GLenum pname, GLfloat *params);
+void GLTrace_glLightModelf(GLenum pname, GLfloat param);
+void GLTrace_glLightModelfv(GLenum pname, const GLfloat *params);
+void GLTrace_glLightf(GLenum light, GLenum pname, GLfloat param);
+void GLTrace_glLightfv(GLenum light, GLenum pname, const GLfloat *params);
+void GLTrace_glLoadMatrixf(const GLfloat *m);
+void GLTrace_glMaterialf(GLenum face, GLenum pname, GLfloat param);
+void GLTrace_glMaterialfv(GLenum face, GLenum pname, const GLfloat *params);
+void GLTrace_glMultMatrixf(const GLfloat *m);
+void GLTrace_glMultiTexCoord4f(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q);
+void GLTrace_glNormal3f(GLfloat nx, GLfloat ny, GLfloat nz);
+void GLTrace_glOrthof(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar);
+void GLTrace_glPointParameterf(GLenum pname, GLfloat param);
+void GLTrace_glPointParameterfv(GLenum pname, const GLfloat *params);
+void GLTrace_glPointSize(GLfloat size);
+void GLTrace_glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z);
+void GLTrace_glScalef(GLfloat x, GLfloat y, GLfloat z);
+void GLTrace_glTexEnvf(GLenum target, GLenum pname, GLfloat param);
+void GLTrace_glTexEnvfv(GLenum target, GLenum pname, const GLfloat *params);
+void GLTrace_glTranslatef(GLfloat x, GLfloat y, GLfloat z);
+void GLTrace_glAlphaFuncx(GLenum func, GLclampx ref);
+void GLTrace_glClearColorx(GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha);
+void GLTrace_glClearDepthx(GLclampx depth);
+void GLTrace_glClientActiveTexture(GLenum texture);
+void GLTrace_glClipPlanex(GLenum plane, const GLfixed *equation);
+void GLTrace_glColor4ub(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha);
+void GLTrace_glColor4x(GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha);
+void GLTrace_glColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+void GLTrace_glDepthRangex(GLclampx zNear, GLclampx zFar);
+void GLTrace_glDisableClientState(GLenum array);
+void GLTrace_glEnableClientState(GLenum array);
+void GLTrace_glFogx(GLenum pname, GLfixed param);
+void GLTrace_glFogxv(GLenum pname, const GLfixed *params);
+void GLTrace_glFrustumx(GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar);
+void GLTrace_glGetClipPlanex(GLenum pname, GLfixed eqn[4]);
+void GLTrace_glGetFixedv(GLenum pname, GLfixed *params);
+void GLTrace_glGetLightxv(GLenum light, GLenum pname, GLfixed *params);
+void GLTrace_glGetMaterialxv(GLenum face, GLenum pname, GLfixed *params);
+void GLTrace_glGetPointerv(GLenum pname, GLvoid **params);
+void GLTrace_glGetTexEnviv(GLenum env, GLenum pname, GLint *params);
+void GLTrace_glGetTexEnvxv(GLenum env, GLenum pname, GLfixed *params);
+void GLTrace_glGetTexParameterxv(GLenum target, GLenum pname, GLfixed *params);
+void GLTrace_glLightModelx(GLenum pname, GLfixed param);
+void GLTrace_glLightModelxv(GLenum pname, const GLfixed *params);
+void GLTrace_glLightx(GLenum light, GLenum pname, GLfixed param);
+void GLTrace_glLightxv(GLenum light, GLenum pname, const GLfixed *params);
+void GLTrace_glLineWidthx(GLfixed width);
+void GLTrace_glLoadIdentity(void);
+void GLTrace_glLoadMatrixx(const GLfixed *m);
+void GLTrace_glLogicOp(GLenum opcode);
+void GLTrace_glMaterialx(GLenum face, GLenum pname, GLfixed param);
+void GLTrace_glMaterialxv(GLenum face, GLenum pname, const GLfixed *params);
+void GLTrace_glMatrixMode(GLenum mode);
+void GLTrace_glMultMatrixx(const GLfixed *m);
+void GLTrace_glMultiTexCoord4x(GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q);
+void GLTrace_glNormal3x(GLfixed nx, GLfixed ny, GLfixed nz);
+void GLTrace_glNormalPointer(GLenum type, GLsizei stride, const GLvoid *pointer);
+void GLTrace_glOrthox(GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar);
+void GLTrace_glPointParameterx(GLenum pname, GLfixed param);
+void GLTrace_glPointParameterxv(GLenum pname, const GLfixed *params);
+void GLTrace_glPointSizex(GLfixed size);
+void GLTrace_glPolygonOffsetx(GLfixed factor, GLfixed units);
+void GLTrace_glPopMatrix(void);
+void GLTrace_glPushMatrix(void);
+void GLTrace_glRotatex(GLfixed angle, GLfixed x, GLfixed y, GLfixed z);
+void GLTrace_glSampleCoveragex(GLclampx value, GLboolean invert);
+void GLTrace_glScalex(GLfixed x, GLfixed y, GLfixed z);
+void GLTrace_glShadeModel(GLenum mode);
+void GLTrace_glTexCoordPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+void GLTrace_glTexEnvi(GLenum target, GLenum pname, GLint param);
+void GLTrace_glTexEnvx(GLenum target, GLenum pname, GLfixed param);
+void GLTrace_glTexEnviv(GLenum target, GLenum pname, const GLint *params);
+void GLTrace_glTexEnvxv(GLenum target, GLenum pname, const GLfixed *params);
+void GLTrace_glTexParameterx(GLenum target, GLenum pname, GLfixed param);
+void GLTrace_glTexParameterxv(GLenum target, GLenum pname, const GLfixed *params);
+void GLTrace_glTranslatex(GLfixed x, GLfixed y, GLfixed z);
+void GLTrace_glVertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+void GLTrace_glPointSizePointerOES(GLenum type, GLsizei stride, const GLvoid *pointer);
+
+// Declarations for GL1Ext APIs
+
+void GLTrace_glBlendEquationSeparateOES(GLenum modeRGB, GLenum modeAlpha);
+void GLTrace_glBlendFuncSeparateOES(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+void GLTrace_glBlendEquationOES(GLenum mode);
+void GLTrace_glDrawTexsOES(GLshort x, GLshort y, GLshort z, GLshort width, GLshort height);
+void GLTrace_glDrawTexiOES(GLint x, GLint y, GLint z, GLint width, GLint height);
+void GLTrace_glDrawTexxOES(GLfixed x, GLfixed y, GLfixed z, GLfixed width, GLfixed height);
+void GLTrace_glDrawTexsvOES(const GLshort *coords);
+void GLTrace_glDrawTexivOES(const GLint *coords);
+void GLTrace_glDrawTexxvOES(const GLfixed *coords);
+void GLTrace_glDrawTexfOES(GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height);
+void GLTrace_glDrawTexfvOES(const GLfloat *coords);
+void GLTrace_glAlphaFuncxOES(GLenum func, GLclampx ref);
+void GLTrace_glClearColorxOES(GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha);
+void GLTrace_glClearDepthxOES(GLclampx depth);
+void GLTrace_glClipPlanexOES(GLenum plane, const GLfixed *equation);
+void GLTrace_glColor4xOES(GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha);
+void GLTrace_glDepthRangexOES(GLclampx zNear, GLclampx zFar);
+void GLTrace_glFogxOES(GLenum pname, GLfixed param);
+void GLTrace_glFogxvOES(GLenum pname, const GLfixed *params);
+void GLTrace_glFrustumxOES(GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar);
+void GLTrace_glGetClipPlanexOES(GLenum pname, GLfixed eqn[4]);
+void GLTrace_glGetFixedvOES(GLenum pname, GLfixed *params);
+void GLTrace_glGetLightxvOES(GLenum light, GLenum pname, GLfixed *params);
+void GLTrace_glGetMaterialxvOES(GLenum face, GLenum pname, GLfixed *params);
+void GLTrace_glGetTexEnvxvOES(GLenum env, GLenum pname, GLfixed *params);
+void GLTrace_glGetTexParameterxvOES(GLenum target, GLenum pname, GLfixed *params);
+void GLTrace_glLightModelxOES(GLenum pname, GLfixed param);
+void GLTrace_glLightModelxvOES(GLenum pname, const GLfixed *params);
+void GLTrace_glLightxOES(GLenum light, GLenum pname, GLfixed param);
+void GLTrace_glLightxvOES(GLenum light, GLenum pname, const GLfixed *params);
+void GLTrace_glLineWidthxOES(GLfixed width);
+void GLTrace_glLoadMatrixxOES(const GLfixed *m);
+void GLTrace_glMaterialxOES(GLenum face, GLenum pname, GLfixed param);
+void GLTrace_glMaterialxvOES(GLenum face, GLenum pname, const GLfixed *params);
+void GLTrace_glMultMatrixxOES(const GLfixed *m);
+void GLTrace_glMultiTexCoord4xOES(GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q);
+void GLTrace_glNormal3xOES(GLfixed nx, GLfixed ny, GLfixed nz);
+void GLTrace_glOrthoxOES(GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar);
+void GLTrace_glPointParameterxOES(GLenum pname, GLfixed param);
+void GLTrace_glPointParameterxvOES(GLenum pname, const GLfixed *params);
+void GLTrace_glPointSizexOES(GLfixed size);
+void GLTrace_glPolygonOffsetxOES(GLfixed factor, GLfixed units);
+void GLTrace_glRotatexOES(GLfixed angle, GLfixed x, GLfixed y, GLfixed z);
+void GLTrace_glSampleCoveragexOES(GLclampx value, GLboolean invert);
+void GLTrace_glScalexOES(GLfixed x, GLfixed y, GLfixed z);
+void GLTrace_glTexEnvxOES(GLenum target, GLenum pname, GLfixed param);
+void GLTrace_glTexEnvxvOES(GLenum target, GLenum pname, const GLfixed *params);
+void GLTrace_glTexParameterxOES(GLenum target, GLenum pname, GLfixed param);
+void GLTrace_glTexParameterxvOES(GLenum target, GLenum pname, const GLfixed *params);
+void GLTrace_glTranslatexOES(GLfixed x, GLfixed y, GLfixed z);
+GLboolean GLTrace_glIsRenderbufferOES(GLuint renderbuffer);
+void GLTrace_glBindRenderbufferOES(GLenum target, GLuint renderbuffer);
+void GLTrace_glDeleteRenderbuffersOES(GLsizei n, const GLuint* renderbuffers);
+void GLTrace_glGenRenderbuffersOES(GLsizei n, GLuint* renderbuffers);
+void GLTrace_glRenderbufferStorageOES(GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
+void GLTrace_glGetRenderbufferParameterivOES(GLenum target, GLenum pname, GLint* params);
+GLboolean GLTrace_glIsFramebufferOES(GLuint framebuffer);
+void GLTrace_glBindFramebufferOES(GLenum target, GLuint framebuffer);
+void GLTrace_glDeleteFramebuffersOES(GLsizei n, const GLuint* framebuffers);
+void GLTrace_glGenFramebuffersOES(GLsizei n, GLuint* framebuffers);
+GLenum GLTrace_glCheckFramebufferStatusOES(GLenum target);
+void GLTrace_glFramebufferRenderbufferOES(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
+void GLTrace_glFramebufferTexture2DOES(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+void GLTrace_glGetFramebufferAttachmentParameterivOES(GLenum target, GLenum attachment, GLenum pname, GLint* params);
+void GLTrace_glGenerateMipmapOES(GLenum target);
+void GLTrace_glCurrentPaletteMatrixOES(GLuint matrixpaletteindex);
+void GLTrace_glLoadPaletteFromModelViewMatrixOES(void);
+void GLTrace_glMatrixIndexPointerOES(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+void GLTrace_glWeightPointerOES(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+GLbitfield GLTrace_glQueryMatrixxOES(GLfixed mantissa[16], GLint exponent[16]);
+void GLTrace_glDepthRangefOES(GLclampf zNear, GLclampf zFar);
+void GLTrace_glFrustumfOES(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar);
+void GLTrace_glOrthofOES(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar);
+void GLTrace_glClipPlanefOES(GLenum plane, const GLfloat *equation);
+void GLTrace_glGetClipPlanefOES(GLenum pname, GLfloat eqn[4]);
+void GLTrace_glClearDepthfOES(GLclampf depth);
+void GLTrace_glTexGenfOES(GLenum coord, GLenum pname, GLfloat param);
+void GLTrace_glTexGenfvOES(GLenum coord, GLenum pname, const GLfloat *params);
+void GLTrace_glTexGeniOES(GLenum coord, GLenum pname, GLint param);
+void GLTrace_glTexGenivOES(GLenum coord, GLenum pname, const GLint *params);
+void GLTrace_glTexGenxOES(GLenum coord, GLenum pname, GLfixed param);
+void GLTrace_glTexGenxvOES(GLenum coord, GLenum pname, const GLfixed *params);
+void GLTrace_glGetTexGenfvOES(GLenum coord, GLenum pname, GLfloat *params);
+void GLTrace_glGetTexGenivOES(GLenum coord, GLenum pname, GLint *params);
+void GLTrace_glGetTexGenxvOES(GLenum coord, GLenum pname, GLfixed *params);
+void GLTrace_glClipPlanefIMG(GLenum p, const GLfloat *eqn);
+void GLTrace_glClipPlanexIMG(GLenum p, const GLfixed *eqn);
+
+
+}; // namespace gltrace
+}; // namespace android
diff --git a/opengl/libs/GLES_trace/src/gltrace_context.cpp b/opengl/libs/GLES_trace/src/gltrace_context.cpp
new file mode 100644
index 0000000..8cf5a51
--- /dev/null
+++ b/opengl/libs/GLES_trace/src/gltrace_context.cpp
@@ -0,0 +1,105 @@
+/*
+ * Copyright 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.
+ */
+
+#include <pthread.h>
+
+extern "C" {
+#include "liblzf/lzf.h"
+}
+
+#include "gltrace_context.h"
+
+namespace android {
+namespace gltrace {
+
+using ::android::gl_hooks_t;
+
+static pthread_key_t sTLSKey = -1;
+static pthread_once_t sPthreadOnceKey = PTHREAD_ONCE_INIT;
+
+void createTLSKey() {
+    pthread_key_create(&sTLSKey, NULL);
+}
+
+GLTraceContext *getGLTraceContext() {
+    return (GLTraceContext*) pthread_getspecific(sTLSKey);
+}
+
+void setGLTraceContext(GLTraceContext *c) {
+    pthread_setspecific(sTLSKey, c);
+}
+
+void initContext(unsigned version, gl_hooks_t *hooks) {
+    pthread_once(&sPthreadOnceKey, createTLSKey);
+
+    GLTraceContext *context = new GLTraceContext();
+    context->hooks = hooks;
+
+    setGLTraceContext(context);
+}
+
+void releaseContext() {
+    GLTraceContext *c = getGLTraceContext();
+    if (c != NULL) {
+        delete c;
+        setGLTraceContext(NULL);
+    }
+}
+
+GLTraceContext::GLTraceContext() {
+    fbcontents = fbcompressed = NULL;
+    fbcontentsSize = 0;
+}
+
+void GLTraceContext::resizeFBMemory(unsigned minSize) {
+    if (fbcontentsSize >= minSize) {
+        return;
+    }
+
+    if (fbcontents != NULL) {
+        free(fbcontents);
+        free(fbcompressed);
+    }
+
+    fbcontents = malloc(minSize);
+    fbcompressed = malloc(minSize);
+
+    fbcontentsSize = minSize;
+}
+
+/** obtain a pointer to the compressed framebuffer image */
+void GLTraceContext::getCompressedFB(void **fb, unsigned *fbsize, unsigned *fbwidth, 
+                            unsigned *fbheight) {
+    int viewport[4] = {};
+    hooks->gl.glGetIntegerv(GL_VIEWPORT, viewport);
+    unsigned fbContentsSize = viewport[2] * viewport[3] * 4;
+
+    resizeFBMemory(fbContentsSize);
+
+    //TODO: On eglSwapBuffer, read FB0. For glDraw calls, read currently
+    //      bound FB.
+    //hooks->gl.glGetIntegerv(GL_FRAMEBUFFER_BINDING, &bound_fb);
+    //hooks->gl.glBindFramebuffer(GL_FRAMEBUFFER, 0);
+    hooks->gl.glReadPixels(viewport[0], viewport[1], viewport[2], viewport[3],
+                                        GL_RGBA, GL_UNSIGNED_BYTE, fbcontents);
+    *fbsize = lzf_compress(fbcontents, fbContentsSize, fbcompressed, fbContentsSize);
+    *fb = fbcompressed;
+    *fbwidth = viewport[2];
+    *fbheight = viewport[3];
+}
+
+}; // namespace gltrace
+}; // namespace android
diff --git a/opengl/libs/GLES_trace/src/gltrace_context.h b/opengl/libs/GLES_trace/src/gltrace_context.h
new file mode 100644
index 0000000..7dbbca4
--- /dev/null
+++ b/opengl/libs/GLES_trace/src/gltrace_context.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright 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.
+ */
+
+#ifndef __GLTRACE_CONTEXT_H_
+#define __GLTRACE_CONTEXT_H_
+
+#include "hooks.h"
+
+namespace android {
+namespace gltrace {
+
+using ::android::gl_hooks_t;
+
+class GLTraceContext {
+    void *fbcontents;           /* memory area to read framebuffer contents */
+    void *fbcompressed;         /* destination for lzf compressed framebuffer */
+    unsigned fbcontentsSize;    /* size of fbcontents & fbcompressed buffers */
+
+    void resizeFBMemory(unsigned minSize);
+public:
+    gl_hooks_t *hooks;
+
+    GLTraceContext();
+    void getCompressedFB(void **fb, unsigned *fbsize, unsigned *fbwidth, unsigned *fbheight);
+};
+
+GLTraceContext *getGLTraceContext();
+void setGLTraceContext(GLTraceContext *c);
+void initContext(unsigned version, gl_hooks_t *hooks);
+void releaseContext();
+
+};
+};
+
+#endif
diff --git a/opengl/libs/GLES_trace/src/gltrace_egl.cpp b/opengl/libs/GLES_trace/src/gltrace_egl.cpp
new file mode 100644
index 0000000..5d1f370
--- /dev/null
+++ b/opengl/libs/GLES_trace/src/gltrace_egl.cpp
@@ -0,0 +1,39 @@
+/*
+ * Copyright 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.
+ */
+
+#include <cutils/log.h>
+
+#include "gltrace.pb.h"
+#include "gltrace_context.h"
+#include "gltrace_fixup.h"
+#include "gltrace_transport.h"
+
+namespace android {
+namespace gltrace {
+
+void GLTrace_eglSwapBuffers(void *dpy, void *draw) {
+    GLMessage glmessage;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmessage.set_context_id(1);
+    glmessage.set_function(GLMessage::eglSwapBuffers);
+
+    fixup_addFBContents(&glmessage);
+    traceGLMessage(&glmessage);
+}
+
+};
+};
diff --git a/opengl/libs/GLES_trace/src/gltrace_egl.h b/opengl/libs/GLES_trace/src/gltrace_egl.h
new file mode 100644
index 0000000..27a4837
--- /dev/null
+++ b/opengl/libs/GLES_trace/src/gltrace_egl.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright 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.
+ */
+
+#ifndef __GLTRACE_EGL_H_
+#define __GLTRACE_EGL_H_
+
+namespace android {
+namespace gltrace {
+
+void GLTrace_eglSwapBuffers(void *dpy, void *draw);
+
+};
+};
+
+#endif
diff --git a/opengl/libs/GLES_trace/src/gltrace_eglapi.cpp b/opengl/libs/GLES_trace/src/gltrace_eglapi.cpp
new file mode 100644
index 0000000..3fe5f8b
--- /dev/null
+++ b/opengl/libs/GLES_trace/src/gltrace_eglapi.cpp
@@ -0,0 +1,64 @@
+/*
+ * Copyright 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.
+ */
+
+#include <stdlib.h>
+#include <cutils/log.h>
+#include <cutils/properties.h>
+
+#include "hooks.h"
+#include "glestrace.h"
+
+#include "gltrace_context.h"
+#include "gltrace_egl.h"
+#include "gltrace_hooks.h"
+#include "gltrace_transport.h"
+
+namespace android {
+
+void GLTrace_eglMakeCurrent(const unsigned version, gl_hooks_t *hooks) {
+    gltrace::initContext(version, hooks);
+}
+
+void GLTrace_eglReleaseThread() {
+    gltrace::releaseContext();
+}
+
+void GLTrace_eglCreateContext(int version, EGLContext c) {
+    // TODO
+}
+
+void GLTrace_start() {
+    char value[PROPERTY_VALUE_MAX];
+
+    property_get("debug.egl.debug_port", value, "5039");
+    const unsigned short port = (unsigned short)atoi(value);
+
+    gltrace::startServer(port);
+}
+
+void GLTrace_stop() {
+    gltrace::stopServer();
+}
+
+gl_hooks_t *GLTrace_getGLHooks() {
+    return gltrace::getGLHooks();
+}
+
+void GLTrace_eglSwapBuffers(void *dpy, void *draw) {
+    gltrace::GLTrace_eglSwapBuffers(dpy, draw);
+}
+
+}
diff --git a/opengl/libs/GLES_trace/src/gltrace_fixup.cpp b/opengl/libs/GLES_trace/src/gltrace_fixup.cpp
new file mode 100644
index 0000000..c5b0451
--- /dev/null
+++ b/opengl/libs/GLES_trace/src/gltrace_fixup.cpp
@@ -0,0 +1,310 @@
+/*
+ * Copyright 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.
+ */
+
+#include <cutils/log.h>
+#include <GLES2/gl2.h>
+
+#include "gltrace.pb.h"
+#include "gltrace_context.h"
+#include "gltrace_fixup.h"
+
+namespace android {
+namespace gltrace {
+
+unsigned getBytesPerTexel(const GLenum format, const GLenum type) {
+    /*
+    Description from glTexImage2D spec:
+
+    Data is read from data as a sequence of unsigned bytes or shorts, depending on type.
+    When type is GL_UNSIGNED_BYTE, each of the bytes is interpreted as one color component.
+    When type is one of GL_UNSIGNED_SHORT_5_6_5, GL_UNSIGNED_SHORT_4_4_4_4, or
+    GL_UNSIGNED_SHORT_5_5_5_1, each unsigned short value is interpreted as containing all
+    the components for a single texel, with the color components arranged according to
+    format. Color components are treated as groups of one, two, three, or four values,
+    again based on format. Groups of components are referred to as texels.
+
+    width × height texels are read from memory, starting at location data. By default,
+    these texels are taken from adjacent memory locations, except that after all width
+    texels are read, the read pointer is advanced to the next four-byte boundary.
+    The four-byte row alignment is specified by glPixelStorei with argument
+    GL_UNPACK_ALIGNMENT, and it can be set to one, two, four, or eight bytes.
+    */
+
+    switch (type) {
+    case GL_UNSIGNED_SHORT_5_6_5:
+    case GL_UNSIGNED_SHORT_4_4_4_4:
+    case GL_UNSIGNED_SHORT_5_5_5_1:
+        return 2;
+    case GL_UNSIGNED_BYTE:
+        break;
+    default:
+        LOGE("GetBytesPerPixel: unknown type %x", type);
+    }
+
+    switch (format) {
+    case GL_ALPHA:
+    case GL_LUMINANCE:
+        return 1;
+    case GL_LUMINANCE_ALPHA:
+        return 2;
+    case GL_RGB:
+        return 3;
+    case GL_RGBA:
+    case 0x80E1: // GL_BGRA_EXT
+        return 4;
+    default:
+        LOGE("GetBytesPerPixel: unknown format %x", format);
+    }
+
+    return 1;   // in doubt...
+}
+
+/** Generic helper function: extract pointer at argIndex and
+    replace it with the C style string at *pointer */
+void fixup_CStringPtr(int argIndex, GLMessage *glmsg) {
+    GLMessage_DataType *arg = glmsg->mutable_args(argIndex);
+    GLchar *ptr = (GLchar *)arg->intvalue(0);
+
+    arg->set_type(GLMessage::DataType::CHAR);
+    arg->set_isarray(true);
+    arg->add_charvalue(ptr);
+}
+
+void fixup_glGetString(GLMessage *glmsg) {
+    /* const GLubyte* GLTrace_glGetString(GLenum name) */
+    GLMessage_DataType *ret = glmsg->mutable_returnvalue();
+    GLchar *ptr = (GLchar *)ret->intvalue(0);
+
+    if (ptr != NULL) {
+        ret->set_type(GLMessage::DataType::CHAR);
+        ret->set_isarray(true);
+        ret->add_charvalue(ptr);
+    }
+}
+
+/* Add the contents of the framebuffer to the protobuf message */
+void fixup_addFBContents(GLMessage *glmsg) {
+    void *fbcontents;
+    unsigned fbsize, fbwidth, fbheight;
+    getGLTraceContext()->getCompressedFB(&fbcontents, &fbsize, &fbwidth, &fbheight);
+
+    GLMessage_FrameBuffer *fb = glmsg->mutable_fb();
+    fb->set_width(fbwidth);
+    fb->set_height(fbheight);
+    fb->add_contents(fbcontents, fbsize);
+}
+
+void fixup_glTexImage2D(GLMessage *glmsg) {
+    /* void glTexImage2D(GLenum target,
+                        GLint level,
+                        GLint internalformat,
+                        GLsizei width,
+                        GLsizei height,
+                        GLint border,
+                        GLenum format,
+                        GLenum type,
+                        const GLvoid *data); 
+     */
+    GLMessage_DataType arg_width  = glmsg->args(3);
+    GLMessage_DataType arg_height = glmsg->args(4);
+    GLMessage_DataType arg_format = glmsg->args(6);
+    GLMessage_DataType arg_type   = glmsg->args(7);
+    GLMessage_DataType *arg_data  = glmsg->mutable_args(8);
+
+    GLsizei width  = arg_width.intvalue(0);
+    GLsizei height = arg_height.intvalue(0);
+    GLenum format  = arg_format.intvalue(0);
+    GLenum type    = arg_type.intvalue(0);
+    void *data     = (void *)arg_data->intvalue(0);
+
+    int bytesPerTexel = getBytesPerTexel(format, type);
+
+    arg_data->set_type(GLMessage::DataType::BYTE);
+    arg_data->set_isarray(true);
+    arg_data->clear_rawbytes();
+
+    if (data != NULL) {
+        arg_data->add_rawbytes(data, bytesPerTexel * width * height);
+    } else {
+        LOGE("fixup_glTexImage2D: image data is NULL.\n");
+        arg_data->set_type(GLMessage::DataType::VOID);
+        // FIXME:
+        // This will create the texture, but it will be uninitialized. 
+        // It can later be initialized with glTexSubImage2D or by
+        // attaching an FBO to it and rendering into the FBO.
+    }
+}
+
+void fixup_glShaderSource(GLMessage *glmsg) {
+    /* void glShaderSource(GLuint shader, GLsizei count, const GLchar** string, 
+                                    const GLint* length) */
+    GLMessage_DataType arg_count  = glmsg->args(1);
+    GLMessage_DataType arg_lenp   = glmsg->args(3);
+    GLMessage_DataType *arg_strpp = glmsg->mutable_args(2);
+
+    GLsizei count = arg_count.intvalue(0);
+    GLchar **stringpp = (GLchar **)arg_strpp->intvalue(0);
+    GLint *lengthp = (GLint *)arg_lenp.intvalue(0);
+
+    arg_strpp->set_type(GLMessage::DataType::CHAR);
+    arg_strpp->set_isarray(true);
+    arg_strpp->clear_charvalue();
+
+    ::std::string src = "";
+    for (int i = 0; i < count; i++) {
+        if (lengthp != NULL)
+            src.append(*stringpp, *lengthp);
+        else
+            src.append(*stringpp);  // assume null terminated
+        stringpp++;
+        lengthp++;
+    }
+
+    arg_strpp->add_charvalue(src);
+}
+
+void fixup_glUniformGeneric(int argIndex, int nFloats, GLMessage *glmsg) {
+    GLMessage_DataType *arg_values = glmsg->mutable_args(argIndex);
+    GLfloat *src = (GLfloat*)arg_values->intvalue(0);
+
+    arg_values->set_type(GLMessage::DataType::FLOAT);
+    arg_values->set_isarray(true);
+    arg_values->clear_floatvalue();
+
+    for (int i = 0; i < nFloats; i++) {
+        arg_values->add_floatvalue(*src++);
+    }
+}
+
+void fixup_glUniformMatrixGeneric(int matrixSize, GLMessage *glmsg) {
+    /* void glUniformMatrix?fv(GLint location, GLsizei count, GLboolean transpose, 
+                                                                const GLfloat* value) */
+    GLMessage_DataType arg_count  = glmsg->args(1);
+    int n_matrices = arg_count.intvalue(0);
+    fixup_glUniformGeneric(3, matrixSize * matrixSize * n_matrices, glmsg);
+}
+
+void fixup_GenericIntArray(int argIndex, int nInts, GLMessage *glmsg) {
+    GLMessage_DataType *arg_intarray = glmsg->mutable_args(argIndex);
+    GLint *intp = (GLint *)arg_intarray->intvalue(0);
+
+    arg_intarray->set_type(GLMessage::DataType::INT);
+    arg_intarray->set_isarray(true);
+    arg_intarray->clear_intvalue();
+
+    for (int i = 0; i < nInts; i++, intp++) {
+        arg_intarray->add_intvalue(*intp);
+    }
+}
+
+void fixup_glGenGeneric(GLMessage *glmsg) {
+    /* void glGen*(GLsizei n, GLuint * buffers); */
+    GLMessage_DataType arg_n  = glmsg->args(0);
+    GLsizei n = arg_n.intvalue(0);
+
+    fixup_GenericIntArray(1, n, glmsg);
+}
+
+void fixup_glGetBooleanv(GLMessage *glmsg) {
+    /* void glGetBooleanv(GLenum pname, GLboolean *params); */
+    GLMessage_DataType *arg_params = glmsg->mutable_args(1);
+    GLboolean *src = (GLboolean*)arg_params->intvalue(0);
+
+    arg_params->set_type(GLMessage::DataType::BOOL);
+    arg_params->set_isarray(true);
+    arg_params->clear_boolvalue();
+    arg_params->add_boolvalue(*src);
+}
+
+void fixup_glGetFloatv(GLMessage *glmsg) {
+    /* void glGetFloatv(GLenum pname, GLfloat *params); */
+    GLMessage_DataType *arg_params = glmsg->mutable_args(1);
+    GLfloat *src = (GLfloat*)arg_params->intvalue(0);
+
+    arg_params->set_type(GLMessage::DataType::FLOAT);
+    arg_params->set_isarray(true);
+    arg_params->clear_floatvalue();
+    arg_params->add_floatvalue(*src);
+}
+
+void fixupGLMessage(GLMessage *glmsg) {
+    switch (glmsg->function()) {
+    case GLMessage::glGenBuffers:        /* void glGenBuffers(GLsizei n, GLuint * buffers); */
+    case GLMessage::glGenFramebuffers:   /* void glGenFramebuffers(GLsizei n, GLuint * buffers); */
+    case GLMessage::glGenRenderbuffers:  /* void glGenFramebuffers(GLsizei n, GLuint * buffers); */
+    case GLMessage::glGenTextures:       /* void glGenTextures(GLsizei n, GLuint * buffers); */
+        fixup_glGenGeneric(glmsg);
+        break;
+    case GLMessage::glGetAttribLocation:  
+    case GLMessage::glGetUniformLocation: 
+        /* int glGetAttribLocation(GLuint program, const GLchar* name) */
+        /* int glGetUniformLocation(GLuint program, const GLchar* name) */
+        fixup_CStringPtr(1, glmsg);
+        break;
+    case GLMessage::glGetBooleanv:
+        fixup_glGetBooleanv(glmsg);
+        break;
+    case GLMessage::glGetFloatv:
+        fixup_glGetFloatv(glmsg);
+        break;
+    case GLMessage::glGetIntegerv:        /* void glGetIntegerv(GLenum pname, GLint *params); */
+        fixup_GenericIntArray(1, 1, glmsg);
+        break;
+    case GLMessage::glGetProgramiv:
+    case GLMessage::glGetRenderbufferParameteriv:
+    case GLMessage::glGetShaderiv:
+        /* void glGetProgramiv(GLuint program, GLenum pname, GLint* params) */
+        /* void glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params) */
+        /* void glGetShaderiv(GLuint shader, GLenum pname, GLint* params) */
+        fixup_GenericIntArray(2, 1, glmsg);
+        break;
+    case GLMessage::glGetString:
+        fixup_glGetString(glmsg);
+        break;
+    case GLMessage::glTexImage2D:
+        fixup_glTexImage2D(glmsg);
+        break;
+    case GLMessage::glShaderSource:
+        fixup_glShaderSource(glmsg);
+        break;
+    case GLMessage::glUniformMatrix2fv:
+        /* void glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose,
+                                                                    const GLfloat* value) */
+        fixup_glUniformMatrixGeneric(2, glmsg);
+        break;
+    case GLMessage::glUniformMatrix3fv:
+        /* void glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose,
+                                                                    const GLfloat* value) */
+        fixup_glUniformMatrixGeneric(3, glmsg);
+        break;
+    case GLMessage::glUniformMatrix4fv:
+        /* void glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose,
+                                                                    const GLfloat* value) */
+        fixup_glUniformMatrixGeneric(4, glmsg);
+        break;
+    case GLMessage::glDrawArrays:
+    case GLMessage::glDrawElements:
+        /* void glDrawArrays(GLenum mode, GLint first, GLsizei count) */
+        /* void glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices) */
+        fixup_addFBContents(glmsg);
+        break;
+    default:
+        break;
+    }
+}
+
+};
+};
diff --git a/opengl/libs/GLES_trace/src/gltrace_fixup.h b/opengl/libs/GLES_trace/src/gltrace_fixup.h
new file mode 100644
index 0000000..bf15a88
--- /dev/null
+++ b/opengl/libs/GLES_trace/src/gltrace_fixup.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright 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.
+ */
+
+#include "gltrace.pb.h"
+
+#ifndef __GLTRACE_FIXUP_H_
+#define __GLTRACE_FIXUP_H_
+
+namespace android {
+namespace gltrace {
+
+void fixupGLMessage(GLMessage *message);
+void fixup_addFBContents(GLMessage *message);
+
+};
+};
+
+#endif
diff --git a/opengl/libs/GLES_trace/src/gltrace_hooks.cpp b/opengl/libs/GLES_trace/src/gltrace_hooks.cpp
new file mode 100644
index 0000000..de8d463
--- /dev/null
+++ b/opengl/libs/GLES_trace/src/gltrace_hooks.cpp
@@ -0,0 +1,41 @@
+/*
+ * Copyright 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.
+ */
+
+#include "hooks.h"
+#include "gltrace_api.h"
+#include "gltrace_hooks.h"
+
+namespace android {
+namespace gltrace {
+
+// Hook up all the GLTrace functions
+#define GL_ENTRY(_r, _api, ...) GLTrace_ ## _api,
+EGLAPI gl_hooks_t gHooksDebug = {
+    {
+        #include "entries.in"
+    },
+    {
+        {0}
+    }
+};
+#undef GL_ENTRY
+
+gl_hooks_t *getGLHooks() {
+    return &gHooksDebug;
+}
+
+};
+};
diff --git a/opengl/libs/GLES_trace/src/gltrace_hooks.h b/opengl/libs/GLES_trace/src/gltrace_hooks.h
new file mode 100644
index 0000000..c946a09
--- /dev/null
+++ b/opengl/libs/GLES_trace/src/gltrace_hooks.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright 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.
+ */
+
+#ifndef __GLD_HOOKS_H_
+#define __GLD_HOOKS_H_
+
+#include "hooks.h"
+
+namespace android {
+namespace gltrace {
+
+using ::android::gl_hooks_t;
+
+gl_hooks_t *getGLHooks();
+
+};
+};
+
+#endif
diff --git a/opengl/libs/GLES_trace/src/gltrace_transport.cpp b/opengl/libs/GLES_trace/src/gltrace_transport.cpp
new file mode 100644
index 0000000..c52ca5f
--- /dev/null
+++ b/opengl/libs/GLES_trace/src/gltrace_transport.cpp
@@ -0,0 +1,113 @@
+/*
+ * Copyright 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.
+ */
+
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <cutils/log.h>
+
+#include "gltrace_transport.h"
+
+namespace android {
+namespace gltrace {
+
+int gServerSocket, gClientSocket;
+
+void startServer(int port) {
+    if (gServerSocket > 0) {
+        LOGD("startServer: server socket already open!");
+        return;
+    }
+
+    gServerSocket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
+    if (gServerSocket < 0) {
+        LOGE("Error (%d) while creating socket. Check if app has network permissions.",
+                                                                            gServerSocket);
+        exit(-1);
+    }
+
+    struct sockaddr_in server, client;
+
+    server.sin_family = AF_INET;
+    server.sin_addr.s_addr = htonl(INADDR_ANY);
+    server.sin_port = htons(port);
+
+    socklen_t sockaddr_len = sizeof(sockaddr_in);
+    if (bind(gServerSocket, (struct sockaddr *) &server, sizeof(server)) < 0) {
+        close(gServerSocket);
+        LOGE("Failed to bind the server socket");
+        exit(-1);
+    }
+
+    if (listen(gServerSocket, 1) < 0) {
+        close(gServerSocket);
+        LOGE("Failed to listen on server socket");
+        exit(-1);
+    }
+
+    LOGD("startServer: server started on %d", port);
+
+    /* Wait for client connection */
+    if ((gClientSocket = accept(gServerSocket, (struct sockaddr *)&client, &sockaddr_len)) < 0) {
+        close(gServerSocket);
+        LOGE("Failed to accept client connection");
+        exit(-1);
+    }
+
+    LOGD("startServer: client connected: %s", inet_ntoa(client.sin_addr));
+}
+
+void stopServer() {
+    if (gServerSocket > 0) {
+        close(gServerSocket);
+        close(gClientSocket);
+        gServerSocket = gClientSocket = 0;
+    }
+}
+
+/** Send GLMessage to the receiver on the host. */
+void traceGLMessage(GLMessage *call) {
+    if (gClientSocket <= 0) {
+        LOGE("traceGLMessage: Attempt to send while client connection is not established");
+        return;
+    }
+
+    std::string str;
+    call->SerializeToString(&str);
+    const uint32_t len = str.length();
+
+    int n = write(gClientSocket, &len, sizeof len);
+    if (n != sizeof len) {
+        LOGE("traceGLMessage: Error (%d) while writing message length\n", n);
+        stopServer();
+        exit(-1);
+    }
+
+    n = write(gClientSocket, str.data(), str.length());
+    if (n != (int) str.length()) {
+        LOGE("traceGLMessage: Error while writing out message, result = %d, length = %d\n",
+            n, str.length());
+        stopServer();
+        exit(-1);
+    }
+}
+
+};  // namespace gltrace
+};  // namespace android
diff --git a/opengl/libs/GLES_trace/src/gltrace_transport.h b/opengl/libs/GLES_trace/src/gltrace_transport.h
new file mode 100644
index 0000000..a0d89be
--- /dev/null
+++ b/opengl/libs/GLES_trace/src/gltrace_transport.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright 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.
+ */
+
+#ifndef __GLTRACE_TRANSPORT_H_
+#define __GLTRACE_TRANSPORT_H_
+
+#include "gltrace.pb.h"
+
+namespace android {
+namespace gltrace {
+
+void startServer(int port);
+void stopServer();
+
+void traceGLMessage(GLMessage *msg);
+
+};
+};
+
+#endif
diff --git a/opengl/libs/GLES_trace/tools/genapi.py b/opengl/libs/GLES_trace/tools/genapi.py
new file mode 100755
index 0000000..3c47a5f
--- /dev/null
+++ b/opengl/libs/GLES_trace/tools/genapi.py
@@ -0,0 +1,386 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2011 Google Inc.
+#
+# 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.
+#
+# ABOUT
+#   This script is used to generate the trace implementations of all
+#   OpenGL calls. When executed, it reads the specs for the OpenGL calls
+#   from the files GLES2/gl2_api.in, GLES2/gl2ext_api.in, GLES_CM/gl_api.in,
+#   and GLES_CM/glext_api.in, and generates trace versions for all the 
+#   defined functions.
+#
+# PREREQUISITES
+#   To generate C++ files, this script uses the 'pyratemp' template
+#   module. The only reason to use pyratemp is that it is extremly
+#   simple to install:
+#   $ wget http://www.simple-is-better.org/template/pyratemp-current/pyratemp.py
+#   Put the file in the GLES2_trace/tools folder, or update PYTHONPATH
+#   to point to wherever it was downloaded.
+#
+# USAGE
+#   $ cd GLES2_trace      - run the program from GLES2_trace folder
+#   $ ./tools/genapi.py   - generates a .cpp and .h file
+#   $ mv *.cpp *.h src/   - move the generated files into the src folder
+
+import sys
+import re
+import pyratemp
+
+# Constants corresponding to the protobuf DataType.Type
+class DataType:
+    def __init__(self, name):
+        self.name = name
+
+    def __str__(self):
+        if self.name == "pointer":  # pointers map to the INT DataType
+            return "INT"
+        return self.name.upper()
+
+    def getProtobufCall(self):
+        if self.name == "void":
+            raise ValueError("Attempt to set void value")
+        elif self.name == "char" or self.name == "byte" \
+                or self.name == "pointer" or self.name == "enum":
+            return "add_intvalue((int)"
+        elif self.name == "int":
+            return "add_intvalue("
+        elif self.name == "float":
+            return "add_floatvalue("
+        elif self.name == "bool":
+            return "add_boolvalue("
+        else:
+            raise ValueError("Unknown value type %s" % self.name)
+
+DataType.VOID = DataType("void")
+DataType.CHAR = DataType("char")
+DataType.BYTE = DataType("byte")
+DataType.ENUM = DataType("enum")
+DataType.BOOL = DataType("bool")
+DataType.INT = DataType("int")
+DataType.FLOAT = DataType("float")
+DataType.POINTER = DataType("pointer")
+
+# mapping of GL types to protobuf DataType
+GL2PROTOBUF_TYPE_MAP = {
+    "GLvoid":DataType.VOID,
+    "void":DataType.VOID,
+    "GLchar":DataType.CHAR,
+    "GLenum":DataType.ENUM,
+    "GLboolean":DataType.BOOL,
+    "GLbitfield":DataType.INT,
+    "GLbyte":DataType.BYTE,
+    "GLshort":DataType.INT,
+    "GLint":DataType.INT,
+    "int":DataType.INT,
+    "GLsizei":DataType.INT,
+    "GLubyte":DataType.BYTE,
+    "GLushort":DataType.INT,
+    "GLuint":DataType.INT,
+    "GLfloat":DataType.FLOAT,
+    "GLclampf":DataType.FLOAT,
+    "GLfixed":DataType.INT,
+    "GLclampx":DataType.INT,
+    "GLsizeiptr":DataType.POINTER,
+    "GLintptr":DataType.POINTER,
+    "GLeglImageOES":DataType.POINTER,
+}
+
+API_SPECS = [
+    ('GL2','../GLES2/gl2_api.in'),
+    ('GL2Ext','../GLES2/gl2ext_api.in'),
+    ('GL1','../GLES_CM/gl_api.in'),
+    ('GL1Ext','../GLES_CM/glext_api.in'),
+]
+
+HEADER_TEXT = """/*
+ * Copyright 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.
+ *
+ * THIS FILE WAS GENERATED BY A SCRIPT. DO NOT EDIT.
+ */
+
+#include <cutils/log.h>
+#include <GLES2/gl2.h>
+
+#include "gltrace.pb.h"
+#include "gltrace_context.h"
+#include "gltrace_fixup.h"
+#include "gltrace_transport.h"
+
+namespace android {
+namespace gltrace {
+
+"""
+
+FOOTER_TEXT = """
+
+}; // namespace gltrace
+}; // namespace android
+"""
+
+TRACE_CALL_TEMPLATE = pyratemp.Template(
+"""$!retType!$ GLTrace_$!func!$($!inputArgList!$) {
+    GLMessage glmsg;
+    GLTraceContext *glContext = getGLTraceContext();
+
+    glmsg.set_context_id(1);
+    glmsg.set_function(GLMessage::$!func!$);
+<!--(if len(parsedArgs) > 0)-->
+    <!--(for argname, argtype in parsedArgs)-->
+
+    // copy argument $!argname!$
+    GLMessage_DataType *arg_$!argname!$ = glmsg.add_args();
+    arg_$!argname!$->set_isarray(false);
+    arg_$!argname!$->set_type(GLMessage::DataType::$!argtype!$);
+    arg_$!argname!$->$!argtype.getProtobufCall()!$$!argname!$);
+    <!--(end)-->
+<!--(end)-->
+
+    // call function
+<!--(if retType != "void")-->
+    $!retType!$ retValue = glContext->hooks->gl.$!callsite!$;
+<!--(else)-->
+    glContext->hooks->gl.$!callsite!$;
+<!--(end)-->
+<!--(if retType != "void")-->
+
+    // set return value
+    GLMessage_DataType *rt = glmsg.mutable_returnvalue();
+    rt->set_isarray(false);
+    rt->set_type(GLMessage::DataType::$!retDataType!$);
+    rt->$!retDataType.getProtobufCall()!$retValue);
+<!--(end)-->
+
+    fixupGLMessage(&glmsg);
+    traceGLMessage(&glmsg);
+<!--(if retType != "void")-->
+
+    return retValue;
+<!--(end)-->
+}
+""")
+
+def getDataTypeFromKw(kw):
+    """ Get the data type given declaration.
+    All pointer declarations are of type DataType.POINTER
+
+    e.g.: GLvoid -> DataType.VOID"""
+
+    if kw.count('*') > 0:
+        return DataType.POINTER
+    return GL2PROTOBUF_TYPE_MAP.get(kw)
+
+def getNameTypePair(decl):
+    """ Split declaration of a variable to a tuple of (variable name, DataType).
+    e.g. "const GLChar* varName" -> (varName, POINTER) """
+    elements = decl.strip().split(' ')
+    name = None
+    if len(elements) > 1:
+        name = " ".join(elements[-1:]).strip()      # last element is the name
+        dataType = " ".join(elements[:-1]).strip()  # everything else is the data type
+
+        # if name is a pointer (e.g. "*ptr"), then remove the "*" from the name
+        # and add it to the data type
+        pointersInName = name.count("*")            
+        if pointersInName > 0:
+            name = name.replace("*", "")
+            dataType += "*" * pointersInName
+
+        # if name is an array (e.g. "array[10]"), then remove the "[X]" from the name
+        # and make the datatype to be a pointer
+        arraysInName = name.count("[")
+        if arraysInName > 0:
+            name = name.split('[')[0]
+            dataType += "*"
+    else:
+        dataType = elements[0]
+    return (name, getDataTypeFromKw(dataType))
+
+def parseArgs(arglist):
+    """ Parse the argument list into a list of (var name, DataType) tuples """
+    args = arglist.split(',')
+    args = map(lambda x: x.strip(), args)    # remove unnecessary whitespaces
+    argtypelist = map(getNameTypePair, args) # split arg into arg type and arg name
+    if len(argtypelist) == 1:
+        (name, argtype) = argtypelist[0]
+        if argtype == DataType.VOID:
+            return []
+
+    return argtypelist
+
+class ApiCall(object):
+    """An ApiCall models all information about a single OpenGL API"""
+
+    # Regex to match API_ENTRY specification:
+    #       e.g. void API_ENTRY(glActiveTexture)(GLenum texture) {
+    # the regex uses a non greedy match (?) to match the first closing paren
+    API_ENTRY_REGEX = "(.*)API_ENTRY\(.*?\)\((.*?)\)"
+
+    # Regex to match CALL_GL_API specification:
+    #       e.g. CALL_GL_API(glCullFace, mode); 
+    #            CALL_GL_API_RETURN(glCreateProgram);
+    CALL_GL_API_REGEX = "CALL_GL_API(_RETURN)?\((.*)\);"
+
+    def __init__(self, prefix, apientry, callsite):
+        """Construct an ApiCall from its specification.
+
+        The specification is provided by the two arguments:
+        prefix: prefix to use for function names
+        defn: specification line containing API_ENTRY macro
+              e.g: void API_ENTRY(glActiveTexture)(GLenum texture) {
+        callsite: specification line containing CALL_GL_API macro
+              e.g: CALL_GL_API(glActiveTexture, texture);        
+        """
+        self.prefix = prefix
+        self.ret = self.getReturnType(apientry)
+        self.arglist = self.getArgList(apientry)
+
+        # some functions (e.g. __glEGLImageTargetRenderbufferStorageOES), define their
+        # names one way in the API_ENTRY and another way in the CALL_GL_API macros.
+        # so self.func is reassigned based on what is there in the call site
+        self.func = self.getFunc(callsite)
+        self.callsite = self.getCallSite(callsite)
+
+    def getReturnType(self, apientry):
+        '''Extract the return type from the API_ENTRY specification'''
+        m = re.search(self.API_ENTRY_REGEX, apientry)
+        if not m:
+            raise ValueError("%s does not match API_ENTRY specification %s" 
+                             % (apientry, self.API_ENTRY_REGEX))
+
+        return m.group(1).strip()
+
+    def getArgList(self, apientry):
+        '''Extract the argument list from the API_ENTRY specification'''
+        m = re.search(self.API_ENTRY_REGEX, apientry)
+        if not m:
+            raise ValueError("%s does not match API_ENTRY specification %s" 
+                             % (apientry, self.API_ENTRY_REGEX))
+
+        return m.group(2).strip()
+
+    def parseCallSite(self, callsite):
+        m = re.search(self.CALL_GL_API_REGEX, callsite)
+        if not m:
+            raise ValueError("%s does not match CALL_GL_API specification (%s)"
+                             % (callsite, self.CALL_GL_API_REGEX))
+
+        arglist = m.group(2)
+        args = arglist.split(',')
+        args = map(lambda x: x.strip(), args)
+
+        return args
+
+    def getCallSite(self, callsite):
+        '''Extract the callsite from the CALL_GL_API specification'''
+        args = self.parseCallSite(callsite)
+        return "%s(%s)" % (args[0], ", ".join(args[1:]))
+
+    def getFunc(self, callsite):
+        '''Extract the function name from the CALL_GL_API specification'''
+        args = self.parseCallSite(callsite)
+        return args[0]
+
+    def genDeclaration(self):
+        return "%s GLTrace_%s(%s);" % (self.ret, self.func, self.arglist)
+
+    def genCode(self):
+        return TRACE_CALL_TEMPLATE(func = self.func, 
+                                   retType = self.ret,
+                                   retDataType = getDataTypeFromKw(self.ret),
+                                   inputArgList = self.arglist,
+                                   callsite = self.callsite,
+                                   parsedArgs = parseArgs(self.arglist),
+                                   DataType=DataType)
+
+def getApis(apiEntryFile, prefix):
+    '''Get a list of all ApiCalls in provided specification file'''
+    lines = open(apiEntryFile).readlines()
+
+    apis = []
+    for i in range(0, len(lines)/3):
+        apis.append(ApiCall(prefix, lines[i*3], lines[i*3+1]))
+
+    return apis
+
+def parseAllSpecs(specs):
+    apis = []
+    for name, specfile in specs:
+        a = getApis(specfile, name)
+        print 'Parsed %s APIs from %s, # of entries = %d' % (name, specfile, len(a))
+        apis.extend(a)
+    return apis
+
+def removeDuplicates(apis):
+    '''Remove all duplicate function entries.
+
+    The input list contains functions declared in GL1 and GL2 APIs.
+    This will return a list that contains only the first function if there are
+    multiple functions with the same name.'''
+    uniqs = []
+    funcs = set()
+    for api in apis:
+        if api.func not in funcs:
+            uniqs.append(api)
+            funcs.add(api.func)
+
+    return uniqs
+
+def genHeaders(apis, fname):
+    lines = []
+    lines.append(HEADER_TEXT)
+    prefix = ""
+    for api in apis:
+        if prefix != api.prefix:
+            lines.append("\n// Declarations for %s APIs\n\n" % api.prefix)
+            prefix = api.prefix
+        lines.append(api.genDeclaration())
+        lines.append("\n")
+    lines.append(FOOTER_TEXT)
+
+    with open(fname, "w") as f:
+        f.writelines(lines)
+
+def genSrcs(apis, fname):
+    lines = []
+    lines.append(HEADER_TEXT)
+    prefix = ""
+    for api in apis:
+        if prefix != api.prefix:
+            lines.append("\n// Definitions for %s APIs\n\n" % api.prefix)
+            prefix = api.prefix
+        lines.append(api.genCode())
+        lines.append("\n")
+    lines.append(FOOTER_TEXT)
+
+    with open(fname, "w") as f:
+        f.writelines(lines)
+
+if __name__ == '__main__':
+    apis = parseAllSpecs(API_SPECS)     # read in all the specfiles
+    apis = removeDuplicates(apis)       # remove duplication of functions common to GL1 and GL2
+    genHeaders(apis, 'gltrace_api.h')  # generate header file
+    genSrcs(apis, 'gltrace_api.cpp')   # generate source file
diff --git a/opengl/libs/GLES_trace/tools/testgenapi.py b/opengl/libs/GLES_trace/tools/testgenapi.py
new file mode 100644
index 0000000..58a12a8
--- /dev/null
+++ b/opengl/libs/GLES_trace/tools/testgenapi.py
@@ -0,0 +1,66 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2011 Google Inc.
+#
+# 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.
+#
+# USAGE
+#   $ cd GLES2_trace/tools
+#   $ python testgenapi.py
+
+import unittest
+from genapi import DataType, ApiCall, getApis, parseArgs
+
+class TestApiCall(unittest.TestCase):
+    def test_parsing(self):
+        apientry = 'void API_ENTRY(glCopyTexSubImage2D)(GLenum target, GLint level, ' \
+                   'GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, ' \
+                   'GLsizei height) {'
+        callsite = 'CALL_GL_API(glCopyTexImage2D, target, level, internalformat, x, y,' \
+                   'width, height, border);'
+
+        api = ApiCall("GL", apientry, callsite)
+        self.assertEqual(api.func, "glCopyTexImage2D")
+        self.assertEqual(api.callsite, 'glCopyTexImage2D(target, level, internalformat, ' \
+                                        'x, y, width, height, border)')
+        self.assertEqual(api.ret, 'void')
+        self.assertEqual(api.arglist, 'GLenum target, GLint level, ' \
+                   'GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, ' \
+                   'GLsizei height')
+
+    def test_num_functions_parsed(self):
+        gl2_apis = getApis('../../GLES2/gl2_api.in', 'GL2')
+        gl2ext_apis = getApis('../../GLES2/gl2ext_api.in', 'GL2Ext')
+        gl_apis = getApis('../../GLES_CM/gl_api.in', "GL1")
+        glext_apis = getApis('../../GLES_CM/glext_api.in', 'GL1Ext')
+
+        self.assertEqual(len(gl2_apis), 142)
+        self.assertEqual(len(gl2ext_apis), 60)
+        self.assertEqual(len(gl_apis), 145)
+        self.assertEqual(len(glext_apis), 126)
+
+    def test_parseArgs(self):
+        args = parseArgs("void")
+        self.assertEqual(len(args), 0)
+
+        args = parseArgs("GLchar a")
+        self.assertEqual(args, [("a", DataType.CHAR)])
+
+        args = parseArgs("GLchar *a")
+        self.assertEqual(args, [("a", DataType.POINTER)])
+
+        args = parseArgs("GLint exponent[16]")
+        self.assertEqual(args, [("exponent", DataType.POINTER)])
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/opengl/libs/glestrace.h b/opengl/libs/glestrace.h
new file mode 100644
index 0000000..5cfacd4
--- /dev/null
+++ b/opengl/libs/glestrace.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright 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.
+ *
+ * This file declares the API provided by the glestrace library.
+ */
+
+#ifndef _GLES_TRACE_H_
+#define _GLES_TRACE_H_
+
+#include "hooks.h"
+
+namespace android {
+
+/* Hooks to be called by "interesting" EGL functions. */
+void GLTrace_eglCreateContext(int version, EGLContext c);
+void GLTrace_eglMakeCurrent(unsigned version, gl_hooks_t *hooks);
+void GLTrace_eglReleaseThread();
+void GLTrace_eglSwapBuffers(void*, void*);
+
+/* Start and stop GL Tracing. */
+void GLTrace_start();
+void GLTrace_stop();
+
+/* Obtain the gl_hooks structure filled with the trace implementation for all GL functions. */
+gl_hooks_t *GLTrace_getGLHooks();
+
+};
+
+#endif
diff --git a/opengl/libs/glesv2dbg.h b/opengl/libs/glesv2dbg.h
deleted file mode 100644
index 44bc288..0000000
--- a/opengl/libs/glesv2dbg.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- ** Copyright 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.
- */
-
-#ifndef _GLESV2_DBG_H_
-#define _GLESV2_DBG_H_
-
-#include <pthread.h>
-
-namespace android
-{
-struct DbgContext;
-
-DbgContext* CreateDbgContext(const unsigned version, const gl_hooks_t * const hooks);
-
-void dbgReleaseThread();
-
-// create and bind socket if haven't already, if failed to create socket or
-//  forceUseFile, then open /data/local/tmp/dump.gles2dbg, exit when size reached
-void StartDebugServer(const unsigned short port, const bool forceUseFile,
-                      const unsigned int maxFileSize, const char * const filePath);
-void StopDebugServer(); // close socket if open
-
-}; // namespace android
-
-#endif // #ifndef _GLESV2_DBG_H_
diff --git a/opengl/libs/glesv2dbg_functions.h b/opengl/libs/glesv2dbg_functions.h
deleted file mode 100644
index 2d70032..0000000
--- a/opengl/libs/glesv2dbg_functions.h
+++ /dev/null
@@ -1,381 +0,0 @@
-extern "C"
-{
-GL_ENTRY(void, glActiveTexture, GLenum texture)
-GL_ENTRY(void, glAlphaFunc, GLenum func, GLclampf ref)
-GL_ENTRY(void, glAlphaFuncx, GLenum func, GLclampx ref)
-GL_ENTRY(void, glAlphaFuncxOES, GLenum func, GLclampx ref)
-GL_ENTRY(void, glAttachShader, GLuint program, GLuint shader)
-GL_ENTRY(void, glBeginPerfMonitorAMD, GLuint monitor)
-GL_ENTRY(void, glBindAttribLocation, GLuint program, GLuint index, const GLchar* name)
-GL_ENTRY(void, glBindBuffer, GLenum target, GLuint buffer)
-GL_ENTRY(void, glBindFramebuffer, GLenum target, GLuint framebuffer)
-GL_ENTRY(void, glBindFramebufferOES, GLenum target, GLuint framebuffer)
-GL_ENTRY(void, glBindRenderbuffer, GLenum target, GLuint renderbuffer)
-GL_ENTRY(void, glBindRenderbufferOES, GLenum target, GLuint renderbuffer)
-GL_ENTRY(void, glBindTexture, GLenum target, GLuint texture)
-GL_ENTRY(void, glBindVertexArrayOES, GLuint array)
-GL_ENTRY(void, glBlendColor, GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
-GL_ENTRY(void, glBlendEquation,  GLenum mode )
-GL_ENTRY(void, glBlendEquationOES, GLenum mode)
-GL_ENTRY(void, glBlendEquationSeparate, GLenum modeRGB, GLenum modeAlpha)
-GL_ENTRY(void, glBlendEquationSeparateOES, GLenum modeRGB, GLenum modeAlpha)
-GL_ENTRY(void, glBlendFunc, GLenum sfactor, GLenum dfactor)
-GL_ENTRY(void, glBlendFuncSeparate, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
-GL_ENTRY(void, glBlendFuncSeparateOES, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
-GL_ENTRY(void, glBufferData, GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage)
-GL_ENTRY(void, glBufferSubData, GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data)
-GL_ENTRY(GLenum, glCheckFramebufferStatus, GLenum target)
-GL_ENTRY(GLenum, glCheckFramebufferStatusOES, GLenum target)
-GL_ENTRY(void, glClear, GLbitfield mask)
-GL_ENTRY(void, glClearColor, GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
-GL_ENTRY(void, glClearColorx, GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha)
-GL_ENTRY(void, glClearColorxOES, GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha)
-GL_ENTRY(void, glClearDepthf, GLclampf depth)
-GL_ENTRY(void, glClearDepthfOES, GLclampf depth)
-GL_ENTRY(void, glClearDepthx, GLclampx depth)
-GL_ENTRY(void, glClearDepthxOES, GLclampx depth)
-GL_ENTRY(void, glClearStencil, GLint s)
-GL_ENTRY(void, glClientActiveTexture, GLenum texture)
-GL_ENTRY(void, glClipPlanef, GLenum plane, const GLfloat *equation)
-GL_ENTRY(void, glClipPlanefIMG, GLenum p, const GLfloat *eqn)
-GL_ENTRY(void, glClipPlanefOES, GLenum plane, const GLfloat *equation)
-GL_ENTRY(void, glClipPlanex, GLenum plane, const GLfixed *equation)
-GL_ENTRY(void, glClipPlanexIMG, GLenum p, const GLfixed *eqn)
-GL_ENTRY(void, glClipPlanexOES, GLenum plane, const GLfixed *equation)
-GL_ENTRY(void, glColor4f, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
-GL_ENTRY(void, glColor4ub, GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha)
-GL_ENTRY(void, glColor4x, GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha)
-GL_ENTRY(void, glColor4xOES, GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha)
-GL_ENTRY(void, glColorMask, GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
-GL_ENTRY(void, glColorPointer, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
-GL_ENTRY(void, glCompileShader, GLuint shader)
-GL_ENTRY(void, glCompressedTexImage2D, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data)
-GL_ENTRY(void, glCompressedTexImage3DOES, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid* data)
-GL_ENTRY(void, glCompressedTexSubImage2D, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data)
-GL_ENTRY(void, glCompressedTexSubImage3DOES, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid* data)
-GL_ENTRY(void, glCopyTexImage2D, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
-GL_ENTRY(void, glCopyTexSubImage2D, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
-GL_ENTRY(void, glCopyTexSubImage3DOES, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height)
-GL_ENTRY(void, glCoverageMaskNV, GLboolean mask)
-GL_ENTRY(void, glCoverageOperationNV, GLenum operation)
-GL_ENTRY(GLuint, glCreateProgram, void)
-GL_ENTRY(GLuint, glCreateShader, GLenum type)
-GL_ENTRY(void, glCullFace, GLenum mode)
-GL_ENTRY(void, glCurrentPaletteMatrixOES, GLuint matrixpaletteindex)
-GL_ENTRY(void, glDeleteBuffers, GLsizei n, const GLuint *buffers)
-GL_ENTRY(void, glDeleteFencesNV, GLsizei n, const GLuint *fences)
-GL_ENTRY(void, glDeleteFramebuffers, GLsizei n, const GLuint* framebuffers)
-GL_ENTRY(void, glDeleteFramebuffersOES, GLsizei n, const GLuint* framebuffers)
-GL_ENTRY(void, glDeletePerfMonitorsAMD, GLsizei n, GLuint *monitors)
-GL_ENTRY(void, glDeleteProgram, GLuint program)
-GL_ENTRY(void, glDeleteRenderbuffers, GLsizei n, const GLuint* renderbuffers)
-GL_ENTRY(void, glDeleteRenderbuffersOES, GLsizei n, const GLuint* renderbuffers)
-GL_ENTRY(void, glDeleteShader, GLuint shader)
-GL_ENTRY(void, glDeleteTextures, GLsizei n, const GLuint *textures)
-GL_ENTRY(void, glDeleteVertexArraysOES, GLsizei n, const GLuint *arrays)
-GL_ENTRY(void, glDepthFunc, GLenum func)
-GL_ENTRY(void, glDepthMask, GLboolean flag)
-GL_ENTRY(void, glDepthRangef, GLclampf zNear, GLclampf zFar)
-GL_ENTRY(void, glDepthRangefOES, GLclampf zNear, GLclampf zFar)
-GL_ENTRY(void, glDepthRangex, GLclampx zNear, GLclampx zFar)
-GL_ENTRY(void, glDepthRangexOES, GLclampx zNear, GLclampx zFar)
-GL_ENTRY(void, glDetachShader, GLuint program, GLuint shader)
-GL_ENTRY(void, glDisable, GLenum cap)
-GL_ENTRY(void, glDisableClientState, GLenum array)
-GL_ENTRY(void, glDisableDriverControlQCOM, GLuint driverControl)
-GL_ENTRY(void, glDisableVertexAttribArray, GLuint index)
-GL_ENTRY(void, glDiscardFramebufferEXT, GLenum target, GLsizei numAttachments, const GLenum *attachments)
-GL_ENTRY(void, glDrawArrays, GLenum mode, GLint first, GLsizei count)
-GL_ENTRY(void, glDrawElements, GLenum mode, GLsizei count, GLenum type, const GLvoid *indices)
-GL_ENTRY(void, glDrawTexfOES, GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height)
-GL_ENTRY(void, glDrawTexfvOES, const GLfloat *coords)
-GL_ENTRY(void, glDrawTexiOES, GLint x, GLint y, GLint z, GLint width, GLint height)
-GL_ENTRY(void, glDrawTexivOES, const GLint *coords)
-GL_ENTRY(void, glDrawTexsOES, GLshort x, GLshort y, GLshort z, GLshort width, GLshort height)
-GL_ENTRY(void, glDrawTexsvOES, const GLshort *coords)
-GL_ENTRY(void, glDrawTexxOES, GLfixed x, GLfixed y, GLfixed z, GLfixed width, GLfixed height)
-GL_ENTRY(void, glDrawTexxvOES, const GLfixed *coords)
-GL_ENTRY(void, glEGLImageTargetRenderbufferStorageOES, GLenum target, GLeglImageOES image)
-GL_ENTRY(void, glEGLImageTargetTexture2DOES, GLenum target, GLeglImageOES image)
-GL_ENTRY(void, glEnable, GLenum cap)
-GL_ENTRY(void, glEnableClientState, GLenum array)
-GL_ENTRY(void, glEnableDriverControlQCOM, GLuint driverControl)
-GL_ENTRY(void, glEnableVertexAttribArray, GLuint index)
-GL_ENTRY(void, glEndPerfMonitorAMD, GLuint monitor)
-GL_ENTRY(void, glEndTilingQCOM, GLbitfield preserveMask)
-GL_ENTRY(void, glExtGetBufferPointervQCOM, GLenum target, GLvoid **params)
-GL_ENTRY(void, glExtGetBuffersQCOM, GLuint *buffers, GLint maxBuffers, GLint *numBuffers)
-GL_ENTRY(void, glExtGetFramebuffersQCOM, GLuint *framebuffers, GLint maxFramebuffers, GLint *numFramebuffers)
-GL_ENTRY(void, glExtGetProgramBinarySourceQCOM, GLuint program, GLenum shadertype, GLchar *source, GLint *length)
-GL_ENTRY(void, glExtGetProgramsQCOM, GLuint *programs, GLint maxPrograms, GLint *numPrograms)
-GL_ENTRY(void, glExtGetRenderbuffersQCOM, GLuint *renderbuffers, GLint maxRenderbuffers, GLint *numRenderbuffers)
-GL_ENTRY(void, glExtGetShadersQCOM, GLuint *shaders, GLint maxShaders, GLint *numShaders)
-GL_ENTRY(void, glExtGetTexLevelParameterivQCOM, GLuint texture, GLenum face, GLint level, GLenum pname, GLint *params)
-GL_ENTRY(void, glExtGetTexSubImageQCOM, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLvoid *texels)
-GL_ENTRY(void, glExtGetTexturesQCOM, GLuint *textures, GLint maxTextures, GLint *numTextures)
-GL_ENTRY(GLboolean, glExtIsProgramBinaryQCOM, GLuint program)
-GL_ENTRY(void, glExtTexObjectStateOverrideiQCOM, GLenum target, GLenum pname, GLint param)
-GL_ENTRY(void, glFinish, void)
-GL_ENTRY(void, glFinishFenceNV, GLuint fence)
-GL_ENTRY(void, glFlush, void)
-GL_ENTRY(void, glFogf, GLenum pname, GLfloat param)
-GL_ENTRY(void, glFogfv, GLenum pname, const GLfloat *params)
-GL_ENTRY(void, glFogx, GLenum pname, GLfixed param)
-GL_ENTRY(void, glFogxOES, GLenum pname, GLfixed param)
-GL_ENTRY(void, glFogxv, GLenum pname, const GLfixed *params)
-GL_ENTRY(void, glFogxvOES, GLenum pname, const GLfixed *params)
-GL_ENTRY(void, glFramebufferRenderbuffer, GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
-GL_ENTRY(void, glFramebufferRenderbufferOES, GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
-GL_ENTRY(void, glFramebufferTexture2D, GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
-GL_ENTRY(void, glFramebufferTexture2DMultisampleIMG, GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples)
-GL_ENTRY(void, glFramebufferTexture2DOES, GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
-GL_ENTRY(void, glFramebufferTexture3DOES, GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset)
-GL_ENTRY(void, glFrontFace, GLenum mode)
-GL_ENTRY(void, glFrustumf, GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar)
-GL_ENTRY(void, glFrustumfOES, GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar)
-GL_ENTRY(void, glFrustumx, GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar)
-GL_ENTRY(void, glFrustumxOES, GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar)
-GL_ENTRY(void, glGenBuffers, GLsizei n, GLuint *buffers)
-GL_ENTRY(void, glGenFencesNV, GLsizei n, GLuint *fences)
-GL_ENTRY(void, glGenFramebuffers, GLsizei n, GLuint* framebuffers)
-GL_ENTRY(void, glGenFramebuffersOES, GLsizei n, GLuint* framebuffers)
-GL_ENTRY(void, glGenPerfMonitorsAMD, GLsizei n, GLuint *monitors)
-GL_ENTRY(void, glGenRenderbuffers, GLsizei n, GLuint* renderbuffers)
-GL_ENTRY(void, glGenRenderbuffersOES, GLsizei n, GLuint* renderbuffers)
-GL_ENTRY(void, glGenTextures, GLsizei n, GLuint *textures)
-GL_ENTRY(void, glGenVertexArraysOES, GLsizei n, GLuint *arrays)
-GL_ENTRY(void, glGenerateMipmap, GLenum target)
-GL_ENTRY(void, glGenerateMipmapOES, GLenum target)
-GL_ENTRY(void, glGetActiveAttrib, GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
-GL_ENTRY(void, glGetActiveUniform, GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
-GL_ENTRY(void, glGetAttachedShaders, GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
-GL_ENTRY(int, glGetAttribLocation, GLuint program, const GLchar* name)
-GL_ENTRY(void, glGetBooleanv, GLenum pname, GLboolean *params)
-GL_ENTRY(void, glGetBufferParameteriv, GLenum target, GLenum pname, GLint *params)
-GL_ENTRY(void, glGetBufferPointervOES, GLenum target, GLenum pname, GLvoid ** params)
-GL_ENTRY(void, glGetClipPlanef, GLenum pname, GLfloat eqn[4])
-GL_ENTRY(void, glGetClipPlanefOES, GLenum pname, GLfloat eqn[4])
-GL_ENTRY(void, glGetClipPlanex, GLenum pname, GLfixed eqn[4])
-GL_ENTRY(void, glGetClipPlanexOES, GLenum pname, GLfixed eqn[4])
-GL_ENTRY(void, glGetDriverControlStringQCOM, GLuint driverControl, GLsizei bufSize, GLsizei *length, GLchar *driverControlString)
-GL_ENTRY(void, glGetDriverControlsQCOM, GLint *num, GLsizei size, GLuint *driverControls)
-GL_ENTRY(GLenum, glGetError, void)
-GL_ENTRY(void, glGetFenceivNV, GLuint fence, GLenum pname, GLint *params)
-GL_ENTRY(void, glGetFixedv, GLenum pname, GLfixed *params)
-GL_ENTRY(void, glGetFixedvOES, GLenum pname, GLfixed *params)
-GL_ENTRY(void, glGetFloatv, GLenum pname, GLfloat *params)
-GL_ENTRY(void, glGetFramebufferAttachmentParameteriv, GLenum target, GLenum attachment, GLenum pname, GLint* params)
-GL_ENTRY(void, glGetFramebufferAttachmentParameterivOES, GLenum target, GLenum attachment, GLenum pname, GLint* params)
-GL_ENTRY(void, glGetIntegerv, GLenum pname, GLint *params)
-GL_ENTRY(void, glGetLightfv, GLenum light, GLenum pname, GLfloat *params)
-GL_ENTRY(void, glGetLightxv, GLenum light, GLenum pname, GLfixed *params)
-GL_ENTRY(void, glGetLightxvOES, GLenum light, GLenum pname, GLfixed *params)
-GL_ENTRY(void, glGetMaterialfv, GLenum face, GLenum pname, GLfloat *params)
-GL_ENTRY(void, glGetMaterialxv, GLenum face, GLenum pname, GLfixed *params)
-GL_ENTRY(void, glGetMaterialxvOES, GLenum face, GLenum pname, GLfixed *params)
-GL_ENTRY(void, glGetPerfMonitorCounterDataAMD, GLuint monitor, GLenum pname, GLsizei dataSize, GLuint *data, GLint *bytesWritten)
-GL_ENTRY(void, glGetPerfMonitorCounterInfoAMD, GLuint group, GLuint counter, GLenum pname, GLvoid *data)
-GL_ENTRY(void, glGetPerfMonitorCounterStringAMD, GLuint group, GLuint counter, GLsizei bufSize, GLsizei *length, GLchar *counterString)
-GL_ENTRY(void, glGetPerfMonitorCountersAMD, GLuint group, GLint *numCounters, GLint *maxActiveCounters, GLsizei counterSize, GLuint *counters)
-GL_ENTRY(void, glGetPerfMonitorGroupStringAMD, GLuint group, GLsizei bufSize, GLsizei *length, GLchar *groupString)
-GL_ENTRY(void, glGetPerfMonitorGroupsAMD, GLint *numGroups, GLsizei groupsSize, GLuint *groups)
-GL_ENTRY(void, glGetPointerv, GLenum pname, GLvoid **params)
-GL_ENTRY(void, glGetProgramBinaryOES, GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, GLvoid *binary)
-GL_ENTRY(void, glGetProgramInfoLog, GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
-GL_ENTRY(void, glGetProgramiv, GLuint program, GLenum pname, GLint* params)
-GL_ENTRY(void, glGetRenderbufferParameteriv, GLenum target, GLenum pname, GLint* params)
-GL_ENTRY(void, glGetRenderbufferParameterivOES, GLenum target, GLenum pname, GLint* params)
-GL_ENTRY(void, glGetShaderInfoLog, GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
-GL_ENTRY(void, glGetShaderPrecisionFormat, GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
-GL_ENTRY(void, glGetShaderSource, GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
-GL_ENTRY(void, glGetShaderiv, GLuint shader, GLenum pname, GLint* params)
-GL_ENTRY(const GLubyte *, glGetString, GLenum name)
-GL_ENTRY(void, glGetTexEnvfv, GLenum env, GLenum pname, GLfloat *params)
-GL_ENTRY(void, glGetTexEnviv, GLenum env, GLenum pname, GLint *params)
-GL_ENTRY(void, glGetTexEnvxv, GLenum env, GLenum pname, GLfixed *params)
-GL_ENTRY(void, glGetTexEnvxvOES, GLenum env, GLenum pname, GLfixed *params)
-GL_ENTRY(void, glGetTexGenfvOES, GLenum coord, GLenum pname, GLfloat *params)
-GL_ENTRY(void, glGetTexGenivOES, GLenum coord, GLenum pname, GLint *params)
-GL_ENTRY(void, glGetTexGenxvOES, GLenum coord, GLenum pname, GLfixed *params)
-GL_ENTRY(void, glGetTexParameterfv, GLenum target, GLenum pname, GLfloat *params)
-GL_ENTRY(void, glGetTexParameteriv, GLenum target, GLenum pname, GLint *params)
-GL_ENTRY(void, glGetTexParameterxv, GLenum target, GLenum pname, GLfixed *params)
-GL_ENTRY(void, glGetTexParameterxvOES, GLenum target, GLenum pname, GLfixed *params)
-GL_ENTRY(int, glGetUniformLocation, GLuint program, const GLchar* name)
-GL_ENTRY(void, glGetUniformfv, GLuint program, GLint location, GLfloat* params)
-GL_ENTRY(void, glGetUniformiv, GLuint program, GLint location, GLint* params)
-GL_ENTRY(void, glGetVertexAttribPointerv, GLuint index, GLenum pname, GLvoid** pointer)
-GL_ENTRY(void, glGetVertexAttribfv, GLuint index, GLenum pname, GLfloat* params)
-GL_ENTRY(void, glGetVertexAttribiv, GLuint index, GLenum pname, GLint* params)
-GL_ENTRY(void, glHint, GLenum target, GLenum mode)
-GL_ENTRY(GLboolean, glIsBuffer, GLuint buffer)
-GL_ENTRY(GLboolean, glIsEnabled, GLenum cap)
-GL_ENTRY(GLboolean, glIsFenceNV, GLuint fence)
-GL_ENTRY(GLboolean, glIsFramebuffer, GLuint framebuffer)
-GL_ENTRY(GLboolean, glIsFramebufferOES, GLuint framebuffer)
-GL_ENTRY(GLboolean, glIsProgram, GLuint program)
-GL_ENTRY(GLboolean, glIsRenderbuffer, GLuint renderbuffer)
-GL_ENTRY(GLboolean, glIsRenderbufferOES, GLuint renderbuffer)
-GL_ENTRY(GLboolean, glIsShader, GLuint shader)
-GL_ENTRY(GLboolean, glIsTexture, GLuint texture)
-GL_ENTRY(GLboolean, glIsVertexArrayOES, GLuint array)
-GL_ENTRY(void, glLightModelf, GLenum pname, GLfloat param)
-GL_ENTRY(void, glLightModelfv, GLenum pname, const GLfloat *params)
-GL_ENTRY(void, glLightModelx, GLenum pname, GLfixed param)
-GL_ENTRY(void, glLightModelxOES, GLenum pname, GLfixed param)
-GL_ENTRY(void, glLightModelxv, GLenum pname, const GLfixed *params)
-GL_ENTRY(void, glLightModelxvOES, GLenum pname, const GLfixed *params)
-GL_ENTRY(void, glLightf, GLenum light, GLenum pname, GLfloat param)
-GL_ENTRY(void, glLightfv, GLenum light, GLenum pname, const GLfloat *params)
-GL_ENTRY(void, glLightx, GLenum light, GLenum pname, GLfixed param)
-GL_ENTRY(void, glLightxOES, GLenum light, GLenum pname, GLfixed param)
-GL_ENTRY(void, glLightxv, GLenum light, GLenum pname, const GLfixed *params)
-GL_ENTRY(void, glLightxvOES, GLenum light, GLenum pname, const GLfixed *params)
-GL_ENTRY(void, glLineWidth, GLfloat width)
-GL_ENTRY(void, glLineWidthx, GLfixed width)
-GL_ENTRY(void, glLineWidthxOES, GLfixed width)
-GL_ENTRY(void, glLinkProgram, GLuint program)
-GL_ENTRY(void, glLoadIdentity, void)
-GL_ENTRY(void, glLoadMatrixf, const GLfloat *m)
-GL_ENTRY(void, glLoadMatrixx, const GLfixed *m)
-GL_ENTRY(void, glLoadMatrixxOES, const GLfixed *m)
-GL_ENTRY(void, glLoadPaletteFromModelViewMatrixOES, void)
-GL_ENTRY(void, glLogicOp, GLenum opcode)
-GL_ENTRY(void*, glMapBufferOES, GLenum target, GLenum access)
-GL_ENTRY(void, glMaterialf, GLenum face, GLenum pname, GLfloat param)
-GL_ENTRY(void, glMaterialfv, GLenum face, GLenum pname, const GLfloat *params)
-GL_ENTRY(void, glMaterialx, GLenum face, GLenum pname, GLfixed param)
-GL_ENTRY(void, glMaterialxOES, GLenum face, GLenum pname, GLfixed param)
-GL_ENTRY(void, glMaterialxv, GLenum face, GLenum pname, const GLfixed *params)
-GL_ENTRY(void, glMaterialxvOES, GLenum face, GLenum pname, const GLfixed *params)
-GL_ENTRY(void, glMatrixIndexPointerOES, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
-GL_ENTRY(void, glMatrixMode, GLenum mode)
-GL_ENTRY(void, glMultMatrixf, const GLfloat *m)
-GL_ENTRY(void, glMultMatrixx, const GLfixed *m)
-GL_ENTRY(void, glMultMatrixxOES, const GLfixed *m)
-GL_ENTRY(void, glMultiDrawArraysEXT, GLenum mode, GLint *first, GLsizei *count, GLsizei primcount)
-GL_ENTRY(void, glMultiDrawElementsEXT, GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount)
-GL_ENTRY(void, glMultiTexCoord4f, GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q)
-GL_ENTRY(void, glMultiTexCoord4x, GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q)
-GL_ENTRY(void, glMultiTexCoord4xOES, GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q)
-GL_ENTRY(void, glNormal3f, GLfloat nx, GLfloat ny, GLfloat nz)
-GL_ENTRY(void, glNormal3x, GLfixed nx, GLfixed ny, GLfixed nz)
-GL_ENTRY(void, glNormal3xOES, GLfixed nx, GLfixed ny, GLfixed nz)
-GL_ENTRY(void, glNormalPointer, GLenum type, GLsizei stride, const GLvoid *pointer)
-GL_ENTRY(void, glOrthof, GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar)
-GL_ENTRY(void, glOrthofOES, GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar)
-GL_ENTRY(void, glOrthox, GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar)
-GL_ENTRY(void, glOrthoxOES, GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar)
-GL_ENTRY(void, glPixelStorei, GLenum pname, GLint param)
-GL_ENTRY(void, glPointParameterf, GLenum pname, GLfloat param)
-GL_ENTRY(void, glPointParameterfv, GLenum pname, const GLfloat *params)
-GL_ENTRY(void, glPointParameterx, GLenum pname, GLfixed param)
-GL_ENTRY(void, glPointParameterxOES, GLenum pname, GLfixed param)
-GL_ENTRY(void, glPointParameterxv, GLenum pname, const GLfixed *params)
-GL_ENTRY(void, glPointParameterxvOES, GLenum pname, const GLfixed *params)
-GL_ENTRY(void, glPointSize, GLfloat size)
-GL_ENTRY(void, glPointSizePointerOES, GLenum type, GLsizei stride, const GLvoid *pointer)
-GL_ENTRY(void, glPointSizex, GLfixed size)
-GL_ENTRY(void, glPointSizexOES, GLfixed size)
-GL_ENTRY(void, glPolygonOffset, GLfloat factor, GLfloat units)
-GL_ENTRY(void, glPolygonOffsetx, GLfixed factor, GLfixed units)
-GL_ENTRY(void, glPolygonOffsetxOES, GLfixed factor, GLfixed units)
-GL_ENTRY(void, glPopMatrix, void)
-GL_ENTRY(void, glProgramBinaryOES, GLuint program, GLenum binaryFormat, const GLvoid *binary, GLint length)
-GL_ENTRY(void, glPushMatrix, void)
-GL_ENTRY(GLbitfield, glQueryMatrixxOES, GLfixed mantissa[16], GLint exponent[16])
-GL_ENTRY(void, glReadPixels, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels)
-GL_ENTRY(void, glReleaseShaderCompiler, void)
-GL_ENTRY(void, glRenderbufferStorage, GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
-GL_ENTRY(void, glRenderbufferStorageMultisampleIMG, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
-GL_ENTRY(void, glRenderbufferStorageOES, GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
-GL_ENTRY(void, glRotatef, GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
-GL_ENTRY(void, glRotatex, GLfixed angle, GLfixed x, GLfixed y, GLfixed z)
-GL_ENTRY(void, glRotatexOES, GLfixed angle, GLfixed x, GLfixed y, GLfixed z)
-GL_ENTRY(void, glSampleCoverage, GLclampf value, GLboolean invert)
-GL_ENTRY(void, glSampleCoveragex, GLclampx value, GLboolean invert)
-GL_ENTRY(void, glSampleCoveragexOES, GLclampx value, GLboolean invert)
-GL_ENTRY(void, glScalef, GLfloat x, GLfloat y, GLfloat z)
-GL_ENTRY(void, glScalex, GLfixed x, GLfixed y, GLfixed z)
-GL_ENTRY(void, glScalexOES, GLfixed x, GLfixed y, GLfixed z)
-GL_ENTRY(void, glScissor, GLint x, GLint y, GLsizei width, GLsizei height)
-GL_ENTRY(void, glSelectPerfMonitorCountersAMD, GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint *countersList)
-GL_ENTRY(void, glSetFenceNV, GLuint fence, GLenum condition)
-GL_ENTRY(void, glShadeModel, GLenum mode)
-GL_ENTRY(void, glShaderBinary, GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
-GL_ENTRY(void, glShaderSource, GLuint shader, GLsizei count, const GLchar** string, const GLint* length)
-GL_ENTRY(void, glStartTilingQCOM, GLuint x, GLuint y, GLuint width, GLuint height, GLbitfield preserveMask)
-GL_ENTRY(void, glStencilFunc, GLenum func, GLint ref, GLuint mask)
-GL_ENTRY(void, glStencilFuncSeparate, GLenum face, GLenum func, GLint ref, GLuint mask)
-GL_ENTRY(void, glStencilMask, GLuint mask)
-GL_ENTRY(void, glStencilMaskSeparate, GLenum face, GLuint mask)
-GL_ENTRY(void, glStencilOp, GLenum fail, GLenum zfail, GLenum zpass)
-GL_ENTRY(void, glStencilOpSeparate, GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
-GL_ENTRY(GLboolean, glTestFenceNV, GLuint fence)
-GL_ENTRY(void, glTexCoordPointer, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
-GL_ENTRY(void, glTexEnvf, GLenum target, GLenum pname, GLfloat param)
-GL_ENTRY(void, glTexEnvfv, GLenum target, GLenum pname, const GLfloat *params)
-GL_ENTRY(void, glTexEnvi, GLenum target, GLenum pname, GLint param)
-GL_ENTRY(void, glTexEnviv, GLenum target, GLenum pname, const GLint *params)
-GL_ENTRY(void, glTexEnvx, GLenum target, GLenum pname, GLfixed param)
-GL_ENTRY(void, glTexEnvxOES, GLenum target, GLenum pname, GLfixed param)
-GL_ENTRY(void, glTexEnvxv, GLenum target, GLenum pname, const GLfixed *params)
-GL_ENTRY(void, glTexEnvxvOES, GLenum target, GLenum pname, const GLfixed *params)
-GL_ENTRY(void, glTexGenfOES, GLenum coord, GLenum pname, GLfloat param)
-GL_ENTRY(void, glTexGenfvOES, GLenum coord, GLenum pname, const GLfloat *params)
-GL_ENTRY(void, glTexGeniOES, GLenum coord, GLenum pname, GLint param)
-GL_ENTRY(void, glTexGenivOES, GLenum coord, GLenum pname, const GLint *params)
-GL_ENTRY(void, glTexGenxOES, GLenum coord, GLenum pname, GLfixed param)
-GL_ENTRY(void, glTexGenxvOES, GLenum coord, GLenum pname, const GLfixed *params)
-GL_ENTRY(void, glTexImage2D, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
-GL_ENTRY(void, glTexImage3DOES, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid* pixels)
-GL_ENTRY(void, glTexParameterf, GLenum target, GLenum pname, GLfloat param)
-GL_ENTRY(void, glTexParameterfv, GLenum target, GLenum pname, const GLfloat *params)
-GL_ENTRY(void, glTexParameteri, GLenum target, GLenum pname, GLint param)
-GL_ENTRY(void, glTexParameteriv, GLenum target, GLenum pname, const GLint *params)
-GL_ENTRY(void, glTexParameterx, GLenum target, GLenum pname, GLfixed param)
-GL_ENTRY(void, glTexParameterxOES, GLenum target, GLenum pname, GLfixed param)
-GL_ENTRY(void, glTexParameterxv, GLenum target, GLenum pname, const GLfixed *params)
-GL_ENTRY(void, glTexParameterxvOES, GLenum target, GLenum pname, const GLfixed *params)
-GL_ENTRY(void, glTexSubImage2D, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels)
-GL_ENTRY(void, glTexSubImage3DOES, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid* pixels)
-GL_ENTRY(void, glTranslatef, GLfloat x, GLfloat y, GLfloat z)
-GL_ENTRY(void, glTranslatex, GLfixed x, GLfixed y, GLfixed z)
-GL_ENTRY(void, glTranslatexOES, GLfixed x, GLfixed y, GLfixed z)
-GL_ENTRY(void, glUniform1f, GLint location, GLfloat x)
-GL_ENTRY(void, glUniform1fv, GLint location, GLsizei count, const GLfloat* v)
-GL_ENTRY(void, glUniform1i, GLint location, GLint x)
-GL_ENTRY(void, glUniform1iv, GLint location, GLsizei count, const GLint* v)
-GL_ENTRY(void, glUniform2f, GLint location, GLfloat x, GLfloat y)
-GL_ENTRY(void, glUniform2fv, GLint location, GLsizei count, const GLfloat* v)
-GL_ENTRY(void, glUniform2i, GLint location, GLint x, GLint y)
-GL_ENTRY(void, glUniform2iv, GLint location, GLsizei count, const GLint* v)
-GL_ENTRY(void, glUniform3f, GLint location, GLfloat x, GLfloat y, GLfloat z)
-GL_ENTRY(void, glUniform3fv, GLint location, GLsizei count, const GLfloat* v)
-GL_ENTRY(void, glUniform3i, GLint location, GLint x, GLint y, GLint z)
-GL_ENTRY(void, glUniform3iv, GLint location, GLsizei count, const GLint* v)
-GL_ENTRY(void, glUniform4f, GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
-GL_ENTRY(void, glUniform4fv, GLint location, GLsizei count, const GLfloat* v)
-GL_ENTRY(void, glUniform4i, GLint location, GLint x, GLint y, GLint z, GLint w)
-GL_ENTRY(void, glUniform4iv, GLint location, GLsizei count, const GLint* v)
-GL_ENTRY(void, glUniformMatrix2fv, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
-GL_ENTRY(void, glUniformMatrix3fv, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
-GL_ENTRY(void, glUniformMatrix4fv, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
-GL_ENTRY(GLboolean, glUnmapBufferOES, GLenum target)
-GL_ENTRY(void, glUseProgram, GLuint program)
-GL_ENTRY(void, glValidateProgram, GLuint program)
-GL_ENTRY(void, glVertexAttrib1f, GLuint indx, GLfloat x)
-GL_ENTRY(void, glVertexAttrib1fv, GLuint indx, const GLfloat* values)
-GL_ENTRY(void, glVertexAttrib2f, GLuint indx, GLfloat x, GLfloat y)
-GL_ENTRY(void, glVertexAttrib2fv, GLuint indx, const GLfloat* values)
-GL_ENTRY(void, glVertexAttrib3f, GLuint indx, GLfloat x, GLfloat y, GLfloat z)
-GL_ENTRY(void, glVertexAttrib3fv, GLuint indx, const GLfloat* values)
-GL_ENTRY(void, glVertexAttrib4f, GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
-GL_ENTRY(void, glVertexAttrib4fv, GLuint indx, const GLfloat* values)
-GL_ENTRY(void, glVertexAttribPointer, GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
-GL_ENTRY(void, glVertexPointer, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
-GL_ENTRY(void, glViewport, GLint x, GLint y, GLsizei width, GLsizei height)
-GL_ENTRY(void, glWeightPointerOES, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
-
-
-}
diff --git a/opengl/specs/README b/opengl/specs/README
index 2fa2587..16b278f 100644
--- a/opengl/specs/README
+++ b/opengl/specs/README
@@ -9,4 +9,5 @@
 0x3140               EGL_ANDROID_image_native_buffer
 0x3141               (unused)
 0x3142               EGL_ANDROID_recordable
-0x3143 - 0x314F      (unused)
+0x3143               EGL_VERSION_HW_ANDROID (internal use)
+0x3144 - 0x314F      (unused)
diff --git a/packages/BackupRestoreConfirmation/res/values-af/strings.xml b/packages/BackupRestoreConfirmation/res/values-af/strings.xml
index 8ee5550..fadd125 100644
--- a/packages/BackupRestoreConfirmation/res/values-af/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-af/strings.xml
@@ -18,10 +18,10 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="backup_confirm_title" msgid="827563724209303345">"Volledige rugsteun"</string>
     <string name="restore_confirm_title" msgid="5469365809567486602">"Volledige herstel"</string>
-    <string name="backup_confirm_text" msgid="1878021282758896593">"\'n Volledige rugsteun van al die data na \'n tafelrekenaar is aangevra. Wil jy dit toelaat? "\n\n"As jy nie self die rugsteun versoek het nie, moenie toelaat dat die aksie voortgaan nie."</string>
+    <string name="backup_confirm_text" msgid="1878021282758896593">"\'n Volledige rugsteun van al die data na \'n rekenaar is aangevra. Wil jy dit toelaat? "\n\n"As jy nie self die rugsteun versoek het nie, moenie toelaat dat die aksie voortgaan nie."</string>
     <string name="allow_backup_button_label" msgid="4217228747769644068">"Rugsteun my data"</string>
     <string name="deny_backup_button_label" msgid="6009119115581097708">"Moenie rugsteun nie"</string>
-    <string name="restore_confirm_text" msgid="7499866728030461776">"\'n Volle teruglaai van alle data van \'n gekoppelde tafelrekenaar is versoek. Wil jy dit toelaat? "\n\n" As jy nie die teruglaai self versoek het nie, moenie die aksie toelaat nie. Dit sal enige data tans op die toestel vervang!"</string>
+    <string name="restore_confirm_text" msgid="7499866728030461776">"\'n Volle teruglaai van alle data van \'n gekoppelde rekenaar is versoek. Wil jy dit toelaat? "\n\n" As jy nie die teruglaai self versoek het nie, moenie die aksie toelaat nie. Dit sal enige data tans op die toestel vervang!"</string>
     <string name="allow_restore_button_label" msgid="3081286752277127827">"Laai my data terug"</string>
     <string name="deny_restore_button_label" msgid="1724367334453104378">"Moenie herstel nie"</string>
     <string name="current_password_text" msgid="8268189555578298067">"Voer asseblief jou huidige rugsteunwagwoord hieronder in:"</string>
diff --git a/packages/BackupRestoreConfirmation/res/values-zu/strings.xml b/packages/BackupRestoreConfirmation/res/values-zu/strings.xml
index 2fe0c0f..241bd37 100644
--- a/packages/BackupRestoreConfirmation/res/values-zu/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-zu/strings.xml
@@ -24,12 +24,12 @@
     <string name="restore_confirm_text" msgid="7499866728030461776">"Kucelwe ukubuyiselwa esimweni okuphelele kwayo yonke imininingo yakho kwi-desktop yekhompuyutha exhunyiswe. Ngabe ufuna ukuvumela lokhu ukuthi kwenzeke?"\n\n"Uma ungazange ucele ukuthi lokhu kwenzeke wena uqobo, ungavumeli lokhu ukuthi kuqhubekele phambili. Lokhu kuzothatha indawo yayo yonke imininingo ekhona njengamanje kwi-device!"</string>
     <string name="allow_restore_button_label" msgid="3081286752277127827">"Buyisela esimweni imininingo yami"</string>
     <string name="deny_restore_button_label" msgid="1724367334453104378">"Ungabuyiseli esimweni"</string>
-    <string name="current_password_text" msgid="8268189555578298067">"Sicela ufake i-password yakho yamanje yokwenza isipele ngezansi:"</string>
+    <string name="current_password_text" msgid="8268189555578298067">"Sicela ufake iphasiwedi yakho yamanje yokwenza isipele ngezansi:"</string>
     <string name="device_encryption_restore_text" msgid="1570864916855208992">"Uyacelwa ukuba ufake ihasiwedi efakwe kudivayisi ngezansi."</string>
     <string name="device_encryption_backup_text" msgid="5866590762672844664">"Uyacelwa ukuba ufake iphasiwedi efakwe kudivayisi yakho ngezansi. lokhu kuzosetshenziswa ukufaka kusilondoloza sokusiza lapho kudingeka."</string>
-    <string name="backup_enc_password_text" msgid="4981585714795233099">"Sicela ufake i-password ezosetshenziselwa ukubhala ngokufihlekileyo imininingo eyesekwe ngokulondoloza. Uma lokhu kushiywe kungabhalwe lutho, kuzosetshenziswa i-password yokweseka ngokulondoloza yamanje:"</string>
+    <string name="backup_enc_password_text" msgid="4981585714795233099">"Sicela ufake iphasiwedi ezosetshenziselwa ukubhala ngokufihlekileyo imininingo eyesekwe ngokulondoloza. Uma lokhu kushiywe kungabhalwe lutho, kuzosetshenziswa iphasiwedi yokweseka ngokulondoloza yamanje:"</string>
     <string name="backup_enc_password_optional" msgid="1350137345907579306">"Uma ufuna ukufaka ikhowudi kwimininingo yonke eyesekelwe ngokulondoloza faka i-passowrd engezansi:"</string>
-    <string name="restore_enc_password_text" msgid="6140898525580710823">"Uma insiza yokubuyiselwa esimweni kwmininingo ibhalwe ngokufihlekileyo, sicela ufake i-password ngezansi:"</string>
+    <string name="restore_enc_password_text" msgid="6140898525580710823">"Uma insiza yokubuyiselwa esimweni kwmininingo ibhalwe ngokufihlekileyo, sicela ufake iphasiwedi engezansi:"</string>
     <string name="toast_backup_started" msgid="550354281452756121">"Ukulondoloza kuyaqala..."</string>
     <string name="toast_backup_ended" msgid="3818080769548726424">"Ukulondoloza kuphelile"</string>
     <string name="toast_restore_started" msgid="7881679218971277385">"Ukubuyisa kuyaqala..."</string>
diff --git a/packages/SettingsProvider/res/values-vi/strings.xml b/packages/SettingsProvider/res/values-vi/strings.xml
index 113d7ad..504479d 100644
--- a/packages/SettingsProvider/res/values-vi/strings.xml
+++ b/packages/SettingsProvider/res/values-vi/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">"Bộ nhớ Cài đặt"</string>
+    <string name="app_label" msgid="4567566098528588863">"Lưu trữ cài đặt"</string>
 </resources>
diff --git a/packages/SettingsProvider/res/values/defaults.xml b/packages/SettingsProvider/res/values/defaults.xml
index 7a98615..4ea2c31 100644
--- a/packages/SettingsProvider/res/values/defaults.xml
+++ b/packages/SettingsProvider/res/values/defaults.xml
@@ -80,6 +80,9 @@
     <!-- Default for Settings.Secure.ACCESSIBILITY_SCRIPT_INJECTION -->
     <bool name="def_accessibility_script_injection">false</bool>
 
+    <!-- Default for Settings.Secure.ACCESSIBILITY_SPEAK_PASSWORD -->
+    <bool name="def_accessibility_speak_password">false</bool>
+
     <!-- Default for Settings.Secure.ACCESSIBILITY_WEB_CONTENT_KEY_BINDINGS -->
     <string name="def_accessibility_web_content_key_bindings" translatable="false">
             <!-- DPAD/Trackball UP - traverse previous on current axis and send an event. -->
@@ -112,6 +115,11 @@
             0x200000038=0x03000701:0x03010701:0x03020701;
     </string>
 
+    <!-- Default for Settings.Secure.ACCESSIBILITY_SCRIPT_INJECTION_URL -->
+    <string name="def_accessibility_screen_reader_url" translatable="false">
+        https://ssl.gstatic.com/accessibility/javascript/android/AndroidScriptChooser.user.js
+    </string>
+
     <!-- Default for Settings.Secure.TOUCH_EXPLORATION_ENABLED -->
     <bool name="def_touch_exploration_enabled">false</bool>
 
diff --git a/packages/SettingsProvider/res/xml/bookmarks.xml b/packages/SettingsProvider/res/xml/bookmarks.xml
index 83229f4..454f456 100644
--- a/packages/SettingsProvider/res/xml/bookmarks.xml
+++ b/packages/SettingsProvider/res/xml/bookmarks.xml
@@ -19,6 +19,7 @@
      Bookmarks for vendor apps should be added to a bookmarks resource overlay; not here.
 
      Typical shortcuts (not necessarily defined here):
+       'a': Calculator
        'b': Browser
        'c': Contacts
        'e': Email
@@ -32,27 +33,27 @@
 -->
 <bookmarks>
     <bookmark
-        package="com.android.browser"
-        class="com.android.browser.BrowserActivity"
+        category="android.intent.category.APP_CALCULATOR"
+        shortcut="a" />
+    <bookmark
+        category="android.intent.category.APP_BROWSER"
         shortcut="b" />
     <bookmark
-        package="com.android.contacts"
-        class="com.android.contacts.activities.ContactsFrontDoor"
+        category="android.intent.category.APP_CONTACTS"
         shortcut="c" />
     <bookmark
-        package="com.google.android.email"
-        class="com.android.email.activity.Welcome"
+        category="android.intent.category.APP_EMAIL"
         shortcut="e" />
     <bookmark
-        package="com.google.android.calendar"
-        class="com.android.calendar.LaunchActivity"
+        category="android.intent.category.APP_CALENDAR"
         shortcut="l" />
     <bookmark
-        package="com.android.music"
-        class="com.android.music.MusicBrowserActivity"
+        category="android.intent.category.APP_MAPS"
+        shortcut="m" />
+    <bookmark
+        category="android.intent.category.APP_MUSIC"
         shortcut="p" />
     <bookmark
-        package="com.android.mms"
-        class="com.android.mms.ui.ConversationList"
+        category="android.intent.category.APP_MESSAGING"
         shortcut="s" />
 </bookmarks>
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
index aa08e64..a6a3303 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
@@ -63,7 +63,7 @@
     // database gets upgraded properly. At a minimum, please confirm that 'upgradeVersion'
     // is properly propagated through your change.  Not doing so will result in a loss of user
     // settings.
-    private static final int DATABASE_VERSION = 70;
+    private static final int DATABASE_VERSION = 74;
 
     private Context mContext;
 
@@ -946,6 +946,62 @@
             upgradeVersion = 70;
         }
 
+        if (upgradeVersion == 70) {
+            // Update all built-in bookmarks.  Some of the package names have changed.
+            loadBookmarks(db);
+            upgradeVersion = 71;
+        }
+
+        if (upgradeVersion == 71) {
+             // New setting to specify whether to speak passwords in accessibility mode.
+            db.beginTransaction();
+            SQLiteStatement stmt = null;
+            try {
+                stmt = db.compileStatement("INSERT INTO secure(name,value)"
+                        + " VALUES(?,?);");
+                loadBooleanSetting(stmt, Settings.Secure.ACCESSIBILITY_SPEAK_PASSWORD,
+                        R.bool.def_accessibility_speak_password);
+                db.setTransactionSuccessful();
+            } finally {
+                db.endTransaction();
+                if (stmt != null) stmt.close();
+            }
+            upgradeVersion = 72;
+        }
+
+        if (upgradeVersion == 72) {
+            // update vibration settings
+            db.beginTransaction();
+            SQLiteStatement stmt = null;
+            try {
+                stmt = db.compileStatement("INSERT OR REPLACE INTO system(name,value)"
+                        + " VALUES(?,?);");
+                loadBooleanSetting(stmt, Settings.System.VIBRATE_IN_SILENT,
+                        R.bool.def_vibrate_in_silent);
+                db.setTransactionSuccessful();
+            } finally {
+                db.endTransaction();
+                if (stmt != null) stmt.close();
+            }
+            upgradeVersion = 73;
+        }
+
+        if (upgradeVersion == 73) {
+            // URL from which WebView loads a JavaScript based screen-reader.
+            db.beginTransaction();
+            SQLiteStatement stmt = null;
+            try {
+                stmt = db.compileStatement("INSERT INTO secure(name,value) VALUES(?,?);");
+                loadStringSetting(stmt, Settings.Secure.ACCESSIBILITY_SCREEN_READER_URL,
+                        R.string.def_accessibility_screen_reader_url);
+                db.setTransactionSuccessful();
+            } finally {
+                db.endTransaction();
+                if (stmt != null) stmt.close();
+            }
+            upgradeVersion = 74;
+        }
+
         // *** Remember to update DATABASE_VERSION above!
 
         if (upgradeVersion != currentVersion) {
@@ -1086,16 +1142,11 @@
      * Loads the default set of bookmarked shortcuts from an xml file.
      *
      * @param db The database to write the values into
-     * @param startingIndex The zero-based position at which bookmarks in this file should begin
      */
-    private int loadBookmarks(SQLiteDatabase db, int startingIndex) {
-        Intent intent = new Intent(Intent.ACTION_MAIN, null);
-        intent.addCategory(Intent.CATEGORY_LAUNCHER);
+    private void loadBookmarks(SQLiteDatabase db) {
         ContentValues values = new ContentValues();
 
         PackageManager packageManager = mContext.getPackageManager();
-        int i = startingIndex;
-
         try {
             XmlResourceParser parser = mContext.getResources().getXml(R.xml.bookmarks);
             XmlUtils.beginDocument(parser, "bookmarks");
@@ -1118,54 +1169,59 @@
                 String pkg = parser.getAttributeValue(null, "package");
                 String cls = parser.getAttributeValue(null, "class");
                 String shortcutStr = parser.getAttributeValue(null, "shortcut");
+                String category = parser.getAttributeValue(null, "category");
 
                 int shortcutValue = shortcutStr.charAt(0);
                 if (TextUtils.isEmpty(shortcutStr)) {
                     Log.w(TAG, "Unable to get shortcut for: " + pkg + "/" + cls);
+                    continue;
                 }
 
-                ActivityInfo info = null;                
-                ComponentName cn = new ComponentName(pkg, cls);
-                try {
-                    info = packageManager.getActivityInfo(cn, 0);
-                } catch (PackageManager.NameNotFoundException e) {
-                    String[] packages = packageManager.canonicalToCurrentPackageNames(
-                            new String[] { pkg });
-                    cn = new ComponentName(packages[0], cls);
+                final Intent intent;
+                final String title;
+                if (pkg != null && cls != null) {
+                    ActivityInfo info = null;
+                    ComponentName cn = new ComponentName(pkg, cls);
                     try {
                         info = packageManager.getActivityInfo(cn, 0);
-                    } catch (PackageManager.NameNotFoundException e1) {
-                        Log.w(TAG, "Unable to add bookmark: " + pkg + "/" + cls, e);
+                    } catch (PackageManager.NameNotFoundException e) {
+                        String[] packages = packageManager.canonicalToCurrentPackageNames(
+                                new String[] { pkg });
+                        cn = new ComponentName(packages[0], cls);
+                        try {
+                            info = packageManager.getActivityInfo(cn, 0);
+                        } catch (PackageManager.NameNotFoundException e1) {
+                            Log.w(TAG, "Unable to add bookmark: " + pkg + "/" + cls, e);
+                            continue;
+                        }
                     }
-                }
-                
-                if (info != null) {
+
+                    intent = new Intent(Intent.ACTION_MAIN, null);
+                    intent.addCategory(Intent.CATEGORY_LAUNCHER);
                     intent.setComponent(cn);
-                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-                    values.put(Settings.Bookmarks.INTENT, intent.toUri(0));
-                    values.put(Settings.Bookmarks.TITLE,
-                            info.loadLabel(packageManager).toString());
-                    values.put(Settings.Bookmarks.SHORTCUT, shortcutValue);
-                    db.insert("bookmarks", null, values);
-                    i++;
+                    title = info.loadLabel(packageManager).toString();
+                } else if (category != null) {
+                    intent = Intent.makeMainSelectorActivity(Intent.ACTION_MAIN, category);
+                    title = "";
+                } else {
+                    Log.w(TAG, "Unable to add bookmark for shortcut " + shortcutStr
+                            + ": missing package/class or category attributes");
+                    continue;
                 }
+
+                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+                values.put(Settings.Bookmarks.INTENT, intent.toUri(0));
+                values.put(Settings.Bookmarks.TITLE, title);
+                values.put(Settings.Bookmarks.SHORTCUT, shortcutValue);
+                db.delete("bookmarks", "shortcut = ?",
+                        new String[] { Integer.toString(shortcutValue) });
+                db.insert("bookmarks", null, values);
             }
         } catch (XmlPullParserException e) {
             Log.w(TAG, "Got execption parsing bookmarks.", e);
         } catch (IOException e) {
             Log.w(TAG, "Got execption parsing bookmarks.", e);
         }
-
-        return i;
-    }
-
-    /**
-     * Loads the default set of bookmark packages.
-     *
-     * @param db The database to write the values into
-     */
-    private void loadBookmarks(SQLiteDatabase db) {
-        loadBookmarks(db, 0);
     }
 
     /**
@@ -1483,6 +1539,12 @@
 
             loadBooleanSetting(stmt, Settings.Secure.TOUCH_EXPLORATION_ENABLED,
                     R.bool.def_touch_exploration_enabled);
+
+            loadBooleanSetting(stmt, Settings.Secure.ACCESSIBILITY_SPEAK_PASSWORD,
+                    R.bool.def_accessibility_speak_password);
+
+            loadStringSetting(stmt, Settings.Secure.ACCESSIBILITY_SCREEN_READER_URL,
+                    R.string.def_accessibility_screen_reader_url);
         } finally {
             if (stmt != null) stmt.close();
         }
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_ime_default.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_ime.png
similarity index 100%
rename from packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_ime_default.png
rename to packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_ime.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_ime_pressed.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_ime_pressed.png
deleted file mode 100644
index 4757125..0000000
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_ime_pressed.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime_default.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime.png
similarity index 100%
rename from packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime_default.png
rename to packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime_pressed.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime_pressed.png
deleted file mode 100644
index 0cd05a3..0000000
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime_pressed.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_ime_default.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_ime.png
similarity index 100%
rename from packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_ime_default.png
rename to packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_ime.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_ime_pressed.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_ime_pressed.png
deleted file mode 100644
index 3e59c8d..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_ime_pressed.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/layout-sw600dp/status_bar_recent_panel.xml b/packages/SystemUI/res/layout-sw600dp/status_bar_recent_panel.xml
index 111f9a4..8e231d0 100644
--- a/packages/SystemUI/res/layout-sw600dp/status_bar_recent_panel.xml
+++ b/packages/SystemUI/res/layout-sw600dp/status_bar_recent_panel.xml
@@ -32,7 +32,7 @@
         android:layout_width="wrap_content"
         android:layout_height="match_parent"
         android:layout_alignParentBottom="true"
-        android:paddingBottom="@*android:dimen/status_bar_height"
+        android:layout_marginBottom="@*android:dimen/status_bar_height"
         android:clipToPadding="false"
         android:clipChildren="false">
 
@@ -69,13 +69,12 @@
 
     </FrameLayout>
 
-    <View android:id="@+id/recents_dismiss_button"
-        android:layout_width="80px"
+    <com.android.systemui.recent.StatusBarTouchProxy
+        android:id="@+id/status_bar_touch_proxy"
+        android:layout_width="match_parent"
         android:layout_height="@*android:dimen/status_bar_height"
         android:layout_alignParentBottom="true"
         android:layout_alignParentLeft="true"
-        android:background="@drawable/ic_sysbar_back_ime"
-        android:contentDescription="@string/status_bar_accessibility_dismiss_recents"
     />
 
 
diff --git a/packages/SystemUI/res/layout-sw600dp/status_bar_ticker_panel.xml b/packages/SystemUI/res/layout-sw600dp/status_bar_ticker_panel.xml
index 6cd8899..d51f9c8 100644
--- a/packages/SystemUI/res/layout-sw600dp/status_bar_ticker_panel.xml
+++ b/packages/SystemUI/res/layout-sw600dp/status_bar_ticker_panel.xml
@@ -15,20 +15,29 @@
  * limitations under the License.
 -->
 
-<LinearLayout
+<RelativeLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    android:orientation="horizontal"
-    android:gravity="bottom"
     >
 
+    <View
+        android:layout_height="@*android:dimen/status_bar_height"
+        android:layout_width="match_parent"
+        android:background="@drawable/status_bar_ticker_background"
+        android:layout_alignParentLeft="true"
+        android:layout_alignParentBottom="true"
+        android:clickable="false"
+        />
+
     <ImageView
         android:id="@+id/large_icon"
         android:layout_width="@android:dimen/notification_large_icon_height"
         android:layout_height="@android:dimen/notification_large_icon_width"
         android:scaleType="center"
         android:visibility="gone"
+        android:layout_alignParentLeft="true"
+        android:layout_alignParentBottom="true"
         />
 
     <FrameLayout
@@ -36,6 +45,8 @@
         android:layout_weight="1"
         android:layout_height="@*android:dimen/status_bar_height"
         android:layout_width="match_parent"
-        android:background="@drawable/status_bar_ticker_background"
+        android:layout_toRightOf="@id/large_icon"
+        android:layout_alignParentBottom="true"
+        android:layout_alignWithParentIfMissing="true"
         />
-</LinearLayout>
+</RelativeLayout>
diff --git a/packages/SystemUI/res/layout/global_screenshot.xml b/packages/SystemUI/res/layout/global_screenshot.xml
index d416af9..8b337ea 100644
--- a/packages/SystemUI/res/layout/global_screenshot.xml
+++ b/packages/SystemUI/res/layout/global_screenshot.xml
@@ -19,23 +19,18 @@
     <ImageView android:id="@+id/global_screenshot_background"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
-        android:background="#FF000000"
+        android:src="@android:color/black"
         android:visibility="gone" />
-    <FrameLayout
-        android:id="@+id/global_screenshot_container"
+    <ImageView android:id="@+id/global_screenshot"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_gravity="center"
         android:background="@drawable/screenshot_panel"
-        android:visibility="gone">
-        <ImageView android:id="@+id/global_screenshot"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:adjustViewBounds="true" />
-    </FrameLayout>
+        android:visibility="gone"
+        android:adjustViewBounds="true" />
     <ImageView android:id="@+id/global_screenshot_flash"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
-        android:background="#FFFFFFFF"
+        android:src="@android:color/white"
         android:visibility="gone" />
 </FrameLayout>
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index a57cac2..08dedfa 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -102,16 +102,11 @@
     <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"Wi-Fi twee strepies."</string>
     <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"Wi-Fi drie strepies."</string>
     <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Wi-Fi-sein vol."</string>
-    <!-- no translation found for accessibility_no_wimax (4329180129727630368) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_one_bar (4170994299011863648) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_two_bars (9176236858336502288) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_three_bars (6116551636752103927) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_signal_full (2768089986795579558) -->
-    <skip />
+    <string name="accessibility_no_wimax" msgid="4329180129727630368">"Geen WiMAX nie."</string>
+    <string name="accessibility_wimax_one_bar" msgid="4170994299011863648">"WiMAX een strepie."</string>
+    <string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"WiMAX twee strepies."</string>
+    <string name="accessibility_wimax_three_bars" msgid="6116551636752103927">"WiMAX drie strepies."</string>
+    <string name="accessibility_wimax_signal_full" msgid="2768089986795579558">"WiMAX-sein vol."</string>
     <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
     <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
     <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
@@ -143,6 +138,5 @@
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"Soek vir GPS"</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Ligging deur GPS gestel"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Verwyder alle kennisgewings."</string>
-    <!-- no translation found for dreams_dock_launcher (3541196417659166245) -->
-    <skip />
+    <string name="dreams_dock_launcher" msgid="3541196417659166245">"Aktiveer sluimerskerm"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index 70f4bf2..612b666 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -102,16 +102,11 @@
     <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"Wi-Fi ሁለት አሞሌዎች::"</string>
     <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"Wi-Fi ሶስት አሞሌዎች::"</string>
     <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"የWiFi  አመልካች ሙሉ ነው።"</string>
-    <!-- no translation found for accessibility_no_wimax (4329180129727630368) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_one_bar (4170994299011863648) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_two_bars (9176236858336502288) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_three_bars (6116551636752103927) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_signal_full (2768089986795579558) -->
-    <skip />
+    <string name="accessibility_no_wimax" msgid="4329180129727630368">"ምንም WiMAX."</string>
+    <string name="accessibility_wimax_one_bar" msgid="4170994299011863648">"WiMAX አንድ አሞሌ።"</string>
+    <string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"WiMAX ሁለት አሞሌዎች።"</string>
+    <string name="accessibility_wimax_three_bars" msgid="6116551636752103927">"WiMAX ሦስት አሞሌዎች።"</string>
+    <string name="accessibility_wimax_signal_full" msgid="2768089986795579558">"WiMAX አመልካች ሙሉ ነው።"</string>
     <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
     <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
     <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index 7e3c01e..4bc56af 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -102,16 +102,11 @@
     <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"شريطان لـ Wi-Fi."</string>
     <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"ثلاثة أشرطة لـ Wi-Fi."</string>
     <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"إشارة WiFi كاملة."</string>
-    <!-- no translation found for accessibility_no_wimax (4329180129727630368) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_one_bar (4170994299011863648) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_two_bars (9176236858336502288) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_three_bars (6116551636752103927) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_signal_full (2768089986795579558) -->
-    <skip />
+    <string name="accessibility_no_wimax" msgid="4329180129727630368">"ليس هناك WiMAX."</string>
+    <string name="accessibility_wimax_one_bar" msgid="4170994299011863648">"شريط WiMAX واحد."</string>
+    <string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"شريطا WiMAX."</string>
+    <string name="accessibility_wimax_three_bars" msgid="6116551636752103927">"أشرطة WiMAX الثلاثة."</string>
+    <string name="accessibility_wimax_signal_full" msgid="2768089986795579558">"إشارة WiMAX كاملة."</string>
     <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
     <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"شبكة الجيل الثالث"</string>
     <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"شبكة 3.5G"</string>
@@ -143,6 +138,5 @@
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"جارٍ البحث عن GPS"</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"تم تعيين الموقع بواسطة GPS"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"محو جميع الإشعارات."</string>
-    <!-- no translation found for dreams_dock_launcher (3541196417659166245) -->
-    <skip />
+    <string name="dreams_dock_launcher" msgid="3541196417659166245">"تنشيط شاشة التوقف"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index 5921bf8..33aca92 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -102,16 +102,11 @@
     <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"Wi-Fi е с две чертички."</string>
     <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"Wi-Fi е с три чертички."</string>
     <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Сигналът за WiFi е пълен."</string>
-    <!-- no translation found for accessibility_no_wimax (4329180129727630368) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_one_bar (4170994299011863648) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_two_bars (9176236858336502288) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_three_bars (6116551636752103927) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_signal_full (2768089986795579558) -->
-    <skip />
+    <string name="accessibility_no_wimax" msgid="4329180129727630368">"Няма WiMAX."</string>
+    <string name="accessibility_wimax_one_bar" msgid="4170994299011863648">"WiMAX е с една чертичка."</string>
+    <string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"WiMAX е с две чертички."</string>
+    <string name="accessibility_wimax_three_bars" msgid="6116551636752103927">"WiMAX е с три чертички."</string>
+    <string name="accessibility_wimax_signal_full" msgid="2768089986795579558">"Сигналът за WiMAX е пълен."</string>
     <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
     <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
     <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
@@ -143,6 +138,5 @@
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"Търси се GPS"</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Местоположението е зададено от GPS"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Изчистване на всички известия."</string>
-    <!-- no translation found for dreams_dock_launcher (3541196417659166245) -->
-    <skip />
+    <string name="dreams_dock_launcher" msgid="3541196417659166245">"Активиране на скрийнсейвъра"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 58aaa40..775e610 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -102,16 +102,11 @@
     <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"Dues barres de Wi-Fi."</string>
     <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"Tres barres de Wi-Fi."</string>
     <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Senyal Wi-Fi: complet."</string>
-    <!-- no translation found for accessibility_no_wimax (4329180129727630368) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_one_bar (4170994299011863648) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_two_bars (9176236858336502288) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_three_bars (6116551636752103927) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_signal_full (2768089986795579558) -->
-    <skip />
+    <string name="accessibility_no_wimax" msgid="4329180129727630368">"Sense WiMAX."</string>
+    <string name="accessibility_wimax_one_bar" msgid="4170994299011863648">"Una barra de WiMAX."</string>
+    <string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"Dues barres de WiMAX."</string>
+    <string name="accessibility_wimax_three_bars" msgid="6116551636752103927">"Tres barres de WiMAX."</string>
+    <string name="accessibility_wimax_signal_full" msgid="2768089986795579558">"Senyal de WiMAX plena."</string>
     <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
     <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
     <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3,5G"</string>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 743ca22..4d9b2cd 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -102,16 +102,11 @@
     <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"Wi-Fi – dvě čárky."</string>
     <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"Wi-Fi – tři čárky."</string>
     <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Plný signál sítě Wi-Fi."</string>
-    <!-- no translation found for accessibility_no_wimax (4329180129727630368) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_one_bar (4170994299011863648) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_two_bars (9176236858336502288) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_three_bars (6116551636752103927) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_signal_full (2768089986795579558) -->
-    <skip />
+    <string name="accessibility_no_wimax" msgid="4329180129727630368">"Žádný signál sítě WiMAX."</string>
+    <string name="accessibility_wimax_one_bar" msgid="4170994299011863648">"Jedna čárka signálu sítě WiMAX."</string>
+    <string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"Dvě čárky signálu sítě WiMAX."</string>
+    <string name="accessibility_wimax_three_bars" msgid="6116551636752103927">"Tři čárky signálu sítě WiMAX."</string>
+    <string name="accessibility_wimax_signal_full" msgid="2768089986795579558">"Plný signál sítě WiMAX."</string>
     <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
     <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
     <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3,5G"</string>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index b566d95..b518898 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -33,7 +33,7 @@
   </plurals>
     <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Ingen meddelelser"</string>
     <string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"I gang"</string>
-    <string name="status_bar_latest_events_title" msgid="6594767438577593172">"Meddelelser"</string>
+    <string name="status_bar_latest_events_title" msgid="6594767438577593172">"Underretninger"</string>
     <string name="battery_low_title" msgid="2783104807551211639">"Tilslut oplader"</string>
     <string name="battery_low_subtitle" msgid="1752040062087829196">"Batteriet er ved at være fladt."</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"<xliff:g id="NUMBER">%d%%</xliff:g> tilbage"</string>
@@ -45,7 +45,7 @@
     <string name="status_bar_settings_auto_rotation" msgid="3790482541357798421">"Automatisk skærmrotation"</string>
     <string name="status_bar_settings_mute_label" msgid="554682549917429396">"LYDLØS"</string>
     <string name="status_bar_settings_auto_brightness_label" msgid="511453614962324674">"AUTO"</string>
-    <string name="status_bar_settings_notifications" msgid="397146176280905137">"Meddelelser"</string>
+    <string name="status_bar_settings_notifications" msgid="397146176280905137">"Underretninger"</string>
     <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth-tethering anvendt"</string>
     <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Konfigurer inputmetoder"</string>
     <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Brug fysisk tastatur"</string>
@@ -102,16 +102,11 @@
     <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"Wi-Fi har to bjælker."</string>
     <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"Wi-Fi har tre bjælker."</string>
     <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Wi-Fi-signal fuldt."</string>
-    <!-- no translation found for accessibility_no_wimax (4329180129727630368) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_one_bar (4170994299011863648) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_two_bars (9176236858336502288) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_three_bars (6116551636752103927) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_signal_full (2768089986795579558) -->
-    <skip />
+    <string name="accessibility_no_wimax" msgid="4329180129727630368">"Ingen WiMAX."</string>
+    <string name="accessibility_wimax_one_bar" msgid="4170994299011863648">"WiMAX en bjælke."</string>
+    <string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"WiMAX to bjælker."</string>
+    <string name="accessibility_wimax_three_bars" msgid="6116551636752103927">"WiMAX tre bjælker."</string>
+    <string name="accessibility_wimax_signal_full" msgid="2768089986795579558">"WiMAX-signal er fuldt."</string>
     <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
     <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
     <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
@@ -124,7 +119,7 @@
     <string name="accessibility_airplane_mode" msgid="834748999790763092">"Flytilstand."</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Batteri <xliff:g id="NUMBER">%d</xliff:g> procent."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Systemindstillinger."</string>
-    <string name="accessibility_notifications_button" msgid="4498000369779421892">"Meddelelser."</string>
+    <string name="accessibility_notifications_button" msgid="4498000369779421892">"Underretninger."</string>
     <string name="accessibility_remove_notification" msgid="3603099514902182350">"Ryd meddelelse."</string>
     <string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS aktiveret."</string>
     <string name="accessibility_gps_acquiring" msgid="8959333351058967158">"GPS samler data."</string>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 3e60475..dc1f1e3 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -102,16 +102,11 @@
     <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"WLAN, zwei Balken"</string>
     <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"WLAN, drei Balken"</string>
     <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Volle WLAN-Signalstärke"</string>
-    <!-- no translation found for accessibility_no_wimax (4329180129727630368) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_one_bar (4170994299011863648) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_two_bars (9176236858336502288) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_three_bars (6116551636752103927) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_signal_full (2768089986795579558) -->
-    <skip />
+    <string name="accessibility_no_wimax" msgid="4329180129727630368">"Kein WiMAX"</string>
+    <string name="accessibility_wimax_one_bar" msgid="4170994299011863648">"WiMAX - ein Balken"</string>
+    <string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"WiMAX - zwei Balken"</string>
+    <string name="accessibility_wimax_three_bars" msgid="6116551636752103927">"WiMAX - drei Balken"</string>
+    <string name="accessibility_wimax_signal_full" msgid="2768089986795579558">"Volle WiMAX-Signalstärke"</string>
     <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
     <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
     <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3,5G"</string>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index df0ee29..cc9dce1 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -102,16 +102,11 @@
     <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"Δύο γραμμές Wi-Fi."</string>
     <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"Τρεις γραμμές Wi-Fi."</string>
     <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Πλήρες σήμα WiFi."</string>
-    <!-- no translation found for accessibility_no_wimax (4329180129727630368) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_one_bar (4170994299011863648) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_two_bars (9176236858336502288) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_three_bars (6116551636752103927) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_signal_full (2768089986795579558) -->
-    <skip />
+    <string name="accessibility_no_wimax" msgid="4329180129727630368">"Δεν υπάρχει σήμα WiMAX."</string>
+    <string name="accessibility_wimax_one_bar" msgid="4170994299011863648">"Σήμα WiMAX μία γραμμή."</string>
+    <string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"Σήμα WiMAX δύο γραμμές."</string>
+    <string name="accessibility_wimax_three_bars" msgid="6116551636752103927">"Σήμα WiMAX τρεις γραμμές."</string>
+    <string name="accessibility_wimax_signal_full" msgid="2768089986795579558">"Πλήρες σήμα WiMAX."</string>
     <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
     <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
     <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index 4260c66..3c70b15 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -102,16 +102,11 @@
     <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"Wi-Fi two bars."</string>
     <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"Wi-Fi three bars."</string>
     <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Wi-Fi signal full."</string>
-    <!-- no translation found for accessibility_no_wimax (4329180129727630368) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_one_bar (4170994299011863648) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_two_bars (9176236858336502288) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_three_bars (6116551636752103927) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_signal_full (2768089986795579558) -->
-    <skip />
+    <string name="accessibility_no_wimax" msgid="4329180129727630368">"No WiMAX."</string>
+    <string name="accessibility_wimax_one_bar" msgid="4170994299011863648">"WiMAX one bar."</string>
+    <string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"WiMAX two bars."</string>
+    <string name="accessibility_wimax_three_bars" msgid="6116551636752103927">"WiMAX three bars."</string>
+    <string name="accessibility_wimax_signal_full" msgid="2768089986795579558">"WiMAX signal full."</string>
     <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
     <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
     <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 3d22cac..85818ae 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -102,16 +102,11 @@
     <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"Dos barras de señal Wi-Fi"</string>
     <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"Tres barras de señal Wi-Fi"</string>
     <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Señal de Wi-Fi completa"</string>
-    <!-- no translation found for accessibility_no_wimax (4329180129727630368) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_one_bar (4170994299011863648) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_two_bars (9176236858336502288) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_three_bars (6116551636752103927) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_signal_full (2768089986795579558) -->
-    <skip />
+    <string name="accessibility_no_wimax" msgid="4329180129727630368">"Sin conexión WiMAX"</string>
+    <string name="accessibility_wimax_one_bar" msgid="4170994299011863648">"Una barra de WiMAX"</string>
+    <string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"Dos barras de WiMAX"</string>
+    <string name="accessibility_wimax_three_bars" msgid="6116551636752103927">"Tres barras de WiMAX"</string>
+    <string name="accessibility_wimax_signal_full" msgid="2768089986795579558">"Señal de WiMAX al máximo"</string>
     <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
     <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
     <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3,5G"</string>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 2b9dd54..f0dcc23 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -102,16 +102,11 @@
     <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"Dos barras de Wi-Fi"</string>
     <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"Tres barras de Wi-Fi"</string>
     <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Señal de Wi-Fi al máximo"</string>
-    <!-- no translation found for accessibility_no_wimax (4329180129727630368) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_one_bar (4170994299011863648) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_two_bars (9176236858336502288) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_three_bars (6116551636752103927) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_signal_full (2768089986795579558) -->
-    <skip />
+    <string name="accessibility_no_wimax" msgid="4329180129727630368">"Sin conexión WiMAX"</string>
+    <string name="accessibility_wimax_one_bar" msgid="4170994299011863648">"Una barra de WiMAX"</string>
+    <string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"Dos barras de WiMAX"</string>
+    <string name="accessibility_wimax_three_bars" msgid="6116551636752103927">"Tres barras de WiMAX"</string>
+    <string name="accessibility_wimax_signal_full" msgid="2768089986795579558">"Señal de WiMAX al máximo"</string>
     <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
     <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
     <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5 G"</string>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index b17182f..91a8f64 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -102,16 +102,11 @@
     <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"Wi-Fi دو نوار دارد."</string>
     <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"Wi-Fi سه نوار دارد."</string>
     <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"قدرت سیگنال WiFi کامل است."</string>
-    <!-- no translation found for accessibility_no_wimax (4329180129727630368) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_one_bar (4170994299011863648) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_two_bars (9176236858336502288) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_three_bars (6116551636752103927) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_signal_full (2768089986795579558) -->
-    <skip />
+    <string name="accessibility_no_wimax" msgid="4329180129727630368">"WiMAX وجود ندارد."</string>
+    <string name="accessibility_wimax_one_bar" msgid="4170994299011863648">"WiMAX دارای یک نوار است."</string>
+    <string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"WiMAX دارای دو نوار است."</string>
+    <string name="accessibility_wimax_three_bars" msgid="6116551636752103927">"WiMAX دارای سه نوار است."</string>
+    <string name="accessibility_wimax_signal_full" msgid="2768089986795579558">"قدرت سیگنال WiMAX کامل است."</string>
     <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
     <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
     <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
@@ -143,6 +138,5 @@
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"جستجو برای GPS"</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"مکان تنظیم شده توسط GPS"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"پاک کردن تمام اعلان‌ها"</string>
-    <!-- no translation found for dreams_dock_launcher (3541196417659166245) -->
-    <skip />
+    <string name="dreams_dock_launcher" msgid="3541196417659166245">"فعال کردن محافظ صفحه نمایش"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index af42f59..cf9230c7 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -102,16 +102,11 @@
     <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"Wifi-signaali: kaksi palkkia."</string>
     <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"Wifi-signaali: kolme palkkia."</string>
     <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Vahva wifi-signaali."</string>
-    <!-- no translation found for accessibility_no_wimax (4329180129727630368) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_one_bar (4170994299011863648) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_two_bars (9176236858336502288) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_three_bars (6116551636752103927) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_signal_full (2768089986795579558) -->
-    <skip />
+    <string name="accessibility_no_wimax" msgid="4329180129727630368">"Ei WiMAX-yhteyttä."</string>
+    <string name="accessibility_wimax_one_bar" msgid="4170994299011863648">"WiMAX: yksi palkki."</string>
+    <string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"WiMAX: kaksi palkkia."</string>
+    <string name="accessibility_wimax_three_bars" msgid="6116551636752103927">"WiMAX: kolme palkkia."</string>
+    <string name="accessibility_wimax_signal_full" msgid="2768089986795579558">"Vahva WiMAX-signaali."</string>
     <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
     <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
     <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3,5G"</string>
@@ -143,6 +138,5 @@
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"Haetaan GPS-yhteyttä"</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Sijainti määritetty GPS:n avulla"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Tyhjennä kaikki ilmoitukset."</string>
-    <!-- no translation found for dreams_dock_launcher (3541196417659166245) -->
-    <skip />
+    <string name="dreams_dock_launcher" msgid="3541196417659166245">"Ota näytönsäästäjä käyttöön"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 3cda48c..d313517 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -102,16 +102,11 @@
     <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"Signal Wi-Fi faible"</string>
     <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"Signal Wi-Fi bon"</string>
     <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Signal Wi-Fi excellent"</string>
-    <!-- no translation found for accessibility_no_wimax (4329180129727630368) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_one_bar (4170994299011863648) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_two_bars (9176236858336502288) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_three_bars (6116551636752103927) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_signal_full (2768089986795579558) -->
-    <skip />
+    <string name="accessibility_no_wimax" msgid="4329180129727630368">"Aucun signal WiMAX"</string>
+    <string name="accessibility_wimax_one_bar" msgid="4170994299011863648">"Signal WiMAX : faible"</string>
+    <string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"Signal WiMAX : moyen"</string>
+    <string name="accessibility_wimax_three_bars" msgid="6116551636752103927">"Signal WiMAX : bon"</string>
+    <string name="accessibility_wimax_signal_full" msgid="2768089986795579558">"Signal WiMAX : excellent"</string>
     <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
     <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
     <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3G+"</string>
@@ -145,6 +140,5 @@
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"Recherche de GPS..."</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Position définie par GPS"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Supprimer toutes les notifications"</string>
-    <!-- no translation found for dreams_dock_launcher (3541196417659166245) -->
-    <skip />
+    <string name="dreams_dock_launcher" msgid="3541196417659166245">"Activer l\'économiseur d\'écran"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index 4bf8dcd..42b901c 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -87,7 +87,7 @@
     <string name="accessibility_battery_two_bars" msgid="8500650438735009973">"बैटरी दो बार."</string>
     <string name="accessibility_battery_three_bars" msgid="2302983330865040446">"बैटरी तीन बार."</string>
     <string name="accessibility_battery_full" msgid="8909122401720158582">"बैटरी पूर्ण."</string>
-    <string name="accessibility_no_phone" msgid="4894708937052611281">"कोई फ़ोन नहीं."</string>
+    <string name="accessibility_no_phone" msgid="4894708937052611281">"कोई फ़ोन नहीं."</string>
     <string name="accessibility_phone_one_bar" msgid="687699278132664115">"फ़ोन एक बार."</string>
     <string name="accessibility_phone_two_bars" msgid="8384905382804815201">"फ़ोन दो बार."</string>
     <string name="accessibility_phone_three_bars" msgid="8521904843919971885">"फोन तीन बार."</string>
@@ -102,16 +102,11 @@
     <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"Wi-Fi के दो बार."</string>
     <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"Wi-Fi के तीन बार."</string>
     <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"पूर्ण WiFi सि‍ग्‍नल."</string>
-    <!-- no translation found for accessibility_no_wimax (4329180129727630368) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_one_bar (4170994299011863648) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_two_bars (9176236858336502288) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_three_bars (6116551636752103927) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_signal_full (2768089986795579558) -->
-    <skip />
+    <string name="accessibility_no_wimax" msgid="4329180129727630368">"WiMAX नहीं."</string>
+    <string name="accessibility_wimax_one_bar" msgid="4170994299011863648">"WiMAX एक बार."</string>
+    <string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"WiMAX दो बार."</string>
+    <string name="accessibility_wimax_three_bars" msgid="6116551636752103927">"WiMAX तीन बार."</string>
+    <string name="accessibility_wimax_signal_full" msgid="2768089986795579558">"WiMAX सि‍ग्‍नल पूर्ण."</string>
     <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
     <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
     <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
@@ -143,6 +138,5 @@
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"GPS को खोजा जा रहा है"</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"GPS द्वारा सेट किया गया स्‍थान"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"सभी सूचनाएं साफ़ करें."</string>
-    <!-- no translation found for dreams_dock_launcher (3541196417659166245) -->
-    <skip />
+    <string name="dreams_dock_launcher" msgid="3541196417659166245">"स्‍क्रीन सेवर सक्रिय करें"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index f011abd..4e6d99c 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -102,16 +102,11 @@
     <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"Wi-Fi dvije crtice."</string>
     <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"Wi-Fi tri crtice."</string>
     <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"WiFi signal pun."</string>
-    <!-- no translation found for accessibility_no_wimax (4329180129727630368) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_one_bar (4170994299011863648) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_two_bars (9176236858336502288) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_three_bars (6116551636752103927) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_signal_full (2768089986795579558) -->
-    <skip />
+    <string name="accessibility_no_wimax" msgid="4329180129727630368">"Nema signala WiMAX."</string>
+    <string name="accessibility_wimax_one_bar" msgid="4170994299011863648">"WiMAX s jednim stupcem."</string>
+    <string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"WiMAX s dva stupca."</string>
+    <string name="accessibility_wimax_three_bars" msgid="6116551636752103927">"WiMAX s tri stupca."</string>
+    <string name="accessibility_wimax_signal_full" msgid="2768089986795579558">"Signal WiMAX potpun je."</string>
     <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
     <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
     <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
@@ -143,6 +138,5 @@
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"Traženje GPS-a"</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Lokaciju utvrdio GPS"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Brisanje svih obavijesti."</string>
-    <!-- no translation found for dreams_dock_launcher (3541196417659166245) -->
-    <skip />
+    <string name="dreams_dock_launcher" msgid="3541196417659166245">"Aktivirajte čuvar zaslona"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index ec61736..e710d50 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -102,16 +102,11 @@
     <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"Wi-Fi -- két sáv"</string>
     <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"Wi-Fi -- három sáv"</string>
     <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Wi-Fi jel teljes."</string>
-    <!-- no translation found for accessibility_no_wimax (4329180129727630368) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_one_bar (4170994299011863648) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_two_bars (9176236858336502288) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_three_bars (6116551636752103927) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_signal_full (2768089986795579558) -->
-    <skip />
+    <string name="accessibility_no_wimax" msgid="4329180129727630368">"Nincs WiMAX."</string>
+    <string name="accessibility_wimax_one_bar" msgid="4170994299011863648">"WiMAX-jel: egy sáv."</string>
+    <string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"WiMAX-jel: két sáv."</string>
+    <string name="accessibility_wimax_three_bars" msgid="6116551636752103927">"WiMAX-jel: három sáv."</string>
+    <string name="accessibility_wimax_signal_full" msgid="2768089986795579558">"WiMAX-jel: teljes."</string>
     <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
     <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
     <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index d89886e..a8b024d 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -102,16 +102,11 @@
     <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"Wi-Fi dua bilah."</string>
     <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"Wi-Fi tiga bilah."</string>
     <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Sinyal WiFi penuh."</string>
-    <!-- no translation found for accessibility_no_wimax (4329180129727630368) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_one_bar (4170994299011863648) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_two_bars (9176236858336502288) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_three_bars (6116551636752103927) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_signal_full (2768089986795579558) -->
-    <skip />
+    <string name="accessibility_no_wimax" msgid="4329180129727630368">"Tidak ada WiMAX."</string>
+    <string name="accessibility_wimax_one_bar" msgid="4170994299011863648">"WiMAX satu batang."</string>
+    <string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"WiMAX dua batang."</string>
+    <string name="accessibility_wimax_three_bars" msgid="6116551636752103927">"WiMAX tiga batang."</string>
+    <string name="accessibility_wimax_signal_full" msgid="2768089986795579558">"Sinyal WiMAX penuh."</string>
     <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
     <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
     <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
@@ -143,6 +138,5 @@
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"Menelusuri GPS"</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Lokasi yang disetel oleh GPS"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Menghapus semua pemberitahuan."</string>
-    <!-- no translation found for dreams_dock_launcher (3541196417659166245) -->
-    <skip />
+    <string name="dreams_dock_launcher" msgid="3541196417659166245">"Aktifkan tirai layar"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index c3e95f53..0119d5c 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -102,16 +102,11 @@
     <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"Wi-Fi: due barre."</string>
     <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"Wi-Fi: tre barre."</string>
     <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Massimo segnale Wi-Fi."</string>
-    <!-- no translation found for accessibility_no_wimax (4329180129727630368) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_one_bar (4170994299011863648) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_two_bars (9176236858336502288) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_three_bars (6116551636752103927) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_signal_full (2768089986795579558) -->
-    <skip />
+    <string name="accessibility_no_wimax" msgid="4329180129727630368">"Nessun segnale WiMAX."</string>
+    <string name="accessibility_wimax_one_bar" msgid="4170994299011863648">"WiMAX: una barra."</string>
+    <string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"WiMAX: due barre."</string>
+    <string name="accessibility_wimax_three_bars" msgid="6116551636752103927">"WiMAX: tre barre."</string>
+    <string name="accessibility_wimax_signal_full" msgid="2768089986795579558">"Massimo segnale WiMAX."</string>
     <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
     <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
     <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index 9605284..b6376c8 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -102,16 +102,11 @@
     <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"שני פסי Wi-Fi."</string>
     <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"שלושה פסי Wi-Fi."</string>
     <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"אות ה-WiFi מלא."</string>
-    <!-- no translation found for accessibility_no_wimax (4329180129727630368) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_one_bar (4170994299011863648) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_two_bars (9176236858336502288) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_three_bars (6116551636752103927) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_signal_full (2768089986795579558) -->
-    <skip />
+    <string name="accessibility_no_wimax" msgid="4329180129727630368">"ללא WiMAX."</string>
+    <string name="accessibility_wimax_one_bar" msgid="4170994299011863648">"פס אחד של WiMAX."</string>
+    <string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"שני פסים של WiMAX."</string>
+    <string name="accessibility_wimax_three_bars" msgid="6116551636752103927">"שלושה פסים של WiMAX."</string>
+    <string name="accessibility_wimax_signal_full" msgid="2768089986795579558">"אות ה-WiMAX מלא."</string>
     <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
     <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
     <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index e113c72..d9c9aa2 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -102,16 +102,11 @@
     <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"Wi-Fi電波: レベル2"</string>
     <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"Wi-Fi電波: レベル3"</string>
     <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Wi-Fi電波:フル"</string>
-    <!-- no translation found for accessibility_no_wimax (4329180129727630368) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_one_bar (4170994299011863648) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_two_bars (9176236858336502288) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_three_bars (6116551636752103927) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_signal_full (2768089986795579558) -->
-    <skip />
+    <string name="accessibility_no_wimax" msgid="4329180129727630368">"WiMAX電波状態:圏外"</string>
+    <string name="accessibility_wimax_one_bar" msgid="4170994299011863648">"WiMAX電波状態:レベル1"</string>
+    <string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"WiMAX電波状態:レベル2"</string>
+    <string name="accessibility_wimax_three_bars" msgid="6116551636752103927">"WiMAX電波状態:レベル3"</string>
+    <string name="accessibility_wimax_signal_full" msgid="2768089986795579558">"WiMAX電波状態:フル"</string>
     <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
     <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
     <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
@@ -145,6 +140,5 @@
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"GPSで検索中"</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"GPSにより現在地が設定されました"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"通知をすべて消去。"</string>
-    <!-- no translation found for dreams_dock_launcher (3541196417659166245) -->
-    <skip />
+    <string name="dreams_dock_launcher" msgid="3541196417659166245">"スクリーンセーバーを有効にする"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index 5661dc0..79569c5 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -102,16 +102,11 @@
     <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"Wi-Fi 신호 막대가 두 개입니다."</string>
     <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"Wi-Fi 신호 막대가 세 개입니다."</string>
     <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"WiFi 신호가 강합니다."</string>
-    <!-- no translation found for accessibility_no_wimax (4329180129727630368) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_one_bar (4170994299011863648) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_two_bars (9176236858336502288) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_three_bars (6116551636752103927) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_signal_full (2768089986795579558) -->
-    <skip />
+    <string name="accessibility_no_wimax" msgid="4329180129727630368">"WiMAX가 없습니다."</string>
+    <string name="accessibility_wimax_one_bar" msgid="4170994299011863648">"WiMAX 신호 막대가 하나입니다."</string>
+    <string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"WiMAX 신호 막대가 두 개입니다."</string>
+    <string name="accessibility_wimax_three_bars" msgid="6116551636752103927">"WiMAX 신호 막대가 세 개입니다."</string>
+    <string name="accessibility_wimax_signal_full" msgid="2768089986795579558">"WiMAX 신호가 강합니다."</string>
     <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
     <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
     <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
@@ -143,6 +138,5 @@
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"GPS 검색 중"</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"GPS에서 위치 설정"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"모든 알림 지우기"</string>
-    <!-- no translation found for dreams_dock_launcher (3541196417659166245) -->
-    <skip />
+    <string name="dreams_dock_launcher" msgid="3541196417659166245">"스크린 세이버 활성화"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index a8e7134..490bd4a 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -102,16 +102,11 @@
     <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"Dvi „Wi-Fi“ signalo juostos."</string>
     <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"Trys „Wi-Fi“ signalo juostos."</string>
     <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"„Wi-Fi“ signalas stiprus."</string>
-    <!-- no translation found for accessibility_no_wimax (4329180129727630368) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_one_bar (4170994299011863648) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_two_bars (9176236858336502288) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_three_bars (6116551636752103927) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_signal_full (2768089986795579558) -->
-    <skip />
+    <string name="accessibility_no_wimax" msgid="4329180129727630368">"Nėra „WiMAX“ signalo."</string>
+    <string name="accessibility_wimax_one_bar" msgid="4170994299011863648">"Viena „WiMAX“ signalo juosta."</string>
+    <string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"Dvi „WiMAX“ signalo juostos."</string>
+    <string name="accessibility_wimax_three_bars" msgid="6116551636752103927">"Trys „WiMAX“ signalo juostos."</string>
+    <string name="accessibility_wimax_signal_full" msgid="2768089986795579558">"„WiMAX“ signalas stiprus."</string>
     <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
     <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
     <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
@@ -143,6 +138,5 @@
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"Ieškoma GPS"</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"GPS nustatyta vieta"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Išvalyti visus pranešimus."</string>
-    <!-- no translation found for dreams_dock_launcher (3541196417659166245) -->
-    <skip />
+    <string name="dreams_dock_launcher" msgid="3541196417659166245">"Aktyvinti ekrano užsklandą"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index ae46dc2..62e99ee 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -102,16 +102,11 @@
     <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"Wi-Fi: divas joslas."</string>
     <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"Wi-Fi: trīs joslas."</string>
     <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Pilna piekļuve Wi-Fi signālam"</string>
-    <!-- no translation found for accessibility_no_wimax (4329180129727630368) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_one_bar (4170994299011863648) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_two_bars (9176236858336502288) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_three_bars (6116551636752103927) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_signal_full (2768089986795579558) -->
-    <skip />
+    <string name="accessibility_no_wimax" msgid="4329180129727630368">"Bez WiMAX."</string>
+    <string name="accessibility_wimax_one_bar" msgid="4170994299011863648">"WiMAX viena josla."</string>
+    <string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"WiMAX divas joslas."</string>
+    <string name="accessibility_wimax_three_bars" msgid="6116551636752103927">"WiMAX trīs joslas."</string>
+    <string name="accessibility_wimax_signal_full" msgid="2768089986795579558">"WiMAX signāls pilns."</string>
     <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
     <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
     <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
@@ -143,6 +138,5 @@
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"Notiek GPS meklēšana..."</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"GPS iestatītā atrašanās vieta"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Notīrīt visus paziņojumus"</string>
-    <!-- no translation found for dreams_dock_launcher (3541196417659166245) -->
-    <skip />
+    <string name="dreams_dock_launcher" msgid="3541196417659166245">"Aktivizēt ekrānsaudzētāju"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index 5c11c88..5f64f7b 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -102,16 +102,11 @@
     <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"Dua bar Wi-Fi."</string>
     <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"Tiga bar Wi-Fi."</string>
     <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Isyarat WiFi penuh."</string>
-    <!-- no translation found for accessibility_no_wimax (4329180129727630368) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_one_bar (4170994299011863648) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_two_bars (9176236858336502288) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_three_bars (6116551636752103927) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_signal_full (2768089986795579558) -->
-    <skip />
+    <string name="accessibility_no_wimax" msgid="4329180129727630368">"Tiada WiMAX"</string>
+    <string name="accessibility_wimax_one_bar" msgid="4170994299011863648">"WiMAX satu bar."</string>
+    <string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"WiMAX dua bar."</string>
+    <string name="accessibility_wimax_three_bars" msgid="6116551636752103927">"WiMAX tiga bar."</string>
+    <string name="accessibility_wimax_signal_full" msgid="2768089986795579558">"Isyarat WiMAX penuh."</string>
     <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
     <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
     <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
@@ -143,6 +138,5 @@
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"Mencari GPS"</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Lokasi ditetapkan oleh GPS"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Padamkan semua pemberitahuan."</string>
-    <!-- no translation found for dreams_dock_launcher (3541196417659166245) -->
-    <skip />
+    <string name="dreams_dock_launcher" msgid="3541196417659166245">"Aktifkan gambar skrin"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index bbc321d..b90876a 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -102,16 +102,11 @@
     <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"Dekningssignal for Wi-Fi med to stolper."</string>
     <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"Dekningssignal for Wi-Fi med tre stolper."</string>
     <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Wi-Fi-signal er fullt."</string>
-    <!-- no translation found for accessibility_no_wimax (4329180129727630368) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_one_bar (4170994299011863648) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_two_bars (9176236858336502288) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_three_bars (6116551636752103927) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_signal_full (2768089986795579558) -->
-    <skip />
+    <string name="accessibility_no_wimax" msgid="4329180129727630368">"Ingen WiMAX."</string>
+    <string name="accessibility_wimax_one_bar" msgid="4170994299011863648">"WiMAX – én stolpe."</string>
+    <string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"WiMAX – to stolper."</string>
+    <string name="accessibility_wimax_three_bars" msgid="6116551636752103927">"WiMAX – tre stolper."</string>
+    <string name="accessibility_wimax_signal_full" msgid="2768089986795579558">"Fullt WiMAX-signal."</string>
     <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
     <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
     <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3,5G"</string>
@@ -143,5 +138,5 @@
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"Søker etter GPS"</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Posisjon angitt av GPS"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Fjern alle varslinger."</string>
-    <string name="dreams_dock_launcher" msgid="3541196417659166245">"Aktivér skjermbeskytter"</string>
+    <string name="dreams_dock_launcher" msgid="3541196417659166245">"Aktiver skjermbeskytter"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 16e4ead..cf85c75 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -102,16 +102,11 @@
     <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"Wifi: twee streepjes."</string>
     <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"Wifi: drie streepjes."</string>
     <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Wi-Fi-signaal is op volledige sterkte."</string>
-    <!-- no translation found for accessibility_no_wimax (4329180129727630368) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_one_bar (4170994299011863648) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_two_bars (9176236858336502288) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_three_bars (6116551636752103927) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_signal_full (2768089986795579558) -->
-    <skip />
+    <string name="accessibility_no_wimax" msgid="4329180129727630368">"Geen WiMAX."</string>
+    <string name="accessibility_wimax_one_bar" msgid="4170994299011863648">"WiMAX: één streepje."</string>
+    <string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"WiMAX: twee streepjes."</string>
+    <string name="accessibility_wimax_three_bars" msgid="6116551636752103927">"WiMAX: drie streepjes."</string>
+    <string name="accessibility_wimax_signal_full" msgid="2768089986795579558">"WiMAX-signaal  is op volle sterkte."</string>
     <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
     <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
     <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
@@ -143,6 +138,5 @@
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"Zoeken naar GPS"</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Locatie bepaald met GPS"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Alle meldingen wissen."</string>
-    <!-- no translation found for dreams_dock_launcher (3541196417659166245) -->
-    <skip />
+    <string name="dreams_dock_launcher" msgid="3541196417659166245">"Schermbeveiliging inschakelen"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index c3a6636..c65f99e 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -102,16 +102,11 @@
     <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"Wi-Fi dwa paski."</string>
     <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"Wi-Fi trzy paski."</string>
     <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Sieć Wi-Fi: pełna moc sygnału."</string>
-    <!-- no translation found for accessibility_no_wimax (4329180129727630368) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_one_bar (4170994299011863648) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_two_bars (9176236858336502288) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_three_bars (6116551636752103927) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_signal_full (2768089986795579558) -->
-    <skip />
+    <string name="accessibility_no_wimax" msgid="4329180129727630368">"WiMAX: brak"</string>
+    <string name="accessibility_wimax_one_bar" msgid="4170994299011863648">"WiMAX: jeden pasek"</string>
+    <string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"WiMAX: dwa paski"</string>
+    <string name="accessibility_wimax_three_bars" msgid="6116551636752103927">"WiMAX: trzy paski"</string>
+    <string name="accessibility_wimax_signal_full" msgid="2768089986795579558">"WiMAX: pełna moc sygnału"</string>
     <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
     <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
     <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
@@ -143,6 +138,5 @@
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"Wyszukiwanie sygnału GPS"</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Lokalizacja ustawiona według GPS"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Usuń wszystkie powiadomienia."</string>
-    <!-- no translation found for dreams_dock_launcher (3541196417659166245) -->
-    <skip />
+    <string name="dreams_dock_launcher" msgid="3541196417659166245">"Włącz wygaszacz ekranu."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index 4014a1d..e1340ec 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -102,16 +102,11 @@
     <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"Duas barras de Wi-Fi."</string>
     <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"Três barras de Wi-Fi."</string>
     <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Sinal Wi-Fi completo."</string>
-    <!-- no translation found for accessibility_no_wimax (4329180129727630368) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_one_bar (4170994299011863648) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_two_bars (9176236858336502288) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_three_bars (6116551636752103927) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_signal_full (2768089986795579558) -->
-    <skip />
+    <string name="accessibility_no_wimax" msgid="4329180129727630368">"Sem WiMAX."</string>
+    <string name="accessibility_wimax_one_bar" msgid="4170994299011863648">"Uma barra de WiMAX."</string>
+    <string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"Duas barras de WiMAX."</string>
+    <string name="accessibility_wimax_three_bars" msgid="6116551636752103927">"Três barras de WiMAX."</string>
+    <string name="accessibility_wimax_signal_full" msgid="2768089986795579558">"Sinal WiMAX completo."</string>
     <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
     <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
     <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3,5G"</string>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index ec5e1d4..545d54e 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -102,16 +102,11 @@
     <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"Duas barras de Wi-Fi."</string>
     <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"Três barras de Wi-Fi."</string>
     <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Sinal do Wi-Fi cheio."</string>
-    <!-- no translation found for accessibility_no_wimax (4329180129727630368) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_one_bar (4170994299011863648) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_two_bars (9176236858336502288) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_three_bars (6116551636752103927) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_signal_full (2768089986795579558) -->
-    <skip />
+    <string name="accessibility_no_wimax" msgid="4329180129727630368">"Sem WiMAX."</string>
+    <string name="accessibility_wimax_one_bar" msgid="4170994299011863648">"Uma barra do WiMAX."</string>
+    <string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"Duas barras do WiMAX."</string>
+    <string name="accessibility_wimax_three_bars" msgid="6116551636752103927">"Três barras do WiMAX."</string>
+    <string name="accessibility_wimax_signal_full" msgid="2768089986795579558">"Sinal WiMAX completo."</string>
     <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
     <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
     <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 2a0451f..e4c55d6 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -102,16 +102,11 @@
     <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"Wi-Fi două bare."</string>
     <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"Wi-Fi trei bare."</string>
     <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Semnal Wi-Fi: complet."</string>
-    <!-- no translation found for accessibility_no_wimax (4329180129727630368) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_one_bar (4170994299011863648) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_two_bars (9176236858336502288) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_three_bars (6116551636752103927) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_signal_full (2768089986795579558) -->
-    <skip />
+    <string name="accessibility_no_wimax" msgid="4329180129727630368">"Fără WiMAX."</string>
+    <string name="accessibility_wimax_one_bar" msgid="4170994299011863648">"WiMAX o bară."</string>
+    <string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"WiMAX două bare."</string>
+    <string name="accessibility_wimax_three_bars" msgid="6116551636752103927">"WiMAX trei bare."</string>
+    <string name="accessibility_wimax_signal_full" msgid="2768089986795579558">"WiMAX semnal complet."</string>
     <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
     <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
     <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
@@ -143,5 +138,5 @@
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"Se caută GPS"</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Locaţie setată prin GPS"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Ştergeţi toate notificările."</string>
-    <string name="dreams_dock_launcher" msgid="3541196417659166245">"Activaţi economizorul de ecran"</string>
+    <string name="dreams_dock_launcher" msgid="3541196417659166245">"Activaţi screensaverul"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index c75a756..17330b1 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -102,16 +102,11 @@
     <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"Wi-Fi: два деления."</string>
     <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"Wi-Fi: три деления."</string>
     <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Надежный сигнал Wi-Fi."</string>
-    <!-- no translation found for accessibility_no_wimax (4329180129727630368) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_one_bar (4170994299011863648) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_two_bars (9176236858336502288) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_three_bars (6116551636752103927) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_signal_full (2768089986795579558) -->
-    <skip />
+    <string name="accessibility_no_wimax" msgid="4329180129727630368">"Нет сигнала WiMAX."</string>
+    <string name="accessibility_wimax_one_bar" msgid="4170994299011863648">"Сигнал WiMAX: одно деление."</string>
+    <string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"Сигнал WiMAX: два деления."</string>
+    <string name="accessibility_wimax_three_bars" msgid="6116551636752103927">"Сигнал WiMAX: три деления."</string>
+    <string name="accessibility_wimax_signal_full" msgid="2768089986795579558">"Надежный сигнал WiMAX."</string>
     <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
     <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
     <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3,5G"</string>
@@ -136,7 +131,7 @@
     <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"Приложение \"<xliff:g id="APP">%s</xliff:g>\" удалено из списка."</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"Передача данных по каналам 2G и 3G отключена"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Передача данных по каналу 4G отключена"</string>
-    <string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Мобильный Интернет отключен"</string>
+    <string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Моб. Интернет отключен"</string>
     <string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Передача данных отключена"</string>
     <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Достигнут лимит трафика."\n\n"При восстановлении подключения оператор может взимать плату за передачу данных."</string>
     <string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Восстановить подключение"</string>
@@ -145,6 +140,5 @@
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"Поиск GPS"</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Местоположение установлено с помощью GPS"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Удалить все уведомления"</string>
-    <!-- no translation found for dreams_dock_launcher (3541196417659166245) -->
-    <skip />
+    <string name="dreams_dock_launcher" msgid="3541196417659166245">"Активация заставки экрана"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index 06cce27..f0ec8ff 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -102,16 +102,11 @@
     <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"Dve čiarky signálu Wi-Fi."</string>
     <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"Tri čiarky signálu Wi-Fi."</string>
     <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Plný signál siete Wi-Fi."</string>
-    <!-- no translation found for accessibility_no_wimax (4329180129727630368) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_one_bar (4170994299011863648) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_two_bars (9176236858336502288) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_three_bars (6116551636752103927) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_signal_full (2768089986795579558) -->
-    <skip />
+    <string name="accessibility_no_wimax" msgid="4329180129727630368">"Žiadna sieť WiMAX."</string>
+    <string name="accessibility_wimax_one_bar" msgid="4170994299011863648">"Jeden stĺpec signálu siete WiMAX."</string>
+    <string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"Dva stĺpce signálu siete WiMAX."</string>
+    <string name="accessibility_wimax_three_bars" msgid="6116551636752103927">"Tri stĺpce signálu siete WiMAX."</string>
+    <string name="accessibility_wimax_signal_full" msgid="2768089986795579558">"Plný signál siete WiMAX."</string>
     <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
     <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
     <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index 32c9333..61b82c9 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -102,16 +102,11 @@
     <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"Dve črtici signala Wi-Fi."</string>
     <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"Tri črtice signala Wi-Fi."</string>
     <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Signal Wi-Fi poln."</string>
-    <!-- no translation found for accessibility_no_wimax (4329180129727630368) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_one_bar (4170994299011863648) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_two_bars (9176236858336502288) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_three_bars (6116551636752103927) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_signal_full (2768089986795579558) -->
-    <skip />
+    <string name="accessibility_no_wimax" msgid="4329180129727630368">"Ni signala WiMAX."</string>
+    <string name="accessibility_wimax_one_bar" msgid="4170994299011863648">"Signal WiMAX: ena črtica."</string>
+    <string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"Signal WiMAX: dve črtici."</string>
+    <string name="accessibility_wimax_three_bars" msgid="6116551636752103927">"Signal WiMAX: tri črtice."</string>
+    <string name="accessibility_wimax_signal_full" msgid="2768089986795579558">"Poln signal WiMAX."</string>
     <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
     <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
     <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index 378e3dc..f341fba 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -102,16 +102,11 @@
     <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"Wi-Fi сигнал има две црте."</string>
     <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"Wi-Fi сигнал има три црте."</string>
     <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"WiFi сигнал је најјачи."</string>
-    <!-- no translation found for accessibility_no_wimax (4329180129727630368) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_one_bar (4170994299011863648) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_two_bars (9176236858336502288) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_three_bars (6116551636752103927) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_signal_full (2768089986795579558) -->
-    <skip />
+    <string name="accessibility_no_wimax" msgid="4329180129727630368">"Нема WiMAX сигнала."</string>
+    <string name="accessibility_wimax_one_bar" msgid="4170994299011863648">"WiMAX сигнал има једну црту."</string>
+    <string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"WiMAX сигнал има две црте."</string>
+    <string name="accessibility_wimax_three_bars" msgid="6116551636752103927">"WiMAX сигнал има три црте."</string>
+    <string name="accessibility_wimax_signal_full" msgid="2768089986795579558">"WiMAX сигнал је најјачи."</string>
     <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
     <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
     <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
@@ -143,6 +138,5 @@
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"Тражи се GPS"</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Локацију је подесио GPS"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Обриши сва обавештења."</string>
-    <!-- no translation found for dreams_dock_launcher (3541196417659166245) -->
-    <skip />
+    <string name="dreams_dock_launcher" msgid="3541196417659166245">"Активирање чувара екрана"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index 93fbbad..f8fb054 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -102,16 +102,11 @@
     <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"Wi-Fi: två staplar."</string>
     <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"Wi-Fi: tre staplar."</string>
     <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Wi-Fi-signalen är full."</string>
-    <!-- no translation found for accessibility_no_wimax (4329180129727630368) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_one_bar (4170994299011863648) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_two_bars (9176236858336502288) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_three_bars (6116551636752103927) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_signal_full (2768089986795579558) -->
-    <skip />
+    <string name="accessibility_no_wimax" msgid="4329180129727630368">"Ingen WiMAX."</string>
+    <string name="accessibility_wimax_one_bar" msgid="4170994299011863648">"WiMAX: en stapel."</string>
+    <string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"WiMAX: två staplar."</string>
+    <string name="accessibility_wimax_three_bars" msgid="6116551636752103927">"WiMAX: tre staplar."</string>
+    <string name="accessibility_wimax_signal_full" msgid="2768089986795579558">"WiMAX-signalen är full."</string>
     <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
     <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
     <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 60f8e69..3843ea9 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -26,7 +26,7 @@
     <string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Ondoa kwenye orodha"</string>
     <string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"Taarifa za programu-matumizi"</string>
     <string name="status_bar_no_recent_apps" msgid="6576392951053994640">"Hakuna programu za sasa"</string>
-    <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Ondosha prog za hivi karibuni"</string>
+    <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Ondosha programu za hivi karibuni"</string>
     <!-- String.format failed for translation -->
     <!-- no translation found for status_bar_accessibility_recent_apps:other (1040784359794890744) -->
     <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Hakuna arifa"</string>
@@ -100,16 +100,11 @@
     <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"Miambaa miwili ya Wi-Fi."</string>
     <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"Miamba tatu ya Wi-Fi."</string>
     <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Ishara ya Mtandao hewa imejaa"</string>
-    <!-- no translation found for accessibility_no_wimax (4329180129727630368) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_one_bar (4170994299011863648) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_two_bars (9176236858336502288) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_three_bars (6116551636752103927) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_signal_full (2768089986795579558) -->
-    <skip />
+    <string name="accessibility_no_wimax" msgid="4329180129727630368">"Hakuna WiMAX."</string>
+    <string name="accessibility_wimax_one_bar" msgid="4170994299011863648">"Pau moja ya WiMAX."</string>
+    <string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"Pau mbili za WiMAX."</string>
+    <string name="accessibility_wimax_three_bars" msgid="6116551636752103927">"Pau tatu za WiMAX."</string>
+    <string name="accessibility_wimax_signal_full" msgid="2768089986795579558">"Ishara ya WiMAX imejaa."</string>
     <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
     <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
     <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
@@ -141,6 +136,5 @@
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"Inatafuta GPS"</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Mahali pamewekwa na GPS"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Futa arifa zote."</string>
-    <!-- no translation found for dreams_dock_launcher (3541196417659166245) -->
-    <skip />
+    <string name="dreams_dock_launcher" msgid="3541196417659166245">"Amilisha hifadhi ya skrini"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index eba914a..3f37060 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -102,16 +102,11 @@
     <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"สัญญาณ WiFi สองขีด"</string>
     <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"สัญญาณ WiFi สามขีด"</string>
     <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"สัญญาณ WiFi เต็ม"</string>
-    <!-- no translation found for accessibility_no_wimax (4329180129727630368) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_one_bar (4170994299011863648) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_two_bars (9176236858336502288) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_three_bars (6116551636752103927) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_signal_full (2768089986795579558) -->
-    <skip />
+    <string name="accessibility_no_wimax" msgid="4329180129727630368">"ไม่มีสัญญาณ WiMAX"</string>
+    <string name="accessibility_wimax_one_bar" msgid="4170994299011863648">"สัญญาณ WiMAX หนึ่งขีด"</string>
+    <string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"สัญญาณ WiMAX สองขีด"</string>
+    <string name="accessibility_wimax_three_bars" msgid="6116551636752103927">"สัญญาณ WiMAX สามขีด"</string>
+    <string name="accessibility_wimax_signal_full" msgid="2768089986795579558">"สัญญาณ WiMAX เต็ม"</string>
     <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
     <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
     <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
@@ -143,6 +138,5 @@
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"กำลังค้นหา GPS"</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"ตำแหน่งที่กำหนดโดย GPS"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"ล้างการแจ้งเตือนทั้งหมด"</string>
-    <!-- no translation found for dreams_dock_launcher (3541196417659166245) -->
-    <skip />
+    <string name="dreams_dock_launcher" msgid="3541196417659166245">"เปิดโปรแกรมรักษาหน้าจอ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index ab56c1e..807d797 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -102,16 +102,11 @@
     <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"Dalawang bar ang Wi-Fi."</string>
     <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"Tatlong bar ang Wi-Fi."</string>
     <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Puno ang signal ng WiFi."</string>
-    <!-- no translation found for accessibility_no_wimax (4329180129727630368) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_one_bar (4170994299011863648) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_two_bars (9176236858336502288) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_three_bars (6116551636752103927) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_signal_full (2768089986795579558) -->
-    <skip />
+    <string name="accessibility_no_wimax" msgid="4329180129727630368">"Walang WiMAX."</string>
+    <string name="accessibility_wimax_one_bar" msgid="4170994299011863648">"WiMAX na isang bar."</string>
+    <string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"WiMAX na dalawang bar."</string>
+    <string name="accessibility_wimax_three_bars" msgid="6116551636752103927">"WiMAX na tatlong bar."</string>
+    <string name="accessibility_wimax_signal_full" msgid="2768089986795579558">"Puno ang signal ng WiMAX."</string>
     <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
     <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
     <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index 5f1ca91..83567ae 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -102,16 +102,11 @@
     <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"Kablosuz sinyal gücü iki çubuk."</string>
     <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"Kablosuz sinyal gücü üç çubuk."</string>
     <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Kablosuz sinyali tam."</string>
-    <!-- no translation found for accessibility_no_wimax (4329180129727630368) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_one_bar (4170994299011863648) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_two_bars (9176236858336502288) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_three_bars (6116551636752103927) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_signal_full (2768089986795579558) -->
-    <skip />
+    <string name="accessibility_no_wimax" msgid="4329180129727630368">"WiMAX yok."</string>
+    <string name="accessibility_wimax_one_bar" msgid="4170994299011863648">"WiMAX tek çubuk."</string>
+    <string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"WiMAX iki çubuk."</string>
+    <string name="accessibility_wimax_three_bars" msgid="6116551636752103927">"WiMAX üç çubuk."</string>
+    <string name="accessibility_wimax_signal_full" msgid="2768089986795579558">"WiMAX sinyali tam."</string>
     <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
     <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
     <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
@@ -143,6 +138,5 @@
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"GPS aranıyor"</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Konum GPS ile belirlendi"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Tüm bildirimleri temizle"</string>
-    <!-- no translation found for dreams_dock_launcher (3541196417659166245) -->
-    <skip />
+    <string name="dreams_dock_launcher" msgid="3541196417659166245">"Ekran koruyucuyu etkinleştir"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 7e32dbd..bec231a 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -102,16 +102,11 @@
     <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"Дві смужки сигналу Wi-Fi."</string>
     <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"Три смужки сигналу Wi-Fi."</string>
     <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Максимальний сигнал Wi-Fi."</string>
-    <!-- no translation found for accessibility_no_wimax (4329180129727630368) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_one_bar (4170994299011863648) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_two_bars (9176236858336502288) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_three_bars (6116551636752103927) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_signal_full (2768089986795579558) -->
-    <skip />
+    <string name="accessibility_no_wimax" msgid="4329180129727630368">"Немає сигналу WiMAX."</string>
+    <string name="accessibility_wimax_one_bar" msgid="4170994299011863648">"Одна смужка сигналу WiMAX."</string>
+    <string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"Дві смужки сигналу WiMAX."</string>
+    <string name="accessibility_wimax_three_bars" msgid="6116551636752103927">"Три смужки сигналу WiMAX."</string>
+    <string name="accessibility_wimax_signal_full" msgid="2768089986795579558">"Максимальний сигнал WiMAX."</string>
     <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
     <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
     <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
@@ -143,6 +138,5 @@
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"Виконується пошук GPS-сигналу"</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Місцезнаходження встановлено за допомогою GPS"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Очистити всі сповіщення."</string>
-    <!-- no translation found for dreams_dock_launcher (3541196417659166245) -->
-    <skip />
+    <string name="dreams_dock_launcher" msgid="3541196417659166245">"Активувати заставку"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 43d7826..34b84af 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -20,7 +20,7 @@
 <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="7164937344850004466">"Giao diện người dùng hệ thống"</string>
-    <string name="status_bar_clear_all_button" msgid="7774721344716731603">"Xoá"</string>
+    <string name="status_bar_clear_all_button" msgid="7774721344716731603">"Xóa"</string>
     <string name="status_bar_do_not_disturb_button" msgid="5812628897510997853">"Không làm phiền"</string>
     <string name="status_bar_please_disturb_button" msgid="3345398298841572813">"Hiển thị thông báo"</string>
     <string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Xóa khỏi danh sách"</string>
@@ -49,8 +49,8 @@
     <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth được dùng làm điểm truy cập Internet"</string>
     <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Thiết lập phương thức nhập"</string>
     <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Sử dụng bàn phím vật lý"</string>
-    <string name="usb_device_permission_prompt" msgid="834698001271562057">"Cho phép ứng dụng <xliff:g id="APPLICATION">%1$s</xliff:g> truy cập thiết bị USB?"</string>
-    <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"Cho phép ứng dụng <xliff:g id="APPLICATION">%1$s</xliff:g> truy cập phụ kiện USB?"</string>
+    <string name="usb_device_permission_prompt" msgid="834698001271562057">"Cho phép ứng dụng <xliff:g id="APPLICATION">%1$s</xliff:g> truy cập thiết bị USB?"</string>
+    <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"Cho phép ứng dụng <xliff:g id="APPLICATION">%1$s</xliff:g> truy cập phụ kiện USB?"</string>
     <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Mở <xliff:g id="ACTIVITY">%1$s</xliff:g> khi thiết bị USB này được kết nối?"</string>
     <string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"Mở <xliff:g id="ACTIVITY">%1$s</xliff:g> khi phụ kiện USB này được kết nối?"</string>
     <string name="usb_accessory_uri_prompt" msgid="513450621413733343">"Không có ứng dụng được cài đặt nào hoạt động với phụ kiện USB này. Tìm hiểu thêm về phụ kiện này tại <xliff:g id="URL">%1$s</xliff:g>"</string>
@@ -67,8 +67,8 @@
     <string name="screenshot_saving_text" msgid="2419718443411738818">"Ảnh chụp màn hình đang được lưu."</string>
     <string name="screenshot_saved_title" msgid="6461865960961414961">"Đã chụp ảnh màn hình."</string>
     <string name="screenshot_saved_text" msgid="1152839647677558815">"Chạm để xem ảnh chụp màn hình của bạn."</string>
-    <string name="screenshot_failed_title" msgid="705781116746922771">"Không thể chụp ảnh màn hình."</string>
-    <string name="screenshot_failed_text" msgid="8134011269572415402">"Không thể lưu ảnh chụp màn hình. Bộ lưu trữ có thể đang được sử dụng."</string>
+    <string name="screenshot_failed_title" msgid="705781116746922771">"Không thể chụp ảnh màn hình."</string>
+    <string name="screenshot_failed_text" msgid="8134011269572415402">"Không thể lưu ảnh chụp màn hình. Bộ lưu trữ có thể đang được sử dụng."</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"Tùy chọn truyền tệp USB"</string>
     <string name="use_mtp_button_title" msgid="4333504413563023626">"Gắn như một trình phát đa phương tiện (MTP)"</string>
     <string name="use_ptp_button_title" msgid="7517127540301625751">"Gắn như một máy ảnh (PTP)"</string>
@@ -97,21 +97,16 @@
     <string name="accessibility_data_two_bars" msgid="6166018492360432091">"Tín hiệu dữ liệu hai vạch."</string>
     <string name="accessibility_data_three_bars" msgid="9167670452395038520">"Tín hiệu dữ liệu ba vạch."</string>
     <string name="accessibility_data_signal_full" msgid="2708384608124519369">"Tín hiệu dữ liệu đầy đủ."</string>
-    <string name="accessibility_no_wifi" msgid="7455607460517331976">"Không có Wi-Fi."</string>
-    <string name="accessibility_wifi_one_bar" msgid="6854947280074467207">"Wi-Fi một vạch."</string>
-    <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"Wi-Fi hai vạch."</string>
-    <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"Wi-Fi ba vạch."</string>
+    <string name="accessibility_no_wifi" msgid="7455607460517331976">"Không có Wi-Fi."</string>
+    <string name="accessibility_wifi_one_bar" msgid="6854947280074467207">"Wi-Fi một vạch."</string>
+    <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"Wi-Fi hai vạch."</string>
+    <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"Wi-Fi ba vạch."</string>
     <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"Tín hiệu WiFi đầy đủ."</string>
-    <!-- no translation found for accessibility_no_wimax (4329180129727630368) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_one_bar (4170994299011863648) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_two_bars (9176236858336502288) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_three_bars (6116551636752103927) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_signal_full (2768089986795579558) -->
-    <skip />
+    <string name="accessibility_no_wimax" msgid="4329180129727630368">"Không có WiMAX."</string>
+    <string name="accessibility_wimax_one_bar" msgid="4170994299011863648">"WiMAX một vạch."</string>
+    <string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"WiMAX hai vạch."</string>
+    <string name="accessibility_wimax_three_bars" msgid="6116551636752103927">"WiMAX ba vạch."</string>
+    <string name="accessibility_wimax_signal_full" msgid="2768089986795579558">"Tín hiệu WiMAX đầy đủ."</string>
     <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
     <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
     <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3,5G"</string>
@@ -136,7 +131,7 @@
     <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Đã tắt dữ liệu 4G"</string>
     <string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Dữ liệu di động bị vô hiệu hóa"</string>
     <string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Dữ liệu đã bị vô hiệu hóa"</string>
-    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Bạn đã đạt đến giới hạn sử dụng dữ liệu chỉ định."\n\n"Nếu bạn bật lại dữ liệu, bạn có thể bị nhà cung cấp tính phí."</string>
+    <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Bạn đã đạt đến giới hạn sử dụng dữ liệu chỉ định."\n\n"Nếu bạn bật lại dữ liệu, bạn có thể bị nhà cung cấp tính phí."</string>
     <string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Bật lại dữ liệu"</string>
     <string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Ko có k.nối Internet"</string>
     <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Đã kết nối Wi-Fi"</string>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index 318f0f5..7e0e3c4 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -102,16 +102,11 @@
     <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"Wi-Fi 信号强度为 2 格。"</string>
     <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"Wi-Fi 信号强度为 3 格。"</string>
     <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"WiFi 信号满格。"</string>
-    <!-- no translation found for accessibility_no_wimax (4329180129727630368) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_one_bar (4170994299011863648) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_two_bars (9176236858336502288) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_three_bars (6116551636752103927) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_signal_full (2768089986795579558) -->
-    <skip />
+    <string name="accessibility_no_wimax" msgid="4329180129727630368">"无 WiMAX 信号。"</string>
+    <string name="accessibility_wimax_one_bar" msgid="4170994299011863648">"WiMAX 信号强度为一格。"</string>
+    <string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"WiMAX 信号强度为两格。"</string>
+    <string name="accessibility_wimax_three_bars" msgid="6116551636752103927">"WiMAX 信号强度为三格。"</string>
+    <string name="accessibility_wimax_signal_full" msgid="2768089986795579558">"WiMAX 信号满格。"</string>
     <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
     <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
     <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
@@ -145,6 +140,5 @@
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"正在搜索 GPS"</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"已通过 GPS 确定位置"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"清除所有通知。"</string>
-    <!-- no translation found for dreams_dock_launcher (3541196417659166245) -->
-    <skip />
+    <string name="dreams_dock_launcher" msgid="3541196417659166245">"激活屏幕保护程序"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 7d788b8..614f143 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -102,16 +102,11 @@
     <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"Wi-Fi 訊號兩格。"</string>
     <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"Wi-Fi 訊號三格。"</string>
     <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"WiFi 訊號滿格。"</string>
-    <!-- no translation found for accessibility_no_wimax (4329180129727630368) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_one_bar (4170994299011863648) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_two_bars (9176236858336502288) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_three_bars (6116551636752103927) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_signal_full (2768089986795579558) -->
-    <skip />
+    <string name="accessibility_no_wimax" msgid="4329180129727630368">"沒有 WiMAX 訊號。"</string>
+    <string name="accessibility_wimax_one_bar" msgid="4170994299011863648">"WiMAX 訊號一格。"</string>
+    <string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"WiMAX 訊號兩格。"</string>
+    <string name="accessibility_wimax_three_bars" msgid="6116551636752103927">"WiMAX 訊號三格。"</string>
+    <string name="accessibility_wimax_signal_full" msgid="2768089986795579558">"WiMAX 訊號滿格。"</string>
     <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
     <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
     <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
@@ -145,6 +140,5 @@
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"正在搜尋 GPS"</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"GPS 已定位"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"清除所有通知。"</string>
-    <!-- no translation found for dreams_dock_launcher (3541196417659166245) -->
-    <skip />
+    <string name="dreams_dock_launcher" msgid="3541196417659166245">"啟用螢幕保護程式"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 3090915..39b428a 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -68,7 +68,7 @@
     <string name="screenshot_saved_title" msgid="6461865960961414961">"Umfanekiso weskrini uqoshiwe"</string>
     <string name="screenshot_saved_text" msgid="1152839647677558815">"Thinta ukubona imifanekiso yakho yeskrini"</string>
     <string name="screenshot_failed_title" msgid="705781116746922771">"Yehlulekile ukulondoloza umfanekiso weskrini."</string>
-    <string name="screenshot_failed_text" msgid="8134011269572415402">"Ayikwazanga ukulondoloza isithombe-skrini. Ukugcina kwangaphandle kungenzeka kuyasetshenziswa."</string>
+    <string name="screenshot_failed_text" msgid="8134011269572415402">"Ayikwazanga ukulondoloza isithombe-skrini. Isitoreji sangaphandle kungenzeka kuyasetshenziswa."</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"Okukhethwa kokudluliswa kwefayela ye-USB"</string>
     <string name="use_mtp_button_title" msgid="4333504413563023626">"Lengisa njengesidlali semediya (MTP)"</string>
     <string name="use_ptp_button_title" msgid="7517127540301625751">"Lengisa ikhamera (PTP)"</string>
@@ -102,16 +102,11 @@
     <string name="accessibility_wifi_two_bars" msgid="3344340012058984348">"I-Wi-Fi imigqaa emibili."</string>
     <string name="accessibility_wifi_three_bars" msgid="928322805193265041">"I-Wi-Fi imigqaa emithathu."</string>
     <string name="accessibility_wifi_signal_full" msgid="1275764416228473932">"i-signal ye-WiFi igcwele"</string>
-    <!-- no translation found for accessibility_no_wimax (4329180129727630368) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_one_bar (4170994299011863648) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_two_bars (9176236858336502288) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_three_bars (6116551636752103927) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_signal_full (2768089986795579558) -->
-    <skip />
+    <string name="accessibility_no_wimax" msgid="4329180129727630368">"Ayikho i-WiMAX."</string>
+    <string name="accessibility_wimax_one_bar" msgid="4170994299011863648">"Ibha eyodwa ye-WiMAX."</string>
+    <string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"Amabha amabili we-WiMAX."</string>
+    <string name="accessibility_wimax_three_bars" msgid="6116551636752103927">"Amabha amathathu we-WiMAX."</string>
+    <string name="accessibility_wimax_signal_full" msgid="2768089986795579558">"Isiginali ye-WiMAX egcwele."</string>
     <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
     <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
     <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
@@ -120,7 +115,7 @@
     <string name="accessibility_data_connection_edge" msgid="4477457051631979278">"Ekucupheleni"</string>
     <string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"I-Wi-Fi"</string>
     <string name="accessibility_no_sim" msgid="8274017118472455155">"Ayikho i-SIM"</string>
-    <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Ukusebenzisa i-Bluetooth."</string>
+    <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Imodemu nge-Bluetooth."</string>
     <string name="accessibility_airplane_mode" msgid="834748999790763092">"Imodi yendiza."</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Iphesenti <xliff:g id="NUMBER">%d</xliff:g> lebhetri"</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Izilungiselelo zesistimu"</string>
@@ -143,6 +138,5 @@
     <string name="gps_notification_searching_text" msgid="8574247005642736060">"Isesha i-GPS"</string>
     <string name="gps_notification_found_text" msgid="4619274244146446464">"Indawo ihlelwe i-GPS"</string>
     <string name="accessibility_clear_all" msgid="5235938559247164925">"Susa zonke izaziso."</string>
-    <!-- no translation found for dreams_dock_launcher (3541196417659166245) -->
-    <skip />
+    <string name="dreams_dock_launcher" msgid="3541196417659166245">"Yenza ukuthi iskrini seyiva sisebenze"</string>
 </resources>
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
index 8bfd711..4aec22c 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
@@ -68,10 +68,11 @@
     private View mRecentsScrim;
     private View mRecentsNoApps;
     private ViewGroup mRecentsContainer;
+    private StatusBarTouchProxy mStatusBarTouchProxy;
 
     private boolean mShowing;
     private Choreographer mChoreo;
-    private View mRecentsDismissButton;
+    OnRecentsPanelVisibilityChangedListener mVisibilityChangedListener;
 
     private RecentTasksLoader mRecentTasksLoader;
     private ArrayList<TaskDescription> mRecentTaskDescriptions;
@@ -81,8 +82,8 @@
     private int mThumbnailWidth;
     private boolean mFitThumbnailToXY;
 
-    public void setRecentTasksLoader(RecentTasksLoader loader) {
-        mRecentTasksLoader = loader;
+    public static interface OnRecentsPanelVisibilityChangedListener {
+        public void onRecentsPanelVisibilityChanged(boolean visible);
     }
 
     private final class OnLongClickDelegate implements View.OnLongClickListener {
@@ -171,15 +172,18 @@
         return super.onKeyUp(keyCode, event);
     }
 
-    public boolean isInContentArea(int x, int y) {
-        // use mRecentsContainer's exact bounds to determine horizontal position
-        final int l = mRecentsContainer.getLeft();
-        final int r = mRecentsContainer.getRight();
-        final int t = mRecentsContainer.getTop();
-        final int b = mRecentsContainer.getBottom();
+    private boolean pointInside(int x, int y, View v) {
+        final int l = v.getLeft();
+        final int r = v.getRight();
+        final int t = v.getTop();
+        final int b = v.getBottom();
         return x >= l && x < r && y >= t && y < b;
     }
 
+    public boolean isInContentArea(int x, int y) {
+        return pointInside(x, y, mRecentsContainer) || pointInside(x, y, mStatusBarTouchProxy);
+    }
+
     public void show(boolean show, boolean animate) {
         show(show, animate, null);
     }
@@ -278,7 +282,6 @@
     public void onAnimationStart(Animator animation) {
     }
 
-
     /**
      * We need to be aligned at the bottom.  LinearLayout can't do this, so instead,
      * let LinearLayout do all the hard work, and then shift everything down to the bottom.
@@ -312,6 +315,29 @@
 
     public void setBar(StatusBar bar) {
         mBar = bar;
+
+    }
+
+    public void setStatusBarView(View statusBarView) {
+        if (mStatusBarTouchProxy != null) {
+            mStatusBarTouchProxy.setStatusBar(statusBarView);
+        }
+    }
+
+    public void setRecentTasksLoader(RecentTasksLoader loader) {
+        mRecentTasksLoader = loader;
+    }
+
+    public void setOnVisibilityChangedListener(OnRecentsPanelVisibilityChangedListener l) {
+        mVisibilityChangedListener = l;
+
+    }
+
+    public void setVisibility(int visibility) {
+        if (mVisibilityChangedListener != null) {
+            mVisibilityChangedListener.onRecentsPanelVisibilityChanged(visibility == VISIBLE);
+        }
+        super.setVisibility(visibility);
     }
 
     public RecentsPanelView(Context context, AttributeSet attrs) {
@@ -335,6 +361,7 @@
         super.onFinishInflate();
         mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
         mRecentsContainer = (ViewGroup) findViewById(R.id.recents_container);
+        mStatusBarTouchProxy = (StatusBarTouchProxy) findViewById(R.id.status_bar_touch_proxy);
         mListAdapter = new TaskDescriptionAdapter(mContext);
         if (mRecentsContainer instanceof RecentsHorizontalScrollView){
             RecentsHorizontalScrollView scrollView
@@ -355,14 +382,6 @@
         mRecentsScrim = findViewById(R.id.recents_bg_protect);
         mRecentsNoApps = findViewById(R.id.recents_no_apps);
         mChoreo = new Choreographer(this, mRecentsScrim, mRecentsContainer, mRecentsNoApps, this);
-        mRecentsDismissButton = findViewById(R.id.recents_dismiss_button);
-        if (mRecentsDismissButton != null) {
-            mRecentsDismissButton.setOnClickListener(new OnClickListener() {
-                public void onClick(View v) {
-                    hide(true);
-                }
-            });
-        }
 
         // In order to save space, we make the background texture repeat in the Y direction
         if (mRecentsScrim != null && mRecentsScrim.getBackground() instanceof BitmapDrawable) {
diff --git a/packages/SystemUI/src/com/android/systemui/recent/StatusBarTouchProxy.java b/packages/SystemUI/src/com/android/systemui/recent/StatusBarTouchProxy.java
new file mode 100644
index 0000000..ded114f
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/recent/StatusBarTouchProxy.java
@@ -0,0 +1,40 @@
+/*
+ * 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.systemui.recent;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+import android.view.View;
+import android.widget.FrameLayout;
+
+public class StatusBarTouchProxy extends FrameLayout {
+
+    private View mStatusBar;
+
+    public StatusBarTouchProxy(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public void setStatusBar(View statusBar) {
+        mStatusBar = statusBar;
+    }
+
+    public boolean onTouchEvent (MotionEvent event) {
+        return mStatusBar.dispatchTouchEvent(event);
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
index ad37603..2232995 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
@@ -34,15 +34,14 @@
 import android.graphics.Matrix;
 import android.graphics.PixelFormat;
 import android.graphics.PointF;
+import android.hardware.CameraSound;
 import android.net.Uri;
 import android.os.AsyncTask;
 import android.os.Environment;
 import android.os.Process;
-import android.os.ServiceManager;
 import android.provider.MediaStore;
 import android.util.DisplayMetrics;
 import android.view.Display;
-import android.view.IWindowManager;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
 import android.view.Surface;
@@ -50,7 +49,6 @@
 import android.view.ViewGroup;
 import android.view.WindowManager;
 import android.view.animation.Interpolator;
-import android.widget.FrameLayout;
 import android.widget.ImageView;
 
 import com.android.systemui.R;
@@ -77,7 +75,6 @@
  */
 class SaveImageInBackgroundTask extends AsyncTask<SaveImageInBackgroundData, Void,
         SaveImageInBackgroundData> {
-    private static final String TAG = "SaveImageInBackgroundTask";
     private static final String SCREENSHOTS_DIR_NAME = "Screenshots";
     private static final String SCREENSHOT_FILE_NAME_TEMPLATE = "Screenshot_%s.png";
     private static final String SCREENSHOT_FILE_PATH_TEMPLATE = "%s/%s/%s";
@@ -85,11 +82,8 @@
     private int mNotificationId;
     private NotificationManager mNotificationManager;
     private Notification.Builder mNotificationBuilder;
-    private Intent mLaunchIntent;
-    private String mImageDir;
     private String mImageFileName;
     private String mImageFilePath;
-    private String mImageDate;
     private long mImageTime;
 
     // WORKAROUND: We want the same notification across screenshots that we update so that we don't
@@ -105,11 +99,11 @@
 
         // Prepare all the output metadata
         mImageTime = System.currentTimeMillis();
-        mImageDate = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss").format(new Date(mImageTime));
-        mImageDir = Environment.getExternalStoragePublicDirectory(
+        String imageDate = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss").format(new Date(mImageTime));
+        String imageDir = Environment.getExternalStoragePublicDirectory(
                 Environment.DIRECTORY_PICTURES).getAbsolutePath();
-        mImageFileName = String.format(SCREENSHOT_FILE_NAME_TEMPLATE, mImageDate);
-        mImageFilePath = String.format(SCREENSHOT_FILE_PATH_TEMPLATE, mImageDir,
+        mImageFileName = String.format(SCREENSHOT_FILE_NAME_TEMPLATE, imageDate);
+        mImageFilePath = String.format(SCREENSHOT_FILE_PATH_TEMPLATE, imageDir,
                 SCREENSHOTS_DIR_NAME, mImageFileName);
 
         // Create the large notification icon
@@ -190,7 +184,7 @@
         }
 
         return params[0];
-    };
+    }
 
     @Override
     protected void onPostExecute(SaveImageInBackgroundData params) {
@@ -202,14 +196,14 @@
             Resources r = params.context.getResources();
 
             // Create the intent to show the screenshot in gallery
-            mLaunchIntent = new Intent(Intent.ACTION_VIEW);
-            mLaunchIntent.setDataAndType(params.imageUri, "image/png");
-            mLaunchIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+            Intent launchIntent = new Intent(Intent.ACTION_VIEW);
+            launchIntent.setDataAndType(params.imageUri, "image/png");
+            launchIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
 
             mNotificationBuilder
                 .setContentTitle(r.getString(R.string.screenshot_saved_title))
                 .setContentText(r.getString(R.string.screenshot_saved_text))
-                .setContentIntent(PendingIntent.getActivity(params.context, 0, mLaunchIntent, 0))
+                .setContentIntent(PendingIntent.getActivity(params.context, 0, launchIntent, 0))
                 .setWhen(System.currentTimeMillis())
                 .setAutoCancel(true);
 
@@ -218,7 +212,7 @@
             mNotificationManager.notify(mNotificationId, n);
         }
         params.finisher.run();
-    };
+    }
 }
 
 /**
@@ -228,7 +222,6 @@
  *     type of gallery?
  */
 class GlobalScreenshot {
-    private static final String TAG = "GlobalScreenshot";
     private static final int SCREENSHOT_NOTIFICATION_ID = 789;
     private static final int SCREENSHOT_FLASH_TO_PEAK_DURATION = 130;
     private static final int SCREENSHOT_DROP_IN_DURATION = 430;
@@ -244,8 +237,6 @@
     private static final float SCREENSHOT_DROP_OUT_MIN_SCALE_OFFSET = 0f;
 
     private Context mContext;
-    private LayoutInflater mLayoutInflater;
-    private IWindowManager mIWindowManager;
     private WindowManager mWindowManager;
     private WindowManager.LayoutParams mWindowLayoutParams;
     private NotificationManager mNotificationManager;
@@ -256,7 +247,6 @@
     private Bitmap mScreenBitmap;
     private View mScreenshotLayout;
     private ImageView mBackgroundView;
-    private FrameLayout mScreenshotContainerView;
     private ImageView mScreenshotView;
     private ImageView mScreenshotFlash;
 
@@ -266,6 +256,8 @@
     private float mBgPadding;
     private float mBgPaddingScale;
 
+    private CameraSound mCameraSound;
+
 
     /**
      * @param context everything needs a context :(
@@ -273,14 +265,13 @@
     public GlobalScreenshot(Context context) {
         Resources r = context.getResources();
         mContext = context;
-        mLayoutInflater = (LayoutInflater)
+        LayoutInflater layoutInflater = (LayoutInflater)
                 context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
 
         // Inflate the screenshot layout
         mDisplayMatrix = new Matrix();
-        mScreenshotLayout = mLayoutInflater.inflate(R.layout.global_screenshot, null);
+        mScreenshotLayout = layoutInflater.inflate(R.layout.global_screenshot, null);
         mBackgroundView = (ImageView) mScreenshotLayout.findViewById(R.id.global_screenshot_background);
-        mScreenshotContainerView = (FrameLayout) mScreenshotLayout.findViewById(R.id.global_screenshot_container);
         mScreenshotView = (ImageView) mScreenshotLayout.findViewById(R.id.global_screenshot);
         mScreenshotFlash = (ImageView) mScreenshotLayout.findViewById(R.id.global_screenshot_flash);
         mScreenshotLayout.setFocusable(true);
@@ -293,8 +284,6 @@
         });
 
         // Setup the window that we are going to use
-        mIWindowManager = IWindowManager.Stub.asInterface(
-                ServiceManager.getService(Context.WINDOW_SERVICE));
         mWindowLayoutParams = new WindowManager.LayoutParams(
                 ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT, 0, 0,
                 WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY,
@@ -318,6 +307,9 @@
         // Scale has to account for both sides of the bg
         mBgPadding = (float) r.getDimensionPixelSize(R.dimen.global_screenshot_bg_padding);
         mBgPaddingScale = mBgPadding /  mDisplayMetrics.widthPixels;
+
+        // Setup the Camera shutter sound
+        mCameraSound = new CameraSound();
     }
 
     /**
@@ -428,8 +420,11 @@
         mScreenshotLayout.post(new Runnable() {
             @Override
             public void run() {
-                mScreenshotContainerView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
-                mScreenshotContainerView.buildLayer();
+                // Play the shutter sound to notify that we've taken a screenshot
+                mCameraSound.playSound(CameraSound.SHUTTER_CLICK);
+
+                mScreenshotView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+                mScreenshotView.buildLayer();
                 mScreenshotAnimation.start();
             }
         });
@@ -463,20 +458,16 @@
         anim.addListener(new AnimatorListenerAdapter() {
             @Override
             public void onAnimationStart(Animator animation) {
-                mBackgroundView.setFastAlpha(0f);
+                mBackgroundView.setAlpha(0f);
                 mBackgroundView.setVisibility(View.VISIBLE);
-                mBackgroundView.fastInvalidate();
-                mScreenshotContainerView.setFastAlpha(0f);
-                mScreenshotContainerView.setFastTranslationX(0f);
-                mScreenshotContainerView.setFastTranslationY(0f);
-                mScreenshotContainerView.setFastScaleX(SCREENSHOT_SCALE + mBgPaddingScale);
-                mScreenshotContainerView.setFastScaleY(SCREENSHOT_SCALE + mBgPaddingScale);
-                mScreenshotContainerView.setVisibility(View.VISIBLE);
-                mScreenshotContainerView.fastInvalidate();
-                mScreenshotFlash.setFastAlpha(0f);
+                mScreenshotView.setAlpha(0f);
+                mScreenshotView.setTranslationX(0f);
+                mScreenshotView.setTranslationY(0f);
+                mScreenshotView.setScaleX(SCREENSHOT_SCALE + mBgPaddingScale);
+                mScreenshotView.setScaleY(SCREENSHOT_SCALE + mBgPaddingScale);
+                mScreenshotView.setVisibility(View.VISIBLE);
+                mScreenshotFlash.setAlpha(0f);
                 mScreenshotFlash.setVisibility(View.VISIBLE);
-                mScreenshotFlash.fastInvalidate();
-                mScreenshotLayout.invalidate();
             }
             @Override
             public void onAnimationEnd(android.animation.Animator animation) {
@@ -486,19 +477,15 @@
         anim.addUpdateListener(new AnimatorUpdateListener() {
             @Override
             public void onAnimationUpdate(ValueAnimator animation) {
-                float t = ((Float) animation.getAnimatedValue()).floatValue();
+                float t = (Float) animation.getAnimatedValue();
                 float scaleT = (SCREENSHOT_SCALE + mBgPaddingScale)
-                    - (float) scaleInterpolator.getInterpolation(t)
+                    - scaleInterpolator.getInterpolation(t)
                         * (SCREENSHOT_SCALE - SCREENSHOT_DROP_IN_MIN_SCALE);
-                mBackgroundView.setFastAlpha(scaleInterpolator.getInterpolation(t) * BACKGROUND_ALPHA);
-                mBackgroundView.fastInvalidate();
-                mScreenshotContainerView.setFastAlpha(t);
-                mScreenshotContainerView.setFastScaleX(scaleT);
-                mScreenshotContainerView.setFastScaleY(scaleT);
-                mScreenshotContainerView.fastInvalidate();
-                mScreenshotFlash.setFastAlpha(flashAlphaInterpolator.getInterpolation(t));
-                mScreenshotFlash.fastInvalidate();
-                mScreenshotLayout.invalidate();
+                mBackgroundView.setAlpha(scaleInterpolator.getInterpolation(t) * BACKGROUND_ALPHA);
+                mScreenshotView.setAlpha(t);
+                mScreenshotView.setScaleX(scaleT);
+                mScreenshotView.setScaleY(scaleT);
+                mScreenshotFlash.setAlpha(flashAlphaInterpolator.getInterpolation(t));
             }
         });
         return anim;
@@ -511,8 +498,8 @@
             @Override
             public void onAnimationEnd(Animator animation) {
                 mBackgroundView.setVisibility(View.GONE);
-                mScreenshotContainerView.setVisibility(View.GONE);
-                mScreenshotContainerView.setLayerType(View.LAYER_TYPE_NONE, null);
+                mScreenshotView.setVisibility(View.GONE);
+                mScreenshotView.setLayerType(View.LAYER_TYPE_NONE, null);
             }
         });
 
@@ -522,17 +509,13 @@
             anim.addUpdateListener(new AnimatorUpdateListener() {
                 @Override
                 public void onAnimationUpdate(ValueAnimator animation) {
-                    float t = ((Float) animation.getAnimatedValue()).floatValue();
+                    float t = (Float) animation.getAnimatedValue();
                     float scaleT = (SCREENSHOT_DROP_IN_MIN_SCALE + mBgPaddingScale)
-                            - (float) t * (SCREENSHOT_DROP_IN_MIN_SCALE
-                                    - SCREENSHOT_FAST_DROP_OUT_MIN_SCALE);
-                    mBackgroundView.setFastAlpha((1f - t) * BACKGROUND_ALPHA);
-                    mBackgroundView.fastInvalidate();
-                    mScreenshotContainerView.setFastAlpha(1f - t);
-                    mScreenshotContainerView.setFastScaleX(scaleT);
-                    mScreenshotContainerView.setFastScaleY(scaleT);
-                    mScreenshotContainerView.fastInvalidate();
-                    mScreenshotLayout.invalidate();
+                            - t * (SCREENSHOT_DROP_IN_MIN_SCALE - SCREENSHOT_FAST_DROP_OUT_MIN_SCALE);
+                    mBackgroundView.setAlpha((1f - t) * BACKGROUND_ALPHA);
+                    mScreenshotView.setAlpha(1f - t);
+                    mScreenshotView.setScaleX(scaleT);
+                    mScreenshotView.setScaleY(scaleT);
                 }
             });
         } else {
@@ -563,19 +546,16 @@
             anim.addUpdateListener(new AnimatorUpdateListener() {
                 @Override
                 public void onAnimationUpdate(ValueAnimator animation) {
-                    float t = ((Float) animation.getAnimatedValue()).floatValue();
+                    float t = (Float) animation.getAnimatedValue();
                     float scaleT = (SCREENSHOT_DROP_IN_MIN_SCALE + mBgPaddingScale)
-                        - (float) scaleInterpolator.getInterpolation(t)
+                        - scaleInterpolator.getInterpolation(t)
                             * (SCREENSHOT_DROP_IN_MIN_SCALE - SCREENSHOT_DROP_OUT_MIN_SCALE);
-                    mBackgroundView.setFastAlpha((1f - t) * BACKGROUND_ALPHA);
-                    mBackgroundView.fastInvalidate();
-                    mScreenshotContainerView.setFastAlpha(1f - scaleInterpolator.getInterpolation(t));
-                    mScreenshotContainerView.setFastScaleX(scaleT);
-                    mScreenshotContainerView.setFastScaleY(scaleT);
-                    mScreenshotContainerView.setFastTranslationX(t * finalPos.x);
-                    mScreenshotContainerView.setFastTranslationY(t * finalPos.y);
-                    mScreenshotContainerView.fastInvalidate();
-                    mScreenshotLayout.invalidate();
+                    mBackgroundView.setAlpha((1f - t) * BACKGROUND_ALPHA);
+                    mScreenshotView.setAlpha(1f - scaleInterpolator.getInterpolation(t));
+                    mScreenshotView.setScaleX(scaleT);
+                    mScreenshotView.setScaleY(scaleT);
+                    mScreenshotView.setTranslationX(t * finalPos.x);
+                    mScreenshotView.setTranslationY(t * finalPos.y);
                 }
             });
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
index bf2d5e8..f8dfa8f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
@@ -62,6 +62,8 @@
     
     private static final int MSG_TOGGLE_RECENT_APPS       = 11 << MSG_SHIFT;
 
+    private static final int MSG_SET_NAVIGATION_ICON_HINTS = 13 << MSG_SHIFT;
+
     private StatusBarIconList mList;
     private Callbacks mCallbacks;
     private Handler mHandler = new H();
@@ -90,6 +92,7 @@
         public void setImeWindowStatus(IBinder token, int vis, int backDisposition);
         public void setHardKeyboardStatus(boolean available, boolean enabled);
         public void toggleRecentApps();
+        public void setNavigationIconHints(int hints);
     }
 
     public CommandQueue(Callbacks callbacks, StatusBarIconList list) {
@@ -196,6 +199,13 @@
         }
     }
 
+    public void setNavigationIconHints(int hints) {
+        synchronized (mList) {
+            mHandler.removeMessages(MSG_SET_NAVIGATION_ICON_HINTS);
+            mHandler.obtainMessage(MSG_SET_NAVIGATION_ICON_HINTS, hints, 0, null).sendToTarget();
+        }
+    }
+
     private final class H extends Handler {
         public void handleMessage(Message msg) {
             final int what = msg.what & MSG_MASK;
@@ -265,6 +275,9 @@
                 case MSG_TOGGLE_RECENT_APPS:
                     mCallbacks.toggleRecentApps();
                     break;
+                case MSG_SET_NAVIGATION_ICON_HINTS:
+                    mCallbacks.setNavigationIconHints(msg.arg1);
+                    break;
             }
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
index 694da20..69a247d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -18,8 +18,11 @@
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
+import android.animation.ObjectAnimator;
+import android.app.StatusBarManager;
 import android.content.Context;
 import android.content.res.Resources;
+import android.graphics.Rect;
 import android.os.ServiceManager;
 import android.util.AttributeSet;
 import android.util.Slog;
@@ -30,8 +33,13 @@
 import android.view.ViewGroup;
 import android.view.Surface;
 import android.view.WindowManager;
+import android.widget.ImageView;
 import android.widget.LinearLayout;
 
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.lang.StringBuilder;
+
 import com.android.internal.statusbar.IStatusBarService;
 
 import com.android.systemui.R;
@@ -56,6 +64,7 @@
 
     boolean mHidden, mLowProfile, mShowMenu;
     int mDisabledFlags = 0;
+    int mNavigationIconHints = 0;
 
     public View getRecentsButton() {
         return mCurrentView.findViewById(R.id.recent_apps);
@@ -107,6 +116,34 @@
         }
     };
 
+    public void setNavigationIconHints(int hints) {
+        setNavigationIconHints(hints, false);
+    }
+
+    public void setNavigationIconHints(int hints, boolean force) {
+        if (!force && hints == mNavigationIconHints) return;
+
+        if (DEBUG) {
+            android.widget.Toast.makeText(mContext,
+                "Navigation icon hints = " + hints,
+                500).show();
+        }
+
+        mNavigationIconHints = hints;
+
+        getBackButton().setAlpha(
+            (0 != (hints & StatusBarManager.NAVIGATION_HINT_BACK_NOP)) ? 0.5f : 1.0f);
+        getHomeButton().setAlpha(
+            (0 != (hints & StatusBarManager.NAVIGATION_HINT_HOME_NOP)) ? 0.5f : 1.0f);
+        getRecentsButton().setAlpha(
+            (0 != (hints & StatusBarManager.NAVIGATION_HINT_RECENT_NOP)) ? 0.5f : 1.0f);
+
+        ((ImageView)getBackButton()).setImageResource(
+            (0 != (hints & StatusBarManager.NAVIGATION_HINT_BACK_ALT))
+                ? R.drawable.ic_sysbar_back_ime
+                : R.drawable.ic_sysbar_back);
+    }
+
     public void setDisabledFlags(int disabledFlags) {
         setDisabledFlags(disabledFlags, false);
     }
@@ -237,4 +274,79 @@
             Slog.d(TAG, "reorient(): rot=" + mDisplay.getRotation());
         }
     }
+
+    private String getResourceName(int resId) {
+        if (resId != 0) {
+            final android.content.res.Resources res = mContext.getResources();
+            try {
+                return res.getResourceName(resId);
+            } catch (android.content.res.Resources.NotFoundException ex) {
+                return "(unknown)";
+            }
+        } else {
+            return "(null)";
+        }
+    }
+
+    private static String visibilityToString(int vis) {
+        switch (vis) {
+            case View.INVISIBLE:
+                return "INVISIBLE";
+            case View.GONE:
+                return "GONE";
+            default:
+                return "VISIBLE";
+        }
+    }
+
+    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        pw.println("NavigationBarView {");
+        final Rect r = new Rect();
+
+        pw.println(String.format("      this: " + PhoneStatusBar.viewInfo(this)
+                        + " " + visibilityToString(getVisibility())));
+
+        getWindowVisibleDisplayFrame(r);
+        final boolean offscreen = r.right > mDisplay.getRawWidth()
+            || r.bottom > mDisplay.getRawHeight();
+        pw.println("      window: " 
+                + r.toShortString()
+                + " " + visibilityToString(getWindowVisibility())
+                + (offscreen ? " OFFSCREEN!" : ""));
+
+        pw.println(String.format("      mCurrentView: id=%s (%dx%d) %s",
+                        getResourceName(mCurrentView.getId()),
+                        mCurrentView.getWidth(), mCurrentView.getHeight(),
+                        visibilityToString(mCurrentView.getVisibility())));
+
+        pw.println(String.format("      disabled=0x%08x vertical=%s hidden=%s low=%s menu=%s",
+                        mDisabledFlags,
+                        mVertical ? "true" : "false",
+                        mHidden ? "true" : "false",
+                        mLowProfile ? "true" : "false",
+                        mShowMenu ? "true" : "false"));
+
+        final View back = getBackButton();
+        final View home = getHomeButton();
+        final View recent = getRecentsButton();
+        final View menu = getMenuButton();
+
+        pw.println("      back: "
+                + PhoneStatusBar.viewInfo(back)
+                + " " + visibilityToString(back.getVisibility())
+                );
+        pw.println("      home: "
+                + PhoneStatusBar.viewInfo(home)
+                + " " + visibilityToString(home.getVisibility())
+                );
+        pw.println("      rcnt: "
+                + PhoneStatusBar.viewInfo(recent)
+                + " " + visibilityToString(recent.getVisibility())
+                );
+        pw.println("      menu: "
+                + PhoneStatusBar.viewInfo(menu)
+                + " " + visibilityToString(menu.getVisibility())
+                );
+        pw.println("    }");
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index f0093d3..5a1e3f4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -32,6 +32,7 @@
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.res.Resources;
 import android.content.res.Configuration;
+import android.inputmethodservice.InputMethodService;
 import android.graphics.PixelFormat;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
@@ -136,7 +137,7 @@
     BatteryController mBatteryController;
     LocationController mLocationController;
     NetworkController mNetworkController;
-    
+
     int mNaturalBarHeight = -1;
     int mIconSize = -1;
     int mIconHPadding = -1;
@@ -168,7 +169,7 @@
 
     // drag bar
     CloseDragHandle mCloseView;
-    
+
     // all notifications
     NotificationData mNotificationData = new NotificationData();
     NotificationRowLayout mPile;
@@ -229,6 +230,8 @@
 
     DisplayMetrics mDisplayMetrics = new DisplayMetrics();
 
+    private int mNavigationIconHints = 0;
+
     private class ExpandedDialog extends Dialog {
         ExpandedDialog(Context context) {
             super(context, com.android.internal.R.style.Theme_Translucent_NoTitleBar);
@@ -298,7 +301,7 @@
         try {
             boolean showNav = mWindowManager.hasNavigationBar();
             if (showNav) {
-                mNavigationBarView = 
+                mNavigationBarView =
                     (NavigationBarView) View.inflate(context, R.layout.navigation_bar, null);
 
                 mNavigationBarView.setDisabledFlags(mDisabled);
@@ -352,11 +355,11 @@
         mBatteryController = new BatteryController(mContext);
         mBatteryController.addIconView((ImageView)sb.findViewById(R.id.battery));
         mNetworkController = new NetworkController(mContext);
-        final SignalClusterView signalCluster = 
+        final SignalClusterView signalCluster =
                 (SignalClusterView)sb.findViewById(R.id.signal_cluster);
         mNetworkController.addSignalCluster(signalCluster);
         signalCluster.setNetworkController(mNetworkController);
-//        final ImageView wimaxRSSI = 
+//        final ImageView wimaxRSSI =
 //                (ImageView)sb.findViewById(R.id.wimax_signal);
 //        if (wimaxRSSI != null) {
 //            mNetworkController.addWimaxIconView(wimaxRSSI);
@@ -973,7 +976,7 @@
             } catch (NameNotFoundException ex) {
                 Slog.e(TAG, "Failed looking up ApplicationInfo for " + sbn.pkg, ex);
             }
-            if (version > 0 && version < Build.VERSION_CODES.HONEYCOMB) {
+            if (version > 0 && version < Build.VERSION_CODES.GINGERBREAD) {
                 content.setBackgroundResource(R.drawable.notification_row_legacy_bg);
             } else {
                 content.setBackgroundResource(R.drawable.notification_row_bg);
@@ -1085,8 +1088,8 @@
             }
         }
 
-        if ((diff & (StatusBarManager.DISABLE_HOME 
-                        | StatusBarManager.DISABLE_RECENT 
+        if ((diff & (StatusBarManager.DISABLE_HOME
+                        | StatusBarManager.DISABLE_RECENT
                         | StatusBarManager.DISABLE_BACK)) != 0) {
             // the nav bar will take care of these
             if (mNavigationBarView != null) mNavigationBarView.setDisabledFlags(state);
@@ -1204,7 +1207,7 @@
     public void animateCollapse(boolean excludeRecents) {
         animateCollapse(excludeRecents, 1.0f);
     }
-    
+
     public void animateCollapse(boolean excludeRecents, float velocityMultiplier) {
         if (SPEW) {
             Slog.d(TAG, "animateCollapse(): mExpanded=" + mExpanded
@@ -1516,8 +1519,8 @@
                 }
 
                 if (CHATTY) {
-                    Slog.d(TAG, String.format("gesture: vraw=(%f,%f) vnorm=(%f,%f) vlinear=%f", 
-                        mVelocityTracker.getXVelocity(), 
+                    Slog.d(TAG, String.format("gesture: vraw=(%f,%f) vnorm=(%f,%f) vlinear=%f",
+                        mVelocityTracker.getXVelocity(),
                         mVelocityTracker.getYVelocity(),
                         xVel, yVel,
                         vel));
@@ -1541,6 +1544,17 @@
     }
 
     @Override // CommandQueue
+    public void setNavigationIconHints(int hints) {
+        if (hints == mNavigationIconHints) return;
+
+        mNavigationIconHints = hints;
+
+        if (mNavigationBarView != null) {
+            mNavigationBarView.setNavigationIconHints(hints);
+        }
+    }
+
+    @Override // CommandQueue
     public void setSystemUiVisibility(int vis) {
         final int old = mSystemUiVisibility;
         final int diff = vis ^ old;
@@ -1590,8 +1604,16 @@
         if (showMenu) setLightsOn(true);
     }
 
-    // Not supported
-    public void setImeWindowStatus(IBinder token, int vis, int backDisposition) { }
+    @Override
+    public void setImeWindowStatus(IBinder token, int vis, int backDisposition) {
+        boolean altBack = (backDisposition == InputMethodService.BACK_DISPOSITION_WILL_DISMISS)
+            || ((vis & InputMethodService.IME_VISIBLE) != 0);
+
+        mCommandQueue.setNavigationIconHints(
+                altBack ? (mNavigationIconHints | StatusBarManager.NAVIGATION_HINT_BACK_ALT)
+                        : (mNavigationIconHints & ~StatusBarManager.NAVIGATION_HINT_BACK_ALT));
+    }
+
     @Override
     public void setHardKeyboardStatus(boolean available, boolean enabled) { }
 
@@ -1735,9 +1757,9 @@
         return anim;
     }
 
-    public String viewInfo(View v) {
-        return "(" + v.getLeft() + "," + v.getTop() + ")(" + v.getRight() + "," + v.getBottom()
-                + " " + v.getWidth() + "x" + v.getHeight() + ")";
+    public static String viewInfo(View v) {
+        return "[(" + v.getLeft() + "," + v.getTop() + ")(" + v.getRight() + "," + v.getBottom()
+                + ") " + v.getWidth() + "x" + v.getHeight() + "]";
     }
 
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
@@ -1768,6 +1790,13 @@
                     + " scroll " + mScrollView.getScrollX() + "," + mScrollView.getScrollY());
         }
 
+        pw.print("  mNavigationBarView=");
+        if (mNavigationBarView == null) {
+            pw.println("null");
+        } else {
+            mNavigationBarView.dump(fd, pw, args);
+        }
+
         if (DUMPTRUCK) {
             synchronized (mNotificationData) {
                 int N = mNotificationData.size();
@@ -1788,7 +1817,7 @@
                 StatusBarIconView ic = (StatusBarIconView) mStatusIcons.getChildAt(i);
                 pw.println("    [" + i + "] icon=" + ic);
             }
-            
+
             if (false) {
                 pw.println("see the logcat for a dump of the views we have created.");
                 // must happen on ui thread
@@ -1963,10 +1992,10 @@
                         - (mTrackingParams.height-closePos) - contentsBottom;
 
                 if (SPEW) {
-                    Slog.d(PhoneStatusBar.TAG, 
+                    Slog.d(PhoneStatusBar.TAG,
                             "pos=" + pos +
                             " trackingHeight=" + mTrackingView.getHeight() +
-                            " (trackingParams.height - closePos)=" + 
+                            " (trackingParams.height - closePos)=" +
                                 (mTrackingParams.height - closePos) +
                             " contentsBottom=" + contentsBottom);
                 }
@@ -2041,7 +2070,7 @@
                 mExpandedDialog.getWindow().setAttributes(mExpandedParams);
             }
             if (DEBUG) {
-                Slog.d(TAG, "updateExpandedSize: height=" + mExpandedParams.height + " " + 
+                Slog.d(TAG, "updateExpandedSize: height=" + mExpandedParams.height + " " +
                     (mExpandedVisible ? "VISIBLE":"INVISIBLE"));
             }
         }
@@ -2181,6 +2210,11 @@
 
     private View.OnClickListener mSettingsButtonListener = new View.OnClickListener() {
         public void onClick(View v) {
+            try {
+                // Dismiss the lock screen when Settings starts.
+                ActivityManagerNative.getDefault().dismissKeyguardOnNextActivity();
+            } catch (RemoteException e) {
+            }
             v.getContext().startActivity(new Intent(Settings.ACTION_SETTINGS)
                     .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
             animateCollapse();
@@ -2230,7 +2264,7 @@
 
         loadDimens();
     }
-    
+
     protected void loadDimens() {
         final Resources res = mContext.getResources();
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothController.java
index 903a300..603808e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothController.java
@@ -36,7 +36,7 @@
 
     private int mIconId = R.drawable.stat_sys_data_bluetooth;
     private int mContentDescriptionId = 0;
-    private boolean mEnabled;
+    private boolean mEnabled = false;
 
     public BluetoothController(Context context) {
         mContext = context;
@@ -47,8 +47,10 @@
         context.registerReceiver(this, filter);
 
         final BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
-        handleAdapterStateChange(adapter.getState());
-        handleConnectionStateChange(adapter.getConnectionState());
+        if (adapter != null) {
+            handleAdapterStateChange(adapter.getState());
+            handleConnectionStateChange(adapter.getConnectionState());
+        }
         refreshViews();
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CompatModeButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CompatModeButton.java
index 7fbf734..2d951c2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CompatModeButton.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CompatModeButton.java
@@ -49,6 +49,10 @@
 
     public void refresh() {
         int mode = mAM.getFrontActivityScreenCompatMode();
+        if (mode == ActivityManager.COMPAT_MODE_UNKNOWN) {
+            // If in an unknown state, don't change.
+            return;
+        }
         final boolean vis = (mode != ActivityManager.COMPAT_MODE_NEVER
                           && mode != ActivityManager.COMPAT_MODE_ALWAYS);
         if (DEBUG) Slog.d(TAG, "compat mode is " + mode + "; icon will " + (vis ? "show" : "hide"));
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
index 55a5b0a..135a04c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
@@ -898,7 +898,7 @@
             combinedSignalIconId = mDataSignalIconId; // set by updateDataIcon()
             mContentDescriptionCombinedSignal = mContentDescriptionDataType;
         }
-        
+
         if (mWifiConnected) {
             if (mWifiSsid == null) {
                 label = context.getString(R.string.status_bar_settings_signal_meter_wifi_nossid);
@@ -932,19 +932,23 @@
             mContentDescriptionCombinedSignal = mContext.getString(
                     R.string.accessibility_bluetooth_tether);
         }
-        
+
         if (mAirplaneMode &&
                 (mServiceState == null || (!hasService() && !mServiceState.isEmergencyOnly()))) {
             // Only display the flight-mode icon if not in "emergency calls only" mode.
-            label = context.getString(R.string.status_bar_settings_signal_meter_disconnected);
-            mContentDescriptionCombinedSignal = mContentDescriptionPhoneSignal
-                = mContext.getString(R.string.accessibility_airplane_mode);
-            
+
             // look again; your radios are now airplanes
+            mContentDescriptionPhoneSignal = mContext.getString(
+                    R.string.accessibility_airplane_mode);
             mPhoneSignalIconId = mDataSignalIconId = R.drawable.stat_sys_signal_flightmode;
             mDataTypeIconId = 0;
 
-            combinedSignalIconId = mDataSignalIconId;
+            // combined values from connected wifi take precedence over airplane mode
+            if (!mWifiConnected) {
+                label = context.getString(R.string.status_bar_settings_signal_meter_disconnected);
+                mContentDescriptionCombinedSignal = mContentDescriptionPhoneSignal;
+                combinedSignalIconId = mDataSignalIconId;
+            }
         }
         else if (!mDataConnected && !mWifiConnected && !mBluetoothTethered && !mWimaxConnected) {
             // pretty much totally disconnected
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
index 01406bc..9919d825 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
@@ -88,7 +88,8 @@
 
 public class TabletStatusBar extends StatusBar implements
         HeightReceiver.OnBarHeightChangedListener,
-        InputMethodsPanel.OnHardKeyboardEnabledChangeListener {
+        InputMethodsPanel.OnHardKeyboardEnabledChangeListener,
+        RecentsPanelView.OnRecentsPanelVisibilityChangedListener {
     public static final boolean DEBUG = false;
     public static final boolean DEBUG_COMPAT_HELP = false;
     public static final String TAG = "TabletStatusBar";
@@ -143,6 +144,7 @@
     View mHomeButton;
     View mMenuButton;
     View mRecentButton;
+    private boolean mAltBackButtonEnabledForIme;
 
     ViewGroup mFeedbackIconArea; // notification icons, IME icon, compat icon
     InputMethodButton mInputMethodSwitchButton;
@@ -168,7 +170,6 @@
     NetworkController mNetworkController;
 
     ViewGroup mBarContents;
-    LayoutTransition mBarContentsLayoutTransition;
 
     // hide system chrome ("lights out") support
     View mShadow;
@@ -194,6 +195,8 @@
     // used to notify status bar for suppressing notification LED
     private boolean mPanelSlightlyVisible;
 
+    private int mNavigationIconHints = 0;
+
     public Context getContext() { return mContext; }
 
     protected void addPanelWindows() {
@@ -311,12 +314,11 @@
         mRecentsPanel = (RecentsPanelView) View.inflate(context,
                 R.layout.status_bar_recent_panel, null);
         mRecentsPanel.setVisibility(View.GONE);
-        mRecentsPanel.setSystemUiVisibility(View.STATUS_BAR_DISABLE_BACK);
         mRecentsPanel.setOnTouchListener(new TouchOutsideListener(MSG_CLOSE_RECENTS_PANEL,
                 mRecentsPanel));
+        mRecentsPanel.setOnVisibilityChangedListener(this);
         mRecentsPanel.setRecentTasksLoader(mRecentTasksLoader);
         mRecentTasksLoader.setRecentsPanel(mRecentsPanel);
-        mStatusBarView.setIgnoreChildren(2, mRecentButton, mRecentsPanel);
 
         lp = new WindowManager.LayoutParams(
                 (int) res.getDimension(R.dimen.status_bar_recents_width),
@@ -335,6 +337,7 @@
 
         WindowManagerImpl.getDefault().addView(mRecentsPanel, lp);
         mRecentsPanel.setBar(this);
+        mRecentsPanel.setStatusBarView(mStatusBarView);
 
         // Input methods Panel
         mInputMethodsPanel = (InputMethodsPanel) View.inflate(context,
@@ -343,7 +346,7 @@
         mInputMethodsPanel.setOnTouchListener(new TouchOutsideListener(
                 MSG_CLOSE_INPUT_METHODS_PANEL, mInputMethodsPanel));
         mInputMethodsPanel.setImeSwitchButton(mInputMethodSwitchButton);
-        mStatusBarView.setIgnoreChildren(3, mInputMethodSwitchButton, mInputMethodsPanel);
+        mStatusBarView.setIgnoreChildren(2, mInputMethodSwitchButton, mInputMethodsPanel);
         lp = new WindowManager.LayoutParams(
                 ViewGroup.LayoutParams.WRAP_CONTENT,
                 ViewGroup.LayoutParams.WRAP_CONTENT,
@@ -366,7 +369,7 @@
                 MSG_CLOSE_COMPAT_MODE_PANEL, mCompatModePanel));
         mCompatModePanel.setTrigger(mCompatModeButton);
         mCompatModePanel.setVisibility(View.GONE);
-        mStatusBarView.setIgnoreChildren(4, mCompatModeButton, mCompatModePanel);
+        mStatusBarView.setIgnoreChildren(3, mCompatModeButton, mCompatModePanel);
         lp = new WindowManager.LayoutParams(
                 250,
                 ViewGroup.LayoutParams.WRAP_CONTENT,
@@ -432,6 +435,10 @@
         }
     }
 
+    public View getStatusBarView() {
+        return mStatusBarView;
+    }
+
     protected View makeStatusBarView() {
         final Context context = mContext;
 
@@ -461,19 +468,6 @@
         }
 
         mBarContents = (ViewGroup) sb.findViewById(R.id.bar_contents);
-        // layout transitions for the status bar's contents
-        mBarContentsLayoutTransition = new LayoutTransition();
-        // add/removal will fade as normal
-        mBarContentsLayoutTransition.setAnimator(LayoutTransition.APPEARING,
-                ObjectAnimator.ofFloat(null, "alpha", 0f, 1f));
-        mBarContentsLayoutTransition.setAnimator(LayoutTransition.DISAPPEARING,
-                ObjectAnimator.ofFloat(null, "alpha", 1f, 0f));
-        // no animations for siblings on change: just jump into place please
-        mBarContentsLayoutTransition.setAnimator(LayoutTransition.CHANGE_APPEARING, null);
-        mBarContentsLayoutTransition.setAnimator(LayoutTransition.CHANGE_DISAPPEARING, null);
-        // quick like bunny
-        mBarContentsLayoutTransition.setDuration(250 * (DEBUG?10:1));
-        mBarContents.setLayoutTransition(mBarContentsLayoutTransition);
 
         // the whole right-hand side of the bar
         mNotificationArea = sb.findViewById(R.id.notificationArea);
@@ -522,7 +516,23 @@
         mMenuButton = mNavigationArea.findViewById(R.id.menu);
         mRecentButton = mNavigationArea.findViewById(R.id.recent_apps);
         mRecentButton.setOnClickListener(mOnClickListener);
-        mNavigationArea.setLayoutTransition(mBarContentsLayoutTransition);
+
+        LayoutTransition lt = new LayoutTransition();
+        lt.setDuration(250);
+        // don't wait for these transitions; we just want icons to fade in/out, not move around
+        lt.setDuration(LayoutTransition.CHANGE_APPEARING, 0);
+        lt.setDuration(LayoutTransition.CHANGE_DISAPPEARING, 0);
+        lt.addTransitionListener(new LayoutTransition.TransitionListener() {
+            public void endTransition(LayoutTransition transition, ViewGroup container,
+                    View view, int transitionType) {
+                // ensure the menu button doesn't stick around on the status bar after it's been
+                // removed
+                mBarContents.invalidate();
+            }
+            public void startTransition(LayoutTransition transition, ViewGroup container,
+                    View view, int transitionType) {}
+        });
+        mNavigationArea.setLayoutTransition(lt);
         // no multi-touch on the nav buttons
         mNavigationArea.setMotionEventSplittingEnabled(false);
 
@@ -534,6 +544,7 @@
 
         mCompatModeButton = (CompatModeButton) sb.findViewById(R.id.compatModeButton);
         mCompatModeButton.setOnClickListener(mOnClickListener);
+        mCompatModeButton.setVisibility(View.GONE);
 
         // for redirecting errant bar taps to the IME
         mFakeSpaceBar = sb.findViewById(R.id.fake_space_bar);
@@ -1089,6 +1100,31 @@
         }
     }
 
+    @Override // CommandQueue
+    public void setNavigationIconHints(int hints) {
+        if (hints == mNavigationIconHints) return;
+
+        if (DEBUG) {
+            android.widget.Toast.makeText(mContext,
+                "Navigation icon hints = " + hints,
+                500).show();
+        }
+
+        mNavigationIconHints = hints;
+
+        mBackButton.setAlpha(
+            (0 != (hints & StatusBarManager.NAVIGATION_HINT_BACK_NOP)) ? 0.5f : 1.0f);
+        mHomeButton.setAlpha(
+            (0 != (hints & StatusBarManager.NAVIGATION_HINT_HOME_NOP)) ? 0.5f : 1.0f);
+        mRecentButton.setAlpha(
+            (0 != (hints & StatusBarManager.NAVIGATION_HINT_RECENT_NOP)) ? 0.5f : 1.0f);
+
+        mBackButton.setImageResource(
+            (0 != (hints & StatusBarManager.NAVIGATION_HINT_BACK_ALT))
+                ? R.drawable.ic_sysbar_back_ime
+                : R.drawable.ic_sysbar_back);
+    }
+
     private void notifyUiVisibilityChanged() {
         try {
             mWindowManager.statusBarVisibilityChanged(mSystemUiVisibility);
@@ -1192,24 +1228,15 @@
                 (vis & InputMethodService.IME_ACTIVE) != 0);
         updateNotificationIcons();
         mInputMethodsPanel.setImeToken(token);
-        int res;
-        switch (backDisposition) {
-            case InputMethodService.BACK_DISPOSITION_WILL_NOT_DISMISS:
-                res = R.drawable.ic_sysbar_back;
-                break;
-            case InputMethodService.BACK_DISPOSITION_WILL_DISMISS:
-                res = R.drawable.ic_sysbar_back_ime;
-                break;
-            case InputMethodService.BACK_DISPOSITION_DEFAULT:
-            default:
-                if ((vis & InputMethodService.IME_VISIBLE) != 0) {
-                    res = R.drawable.ic_sysbar_back_ime;
-                } else {
-                    res = R.drawable.ic_sysbar_back;
-                }
-                break;
-        }
-        mBackButton.setImageResource(res);
+
+        boolean altBack = (backDisposition == InputMethodService.BACK_DISPOSITION_WILL_DISMISS)
+            || ((vis & InputMethodService.IME_VISIBLE) != 0);
+        mAltBackButtonEnabledForIme = altBack;
+
+        mCommandQueue.setNavigationIconHints(
+                altBack ? (mNavigationIconHints | StatusBarManager.NAVIGATION_HINT_BACK_ALT)
+                        : (mNavigationIconHints & ~StatusBarManager.NAVIGATION_HINT_BACK_ALT));
+
         if (FAKE_SPACE_BAR) {
             mFakeSpaceBar.setVisibility(((vis & InputMethodService.IME_VISIBLE) != 0)
                     ? View.VISIBLE : View.GONE);
@@ -1217,6 +1244,14 @@
     }
 
     @Override
+    public void onRecentsPanelVisibilityChanged(boolean visible) {
+        boolean altBack = visible || mAltBackButtonEnabledForIme;
+        mCommandQueue.setNavigationIconHints(
+                altBack ? (mNavigationIconHints | StatusBarManager.NAVIGATION_HINT_BACK_ALT)
+                        : (mNavigationIconHints & ~StatusBarManager.NAVIGATION_HINT_BACK_ALT));
+    }
+
+    @Override
     public void setHardKeyboardStatus(boolean available, boolean enabled) {
         if (DEBUG) {
             Slog.d(TAG, "Set hard keyboard status: available=" + available
@@ -1835,7 +1870,7 @@
             } catch (NameNotFoundException ex) {
                 Slog.e(TAG, "Failed looking up ApplicationInfo for " + sbn.pkg, ex);
             }
-            if (version > 0 && version < Build.VERSION_CODES.HONEYCOMB) {
+            if (version > 0 && version < Build.VERSION_CODES.GINGERBREAD) {
                 content.setBackgroundResource(R.drawable.notification_row_legacy_bg);
             } else {
                 content.setBackgroundResource(R.drawable.notification_row_bg);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarView.java
index 7d11251..877a40e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarView.java
@@ -46,10 +46,11 @@
             if (TabletStatusBar.DEBUG) {
                 Slog.d(TabletStatusBar.TAG, "TabletStatusBarView intercepting touch event: " + ev);
             }
+            // do not close the recents panel here- the intended behavior is that recents is dismissed
+            // on touch up when clicking on status bar buttons
+            // TODO: should we be closing the notification panel and input methods panel?
             mHandler.removeMessages(TabletStatusBar.MSG_CLOSE_NOTIFICATION_PANEL);
             mHandler.sendEmptyMessage(TabletStatusBar.MSG_CLOSE_NOTIFICATION_PANEL);
-            mHandler.removeMessages(TabletStatusBar.MSG_CLOSE_RECENTS_PANEL);
-            mHandler.sendEmptyMessage(TabletStatusBar.MSG_CLOSE_RECENTS_PANEL);
             mHandler.removeMessages(TabletStatusBar.MSG_CLOSE_INPUT_METHODS_PANEL);
             mHandler.sendEmptyMessage(TabletStatusBar.MSG_CLOSE_INPUT_METHODS_PANEL);
             mHandler.removeMessages(TabletStatusBar.MSG_STOP_TICKER);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletTicker.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletTicker.java
index 6045e31..e93a32b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletTicker.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletTicker.java
@@ -73,6 +73,8 @@
     private StatusBarNotification[] mQueue = new StatusBarNotification[QUEUE_LENGTH];
     private int mQueuePos;
 
+    private final int mLargeIconHeight;
+
     private TabletStatusBar mBar;
 
     private LayoutTransition mLayoutTransition;
@@ -81,6 +83,9 @@
     public TabletTicker(TabletStatusBar bar) {
         mBar = bar;
         mContext = bar.getContext();
+        final Resources res = mContext.getResources();
+        mLargeIconHeight = res.getDimensionPixelSize(
+                android.R.dimen.notification_large_icon_height);
     }
 
     public void add(IBinder key, StatusBarNotification notification) {
@@ -209,8 +214,6 @@
         final Resources res = mContext.getResources();
         final FrameLayout view = new FrameLayout(mContext);
         final int width = res.getDimensionPixelSize(R.dimen.notification_ticker_width);
-        final int height = res.getDimensionPixelSize(
-                android.R.dimen.notification_large_icon_height);
         int windowFlags = WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
                     | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                     | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
@@ -219,7 +222,7 @@
         } else {
             windowFlags |= WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
         }
-        WindowManager.LayoutParams lp = new WindowManager.LayoutParams(width, height,
+        WindowManager.LayoutParams lp = new WindowManager.LayoutParams(width, mLargeIconHeight,
                 WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL, windowFlags,
                 PixelFormat.TRANSLUCENT);
         lp.gravity = Gravity.BOTTOM | Gravity.RIGHT;
@@ -297,6 +300,16 @@
         if (n.largeIcon != null) {
             largeIcon.setImageBitmap(n.largeIcon);
             largeIcon.setVisibility(View.VISIBLE);
+            final ViewGroup.LayoutParams lp = largeIcon.getLayoutParams();
+            final int statusBarHeight = mBar.getStatusBarHeight();
+            if (n.largeIcon.getHeight() <= statusBarHeight) {
+                // for smallish largeIcons, it looks a little odd to have them floating halfway up
+                // the ticker, so we vertically center them in the status bar area instead
+                lp.height = statusBarHeight;
+            } else {
+                lp.height = mLargeIconHeight;
+            }
+            largeIcon.setLayoutParams(lp);
         }
 
         if (CLICKABLE_TICKER) {
diff --git a/policy/src/com/android/internal/policy/impl/GlobalActions.java b/policy/src/com/android/internal/policy/impl/GlobalActions.java
index f040e87..38c85bb 100644
--- a/policy/src/com/android/internal/policy/impl/GlobalActions.java
+++ b/policy/src/com/android/internal/policy/impl/GlobalActions.java
@@ -56,13 +56,15 @@
 
     private static final String TAG = "GlobalActions";
 
+    private static final boolean SHOW_SILENT_TOGGLE = true;
+
     private final Context mContext;
     private final AudioManager mAudioManager;
 
     private ArrayList<Action> mItems;
     private AlertDialog mDialog;
 
-    private ToggleAction mSilentModeToggle;
+    private SilentModeAction mSilentModeAction;
     private ToggleAction mAirplaneModeOn;
 
     private MyAdapter mAdapter;
@@ -113,39 +115,7 @@
      * @return A new dialog.
      */
     private AlertDialog createDialog() {
-        mSilentModeToggle = new ToggleAction(
-                R.drawable.ic_audio_vol_mute,
-                R.drawable.ic_audio_vol,
-                R.string.global_action_toggle_silent_mode,
-                R.string.global_action_silent_mode_on_status,
-                R.string.global_action_silent_mode_off_status) {
-
-            void willCreate() {
-                mEnabledIconResId = (Settings.System.getInt(mContext.getContentResolver(),
-                        Settings.System.VIBRATE_IN_SILENT, 1) == 1)
-                    ? R.drawable.ic_audio_ring_notif_vibrate
-                    : R.drawable.ic_audio_vol_mute;
-            }
-
-            void onToggle(boolean on) {
-                if (on) {
-                    mAudioManager.setRingerMode((Settings.System.getInt(mContext.getContentResolver(),
-                        Settings.System.VIBRATE_IN_SILENT, 1) == 1)
-                        ? AudioManager.RINGER_MODE_VIBRATE
-                        : AudioManager.RINGER_MODE_SILENT);
-                } else {
-                    mAudioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
-                }
-            }
-
-            public boolean showDuringKeyguard() {
-                return true;
-            }
-
-            public boolean showBeforeProvisioning() {
-                return false;
-            }
-        };
+        mSilentModeAction = new SilentModeAction(mAudioManager, mHandler);
 
         mAirplaneModeOn = new ToggleAction(
                 R.drawable.ic_lock_airplane_mode,
@@ -187,39 +157,45 @@
             }
         };
 
-        mItems = Lists.newArrayList(
-                // silent mode
-                mSilentModeToggle,
-                // next: airplane mode
-                mAirplaneModeOn,
-                // last: power off
-                new SinglePressAction(
-                        com.android.internal.R.drawable.ic_lock_power_off,
-                        R.string.global_action_power_off) {
+        mItems = new ArrayList<Action>();
 
-                    public void onPress() {
-                        // shutdown by making sure radio and power are handled accordingly.
-                        ShutdownThread.shutdown(mContext, true);
-                    }
+        // first: power off
+        mItems.add(
+            new SinglePressAction(
+                    com.android.internal.R.drawable.ic_lock_power_off,
+                    R.string.global_action_power_off) {
 
-                    public boolean showDuringKeyguard() {
-                        return true;
-                    }
+                public void onPress() {
+                    // shutdown by making sure radio and power are handled accordingly.
+                    ShutdownThread.shutdown(mContext, true);
+                }
 
-                    public boolean showBeforeProvisioning() {
-                        return true;
-                    }
-                });
+                public boolean showDuringKeyguard() {
+                    return true;
+                }
+
+                public boolean showBeforeProvisioning() {
+                    return true;
+                }
+            });
+
+        // next: airplane mode
+        mItems.add(mAirplaneModeOn);
+
+        // last: silent mode
+        if (SHOW_SILENT_TOGGLE) {
+            mItems.add(mSilentModeAction);
+        }
 
         mAdapter = new MyAdapter();
 
         final AlertDialog.Builder ab = new AlertDialog.Builder(mContext);
 
         ab.setAdapter(mAdapter, this)
-                .setInverseBackgroundForced(true)
-                .setTitle(R.string.global_actions);
+                .setInverseBackgroundForced(true);
 
         final AlertDialog dialog = ab.create();
+        dialog.getListView().setItemsCanFocus(true);
         dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG);
 
         dialog.setOnDismissListener(this);
@@ -230,8 +206,6 @@
     private void prepareDialog() {
         final boolean silentModeOn =
                 mAudioManager.getRingerMode() != AudioManager.RINGER_MODE_NORMAL;
-        mSilentModeToggle.updateState(
-                silentModeOn ? ToggleAction.State.On : ToggleAction.State.Off);
         mAirplaneModeOn.updateState(mAirplaneState);
         mAdapter.notifyDataSetChanged();
         if (mKeyguardShowing) {
@@ -239,20 +213,28 @@
         } else {
             mDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG);
         }
+        if (SHOW_SILENT_TOGGLE) {
+            IntentFilter filter = new IntentFilter(AudioManager.RINGER_MODE_CHANGED_ACTION);
+            mContext.registerReceiver(mRingerModeReceiver, filter);
+        }
     }
 
 
     /** {@inheritDoc} */
     public void onDismiss(DialogInterface dialog) {
+        if (SHOW_SILENT_TOGGLE) {
+            mContext.unregisterReceiver(mRingerModeReceiver);
+        }
     }
 
     /** {@inheritDoc} */
     public void onClick(DialogInterface dialog, int which) {
-        dialog.dismiss();
+        if (!(mAdapter.getItem(which) instanceof SilentModeAction)) {
+            dialog.dismiss();
+        }
         mAdapter.getItem(which).onPress();
     }
 
-
     /**
      * The adapter used for the list within the global actions dialog, taking
      * into account whether the keyguard is showing via
@@ -373,9 +355,7 @@
 
         public View create(
                 Context context, View convertView, ViewGroup parent, LayoutInflater inflater) {
-            View v = (convertView != null) ?
-                    convertView :
-                    inflater.inflate(R.layout.global_actions_item, parent, false);
+            View v = inflater.inflate(R.layout.global_actions_item, parent, false);
 
             ImageView icon = (ImageView) v.findViewById(R.id.icon);
             TextView messageView = (TextView) v.findViewById(R.id.message);
@@ -452,27 +432,31 @@
                 LayoutInflater inflater) {
             willCreate();
 
-            View v = (convertView != null) ?
-                    convertView :
-                    inflater.inflate(R
+            View v = inflater.inflate(R
                             .layout.global_actions_item, parent, false);
 
             ImageView icon = (ImageView) v.findViewById(R.id.icon);
             TextView messageView = (TextView) v.findViewById(R.id.message);
             TextView statusView = (TextView) v.findViewById(R.id.status);
+            final boolean enabled = isEnabled();
 
-            messageView.setText(mMessageResId);
+            if (messageView != null) {
+                messageView.setText(mMessageResId);
+                messageView.setEnabled(enabled);
+            }
 
             boolean on = ((mState == State.On) || (mState == State.TurningOn));
-            icon.setImageDrawable(context.getResources().getDrawable(
-                    (on ? mEnabledIconResId : mDisabledIconResid)));
-            statusView.setText(on ? mEnabledStatusMessageResId : mDisabledStatusMessageResId);
-            statusView.setVisibility(View.VISIBLE);
+            if (icon != null) {
+                icon.setImageDrawable(context.getResources().getDrawable(
+                        (on ? mEnabledIconResId : mDisabledIconResid)));
+                icon.setEnabled(enabled);
+            }
 
-            final boolean enabled = isEnabled();
-            messageView.setEnabled(enabled);
-            statusView.setEnabled(enabled);
-            icon.setEnabled(enabled);
+            if (statusView != null) {
+                statusView.setText(on ? mEnabledStatusMessageResId : mDisabledStatusMessageResId);
+                statusView.setVisibility(View.VISIBLE);
+                statusView.setEnabled(enabled);
+            }
             v.setEnabled(enabled);
 
             return v;
@@ -510,6 +494,70 @@
         }
     }
 
+    private static class SilentModeAction implements Action, View.OnClickListener {
+
+        private final int[] ITEM_IDS = { R.id.option1, R.id.option2, R.id.option3 };
+
+        private final AudioManager mAudioManager;
+        private final Handler mHandler;
+
+        SilentModeAction(AudioManager audioManager, Handler handler) {
+            mAudioManager = audioManager;
+            mHandler = handler;
+        }
+
+        private int ringerModeToIndex(int ringerMode) {
+            // They just happen to coincide
+            return ringerMode;
+        }
+
+        private int indexToRingerMode(int index) {
+            // They just happen to coincide
+            return index;
+        }
+
+        public View create(Context context, View convertView, ViewGroup parent,
+                LayoutInflater inflater) {
+            View v = inflater.inflate(R.layout.global_actions_silent_mode, parent, false);
+
+            int selectedIndex = ringerModeToIndex(mAudioManager.getRingerMode());
+            for (int i = 0; i < 3; i++) {
+                View itemView = v.findViewById(ITEM_IDS[i]);
+                itemView.setSelected(selectedIndex == i);
+                // Set up click handler
+                itemView.setTag(i);
+                itemView.setOnClickListener(this);
+            }
+            return v;
+        }
+
+        public void onPress() {
+        }
+
+        public boolean showDuringKeyguard() {
+            return true;
+        }
+
+        public boolean showBeforeProvisioning() {
+            return false;
+        }
+
+        public boolean isEnabled() {
+            return true;
+        }
+
+        void willCreate() {
+        }
+
+        public void onClick(View v) {
+            if (!(v.getTag() instanceof Integer)) return;
+
+            int index = (Integer) v.getTag();
+            mAudioManager.setRingerMode(indexToRingerMode(index));
+            mHandler.sendEmptyMessageDelayed(MESSAGE_DISMISS, DIALOG_DISMISS_DELAY);
+        }
+    }
+
     private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
         public void onReceive(Context context, Intent intent) {
             String action = intent.getAction();
@@ -541,13 +589,27 @@
         }
     };
 
+    private BroadcastReceiver mRingerModeReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (intent.getAction().equals(AudioManager.RINGER_MODE_CHANGED_ACTION)) {
+                mHandler.sendEmptyMessage(MESSAGE_REFRESH);
+            }
+        }
+    };
+
     private static final int MESSAGE_DISMISS = 0;
+    private static final int MESSAGE_REFRESH = 1;
+    private static final int DIALOG_DISMISS_DELAY = 300; // ms
+
     private Handler mHandler = new Handler() {
         public void handleMessage(Message msg) {
             if (msg.what == MESSAGE_DISMISS) {
                 if (mDialog != null) {
                     mDialog.dismiss();
                 }
+            } else if (msg.what == MESSAGE_REFRESH) {
+                mAdapter.notifyDataSetChanged();
             }
         }
     };
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java b/policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java
index ee54de1..dbdfb98 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java
@@ -293,6 +293,10 @@
         mUpdateMonitor.registerInfoCallback(mInfoCallback);
         mUpdateMonitor.registerSimStateCallback(mSimStateCallback);
         resetStatusInfo();
+        //Issue the faceunlock failure message in a centralized place
+        if (mUpdateMonitor.getMaxFaceUnlockAttemptsReached()) {
+            setInstructionText(getContext().getString(R.string.faceunlock_multiple_failures));
+        }
     }
 
     void resetStatusInfo() {
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java b/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java
index b4b82aa..1d6f39a 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java
@@ -81,6 +81,8 @@
     private CharSequence mTelephonySpn;
 
     private int mFailedAttempts = 0;
+    private int mFailedFaceUnlockAttempts = 0;
+    private static final int FAILED_FACE_UNLOCK_ATTEMPTS_BEFORE_BACKUP = 15;
 
     private boolean mClockVisible;
 
@@ -630,6 +632,7 @@
 
     public void clearFailedAttempts() {
         mFailedAttempts = 0;
+        mFailedFaceUnlockAttempts = 0;
     }
 
     public void reportFailedAttempt() {
@@ -643,4 +646,12 @@
     public int getPhoneState() {
         return mPhoneState;
     }
+
+    public void reportFailedFaceUnlockAttempt() {
+        mFailedFaceUnlockAttempts++;
+    }
+
+    public boolean getMaxFaceUnlockAttemptsReached() {
+        return mFailedFaceUnlockAttempts >= FAILED_FACE_UNLOCK_ATTEMPTS_BEFORE_BACKUP;
+    }
 }
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardViewBase.java b/policy/src/com/android/internal/policy/impl/KeyguardViewBase.java
index 26bd697..f204070 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardViewBase.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardViewBase.java
@@ -46,6 +46,10 @@
     private KeyguardViewCallback mCallback;
     private AudioManager mAudioManager;
     private TelephonyManager mTelephonyManager = null;
+    // Whether the volume keys should be handled by keyguard. If true, then
+    // they will be handled here for specific media types such as music, otherwise
+    // the audio service will bring up the volume dialog.
+    private static final boolean KEYGUARD_MANAGES_VOLUME = true;
 
     // This is a faster way to draw the background on devices without hardware acceleration
     Drawable mBackgroundDrawable = new Drawable() {
@@ -203,24 +207,28 @@
                 case KeyEvent.KEYCODE_VOLUME_UP:
                 case KeyEvent.KEYCODE_VOLUME_DOWN:
                 case KeyEvent.KEYCODE_VOLUME_MUTE: {
-                    synchronized (this) {
-                        if (mAudioManager == null) {
-                            mAudioManager = (AudioManager) getContext().getSystemService(
-                                    Context.AUDIO_SERVICE);
+                    if (KEYGUARD_MANAGES_VOLUME) {
+                        synchronized (this) {
+                            if (mAudioManager == null) {
+                                mAudioManager = (AudioManager) getContext().getSystemService(
+                                        Context.AUDIO_SERVICE);
+                            }
                         }
+                        // Volume buttons should only function for music.
+                        if (mAudioManager.isMusicActive()) {
+                            // TODO: Actually handle MUTE.
+                            mAudioManager.adjustStreamVolume(
+                                        AudioManager.STREAM_MUSIC,
+                                        keyCode == KeyEvent.KEYCODE_VOLUME_UP
+                                                ? AudioManager.ADJUST_RAISE
+                                                : AudioManager.ADJUST_LOWER,
+                                        0);
+                        }
+                        // Don't execute default volume behavior
+                        return true;
+                    } else {
+                        return false;
                     }
-                    // Volume buttons should only function for music.
-                    if (mAudioManager.isMusicActive()) {
-                        // TODO: Actually handle MUTE.
-                        mAudioManager.adjustStreamVolume(
-                                    AudioManager.STREAM_MUSIC,
-                                    keyCode == KeyEvent.KEYCODE_VOLUME_UP
-                                            ? AudioManager.ADJUST_RAISE
-                                            : AudioManager.ADJUST_LOWER,
-                                    0);
-                    }
-                    // Don't execute default volume behavior
-                    return true;
                 }
             }
         } else if (event.getAction() == KeyEvent.ACTION_UP) {
diff --git a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
index 11da17c5..67a6855 100644
--- a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
+++ b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
@@ -132,10 +132,6 @@
     // So the user has a consistent amount of time when brought to the backup method from FaceLock
     private final int BACKUP_LOCK_TIMEOUT = 5000;
 
-    // Needed to keep track of failed FaceUnlock attempts
-    private int mFailedFaceUnlockAttempts = 0;
-    private static final int FAILED_FACE_UNLOCK_ATTEMPTS_BEFORE_BACKUP = 15;
-
     /**
      * The current {@link KeyguardScreen} will use this to communicate back to us.
      */
@@ -370,14 +366,15 @@
 
             public void takeEmergencyCallAction() {
                 mHasOverlay = true;
-                // FaceLock must be stopped if it is running when emergency call is pressed
-                stopAndUnbindFromFaceLock();
 
                 // Continue showing FaceLock area until dialer comes up or call is resumed
                 if (usingFaceLock() && mFaceLockServiceRunning) {
                     showFaceLockAreaWithTimeout(FACELOCK_VIEW_AREA_EMERGENCY_DIALER_TIMEOUT);
                 }
 
+                // FaceLock must be stopped if it is running when emergency call is pressed
+                stopAndUnbindFromFaceLock();
+
                 pokeWakelock(EMERGENCY_CALL_TIMEOUT);
                 if (TelephonyManager.getDefault().getCallState()
                         == TelephonyManager.CALL_STATE_OFFHOOK) {
@@ -464,7 +461,6 @@
             }
 
             public void reportSuccessfulUnlockAttempt() {
-                mFailedFaceUnlockAttempts = 0;
                 mLockPatternUtils.reportSuccessfulPasswordAttempt();
             }
         };
@@ -583,8 +579,7 @@
      *  FaceLock, but only if we're not dealing with a call
     */
     private void activateFaceLockIfAble() {
-        final boolean tooManyFaceUnlockTries =
-                (mFailedFaceUnlockAttempts >= FAILED_FACE_UNLOCK_ATTEMPTS_BEFORE_BACKUP);
+        final boolean tooManyFaceUnlockTries = mUpdateMonitor.getMaxFaceUnlockAttemptsReached();
         final int failedBackupAttempts = mUpdateMonitor.getFailedAttempts();
         final boolean backupIsTimedOut =
                 (failedBackupAttempts >= LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT);
@@ -1398,7 +1393,7 @@
         @Override
         public void reportFailedAttempt() {
             if (DEBUG) Log.d(TAG, "FaceLock reportFailedAttempt()");
-            mFailedFaceUnlockAttempts++;
+            mUpdateMonitor.reportFailedFaceUnlockAttempt();
             hideFaceLockArea(); // Expose fallback
             stopFaceLock();
             mKeyguardScreenCallback.pokeWakelock(BACKUP_LOCK_TIMEOUT);
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 72856b8..92260d6 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -40,12 +40,12 @@
 import android.graphics.Rect;
 import android.graphics.RectF;
 import android.os.BatteryManager;
-import android.os.Binder;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.IRemoteCallback;
 import android.os.LocalPowerManager;
+import android.os.Looper;
 import android.os.Message;
 import android.os.Messenger;
 import android.os.PowerManager;
@@ -62,20 +62,21 @@
 import com.android.internal.policy.PolicyManager;
 import com.android.internal.statusbar.IStatusBarService;
 import com.android.internal.telephony.ITelephony;
-import com.android.internal.view.BaseInputHandler;
 import com.android.internal.widget.PointerLocationView;
 
 import android.util.DisplayMetrics;
 import android.util.EventLog;
 import android.util.Log;
 import android.util.Slog;
+import android.util.SparseArray;
 import android.view.Gravity;
 import android.view.HapticFeedbackConstants;
+import android.view.IApplicationToken;
 import android.view.IWindowManager;
 import android.view.InputChannel;
 import android.view.InputDevice;
-import android.view.InputQueue;
-import android.view.InputHandler;
+import android.view.InputEvent;
+import android.view.InputEventReceiver;
 import android.view.KeyCharacterMap;
 import android.view.KeyEvent;
 import android.view.MotionEvent;
@@ -230,7 +231,30 @@
     // Useful scan codes.
     private static final int SW_LID = 0x00;
     private static final int BTN_MOUSE = 0x110;
-    
+
+    /* Table of Application Launch keys.  Maps from key codes to intent categories.
+     *
+     * These are special keys that are used to launch particular kinds of applications,
+     * such as a web browser.  HID defines nearly a hundred of them in the Consumer (0x0C)
+     * usage page.  We don't support quite that many yet...
+     */
+    static SparseArray<String> sApplicationLaunchKeyCategories;
+    static {
+        sApplicationLaunchKeyCategories = new SparseArray<String>();
+        sApplicationLaunchKeyCategories.append(
+                KeyEvent.KEYCODE_EXPLORER, Intent.CATEGORY_APP_BROWSER);
+        sApplicationLaunchKeyCategories.append(
+                KeyEvent.KEYCODE_ENVELOPE, Intent.CATEGORY_APP_EMAIL);
+        sApplicationLaunchKeyCategories.append(
+                KeyEvent.KEYCODE_CONTACTS, Intent.CATEGORY_APP_CONTACTS);
+        sApplicationLaunchKeyCategories.append(
+                KeyEvent.KEYCODE_CALENDAR, Intent.CATEGORY_APP_CALENDAR);
+        sApplicationLaunchKeyCategories.append(
+                KeyEvent.KEYCODE_MUSIC, Intent.CATEGORY_APP_MUSIC);
+        sApplicationLaunchKeyCategories.append(
+                KeyEvent.KEYCODE_CALCULATOR, Intent.CATEGORY_APP_CALCULATOR);
+    }
+
     /**
      * Lock protecting internal state.  Must not call out into window
      * manager with lock held.  (This lock will be acquired in places
@@ -319,26 +343,34 @@
 
     // The last window we were told about in focusChanged.
     WindowState mFocusedWindow;
+    IApplicationToken mFocusedApp;
 
-    private final InputHandler mPointerLocationInputHandler = new BaseInputHandler() {
+    final class PointerLocationInputEventReceiver extends InputEventReceiver {
+        public PointerLocationInputEventReceiver(InputChannel inputChannel, Looper looper) {
+            super(inputChannel, looper);
+        }
+
         @Override
-        public void handleMotion(MotionEvent event, InputQueue.FinishedCallback finishedCallback) {
+        public void onInputEvent(InputEvent event) {
             boolean handled = false;
             try {
-                if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) {
+                if (event instanceof MotionEvent
+                        && (event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) {
+                    final MotionEvent motionEvent = (MotionEvent)event;
                     synchronized (mLock) {
                         if (mPointerLocationView != null) {
-                            mPointerLocationView.addPointerEvent(event);
+                            mPointerLocationView.addPointerEvent(motionEvent);
                             handled = true;
                         }
                     }
                 }
             } finally {
-                finishedCallback.finished(handled);
+                finishInputEvent(event, handled);
             }
         }
-    };
-    
+    }
+    PointerLocationInputEventReceiver mPointerLocationInputEventReceiver;
+
     // The current size of the screen; really; (ir)regardless of whether the status
     // bar can be hidden or not
     int mUnrestrictedScreenLeft, mUnrestrictedScreenTop;
@@ -975,9 +1007,10 @@
             if (mPointerLocationInputChannel == null) {
                 try {
                     mPointerLocationInputChannel =
-                        mWindowManager.monitorInput("PointerLocationView");
-                    InputQueue.registerInputChannel(mPointerLocationInputChannel,
-                            mPointerLocationInputHandler, mHandler.getLooper().getQueue());
+                            mWindowManager.monitorInput("PointerLocationView");
+                    mPointerLocationInputEventReceiver =
+                            new PointerLocationInputEventReceiver(
+                                    mPointerLocationInputChannel, mHandler.getLooper());
                 } catch (RemoteException ex) {
                     Slog.e(TAG, "Could not set up input monitoring channel for PointerLocation.",
                             ex);
@@ -985,8 +1018,11 @@
             }
         }
         if (removeView != null) {
+            if (mPointerLocationInputEventReceiver != null) {
+                mPointerLocationInputEventReceiver.dispose();
+                mPointerLocationInputEventReceiver = null;
+            }
             if (mPointerLocationInputChannel != null) {
-                InputQueue.unregisterInputChannel(mPointerLocationInputChannel);
                 mPointerLocationInputChannel.dispose();
                 mPointerLocationInputChannel = null;
             }
@@ -1649,6 +1685,22 @@
             }
         }
 
+        // Handle application launch keys.
+        if (down && repeatCount == 0) {
+            String category = sApplicationLaunchKeyCategories.get(keyCode);
+            if (category != null) {
+                Intent intent = Intent.makeMainSelectorActivity(Intent.ACTION_MAIN, category);
+                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+                try {
+                    mContext.startActivity(intent);
+                } catch (ActivityNotFoundException ex) {
+                    Slog.w(TAG, "Dropping application launch key because "
+                            + "the activity to which it is registered was not found: "
+                            + "keyCode=" + keyCode + ", category=" + category, ex);
+                }
+            }
+        }
+
         return 0;
     }
 
@@ -1794,13 +1846,19 @@
      * to determine when the nav bar should be shown and prevent applications from
      * receiving those touches.
      */
-    final InputHandler mHideNavInputHandler = new BaseInputHandler() {
+    final class HideNavInputEventReceiver extends InputEventReceiver {
+        public HideNavInputEventReceiver(InputChannel inputChannel, Looper looper) {
+            super(inputChannel, looper);
+        }
+
         @Override
-        public void handleMotion(MotionEvent event, InputQueue.FinishedCallback finishedCallback) {
+        public void onInputEvent(InputEvent event) {
             boolean handled = false;
             try {
-                if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) {
-                    if (event.getAction() == MotionEvent.ACTION_DOWN) {
+                if (event instanceof MotionEvent
+                        && (event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) {
+                    final MotionEvent motionEvent = (MotionEvent)event;
+                    if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
                         // When the user taps down, we re-show the nav bar.
                         boolean changed = false;
                         synchronized (mLock) {
@@ -1837,9 +1895,17 @@
                     }
                 }
             } finally {
-                finishedCallback.finished(handled);
+                finishInputEvent(event, handled);
             }
         }
+    }
+    final InputEventReceiver.Factory mHideNavInputEventReceiverFactory =
+            new InputEventReceiver.Factory() {
+        @Override
+        public InputEventReceiver createInputEventReceiver(
+                InputChannel inputChannel, Looper looper) {
+            return new HideNavInputEventReceiver(inputChannel, looper);
+        }
     };
 
     @Override
@@ -1903,7 +1969,7 @@
             }
         } else if (mHideNavFakeWindow == null) {
             mHideNavFakeWindow = mWindowManagerFuncs.addFakeWindow(
-                    mHandler.getLooper(), mHideNavInputHandler,
+                    mHandler.getLooper(), mHideNavInputEventReceiverFactory,
                     "hidden nav", WindowManager.LayoutParams.TYPE_HIDDEN_NAV_CONSUMER,
                     0, false, false, true);
         }
@@ -3147,10 +3213,7 @@
             }
 
             final int preferredRotation;
-            if (mHdmiPlugged) {
-                // Ignore sensor when plugged into HDMI.
-                preferredRotation = mHdmiRotation;
-            } else if (mLidOpen == LID_OPEN && mLidOpenRotation >= 0) {
+            if (mLidOpen == LID_OPEN && mLidOpenRotation >= 0) {
                 // Ignore sensor when lid switch is open and rotation is forced.
                 preferredRotation = mLidOpenRotation;
             } else if (mDockMode == Intent.EXTRA_DOCK_STATE_CAR
@@ -3169,6 +3232,10 @@
                 // enable 180 degree rotation while docked.
                 preferredRotation = mDeskDockEnablesAccelerometer
                         ? sensorRotation : mDeskDockRotation;
+            } else if (mHdmiPlugged) {
+                // Ignore sensor when plugged into HDMI.
+                // Note that the dock orientation overrides the HDMI orientation.
+                preferredRotation = mHdmiRotation;
             } else if ((mAccelerometerDefault != 0 /* implies not rotation locked */
                             && (orientation == ActivityInfo.SCREEN_ORIENTATION_USER
                                     || orientation == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED))
@@ -3411,6 +3478,9 @@
                             WindowManager.LayoutParams.FLAG_DIM_BEHIND
                             | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN);
                     mBootMsgDialog.getWindow().setDimAmount(1);
+                    WindowManager.LayoutParams lp = mBootMsgDialog.getWindow().getAttributes();
+                    lp.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_NOSENSOR;
+                    mBootMsgDialog.getWindow().setAttributes(lp);
                     mBootMsgDialog.setCancelable(false);
                     mBootMsgDialog.show();
                 }
@@ -3468,6 +3538,15 @@
                 if (localLOGV) Log.v(TAG, "mScreenSaverActivator: not running screen saver when not plugged in");
                 return;
             }
+            // Quick fix for automation tests.
+            // The correct fix is to move this triggering logic to PowerManager, where more complete
+            // information about wakelocks (including StayOnWhilePluggedIn) is available.
+            if (Settings.System.getInt(mContext.getContentResolver(),
+                        Settings.System.STAY_ON_WHILE_PLUGGED_IN,
+                        BatteryManager.BATTERY_PLUGGED_AC) != 0) {
+                Log.v(TAG, "mScreenSaverActivator: not running screen saver when STAY_ON_WHILE_PLUGGED_IN");
+                return;
+            }
 
             if (localLOGV) Log.v(TAG, "mScreenSaverActivator entering dreamland");
 
@@ -3479,7 +3558,8 @@
                 }
                 if (component != null) {
                     // dismiss the notification shade, recents, etc.
-                    mContext.sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));
+                    mContext.sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)
+                            .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT));
 
                     ComponentName cn = ComponentName.unflattenFromString(component);
                     Intent intent = new Intent(Intent.ACTION_MAIN)
@@ -3765,11 +3845,13 @@
         int diff = visibility ^ mLastSystemUiFlags;
         final boolean needsMenu = (mFocusedWindow.getAttrs().flags
                 & WindowManager.LayoutParams.FLAG_NEEDS_MENU_KEY) != 0;
-        if (diff == 0 && mLastFocusNeedsMenu == needsMenu) {
+        if (diff == 0 && mLastFocusNeedsMenu == needsMenu
+                && mFocusedApp == mFocusedWindow.getAppToken()) {
             return 0;
         }
         mLastSystemUiFlags = visibility;
         mLastFocusNeedsMenu = needsMenu;
+        mFocusedApp = mFocusedWindow.getAppToken();
         mHandler.post(new Runnable() {
                 public void run() {
                     if (mStatusBarService == null) {
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 66537df..b48f23d 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -89,6 +89,12 @@
 
 static const nsecs_t kSetParametersTimeout = seconds(2);
 
+// minimum sleep time for the mixer thread loop when tracks are active but in underrun
+static const uint32_t kMinThreadSleepTimeUs = 5000;
+// maximum divider applied to the active sleep time in the mixer thread loop
+static const uint32_t kMaxThreadSleepTimeShift = 2;
+
+
 // ----------------------------------------------------------------------------
 
 static bool recordingAllowed() {
@@ -1810,6 +1816,18 @@
     return &mOutput->stream->common;
 }
 
+uint32_t AudioFlinger::PlaybackThread::activeSleepTimeUs()
+{
+    // A2DP output latency is not due only to buffering capacity. It also reflects encoding,
+    // decoding and transfer time. So sleeping for half of the latency would likely cause
+    // underruns
+    if (audio_is_a2dp_device((audio_devices_t)mDevice)) {
+        return (uint32_t)((uint32_t)((mFrameCount * 1000) / mSampleRate) * 1000);
+    } else {
+        return (uint32_t)(mOutput->stream->get_latency(mOutput->stream) * 1000) / 2;
+    }
+}
+
 // ----------------------------------------------------------------------------
 
 AudioFlinger::MixerThread::MixerThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, int id, uint32_t device)
@@ -1846,6 +1864,7 @@
     uint32_t activeSleepTime = activeSleepTimeUs();
     uint32_t idleSleepTime = idleSleepTimeUs();
     uint32_t sleepTime = idleSleepTime;
+    uint32_t sleepTimeShift = 0;
     Vector< sp<EffectChain> > effectChains;
 #ifdef DEBUG_CPU_USAGE
     ThreadCpuUsage cpu;
@@ -1937,6 +1956,7 @@
 
                     standbyTime = systemTime() + kStandbyTimeInNsecs;
                     sleepTime = idleSleepTime;
+                    sleepTimeShift = 0;
                     continue;
                 }
             }
@@ -1953,6 +1973,10 @@
             // mix buffers...
             mAudioMixer->process();
             sleepTime = 0;
+            // increase sleep time progressively when application underrun condition clears
+            if (sleepTimeShift > 0) {
+                sleepTimeShift--;
+            }
             standbyTime = systemTime() + kStandbyTimeInNsecs;
             //TODO: delay standby when effects have a tail
         } else {
@@ -1960,7 +1984,17 @@
             // buffer size, then write 0s to the output
             if (sleepTime == 0) {
                 if (mixerStatus == MIXER_TRACKS_ENABLED) {
-                    sleepTime = activeSleepTime;
+                    sleepTime = activeSleepTime >> sleepTimeShift;
+                    if (sleepTime < kMinThreadSleepTimeUs) {
+                        sleepTime = kMinThreadSleepTimeUs;
+                    }
+                    // reduce sleep time in case of consecutive application underruns to avoid
+                    // starving the audio HAL. As activeSleepTimeUs() is larger than a buffer
+                    // duration we would end up writing less data than needed by the audio HAL if
+                    // the condition persists.
+                    if (sleepTimeShift < kMaxThreadSleepTimeShift) {
+                        sleepTimeShift++;
+                    }
                 } else {
                     sleepTime = idleSleepTime;
                 }
@@ -2400,11 +2434,6 @@
     return NO_ERROR;
 }
 
-uint32_t AudioFlinger::MixerThread::activeSleepTimeUs()
-{
-    return (uint32_t)(mOutput->stream->get_latency(mOutput->stream) * 1000) / 2;
-}
-
 uint32_t AudioFlinger::MixerThread::idleSleepTimeUs()
 {
     return (uint32_t)(((mFrameCount * 1000) / mSampleRate) * 1000) / 2;
@@ -2871,7 +2900,7 @@
 {
     uint32_t time;
     if (audio_is_linear_pcm(mFormat)) {
-        time = (uint32_t)(mOutput->stream->get_latency(mOutput->stream) * 1000) / 2;
+        time = PlaybackThread::activeSleepTimeUs();
     } else {
         time = 10000;
     }
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 897bc78..6cafa7e 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -776,7 +776,7 @@
 
         virtual int             getTrackName_l() = 0;
         virtual void            deleteTrackName_l(int name) = 0;
-        virtual uint32_t        activeSleepTimeUs() = 0;
+        virtual uint32_t        activeSleepTimeUs();
         virtual uint32_t        idleSleepTimeUs() = 0;
         virtual uint32_t        suspendSleepTimeUs() = 0;
 
@@ -833,7 +833,6 @@
                                                 Vector< sp<Track> > *tracksToRemove);
         virtual     int         getTrackName_l();
         virtual     void        deleteTrackName_l(int name);
-        virtual     uint32_t    activeSleepTimeUs();
         virtual     uint32_t    idleSleepTimeUs();
         virtual     uint32_t    suspendSleepTimeUs();
 
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index bb0e664..4760f07 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -361,7 +361,7 @@
 
     // Enable zoom, error, focus, and metadata messages by default
     enableMsgType(CAMERA_MSG_ERROR | CAMERA_MSG_ZOOM | CAMERA_MSG_FOCUS |
-                  CAMERA_MSG_PREVIEW_METADATA);
+                  CAMERA_MSG_PREVIEW_METADATA | CAMERA_MSG_FOCUS_MOVE);
 
     // Callback is disabled by default
     mPreviewCallbackFlag = CAMERA_FRAME_CALLBACK_FLAG_NOOP;
diff --git a/services/java/com/android/server/AppWidgetService.java b/services/java/com/android/server/AppWidgetService.java
index 2af5103..4f81178 100644
--- a/services/java/com/android/server/AppWidgetService.java
+++ b/services/java/com/android/server/AppWidgetService.java
@@ -24,9 +24,9 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.content.Intent.FilterComparison;
 import android.content.IntentFilter;
 import android.content.ServiceConnection;
-import android.content.Intent.FilterComparison;
 import android.content.pm.ActivityInfo;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageInfo;
@@ -39,6 +39,8 @@
 import android.net.Uri;
 import android.os.Binder;
 import android.os.Bundle;
+import android.os.Handler;
+import android.os.HandlerThread;
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.os.SystemClock;
@@ -74,6 +76,7 @@
 import java.util.Iterator;
 import java.util.List;
 import java.util.Locale;
+import java.util.Set;
 
 class AppWidgetService extends IAppWidgetService.Stub
 {
@@ -805,6 +808,45 @@
                     id.host.callbacks = null;
                 }
             }
+
+            // If the host is unavailable, then we call the associated
+            // RemoteViewsFactory.onDataSetChanged() directly
+            if (id.host.callbacks == null) {
+                Set<FilterComparison> keys = mRemoteViewsServicesAppWidgets.keySet();
+                for (FilterComparison key : keys) {
+                    if (mRemoteViewsServicesAppWidgets.get(key).contains(id.appWidgetId)) {
+                        Intent intent = key.getIntent();
+
+                        final ServiceConnection conn = new ServiceConnection() {
+                            @Override
+                            public void onServiceConnected(ComponentName name, IBinder service) {
+                                IRemoteViewsFactory cb =
+                                    IRemoteViewsFactory.Stub.asInterface(service);
+                                try {
+                                    cb.onDataSetChangedAsync();
+                                } catch (RemoteException e) {
+                                    e.printStackTrace();
+                                } catch (RuntimeException e) {
+                                    e.printStackTrace();
+                                }
+                                mContext.unbindService(this);
+                            }
+                            @Override
+                            public void onServiceDisconnected(android.content.ComponentName name) {
+                                // Do nothing
+                            }
+                        };
+
+                        // Bind to the service and call onDataSetChanged()
+                        final long token = Binder.clearCallingIdentity();
+                        try {
+                            mContext.bindService(intent, conn, Context.BIND_AUTO_CREATE);
+                        } finally {
+                            Binder.restoreCallingIdentity(token);
+                        }
+                    }
+                }
+            }
         }
     }
 
diff --git a/services/java/com/android/server/DeviceStorageMonitorService.java b/services/java/com/android/server/DeviceStorageMonitorService.java
index d34087f..16eeb7ba 100644
--- a/services/java/com/android/server/DeviceStorageMonitorService.java
+++ b/services/java/com/android/server/DeviceStorageMonitorService.java
@@ -163,7 +163,6 @@
             } catch (IllegalArgumentException e) {
                 // ignore; report -1
             }
-            mCacheFileStats.restat(CACHE_PATH);
             EventLog.writeEvent(EventLogTags.FREE_STORAGE_LEFT,
                                 mFreeMem, mFreeSystem, mFreeCache);
         }
diff --git a/services/java/com/android/server/EventLogTags.logtags b/services/java/com/android/server/EventLogTags.logtags
index 5408436..4dad209 100644
--- a/services/java/com/android/server/EventLogTags.logtags
+++ b/services/java/com/android/server/EventLogTags.logtags
@@ -50,12 +50,12 @@
 # NotificationManagerService.java
 # ---------------------------
 # when a NotificationManager.notify is called
-2750 notification_enqueue (pkg|3),(id|1|5),(notification|3)
+2750 notification_enqueue (pkg|3),(id|1|5),(tag|3),(notification|3)
 # when someone tries to cancel a notification, the notification manager sometimes
 # calls this with flags too
-2751 notification_cancel (pkg|3),(id|1|5),(required_flags|1)
+2751 notification_cancel (pkg|3),(id|1|5),(tag|3),(required_flags|1),(forbidden_flags|1)
 # when someone tries to cancel all of the notifications for a particular package
-2752 notification_cancel_all (pkg|3),(required_flags|1)
+2752 notification_cancel_all (pkg|3),(required_flags|1),(forbidden_flags|1)
 
 
 # ---------------------------
diff --git a/services/java/com/android/server/MountService.java b/services/java/com/android/server/MountService.java
index 5425813..1dd6bca 100644
--- a/services/java/com/android/server/MountService.java
+++ b/services/java/com/android/server/MountService.java
@@ -20,6 +20,7 @@
 import com.android.internal.util.XmlUtils;
 import com.android.server.am.ActivityManagerService;
 import com.android.server.pm.PackageManagerService;
+import com.android.server.NativeDaemonConnector.Command;
 
 import android.Manifest;
 import android.content.BroadcastReceiver;
@@ -564,8 +565,7 @@
         }
 
         try {
-            mConnector.doCommand(String.format(
-                    "volume %sshare %s %s", (enable ? "" : "un"), path, method));
+            mConnector.execute("volume", enable ? "share" : "unshare", path, method);
         } catch (NativeDaemonConnectorException e) {
             Slog.e(TAG, "Failed to share/unshare", e);
         }
@@ -633,8 +633,9 @@
                  * Determine media state and UMS detection status
                  */
                 try {
-                    String[] vols = mConnector.doListCommand(
-                        "volume list", VoldResponseCode.VolumeListResult);
+                    final String[] vols = NativeDaemonEvent.filterMessageList(
+                            mConnector.executeForList("volume", "list"),
+                            VoldResponseCode.VolumeListResult);
                     for (String volstr : vols) {
                         String[] tok = volstr.split(" ");
                         // FMT: <label> <mountpoint> <state>
@@ -839,7 +840,7 @@
 
         if (DEBUG_EVENTS) Slog.i(TAG, "doMountVolume: Mouting " + path);
         try {
-            mConnector.doCommand(String.format("volume mount %s", path));
+            mConnector.execute("volume", "mount", path);
         } catch (NativeDaemonConnectorException e) {
             /*
              * Mount failed for some reason
@@ -909,10 +910,13 @@
         // Redundant probably. But no harm in updating state again.
         mPms.updateExternalMediaStatus(false, false);
         try {
-            String arg = removeEncryption
-                    ? " force_and_revert"
-                    : (force ? " force" : "");
-            mConnector.doCommand(String.format("volume unmount %s%s", path, arg));
+            final Command cmd = new Command("volume", "unmount", path);
+            if (removeEncryption) {
+                cmd.appendArg("force_and_revert");
+            } else if (force) {
+                cmd.appendArg("force");
+            }
+            mConnector.execute(cmd);
             // We unmounted the volume. None of the asec containers are available now.
             synchronized (mAsecMountSet) {
                 mAsecMountSet.clear();
@@ -934,8 +938,7 @@
 
     private int doFormatVolume(String path) {
         try {
-            String cmd = String.format("volume format %s", path);
-            mConnector.doCommand(cmd);
+            mConnector.execute("volume", "format", path);
             return StorageResultCode.OperationSucceeded;
         } catch (NativeDaemonConnectorException e) {
             int code = e.getCode();
@@ -950,39 +953,19 @@
     }
 
     private boolean doGetVolumeShared(String path, String method) {
-        String cmd = String.format("volume shared %s %s", path, method);
-        ArrayList<String> rsp;
-
+        final NativeDaemonEvent event;
         try {
-            rsp = mConnector.doCommand(cmd);
+            event = mConnector.execute("volume", "shared", path, method);
         } catch (NativeDaemonConnectorException ex) {
             Slog.e(TAG, "Failed to read response to volume shared " + path + " " + method);
             return false;
         }
 
-        for (String line : rsp) {
-            String[] tok = line.split(" ");
-            if (tok.length < 3) {
-                Slog.e(TAG, "Malformed response to volume shared " + path + " " + method + " command");
-                return false;
-            }
-
-            int code;
-            try {
-                code = Integer.parseInt(tok[0]);
-            } catch (NumberFormatException nfe) {
-                Slog.e(TAG, String.format("Error parsing code %s", tok[0]));
-                return false;
-            }
-            if (code == VoldResponseCode.ShareEnabledResult) {
-                return "enabled".equals(tok[2]);
-            } else {
-                Slog.e(TAG, String.format("Unexpected response code %d", code));
-                return false;
-            }
+        if (event.getCode() == VoldResponseCode.ShareEnabledResult) {
+            return event.getMessage().endsWith("enabled");
+        } else {
+            return false;
         }
-        Slog.e(TAG, "Got an empty response");
-        return false;
     }
 
     private void notifyShareAvailabilityChange(final boolean avail) {
@@ -1410,13 +1393,14 @@
         validatePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS);
         waitForReady();
         try {
-            String[] r = mConnector.doListCommand(
-                    String.format("storage users %s", path),
-                            VoldResponseCode.StorageUsersListResult);
+            final String[] r = NativeDaemonEvent.filterMessageList(
+                    mConnector.executeForList("storage", "users", path),
+                    VoldResponseCode.StorageUsersListResult);
+
             // FMT: <pid> <process name>
             int[] data = new int[r.length];
             for (int i = 0; i < r.length; i++) {
-                String []tok = r[i].split(" ");
+                String[] tok = r[i].split(" ");
                 try {
                     data[i] = Integer.parseInt(tok[0]);
                 } catch (NumberFormatException nfe) {
@@ -1443,7 +1427,8 @@
         warnOnNotMounted();
 
         try {
-            return mConnector.doListCommand("asec list", VoldResponseCode.AsecListResult);
+            return NativeDaemonEvent.filterMessageList(
+                    mConnector.executeForList("asec", "list"), VoldResponseCode.AsecListResult);
         } catch (NativeDaemonConnectorException e) {
             return new String[0];
         }
@@ -1456,9 +1441,8 @@
         warnOnNotMounted();
 
         int rc = StorageResultCode.OperationSucceeded;
-        String cmd = String.format("asec create %s %d %s %s %d", id, sizeMb, fstype, key, ownerUid);
         try {
-            mConnector.doCommand(cmd);
+            mConnector.execute("asec", "create", id, sizeMb, fstype, key, ownerUid);
         } catch (NativeDaemonConnectorException e) {
             rc = StorageResultCode.OperationFailedInternalError;
         }
@@ -1477,7 +1461,7 @@
 
         int rc = StorageResultCode.OperationSucceeded;
         try {
-            mConnector.doCommand(String.format("asec finalize %s", id));
+            mConnector.execute("asec", "finalize", id);
             /*
              * Finalization does a remount, so no need
              * to update mAsecMountSet
@@ -1503,7 +1487,11 @@
 
         int rc = StorageResultCode.OperationSucceeded;
         try {
-            mConnector.doCommand(String.format("asec destroy %s%s", id, (force ? " force" : "")));
+            final Command cmd = new Command("asec", "destroy", id);
+            if (force) {
+                cmd.appendArg("force");
+            }
+            mConnector.execute(cmd);
         } catch (NativeDaemonConnectorException e) {
             int code = e.getCode();
             if (code == VoldResponseCode.OpFailedStorageBusy) {
@@ -1536,9 +1524,8 @@
         }
 
         int rc = StorageResultCode.OperationSucceeded;
-        String cmd = String.format("asec mount %s %s %d", id, key, ownerUid);
         try {
-            mConnector.doCommand(cmd);
+            mConnector.execute("asec", "mount", id, key, ownerUid);
         } catch (NativeDaemonConnectorException e) {
             int code = e.getCode();
             if (code != VoldResponseCode.OpFailedStorageBusy) {
@@ -1574,9 +1561,12 @@
         Runtime.getRuntime().gc();
 
         int rc = StorageResultCode.OperationSucceeded;
-        String cmd = String.format("asec unmount %s%s", id, (force ? " force" : ""));
         try {
-            mConnector.doCommand(cmd);
+            final Command cmd = new Command("asec", "unmount", id);
+            if (force) {
+                cmd.appendArg("force");
+            }
+            mConnector.execute(cmd);
         } catch (NativeDaemonConnectorException e) {
             int code = e.getCode();
             if (code == VoldResponseCode.OpFailedStorageBusy) {
@@ -1620,9 +1610,8 @@
         }
 
         int rc = StorageResultCode.OperationSucceeded;
-        String cmd = String.format("asec rename %s %s", oldId, newId);
         try {
-            mConnector.doCommand(cmd);
+            mConnector.execute("asec", "rename", oldId, newId);
         } catch (NativeDaemonConnectorException e) {
             rc = StorageResultCode.OperationFailedInternalError;
         }
@@ -1635,14 +1624,11 @@
         waitForReady();
         warnOnNotMounted();
 
+        final NativeDaemonEvent event;
         try {
-            ArrayList<String> rsp = mConnector.doCommand(String.format("asec path %s", id));
-            String []tok = rsp.get(0).split(" ");
-            int code = Integer.parseInt(tok[0]);
-            if (code != VoldResponseCode.AsecPathResult) {
-                throw new IllegalStateException(String.format("Unexpected response code %d", code));
-            }
-            return tok[1];
+            event = mConnector.execute("asec", "path", id);
+            event.checkCode(VoldResponseCode.AsecPathResult);
+            return event.getMessage();
         } catch (NativeDaemonConnectorException e) {
             int code = e.getCode();
             if (code == VoldResponseCode.OpFailedStorageNotFound) {
@@ -1659,14 +1645,11 @@
         waitForReady();
         warnOnNotMounted();
 
+        final NativeDaemonEvent event;
         try {
-            ArrayList<String> rsp = mConnector.doCommand(String.format("asec fspath %s", id));
-            String []tok = rsp.get(0).split(" ");
-            int code = Integer.parseInt(tok[0]);
-            if (code != VoldResponseCode.AsecPathResult) {
-                throw new IllegalStateException(String.format("Unexpected response code %d", code));
-            }
-            return tok[1];
+            event = mConnector.execute("asec", "fspath", id);
+            event.checkCode(VoldResponseCode.AsecPathResult);
+            return event.getMessage();
         } catch (NativeDaemonConnectorException e) {
             int code = e.getCode();
             if (code == VoldResponseCode.OpFailedStorageNotFound) {
@@ -1709,14 +1692,11 @@
         waitForReady();
         warnOnNotMounted();
 
+        final NativeDaemonEvent event;
         try {
-            ArrayList<String> rsp = mConnector.doCommand(String.format("obb path %s", filename));
-            String []tok = rsp.get(0).split(" ");
-            int code = Integer.parseInt(tok[0]);
-            if (code != VoldResponseCode.AsecPathResult) {
-                throw new IllegalStateException(String.format("Unexpected response code %d", code));
-            }
-            return tok[1];
+            event = mConnector.execute("obb", "path", filename);
+            event.checkCode(VoldResponseCode.AsecPathResult);
+            return event.getMessage();
         } catch (NativeDaemonConnectorException e) {
             int code = e.getCode();
             if (code == VoldResponseCode.OpFailedStorageNotFound) {
@@ -1778,18 +1758,10 @@
 
         waitForReady();
 
+        final NativeDaemonEvent event;
         try {
-            ArrayList<String> rsp = mConnector.doCommand("cryptfs cryptocomplete");
-            String[] tokens = rsp.get(0).split(" ");
-
-            if (tokens == null || tokens.length != 2) {
-                // Unexpected.
-                Slog.w(TAG, "Unexpected result from cryptfs cryptocomplete");
-                return ENCRYPTION_STATE_ERROR_UNKNOWN;
-            }
-
-            return Integer.parseInt(tokens[1]);
-
+            event = mConnector.execute("cryptfs", "cryptocomplete");
+            return Integer.parseInt(event.getMessage());
         } catch (NumberFormatException e) {
             // Bad result - unexpected.
             Slog.w(TAG, "Unable to parse result from cryptfs cryptocomplete");
@@ -1816,22 +1788,21 @@
             Slog.i(TAG, "decrypting storage...");
         }
 
+        final NativeDaemonEvent event;
         try {
-            ArrayList<String> rsp = mConnector.doCommand("cryptfs checkpw " + password);
-            String[] tokens = rsp.get(0).split(" ");
+            event = mConnector.execute("cryptfs", "checkpw", password);
 
-            if (tokens == null || tokens.length != 2) {
-                return -1;
-            }
-
-            int code = Integer.parseInt(tokens[1]);
-
+            final int code = event.getCode();
             if (code == 0) {
                 // Decrypt was successful. Post a delayed message before restarting in order
                 // to let the UI to clear itself
                 mHandler.postDelayed(new Runnable() {
                     public void run() {
-                        mConnector.doCommand(String.format("cryptfs restart"));
+                        try {
+                            mConnector.execute("cryptfs", "restart");
+                        } catch (NativeDaemonConnectorException e) {
+                            Slog.e(TAG, "problem executing in background", e);
+                        }
                     }
                 }, 1000); // 1 second
             }
@@ -1858,7 +1829,7 @@
         }
 
         try {
-            mConnector.doCommand(String.format("cryptfs enablecrypto inplace %s", password));
+            mConnector.execute("cryptfs", "enablecrypto", "inplace", password);
         } catch (NativeDaemonConnectorException e) {
             // Encryption failed
             return e.getCode();
@@ -1881,16 +1852,10 @@
             Slog.i(TAG, "changing encryption password...");
         }
 
+        final NativeDaemonEvent event;
         try {
-            ArrayList<String> response = mConnector.doCommand("cryptfs changepw " + password);
-
-            String[] tokens = response.get(0).split(" ");
-
-            if (tokens == null || tokens.length != 2) {
-                return -1;
-            }
-
-            return Integer.parseInt(tokens[1]);
+            event = mConnector.execute("cryptfs", "changepw", password);
+            return Integer.parseInt(event.getMessage());
         } catch (NativeDaemonConnectorException e) {
             // Encryption failed
             return e.getCode();
@@ -1920,24 +1885,11 @@
             Slog.i(TAG, "validating encryption password...");
         }
 
+        final NativeDaemonEvent event;
         try {
-            ArrayList<String> response = mConnector.doCommand("cryptfs verifypw " + password);
-            String[] tokens = response.get(0).split(" ");
-
-            if (tokens == null || tokens.length != 2) {
-                String msg = "Unexpected result from cryptfs verifypw: {";
-                if (tokens == null) msg += "null";
-                else for (int i = 0; i < tokens.length; i++) {
-                    if (i != 0) msg += ',';
-                    msg += tokens[i];
-                }
-                msg += '}';
-                Slog.e(TAG, msg);
-                return -1;
-            }
-
-            Slog.i(TAG, "cryptfs verifypw => " + tokens[1]);
-            return Integer.parseInt(tokens[1]);
+            event = mConnector.execute("cryptfs", "verifypw", password);
+            Slog.i(TAG, "cryptfs verifypw => " + event.getMessage());
+            return Integer.parseInt(event.getMessage());
         } catch (NativeDaemonConnectorException e) {
             // Encryption failed
             return e.getCode();
@@ -2296,10 +2248,9 @@
             }
 
             int rc = StorageResultCode.OperationSucceeded;
-            String cmd = String.format("obb mount %s %s %d", mObbState.filename, hashedKey,
-                    mObbState.callerUid);
             try {
-                mConnector.doCommand(cmd);
+                mConnector.execute(
+                        "obb", "mount", mObbState.filename, hashedKey, mObbState.callerUid);
             } catch (NativeDaemonConnectorException e) {
                 int code = e.getCode();
                 if (code != VoldResponseCode.OpFailedStorageBusy) {
@@ -2380,10 +2331,12 @@
             mObbState.filename = obbInfo.filename;
 
             int rc = StorageResultCode.OperationSucceeded;
-            String cmd = String.format("obb unmount %s%s", mObbState.filename,
-                    (mForceUnmount ? " force" : ""));
             try {
-                mConnector.doCommand(cmd);
+                final Command cmd = new Command("obb", "unmount", mObbState.filename);
+                if (mForceUnmount) {
+                    cmd.appendArg("force");
+                }
+                mConnector.execute(cmd);
             } catch (NativeDaemonConnectorException e) {
                 int code = e.getCode();
                 if (code == VoldResponseCode.OpFailedStorageBusy) {
diff --git a/services/java/com/android/server/NativeDaemonConnector.java b/services/java/com/android/server/NativeDaemonConnector.java
index 28013bd..cc2bcd9 100644
--- a/services/java/com/android/server/NativeDaemonConnector.java
+++ b/services/java/com/android/server/NativeDaemonConnector.java
@@ -24,57 +24,44 @@
 import android.os.SystemClock;
 import android.util.Slog;
 
+import com.google.android.collect.Lists;
+
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.nio.charset.Charsets;
 import java.util.ArrayList;
 import java.util.concurrent.BlockingQueue;
 import java.util.concurrent.LinkedBlockingQueue;
 
 /**
- * Generic connector class for interfacing with a native
- * daemon which uses the libsysutils FrameworkListener
- * protocol.
+ * Generic connector class for interfacing with a native daemon which uses the
+ * {@code libsysutils} FrameworkListener protocol.
  */
 final class NativeDaemonConnector implements Runnable, Handler.Callback, Watchdog.Monitor {
-    private static final boolean LOCAL_LOGD = false;
+    private static final boolean LOGD = false;
 
-    private BlockingQueue<String> mResponseQueue;
-    private OutputStream          mOutputStream;
-    private String                TAG = "NativeDaemonConnector";
-    private String                mSocket;
+    private final String TAG;
+
+    private String mSocket;
+    private OutputStream mOutputStream;
+
+    private final BlockingQueue<NativeDaemonEvent> mResponseQueue;
+
     private INativeDaemonConnectorCallbacks mCallbacks;
-    private Handler               mCallbackHandler;
+    private Handler mCallbackHandler;
 
     /** Lock held whenever communicating with native daemon. */
-    private Object mDaemonLock = new Object();
+    private final Object mDaemonLock = new Object();
 
     private final int BUFFER_SIZE = 4096;
 
-    class ResponseCode {
-        public static final int ActionInitiated                = 100;
-
-        public static final int CommandOkay                    = 200;
-
-        // The range of 400 -> 599 is reserved for cmd failures
-        public static final int OperationFailed                = 400;
-        public static final int CommandSyntaxError             = 500;
-        public static final int CommandParameterError          = 501;
-
-        public static final int UnsolicitedInformational       = 600;
-
-        //
-        public static final int FailedRangeStart               = 400;
-        public static final int FailedRangeEnd                 = 599;
-    }
-
-    NativeDaemonConnector(INativeDaemonConnectorCallbacks callbacks,
-                          String socket, int responseQueueSize, String logTag) {
+    NativeDaemonConnector(INativeDaemonConnectorCallbacks callbacks, String socket,
+            int responseQueueSize, String logTag) {
         mCallbacks = callbacks;
-        if (logTag != null)
-            TAG = logTag;
         mSocket = socket;
-        mResponseQueue = new LinkedBlockingQueue<String>(responseQueueSize);
+        mResponseQueue = new LinkedBlockingQueue<NativeDaemonEvent>(responseQueueSize);
+        TAG = logTag != null ? logTag : "NativeDaemonConnector";
     }
 
     @Override
@@ -136,26 +123,28 @@
 
                 for (int i = 0; i < count; i++) {
                     if (buffer[i] == 0) {
-                        String event = new String(buffer, start, i - start);
-                        if (LOCAL_LOGD) Slog.d(TAG, String.format("RCV <- {%s}", event));
+                        final String rawEvent = new String(
+                                buffer, start, i - start, Charsets.UTF_8);
+                        if (LOGD) Slog.d(TAG, "RCV <- " + rawEvent);
 
-                        String[] tokens = event.split(" ", 2);
                         try {
-                            int code = Integer.parseInt(tokens[0]);
-
-                            if (code >= ResponseCode.UnsolicitedInformational) {
-                                mCallbackHandler.sendMessage(
-                                        mCallbackHandler.obtainMessage(code, event));
+                            final NativeDaemonEvent event = NativeDaemonEvent.parseRawEvent(
+                                    rawEvent);
+                            if (event.isClassUnsolicited()) {
+                                // TODO: migrate to sending NativeDaemonEvent instances
+                                mCallbackHandler.sendMessage(mCallbackHandler.obtainMessage(
+                                        event.getCode(), event.getRawEvent()));
                             } else {
                                 try {
                                     mResponseQueue.put(event);
                                 } catch (InterruptedException ex) {
-                                    Slog.e(TAG, "Failed to put response onto queue", ex);
+                                    Slog.e(TAG, "Failed to put response onto queue: " + ex);
                                 }
                             }
-                        } catch (NumberFormatException nfe) {
-                            Slog.w(TAG, String.format("Bad msg (%s)", event));
+                        } catch (IllegalArgumentException e) {
+                            Slog.w(TAG, "Problem parsing message: " + rawEvent, e);
                         }
+
                         start = i + 1;
                     }
                 }
@@ -195,133 +184,248 @@
         }
     }
 
-    private void sendCommandLocked(String command) throws NativeDaemonConnectorException {
-        sendCommandLocked(command, null);
-    }
-
     /**
-     * Sends a command to the daemon with a single argument
+     * Send command to daemon, escaping arguments as needed.
      *
-     * @param command  The command to send to the daemon
-     * @param argument The argument to send with the command (or null)
+     * @return the final command issued.
      */
-    private void sendCommandLocked(String command, String argument)
+    private String sendCommandLocked(String cmd, Object... args)
             throws NativeDaemonConnectorException {
-        if (command != null && command.indexOf('\0') >= 0) {
-            throw new IllegalArgumentException("unexpected command: " + command);
-        }
-        if (argument != null && argument.indexOf('\0') >= 0) {
-            throw new IllegalArgumentException("unexpected argument: " + argument);
+        // TODO: eventually enforce that cmd doesn't contain arguments
+        if (cmd.indexOf('\0') >= 0) {
+            throw new IllegalArgumentException("unexpected command: " + cmd);
         }
 
-        if (LOCAL_LOGD) Slog.d(TAG, String.format("SND -> {%s} {%s}", command, argument));
+        final StringBuilder builder = new StringBuilder(cmd);
+        for (Object arg : args) {
+            final String argString = String.valueOf(arg);
+            if (argString.indexOf('\0') >= 0) {
+                throw new IllegalArgumentException("unexpected argument: " + arg);
+            }
+
+            builder.append(' ');
+            appendEscaped(builder, argString);
+        }
+
+        final String unterminated = builder.toString();
+        if (LOGD) Slog.d(TAG, "SND -> " + unterminated);
+
+        builder.append('\0');
+
         if (mOutputStream == null) {
-            Slog.e(TAG, "No connection to daemon", new IllegalStateException());
-            throw new NativeDaemonConnectorException("No output stream!");
+            throw new NativeDaemonConnectorException("missing output stream");
         } else {
-            StringBuilder builder = new StringBuilder(command);
-            if (argument != null) {
-                builder.append(argument);
-            }
-            builder.append('\0');
-
             try {
-                mOutputStream.write(builder.toString().getBytes());
-            } catch (IOException ex) {
-                Slog.e(TAG, "IOException in sendCommand", ex);
+                mOutputStream.write(builder.toString().getBytes(Charsets.UTF_8));
+            } catch (IOException e) {
+                throw new NativeDaemonConnectorException("problem sending command", e);
             }
         }
+
+        return unterminated;
     }
 
     /**
-     * Issue a command to the native daemon and return the responses
+     * Issue the given command to the native daemon and return a single expected
+     * response.
+     *
+     * @throws NativeDaemonConnectorException when problem communicating with
+     *             native daemon, or if the response matches
+     *             {@link NativeDaemonEvent#isClassClientError()} or
+     *             {@link NativeDaemonEvent#isClassServerError()}.
      */
-    public ArrayList<String> doCommand(String cmd) throws NativeDaemonConnectorException {
-        synchronized (mDaemonLock) {
-            return doCommandLocked(cmd);
-        }
-    }
-
-    private ArrayList<String> doCommandLocked(String cmd) throws NativeDaemonConnectorException {
-        mResponseQueue.clear();
-        sendCommandLocked(cmd);
-
-        ArrayList<String> response = new ArrayList<String>();
-        boolean complete = false;
-        int code = -1;
-
-        while (!complete) {
-            try {
-                // TODO - this should not block forever
-                String line = mResponseQueue.take();
-                if (LOCAL_LOGD) Slog.d(TAG, String.format("RSP <- {%s}", line));
-                String[] tokens = line.split(" ");
-                try {
-                    code = Integer.parseInt(tokens[0]);
-                } catch (NumberFormatException nfe) {
-                    throw new NativeDaemonConnectorException(
-                            String.format("Invalid response from daemon (%s)", line));
-                }
-
-                if ((code >= 200) && (code < 600)) {
-                    complete = true;
-                }
-                response.add(line);
-            } catch (InterruptedException ex) {
-                Slog.e(TAG, "Failed to process response", ex);
-            }
-        }
-
-        if (code >= ResponseCode.FailedRangeStart &&
-                code <= ResponseCode.FailedRangeEnd) {
-            /*
-             * Note: The format of the last response in this case is
-             *        "NNN <errmsg>"
-             */
-            throw new NativeDaemonConnectorException(
-                    code, cmd, response.get(response.size()-1).substring(4));
-        }
-        return response;
+    public NativeDaemonEvent execute(Command cmd) throws NativeDaemonConnectorException {
+        return execute(cmd.mCmd, cmd.mArguments.toArray());
     }
 
     /**
-     * Issues a list command and returns the cooked list
+     * Issue the given command to the native daemon and return a single expected
+     * response.
+     *
+     * @throws NativeDaemonConnectorException when problem communicating with
+     *             native daemon, or if the response matches
+     *             {@link NativeDaemonEvent#isClassClientError()} or
+     *             {@link NativeDaemonEvent#isClassServerError()}.
      */
-    public String[] doListCommand(String cmd, int expectedResponseCode)
+    public NativeDaemonEvent execute(String cmd, Object... args)
             throws NativeDaemonConnectorException {
+        final NativeDaemonEvent[] events = executeForList(cmd, args);
+        if (events.length != 1) {
+            throw new NativeDaemonConnectorException(
+                    "Expected exactly one response, but received " + events.length);
+        }
+        return events[0];
+    }
 
-        ArrayList<String> rsp = doCommand(cmd);
-        String[] rdata = new String[rsp.size()-1];
-        int idx = 0;
+    /**
+     * Issue the given command to the native daemon and return any
+     * {@link NativeDaemonEvent#isClassContinue()} responses, including the
+     * final terminal response.
+     *
+     * @throws NativeDaemonConnectorException when problem communicating with
+     *             native daemon, or if the response matches
+     *             {@link NativeDaemonEvent#isClassClientError()} or
+     *             {@link NativeDaemonEvent#isClassServerError()}.
+     */
+    public NativeDaemonEvent[] executeForList(Command cmd) throws NativeDaemonConnectorException {
+        return executeForList(cmd.mCmd, cmd.mArguments.toArray());
+    }
 
-        for (int i = 0; i < rsp.size(); i++) {
-            String line = rsp.get(i);
+    /**
+     * Issue the given command to the native daemon and return any
+     * {@link NativeDaemonEvent#isClassContinue()} responses, including the
+     * final terminal response.
+     *
+     * @throws NativeDaemonConnectorException when problem communicating with
+     *             native daemon, or if the response matches
+     *             {@link NativeDaemonEvent#isClassClientError()} or
+     *             {@link NativeDaemonEvent#isClassServerError()}.
+     */
+    public NativeDaemonEvent[] executeForList(String cmd, Object... args)
+            throws NativeDaemonConnectorException {
+        synchronized (mDaemonLock) {
+            return executeLocked(cmd, args);
+        }
+    }
+
+    private NativeDaemonEvent[] executeLocked(String cmd, Object... args)
+            throws NativeDaemonConnectorException {
+        final ArrayList<NativeDaemonEvent> events = Lists.newArrayList();
+
+        mResponseQueue.clear();
+
+        final String sentCommand = sendCommandLocked(cmd, args);
+
+        NativeDaemonEvent event = null;
+        do {
             try {
-                String[] tok = line.split(" ");
-                int code = Integer.parseInt(tok[0]);
-                if (code == expectedResponseCode) {
-                    rdata[idx++] = line.substring(tok[0].length() + 1);
-                } else if (code == NativeDaemonConnector.ResponseCode.CommandOkay) {
-                    if (LOCAL_LOGD) Slog.d(TAG, String.format("List terminated with {%s}", line));
-                    int last = rsp.size() -1;
-                    if (i != last) {
-                        Slog.w(TAG, String.format("Recv'd %d lines after end of list {%s}", (last-i), cmd));
-                        for (int j = i; j <= last ; j++) {
-                            Slog.w(TAG, String.format("ExtraData <%s>", rsp.get(i)));
-                        }
-                    }
-                    return rdata;
-                } else {
-                    throw new NativeDaemonConnectorException(
-                            String.format("Expected list response %d, but got %d",
-                                    expectedResponseCode, code));
-                }
-            } catch (NumberFormatException nfe) {
+                event = mResponseQueue.take();
+            } catch (InterruptedException e) {
+                Slog.w(TAG, "interrupted waiting for event line");
+                continue;
+            }
+            events.add(event);
+        } while (event.isClassContinue());
+
+        if (event.isClassClientError()) {
+            throw new NativeDaemonArgumentException(sentCommand, event);
+        }
+        if (event.isClassServerError()) {
+            throw new NativeDaemonFailureException(sentCommand, event);
+        }
+
+        return events.toArray(new NativeDaemonEvent[events.size()]);
+    }
+
+    /**
+     * Issue a command to the native daemon and return the raw responses.
+     *
+     * @deprecated callers should move to {@link #execute(String, Object...)}
+     *             which returns parsed {@link NativeDaemonEvent}.
+     */
+    @Deprecated
+    public ArrayList<String> doCommand(String cmd) throws NativeDaemonConnectorException {
+        final ArrayList<String> rawEvents = Lists.newArrayList();
+        final NativeDaemonEvent[] events = executeForList(cmd);
+        for (NativeDaemonEvent event : events) {
+            rawEvents.add(event.getRawEvent());
+        }
+        return rawEvents;
+    }
+
+    /**
+     * Issues a list command and returns the cooked list of all
+     * {@link NativeDaemonEvent#getMessage()} which match requested code.
+     */
+    @Deprecated
+    public String[] doListCommand(String cmd, int expectedCode)
+            throws NativeDaemonConnectorException {
+        final ArrayList<String> list = Lists.newArrayList();
+
+        final NativeDaemonEvent[] events = executeForList(cmd);
+        for (int i = 0; i < events.length - 1; i++) {
+            final NativeDaemonEvent event = events[i];
+            final int code = event.getCode();
+            if (code == expectedCode) {
+                list.add(event.getMessage());
+            } else {
                 throw new NativeDaemonConnectorException(
-                        String.format("Error reading code '%s'", line));
+                        "unexpected list response " + code + " instead of " + expectedCode);
             }
         }
-        throw new NativeDaemonConnectorException("Got an empty response");
+
+        final NativeDaemonEvent finalEvent = events[events.length - 1];
+        if (!finalEvent.isClassOk()) {
+            throw new NativeDaemonConnectorException("unexpected final event: " + finalEvent);
+        }
+
+        return list.toArray(new String[list.size()]);
+    }
+
+    /**
+     * Append the given argument to {@link StringBuilder}, escaping as needed,
+     * and surrounding with quotes when it contains spaces.
+     */
+    // @VisibleForTesting
+    static void appendEscaped(StringBuilder builder, String arg) {
+        final boolean hasSpaces = arg.indexOf(' ') >= 0;
+        if (hasSpaces) {
+            builder.append('"');
+        }
+
+        final int length = arg.length();
+        for (int i = 0; i < length; i++) {
+            final char c = arg.charAt(i);
+
+            if (c == '"') {
+                builder.append("\\\"");
+            } else if (c == '\\') {
+                builder.append("\\\\");
+            } else {
+                builder.append(c);
+            }
+        }
+
+        if (hasSpaces) {
+            builder.append('"');
+        }
+    }
+
+    private static class NativeDaemonArgumentException extends NativeDaemonConnectorException {
+        public NativeDaemonArgumentException(String command, NativeDaemonEvent event) {
+            super(command, event);
+        }
+
+        @Override
+        public IllegalArgumentException rethrowAsParcelableException() {
+            throw new IllegalArgumentException(getMessage(), this);
+        }
+    }
+
+    private static class NativeDaemonFailureException extends NativeDaemonConnectorException {
+        public NativeDaemonFailureException(String command, NativeDaemonEvent event) {
+            super(command, event);
+        }
+    }
+
+    /**
+     * Command builder that handles argument list building.
+     */
+    public static class Command {
+        private String mCmd;
+        private ArrayList<Object> mArguments = Lists.newArrayList();
+
+        public Command(String cmd, Object... args) {
+            mCmd = cmd;
+            for (Object arg : args) {
+                appendArg(arg);
+            }
+        }
+
+        public Command appendArg(Object arg) {
+            mArguments.add(arg);
+            return this;
+        }
     }
 
     /** {@inheritDoc} */
diff --git a/services/java/com/android/server/NativeDaemonConnectorException.java b/services/java/com/android/server/NativeDaemonConnectorException.java
index 426742b..590bbcc 100644
--- a/services/java/com/android/server/NativeDaemonConnectorException.java
+++ b/services/java/com/android/server/NativeDaemonConnectorException.java
@@ -16,33 +16,43 @@
 
 package com.android.server;
 
+import android.os.Parcel;
+
 /**
- * An exception that indicates there was an error with a NativeDaemonConnector operation
+ * An exception that indicates there was an error with a
+ * {@link NativeDaemonConnector} operation.
  */
-public class NativeDaemonConnectorException extends RuntimeException
-{
-    private int mCode = -1;
+public class NativeDaemonConnectorException extends Exception {
     private String mCmd;
+    private NativeDaemonEvent mEvent;
 
-    public NativeDaemonConnectorException() {}
-
-    public NativeDaemonConnectorException(String error)
-    {
-        super(error);
+    public NativeDaemonConnectorException(String detailMessage) {
+        super(detailMessage);
     }
 
-    public NativeDaemonConnectorException(int code, String cmd, String error)
-    {
-        super(String.format("Cmd {%s} failed with code %d : {%s}", cmd, code, error));
-        mCode = code;
+    public NativeDaemonConnectorException(String detailMessage, Throwable throwable) {
+        super(detailMessage, throwable);
+    }
+
+    public NativeDaemonConnectorException(String cmd, NativeDaemonEvent event) {
+        super("command '" + cmd + "' failed with '" + event + "'");
         mCmd = cmd;
+        mEvent = event;
     }
 
     public int getCode() {
-        return mCode;
+        return mEvent.getCode();
     }
 
     public String getCmd() {
         return mCmd;
     }
+
+    /**
+     * Rethrow as a {@link RuntimeException} subclass that is handled by
+     * {@link Parcel#writeException(Exception)}.
+     */
+    public IllegalArgumentException rethrowAsParcelableException() {
+        throw new IllegalStateException(getMessage(), this);
+    }
 }
diff --git a/services/java/com/android/server/NativeDaemonEvent.java b/services/java/com/android/server/NativeDaemonEvent.java
new file mode 100644
index 0000000..62084c0
--- /dev/null
+++ b/services/java/com/android/server/NativeDaemonEvent.java
@@ -0,0 +1,142 @@
+/*
+ * 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.server;
+
+import com.google.android.collect.Lists;
+
+import java.util.ArrayList;
+
+/**
+ * Parsed event from native side of {@link NativeDaemonConnector}.
+ */
+public class NativeDaemonEvent {
+
+    // TODO: keep class ranges in sync with ResponseCode.h
+    // TODO: swap client and server error ranges to roughly mirror HTTP spec
+
+    private final int mCode;
+    private final String mMessage;
+    private final String mRawEvent;
+
+    private NativeDaemonEvent(int code, String message, String rawEvent) {
+        mCode = code;
+        mMessage = message;
+        mRawEvent = rawEvent;
+    }
+
+    public int getCode() {
+        return mCode;
+    }
+
+    public String getMessage() {
+        return mMessage;
+    }
+
+    @Deprecated
+    public String getRawEvent() {
+        return mRawEvent;
+    }
+
+    @Override
+    public String toString() {
+        return mRawEvent;
+    }
+
+    /**
+     * Test if event represents a partial response which is continued in
+     * additional subsequent events.
+     */
+    public boolean isClassContinue() {
+        return mCode >= 100 && mCode < 200;
+    }
+
+    /**
+     * Test if event represents a command success.
+     */
+    public boolean isClassOk() {
+        return mCode >= 200 && mCode < 300;
+    }
+
+    /**
+     * Test if event represents a remote native daemon error.
+     */
+    public boolean isClassServerError() {
+        return mCode >= 400 && mCode < 500;
+    }
+
+    /**
+     * Test if event represents a command syntax or argument error.
+     */
+    public boolean isClassClientError() {
+        return mCode >= 500 && mCode < 600;
+    }
+
+    /**
+     * Test if event represents an unsolicited event from native daemon.
+     */
+    public boolean isClassUnsolicited() {
+        return mCode >= 600 && mCode < 700;
+    }
+
+    /**
+     * Verify this event matches the given code.
+     *
+     * @throws IllegalStateException if {@link #getCode()} doesn't match.
+     */
+    public void checkCode(int code) {
+        if (mCode != code) {
+            throw new IllegalStateException("Expected " + code + " but was: " + this);
+        }
+    }
+
+    /**
+     * Parse the given raw event into {@link NativeDaemonEvent} instance.
+     *
+     * @throws IllegalArgumentException when line doesn't match format expected
+     *             from native side.
+     */
+    public static NativeDaemonEvent parseRawEvent(String rawEvent) {
+        final int splitIndex = rawEvent.indexOf(' ');
+        if (splitIndex == -1) {
+            throw new IllegalArgumentException("unable to find ' ' separator");
+        }
+
+        final int code;
+        try {
+            code = Integer.parseInt(rawEvent.substring(0, splitIndex));
+        } catch (NumberFormatException e) {
+            throw new IllegalArgumentException("problem parsing code", e);
+        }
+
+        final String message = rawEvent.substring(splitIndex + 1);
+        return new NativeDaemonEvent(code, message, rawEvent);
+    }
+
+    /**
+     * Filter the given {@link NativeDaemonEvent} list, returning
+     * {@link #getMessage()} for any events matching the requested code.
+     */
+    public static String[] filterMessageList(NativeDaemonEvent[] events, int matchCode) {
+        final ArrayList<String> result = Lists.newArrayList();
+        for (NativeDaemonEvent event : events) {
+            if (event.getCode() == matchCode) {
+                result.add(event.getMessage());
+            }
+        }
+        return result.toArray(new String[result.size()]);
+    }
+}
diff --git a/services/java/com/android/server/NetworkManagementService.java b/services/java/com/android/server/NetworkManagementService.java
index b58ba73..f7bf8b5 100644
--- a/services/java/com/android/server/NetworkManagementService.java
+++ b/services/java/com/android/server/NetworkManagementService.java
@@ -27,6 +27,16 @@
 import static android.net.NetworkStats.UID_ALL;
 import static android.net.TrafficStats.UID_TETHERING;
 import static android.provider.Settings.Secure.NETSTATS_ENABLED;
+import static com.android.server.NetworkManagementService.NetdResponseCode.InterfaceGetCfgResult;
+import static com.android.server.NetworkManagementService.NetdResponseCode.InterfaceListResult;
+import static com.android.server.NetworkManagementService.NetdResponseCode.InterfaceRxThrottleResult;
+import static com.android.server.NetworkManagementService.NetdResponseCode.InterfaceTxThrottleResult;
+import static com.android.server.NetworkManagementService.NetdResponseCode.IpFwdStatusResult;
+import static com.android.server.NetworkManagementService.NetdResponseCode.TetherDnsFwdTgtListResult;
+import static com.android.server.NetworkManagementService.NetdResponseCode.TetherInterfaceListResult;
+import static com.android.server.NetworkManagementService.NetdResponseCode.TetherStatusResult;
+import static com.android.server.NetworkManagementService.NetdResponseCode.TetheringStatsResult;
+import static com.android.server.NetworkManagementService.NetdResponseCode.TtyListResult;
 import static com.android.server.NetworkManagementSocketTagger.PROP_QTAGUID_ENABLED;
 
 import android.content.Context;
@@ -48,6 +58,7 @@
 import android.util.SparseBooleanArray;
 
 import com.android.internal.net.NetworkStatsFactory;
+import com.android.server.NativeDaemonConnector.Command;
 import com.google.android.collect.Sets;
 
 import java.io.BufferedReader;
@@ -79,8 +90,8 @@
     private static final boolean DBG = false;
     private static final String NETD_TAG = "NetdConnector";
 
-    private static final int ADD = 1;
-    private static final int REMOVE = 2;
+    private static final String ADD = "add";
+    private static final String REMOVE = "remove";
 
     private static final String DEFAULT = "default";
     private static final String SECONDARY = "secondary";
@@ -182,7 +193,7 @@
         if (hasKernelSupport && shouldEnable) {
             Slog.d(TAG, "enabling bandwidth control");
             try {
-                mConnector.doCommand("bandwidth enable");
+                mConnector.execute("bandwidth", "enable");
                 mBandwidthControlEnabled = true;
             } catch (NativeDaemonConnectorException e) {
                 Log.wtf(TAG, "problem enabling bandwidth controls", e);
@@ -281,7 +292,6 @@
      * Let us know the daemon is connected
      */
     protected void onDaemonConnected() {
-        if (DBG) Slog.d(TAG, "onConnected");
         mConnectedSignal.countDown();
     }
 
@@ -358,123 +368,103 @@
     public String[] listInterfaces() {
         mContext.enforceCallingOrSelfPermission(ACCESS_NETWORK_STATE, TAG);
         try {
-            return mConnector.doListCommand("interface list", NetdResponseCode.InterfaceListResult);
+            return NativeDaemonEvent.filterMessageList(
+                    mConnector.executeForList("interface", "list"), InterfaceListResult);
         } catch (NativeDaemonConnectorException e) {
-            throw new IllegalStateException(
-                    "Cannot communicate with native daemon to list interfaces");
+            throw e.rethrowAsParcelableException();
         }
     }
 
     @Override
     public InterfaceConfiguration getInterfaceConfig(String iface) {
         mContext.enforceCallingOrSelfPermission(ACCESS_NETWORK_STATE, TAG);
-        String rsp;
-        try {
-            rsp = mConnector.doCommand("interface getcfg " + iface).get(0);
-        } catch (NativeDaemonConnectorException e) {
-            throw new IllegalStateException(
-                    "Cannot communicate with native daemon to get interface config");
-        }
-        Slog.d(TAG, String.format("rsp <%s>", rsp));
 
-        // Rsp: 213 xx:xx:xx:xx:xx:xx yyy.yyy.yyy.yyy zzz [flag1 flag2 flag3]
-        StringTokenizer st = new StringTokenizer(rsp);
+        final NativeDaemonEvent event;
+        try {
+            event = mConnector.execute("interface", "getcfg", iface);
+        } catch (NativeDaemonConnectorException e) {
+            throw e.rethrowAsParcelableException();
+        }
+
+        event.checkCode(InterfaceGetCfgResult);
+
+        // Rsp: 213 xx:xx:xx:xx:xx:xx yyy.yyy.yyy.yyy zzz flag1 flag2 flag3
+        final StringTokenizer st = new StringTokenizer(event.getMessage());
 
         InterfaceConfiguration cfg;
         try {
-            try {
-                int code = Integer.parseInt(st.nextToken(" "));
-                if (code != NetdResponseCode.InterfaceGetCfgResult) {
-                    throw new IllegalStateException(
-                        String.format("Expected code %d, but got %d",
-                                NetdResponseCode.InterfaceGetCfgResult, code));
-                }
-            } catch (NumberFormatException nfe) {
-                throw new IllegalStateException(
-                        String.format("Invalid response from daemon (%s)", rsp));
-            }
-
             cfg = new InterfaceConfiguration();
-            cfg.hwAddr = st.nextToken(" ");
+            cfg.setHardwareAddress(st.nextToken(" "));
             InetAddress addr = null;
             int prefixLength = 0;
             try {
-                addr = NetworkUtils.numericToInetAddress(st.nextToken(" "));
+                addr = NetworkUtils.numericToInetAddress(st.nextToken());
             } catch (IllegalArgumentException iae) {
                 Slog.e(TAG, "Failed to parse ipaddr", iae);
             }
 
             try {
-                prefixLength = Integer.parseInt(st.nextToken(" "));
+                prefixLength = Integer.parseInt(st.nextToken());
             } catch (NumberFormatException nfe) {
                 Slog.e(TAG, "Failed to parse prefixLength", nfe);
             }
 
-            cfg.addr = new LinkAddress(addr, prefixLength);
-            cfg.interfaceFlags = st.nextToken("]").trim() +"]";
+            cfg.setLinkAddress(new LinkAddress(addr, prefixLength));
+            while (st.hasMoreTokens()) {
+                cfg.setFlag(st.nextToken());
+            }
         } catch (NoSuchElementException nsee) {
-            throw new IllegalStateException(
-                    String.format("Invalid response from daemon (%s)", rsp));
+            throw new IllegalStateException("Invalid response from daemon: " + event);
         }
-        Slog.d(TAG, String.format("flags <%s>", cfg.interfaceFlags));
         return cfg;
     }
 
     @Override
     public void setInterfaceConfig(String iface, InterfaceConfiguration cfg) {
         mContext.enforceCallingOrSelfPermission(CHANGE_NETWORK_STATE, TAG);
-        LinkAddress linkAddr = cfg.addr;
+        LinkAddress linkAddr = cfg.getLinkAddress();
         if (linkAddr == null || linkAddr.getAddress() == null) {
             throw new IllegalStateException("Null LinkAddress given");
         }
-        String cmd = String.format("interface setcfg %s %s %d %s", iface,
+
+        final Command cmd = new Command("interface", "setcfg", iface,
                 linkAddr.getAddress().getHostAddress(),
-                linkAddr.getNetworkPrefixLength(),
-                cfg.interfaceFlags);
+                linkAddr.getNetworkPrefixLength());
+        for (String flag : cfg.getFlags()) {
+            cmd.appendArg(flag);
+        }
+
         try {
-            mConnector.doCommand(cmd);
+            mConnector.execute(cmd);
         } catch (NativeDaemonConnectorException e) {
-            throw new IllegalStateException(
-                    "Unable to communicate with native daemon to interface setcfg - " + e);
+            throw e.rethrowAsParcelableException();
         }
     }
 
     @Override
     public void setInterfaceDown(String iface) {
         mContext.enforceCallingOrSelfPermission(CHANGE_NETWORK_STATE, TAG);
-        try {
-            InterfaceConfiguration ifcg = getInterfaceConfig(iface);
-            ifcg.interfaceFlags = ifcg.interfaceFlags.replace("up", "down");
-            setInterfaceConfig(iface, ifcg);
-        } catch (NativeDaemonConnectorException e) {
-            throw new IllegalStateException(
-                    "Unable to communicate with native daemon for interface down - " + e);
-        }
+        final InterfaceConfiguration ifcg = getInterfaceConfig(iface);
+        ifcg.setInterfaceDown();
+        setInterfaceConfig(iface, ifcg);
     }
 
     @Override
     public void setInterfaceUp(String iface) {
         mContext.enforceCallingOrSelfPermission(CHANGE_NETWORK_STATE, TAG);
-        try {
-            InterfaceConfiguration ifcg = getInterfaceConfig(iface);
-            ifcg.interfaceFlags = ifcg.interfaceFlags.replace("down", "up");
-            setInterfaceConfig(iface, ifcg);
-        } catch (NativeDaemonConnectorException e) {
-            throw new IllegalStateException(
-                    "Unable to communicate with native daemon for interface up - " + e);
-        }
+        final InterfaceConfiguration ifcg = getInterfaceConfig(iface);
+        ifcg.setInterfaceUp();
+        setInterfaceConfig(iface, ifcg);
     }
 
     @Override
     public void setInterfaceIpv6PrivacyExtensions(String iface, boolean enable) {
         mContext.enforceCallingOrSelfPermission(CHANGE_NETWORK_STATE, TAG);
-        String cmd = String.format("interface ipv6privacyextensions %s %s", iface,
-                enable ? "enable" : "disable");
         try {
-            mConnector.doCommand(cmd);
+            mConnector.execute(
+                    "interface", "ipv6privacyextensions", iface, enable ? "enable" : "disable");
         } catch (NativeDaemonConnectorException e) {
-            throw new IllegalStateException(
-                    "Unable to communicate with native daemon to set ipv6privacyextensions - " + e);
+            throw e.rethrowAsParcelableException();
         }
     }
 
@@ -483,12 +473,10 @@
     @Override
     public void clearInterfaceAddresses(String iface) {
         mContext.enforceCallingOrSelfPermission(CHANGE_NETWORK_STATE, TAG);
-        String cmd = String.format("interface clearaddrs %s", iface);
         try {
-            mConnector.doCommand(cmd);
+            mConnector.execute("interface", "clearaddrs", iface);
         } catch (NativeDaemonConnectorException e) {
-            throw new IllegalStateException(
-                    "Unable to communicate with native daemon to interface clearallips - " + e);
+            throw e.rethrowAsParcelableException();
         }
     }
 
@@ -496,10 +484,9 @@
     public void enableIpv6(String iface) {
         mContext.enforceCallingOrSelfPermission(CHANGE_NETWORK_STATE, TAG);
         try {
-            mConnector.doCommand(String.format("interface ipv6 %s enable", iface));
+            mConnector.execute("interface", "ipv6", iface, "enable");
         } catch (NativeDaemonConnectorException e) {
-            throw new IllegalStateException(
-                    "Unable to communicate to native daemon for enabling ipv6");
+            throw e.rethrowAsParcelableException();
         }
     }
 
@@ -507,10 +494,9 @@
     public void disableIpv6(String iface) {
         mContext.enforceCallingOrSelfPermission(CHANGE_NETWORK_STATE, TAG);
         try {
-            mConnector.doCommand(String.format("interface ipv6 %s disable", iface));
+            mConnector.execute("interface", "ipv6", iface, "disable");
         } catch (NativeDaemonConnectorException e) {
-            throw new IllegalStateException(
-                    "Unable to communicate to native daemon for disabling ipv6");
+            throw e.rethrowAsParcelableException();
         }
     }
 
@@ -538,54 +524,28 @@
         modifyRoute(interfaceName, REMOVE, route, SECONDARY);
     }
 
-    private void modifyRoute(String interfaceName, int action, RouteInfo route, String type) {
-        ArrayList<String> rsp;
-
-        StringBuilder cmd;
-
-        switch (action) {
-            case ADD:
-            {
-                cmd = new StringBuilder("interface route add " + interfaceName + " " + type);
-                break;
-            }
-            case REMOVE:
-            {
-                cmd = new StringBuilder("interface route remove " + interfaceName + " " + type);
-                break;
-            }
-            default:
-                throw new IllegalStateException("Unknown action type " + action);
-        }
+    private void modifyRoute(String interfaceName, String action, RouteInfo route, String type) {
+        final Command cmd = new Command("interface", "route", action, interfaceName, type);
 
         // create triplet: dest-ip-addr prefixlength gateway-ip-addr
-        LinkAddress la = route.getDestination();
-        cmd.append(' ');
-        cmd.append(la.getAddress().getHostAddress());
-        cmd.append(' ');
-        cmd.append(la.getNetworkPrefixLength());
-        cmd.append(' ');
+        final LinkAddress la = route.getDestination();
+        cmd.appendArg(la.getAddress().getHostAddress());
+        cmd.appendArg(la.getNetworkPrefixLength());
+
         if (route.getGateway() == null) {
             if (la.getAddress() instanceof Inet4Address) {
-                cmd.append("0.0.0.0");
+                cmd.appendArg("0.0.0.0");
             } else {
-                cmd.append ("::0");
+                cmd.appendArg("::0");
             }
         } else {
-            cmd.append(route.getGateway().getHostAddress());
-        }
-        try {
-            rsp = mConnector.doCommand(cmd.toString());
-        } catch (NativeDaemonConnectorException e) {
-            throw new IllegalStateException(
-                    "Unable to communicate with native dameon to add routes - "
-                    + e);
+            cmd.appendArg(route.getGateway().getHostAddress());
         }
 
-        if (DBG) {
-            for (String line : rsp) {
-                Log.v(TAG, "add route response is " + line);
-            }
+        try {
+            mConnector.execute(cmd);
+        } catch (NativeDaemonConnectorException e) {
+            throw e.rethrowAsParcelableException();
         }
     }
 
@@ -689,7 +649,7 @@
                 }
             }
         }
-        return (RouteInfo[]) routes.toArray(new RouteInfo[0]);
+        return routes.toArray(new RouteInfo[routes.size()]);
     }
 
     @Override
@@ -704,36 +664,26 @@
     public boolean getIpForwardingEnabled() throws IllegalStateException{
         mContext.enforceCallingOrSelfPermission(ACCESS_NETWORK_STATE, TAG);
 
-        ArrayList<String> rsp;
+        final NativeDaemonEvent event;
         try {
-            rsp = mConnector.doCommand("ipfwd status");
+            event = mConnector.execute("ipfwd", "status");
         } catch (NativeDaemonConnectorException e) {
-            throw new IllegalStateException(
-                    "Unable to communicate with native daemon to ipfwd status");
+            throw e.rethrowAsParcelableException();
         }
 
-        for (String line : rsp) {
-            String[] tok = line.split(" ");
-            if (tok.length < 3) {
-                Slog.e(TAG, "Malformed response from native daemon: " + line);
-                return false;
-            }
-
-            int code = Integer.parseInt(tok[0]);
-            if (code == NetdResponseCode.IpFwdStatusResult) {
-                // 211 Forwarding <enabled/disabled>
-                return "enabled".equals(tok[2]);
-            } else {
-                throw new IllegalStateException(String.format("Unexpected response code %d", code));
-            }
-        }
-        throw new IllegalStateException("Got an empty response");
+        // 211 Forwarding enabled
+        event.checkCode(IpFwdStatusResult);
+        return event.getMessage().endsWith("enabled");
     }
 
     @Override
     public void setIpForwardingEnabled(boolean enable) {
         mContext.enforceCallingOrSelfPermission(CHANGE_NETWORK_STATE, TAG);
-        mConnector.doCommand(String.format("ipfwd %sable", (enable ? "en" : "dis")));
+        try {
+            mConnector.execute("ipfwd", enable ? "enable" : "disable");
+        } catch (NativeDaemonConnectorException e) {
+            throw e.rethrowAsParcelableException();
+        }
     }
 
     @Override
@@ -741,15 +691,16 @@
         mContext.enforceCallingOrSelfPermission(CHANGE_NETWORK_STATE, TAG);
         // cmd is "tether start first_start first_stop second_start second_stop ..."
         // an odd number of addrs will fail
-        String cmd = "tether start";
+
+        final Command cmd = new Command("tether", "start");
         for (String d : dhcpRange) {
-            cmd += " " + d;
+            cmd.appendArg(d);
         }
 
         try {
-            mConnector.doCommand(cmd);
+            mConnector.execute(cmd);
         } catch (NativeDaemonConnectorException e) {
-            throw new IllegalStateException("Unable to communicate to native daemon");
+            throw e.rethrowAsParcelableException();
         }
     }
 
@@ -757,9 +708,9 @@
     public void stopTethering() {
         mContext.enforceCallingOrSelfPermission(CHANGE_NETWORK_STATE, TAG);
         try {
-            mConnector.doCommand("tether stop");
+            mConnector.execute("tether", "stop");
         } catch (NativeDaemonConnectorException e) {
-            throw new IllegalStateException("Unable to communicate to native daemon to stop tether");
+            throw e.rethrowAsParcelableException();
         }
     }
 
@@ -767,38 +718,25 @@
     public boolean isTetheringStarted() {
         mContext.enforceCallingOrSelfPermission(ACCESS_NETWORK_STATE, TAG);
 
-        ArrayList<String> rsp;
+        final NativeDaemonEvent event;
         try {
-            rsp = mConnector.doCommand("tether status");
+            event = mConnector.execute("tether", "status");
         } catch (NativeDaemonConnectorException e) {
-            throw new IllegalStateException(
-                    "Unable to communicate to native daemon to get tether status");
+            throw e.rethrowAsParcelableException();
         }
 
-        for (String line : rsp) {
-            String[] tok = line.split(" ");
-            if (tok.length < 3) {
-                throw new IllegalStateException("Malformed response for tether status: " + line);
-            }
-            int code = Integer.parseInt(tok[0]);
-            if (code == NetdResponseCode.TetherStatusResult) {
-                // XXX: Tethering services <started/stopped> <TBD>...
-                return "started".equals(tok[2]);
-            } else {
-                throw new IllegalStateException(String.format("Unexpected response code %d", code));
-            }
-        }
-        throw new IllegalStateException("Got an empty response");
+        // 210 Tethering services started
+        event.checkCode(TetherStatusResult);
+        return event.getMessage().endsWith("started");
     }
 
     @Override
     public void tetherInterface(String iface) {
         mContext.enforceCallingOrSelfPermission(CHANGE_NETWORK_STATE, TAG);
         try {
-            mConnector.doCommand("tether interface add " + iface);
+            mConnector.execute("tether", "interface", "add", iface);
         } catch (NativeDaemonConnectorException e) {
-            throw new IllegalStateException(
-                    "Unable to communicate to native daemon for adding tether interface");
+            throw e.rethrowAsParcelableException();
         }
     }
 
@@ -806,10 +744,9 @@
     public void untetherInterface(String iface) {
         mContext.enforceCallingOrSelfPermission(CHANGE_NETWORK_STATE, TAG);
         try {
-            mConnector.doCommand("tether interface remove " + iface);
+            mConnector.execute("tether", "interface", "remove", iface);
         } catch (NativeDaemonConnectorException e) {
-            throw new IllegalStateException(
-                    "Unable to communicate to native daemon for removing tether interface");
+            throw e.rethrowAsParcelableException();
         }
     }
 
@@ -817,30 +754,27 @@
     public String[] listTetheredInterfaces() {
         mContext.enforceCallingOrSelfPermission(ACCESS_NETWORK_STATE, TAG);
         try {
-            return mConnector.doListCommand(
-                    "tether interface list", NetdResponseCode.TetherInterfaceListResult);
+            return NativeDaemonEvent.filterMessageList(
+                    mConnector.executeForList("tether", "interface", "list"),
+                    TetherInterfaceListResult);
         } catch (NativeDaemonConnectorException e) {
-            throw new IllegalStateException(
-                    "Unable to communicate to native daemon for listing tether interfaces");
+            throw e.rethrowAsParcelableException();
         }
     }
 
     @Override
     public void setDnsForwarders(String[] dns) {
         mContext.enforceCallingOrSelfPermission(CHANGE_NETWORK_STATE, TAG);
+
+        final Command cmd = new Command("tether", "dns", "set");
+        for (String s : dns) {
+            cmd.appendArg(NetworkUtils.numericToInetAddress(s).getHostAddress());
+        }
+
         try {
-            String cmd = "tether dns set";
-            for (String s : dns) {
-                cmd += " " + NetworkUtils.numericToInetAddress(s).getHostAddress();
-            }
-            try {
-                mConnector.doCommand(cmd);
-            } catch (NativeDaemonConnectorException e) {
-                throw new IllegalStateException(
-                        "Unable to communicate to native daemon for setting tether dns");
-            }
-        } catch (IllegalArgumentException e) {
-            throw new IllegalStateException("Error resolving dns name", e);
+            mConnector.execute(cmd);
+        } catch (NativeDaemonConnectorException e) {
+            throw e.rethrowAsParcelableException();
         }
     }
 
@@ -848,55 +782,56 @@
     public String[] getDnsForwarders() {
         mContext.enforceCallingOrSelfPermission(ACCESS_NETWORK_STATE, TAG);
         try {
-            return mConnector.doListCommand(
-                    "tether dns list", NetdResponseCode.TetherDnsFwdTgtListResult);
+            return NativeDaemonEvent.filterMessageList(
+                    mConnector.executeForList("tether", "dns", "list"), TetherDnsFwdTgtListResult);
         } catch (NativeDaemonConnectorException e) {
-            throw new IllegalStateException(
-                    "Unable to communicate to native daemon for listing tether dns");
+            throw e.rethrowAsParcelableException();
         }
     }
 
-    private void modifyNat(String cmd, String internalInterface, String externalInterface)
+    private void modifyNat(String action, String internalInterface, String externalInterface)
             throws SocketException {
-        cmd = String.format("nat %s %s %s", cmd, internalInterface, externalInterface);
+        final Command cmd = new Command("nat", action, internalInterface, externalInterface);
 
-        NetworkInterface internalNetworkInterface =
-                NetworkInterface.getByName(internalInterface);
-        Collection<InterfaceAddress>interfaceAddresses =
-                internalNetworkInterface.getInterfaceAddresses();
-        cmd += " " + interfaceAddresses.size();
-        for (InterfaceAddress ia : interfaceAddresses) {
-            InetAddress addr = NetworkUtils.getNetworkPart(ia.getAddress(),
-                    ia.getNetworkPrefixLength());
-            cmd = cmd + " " + addr.getHostAddress() + "/" + ia.getNetworkPrefixLength();
+        final NetworkInterface internalNetworkInterface = NetworkInterface.getByName(
+                internalInterface);
+        if (internalNetworkInterface == null) {
+            cmd.appendArg("0");
+        } else {
+            Collection<InterfaceAddress> interfaceAddresses = internalNetworkInterface
+                    .getInterfaceAddresses();
+            cmd.appendArg(interfaceAddresses.size());
+            for (InterfaceAddress ia : interfaceAddresses) {
+                InetAddress addr = NetworkUtils.getNetworkPart(
+                        ia.getAddress(), ia.getNetworkPrefixLength());
+                cmd.appendArg(addr.getHostAddress() + "/" + ia.getNetworkPrefixLength());
+            }
         }
 
-        mConnector.doCommand(cmd);
+        try {
+            mConnector.execute(cmd);
+        } catch (NativeDaemonConnectorException e) {
+            throw e.rethrowAsParcelableException();
+        }
     }
 
     @Override
     public void enableNat(String internalInterface, String externalInterface) {
         mContext.enforceCallingOrSelfPermission(CHANGE_NETWORK_STATE, TAG);
-        if (DBG) Log.d(TAG, "enableNat(" + internalInterface + ", " + externalInterface + ")");
         try {
             modifyNat("enable", internalInterface, externalInterface);
-        } catch (Exception e) {
-            Log.e(TAG, "enableNat got Exception " + e.toString());
-            throw new IllegalStateException(
-                    "Unable to communicate to native daemon for enabling NAT interface");
+        } catch (SocketException e) {
+            throw new IllegalStateException(e);
         }
     }
 
     @Override
     public void disableNat(String internalInterface, String externalInterface) {
         mContext.enforceCallingOrSelfPermission(CHANGE_NETWORK_STATE, TAG);
-        if (DBG) Log.d(TAG, "disableNat(" + internalInterface + ", " + externalInterface + ")");
         try {
             modifyNat("disable", internalInterface, externalInterface);
-        } catch (Exception e) {
-            Log.e(TAG, "disableNat got Exception " + e.toString());
-            throw new IllegalStateException(
-                    "Unable to communicate to native daemon for disabling NAT interface");
+        } catch (SocketException e) {
+            throw new IllegalStateException(e);
         }
     }
 
@@ -904,10 +839,10 @@
     public String[] listTtys() {
         mContext.enforceCallingOrSelfPermission(ACCESS_NETWORK_STATE, TAG);
         try {
-            return mConnector.doListCommand("list_ttys", NetdResponseCode.TtyListResult);
+            return NativeDaemonEvent.filterMessageList(
+                    mConnector.executeForList("list_ttys"), TtyListResult);
         } catch (NativeDaemonConnectorException e) {
-            throw new IllegalStateException(
-                    "Unable to communicate to native daemon for listing TTYs");
+            throw e.rethrowAsParcelableException();
         }
     }
 
@@ -916,15 +851,13 @@
             String tty, String localAddr, String remoteAddr, String dns1Addr, String dns2Addr) {
         mContext.enforceCallingOrSelfPermission(CHANGE_NETWORK_STATE, TAG);
         try {
-            mConnector.doCommand(String.format("pppd attach %s %s %s %s %s", tty,
+            mConnector.execute("pppd", "attach", tty,
                     NetworkUtils.numericToInetAddress(localAddr).getHostAddress(),
                     NetworkUtils.numericToInetAddress(remoteAddr).getHostAddress(),
                     NetworkUtils.numericToInetAddress(dns1Addr).getHostAddress(),
-                    NetworkUtils.numericToInetAddress(dns2Addr).getHostAddress()));
-        } catch (IllegalArgumentException e) {
-            throw new IllegalStateException("Error resolving addr", e);
+                    NetworkUtils.numericToInetAddress(dns2Addr).getHostAddress());
         } catch (NativeDaemonConnectorException e) {
-            throw new IllegalStateException("Error communicating to native daemon to attach pppd", e);
+            throw e.rethrowAsParcelableException();
         }
     }
 
@@ -932,9 +865,9 @@
     public void detachPppd(String tty) {
         mContext.enforceCallingOrSelfPermission(CHANGE_NETWORK_STATE, TAG);
         try {
-            mConnector.doCommand(String.format("pppd detach %s", tty));
+            mConnector.execute("pppd", "detach", tty);
         } catch (NativeDaemonConnectorException e) {
-            throw new IllegalStateException("Error communicating to native daemon to detach pppd", e);
+            throw e.rethrowAsParcelableException();
         }
     }
 
@@ -945,42 +878,20 @@
         mContext.enforceCallingOrSelfPermission(CHANGE_WIFI_STATE, TAG);
         try {
             wifiFirmwareReload(wlanIface, "AP");
-            mConnector.doCommand(String.format("softap start " + wlanIface));
+            mConnector.execute("softap", "start", wlanIface);
             if (wifiConfig == null) {
-                mConnector.doCommand(String.format("softap set " + wlanIface + " " + softapIface));
+                mConnector.execute("softap", "set", wlanIface, softapIface);
             } else {
-                /**
-                 * softap set arg1 arg2 arg3 [arg4 arg5 arg6 arg7 arg8]
-                 * argv1 - wlan interface
-                 * argv2 - softap interface
-                 * argv3 - SSID
-                 * argv4 - Security
-                 * argv5 - Key
-                 * argv6 - Channel
-                 * argv7 - Preamble
-                 * argv8 - Max SCB
-                 */
-                 String str = String.format("softap set " + wlanIface + " " + softapIface +
-                                       " %s %s %s", convertQuotedString(wifiConfig.SSID),
-                                       getSecurityType(wifiConfig),
-                                       convertQuotedString(wifiConfig.preSharedKey));
-                mConnector.doCommand(str);
+                mConnector.execute("softap", "set", wlanIface, softapIface, wifiConfig.SSID,
+                        getSecurityType(wifiConfig), wifiConfig.preSharedKey);
             }
-            mConnector.doCommand(String.format("softap startap"));
+            mConnector.execute("softap", "startap");
         } catch (NativeDaemonConnectorException e) {
-            throw new IllegalStateException("Error communicating to native daemon to start softap", e);
+            throw e.rethrowAsParcelableException();
         }
     }
 
-    private String convertQuotedString(String s) {
-        if (s == null) {
-            return s;
-        }
-        /* Replace \ with \\, then " with \" and add quotes at end */
-        return '"' + s.replaceAll("\\\\","\\\\\\\\").replaceAll("\"","\\\\\"") + '"';
-    }
-
-    private String getSecurityType(WifiConfiguration wifiConfig) {
+    private static String getSecurityType(WifiConfiguration wifiConfig) {
         switch (wifiConfig.getAuthType()) {
             case KeyMgmt.WPA_PSK:
                 return "wpa-psk";
@@ -997,9 +908,9 @@
         mContext.enforceCallingOrSelfPermission(CHANGE_NETWORK_STATE, TAG);
         mContext.enforceCallingOrSelfPermission(CHANGE_WIFI_STATE, TAG);
         try {
-            mConnector.doCommand(String.format("softap fwreload " + wlanIface + " " + mode));
+            mConnector.execute("softap", "fwreload", wlanIface, mode);
         } catch (NativeDaemonConnectorException e) {
-            throw new IllegalStateException("Error communicating to native daemon ", e);
+            throw e.rethrowAsParcelableException();
         }
     }
 
@@ -1008,12 +919,11 @@
         mContext.enforceCallingOrSelfPermission(CHANGE_NETWORK_STATE, TAG);
         mContext.enforceCallingOrSelfPermission(CHANGE_WIFI_STATE, TAG);
         try {
-            mConnector.doCommand("softap stopap");
-            mConnector.doCommand("softap stop " + wlanIface);
+            mConnector.execute("softap", "stopap");
+            mConnector.execute("softap", "stop", wlanIface);
             wifiFirmwareReload(wlanIface, "STA");
         } catch (NativeDaemonConnectorException e) {
-            throw new IllegalStateException("Error communicating to native daemon to stop soft AP",
-                    e);
+            throw e.rethrowAsParcelableException();
         }
     }
 
@@ -1023,59 +933,16 @@
         mContext.enforceCallingOrSelfPermission(CHANGE_WIFI_STATE, TAG);
         try {
             if (wifiConfig == null) {
-                mConnector.doCommand(String.format("softap set " + wlanIface + " " + softapIface));
+                mConnector.execute("softap", "set", wlanIface, softapIface);
             } else {
-                String str = String.format("softap set " + wlanIface + " " + softapIface
-                        + " %s %s %s", convertQuotedString(wifiConfig.SSID),
-                        getSecurityType(wifiConfig),
-                        convertQuotedString(wifiConfig.preSharedKey));
-                mConnector.doCommand(str);
+                mConnector.execute("softap", "set", wlanIface, softapIface, wifiConfig.SSID,
+                        getSecurityType(wifiConfig), wifiConfig.preSharedKey);
             }
         } catch (NativeDaemonConnectorException e) {
-            throw new IllegalStateException("Error communicating to native daemon to set soft AP",
-                    e);
+            throw e.rethrowAsParcelableException();
         }
     }
 
-    private long getInterfaceCounter(String iface, boolean rx) {
-        mContext.enforceCallingOrSelfPermission(ACCESS_NETWORK_STATE, TAG);
-        try {
-            String rsp;
-            try {
-                rsp = mConnector.doCommand(
-                        String.format("interface read%scounter %s", (rx ? "rx" : "tx"), iface)).get(0);
-            } catch (NativeDaemonConnectorException e1) {
-                Slog.e(TAG, "Error communicating with native daemon", e1);
-                return -1;
-            }
-
-            String[] tok = rsp.split(" ");
-            if (tok.length < 2) {
-                Slog.e(TAG, String.format("Malformed response for reading %s interface",
-                        (rx ? "rx" : "tx")));
-                return -1;
-            }
-
-            int code;
-            try {
-                code = Integer.parseInt(tok[0]);
-            } catch (NumberFormatException nfe) {
-                Slog.e(TAG, String.format("Error parsing code %s", tok[0]));
-                return -1;
-            }
-            if ((rx && code != NetdResponseCode.InterfaceRxCounterResult) || (
-                    !rx && code != NetdResponseCode.InterfaceTxCounterResult)) {
-                Slog.e(TAG, String.format("Unexpected response code %d", code));
-                return -1;
-            }
-            return Long.parseLong(tok[1]);
-        } catch (Exception e) {
-            Slog.e(TAG, String.format(
-                    "Failed to read interface %s counters", (rx ? "rx" : "tx")), e);
-        }
-        return -1;
-    }
-
     @Override
     public NetworkStats getNetworkStatsSummary() {
         mContext.enforceCallingOrSelfPermission(ACCESS_NETWORK_STATE, TAG);
@@ -1101,15 +968,12 @@
                 throw new IllegalStateException("iface " + iface + " already has quota");
             }
 
-            final StringBuilder command = new StringBuilder();
-            command.append("bandwidth setiquota ").append(iface).append(" ").append(quotaBytes);
-
             try {
                 // TODO: support quota shared across interfaces
-                mConnector.doCommand(command.toString());
+                mConnector.execute("bandwidth", "setiquota", iface, quotaBytes);
                 mActiveQuotaIfaces.add(iface);
             } catch (NativeDaemonConnectorException e) {
-                throw new IllegalStateException("Error communicating to native daemon", e);
+                throw e.rethrowAsParcelableException();
             }
         }
     }
@@ -1128,18 +992,14 @@
                 return;
             }
 
-            final StringBuilder command = new StringBuilder();
-            command.append("bandwidth removeiquota ").append(iface);
-
             mActiveQuotaIfaces.remove(iface);
             mActiveAlertIfaces.remove(iface);
 
             try {
                 // TODO: support quota shared across interfaces
-                mConnector.doCommand(command.toString());
+                mConnector.execute("bandwidth", "removeiquota", iface);
             } catch (NativeDaemonConnectorException e) {
-                // TODO: include current iptables state
-                throw new IllegalStateException("Error communicating to native daemon", e);
+                throw e.rethrowAsParcelableException();
             }
         }
     }
@@ -1162,16 +1022,12 @@
                 throw new IllegalStateException("iface " + iface + " already has alert");
             }
 
-            final StringBuilder command = new StringBuilder();
-            command.append("bandwidth setinterfacealert ").append(iface).append(" ").append(
-                    alertBytes);
-
             try {
                 // TODO: support alert shared across interfaces
-                mConnector.doCommand(command.toString());
+                mConnector.execute("bandwidth", "setinterfacealert", iface, alertBytes);
                 mActiveAlertIfaces.add(iface);
             } catch (NativeDaemonConnectorException e) {
-                throw new IllegalStateException("Error communicating to native daemon", e);
+                throw e.rethrowAsParcelableException();
             }
         }
     }
@@ -1190,15 +1046,12 @@
                 return;
             }
 
-            final StringBuilder command = new StringBuilder();
-            command.append("bandwidth removeinterfacealert ").append(iface);
-
             try {
                 // TODO: support alert shared across interfaces
-                mConnector.doCommand(command.toString());
+                mConnector.execute("bandwidth", "removeinterfacealert", iface);
                 mActiveAlertIfaces.remove(iface);
             } catch (NativeDaemonConnectorException e) {
-                throw new IllegalStateException("Error communicating to native daemon", e);
+                throw e.rethrowAsParcelableException();
             }
         }
     }
@@ -1211,13 +1064,10 @@
         // TODO: eventually migrate to be always enabled
         if (!mBandwidthControlEnabled) return;
 
-        final StringBuilder command = new StringBuilder();
-        command.append("bandwidth setglobalalert ").append(alertBytes);
-
         try {
-            mConnector.doCommand(command.toString());
+            mConnector.execute("bandwidth", "setglobalalert", alertBytes);
         } catch (NativeDaemonConnectorException e) {
-            throw new IllegalStateException("Error communicating to native daemon", e);
+            throw e.rethrowAsParcelableException();
         }
     }
 
@@ -1236,24 +1086,16 @@
                 return;
             }
 
-            final StringBuilder command = new StringBuilder();
-            command.append("bandwidth");
-            if (rejectOnQuotaInterfaces) {
-                command.append(" addnaughtyapps");
-            } else {
-                command.append(" removenaughtyapps");
-            }
-            command.append(" ").append(uid);
-
             try {
-                mConnector.doCommand(command.toString());
+                mConnector.execute("bandwidth",
+                        rejectOnQuotaInterfaces ? "addnaughtyapps" : "removenaughtyapps", uid);
                 if (rejectOnQuotaInterfaces) {
                     mUidRejectOnQuota.put(uid, true);
                 } else {
                     mUidRejectOnQuota.delete(uid);
                 }
             } catch (NativeDaemonConnectorException e) {
-                throw new IllegalStateException("Error communicating to native daemon", e);
+                throw e.rethrowAsParcelableException();
             }
         }
     }
@@ -1293,33 +1135,19 @@
     }
 
     private NetworkStats.Entry getNetworkStatsTethering(String ifaceIn, String ifaceOut) {
-        final StringBuilder command = new StringBuilder();
-        command.append("bandwidth gettetherstats ").append(ifaceIn).append(" ").append(ifaceOut);
-
-        final String rsp;
+        final NativeDaemonEvent event;
         try {
-            rsp = mConnector.doCommand(command.toString()).get(0);
+            event = mConnector.execute("bandwidth", "gettetherstats", ifaceIn, ifaceOut);
         } catch (NativeDaemonConnectorException e) {
-            throw new IllegalStateException("Error communicating to native daemon", e);
+            throw e.rethrowAsParcelableException();
         }
 
-        final String[] tok = rsp.split(" ");
-        /* Expecting: "code ifaceIn ifaceOut rx_bytes rx_packets tx_bytes tx_packets" */
-        if (tok.length != 7) {
-            throw new IllegalStateException("Native daemon returned unexpected result: " + rsp);
-        }
+        event.checkCode(TetheringStatsResult);
 
-        final int code;
-        try {
-            code = Integer.parseInt(tok[0]);
-        } catch (NumberFormatException e) {
-            throw new IllegalStateException(
-                    "Failed to parse native daemon return code for " + ifaceIn + " " + ifaceOut);
-        }
-        if (code != NetdResponseCode.TetheringStatsResult) {
-            throw new IllegalStateException(
-                    "Unexpected return code from native daemon for " + ifaceIn + " " + ifaceOut);
-        }
+        // 221 ifaceIn ifaceOut rx_bytes rx_packets tx_bytes tx_packets
+        final StringTokenizer tok = new StringTokenizer(event.getMessage());
+        tok.nextToken();
+        tok.nextToken();
 
         try {
             final NetworkStats.Entry entry = new NetworkStats.Entry();
@@ -1327,10 +1155,10 @@
             entry.uid = UID_TETHERING;
             entry.set = SET_DEFAULT;
             entry.tag = TAG_NONE;
-            entry.rxBytes = Long.parseLong(tok[3]);
-            entry.rxPackets = Long.parseLong(tok[4]);
-            entry.txBytes = Long.parseLong(tok[5]);
-            entry.txPackets = Long.parseLong(tok[6]);
+            entry.rxBytes = Long.parseLong(tok.nextToken());
+            entry.rxPackets = Long.parseLong(tok.nextToken());
+            entry.txBytes = Long.parseLong(tok.nextToken());
+            entry.txPackets = Long.parseLong(tok.nextToken());
             return entry;
         } catch (NumberFormatException e) {
             throw new IllegalStateException(
@@ -1342,50 +1170,33 @@
     public void setInterfaceThrottle(String iface, int rxKbps, int txKbps) {
         mContext.enforceCallingOrSelfPermission(CHANGE_NETWORK_STATE, TAG);
         try {
-            mConnector.doCommand(String.format(
-                    "interface setthrottle %s %d %d", iface, rxKbps, txKbps));
+            mConnector.execute("interface", "setthrottle", iface, rxKbps, txKbps);
         } catch (NativeDaemonConnectorException e) {
-            Slog.e(TAG, "Error communicating with native daemon to set throttle", e);
+            throw e.rethrowAsParcelableException();
         }
     }
 
     private int getInterfaceThrottle(String iface, boolean rx) {
         mContext.enforceCallingOrSelfPermission(ACCESS_NETWORK_STATE, TAG);
+
+        final NativeDaemonEvent event;
         try {
-            String rsp;
-            try {
-                rsp = mConnector.doCommand(
-                        String.format("interface getthrottle %s %s", iface,
-                                (rx ? "rx" : "tx"))).get(0);
-            } catch (NativeDaemonConnectorException e) {
-                Slog.e(TAG, "Error communicating with native daemon to getthrottle", e);
-                return -1;
-            }
-
-            String[] tok = rsp.split(" ");
-            if (tok.length < 2) {
-                Slog.e(TAG, "Malformed response to getthrottle command");
-                return -1;
-            }
-
-            int code;
-            try {
-                code = Integer.parseInt(tok[0]);
-            } catch (NumberFormatException nfe) {
-                Slog.e(TAG, String.format("Error parsing code %s", tok[0]));
-                return -1;
-            }
-            if ((rx && code != NetdResponseCode.InterfaceRxThrottleResult) || (
-                    !rx && code != NetdResponseCode.InterfaceTxThrottleResult)) {
-                Slog.e(TAG, String.format("Unexpected response code %d", code));
-                return -1;
-            }
-            return Integer.parseInt(tok[1]);
-        } catch (Exception e) {
-            Slog.e(TAG, String.format(
-                    "Failed to read interface %s throttle value", (rx ? "rx" : "tx")), e);
+            event = mConnector.execute("interface", "getthrottle", iface, rx ? "rx" : "tx");
+        } catch (NativeDaemonConnectorException e) {
+            throw e.rethrowAsParcelableException();
         }
-        return -1;
+
+        if (rx) {
+            event.checkCode(InterfaceRxThrottleResult);
+        } else {
+            event.checkCode(InterfaceTxThrottleResult);
+        }
+
+        try {
+            return Integer.parseInt(event.getMessage());
+        } catch (NumberFormatException e) {
+            throw new IllegalStateException("unexpected response:" + event);
+        }
     }
 
     @Override
@@ -1402,32 +1213,28 @@
     public void setDefaultInterfaceForDns(String iface) {
         mContext.enforceCallingOrSelfPermission(CHANGE_NETWORK_STATE, TAG);
         try {
-            String cmd = "resolver setdefaultif " + iface;
-
-            mConnector.doCommand(cmd);
+            mConnector.execute("resolver", "setdefaultif", iface);
         } catch (NativeDaemonConnectorException e) {
-            throw new IllegalStateException(
-                    "Error communicating with native daemon to set default interface", e);
+            throw e.rethrowAsParcelableException();
         }
     }
 
     @Override
     public void setDnsServersForInterface(String iface, String[] servers) {
         mContext.enforceCallingOrSelfPermission(CHANGE_NETWORK_STATE, TAG);
-        try {
-            String cmd = "resolver setifdns " + iface;
-            for (String s : servers) {
-                InetAddress a = NetworkUtils.numericToInetAddress(s);
-                if (a.isAnyLocalAddress() == false) {
-                    cmd += " " + a.getHostAddress();
-                }
+
+        final Command cmd = new Command("resolver", "setifdns", iface);
+        for (String s : servers) {
+            InetAddress a = NetworkUtils.numericToInetAddress(s);
+            if (a.isAnyLocalAddress() == false) {
+                cmd.appendArg(a.getHostAddress());
             }
-            mConnector.doCommand(cmd);
-        } catch (IllegalArgumentException e) {
-            throw new IllegalStateException("Error setting dnsn for interface", e);
+        }
+
+        try {
+            mConnector.execute(cmd);
         } catch (NativeDaemonConnectorException e) {
-            throw new IllegalStateException(
-                    "Error communicating with native daemon to set dns for interface", e);
+            throw e.rethrowAsParcelableException();
         }
     }
 
@@ -1435,12 +1242,9 @@
     public void flushDefaultDnsCache() {
         mContext.enforceCallingOrSelfPermission(CHANGE_NETWORK_STATE, TAG);
         try {
-            String cmd = "resolver flushdefaultif";
-
-            mConnector.doCommand(cmd);
+            mConnector.execute("resolver", "flushdefaultif");
         } catch (NativeDaemonConnectorException e) {
-            throw new IllegalStateException(
-                    "Error communicating with native deamon to flush default interface", e);
+            throw e.rethrowAsParcelableException();
         }
     }
 
@@ -1448,12 +1252,9 @@
     public void flushInterfaceDnsCache(String iface) {
         mContext.enforceCallingOrSelfPermission(CHANGE_NETWORK_STATE, TAG);
         try {
-            String cmd = "resolver flushif " + iface;
-
-            mConnector.doCommand(cmd);
+            mConnector.execute("resolver", "flushif", iface);
         } catch (NativeDaemonConnectorException e) {
-            throw new IllegalStateException(
-                    "Error communicating with native daemon to flush interface " + iface, e);
+            throw e.rethrowAsParcelableException();
         }
     }
 
diff --git a/services/java/com/android/server/NotificationManagerService.java b/services/java/com/android/server/NotificationManagerService.java
index 7d1d976..5039294 100755
--- a/services/java/com/android/server/NotificationManagerService.java
+++ b/services/java/com/android/server/NotificationManagerService.java
@@ -707,7 +707,8 @@
         //     behalf of the download manager without affecting other apps.
         if (!pkg.equals("com.android.providers.downloads")
                 || Log.isLoggable("DownloadManager", Log.VERBOSE)) {
-            EventLog.writeEvent(EventLogTags.NOTIFICATION_ENQUEUE, pkg, id, notification.toString());
+            EventLog.writeEvent(EventLogTags.NOTIFICATION_ENQUEUE, pkg, id, tag,
+                    notification.toString());
         }
 
         if (pkg == null || notification == null) {
@@ -944,7 +945,8 @@
      */
     private void cancelNotification(String pkg, String tag, int id, int mustHaveFlags,
             int mustNotHaveFlags, boolean sendDelete) {
-        EventLog.writeEvent(EventLogTags.NOTIFICATION_CANCEL, pkg, id, mustHaveFlags);
+        EventLog.writeEvent(EventLogTags.NOTIFICATION_CANCEL, pkg, id, tag,
+                mustHaveFlags, mustNotHaveFlags);
 
         synchronized (mNotificationList) {
             int index = indexOfNotificationLocked(pkg, tag, id);
@@ -972,7 +974,8 @@
      */
     boolean cancelAllNotificationsInt(String pkg, int mustHaveFlags,
             int mustNotHaveFlags, boolean doit) {
-        EventLog.writeEvent(EventLogTags.NOTIFICATION_CANCEL_ALL, pkg, mustHaveFlags);
+        EventLog.writeEvent(EventLogTags.NOTIFICATION_CANCEL_ALL, pkg, mustHaveFlags,
+                mustNotHaveFlags);
 
         synchronized (mNotificationList) {
             final int N = mNotificationList.size();
diff --git a/services/java/com/android/server/PowerManagerService.java b/services/java/com/android/server/PowerManagerService.java
index 5788a31..774495a 100644
--- a/services/java/com/android/server/PowerManagerService.java
+++ b/services/java/com/android/server/PowerManagerService.java
@@ -1689,6 +1689,11 @@
                 // before showing it to the user.  We want the light off
                 // until it is ready to be shown to the user, not it using
                 // whatever the last value it had.
+                if (DEBUG_SCREEN_ON) {
+                    Slog.i(TAG, "Forcing brightness 0: mPowerState=0x"
+                            + Integer.toHexString(mPowerState)
+                            + " mSkippedScreenOn=" + mSkippedScreenOn);
+                }
                 mScreenBrightness.forceValueLocked(Power.BRIGHTNESS_OFF);
             }
         }
@@ -2033,12 +2038,14 @@
             } finally {
                 Binder.restoreCallingIdentity(identity);
             }
-            mScreenBrightness.setTargetLocked(brightness, steps,
-                    INITIAL_SCREEN_BRIGHTNESS, nominalCurrentValue);
-            if (DEBUG_SCREEN_ON) {
-                RuntimeException e = new RuntimeException("here");
-                e.fillInStackTrace();
-                Slog.i(TAG, "Setting screen brightness: " + brightness, e);
+            if (!mSkippedScreenOn) {
+                mScreenBrightness.setTargetLocked(brightness, steps,
+                        INITIAL_SCREEN_BRIGHTNESS, nominalCurrentValue);
+                if (DEBUG_SCREEN_ON) {
+                    RuntimeException e = new RuntimeException("here");
+                    e.fillInStackTrace();
+                    Slog.i(TAG, "Setting screen brightness: " + brightness, e);
+                }
             }
         }
 
@@ -2081,6 +2088,11 @@
                             ? LightsService.BRIGHTNESS_MODE_SENSOR
                             : LightsService.BRIGHTNESS_MODE_USER);
         if ((mask & SCREEN_BRIGHT_BIT) != 0) {
+            if (DEBUG_SCREEN_ON) {
+                RuntimeException e = new RuntimeException("here");
+                e.fillInStackTrace();
+                Slog.i(TAG, "Set LCD brightness: " + value, e);
+            }
             mLcdLight.setBrightness(value, brightnessMode);
         }
         if ((mask & BUTTON_BRIGHT_BIT) != 0) {
@@ -2132,7 +2144,7 @@
             delta = (targetValue -
                     (nominalCurrentValue >= 0 ? nominalCurrentValue : curValue))
                     / stepsToTarget;
-            if (mSpew) {
+            if (mSpew || DEBUG_SCREEN_ON) {
                 String noticeMe = nominalCurrentValue == curValue ? "" : "  ******************";
                 Slog.i(TAG, "setTargetLocked mask=" + mask + " curValue=" + curValue
                         + " target=" + target + " targetValue=" + targetValue + " delta=" + delta
@@ -2523,8 +2535,10 @@
                 }
 
                 if (mAutoBrightessEnabled && mScreenBrightnessOverride < 0) {
-                    mScreenBrightness.setTargetLocked(lcdValue, AUTOBRIGHTNESS_ANIM_STEPS,
-                            INITIAL_SCREEN_BRIGHTNESS, (int)mScreenBrightness.curValue);
+                    if (!mSkippedScreenOn) {
+                        mScreenBrightness.setTargetLocked(lcdValue, AUTOBRIGHTNESS_ANIM_STEPS,
+                                INITIAL_SCREEN_BRIGHTNESS, (int)mScreenBrightness.curValue);
+                    }
                 }
                 if (mButtonBrightnessOverride < 0) {
                     mButtonLight.setBrightness(buttonValue);
diff --git a/services/java/com/android/server/TextServicesManagerService.java b/services/java/com/android/server/TextServicesManagerService.java
index d04b440..8384ebc 100644
--- a/services/java/com/android/server/TextServicesManagerService.java
+++ b/services/java/com/android/server/TextServicesManagerService.java
@@ -392,9 +392,16 @@
             Slog.d(TAG, "FinishSpellCheckerService");
         }
         synchronized(mSpellCheckerMap) {
+            final ArrayList<SpellCheckerBindGroup> removeList =
+                    new ArrayList<SpellCheckerBindGroup>();
             for (SpellCheckerBindGroup group : mSpellCheckerBindGroups.values()) {
                 if (group == null) continue;
-                group.removeListener(listener);
+                // Use removeList to avoid modifying mSpellCheckerBindGroups in this loop.
+                removeList.add(group);
+            }
+            final int removeSize = removeList.size();
+            for (int i = 0; i < removeSize; ++i) {
+                removeList.get(i).removeListener(listener);
             }
         }
     }
@@ -669,6 +676,7 @@
             }
         }
 
+        // cleanLocked may remove elements from mSpellCheckerBindGroups
         private void cleanLocked() {
             if (DBG) {
                 Slog.d(TAG, "cleanLocked");
diff --git a/services/java/com/android/server/WallpaperManagerService.java b/services/java/com/android/server/WallpaperManagerService.java
index 7fa404e..4925a4e 100644
--- a/services/java/com/android/server/WallpaperManagerService.java
+++ b/services/java/com/android/server/WallpaperManagerService.java
@@ -476,6 +476,13 @@
     ParcelFileDescriptor updateWallpaperBitmapLocked(String name) {
         if (name == null) name = "";
         try {
+            if (!WALLPAPER_DIR.exists()) {
+                WALLPAPER_DIR.mkdir();
+                FileUtils.setPermissions(
+                        WALLPAPER_DIR.getPath(),
+                        FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
+                        -1, -1);
+            }
             ParcelFileDescriptor fd = ParcelFileDescriptor.open(WALLPAPER_FILE,
                     MODE_CREATE|MODE_READ_WRITE);
             mName = name;
diff --git a/services/java/com/android/server/WifiService.java b/services/java/com/android/server/WifiService.java
index 3c65255..16643ff 100644
--- a/services/java/com/android/server/WifiService.java
+++ b/services/java/com/android/server/WifiService.java
@@ -1078,7 +1078,6 @@
                 mWifiStateMachine.setHighPerfModeEnabled(strongestLockMode
                         == WifiManager.WIFI_MODE_FULL_HIGH_PERF);
             } else {
-                mWifiStateMachine.requestCmWakeLock();
                 mWifiStateMachine.setDriverStart(false);
             }
         } else {
diff --git a/services/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/java/com/android/server/accessibility/AccessibilityManagerService.java
index 30c12f9..23fa94a 100644
--- a/services/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -115,8 +115,8 @@
 
     private final Set<ComponentName> mEnabledServices = new HashSet<ComponentName>();
 
-    private final SparseArray<IAccessibilityInteractionConnection> mWindowIdToInteractionConnectionMap =
-        new SparseArray<IAccessibilityInteractionConnection>();
+    private final SparseArray<AccessibilityConnectionWrapper> mWindowIdToInteractionConnectionWrapperMap =
+        new SparseArray<AccessibilityConnectionWrapper>();
 
     private final SparseArray<IBinder> mWindowIdToWindowTokenMap = new SparseArray<IBinder>();
 
@@ -439,16 +439,11 @@
             final IWindow addedWindowToken = windowToken;
             final IAccessibilityInteractionConnection addedConnection = connection;
             final int windowId = sNextWindowId++;
-            addedConnection.asBinder().linkToDeath(new DeathRecipient() {
-                public void binderDied() {
-                    synchronized (mLock) {
-                        addedConnection.asBinder().unlinkToDeath(this, 0);
-                        removeAccessibilityInteractionConnection(addedWindowToken);
-                    }
-                }
-            }, 0);
+            AccessibilityConnectionWrapper wrapper = new AccessibilityConnectionWrapper(windowId,
+                    connection);
+            wrapper.linkToDeath();
             mWindowIdToWindowTokenMap.put(windowId, addedWindowToken.asBinder());
-            mWindowIdToInteractionConnectionMap.put(windowId, connection);
+            mWindowIdToInteractionConnectionWrapperMap.put(windowId, wrapper);
             if (DEBUG) {
                 Slog.i(LOG_TAG, "Adding interaction connection to windowId: " + windowId);
             }
@@ -462,18 +457,17 @@
             for (int i = 0; i < count; i++) {
                 if (mWindowIdToWindowTokenMap.valueAt(i) == windowToken.asBinder()) {
                     final int windowId = mWindowIdToWindowTokenMap.keyAt(i);
-                    mWindowIdToWindowTokenMap.remove(windowId);
-                    mWindowIdToInteractionConnectionMap.remove(windowId);
-                    if (DEBUG) {
-                        Slog.i(LOG_TAG, "Removing interaction connection to windowId: " + windowId);
-                    }
+                    AccessibilityConnectionWrapper wrapper =
+                        mWindowIdToInteractionConnectionWrapperMap.get(windowId);
+                    wrapper.unlinkToDeath();
+                    removeAccessibilityInteractionConnectionLocked(windowId);
                     return;
                 }
             }
         }
     }
 
-    public IAccessibilityServiceConnection registerEventListener(IEventListener listener) {
+    public void registerEventListener(IEventListener listener) {
         mSecurityPolicy.enforceCallingPermission(Manifest.permission.RETRIEVE_WINDOW_CONTENT,
                 FUNCTION_REGISTER_EVENT_LISTENER);
         ComponentName componentName = new ComponentName("foo.bar",
@@ -501,7 +495,19 @@
         accessibilityServiceInfo.feedbackType = AccessibilityServiceInfo.FEEDBACK_GENERIC;
         Service service = new Service(componentName, accessibilityServiceInfo, true);
         service.onServiceConnected(componentName, listener.asBinder());
-        return service;
+    }
+
+    /**
+     * Removes an AccessibilityInteractionConnection.
+     *
+     * @param windowId The id of the window to which the connection is targeted.
+     */
+    private void removeAccessibilityInteractionConnectionLocked(int windowId) {
+        mWindowIdToWindowTokenMap.remove(windowId);
+        mWindowIdToInteractionConnectionWrapperMap.remove(windowId);
+        if (DEBUG) {
+            Slog.i(LOG_TAG, "Removing interaction connection to windowId: " + windowId);
+        }
     }
 
     /**
@@ -594,6 +600,13 @@
      */
     private void notifyEventListenerLocked(Service service, int eventType) {
         IEventListener listener = service.mServiceInterface;
+
+        // If the service died/was disabled while the message for dispatching
+        // the accessibility event was propagating the listener may be null.
+        if (listener == null) {
+            return;
+        }
+
         AccessibilityEvent event = service.mPendingEvents.get(eventType);
 
         // Check for null here because there is a concurrent scenario in which this
@@ -618,7 +631,7 @@
         service.mPendingEvents.remove(eventType);
         try {
             if (mSecurityPolicy.canRetrieveWindowContent(service)) {
-                event.setConnection(service);
+                event.setConnectionId(service.mId);
             } else {
                 event.setSource(null);
             }
@@ -666,6 +679,7 @@
         mComponentNameToServiceMap.remove(service.mComponentName);
         mHandler.removeMessages(service.mId);
         service.unlinkToOwnDeath();
+        service.dispose();
         updateInputFilterLocked();
         return removed;
     }
@@ -895,6 +909,33 @@
         sendStateToClientsLocked();
     }
 
+    private class AccessibilityConnectionWrapper implements DeathRecipient {
+        private final int mWindowId;
+        private final IAccessibilityInteractionConnection mConnection;
+
+        public AccessibilityConnectionWrapper(int windowId,
+                IAccessibilityInteractionConnection connection) {
+            mWindowId = windowId;
+            mConnection = connection;
+        }
+
+        public void linkToDeath() throws RemoteException {
+            mConnection.asBinder().linkToDeath(this, 0);
+        }
+
+        public void unlinkToDeath() {
+            mConnection.asBinder().unlinkToDeath(this, 0);
+        }
+
+        @Override
+        public void binderDied() {
+            unlinkToDeath();
+            synchronized (mLock) {
+                removeAccessibilityInteractionConnectionLocked(mWindowId);
+            }
+        }
+    }
+
     /**
      * This class represents an accessibility service. It stores all per service
      * data required for the service management, provides API for starting/stopping the
@@ -997,7 +1038,6 @@
                 if (!mIsAutomation) {
                     mContext.unbindService(this);
                 }
-                mService = null;
                 return true;
             }
             return false;
@@ -1021,7 +1061,7 @@
             mService = service;
             mServiceInterface = IEventListener.Stub.asInterface(service);
             try {
-                mServiceInterface.setConnection(this);
+                mServiceInterface.setConnection(this, mId);
                 synchronized (mLock) {
                     tryAddServiceLocked(this);
                 }
@@ -1123,14 +1163,16 @@
                 if (!permissionGranted) {
                     return 0;
                 } else {
-                    connection = mWindowIdToInteractionConnectionMap.get(accessibilityWindowId);
-                    if (connection == null) {
+                    AccessibilityConnectionWrapper wrapper =
+                        mWindowIdToInteractionConnectionWrapperMap.get(accessibilityWindowId);
+                    if (wrapper == null) {
                         if (DEBUG) {
                             Slog.e(LOG_TAG, "No interaction connection to window: "
                                     + accessibilityWindowId);
                         }
                         return 0;
                     }
+                    connection = wrapper.mConnection;
                 }
             }
             final int interrogatingPid = Binder.getCallingPid();
@@ -1159,14 +1201,16 @@
                 if (!permissionGranted) {
                     return false;
                 } else {
-                    connection = mWindowIdToInteractionConnectionMap.get(accessibilityWindowId);
-                    if (connection == null) {
+                    AccessibilityConnectionWrapper wrapper =
+                        mWindowIdToInteractionConnectionWrapperMap.get(accessibilityWindowId);
+                    if (wrapper == null) {
                         if (DEBUG) {
                             Slog.e(LOG_TAG, "No interaction connection to window: "
                                     + accessibilityWindowId);
                         }
                         return false;
                     }
+                    connection = wrapper.mConnection;
                 }
             }
             final int interrogatingPid = Binder.getCallingPid();
@@ -1197,9 +1241,21 @@
             mService.unlinkToDeath(this, 0);
         }
 
+        public void dispose() {
+            try {
+                // Clear the proxy in the other process so this
+                // IAccessibilityServiceConnection can be garbage collected.
+                mServiceInterface.setConnection(null, mId);
+            } catch (RemoteException re) {
+                /* ignore */
+            }
+            mService = null;
+            mServiceInterface = null;
+        }
+
         public void binderDied() {
             synchronized (mLock) {
-                mService.unlinkToDeath(this, 0);
+                unlinkToOwnDeath();
                 tryRemoveServiceLocked(this);
                 // We no longer have an automation service, so restore
                 // the state based on values in the settings database.
@@ -1214,7 +1270,9 @@
             if (DEBUG) {
                 Slog.i(LOG_TAG, "Trying to get interaction connection to windowId: " + windowId);
             }
-            return mWindowIdToInteractionConnectionMap.get(windowId);
+            AccessibilityConnectionWrapper wrapper =
+                mWindowIdToInteractionConnectionWrapperMap.get(windowId);
+            return (wrapper != null) ? wrapper.mConnection : null;
         }
 
         private float getCompatibilityScale(int windowId) {
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 8023477..df58e83 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -129,7 +129,6 @@
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.IOException;
-import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.PrintWriter;
 import java.io.StringWriter;
@@ -415,7 +414,12 @@
      * is in a different process from the one they are currently in.
      */
     ProcessRecord mPreviousProcess;
-    
+
+    /**
+     * The time at which the previous process was last visible.
+     */
+    long mPreviousProcessVisibleTime;
+
     /**
      * Packages that the user has asked to have run in screen size
      * compatibility mode instead of filling the screen.
@@ -1222,6 +1226,23 @@
                     @Override public void run() {
                         StringBuilder dropBuilder = new StringBuilder(1024);
                         StringBuilder logBuilder = new StringBuilder(1024);
+                        StringWriter oomSw = new StringWriter();
+                        PrintWriter oomPw = new PrintWriter(oomSw);
+                        StringWriter catSw = new StringWriter();
+                        PrintWriter catPw = new PrintWriter(catSw);
+                        String[] emptyArgs = new String[] { };
+                        StringBuilder tag = new StringBuilder(128);
+                        StringBuilder stack = new StringBuilder(128);
+                        tag.append("Low on memory -- ");
+                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw,
+                                tag, stack);
+                        dropBuilder.append(stack);
+                        dropBuilder.append('\n');
+                        dropBuilder.append('\n');
+                        String oomString = oomSw.toString();
+                        dropBuilder.append(oomString);
+                        dropBuilder.append('\n');
+                        logBuilder.append(oomString);
                         try {
                             java.lang.Process proc = Runtime.getRuntime().exec(new String[] {
                                     "procrank", });
@@ -1244,27 +1265,15 @@
                             converter.close();
                         } catch (IOException e) {
                         }
-                        StringWriter sw = new StringWriter();
-                        PrintWriter pw = new PrintWriter(sw);
-                        StringWriter catSw = new StringWriter();
-                        PrintWriter catPw = new PrintWriter(catSw);
-                        String[] emptyArgs = new String[] { };
-                        StringBuilder tag = new StringBuilder(128);
                         synchronized (ActivityManagerService.this) {
+                            catPw.println();
                             dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
                             catPw.println();
                             dumpServicesLocked(null, catPw, emptyArgs, 0, false, false, null);
                             catPw.println();
                             dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
-                            catPw.println();
                         }
-                        tag.append("Low on memory -- ");
-                        dumpApplicationMemoryUsage(null, pw, "  ", emptyArgs, true, catPw, tag);
-                        String memUsage = sw.toString();
-                        dropBuilder.append('\n');
-                        dropBuilder.append(memUsage);
                         dropBuilder.append(catSw.toString());
-                        logBuilder.append(memUsage);
                         addErrorToDropBox("lowmem", null, "system_server", null,
                                 null, tag.toString(), dropBuilder.toString(), null, null);
                         Slog.i(TAG, logBuilder.toString());
@@ -1420,7 +1429,7 @@
             }
 
             mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args,
-                    false, null, null);
+                    false, null, null, null);
         }
     }
 
@@ -2716,6 +2725,10 @@
                     }
                     if (!r.finishing) {
                         Slog.w(TAG, "Force removing " + r + ": app died, no saved state");
+                        EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
+                                System.identityHashCode(r),
+                                r.task.taskId, r.shortComponentName,
+                                "proc died without state saved");
                     }
                     r.makeFinishing();
                     mMainStack.mHistory.remove(i);
@@ -8353,6 +8366,12 @@
         pw.println();
         pw.println("  mHomeProcess: " + mHomeProcess);
         pw.println("  mPreviousProcess: " + mPreviousProcess);
+        if (dumpAll) {
+            StringBuilder sb = new StringBuilder(128);
+            sb.append("  mPreviousProcessVisibleTime: ");
+            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
+            pw.println(sb);
+        }
         if (mHeavyWeightProcess != null) {
             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
         }
@@ -9416,7 +9435,7 @@
             } else if (r.setAdj >= ProcessList.SERVICE_ADJ) {
                 oomAdj = buildOomTag("svc  ", null, r.setAdj, ProcessList.SERVICE_ADJ);
             } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) {
-                oomAdj = buildOomTag("bckup", null, r.setAdj, ProcessList.BACKUP_APP_ADJ);
+                oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ);
             } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
                 oomAdj = buildOomTag("hvy  ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ);
             } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
@@ -9645,7 +9664,8 @@
         1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
     };
 
-    static final void appendMemBucket(StringBuilder out, long memKB, String label) {
+    static final void appendMemBucket(StringBuilder out, long memKB, String label,
+            boolean stackLike) {
         int start = label.lastIndexOf('.');
         if (start >= 0) start++;
         else start = 0;
@@ -9654,13 +9674,13 @@
             if (DUMP_MEM_BUCKETS[i] >= memKB) {
                 long bucket = DUMP_MEM_BUCKETS[i]/1024;
                 out.append(bucket);
-                out.append("MB ");
+                out.append(stackLike ? "MB." : "MB ");
                 out.append(label, start, end);
                 return;
             }
         }
         out.append(memKB/1024);
-        out.append("MB ");
+        out.append(stackLike ? "MB." : "MB ");
         out.append(label, start, end);
     }
 
@@ -9679,7 +9699,7 @@
 
     final void dumpApplicationMemoryUsage(FileDescriptor fd,
             PrintWriter pw, String prefix, String[] args, boolean brief,
-            PrintWriter categoryPw, StringBuilder outTag) {
+            PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) {
         boolean dumpAll = false;
         boolean oomOnly = false;
         
@@ -9816,8 +9836,14 @@
                 }
             }
 
-            if (outTag != null) {
-                appendMemBucket(outTag, totalPss, "total");
+            if (outTag != null || outStack != null) {
+                if (outTag != null) {
+                    appendMemBucket(outTag, totalPss, "total", false);
+                }
+                if (outStack != null) {
+                    appendMemBucket(outStack, totalPss, "total", true);
+                }
+                boolean firstLine = true;
                 for (int i=0; i<oomMems.size(); i++) {
                     MemItem miCat = oomMems.get(i);
                     if (miCat.subitems == null || miCat.subitems.size() < 1) {
@@ -9826,13 +9852,47 @@
                     if (miCat.id < ProcessList.SERVICE_ADJ
                             || miCat.id == ProcessList.HOME_APP_ADJ
                             || miCat.id == ProcessList.PREVIOUS_APP_ADJ) {
-                        outTag.append(" / ");
+                        if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
+                            outTag.append(" / ");
+                        }
+                        if (outStack != null) {
+                            if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
+                                if (firstLine) {
+                                    outStack.append(":");
+                                    firstLine = false;
+                                }
+                                outStack.append("\n\t at ");
+                            } else {
+                                outStack.append("$");
+                            }
+                        }
                         for (int j=0; j<miCat.subitems.size(); j++) {
                             MemItem mi = miCat.subitems.get(j);
                             if (j > 0) {
-                                outTag.append(" ");
+                                if (outTag != null) {
+                                    outTag.append(" ");
+                                }
+                                if (outStack != null) {
+                                    outStack.append("$");
+                                }
                             }
-                            appendMemBucket(outTag, mi.pss, mi.shortLabel);
+                            if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
+                                appendMemBucket(outTag, mi.pss, mi.shortLabel, false);
+                            }
+                            if (outStack != null) {
+                                appendMemBucket(outStack, mi.pss, mi.shortLabel, true);
+                            }
+                        }
+                        if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
+                            outStack.append("(");
+                            for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
+                                if (DUMP_MEM_OOM_ADJ[k] == miCat.id) {
+                                    outStack.append(DUMP_MEM_OOM_LABEL[k]);
+                                    outStack.append(":");
+                                    outStack.append(DUMP_MEM_OOM_ADJ[k]);
+                                }
+                            }
+                            outStack.append(")");
                         }
                     }
                 }
@@ -13551,6 +13611,7 @@
                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
                         app.adjType = "stopping";
                     }
+                    app.hidden = false;
                     app.foregroundActivities = true;
                 }
             }
@@ -14199,7 +14260,7 @@
 
         if (app.curAdj != app.setAdj) {
             if (Process.setOomAdj(app.pid, app.curAdj)) {
-                if (true || DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
+                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
                     TAG, "Set " + app.pid + " " + app.processName +
                     " adj " + app.curAdj + ": " + app.adjType);
                 app.setAdj = app.curAdj;
@@ -14358,10 +14419,16 @@
                             app.thread.scheduleTrimMemory(curLevel);
                         } catch (RemoteException e) {
                         }
-                        if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE) {
-                            // For these apps we will also finish their activities
-                            // to help them free memory.
-                            mMainStack.destroyActivitiesLocked(app, false, "trim");
+                        if (false) {
+                            // For now we won't do this; our memory trimming seems
+                            // to be good enough at this point that destroying
+                            // activities causes more harm than good.
+                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
+                                    && app != mHomeProcess && app != mPreviousProcess) {
+                                // For these apps we will also finish their activities
+                                // to help them free memory.
+                                mMainStack.destroyActivitiesLocked(app, false, "trim");
+                            }
                         }
                     }
                     app.trimMemoryLevel = curLevel;
diff --git a/services/java/com/android/server/am/ActivityRecord.java b/services/java/com/android/server/am/ActivityRecord.java
index 951a946..c819114 100644
--- a/services/java/com/android/server/am/ActivityRecord.java
+++ b/services/java/com/android/server/am/ActivityRecord.java
@@ -80,6 +80,7 @@
     ThumbnailHolder thumbHolder; // where our thumbnails should go.
     long launchTime;        // when we starting launching this activity
     long startTime;         // last time this activity was started
+    long lastVisibleTime;   // last time this activity became visible
     long cpuTimeAtResume;   // the cpu time of host process at the time of resuming activity
     Configuration configuration; // configuration activity was last running in
     CompatibilityInfo compat;// last used compatibility mode
@@ -188,6 +189,10 @@
                     TimeUtils.formatDuration(launchTime, pw); pw.print(" startTime=");
                     TimeUtils.formatDuration(startTime, pw); pw.println("");
         }
+        if (lastVisibleTime != 0) {
+            pw.print(prefix); pw.print("lastVisibleTime=");
+                    TimeUtils.formatDuration(lastVisibleTime, pw); pw.println("");
+        }
         if (waitingVisible || nowVisible) {
             pw.print(prefix); pw.print("waitingVisible="); pw.print(waitingVisible);
                     pw.print(" nowVisible="); pw.println(nowVisible);
@@ -632,6 +637,7 @@
                     ActivityManagerService.TAG, "windowsVisible(): " + this);
             if (!nowVisible) {
                 nowVisible = true;
+                lastVisibleTime = SystemClock.uptimeMillis();
                 if (!idle) {
                     // Instead of doing the full stop routine here, let's just
                     // hide any activities we now can, and let them stop when
diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java
index c7ce3c3..6c11953 100644
--- a/services/java/com/android/server/am/ActivityStack.java
+++ b/services/java/com/android/server/am/ActivityStack.java
@@ -949,6 +949,22 @@
             if (r.configDestroy) {
                 destroyActivityLocked(r, true, false, "stop-config");
                 resumeTopActivityLocked(null);
+            } else {
+                // Now that this process has stopped, we may want to consider
+                // it to be the previous app to try to keep around in case
+                // the user wants to return to it.
+                ProcessRecord fgApp = null;
+                if (mResumedActivity != null) {
+                    fgApp = mResumedActivity.app;
+                } else if (mPausingActivity != null) {
+                    fgApp = mPausingActivity.app;
+                }
+                if (r.app != null && fgApp != null && r.app != fgApp
+                        && r.lastVisibleTime > mService.mPreviousProcessVisibleTime
+                        && r.app != mService.mHomeProcess) {
+                    mService.mPreviousProcess = r.app;
+                    mService.mPreviousProcessVisibleTime = r.lastVisibleTime;
+                }
             }
         }
     }
@@ -1363,14 +1379,6 @@
                         + ", nowVisible=" + next.nowVisible);
                 }
             }
-
-            if (!prev.finishing && prev.app != null && prev.app != next.app
-                    && prev.app != mService.mHomeProcess) {
-                // We are switching to a new activity that is in a different
-                // process than the previous one.  Note the previous process,
-                // so we can try to keep it around.
-                mService.mPreviousProcess = prev.app;
-            }
         }
 
         // Launching this app's activity, make sure the app is no longer
@@ -1924,8 +1932,9 @@
                     // should be left as-is.
                     replyChainEnd = -1;
                 }
-                
-            } else if (target.resultTo != null) {
+
+            } else if (target.resultTo != null && (below == null
+                    || below.task == target.task)) {
                 // If this activity is sending a reply to a previous
                 // activity, we can't do anything with it now until
                 // we reach the start of the reply chain.
@@ -1955,6 +1964,8 @@
                         replyChainEnd = targetI;
                     }
                     ActivityRecord p = null;
+                    if (DEBUG_TASKS) Slog.v(TAG, "Finishing task at index "
+                            + targetI + " to " + replyChainEnd);
                     for (int srcPos=targetI; srcPos<=replyChainEnd; srcPos++) {
                         p = mHistory.get(srcPos);
                         if (p.finishing) {
@@ -1973,6 +1984,8 @@
                     if (replyChainEnd < 0) {
                         replyChainEnd = targetI;
                     }
+                    if (DEBUG_TASKS) Slog.v(TAG, "Reparenting task at index "
+                            + targetI + " to " + replyChainEnd);
                     for (int srcPos=replyChainEnd; srcPos>=targetI; srcPos--) {
                         ActivityRecord p = mHistory.get(srcPos);
                         if (p.finishing) {
@@ -1994,6 +2007,7 @@
                         p.setTask(task, null, false);
                         mHistory.add(lastReparentPos, p);
                         if (DEBUG_TASKS) Slog.v(TAG, "Pulling activity " + p
+                                + " from " + srcPos + " to " + lastReparentPos
                                 + " in to resetting task " + task);
                         mService.mWindowManager.moveAppToken(lastReparentPos, p.appToken);
                         mService.mWindowManager.setAppGroupId(p.appToken, p.task.taskId);
@@ -2023,6 +2037,11 @@
                         }
                     }
                 }
+
+            } else if (below != null && below.task != target.task) {
+                // We hit the botton of a task; the reply chain can't
+                // pass through it.
+                replyChainEnd = -1;
             }
             
             target = below;
diff --git a/services/java/com/android/server/am/TaskRecord.java b/services/java/com/android/server/am/TaskRecord.java
index a860763..de3129b 100644
--- a/services/java/com/android/server/am/TaskRecord.java
+++ b/services/java/com/android/server/am/TaskRecord.java
@@ -54,8 +54,17 @@
     
     void setIntent(Intent _intent, ActivityInfo info) {
         stringName = null;
-        
+
         if (info.targetActivity == null) {
+            if (_intent != null) {
+                // If this Intent has a selector, we want to clear it for the
+                // recent task since it is not relevant if the user later wants
+                // to re-launch the app.
+                if (_intent.getSelector() != null) {
+                    _intent = new Intent(_intent);
+                    _intent.setSelector(null);
+                }
+            }
             intent = _intent;
             realActivity = _intent != null ? _intent.getComponent() : null;
             origActivity = null;
@@ -65,6 +74,7 @@
             if (_intent != null) {
                 Intent targetIntent = new Intent(_intent);
                 targetIntent.setComponent(targetComponent);
+                targetIntent.setSelector(null);
                 intent = targetIntent;
                 realActivity = targetComponent;
                 origActivity = _intent.getComponent();
diff --git a/services/java/com/android/server/connectivity/Tethering.java b/services/java/com/android/server/connectivity/Tethering.java
index c344bc6..b1551a6 100644
--- a/services/java/com/android/server/connectivity/Tethering.java
+++ b/services/java/com/android/server/connectivity/Tethering.java
@@ -545,14 +545,13 @@
                     ifcg = mNMService.getInterfaceConfig(iface);
                     if (ifcg != null) {
                         InetAddress addr = NetworkUtils.numericToInetAddress(USB_NEAR_IFACE_ADDR);
-                        ifcg.addr = new LinkAddress(addr, USB_PREFIX_LENGTH);
+                        ifcg.setLinkAddress(new LinkAddress(addr, USB_PREFIX_LENGTH));
                         if (enabled) {
-                            ifcg.interfaceFlags = ifcg.interfaceFlags.replace("down", "up");
+                            ifcg.setInterfaceUp();
                         } else {
-                            ifcg.interfaceFlags = ifcg.interfaceFlags.replace("up", "down");
+                            ifcg.setInterfaceDown();
                         }
-                        ifcg.interfaceFlags = ifcg.interfaceFlags.replace("running", "");
-                        ifcg.interfaceFlags = ifcg.interfaceFlags.replace("  "," ");
+                        ifcg.clearFlag("running");
                         mNMService.setInterfaceConfig(iface, ifcg);
                     }
                 } catch (Exception e) {
diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java
index 7005541..6b61c47 100644
--- a/services/java/com/android/server/pm/PackageManagerService.java
+++ b/services/java/com/android/server/pm/PackageManagerService.java
@@ -2162,6 +2162,9 @@
             int flags, List<ResolveInfo> query, int priority) {
         // writer
         synchronized (mPackages) {
+            if (intent.getSelector() != null) {
+                intent = intent.getSelector(); 
+            }
             if (DEBUG_PREFERRED) intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION);
             List<PreferredActivity> prefs =
                     mSettings.mPreferredActivities.queryIntent(intent, resolvedType,
@@ -2242,7 +2245,13 @@
 
     public List<ResolveInfo> queryIntentActivities(Intent intent,
             String resolvedType, int flags) {
-        final ComponentName comp = intent.getComponent();
+        ComponentName comp = intent.getComponent();
+        if (comp == null) {
+            if (intent.getSelector() != null) {
+                intent = intent.getSelector(); 
+                comp = intent.getComponent();
+            }
+        }
         if (comp != null) {
             final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
             final ActivityInfo ai = getActivityInfo(comp, flags);
@@ -2440,6 +2449,12 @@
 
     public List<ResolveInfo> queryIntentReceivers(Intent intent, String resolvedType, int flags) {
         ComponentName comp = intent.getComponent();
+        if (comp == null) {
+            if (intent.getSelector() != null) {
+                intent = intent.getSelector(); 
+                comp = intent.getComponent();
+            }
+        }
         if (comp != null) {
             List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
             ActivityInfo ai = getReceiverInfo(comp, flags);
@@ -2478,7 +2493,13 @@
     }
 
     public List<ResolveInfo> queryIntentServices(Intent intent, String resolvedType, int flags) {
-        final ComponentName comp = intent.getComponent();
+        ComponentName comp = intent.getComponent();
+        if (comp == null) {
+            if (intent.getSelector() != null) {
+                intent = intent.getSelector(); 
+                comp = intent.getComponent();
+            }
+        }
         if (comp != null) {
             final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
             final ServiceInfo si = getServiceInfo(comp, flags);
diff --git a/services/java/com/android/server/wm/DragState.java b/services/java/com/android/server/wm/DragState.java
index 73cd64e..a19035a 100644
--- a/services/java/com/android/server/wm/DragState.java
+++ b/services/java/com/android/server/wm/DragState.java
@@ -16,6 +16,7 @@
 
 package com.android.server.wm;
 
+import com.android.server.wm.WindowManagerService.DragInputEventReceiver;
 import com.android.server.wm.WindowManagerService.H;
 
 import android.content.ClipData;
@@ -28,7 +29,6 @@
 import android.util.Slog;
 import android.view.DragEvent;
 import android.view.InputChannel;
-import android.view.InputQueue;
 import android.view.Surface;
 import android.view.View;
 import android.view.WindowManager;
@@ -50,6 +50,7 @@
     float mCurrentX, mCurrentY;
     float mThumbOffsetX, mThumbOffsetY;
     InputChannel mServerChannel, mClientChannel;
+    DragInputEventReceiver mInputEventReceiver;
     InputApplicationHandle mDragApplicationHandle;
     InputWindowHandle mDragWindowHandle;
     WindowState mTargetWindow;
@@ -90,8 +91,8 @@
             mServerChannel = channels[0];
             mClientChannel = channels[1];
             mService.mInputManager.registerInputChannel(mServerChannel, null);
-            InputQueue.registerInputChannel(mClientChannel, mService.mDragInputHandler,
-                    mService.mH.getLooper().getQueue());
+            mInputEventReceiver = mService.new DragInputEventReceiver(mClientChannel,
+                    mService.mH.getLooper());
 
             mDragApplicationHandle = new InputApplicationHandle(null);
             mDragApplicationHandle.name = "drag";
@@ -139,7 +140,8 @@
             Slog.e(WindowManagerService.TAG, "Unregister of nonexistent drag input channel");
         } else {
             mService.mInputManager.unregisterInputChannel(mServerChannel);
-            InputQueue.unregisterInputChannel(mClientChannel);
+            mInputEventReceiver.dispose();
+            mInputEventReceiver = null;
             mClientChannel.dispose();
             mServerChannel.dispose();
             mClientChannel = null;
diff --git a/services/java/com/android/server/wm/FakeWindowImpl.java b/services/java/com/android/server/wm/FakeWindowImpl.java
index 0e72f7d..121ce18 100644
--- a/services/java/com/android/server/wm/FakeWindowImpl.java
+++ b/services/java/com/android/server/wm/FakeWindowImpl.java
@@ -20,7 +20,7 @@
 import android.os.Process;
 import android.util.Slog;
 import android.view.InputChannel;
-import android.view.InputHandler;
+import android.view.InputEventReceiver;
 import android.view.InputQueue;
 import android.view.WindowManagerPolicy;
 
@@ -29,11 +29,13 @@
     final InputChannel mServerChannel, mClientChannel;
     final InputApplicationHandle mApplicationHandle;
     final InputWindowHandle mWindowHandle;
+    final InputEventReceiver mInputEventReceiver;
     final int mWindowLayer;
 
     boolean mTouchFullscreen;
 
-    public FakeWindowImpl(WindowManagerService service, Looper looper, InputHandler inputHandler,
+    public FakeWindowImpl(WindowManagerService service,
+            Looper looper, InputEventReceiver.Factory inputEventReceiverFactory,
             String name, int windowType, int layoutParamsFlags, boolean canReceiveKeys,
             boolean hasFocus, boolean touchFullscreen) {
         mService = service;
@@ -42,7 +44,9 @@
         mServerChannel = channels[0];
         mClientChannel = channels[1];
         mService.mInputManager.registerInputChannel(mServerChannel, null);
-        InputQueue.registerInputChannel(mClientChannel, inputHandler, looper.getQueue());
+
+        mInputEventReceiver = inputEventReceiverFactory.createInputEventReceiver(
+                mClientChannel, looper);
 
         mApplicationHandle = new InputApplicationHandle(null);
         mApplicationHandle.name = name;
@@ -87,8 +91,8 @@
     public void dismiss() {
         synchronized (mService.mWindowMap) {
             if (mService.removeFakeWindowLocked(this)) {
+                mInputEventReceiver.dispose();
                 mService.mInputManager.unregisterInputChannel(mServerChannel);
-                InputQueue.unregisterInputChannel(mClientChannel);
                 mClientChannel.dispose();
                 mServerChannel.dispose();
             }
diff --git a/services/java/com/android/server/wm/Session.java b/services/java/com/android/server/wm/Session.java
index ee62a56..77575f2 100644
--- a/services/java/com/android/server/wm/Session.java
+++ b/services/java/com/android/server/wm/Session.java
@@ -151,18 +151,22 @@
 
     public int relayout(IWindow window, int seq, WindowManager.LayoutParams attrs,
             int requestedWidth, int requestedHeight, int viewFlags,
-            boolean insetsPending, Rect outFrame, Rect outContentInsets,
+            int flags, Rect outFrame, Rect outContentInsets,
             Rect outVisibleInsets, Configuration outConfig, Surface outSurface) {
         if (false) Slog.d(WindowManagerService.TAG, ">>>>>> ENTERED relayout from "
                 + Binder.getCallingPid());
         int res = mService.relayoutWindow(this, window, seq, attrs,
-                requestedWidth, requestedHeight, viewFlags, insetsPending,
+                requestedWidth, requestedHeight, viewFlags, flags,
                 outFrame, outContentInsets, outVisibleInsets, outConfig, outSurface);
         if (false) Slog.d(WindowManagerService.TAG, "<<<<<< EXITING relayout to "
                 + Binder.getCallingPid());
         return res;
     }
 
+    public void performDeferredDestroy(IWindow window) {
+        mService.performDeferredDestroyWindow(this, window);
+    }
+
     public boolean outOfMemory(IWindow window) {
         return mService.outOfMemoryWindow(this, window);
     }
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index ebb13d5..75ace4f 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -36,7 +36,6 @@
 import com.android.internal.app.IBatteryStats;
 import com.android.internal.policy.PolicyManager;
 import com.android.internal.policy.impl.PhoneWindowManager;
-import com.android.internal.view.BaseInputHandler;
 import com.android.internal.view.IInputContext;
 import com.android.internal.view.IInputMethodClient;
 import com.android.internal.view.IInputMethodManager;
@@ -107,8 +106,7 @@
 import android.view.InputChannel;
 import android.view.InputDevice;
 import android.view.InputEvent;
-import android.view.InputHandler;
-import android.view.InputQueue;
+import android.view.InputEventReceiver;
 import android.view.KeyEvent;
 import android.view.MotionEvent;
 import android.view.Surface;
@@ -429,6 +427,18 @@
     boolean mSystemBooted = false;
     boolean mForceDisplayEnabled = false;
     boolean mShowingBootMessages = false;
+
+    // This protects the following display size properties, so that
+    // getDisplaySize() doesn't need to acquire the global lock.  This is
+    // needed because the window manager sometimes needs to use ActivityThread
+    // while it has its global state locked (for example to load animation
+    // resources), but the ActivityThread also needs get the current display
+    // size sometimes when it has its package lock held.
+    //
+    // These will only be modified with both mWindowMap and mDisplaySizeLock
+    // held (in that order) so the window manager doesn't need to acquire this
+    // lock when needing these values in its normal operation.
+    final Object mDisplaySizeLock = new Object();
     int mInitialDisplayWidth = 0;
     int mInitialDisplayHeight = 0;
     int mBaseDisplayWidth = 0;
@@ -437,6 +447,7 @@
     int mCurDisplayHeight = 0;
     int mAppDisplayWidth = 0;
     int mAppDisplayHeight = 0;
+
     int mRotation = 0;
     int mForcedAppOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
     boolean mAltOrientation = false;
@@ -558,18 +569,25 @@
     boolean mTurnOnScreen;
 
     DragState mDragState = null;
-    final InputHandler mDragInputHandler = new BaseInputHandler() {
+
+    final class DragInputEventReceiver extends InputEventReceiver {
+        public DragInputEventReceiver(InputChannel inputChannel, Looper looper) {
+            super(inputChannel, looper);
+        }
+
         @Override
-        public void handleMotion(MotionEvent event, InputQueue.FinishedCallback finishedCallback) {
+        public void onInputEvent(InputEvent event) {
             boolean handled = false;
             try {
-                if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0
+                if (event instanceof MotionEvent
+                        && (event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0
                         && mDragState != null) {
+                    final MotionEvent motionEvent = (MotionEvent)event;
                     boolean endDrag = false;
-                    final float newX = event.getRawX();
-                    final float newY = event.getRawY();
+                    final float newX = motionEvent.getRawX();
+                    final float newY = motionEvent.getRawY();
 
-                    switch (event.getAction()) {
+                    switch (motionEvent.getAction()) {
                     case MotionEvent.ACTION_DOWN: {
                         if (DEBUG_DRAG) {
                             Slog.w(TAG, "Unexpected ACTION_DOWN in drag layer");
@@ -610,10 +628,10 @@
             } catch (Exception e) {
                 Slog.e(TAG, "Exception caught by drag handleMotion", e);
             } finally {
-                finishedCallback.finished(handled);
+                finishInputEvent(event, handled);
             }
         }
-    };
+    }
 
     /**
      * Whether the UI is currently running in touch mode (not showing
@@ -2499,12 +2517,13 @@
 
     public int relayoutWindow(Session session, IWindow client, int seq,
             WindowManager.LayoutParams attrs, int requestedWidth,
-            int requestedHeight, int viewVisibility, boolean insetsPending,
+            int requestedHeight, int viewVisibility, int flags,
             Rect outFrame, Rect outContentInsets, Rect outVisibleInsets,
             Configuration outConfig, Surface outSurface) {
         boolean displayed = false;
         boolean inTouchMode;
         boolean configChanged;
+        boolean surfaceChanged = false;
 
         // if they don't have this permission, mask out the status bar bits
         int systemUiVisibility = 0;
@@ -2534,6 +2553,9 @@
                 mPolicy.adjustWindowParamsLw(attrs);
             }
 
+            win.mSurfaceDestroyDeferred =
+                    (flags&WindowManagerImpl.RELAYOUT_DEFER_SURFACE_DESTROY) != 0;
+
             int attrChanges = 0;
             int flagChanges = 0;
             if (attrs != null) {
@@ -2630,8 +2652,12 @@
                     // To change the format, we need to re-build the surface.
                     win.destroySurfaceLocked();
                     displayed = true;
+                    surfaceChanged = true;
                 }
                 try {
+                    if (win.mSurface == null) {
+                        surfaceChanged = true;
+                    }
                     Surface surface = win.createSurfaceLocked();
                     if (surface != null) {
                         outSurface.copyFrom(surface);
@@ -2683,6 +2709,7 @@
                     // If we are not currently running the exit animation, we
                     // need to see about starting one.
                     if (!win.mExiting || win.mSurfacePendingDestroy) {
+                        surfaceChanged = true;
                         // Try starting an animation; if there isn't one, we
                         // can destroy the surface right away.
                         int transit = WindowManagerPolicy.TRANSIT_EXIT;
@@ -2715,10 +2742,10 @@
                 if (win.mSurface == null || (win.getAttrs().flags
                         & WindowManager.LayoutParams.FLAG_KEEP_SURFACE_WHILE_ANIMATING) == 0
                         || win.mSurfacePendingDestroy) {
-                    // We are being called from a local process, which
+                    // We could be called from a local process, which
                     // means outSurface holds its current surface.  Ensure the
-                    // surface object is cleared, but we don't want it actually
-                    // destroyed at this point.
+                    // surface object is cleared, but we don't necessarily want
+                    // it actually destroyed at this point.
                     win.mSurfacePendingDestroy = false;
                     outSurface.release();
                     if (DEBUG_VISIBILITY) Slog.i(TAG, "Releasing surface in: " + win);
@@ -2760,7 +2787,7 @@
             }
 
             mLayoutNeeded = true;
-            win.mGivenInsetsPending = insetsPending;
+            win.mGivenInsetsPending = (flags&WindowManagerImpl.RELAYOUT_INSETS_PENDING) != 0;
             if (assignLayers) {
                 assignLayersLocked();
             }
@@ -2797,8 +2824,25 @@
 
         Binder.restoreCallingIdentity(origId);
 
-        return (inTouchMode ? WindowManagerImpl.RELAYOUT_IN_TOUCH_MODE : 0)
-                | (displayed ? WindowManagerImpl.RELAYOUT_FIRST_TIME : 0);
+        return (inTouchMode ? WindowManagerImpl.RELAYOUT_RES_IN_TOUCH_MODE : 0)
+                | (displayed ? WindowManagerImpl.RELAYOUT_RES_FIRST_TIME : 0)
+                | (surfaceChanged ? WindowManagerImpl.RELAYOUT_RES_SURFACE_CHANGED : 0);
+    }
+
+    public void performDeferredDestroyWindow(Session session, IWindow client) {
+        long origId = Binder.clearCallingIdentity();
+
+        try {
+            synchronized(mWindowMap) {
+                WindowState win = windowForClientLocked(session, client, false);
+                if (win == null) {
+                    return;
+                }
+                win.destroyDeferredSurfaceLocked();
+            }
+        } finally {
+            Binder.restoreCallingIdentity(origId);
+        }
     }
 
     public boolean outOfMemoryWindow(Session session, IWindow client) {
@@ -3738,7 +3782,7 @@
                 return;
             }
 
-            // If this is a translucent or wallpaper window, then don't
+            // If this is a translucent window, then don't
             // show a starting window -- the current effect (a full-screen
             // opaque starting window that fades away to the real contents
             // when it is ready) does not work for this.
@@ -3755,7 +3799,16 @@
                 }
                 if (ent.array.getBoolean(
                         com.android.internal.R.styleable.Window_windowShowWallpaper, false)) {
-                    return;
+                    if (mWallpaperTarget == null) {
+                        // If this theme is requesting a wallpaper, and the wallpaper
+                        // is not curently visible, then this effectively serves as
+                        // an opaque window and our starting window transition animation
+                        // can still work.  We just need to make sure the starting window
+                        // is also showing the wallpaper.
+                        windowFlags |= WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
+                    } else {
+                        return;
+                    }
                 }
             }
 
@@ -5971,25 +6024,27 @@
         final int realdw = rotated ? mBaseDisplayHeight : mBaseDisplayWidth;
         final int realdh = rotated ? mBaseDisplayWidth : mBaseDisplayHeight;
 
-        if (mAltOrientation) {
-            mCurDisplayWidth = realdw;
-            mCurDisplayHeight = realdh;
-            if (realdw > realdh) {
-                // Turn landscape into portrait.
-                int maxw = (int)(realdh/1.3f);
-                if (maxw < realdw) {
-                    mCurDisplayWidth = maxw;
+        synchronized(mDisplaySizeLock) {
+            if (mAltOrientation) {
+                mCurDisplayWidth = realdw;
+                mCurDisplayHeight = realdh;
+                if (realdw > realdh) {
+                    // Turn landscape into portrait.
+                    int maxw = (int)(realdh/1.3f);
+                    if (maxw < realdw) {
+                        mCurDisplayWidth = maxw;
+                    }
+                } else {
+                    // Turn portrait into landscape.
+                    int maxh = (int)(realdw/1.3f);
+                    if (maxh < realdh) {
+                        mCurDisplayHeight = maxh;
+                    }
                 }
             } else {
-                // Turn portrait into landscape.
-                int maxh = (int)(realdw/1.3f);
-                if (maxh < realdh) {
-                    mCurDisplayHeight = maxh;
-                }
+                mCurDisplayWidth = realdw;
+                mCurDisplayHeight = realdh;
             }
-        } else {
-            mCurDisplayWidth = realdw;
-            mCurDisplayHeight = realdh;
         }
 
         final int dw = mCurDisplayWidth;
@@ -6008,8 +6063,12 @@
 
         // Update application display metrics.
         final DisplayMetrics dm = mDisplayMetrics;
-        mAppDisplayWidth = mPolicy.getNonDecorDisplayWidth(dw, dh, mRotation);
-        mAppDisplayHeight = mPolicy.getNonDecorDisplayHeight(dw, dh, mRotation);
+        final int appWidth = mPolicy.getNonDecorDisplayWidth(dw, dh, mRotation);
+        final int appHeight = mPolicy.getNonDecorDisplayHeight(dw, dh, mRotation);
+        synchronized(mDisplaySizeLock) {
+            mAppDisplayWidth = appWidth;
+            mAppDisplayHeight = appHeight;
+        }
         if (false) {
             Slog.i(TAG, "Set app display size: " + mAppDisplayWidth
                     + " x " + mAppDisplayHeight);
@@ -6379,18 +6438,20 @@
             }
             WindowManager wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
             mDisplay = wm.getDefaultDisplay();
-            mInitialDisplayWidth = mDisplay.getRawWidth();
-            mInitialDisplayHeight = mDisplay.getRawHeight();
-            int rot = mDisplay.getRotation();
-            if (rot == Surface.ROTATION_90 || rot == Surface.ROTATION_270) {
-                // If the screen is currently rotated, we need to swap the
-                // initial width and height to get the true natural values.
-                int tmp = mInitialDisplayWidth;
-                mInitialDisplayWidth = mInitialDisplayHeight;
-                mInitialDisplayHeight = tmp;
+            synchronized(mDisplaySizeLock) {
+                mInitialDisplayWidth = mDisplay.getRawWidth();
+                mInitialDisplayHeight = mDisplay.getRawHeight();
+                int rot = mDisplay.getRotation();
+                if (rot == Surface.ROTATION_90 || rot == Surface.ROTATION_270) {
+                    // If the screen is currently rotated, we need to swap the
+                    // initial width and height to get the true natural values.
+                    int tmp = mInitialDisplayWidth;
+                    mInitialDisplayWidth = mInitialDisplayHeight;
+                    mInitialDisplayHeight = tmp;
+                }
+                mBaseDisplayWidth = mCurDisplayWidth = mAppDisplayWidth = mInitialDisplayWidth;
+                mBaseDisplayHeight = mCurDisplayHeight = mAppDisplayHeight = mInitialDisplayHeight;
             }
-            mBaseDisplayWidth = mCurDisplayWidth = mAppDisplayWidth = mInitialDisplayWidth;
-            mBaseDisplayHeight = mCurDisplayHeight = mAppDisplayHeight = mInitialDisplayHeight;
             mInputManager.setDisplaySize(Display.DEFAULT_DISPLAY,
                     mDisplay.getRawWidth(), mDisplay.getRawHeight(),
                     mDisplay.getRawExternalWidth(), mDisplay.getRawExternalHeight());
@@ -6928,28 +6989,28 @@
     }
 
     public void getDisplaySize(Point size) {
-        synchronized(mWindowMap) {
+        synchronized(mDisplaySizeLock) {
             size.x = mAppDisplayWidth;
             size.y = mAppDisplayHeight;
         }
     }
 
     public void getRealDisplaySize(Point size) {
-        synchronized(mWindowMap) {
+        synchronized(mDisplaySizeLock) {
             size.x = mCurDisplayWidth;
             size.y = mCurDisplayHeight;
         }
     }
 
     public void getInitialDisplaySize(Point size) {
-        synchronized(mWindowMap) {
+        synchronized(mDisplaySizeLock) {
             size.x = mInitialDisplayWidth;
             size.y = mInitialDisplayHeight;
         }
     }
 
     public int getMaximumSizeDimension() {
-        synchronized(mWindowMap) {
+        synchronized(mDisplaySizeLock) {
             // Do this based on the raw screen size, until we are smarter.
             return mBaseDisplayWidth > mBaseDisplayHeight
                     ? mBaseDisplayWidth : mBaseDisplayHeight;
@@ -7042,8 +7103,10 @@
     private void setForcedDisplaySizeLocked(int width, int height) {
         Slog.i(TAG, "Using new display size: " + width + "x" + height);
 
-        mBaseDisplayWidth = width;
-        mBaseDisplayHeight = height;
+        synchronized(mDisplaySizeLock) {
+            mBaseDisplayWidth = width;
+            mBaseDisplayHeight = height;
+        }
         mPolicy.setInitialDisplaySize(mBaseDisplayWidth, mBaseDisplayHeight);
 
         mLayoutNeeded = true;
@@ -7659,7 +7722,8 @@
                         // a detached wallpaper animation.
                         if (nowAnimating) {
                             if (w.mAnimation != null) {
-                                if (w.mAnimation.getDetachWallpaper()) {
+                                if ((w.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0
+                                        && w.mAnimation.getDetachWallpaper()) {
                                     windowDetachedWallpaper = w;
                                 }
                                 if (w.mAnimation.getBackgroundColor() != 0) {
@@ -7679,7 +7743,8 @@
                         // displayed behind it.
                         if (w.mAppToken != null && w.mAppToken.animation != null
                                 && w.mAppToken.animating) {
-                            if (w.mAppToken.animation.getDetachWallpaper()) {
+                            if ((w.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0
+                                    && w.mAppToken.animation.getDetachWallpaper()) {
                                 windowDetachedWallpaper = w;
                             }
                             if (w.mAppToken.animation.getBackgroundColor() != 0) {
@@ -9318,11 +9383,13 @@
     }
 
     @Override
-    public FakeWindow addFakeWindow(Looper looper, InputHandler inputHandler,
+    public FakeWindow addFakeWindow(Looper looper,
+            InputEventReceiver.Factory inputEventReceiverFactory,
             String name, int windowType, int layoutParamsFlags, boolean canReceiveKeys,
             boolean hasFocus, boolean touchFullscreen) {
         synchronized (mWindowMap) {
-            FakeWindowImpl fw = new FakeWindowImpl(this, looper, inputHandler, name, windowType,
+            FakeWindowImpl fw = new FakeWindowImpl(this, looper, inputEventReceiverFactory,
+                    name, windowType,
                     layoutParamsFlags, canReceiveKeys, hasFocus, touchFullscreen);
             int i=0;
             while (i<mFakeWindows.size()) {
diff --git a/services/java/com/android/server/wm/WindowState.java b/services/java/com/android/server/wm/WindowState.java
index 23ec2d9..aa7bf2d 100644
--- a/services/java/com/android/server/wm/WindowState.java
+++ b/services/java/com/android/server/wm/WindowState.java
@@ -85,6 +85,7 @@
     boolean mPolicyVisibilityAfterAnim = true;
     boolean mAppFreezing;
     Surface mSurface;
+    Surface mPendingDestroySurface;
     boolean mReportDestroySurface;
     boolean mSurfacePendingDestroy;
     boolean mAttachedHidden;    // is our parent window hidden?
@@ -121,7 +122,13 @@
      * we must tell them application to resize (and thus redraw itself).
      */
     boolean mSurfaceResized;
-    
+
+    /**
+     * Set if the client has asked that the destroy of its surface be delayed
+     * until it explicitly says it is okay.
+     */
+    boolean mSurfaceDestroyDeferred;
+
     /**
      * Insets that determine the actually visible area.  These are in the application's
      * coordinate space (without compatibility scale applied).
@@ -764,15 +771,32 @@
                     Slog.w(WindowManagerService.TAG, "Window " + this + " destroying surface "
                             + mSurface + ", session " + mSession, e);
                 }
-                if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
-                    RuntimeException e = null;
-                    if (!WindowManagerService.HIDE_STACK_CRAWLS) {
-                        e = new RuntimeException();
-                        e.fillInStackTrace();
+                if (mSurfaceDestroyDeferred) {
+                    if (mSurface != null && mPendingDestroySurface != mSurface) {
+                        if (mPendingDestroySurface != null) {
+                            if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
+                                RuntimeException e = null;
+                                if (!WindowManagerService.HIDE_STACK_CRAWLS) {
+                                    e = new RuntimeException();
+                                    e.fillInStackTrace();
+                                }
+                                WindowManagerService.logSurface(this, "DESTROY PENDING", e);
+                            }
+                            mPendingDestroySurface.destroy();
+                        }
+                        mPendingDestroySurface = mSurface;
                     }
-                    WindowManagerService.logSurface(this, "DESTROY", e);
+                } else {
+                    if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
+                        RuntimeException e = null;
+                        if (!WindowManagerService.HIDE_STACK_CRAWLS) {
+                            e = new RuntimeException();
+                            e.fillInStackTrace();
+                        }
+                        WindowManagerService.logSurface(this, "DESTROY", e);
+                    }
+                    mSurface.destroy();
                 }
-                mSurface.destroy();
             } catch (RuntimeException e) {
                 Slog.w(WindowManagerService.TAG, "Exception thrown when destroying Window " + this
                     + " surface " + mSurface + " session " + mSession
@@ -784,6 +808,28 @@
         }
     }
 
+    void destroyDeferredSurfaceLocked() {
+        try {
+            if (mPendingDestroySurface != null) {
+                if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
+                    RuntimeException e = null;
+                    if (!WindowManagerService.HIDE_STACK_CRAWLS) {
+                        e = new RuntimeException();
+                        e.fillInStackTrace();
+                    }
+                    mService.logSurface(this, "DESTROY PENDING", e);
+                }
+                mPendingDestroySurface.destroy();
+            }
+        } catch (RuntimeException e) {
+            Slog.w(WindowManagerService.TAG, "Exception thrown when destroying Window "
+                    + this + " surface " + mPendingDestroySurface
+                    + " session " + mSession + ": " + e.toString());
+        }
+        mSurfaceDestroyDeferred = false;
+        mPendingDestroySurface = null;
+    }
+
     boolean finishDrawingLocked() {
         if (mDrawPending) {
             if (SHOW_TRANSACTIONS || WindowManagerService.DEBUG_ORIENTATION) Slog.v(
@@ -977,6 +1023,9 @@
             mAnimation.cancel();
             mAnimation = null;
         }
+        if (mService.mWindowDetachedWallpaper == this) {
+            mService.mWindowDetachedWallpaper = null;
+        }
         mAnimLayer = mLayer;
         if (mIsImWindow) {
             mAnimLayer += mService.mInputMethodAnimLayerAdjustment;
@@ -1415,6 +1464,7 @@
             if (WindowManagerService.DEBUG_ADD_REMOVE) Slog.v(WindowManagerService.TAG, "Removing " + this + " from " + mAttachedWindow);
             mAttachedWindow.mChildWindows.remove(this);
         }
+        destroyDeferredSurfaceLocked();
         destroySurfaceLocked();
         mSession.windowRemovedLocked();
         try {
@@ -1612,6 +1662,10 @@
                     pw.print(") "); pw.print(mSurfaceW);
                     pw.print(" x "); pw.println(mSurfaceH);
         }
+        if (mPendingDestroySurface != null) {
+            pw.print(prefix); pw.print("mPendingDestroySurface=");
+                    pw.println(mPendingDestroySurface);
+        }
         if (dumpAll) {
             pw.print(prefix); pw.print("mToken="); pw.println(mToken);
             pw.print(prefix); pw.print("mRootToken="); pw.println(mRootToken);
@@ -1640,6 +1694,10 @@
         if (!mRelayoutCalled) {
             pw.print(prefix); pw.print("mRelayoutCalled="); pw.println(mRelayoutCalled);
         }
+        if (mSurfaceResized || mSurfaceDestroyDeferred) {
+            pw.print(prefix); pw.print("mSurfaceResized="); pw.print(mSurfaceResized);
+                    pw.print(" mSurfaceDestroyDeferred="); pw.println(mSurfaceDestroyDeferred);
+        }
         if (mXOffset != 0 || mYOffset != 0) {
             pw.print(prefix); pw.print("Offsets x="); pw.print(mXOffset);
                     pw.print(" y="); pw.println(mYOffset);
diff --git a/services/jni/com_android_server_PowerManagerService.cpp b/services/jni/com_android_server_PowerManagerService.cpp
index a389c11..08650e1 100644
--- a/services/jni/com_android_server_PowerManagerService.cpp
+++ b/services/jni/com_android_server_PowerManagerService.cpp
@@ -28,6 +28,8 @@
 #include <surfaceflinger/ISurfaceComposer.h>
 #include <surfaceflinger/SurfaceComposerClient.h>
 
+#include <private/gui/ComposerService.h>
+
 #include "com_android_server_PowerManagerService.h"
 
 namespace android {
diff --git a/services/surfaceflinger/Android.mk b/services/surfaceflinger/Android.mk
index 61a8358..95d651a 100644
--- a/services/surfaceflinger/Android.mk
+++ b/services/surfaceflinger/Android.mk
@@ -2,19 +2,22 @@
 include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES:= \
-    Layer.cpp 								\
-    LayerBase.cpp 							\
-    LayerDim.cpp 							\
-    LayerScreenshot.cpp						\
-    DdmConnection.cpp						\
-    DisplayHardware/DisplayHardware.cpp 	\
+    EventThread.cpp                         \
+    Layer.cpp                               \
+    LayerBase.cpp                           \
+    LayerDim.cpp                            \
+    LayerScreenshot.cpp                     \
+    DdmConnection.cpp                       \
+    DisplayHardware/DisplayHardware.cpp     \
     DisplayHardware/DisplayHardwareBase.cpp \
-    DisplayHardware/HWComposer.cpp 			\
-    GLExtensions.cpp 						\
-    MessageQueue.cpp 						\
-    SurfaceFlinger.cpp 						\
-    SurfaceTextureLayer.cpp 				\
-    Transform.cpp 							\
+    DisplayHardware/HWComposer.cpp          \
+    DisplayHardware/VSyncBarrier.cpp        \
+    DisplayEventConnection.cpp              \
+    GLExtensions.cpp                        \
+    MessageQueue.cpp                        \
+    SurfaceFlinger.cpp                      \
+    SurfaceTextureLayer.cpp                 \
+    Transform.cpp                           \
     
 
 LOCAL_CFLAGS:= -DLOG_TAG=\"SurfaceFlinger\"
@@ -28,6 +31,7 @@
 endif
 ifeq ($(TARGET_BOARD_PLATFORM), s5pc110)
 	LOCAL_CFLAGS += -DHAS_CONTEXT_PRIORITY -DNEVER_DEFAULT_TO_ASYNC_MODE
+	LOCAL_CFLAGS += -DREFRESH_RATE=56
 endif
 
 
diff --git a/services/surfaceflinger/DisplayEventConnection.cpp b/services/surfaceflinger/DisplayEventConnection.cpp
new file mode 100644
index 0000000..77ecbd2
--- /dev/null
+++ b/services/surfaceflinger/DisplayEventConnection.cpp
@@ -0,0 +1,71 @@
+/*
+ * 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.
+ */
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <gui/IDisplayEventConnection.h>
+#include <gui/BitTube.h>
+#include <gui/DisplayEventReceiver.h>
+
+#include <utils/Errors.h>
+
+#include "SurfaceFlinger.h"
+#include "DisplayEventConnection.h"
+#include "EventThread.h"
+
+// ---------------------------------------------------------------------------
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+DisplayEventConnection::DisplayEventConnection(
+        const sp<EventThread>& eventThread)
+    : mEventThread(eventThread), mChannel(new BitTube())
+{
+}
+
+DisplayEventConnection::~DisplayEventConnection() {
+    mEventThread->unregisterDisplayEventConnection(this);
+}
+
+void DisplayEventConnection::onFirstRef() {
+    // NOTE: mEventThread doesn't hold a strong reference on us
+    mEventThread->registerDisplayEventConnection(this);
+}
+
+sp<BitTube> DisplayEventConnection::getDataChannel() const {
+    return mChannel;
+}
+
+void DisplayEventConnection::setVsyncRate(uint32_t count) {
+    mEventThread->setVsyncRate(count, this);
+}
+
+void DisplayEventConnection::requestNextVsync() {
+    mEventThread->requestNextVsync(this);
+}
+
+status_t DisplayEventConnection::postEvent(const DisplayEventReceiver::Event& event)
+{
+    ssize_t size = mChannel->write(&event, sizeof(DisplayEventReceiver::Event));
+    return size < 0 ? status_t(size) : status_t(NO_ERROR);
+}
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
diff --git a/services/surfaceflinger/DisplayEventConnection.h b/services/surfaceflinger/DisplayEventConnection.h
new file mode 100644
index 0000000..cc3ee36
--- /dev/null
+++ b/services/surfaceflinger/DisplayEventConnection.h
@@ -0,0 +1,62 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_SURFACE_FLINGER_DISPLAY_EVENT_CONNECTION_H
+#define ANDROID_SURFACE_FLINGER_DISPLAY_EVENT_CONNECTION_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <gui/IDisplayEventConnection.h>
+
+#include <utils/Errors.h>
+#include <gui/DisplayEventReceiver.h>
+
+// ---------------------------------------------------------------------------
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+class BitTube;
+class EventThread;
+
+// ---------------------------------------------------------------------------
+
+class DisplayEventConnection : public BnDisplayEventConnection {
+public:
+    DisplayEventConnection(const sp<EventThread>& flinger);
+
+    status_t postEvent(const DisplayEventReceiver::Event& event);
+
+private:
+    virtual ~DisplayEventConnection();
+    virtual void onFirstRef();
+    virtual sp<BitTube> getDataChannel() const;
+    virtual void setVsyncRate(uint32_t count);
+    virtual void requestNextVsync();    // asynchronous
+
+    sp<EventThread> const mEventThread;
+    sp<BitTube> const mChannel;
+};
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
+
+// ---------------------------------------------------------------------------
+
+#endif /* ANDROID_SURFACE_FLINGER_DISPLAY_EVENT_CONNECTION_H */
diff --git a/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp b/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp
index f94d321..3bbc75e 100644
--- a/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp
+++ b/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp
@@ -140,6 +140,7 @@
     mDpiX = mNativeWindow->xdpi;
     mDpiY = mNativeWindow->ydpi;
     mRefreshRate = fbDev->fps;
+    mNextFakeVSync = 0;
 
 
 /* FIXME: this is a temporary HACK until we are able to report the refresh rate
@@ -152,6 +153,8 @@
 #warning "refresh rate set via makefile to REFRESH_RATE"
 #endif
 
+    mRefreshPeriod = nsecs_t(1e9 / mRefreshRate);
+
     EGLint w, h, dummy;
     EGLint numConfigs=0;
     EGLSurface surface;
@@ -346,6 +349,37 @@
     return mPageFlipCount;
 }
 
+// this needs to be thread safe
+nsecs_t DisplayHardware::waitForVSync() const {
+    nsecs_t timestamp;
+    if (mVSync.wait(&timestamp) < 0) {
+        // vsync not supported!
+        usleep( getDelayToNextVSyncUs(&timestamp) );
+    }
+    return timestamp;
+}
+
+int32_t DisplayHardware::getDelayToNextVSyncUs(nsecs_t* timestamp) const {
+    Mutex::Autolock _l(mFakeVSyncMutex);
+    const nsecs_t period = mRefreshPeriod;
+    const nsecs_t now = systemTime(CLOCK_MONOTONIC);
+    nsecs_t next_vsync = mNextFakeVSync;
+    nsecs_t sleep = next_vsync - now;
+    if (sleep < 0) {
+        // we missed, find where the next vsync should be
+        sleep = (period - ((now - next_vsync) % period));
+        next_vsync = now + sleep;
+    }
+    mNextFakeVSync = next_vsync + period;
+    timestamp[0] = next_vsync;
+
+    // round to next microsecond
+    int32_t sleep_us = (sleep + 999LL) / 1000LL;
+
+    // guaranteed to be > 0
+    return sleep_us;
+}
+
 status_t DisplayHardware::compositionComplete() const {
     return mNativeWindow->compositionComplete();
 }
diff --git a/services/surfaceflinger/DisplayHardware/DisplayHardware.h b/services/surfaceflinger/DisplayHardware/DisplayHardware.h
index f02c954..45d4b45 100644
--- a/services/surfaceflinger/DisplayHardware/DisplayHardware.h
+++ b/services/surfaceflinger/DisplayHardware/DisplayHardware.h
@@ -32,6 +32,7 @@
 #include "GLExtensions.h"
 
 #include "DisplayHardware/DisplayHardwareBase.h"
+#include "DisplayHardware/VSyncBarrier.h"
 
 namespace android {
 
@@ -74,6 +75,9 @@
     uint32_t    getMaxTextureSize() const;
     uint32_t    getMaxViewportDims() const;
 
+    // waits for the next vsync and returns the timestamp of when it happened
+    nsecs_t        waitForVSync() const;
+
     uint32_t getPageFlipCount() const;
     EGLDisplay getEGLDisplay() const { return mDisplay; }
 
@@ -95,6 +99,7 @@
 private:
     void init(uint32_t displayIndex) __attribute__((noinline));
     void fini() __attribute__((noinline));
+    int32_t getDelayToNextVSyncUs(nsecs_t* timestamp) const;
 
     sp<SurfaceFlinger> mFlinger;
     EGLDisplay      mDisplay;
@@ -112,7 +117,12 @@
     mutable uint32_t mPageFlipCount;
     GLint           mMaxViewportDims[2];
     GLint           mMaxTextureSize;
-    
+    VSyncBarrier    mVSync;
+
+    mutable Mutex   mFakeVSyncMutex;
+    mutable nsecs_t mNextFakeVSync;
+    nsecs_t         mRefreshPeriod;
+
     HWComposer*     mHwc;
 
     sp<FramebufferNativeWindow> mNativeWindow;
diff --git a/services/surfaceflinger/DisplayHardware/VSyncBarrier.cpp b/services/surfaceflinger/DisplayHardware/VSyncBarrier.cpp
new file mode 100644
index 0000000..187da20
--- /dev/null
+++ b/services/surfaceflinger/DisplayHardware/VSyncBarrier.cpp
@@ -0,0 +1,81 @@
+/*
+ * 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.
+ */
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Errors.h>
+
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <linux/fb.h>
+
+#include "DisplayHardware/VSyncBarrier.h"
+
+#ifndef FBIO_WAITFORVSYNC
+#define FBIO_WAITFORVSYNC   _IOW('F', 0x20, __u32)
+#endif
+
+namespace android {
+// ---------------------------------------------------------------------------
+
+VSyncBarrier::VSyncBarrier() : mFd(-EINVAL) {
+#if HAS_WAITFORVSYNC
+    mFd = open("/dev/graphics/fb0", O_RDWR);
+    if (mFd < 0) {
+        mFd = -errno;
+    }
+    // try to see if FBIO_WAITFORVSYNC is supported
+    uint32_t crt = 0;
+    int err = ioctl(mFd, FBIO_WAITFORVSYNC, &crt);
+    if (err < 0) {
+        close(mFd);
+        mFd = -EINVAL;
+    }
+#endif
+}
+
+VSyncBarrier::~VSyncBarrier() {
+    if (mFd >= 0) {
+        close(mFd);
+    }
+}
+
+status_t VSyncBarrier::initCheck() const {
+    return mFd < 0 ? mFd : status_t(NO_ERROR);
+}
+
+// this must be thread-safe
+status_t VSyncBarrier::wait(nsecs_t* timestamp) const {
+    if (mFd < 0) {
+        return mFd;
+    }
+
+    int err;
+    uint32_t crt = 0;
+    do {
+        err = ioctl(mFd, FBIO_WAITFORVSYNC, &crt);
+    } while (err<0 && errno==EINTR);
+    if (err < 0) {
+        return -errno;
+    }
+    // ideally this would come from the driver
+    timestamp[0] = systemTime();
+    return NO_ERROR;
+}
+
+// ---------------------------------------------------------------------------
+}; // namespace android
diff --git a/services/surfaceflinger/DisplayHardware/VSyncBarrier.h b/services/surfaceflinger/DisplayHardware/VSyncBarrier.h
new file mode 100644
index 0000000..3c32950
--- /dev/null
+++ b/services/surfaceflinger/DisplayHardware/VSyncBarrier.h
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_SURFACE_FLINGER_VSYNCBARRIER_H_
+#define ANDROID_SURFACE_FLINGER_VSYNCBARRIER_H_
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Errors.h>
+#include <utils/Timers.h>
+
+namespace android {
+// ---------------------------------------------------------------------------
+
+class VSyncBarrier {
+    int mFd;
+public:
+    VSyncBarrier();
+    ~VSyncBarrier();
+    status_t initCheck() const;
+    status_t wait(nsecs_t* timestamp) const;
+};
+
+// ---------------------------------------------------------------------------
+}; // namespace android
+
+#endif /* ANDROID_SURFACE_FLINGER_VSYNCBARRIER_H_ */
diff --git a/services/surfaceflinger/EventThread.cpp b/services/surfaceflinger/EventThread.cpp
new file mode 100644
index 0000000..dc39f88
--- /dev/null
+++ b/services/surfaceflinger/EventThread.cpp
@@ -0,0 +1,226 @@
+/*
+ * 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.
+ */
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <gui/IDisplayEventConnection.h>
+#include <gui/DisplayEventReceiver.h>
+
+#include <utils/Errors.h>
+
+#include "DisplayHardware/DisplayHardware.h"
+#include "DisplayEventConnection.h"
+#include "EventThread.h"
+#include "SurfaceFlinger.h"
+
+// ---------------------------------------------------------------------------
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+EventThread::EventThread(const sp<SurfaceFlinger>& flinger)
+    : mFlinger(flinger),
+      mHw(flinger->graphicPlane(0).displayHardware()),
+      mDeliveredEvents(0)
+{
+}
+
+void EventThread::onFirstRef() {
+    run("EventThread", PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE);
+}
+
+status_t EventThread::registerDisplayEventConnection(
+        const sp<DisplayEventConnection>& connection) {
+    Mutex::Autolock _l(mLock);
+    ConnectionInfo info;
+    mDisplayEventConnections.add(connection, info);
+    mCondition.signal();
+    return NO_ERROR;
+}
+
+status_t EventThread::unregisterDisplayEventConnection(
+        const wp<DisplayEventConnection>& connection) {
+    Mutex::Autolock _l(mLock);
+    mDisplayEventConnections.removeItem(connection);
+    mCondition.signal();
+    return NO_ERROR;
+}
+
+void EventThread::removeDisplayEventConnection(
+        const wp<DisplayEventConnection>& connection) {
+    Mutex::Autolock _l(mLock);
+    mDisplayEventConnections.removeItem(connection);
+}
+
+EventThread::ConnectionInfo* EventThread::getConnectionInfoLocked(
+        const wp<DisplayEventConnection>& connection) {
+    ssize_t index = mDisplayEventConnections.indexOfKey(connection);
+    if (index < 0) return NULL;
+    return &mDisplayEventConnections.editValueAt(index);
+}
+
+void EventThread::setVsyncRate(uint32_t count,
+        const wp<DisplayEventConnection>& connection) {
+    if (int32_t(count) >= 0) { // server must protect against bad params
+        Mutex::Autolock _l(mLock);
+        ConnectionInfo* info = getConnectionInfoLocked(connection);
+        if (info) {
+            info->count = (count == 0) ? -1 : count;
+            mCondition.signal();
+        }
+    }
+}
+
+void EventThread::requestNextVsync(
+        const wp<DisplayEventConnection>& connection) {
+    Mutex::Autolock _l(mLock);
+    ConnectionInfo* info = getConnectionInfoLocked(connection);
+    if (info) {
+        if (info->count < 0) {
+            info->count = 0;
+        }
+        mCondition.signal();
+    }
+}
+
+bool EventThread::threadLoop() {
+
+    nsecs_t timestamp;
+    DisplayEventReceiver::Event vsync;
+    KeyedVector< wp<DisplayEventConnection>, ConnectionInfo > displayEventConnections;
+
+    { // scope for the lock
+        Mutex::Autolock _l(mLock);
+        do {
+            // wait for listeners
+            do {
+                bool waitForNextVsync = false;
+                size_t count = mDisplayEventConnections.size();
+                for (size_t i=0 ; i<count ; i++) {
+                    const ConnectionInfo& info(
+                            mDisplayEventConnections.valueAt(i));
+                    if (info.count >= 1) {
+                        // continuous mode
+                        waitForNextVsync = true;
+                    } else {
+                        // one-shot event
+                        if (info.count >= -1) {
+                            ConnectionInfo& info(
+                                    mDisplayEventConnections.editValueAt(i));
+                            info.count--;
+                            if (info.count == -1) {
+                                // fired this time around
+                                waitForNextVsync = true;
+                            }
+                        }
+                    }
+                }
+
+                if (waitForNextVsync)
+                    break;
+
+                mCondition.wait(mLock);
+            } while(true);
+
+            // wait for vsync
+            mLock.unlock();
+            timestamp = mHw.waitForVSync();
+            mLock.lock();
+            mDeliveredEvents++;
+
+            // make sure we still have some listeners
+        } while (!mDisplayEventConnections.size());
+
+        // dispatch vsync events to listeners...
+        vsync.header.type = DisplayEventReceiver::DISPLAY_EVENT_VSYNC;
+        vsync.header.timestamp = timestamp;
+        vsync.vsync.count = mDeliveredEvents;
+
+        // make a copy of our connection list, so we can
+        // dispatch events without holding mLock
+        displayEventConnections = mDisplayEventConnections;
+    }
+
+    const size_t count = displayEventConnections.size();
+    for (size_t i=0 ; i<count ; i++) {
+        sp<DisplayEventConnection> conn(displayEventConnections.keyAt(i).promote());
+        // make sure the connection didn't die
+        if (conn != NULL) {
+
+            const ConnectionInfo& info(
+                    displayEventConnections.valueAt(i));
+
+            if ((info.count > 1) && (mDeliveredEvents % info.count)) {
+                // continuous event, but not time to send this event yet
+                continue;
+            } else if (info.count < -1) {
+                // disabled event
+                continue;
+            } else if (info.count == 0) {
+                // impossible by construction. but we prefer to be safe.
+                continue;
+            }
+
+            // here, either:
+            // count = -1 : one-shot scheduled this time around
+            // count =  1 : continuous not rate-limited
+            // count >  1 : continuous, rate-limited
+            // Note: count == 0 is not possible by construction
+
+            status_t err = conn->postEvent(vsync);
+            if (err == -EAGAIN || err == -EWOULDBLOCK) {
+                // The destination doesn't accept events anymore, it's probably
+                // full. For now, we just drop the events on the floor.
+                // Note that some events cannot be dropped and would have to be
+                // re-sent later. Right-now we don't have the ability to do
+                // this, but it doesn't matter for VSYNC.
+            } else if (err < 0) {
+                // handle any other error on the pipe as fatal. the only
+                // reasonable thing to do is to clean-up this connection.
+                // The most common error we'll get here is -EPIPE.
+                removeDisplayEventConnection(displayEventConnections.keyAt(i));
+            }
+        } else {
+            // somehow the connection is dead, but we still have it in our list
+            // just clean the list.
+            removeDisplayEventConnection(displayEventConnections.keyAt(i));
+        }
+    }
+
+    // clear all our references without holding mLock
+    displayEventConnections.clear();
+
+    return true;
+}
+
+status_t EventThread::readyToRun() {
+    LOGI("EventThread ready to run.");
+    return NO_ERROR;
+}
+
+void EventThread::dump(String8& result, char* buffer, size_t SIZE) const {
+    Mutex::Autolock _l(mLock);
+    result.append("VSYNC state:\n");
+    snprintf(buffer, SIZE, "  numListeners=%u, events-delivered: %u\n",
+            mDisplayEventConnections.size(), mDeliveredEvents);
+    result.append(buffer);
+}
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
diff --git a/services/surfaceflinger/EventThread.h b/services/surfaceflinger/EventThread.h
new file mode 100644
index 0000000..35bd299
--- /dev/null
+++ b/services/surfaceflinger/EventThread.h
@@ -0,0 +1,102 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_SURFACE_FLINGER_EVENT_THREAD_H
+#define ANDROID_SURFACE_FLINGER_EVENT_THREAD_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <gui/IDisplayEventConnection.h>
+
+#include <utils/Errors.h>
+#include <utils/threads.h>
+#include <utils/KeyedVector.h>
+
+#include "DisplayEventConnection.h"
+
+// ---------------------------------------------------------------------------
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+class SurfaceFlinger;
+class DisplayHardware;
+
+// ---------------------------------------------------------------------------
+
+class EventThread : public Thread {
+    friend class DisplayEventConnection;
+
+public:
+    EventThread(const sp<SurfaceFlinger>& flinger);
+
+    status_t registerDisplayEventConnection(
+            const sp<DisplayEventConnection>& connection);
+
+    status_t unregisterDisplayEventConnection(
+            const wp<DisplayEventConnection>& connection);
+
+    void setVsyncRate(uint32_t count,
+            const wp<DisplayEventConnection>& connection);
+
+    void requestNextVsync(const wp<DisplayEventConnection>& connection);
+
+    void dump(String8& result, char* buffer, size_t SIZE) const;
+
+private:
+    virtual bool        threadLoop();
+    virtual status_t    readyToRun();
+    virtual void        onFirstRef();
+
+    struct ConnectionInfo {
+        ConnectionInfo() : count(-1) { }
+
+        // count >= 1 : continuous event. count is the vsync rate
+        // count == 0 : one-shot event that has not fired
+        // count ==-1 : one-shot event that fired this round / disabled
+        // count ==-2 : one-shot event that fired the round before
+        int32_t count;
+    };
+
+    void removeDisplayEventConnection(
+            const wp<DisplayEventConnection>& connection);
+
+    ConnectionInfo* getConnectionInfoLocked(
+            const wp<DisplayEventConnection>& connection);
+
+    // constants
+    sp<SurfaceFlinger> mFlinger;
+    const DisplayHardware& mHw;
+
+    mutable Mutex mLock;
+    mutable Condition mCondition;
+
+    // protected by mLock
+    KeyedVector< wp<DisplayEventConnection>, ConnectionInfo > mDisplayEventConnections;
+
+    // main thread only
+    size_t mDeliveredEvents;
+};
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
+
+// ---------------------------------------------------------------------------
+
+#endif /* ANDROID_SURFACE_FLINGER_EVENT_THREAD_H */
diff --git a/services/surfaceflinger/MessageQueue.cpp b/services/surfaceflinger/MessageQueue.cpp
index aebe1b8..85845c9 100644
--- a/services/surfaceflinger/MessageQueue.cpp
+++ b/services/surfaceflinger/MessageQueue.cpp
@@ -29,167 +29,75 @@
 
 // ---------------------------------------------------------------------------
 
-void MessageList::insert(const sp<MessageBase>& node) 
-{
-    LIST::iterator cur(mList.begin());
-    LIST::iterator end(mList.end());
-    while (cur != end) {
-        if (*node < **cur) {
-            mList.insert(cur, node);
-            return;
-        }
-        ++cur;
-    }
-    mList.insert(++end, node);
+MessageBase::MessageBase()
+    : MessageHandler() {
 }
 
-void MessageList::remove(MessageList::LIST::iterator pos) 
-{
-    mList.erase(pos);
+MessageBase::~MessageBase() {
 }
 
+void MessageBase::handleMessage(const Message&) {
+    this->handler();
+    barrier.open();
+};
+
 // ---------------------------------------------------------------------------
 
 MessageQueue::MessageQueue()
-    : mInvalidate(false)
-{
-    mInvalidateMessage = new MessageBase(INVALIDATE);
-}
-
-MessageQueue::~MessageQueue()
+    : mLooper(new Looper(true)), mWorkPending(0)
 {
 }
 
-sp<MessageBase> MessageQueue::waitMessage(nsecs_t timeout)
-{
-    sp<MessageBase> result;
+MessageQueue::~MessageQueue() {
+}
 
-    bool again;
+void MessageQueue::waitMessage() {
     do {
-        const nsecs_t timeoutTime = systemTime() + timeout;
-        while (true) {
-            Mutex::Autolock _l(mLock);
-            nsecs_t now = systemTime();
-            nsecs_t nextEventTime = -1;
+        IPCThreadState::self()->flushCommands();
 
-            LIST::iterator cur(mMessages.begin());
-            if (cur != mMessages.end()) {
-                result = *cur;
-            }
-            
-            if (result != 0) {
-                if (result->when <= now) {
-                    // there is a message to deliver
-                    mMessages.remove(cur);
-                    break;
+        int32_t ret = mLooper->pollOnce(-1);
+        switch (ret) {
+            case ALOOPER_POLL_WAKE:
+            case ALOOPER_POLL_CALLBACK:
+                // callback and/or wake
+                if (android_atomic_and(0, &mWorkPending)) {
+                    return;
                 }
-                nextEventTime = result->when;
-                result = 0;
-            }
+                continue;
 
-            // see if we have an invalidate message
-            if (mInvalidate) {
-                mInvalidate = false;
-                mInvalidateMessage->when = now;
-                result = mInvalidateMessage;
-                break;
-            }
+            case ALOOPER_POLL_TIMEOUT:
+                // timeout (should not happen)
+                continue;
 
-            if (timeout >= 0) {
-                if (timeoutTime < now) {
-                    // we timed-out, return a NULL message
-                    result = 0;
-                    break;
-                }
-                if (nextEventTime > 0) {
-                    if (nextEventTime > timeoutTime) {
-                        nextEventTime = timeoutTime;
-                    }
-                } else {
-                    nextEventTime = timeoutTime;
-                }
-            }
+            case ALOOPER_POLL_ERROR:
+                LOGE("ALOOPER_POLL_ERROR");
+                continue;
 
-            if (nextEventTime >= 0) {
-                //LOGD("nextEventTime = %lld ms", nextEventTime);
-                if (nextEventTime > 0) {
-                    // we're about to wait, flush the binder command buffer
-                    IPCThreadState::self()->flushCommands();
-                    const nsecs_t reltime = nextEventTime - systemTime();
-                    if (reltime > 0) {
-                        mCondition.waitRelative(mLock, reltime);
-                    }
-                }
-            } else {
-                //LOGD("going to wait");
-                // we're about to wait, flush the binder command buffer
-                IPCThreadState::self()->flushCommands();
-                mCondition.wait(mLock);
-            }
-        } 
-        // here we're not holding the lock anymore
-
-        if (result == 0)
-            break;
-
-        again = result->handler();
-        if (again) {
-            // the message has been processed. release our reference to it
-            // without holding the lock.
-            result->notify();
-            result = 0;
+            default:
+                // should not happen
+                LOGE("Looper::pollOnce() returned unknown status %d", ret);
+                continue;
         }
-        
-    } while (again);
-
-    return result;
+    } while (true);
 }
 
 status_t MessageQueue::postMessage(
-        const sp<MessageBase>& message, nsecs_t relTime, uint32_t flags)
+        const sp<MessageBase>& messageHandler, nsecs_t relTime)
 {
-    return queueMessage(message, relTime, flags);
+    const Message dummyMessage;
+    if (relTime > 0) {
+        mLooper->sendMessageDelayed(relTime, messageHandler, dummyMessage);
+    } else {
+        mLooper->sendMessage(messageHandler, dummyMessage);
+    }
+    return NO_ERROR;
 }
 
 status_t MessageQueue::invalidate() {
-    Mutex::Autolock _l(mLock);
-    mInvalidate = true;
-    mCondition.signal();
-    return NO_ERROR;
-}
-
-status_t MessageQueue::queueMessage(
-        const sp<MessageBase>& message, nsecs_t relTime, uint32_t flags)
-{
-    Mutex::Autolock _l(mLock);
-    message->when = systemTime() + relTime;
-    mMessages.insert(message);
-    
-    //LOGD("MessageQueue::queueMessage time = %lld ms", message->when);
-    //dumpLocked(message);
-
-    mCondition.signal();
-    return NO_ERROR;
-}
-
-void MessageQueue::dump(const sp<MessageBase>& message)
-{
-    Mutex::Autolock _l(mLock);
-    dumpLocked(message);
-}
-
-void MessageQueue::dumpLocked(const sp<MessageBase>& message)
-{
-    LIST::const_iterator cur(mMessages.begin());
-    LIST::const_iterator end(mMessages.end());
-    int c = 0;
-    while (cur != end) {
-        const char tick = (*cur == message) ? '>' : ' ';
-        LOGD("%c %d: msg{.what=%08x, when=%lld}",
-                tick, c, (*cur)->what, (*cur)->when);
-        ++cur;
-        c++;
+    if (android_atomic_or(1, &mWorkPending) == 0) {
+        mLooper->wake();
     }
+    return NO_ERROR;
 }
 
 // ---------------------------------------------------------------------------
diff --git a/services/surfaceflinger/MessageQueue.h b/services/surfaceflinger/MessageQueue.h
index 890f809..2317d81 100644
--- a/services/surfaceflinger/MessageQueue.h
+++ b/services/surfaceflinger/MessageQueue.h
@@ -23,7 +23,7 @@
 
 #include <utils/threads.h>
 #include <utils/Timers.h>
-#include <utils/List.h>
+#include <utils/Looper.h>
 
 #include "Barrier.h"
 
@@ -31,92 +31,39 @@
 
 // ---------------------------------------------------------------------------
 
-class MessageBase;
-
-class MessageList 
-{
-    List< sp<MessageBase> > mList;
-    typedef List< sp<MessageBase> > LIST;
-public:
-    inline LIST::iterator begin()                { return mList.begin(); }
-    inline LIST::const_iterator begin() const    { return mList.begin(); }
-    inline LIST::iterator end()                  { return mList.end(); }
-    inline LIST::const_iterator end() const      { return mList.end(); }
-    inline bool isEmpty() const { return mList.empty(); }
-    void insert(const sp<MessageBase>& node);
-    void remove(LIST::iterator pos);
-};
-
-// ============================================================================
-
-class MessageBase : 
-    public LightRefBase<MessageBase>
+class MessageBase : public MessageHandler
 {
 public:
-    nsecs_t     when;
-    uint32_t    what;
-    int32_t     arg0;    
-
-    MessageBase() : when(0), what(0), arg0(0) { }
-    MessageBase(uint32_t what, int32_t arg0=0)
-        : when(0), what(what), arg0(arg0) { }
+    MessageBase();
     
     // return true if message has a handler
-    virtual bool handler() { return false; }
+    virtual bool handler() = 0;
 
     // waits for the handler to be processed
     void wait() const { barrier.wait(); }
-    
-    // releases all waiters. this is done automatically if
-    // handler returns true
-    void notify() const { barrier.open(); }
 
 protected:
-    virtual ~MessageBase() { }
+    virtual ~MessageBase();
 
 private:
-    mutable Barrier barrier;
-    friend class LightRefBase<MessageBase>;
-};
+    virtual void handleMessage(const Message& message);
 
-inline bool operator < (const MessageBase& lhs, const MessageBase& rhs) {
-    return lhs.when < rhs.when;
-}
+    mutable Barrier barrier;
+};
 
 // ---------------------------------------------------------------------------
 
-class MessageQueue
-{
-    typedef List< sp<MessageBase> > LIST;
-public:
+class MessageQueue {
+    sp<Looper> mLooper;
+    volatile int32_t mWorkPending;
 
+public:
     MessageQueue();
     ~MessageQueue();
 
-    // pre-defined messages
-    enum {
-        INVALIDATE = '_upd'
-    };
-
-    sp<MessageBase> waitMessage(nsecs_t timeout = -1);
-    
-    status_t postMessage(const sp<MessageBase>& message,
-            nsecs_t reltime=0, uint32_t flags = 0);
-
+    void waitMessage();
+    status_t postMessage(const sp<MessageBase>& message, nsecs_t reltime=0);
     status_t invalidate();
-    
-    void dump(const sp<MessageBase>& message);
-
-private:
-    status_t queueMessage(const sp<MessageBase>& message,
-            nsecs_t reltime, uint32_t flags);
-    void dumpLocked(const sp<MessageBase>& message);
-    
-    Mutex           mLock;
-    Condition       mCondition;
-    MessageList     mMessages;
-    bool            mInvalidate;
-    sp<MessageBase> mInvalidateMessage;
 };
 
 // ---------------------------------------------------------------------------
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 1b00e93..014c7e2 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -34,6 +34,8 @@
 #include <binder/MemoryHeapBase.h>
 #include <binder/PermissionCache.h>
 
+#include <gui/IDisplayEventConnection.h>
+
 #include <utils/String8.h>
 #include <utils/String16.h>
 #include <utils/StopWatch.h>
@@ -46,6 +48,8 @@
 #include <GLES/gl.h>
 
 #include "clz.h"
+#include "DisplayEventConnection.h"
+#include "EventThread.h"
 #include "GLExtensions.h"
 #include "DdmConnection.h"
 #include "Layer.h"
@@ -65,6 +69,8 @@
 #define AID_GRAPHICS 1003
 #endif
 
+#define EGL_VERSION_HW_ANDROID  0x3143
+
 #define DISPLAY_COUNT       1
 
 namespace android {
@@ -293,12 +299,16 @@
     // put the origin in the left-bottom corner
     glOrthof(0, w, 0, h, 0, 1); // l=0, r=w ; b=0, t=h
 
-    mReadyToRunBarrier.open();
+
+    // start the EventThread
+    mEventThread = new EventThread(this);
 
     /*
      *  We're now ready to accept clients...
      */
 
+    mReadyToRunBarrier.open();
+
     // start boot animation
     property_set("ctl.start", "bootanim");
 
@@ -311,25 +321,30 @@
 #pragma mark Events Handler
 #endif
 
-void SurfaceFlinger::waitForEvent()
-{
-    while (true) {
-        nsecs_t timeout = -1;
-        sp<MessageBase> msg = mEventQueue.waitMessage(timeout);
-        if (msg != 0) {
-            switch (msg->what) {
-                case MessageQueue::INVALIDATE:
-                    // invalidate message, just return to the main loop
-                    return;
-            }
-        }
-    }
+void SurfaceFlinger::waitForEvent() {
+    mEventQueue.waitMessage();
 }
 
 void SurfaceFlinger::signalEvent() {
     mEventQueue.invalidate();
 }
 
+status_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg,
+        nsecs_t reltime, uint32_t flags) {
+    return mEventQueue.postMessage(msg, reltime);
+}
+
+status_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg,
+        nsecs_t reltime, uint32_t flags) {
+    status_t res = mEventQueue.postMessage(msg, reltime);
+    if (res == NO_ERROR) {
+        msg->wait();
+    }
+    return res;
+}
+
+// ----------------------------------------------------------------------------
+
 bool SurfaceFlinger::authenticateSurfaceTexture(
         const sp<ISurfaceTexture>& surfaceTexture) const {
     Mutex::Autolock _l(mStateLock);
@@ -371,20 +386,11 @@
     return false;
 }
 
-status_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg,
-        nsecs_t reltime, uint32_t flags)
-{
-    return mEventQueue.postMessage(msg, reltime, flags);
-}
+// ----------------------------------------------------------------------------
 
-status_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg,
-        nsecs_t reltime, uint32_t flags)
-{
-    status_t res = mEventQueue.postMessage(msg, reltime, flags);
-    if (res == NO_ERROR) {
-        msg->wait();
-    }
-    return res;
+sp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection() {
+    sp<DisplayEventConnection> result(new DisplayEventConnection(mEventThread));
+    return result;
 }
 
 // ----------------------------------------------------------------------------
@@ -443,7 +449,7 @@
     } else {
         // pretend we did the post
         hw.compositionComplete();
-        usleep(16667); // 60 fps period
+        hw.waitForVSync();
     }
     return true;
 }
@@ -708,6 +714,14 @@
 
 void SurfaceFlinger::commitTransaction()
 {
+    if (!mLayersPendingRemoval.isEmpty()) {
+        // Notify removed layers now that they can't be drawn from
+        for (size_t i = 0; i < mLayersPendingRemoval.size(); i++) {
+            mLayersPendingRemoval[i]->onRemoved();
+        }
+        mLayersPendingRemoval.clear();
+    }
+
     mDrawingState = mCurrentState;
     mTransationPending = false;
     mTransactionCV.broadcast();
@@ -1160,7 +1174,7 @@
         mLayerPurgatory.add(layerBase);
     }
 
-    layerBase->onRemoved();
+    mLayersPendingRemoval.push(layerBase);
 
     // it's possible that we don't find a layer, because it might
     // have been destroyed already -- this is not technically an error
@@ -1527,7 +1541,7 @@
          * Dump the layers in the purgatory
          */
 
-        const size_t purgatorySize =  mLayerPurgatory.size();
+        const size_t purgatorySize = mLayerPurgatory.size();
         snprintf(buffer, SIZE, "Purgatory state (%d entries)\n", purgatorySize);
         result.append(buffer);
         for (size_t i=0 ; i<purgatorySize ; i++) {
@@ -1548,6 +1562,12 @@
                 extensions.getRenderer(),
                 extensions.getVersion());
         result.append(buffer);
+
+        snprintf(buffer, SIZE, "EGL : %s\n",
+                eglQueryString(graphicPlane(0).getEGLDisplay(),
+                        EGL_VERSION_HW_ANDROID));
+        result.append(buffer);
+
         snprintf(buffer, SIZE, "EXTS: %s\n", extensions.getExtension());
         result.append(buffer);
 
@@ -1583,9 +1603,16 @@
         }
 
         /*
+         * VSYNC state
+         */
+        mEventThread->dump(result, buffer, SIZE);
+
+        /*
          * Dump HWComposer state
          */
         HWComposer& hwc(hw.getHwComposer());
+        snprintf(buffer, SIZE, "h/w composer state:\n");
+        result.append(buffer);
         snprintf(buffer, SIZE, "  h/w composer %s and %s\n",
                 hwc.initCheck()==NO_ERROR ? "present" : "not present",
                 (mDebugDisableHWC || mDebugRegion) ? "disabled" : "enabled");
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 17028db..41caee3 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -46,6 +46,8 @@
 
 class Client;
 class DisplayHardware;
+class DisplayEventConnection;
+class EventThread;
 class Layer;
 class LayerDim;
 class LayerScreenshot;
@@ -171,6 +173,7 @@
                                                             int orientation, uint32_t flags);
     virtual int                         setOrientation(DisplayID dpy, int orientation, uint32_t flags);
     virtual bool                        authenticateSurfaceTexture(const sp<ISurfaceTexture>& surface) const;
+    virtual sp<IDisplayEventConnection> createDisplayEventConnection();
 
     virtual status_t captureScreen(DisplayID dpy,
             sp<IMemoryHeap>* heap,
@@ -222,6 +225,7 @@
 
 private:
     friend class Client;
+    friend class DisplayEventConnection;
     friend class LayerBase;
     friend class LayerBaseClient;
     friend class Layer;
@@ -345,6 +349,7 @@
                 Condition               mTransactionCV;
                 SortedVector< sp<LayerBase> > mLayerPurgatory;
                 bool                    mTransationPending;
+                Vector< sp<LayerBase> > mLayersPendingRemoval;
 
                 // protected by mStateLock (but we could use another lock)
                 GraphicPlane                mGraphicPlanes[1];
@@ -361,6 +366,7 @@
                 GLuint                      mWormholeTexName;
                 GLuint                      mProtectedTexName;
                 nsecs_t                     mBootTime;
+                sp<EventThread>             mEventThread;
 
                 // Can only accessed from the main thread, these members
                 // don't need synchronization
diff --git a/services/surfaceflinger/SurfaceTextureLayer.cpp b/services/surfaceflinger/SurfaceTextureLayer.cpp
index 4390ca1..5020e00 100644
--- a/services/surfaceflinger/SurfaceTextureLayer.cpp
+++ b/services/surfaceflinger/SurfaceTextureLayer.cpp
@@ -28,7 +28,7 @@
 
 
 SurfaceTextureLayer::SurfaceTextureLayer(GLuint tex, const sp<Layer>& layer)
-    : SurfaceTexture(tex), mLayer(layer) {
+    : SurfaceTexture(tex, true, GL_TEXTURE_EXTERNAL_OES, false), mLayer(layer) {
 }
 
 SurfaceTextureLayer::~SurfaceTextureLayer() {
diff --git a/services/surfaceflinger/tests/vsync/Android.mk b/services/surfaceflinger/tests/vsync/Android.mk
new file mode 100644
index 0000000..9181760
--- /dev/null
+++ b/services/surfaceflinger/tests/vsync/Android.mk
@@ -0,0 +1,18 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+	vsync.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+	libcutils \
+	libutils \
+	libbinder \
+    libui \
+    libgui
+
+LOCAL_MODULE:= test-vsync-events
+
+LOCAL_MODULE_TAGS := tests
+
+include $(BUILD_EXECUTABLE)
diff --git a/services/surfaceflinger/tests/vsync/vsync.cpp b/services/surfaceflinger/tests/vsync/vsync.cpp
new file mode 100644
index 0000000..4f79080
--- /dev/null
+++ b/services/surfaceflinger/tests/vsync/vsync.cpp
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gui/DisplayEventReceiver.h>
+#include <utils/Looper.h>
+
+using namespace android;
+
+int receiver(int fd, int events, void* data)
+{
+    DisplayEventReceiver* q = (DisplayEventReceiver*)data;
+
+    ssize_t n;
+    DisplayEventReceiver::Event buffer[1];
+
+    static nsecs_t oldTimeStamp = 0;
+
+    while ((n = q->getEvents(buffer, 1)) > 0) {
+        for (int i=0 ; i<n ; i++) {
+            if (buffer[i].header.type == DisplayEventReceiver::DISPLAY_EVENT_VSYNC) {
+                printf("event vsync: count=%d\t", buffer[i].vsync.count);
+            }
+            if (oldTimeStamp) {
+                float t = float(buffer[i].header.timestamp - oldTimeStamp) / s2ns(1);
+                printf("%f ms (%f Hz)\n", t*1000, 1.0/t);
+            }
+            oldTimeStamp = buffer[i].header.timestamp;
+        }
+    }
+    if (n<0) {
+        printf("error reading events (%s)\n", strerror(-n));
+    }
+    return 1;
+}
+
+int main(int argc, char** argv)
+{
+    DisplayEventReceiver myDisplayEvent;
+
+
+    sp<Looper> loop = new Looper(false);
+    loop->addFd(myDisplayEvent.getFd(), 0, ALOOPER_EVENT_INPUT, receiver,
+            &myDisplayEvent);
+
+    do {
+        //printf("about to poll...\n");
+        int32_t ret = loop->pollOnce(-1);
+        switch (ret) {
+            case ALOOPER_POLL_WAKE:
+                //("ALOOPER_POLL_WAKE\n");
+                break;
+            case ALOOPER_POLL_CALLBACK:
+                //("ALOOPER_POLL_CALLBACK\n");
+                break;
+            case ALOOPER_POLL_TIMEOUT:
+                printf("ALOOPER_POLL_TIMEOUT\n");
+                break;
+            case ALOOPER_POLL_ERROR:
+                printf("ALOOPER_POLL_TIMEOUT\n");
+                break;
+            default:
+                printf("ugh? poll returned %d\n", ret);
+                break;
+        }
+    } while (1);
+
+    return 0;
+}
diff --git a/services/surfaceflinger/tests/waitforvsync/Android.mk b/services/surfaceflinger/tests/waitforvsync/Android.mk
new file mode 100644
index 0000000..c25f5ab
--- /dev/null
+++ b/services/surfaceflinger/tests/waitforvsync/Android.mk
@@ -0,0 +1,14 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+	waitforvsync.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+	libcutils \
+
+LOCAL_MODULE:= test-waitforvsync
+
+LOCAL_MODULE_TAGS := tests
+
+include $(BUILD_EXECUTABLE)
diff --git a/services/surfaceflinger/tests/waitforvsync/waitforvsync.cpp b/services/surfaceflinger/tests/waitforvsync/waitforvsync.cpp
new file mode 100644
index 0000000..279b88b
--- /dev/null
+++ b/services/surfaceflinger/tests/waitforvsync/waitforvsync.cpp
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ */
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <linux/fb.h>
+#include <errno.h>
+#include <string.h>
+#include <stdio.h>
+
+#ifndef FBIO_WAITFORVSYNC
+#define FBIO_WAITFORVSYNC   _IOW('F', 0x20, __u32)
+#endif
+
+int main(int argc, char** argv) {
+    int fd = open("/dev/graphics/fb0", O_RDWR);
+    if (fd >= 0) {
+        do {
+            uint32_t crt = 0;
+           int err = ioctl(fd, FBIO_WAITFORVSYNC, &crt);
+           if (err < 0) {
+               printf("FBIO_WAITFORVSYNC error: %s\n", strerror(errno));
+               break;
+           }
+        } while(1);
+        close(fd);
+    }
+    return 0;
+}
diff --git a/services/tests/servicestests/src/com/android/server/NativeDaemonConnectorTest.java b/services/tests/servicestests/src/com/android/server/NativeDaemonConnectorTest.java
new file mode 100644
index 0000000..275d807
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/NativeDaemonConnectorTest.java
@@ -0,0 +1,70 @@
+/*
+ * 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.server;
+
+import static com.android.server.NativeDaemonConnector.appendEscaped;
+
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+
+/**
+ * Tests for {@link NativeDaemonConnector}.
+ */
+@MediumTest
+public class NativeDaemonConnectorTest extends AndroidTestCase {
+    private static final String TAG = "NativeDaemonConnectorTest";
+
+    public void testArgumentNormal() throws Exception {
+        final StringBuilder builder = new StringBuilder();
+
+        builder.setLength(0);
+        appendEscaped(builder, "");
+        assertEquals("", builder.toString());
+
+        builder.setLength(0);
+        appendEscaped(builder, "foo");
+        assertEquals("foo", builder.toString());
+
+        builder.setLength(0);
+        appendEscaped(builder, "foo\"bar");
+        assertEquals("foo\\\"bar", builder.toString());
+
+        builder.setLength(0);
+        appendEscaped(builder, "foo\\bar\\\"baz");
+        assertEquals("foo\\\\bar\\\\\\\"baz", builder.toString());
+    }
+
+    public void testArgumentWithSpaces() throws Exception {
+        final StringBuilder builder = new StringBuilder();
+
+        builder.setLength(0);
+        appendEscaped(builder, "foo bar");
+        assertEquals("\"foo bar\"", builder.toString());
+
+        builder.setLength(0);
+        appendEscaped(builder, "foo\"bar\\baz foo");
+        assertEquals("\"foo\\\"bar\\\\baz foo\"", builder.toString());
+    }
+
+    public void testArgumentWithUtf() throws Exception {
+        final StringBuilder builder = new StringBuilder();
+
+        builder.setLength(0);
+        appendEscaped(builder, "caf\u00E9 c\u00F6ffee");
+        assertEquals("\"caf\u00E9 c\u00F6ffee\"", builder.toString());
+    }
+}
diff --git a/telephony/java/android/telephony/PhoneNumberUtils.java b/telephony/java/android/telephony/PhoneNumberUtils.java
index 07afe30..5da3d97 100644
--- a/telephony/java/android/telephony/PhoneNumberUtils.java
+++ b/telephony/java/android/telephony/PhoneNumberUtils.java
@@ -20,6 +20,7 @@
 import com.android.i18n.phonenumbers.PhoneNumberUtil;
 import com.android.i18n.phonenumbers.PhoneNumberUtil.PhoneNumberFormat;
 import com.android.i18n.phonenumbers.Phonenumber.PhoneNumber;
+import com.android.i18n.phonenumbers.ShortNumberUtil;
 
 import android.content.Context;
 import android.content.Intent;
@@ -1572,56 +1573,7 @@
      *         listed in the RIL / sim, otherwise return false.
      */
     private static boolean isEmergencyNumberInternal(String number, boolean useExactMatch) {
-        // If the number passed in is null, just return false:
-        if (number == null) return false;
-
-        // If the number passed in is a SIP address, return false, since the
-        // concept of "emergency numbers" is only meaningful for calls placed
-        // over the cell network.
-        // (Be sure to do this check *before* calling extractNetworkPortionAlt(),
-        // since the whole point of extractNetworkPortionAlt() is to filter out
-        // any non-dialable characters (which would turn 'abc911def@example.com'
-        // into '911', for example.))
-        if (isUriNumber(number)) {
-            return false;
-        }
-
-        // Strip the separators from the number before comparing it
-        // to the list.
-        number = extractNetworkPortionAlt(number);
-
-        // retrieve the list of emergency numbers
-        // check read-write ecclist property first
-        String numbers = SystemProperties.get("ril.ecclist");
-        if (TextUtils.isEmpty(numbers)) {
-            // then read-only ecclist property since old RIL only uses this
-            numbers = SystemProperties.get("ro.ril.ecclist");
-        }
-
-        if (!TextUtils.isEmpty(numbers)) {
-            // searches through the comma-separated list for a match,
-            // return true if one is found.
-            for (String emergencyNum : numbers.split(",")) {
-                if (useExactMatch) {
-                    if (number.equals(emergencyNum)) {
-                        return true;
-                    }
-                } else {
-                    if (number.startsWith(emergencyNum)) {
-                        return true;
-                    }
-                }
-            }
-            // no matches found against the list!
-            return false;
-        }
-
-        // No ecclist system property, so use our own list.
-        if (useExactMatch) {
-            return (number.equals("112") || number.equals("911"));
-        } else {
-            return (number.startsWith("112") || number.startsWith("911"));
-        }
+        return isEmergencyNumberInternal(number, null, useExactMatch);
     }
 
     /**
@@ -1684,28 +1636,67 @@
     private static boolean isEmergencyNumberInternal(String number,
                                                      String defaultCountryIso,
                                                      boolean useExactMatch) {
-        PhoneNumberUtil util = PhoneNumberUtil.getInstance();
-        try {
-            PhoneNumber pn = util.parse(number, defaultCountryIso);
-            // libphonenumber guarantees short numbers such as emergency numbers are classified as
-            // invalid. Therefore, if the number passes the validation test, we believe it is not an
-            // emergency number.
-            // TODO: Compare against a list of country-specific known emergency numbers instead, once
-            // that has been collected.
-            if (util.isValidNumber(pn)) {
-                return false;
-            } else if ("BR".equalsIgnoreCase(defaultCountryIso) && number.length() >= 8) {
-                // This is to prevent Brazilian local numbers which start with 911 being incorrectly
-                // classified as emergency numbers. 911 is not an emergency number in Brazil; it is also
-                // not possible to append additional digits to an emergency number to dial the number in
-                // Brazil - it won't connect.
-                // TODO: Clean this up once a list of country-specific known emergency numbers is
-                // collected.
-                return false;
-            }
-        } catch (NumberParseException e) {
+        // If the number passed in is null, just return false:
+        if (number == null) return false;
+
+        // If the number passed in is a SIP address, return false, since the
+        // concept of "emergency numbers" is only meaningful for calls placed
+        // over the cell network.
+        // (Be sure to do this check *before* calling extractNetworkPortionAlt(),
+        // since the whole point of extractNetworkPortionAlt() is to filter out
+        // any non-dialable characters (which would turn 'abc911def@example.com'
+        // into '911', for example.))
+        if (isUriNumber(number)) {
+            return false;
         }
-        return isEmergencyNumberInternal(number, useExactMatch);
+
+        // Strip the separators from the number before comparing it
+        // to the list.
+        number = extractNetworkPortionAlt(number);
+
+        // retrieve the list of emergency numbers
+        // check read-write ecclist property first
+        String numbers = SystemProperties.get("ril.ecclist");
+        if (TextUtils.isEmpty(numbers)) {
+            // then read-only ecclist property since old RIL only uses this
+            numbers = SystemProperties.get("ro.ril.ecclist");
+        }
+
+        if (!TextUtils.isEmpty(numbers)) {
+            // searches through the comma-separated list for a match,
+            // return true if one is found.
+            for (String emergencyNum : numbers.split(",")) {
+                // It is not possible to append additional digits to an emergency number to dial
+                // the number in Brazil - it won't connect.
+                if (useExactMatch || "BR".equalsIgnoreCase(defaultCountryIso)) {
+                    if (number.equals(emergencyNum)) {
+                        return true;
+                    }
+                } else {
+                    if (number.startsWith(emergencyNum)) {
+                        return true;
+                    }
+                }
+            }
+            // no matches found against the list!
+            return false;
+        }
+
+        // No ecclist system property, so use our own list.
+        if (defaultCountryIso != null) {
+            ShortNumberUtil util = new ShortNumberUtil();
+            if (useExactMatch) {
+                return util.isEmergencyNumber(number, defaultCountryIso);
+            } else {
+                return util.connectsToEmergencyNumber(number, defaultCountryIso);
+            }
+        } else {
+            if (useExactMatch) {
+                return (number.equals("112") || number.equals("911"));
+            } else {
+                return (number.startsWith("112") || number.startsWith("911"));
+            }
+        }
     }
 
     /**
diff --git a/telephony/java/com/android/internal/telephony/ApnSetting.java b/telephony/java/com/android/internal/telephony/ApnSetting.java
index 002ffad9..980bb49 100755
--- a/telephony/java/com/android/internal/telephony/ApnSetting.java
+++ b/telephony/java/com/android/internal/telephony/ApnSetting.java
@@ -189,4 +189,11 @@
         }
         return false;
     }
+
+    // TODO - if we have this function we should also have hashCode.
+    // Also should handle changes in type order and perhaps case-insensitivity
+    public boolean equals(Object o) {
+        if (o instanceof ApnSetting == false) return false;
+        return (this.toString().equals(o.toString()));
+    }
 }
diff --git a/telephony/java/com/android/internal/telephony/BaseCommands.java b/telephony/java/com/android/internal/telephony/BaseCommands.java
index f111dd6..07b6183 100644
--- a/telephony/java/com/android/internal/telephony/BaseCommands.java
+++ b/telephony/java/com/android/internal/telephony/BaseCommands.java
@@ -683,6 +683,13 @@
         mRilConnectedRegistrants.remove(h);
     }
 
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setCurrentPreferredNetworkType() {
+    }
+
     //***** Protected Methods
     /**
      * Store new RadioState and send notification based on the changes
diff --git a/telephony/java/com/android/internal/telephony/CommandsInterface.java b/telephony/java/com/android/internal/telephony/CommandsInterface.java
index 33ead75..d6e6ae0 100644
--- a/telephony/java/com/android/internal/telephony/CommandsInterface.java
+++ b/telephony/java/com/android/internal/telephony/CommandsInterface.java
@@ -1311,6 +1311,12 @@
     void queryAvailableBandMode (Message response);
 
     /**
+     * Set the current preferred network type. This will be the last
+     * networkType that was passed to setPreferredNetworkType.
+     */
+    void setCurrentPreferredNetworkType();
+
+    /**
      *  Requests to set the preferred network type for searching and registering
      * (CS/PS domain, RAT, and operation mode)
      * @param networkType one of  NT_*_TYPE
diff --git a/telephony/java/com/android/internal/telephony/DataCallState.java b/telephony/java/com/android/internal/telephony/DataCallState.java
index 6d8956f..efbf608 100644
--- a/telephony/java/com/android/internal/telephony/DataCallState.java
+++ b/telephony/java/com/android/internal/telephony/DataCallState.java
@@ -126,6 +126,8 @@
                 // set link addresses
                 if (addresses != null && addresses.length > 0) {
                     for (String addr : addresses) {
+                        addr = addr.trim();
+                        if (addr.isEmpty()) continue;
                         LinkAddress la;
                         int addrPrefixLen;
 
@@ -159,6 +161,8 @@
                 // set dns servers
                 if (dnses != null && dnses.length > 0) {
                     for (String addr : dnses) {
+                        addr = addr.trim();
+                        if (addr.isEmpty()) continue;
                         InetAddress ia;
                         try {
                             ia = NetworkUtils.numericToInetAddress(addr);
@@ -174,6 +178,8 @@
                     dnsServers[0] = SystemProperties.get(propertyPrefix + "dns1");
                     dnsServers[1] = SystemProperties.get(propertyPrefix + "dns2");
                     for (String dnsAddr : dnsServers) {
+                        dnsAddr = dnsAddr.trim();
+                        if (dnsAddr.isEmpty()) continue;
                         InetAddress ia;
                         try {
                             ia = NetworkUtils.numericToInetAddress(dnsAddr);
@@ -198,6 +204,8 @@
                     }
                 }
                 for (String addr : gateways) {
+                    addr = addr.trim();
+                    if (addr.isEmpty()) continue;
                     InetAddress ia;
                     try {
                         ia = NetworkUtils.numericToInetAddress(addr);
diff --git a/telephony/java/com/android/internal/telephony/DataConnection.java b/telephony/java/com/android/internal/telephony/DataConnection.java
index 636646e..4619899 100644
--- a/telephony/java/com/android/internal/telephony/DataConnection.java
+++ b/telephony/java/com/android/internal/telephony/DataConnection.java
@@ -699,8 +699,10 @@
                     break;
 
                 case EVENT_DISCONNECT:
-                    if (DBG) log("DcDefaultState: msg.what=EVENT_DISCONNECT");
-                    notifyDisconnectCompleted((DisconnectParams) msg.obj);
+                    if (DBG) {
+                        log("DcDefaultState deferring msg.what=EVENT_DISCONNECT" + mRefCount);
+                    }
+                    deferMessage(msg);
                     break;
 
                 case EVENT_RIL_CONNECTED:
@@ -807,6 +809,12 @@
                     retVal = HANDLED;
                     break;
 
+                case EVENT_DISCONNECT:
+                    if (DBG) log("DcInactiveState: msg.what=EVENT_DISCONNECT");
+                    notifyDisconnectCompleted((DisconnectParams)msg.obj);
+                    retVal = HANDLED;
+                    break;
+
                 default:
                     if (VDBG) {
                         log("DcInactiveState nothandled msg.what=0x" +
@@ -831,13 +839,6 @@
             ConnectionParams cp;
 
             switch (msg.what) {
-                case EVENT_DISCONNECT:
-                    if (DBG) log("DcActivatingState deferring msg.what=EVENT_DISCONNECT"
-                            + mRefCount);
-                    deferMessage(msg);
-                    retVal = HANDLED;
-                    break;
-
                 case EVENT_CONNECT:
                     if (DBG) log("DcActivatingState deferring msg.what=EVENT_CONNECT refCount = "
                             + mRefCount);
diff --git a/telephony/java/com/android/internal/telephony/RIL.java b/telephony/java/com/android/internal/telephony/RIL.java
index 9f93fb8..f2e7f45 100644
--- a/telephony/java/com/android/internal/telephony/RIL.java
+++ b/telephony/java/com/android/internal/telephony/RIL.java
@@ -1823,6 +1823,16 @@
     /**
      * {@inheritDoc}
      */
+    @Override
+    public void setCurrentPreferredNetworkType() {
+        if (RILJ_LOGD) riljLog("setCurrentPreferredNetworkType: " + mSetPreferredNetworkType);
+        setPreferredNetworkType(mSetPreferredNetworkType, null);
+    }
+    private int mSetPreferredNetworkType;
+
+    /**
+     * {@inheritDoc}
+     */
     public void setPreferredNetworkType(int networkType , Message response) {
         RILRequest rr = RILRequest.obtain(
                 RILConstants.RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE, response);
@@ -1830,6 +1840,7 @@
         rr.mp.writeInt(1);
         rr.mp.writeInt(networkType);
 
+        mSetPreferredNetworkType = networkType;
         mPreferredNetworkType = networkType;
 
         if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
index 3d6cd68..d939e98 100755
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
@@ -257,6 +257,9 @@
             break;
 
         case EVENT_RUIM_READY:
+            // TODO: Consider calling setCurrentPreferredNetworkType as we do in GsmSST.
+            // cm.setCurrentPreferredNetworkType();
+
             // The RUIM is now ready i.e if it was locked it has been
             // unlocked. At this stage, the radio is already powered on.
             isSubscriptionFromRuim = true;
@@ -277,6 +280,9 @@
             break;
 
         case EVENT_NV_READY:
+            // TODO: Consider calling setCurrentPreferredNetworkType as we do in GsmSST.
+            // cm.setCurrentPreferredNetworkType();
+
             isSubscriptionFromRuim = false;
             // For Non-RUIM phones, the subscription information is stored in
             // Non Volatile. Here when Non-Volatile is ready, we can poll the CDMA
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
index 7cd01a1..963db2c 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
@@ -914,10 +914,16 @@
                         cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.NUMERIC)),
                         cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.NAME)),
                         cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.APN)),
-                        cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.PROXY)),
+                        NetworkUtils.trimV4AddrZeros(
+                                cursor.getString(
+                                cursor.getColumnIndexOrThrow(Telephony.Carriers.PROXY))),
                         cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.PORT)),
-                        cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.MMSC)),
-                        cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.MMSPROXY)),
+                        NetworkUtils.trimV4AddrZeros(
+                                cursor.getString(
+                                cursor.getColumnIndexOrThrow(Telephony.Carriers.MMSC))),
+                        NetworkUtils.trimV4AddrZeros(
+                                cursor.getString(
+                                cursor.getColumnIndexOrThrow(Telephony.Carriers.MMSPROXY))),
                         cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.MMSPORT)),
                         cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.USER)),
                         cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.PASSWORD)),
@@ -1720,11 +1726,25 @@
     private DataConnection checkForConnectionForApnContext(ApnContext apnContext) {
         // Loop through all apnContexts looking for one with a conn that satisfies this apnType
         String apnType = apnContext.getApnType();
+        ApnSetting dunSetting = null;
+
+        if (Phone.APN_TYPE_DUN.equals(apnType)) {
+            dunSetting = fetchDunApn();
+        }
+
         for (ApnContext c : mApnContexts.values()) {
             DataConnection conn = c.getDataConnection();
             if (conn != null) {
                 ApnSetting apnSetting = c.getApnSetting();
-                if (apnSetting != null && apnSetting.canHandleType(apnType)) {
+                if (dunSetting != null) {
+                    if (dunSetting.equals(apnSetting)) {
+                        if (DBG) {
+                            log("checkForConnectionForApnContext: apnContext=" + apnContext +
+                                    " found conn=" + conn);
+                        }
+                        return conn;
+                    }
+                } else if (apnSetting != null && apnSetting.canHandleType(apnType)) {
                     if (DBG) {
                         log("checkForConnectionForApnContext: apnContext=" + apnContext +
                                 " found conn=" + conn);
@@ -1848,8 +1868,14 @@
             DataConnection dc = apnContext.getDataConnection();
 
             if (DBG) {
-                log(String.format("onDataSetupComplete: success apn=%s",
-                    apnContext.getWaitingApns().get(0).apn));
+                // TODO We may use apnContext.getApnSetting() directly
+                // instead of getWaitingApns().get(0)
+                String apnStr = "<unknown>";
+                if (apnContext.getWaitingApns() != null
+                        && !apnContext.getWaitingApns().isEmpty()){
+                    apnStr = apnContext.getWaitingApns().get(0).apn;
+                }
+                log("onDataSetupComplete: success apn=" + apnStr);
             }
             ApnSetting apn = apnContext.getApnSetting();
             if (apn.proxy != null && apn.proxy.length() != 0) {
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmMmiCode.java b/telephony/java/com/android/internal/telephony/gsm/GsmMmiCode.java
index 3799894..16d3129 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmMmiCode.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmMmiCode.java
@@ -132,7 +132,7 @@
     // See TS 22.030 6.5.2 "Structure of the MMI"
 
     static Pattern sPatternSuppService = Pattern.compile(
-        "((\\*|#|\\*#|\\*\\*|##)(\\d{2,3})(\\*([^*#]*)(\\*([^*#]*)(\\*([^*#]*)(\\*([^*#]*))?)?)?)?#)(.*)");
+        "((\\*|#|\\*#|\\*\\*|##)(\\d{2,3})(\\*([^*#]*)(\\*([^*#]*)(\\*([^*#]*)(\\*([^*#]*))?)?)?)?#)([^#]*)");
 /*       1  2                    3          4  5       6   7         8    9     10  11             12
 
          1 = Full string up to and including #
@@ -141,7 +141,7 @@
          5 = SIA
          7 = SIB
          9 = SIC
-         10 = dialing number
+         10 = dialing number which must not include #, e.g. *SCn*SI#DN format
 */
 
     static final int MATCH_GROUP_POUND_STRING = 1;
@@ -1338,4 +1338,20 @@
      * SpecialCharSequenceMgr class.
      */
 
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder("GsmMmiCode {");
+
+        sb.append("State=" + getState());
+        if (action != null) sb.append(" action=" + action);
+        if (sc != null) sb.append(" sc=" + sc);
+        if (sia != null) sb.append(" sia=" + sia);
+        if (sib != null) sb.append(" sib=" + sib);
+        if (sic != null) sb.append(" sic=" + sic);
+        if (poundString != null) sb.append(" poundString=" + poundString);
+        if (dialingNumber != null) sb.append(" dialingNumber=" + dialingNumber);
+        if (pwd != null) sb.append(" pwd=" + pwd);
+        sb.append("}");
+        return sb.toString();
+    }
 }
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java
index eea2780..84127cf 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java
@@ -270,6 +270,9 @@
                 break;
 
             case EVENT_SIM_READY:
+                // Set the network type, in case the radio does not restore it.
+                cm.setCurrentPreferredNetworkType();
+
                 // The SIM is now ready i.e if it was locked
                 // it has been unlocked. At this stage, the radio is already
                 // powered on.
diff --git a/tests/FrameworkPerf/res/layout/main.xml b/tests/FrameworkPerf/res/layout/main.xml
index 7812648..e00ad92 100644
--- a/tests/FrameworkPerf/res/layout/main.xml
+++ b/tests/FrameworkPerf/res/layout/main.xml
@@ -66,7 +66,24 @@
         >
         <TextView android:layout_width="wrap_content" android:layout_height="wrap_content"
             android:textAppearance="?android:attr/textAppearanceMedium"
+            android:text="Limit by: "
+            />
+        <Spinner android:id="@+id/limitspinner"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:drawSelectorOnTop="true"
+        />
+    </LinearLayout>
+
+    <LinearLayout android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal"
+        android:layout_marginTop="10dp"
+        >
+        <TextView android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:textAppearance="?android:attr/textAppearanceMedium"
             android:text="Test time (ms): "
+            android:id="@+id/limitlabel"
             />
         <EditText android:id="@+id/testtime"
             android:layout_width="match_parent"
diff --git a/tests/FrameworkPerf/src/com/android/frameworkperf/FrameworkPerfActivity.java b/tests/FrameworkPerf/src/com/android/frameworkperf/FrameworkPerfActivity.java
index 8ee5978..30a968f 100644
--- a/tests/FrameworkPerf/src/com/android/frameworkperf/FrameworkPerfActivity.java
+++ b/tests/FrameworkPerf/src/com/android/frameworkperf/FrameworkPerfActivity.java
@@ -50,6 +50,8 @@
 
     Spinner mFgSpinner;
     Spinner mBgSpinner;
+    Spinner mLimitSpinner;
+    TextView mLimitLabel;
     TextView mTestTime;
     Button mStartButton;
     Button mStopButton;
@@ -58,10 +60,12 @@
     PowerManager.WakeLock mPartialWakeLock;
 
     long mMaxRunTime = 5000;
+    boolean mLimitIsIterations;
     boolean mStarted;
 
     final String[] mAvailOpLabels;
     final String[] mAvailOpDescriptions;
+    final String[] mLimitLabels = { "Time", "Iterations" };
 
     int mFgTestIndex = -1;
     int mBgTestIndex = -1;
@@ -169,8 +173,15 @@
         adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
         mBgSpinner.setAdapter(adapter);
         mBgSpinner.setOnItemSelectedListener(this);
+        mLimitSpinner = (Spinner) findViewById(R.id.limitspinner);
+        adapter = new ArrayAdapter<String>(this,
+                android.R.layout.simple_spinner_item, mLimitLabels);
+        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+        mLimitSpinner.setAdapter(adapter);
+        mLimitSpinner.setOnItemSelectedListener(this);
 
         mTestTime = (TextView)findViewById(R.id.testtime);
+        mLimitLabel = (TextView)findViewById(R.id.limitlabel);
 
         mStartButton = (Button)findViewById(R.id.start);
         mStartButton.setOnClickListener(new View.OnClickListener() {
@@ -196,16 +207,23 @@
 
     @Override
     public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
-        if (parent == mFgSpinner || parent == mBgSpinner) {
+        if (parent == mFgSpinner || parent == mBgSpinner || parent == mLimitSpinner) {
             TestService.Op op = TestService.mAvailOps[position];
             if (parent == mFgSpinner) {
                 mFgTestIndex = position;
                 mFgTest = op;
                 ((TextView)findViewById(R.id.fgtext)).setText(mAvailOpDescriptions[position]);
-            } else {
+            } else if (parent == mBgSpinner) {
                 mBgTestIndex = position;
                 mBgTest = op;
                 ((TextView)findViewById(R.id.bgtext)).setText(mAvailOpDescriptions[position]);
+            } else if (parent == mLimitSpinner) {
+                mLimitIsIterations = (position != 0);
+                if (mLimitIsIterations) {
+                    mLimitLabel.setText("Iterations: ");
+                } else {
+                    mLimitLabel.setText("Test time (ms): ");
+                }
             }
         }
     }
@@ -234,7 +252,11 @@
             return;
         }
         TestArgs args = new TestArgs();
-        args.maxTime = mMaxRunTime;
+        if (mLimitIsIterations) {
+            args.maxOps = mMaxRunTime;
+        } else {
+            args.maxTime = mMaxRunTime;
+        }
         if (mFgTestIndex == 0 && mBgTestIndex == 0) {
             args.combOp = mCurOpIndex;
         } else if (mFgTestIndex != 0 && mBgTestIndex != 0) {
@@ -376,6 +398,7 @@
             mTestTime.setEnabled(false);
             mFgSpinner.setEnabled(false);
             mBgSpinner.setEnabled(false);
+            mLimitSpinner.setEnabled(false);
             updateWakeLock();
             startService(new Intent(this, SchedulerService.class));
             mCurOpIndex = 0;
@@ -397,6 +420,7 @@
             mTestTime.setEnabled(true);
             mFgSpinner.setEnabled(true);
             mBgSpinner.setEnabled(true);
+            mLimitSpinner.setEnabled(true);
             updateWakeLock();
             stopService(new Intent(this, SchedulerService.class));
             synchronized (mResults) {
diff --git a/tests/FrameworkPerf/src/com/android/frameworkperf/TestArgs.java b/tests/FrameworkPerf/src/com/android/frameworkperf/TestArgs.java
index f2f7c56..2fe38aa 100644
--- a/tests/FrameworkPerf/src/com/android/frameworkperf/TestArgs.java
+++ b/tests/FrameworkPerf/src/com/android/frameworkperf/TestArgs.java
@@ -21,6 +21,7 @@
 
 public class TestArgs implements Parcelable {
     long maxTime;
+    long maxOps = -1;
     int combOp = -1;
     int fgOp = -1;
     int bgOp = -1;
@@ -30,6 +31,7 @@
 
     public TestArgs(Parcel source) {
         maxTime = source.readLong();
+        maxOps = source.readLong();
         combOp = source.readInt();
         fgOp = source.readInt();
         bgOp = source.readInt();
@@ -43,6 +45,7 @@
     @Override
     public void writeToParcel(Parcel dest, int flags) {
         dest.writeLong(maxTime);
+        dest.writeLong(maxOps);
         dest.writeInt(combOp);
         dest.writeInt(fgOp);
         dest.writeInt(bgOp);
diff --git a/tests/FrameworkPerf/src/com/android/frameworkperf/TestService.java b/tests/FrameworkPerf/src/com/android/frameworkperf/TestService.java
index 8cf1ac2..a8c43e9 100644
--- a/tests/FrameworkPerf/src/com/android/frameworkperf/TestService.java
+++ b/tests/FrameworkPerf/src/com/android/frameworkperf/TestService.java
@@ -224,6 +224,7 @@
     public class TestRunner {
         Handler mHandler;
         long mMaxRunTime;
+        long mMaxOps;
         Op mForegroundOp;
         Op mBackgroundOp;
         Runnable mDoneCallback;
@@ -277,6 +278,7 @@
         public void run(Handler handler, TestArgs args, Runnable doneCallback) {
             mHandler = handler;
             mMaxRunTime = args.maxTime;
+            mMaxOps = args.maxOps;
             if (args.combOp >= 0) {
                 mForegroundOp = mOpPairs[args.combOp];
                 mBackgroundOp = mOpPairs[args.combOp+1];
@@ -352,9 +354,18 @@
                 if (!mBackgroundRunning && !mForegroundRunning) {
                     return false;
                 }
-                long now = SystemClock.uptimeMillis();
-                if (now > (mStartTime+mMaxRunTime)) {
-                    return false;
+                if (mMaxOps > 0) {
+                    // iteration-limited case
+                    if (mForegroundOps >= mMaxOps) {
+                        return false;
+                    }
+                    mForegroundOps++;
+                } else {
+                    // time-limited case
+                    long now = SystemClock.uptimeMillis();
+                    if (now > (mStartTime+mMaxRunTime)) {
+                        return false;
+                    }
                 }
                 return true;
             }
diff --git a/tests/RenderScriptTests/ModelViewer/src/com/android/modelviewer/simplemodel.rs b/tests/RenderScriptTests/ModelViewer/src/com/android/modelviewer/simplemodel.rs
index 8cec409..de2a0a7 100644
--- a/tests/RenderScriptTests/ModelViewer/src/com/android/modelviewer/simplemodel.rs
+++ b/tests/RenderScriptTests/ModelViewer/src/com/android/modelviewer/simplemodel.rs
@@ -48,6 +48,14 @@
 static float gLastX;
 static float gLastY;
 
+static float3 toFloat3(float x, float y, float z) {
+    float3 f;
+    f.x = x;
+    f.y = y;
+    f.z = z;
+    return f;
+}
+
 void onActionDown(float x, float y) {
     gLastX = x;
     gLastY = y;
@@ -104,8 +112,8 @@
         rsgMeshComputeBoundingBox(info->mMesh,
                                   &minX, &minY, &minZ,
                                   &maxX, &maxY, &maxZ);
-        info->bBoxMin = (minX, minY, minZ);
-        info->bBoxMax = (maxX, maxY, maxZ);
+        info->bBoxMin = toFloat3(minX, minY, minZ);
+        info->bBoxMax = toFloat3(maxX, maxY, maxZ);
         gLookAt += (info->bBoxMin + info->bBoxMax)*0.5f;
     }
     gLookAt = gLookAt / (float)size;
diff --git a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/FillTest.java b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/FillTest.java
index 06b4af7..ba70c71 100644
--- a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/FillTest.java
+++ b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/FillTest.java
@@ -62,6 +62,9 @@
         mTests[index].testName = Allocation.createFromString(mRS,
                                                              mNames[index],
                                                              Allocation.USAGE_SCRIPT);
+        mTests[index].debugName = RsBenchRS.createZeroTerminatedAlloc(mRS,
+                                                                      mNames[index],
+                                                                      Allocation.USAGE_SCRIPT);
 
         ScriptField_FillTestData_s.Item dataItem = new ScriptField_FillTestData_s.Item();
         dataItem.testId = testId;
diff --git a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/MeshTest.java b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/MeshTest.java
index f39e7db..cdb4435 100644
--- a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/MeshTest.java
+++ b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/MeshTest.java
@@ -69,6 +69,9 @@
         mTests[index].testName = Allocation.createFromString(mRS,
                                                              mNames[index],
                                                              Allocation.USAGE_SCRIPT);
+        mTests[index].debugName = RsBenchRS.createZeroTerminatedAlloc(mRS,
+                                                                      mNames[index],
+                                                                      Allocation.USAGE_SCRIPT);
 
         ScriptField_MeshTestData_s.Item dataItem = new ScriptField_MeshTestData_s.Item();
         dataItem.meshNum = meshNum;
diff --git a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/RsBench.java b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/RsBench.java
index 4ed42b4..0dceafe 100644
--- a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/RsBench.java
+++ b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/RsBench.java
@@ -95,8 +95,10 @@
         switch (item.getItemId()) {
             case R.id.benchmark_all:
                 mView.setBenchmarkMode(-1);
+                mView.suspendRendering(false);
                 return true;
             case R.id.benchmark_one:
+                mView.suspendRendering(true);
                 AlertDialog.Builder builder = new AlertDialog.Builder(this);
                 builder.setTitle("Pick a Test");
                 builder.setItems(mView.getTestNames(),
@@ -106,11 +108,13 @@
                                        "Starting to benchmark: " + mView.getTestNames()[item],
                                        Toast.LENGTH_SHORT).show();
                         mView.setBenchmarkMode(item);
+                        mView.suspendRendering(false);
                     }
                 });
                 builder.show();
                 return true;
             case R.id.debug_mode:
+                mView.suspendRendering(true);
                 AlertDialog.Builder debugBuilder = new AlertDialog.Builder(this);
                 debugBuilder.setTitle("Pick a Test");
                 debugBuilder.setItems(mView.getTestNames(),
@@ -120,6 +124,7 @@
                                        "Switching to: " + mView.getTestNames()[item],
                                        Toast.LENGTH_SHORT).show();
                         mView.setDebugMode(item);
+                        mView.suspendRendering(false);
                     }
                 });
                 debugBuilder.show();
diff --git a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/RsBenchRS.java b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/RsBenchRS.java
index c51bd82..4ac7dd5 100644
--- a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/RsBenchRS.java
+++ b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/RsBenchRS.java
@@ -60,7 +60,6 @@
         mWidth = width;
         mHeight = height;
         mMode = 0;
-        mMaxModes = 0;
         mLoops = loops;
         mCurrentLoop = 0;
         mBenchmarkDimX = 1280;
@@ -88,11 +87,30 @@
     ScriptField_TestScripts_s.Item[] mIndividualTests;
 
     int mMode;
-    int mMaxModes;
 
     String[] mTestNames;
     float[] mLocalTestResults;
 
+    static Allocation createZeroTerminatedAlloc(RenderScript rs,
+                                                String str,
+                                                int usage) {
+        byte[] allocArray = null;
+        try {
+            allocArray = str.getBytes("UTF-8");
+            byte[] allocArrayZero = new byte[allocArray.length + 1];
+            System.arraycopy(allocArray, 0, allocArrayZero, 0, allocArray.length);
+            allocArrayZero[allocArrayZero.length - 1] = '\0';
+            Allocation alloc = Allocation.createSized(rs, Element.U8(rs),
+                                                      allocArrayZero.length, usage);
+            alloc.copyFrom(allocArrayZero);
+            return alloc;
+        }
+        catch (Exception e) {
+            throw new RSRuntimeException("Could not convert string to utf-8.");
+        }
+
+    }
+
     void appendTests(RsBenchBaseTest testSet) {
         ScriptField_TestScripts_s.Item[] newTests = testSet.getTests();
         if (mIndividualTests != null) {
@@ -119,6 +137,7 @@
 
     void createTestAllocation() {
         int numTests = mIndividualTests.length;
+        mLocalTestResults = new float[numTests];
         ScriptField_TestScripts_s allTests;
         allTests = new ScriptField_TestScripts_s(mRS, numTests);
         for (int i = 0; i < numTests; i ++) {
@@ -239,11 +258,6 @@
         return count;
     }
 
-    private void prepareTestData() {
-        mTestNames = new String[mMaxModes];
-        mLocalTestResults = new float[mMaxModes];
-    }
-
     public void setDebugMode(int num) {
         mScript.invoke_setDebugMode(num);
     }
@@ -252,6 +266,10 @@
         mScript.invoke_setBenchmarkMode(benchNum);
     }
 
+    public void pause(boolean pause) {
+        mScript.set_gPauseRendering(pause);
+    }
+
     private void initRS() {
 
         mScript = new ScriptC_rsbench(mRS, mRes, R.raw.rsbench);
@@ -261,8 +279,6 @@
 
         mScript.set_gMaxLoops(mLoops);
 
-        prepareTestData();
-
         initProgramVertex();
         initProgramFragment();
         mScript.set_gFontSerif(Font.create(mRS, mRes, "serif", Font.Style.NORMAL, 8));
diff --git a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/RsBenchView.java b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/RsBenchView.java
index 004e6bf..124071e 100644
--- a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/RsBenchView.java
+++ b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/RsBenchView.java
@@ -92,6 +92,10 @@
         mRender.setBenchmarkMode(benchNum);
     }
 
+    void suspendRendering(boolean pause) {
+        mRender.pause(pause);
+    }
+
     void setDebugMode(int num) {
         mRender.setDebugMode(num);
     }
diff --git a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/TextTest.java b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/TextTest.java
index ca9e660..3ca2792 100644
--- a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/TextTest.java
+++ b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/TextTest.java
@@ -48,6 +48,9 @@
         mTests[index].testName = Allocation.createFromString(mRS,
                                                              mNames[index],
                                                              Allocation.USAGE_SCRIPT);
+        mTests[index].debugName = RsBenchRS.createZeroTerminatedAlloc(mRS,
+                                                                     mNames[index],
+                                                                     Allocation.USAGE_SCRIPT);
 
         ScriptField_TextTestData_s.Item dataItem = new ScriptField_TextTestData_s.Item();
         dataItem.fillNum = fillNum;
diff --git a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/TorusTest.java b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/TorusTest.java
index d785dc1..5c9ecd5 100644
--- a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/TorusTest.java
+++ b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/TorusTest.java
@@ -98,6 +98,9 @@
         mTests[index].testName = Allocation.createFromString(mRS,
                                                              mNames[index],
                                                              Allocation.USAGE_SCRIPT);
+        mTests[index].debugName = RsBenchRS.createZeroTerminatedAlloc(mRS,
+                                                                      mNames[index],
+                                                                      Allocation.USAGE_SCRIPT);
 
         ScriptField_TorusTestData_s.Item dataItem = new ScriptField_TorusTestData_s.Item();
         dataItem.testId = testId;
diff --git a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/UiTest.java b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/UiTest.java
index cca237e..c8b58b2 100644
--- a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/UiTest.java
+++ b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/UiTest.java
@@ -82,6 +82,9 @@
         mTests[index].testName = Allocation.createFromString(mRS,
                                                              mNames[index],
                                                              Allocation.USAGE_SCRIPT);
+        mTests[index].debugName = RsBenchRS.createZeroTerminatedAlloc(mRS,
+                                                                      mNames[index],
+                                                                      Allocation.USAGE_SCRIPT);
 
         ScriptField_UiTestData_s.Item dataItem = new ScriptField_UiTestData_s.Item();
         dataItem.testId = testId;
diff --git a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/rsbench.rs b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/rsbench.rs
index 2b849a2..27e5b11 100644
--- a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/rsbench.rs
+++ b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/rsbench.rs
@@ -45,11 +45,13 @@
 typedef struct TestScripts_s {
     rs_allocation testData;
     rs_allocation testName;
+    rs_allocation debugName;
     rs_script testScript;
 } TestScripts;
 TestScripts *gTestScripts;
 
 bool gLoadComplete = false;
+bool gPauseRendering = false;
 
 static float gDt = 0;
 
@@ -195,7 +197,8 @@
 
     int64_t end = rsUptimeMillis();
     float fps = (float)(frameCount) / ((float)(end - start)*0.001f);
-    rsDebug("Finishes test ", fps);
+    const char *testName = rsGetElementAt(gTestScripts[benchMode].debugName, 0);
+    rsDebug(testName, fps);
 
     gResultBuffer[benchMode] = fps;
     int bufferW = rsAllocationGetDimX(gRenderBufferColor);
@@ -255,6 +258,10 @@
         return 1;
     }
 
+    if (gPauseRendering) {
+        rsgDrawText("Paused", 50, 50);
+        return 30;
+    }
     if (gIsDebugMode) {
         debug();
     } else {
diff --git a/tests/RenderScriptTests/ShadersTest/src/com/android/shaderstest/shaderstest.rs b/tests/RenderScriptTests/ShadersTest/src/com/android/shaderstest/shaderstest.rs
index 53f10f9..ae32e3a 100644
--- a/tests/RenderScriptTests/ShadersTest/src/com/android/shaderstest/shaderstest.rs
+++ b/tests/RenderScriptTests/ShadersTest/src/com/android/shaderstest/shaderstest.rs
@@ -57,6 +57,14 @@
 static float gLastX;
 static float gLastY;
 
+static float3 toFloat3(float x, float y, float z) {
+    float3 f;
+    f.x = x;
+    f.y = y;
+    f.z = z;
+    return f;
+}
+
 void onActionDown(float x, float y) {
     gLastX = x;
     gLastY = y;
@@ -112,8 +120,8 @@
         rsgMeshComputeBoundingBox(info->mMesh,
                                   &minX, &minY, &minZ,
                                   &maxX, &maxY, &maxZ);
-        info->bBoxMin = (minX, minY, minZ);
-        info->bBoxMax = (maxX, maxY, maxZ);
+        info->bBoxMin = toFloat3(minX, minY, minZ);
+        info->bBoxMax = toFloat3(maxX, maxY, maxZ);
         gLookAt += (info->bBoxMin + info->bBoxMax)*0.5f;
     }
     gLookAt = gLookAt / (float)size;
diff --git a/tests/StatusBar/res/layout/notification_builder_test.xml b/tests/StatusBar/res/layout/notification_builder_test.xml
index e1199c7..6c384f7 100644
--- a/tests/StatusBar/res/layout/notification_builder_test.xml
+++ b/tests/StatusBar/res/layout/notification_builder_test.xml
@@ -605,6 +605,11 @@
                         style="@style/FieldContents"
                         android:text="pineapple2"
                         />
+                <RadioButton
+                        android:id="@+id/large_icon_small"
+                        style="@style/FieldContents"
+                        android:text="small"
+                        />
             </RadioGroup>
             
 
diff --git a/tests/StatusBar/src/com/android/statusbartest/NotificationBuilderTest.java b/tests/StatusBar/src/com/android/statusbartest/NotificationBuilderTest.java
index 5a2ebac..fefd890 100644
--- a/tests/StatusBar/src/com/android/statusbartest/NotificationBuilderTest.java
+++ b/tests/StatusBar/src/com/android/statusbartest/NotificationBuilderTest.java
@@ -287,6 +287,9 @@
             case R.id.large_icon_pineapple2:
                 b.setLargeIcon(loadBitmap(R.drawable.pineapple2));
                 break;
+            case R.id.large_icon_small:
+                b.setLargeIcon(loadBitmap(R.drawable.icon2));
+                break;
         }
 
         // sound TODO
diff --git a/tests/TileBenchmark/src/com/test/tilebenchmark/ProfiledWebView.java b/tests/TileBenchmark/src/com/test/tilebenchmark/ProfiledWebView.java
index b1cef15c..10802b4 100644
--- a/tests/TileBenchmark/src/com/test/tilebenchmark/ProfiledWebView.java
+++ b/tests/TileBenchmark/src/com/test/tilebenchmark/ProfiledWebView.java
@@ -110,9 +110,9 @@
      * been redrawn.
      */
     @Override
-    protected void pageSwapCallback() {
+    protected void pageSwapCallback(boolean startAnim) {
         mContentInvalMillis = System.currentTimeMillis() - mContentInvalMillis;
-        super.pageSwapCallback();
+        super.pageSwapCallback(startAnim);
         Log.d("ProfiledWebView", "REDRAW TOOK " + mContentInvalMillis
                 + "millis");
         mIsTesting = true;
diff --git a/tools/aapt/Command.cpp b/tools/aapt/Command.cpp
index 637c27d..d7ac15e 100644
--- a/tools/aapt/Command.cpp
+++ b/tools/aapt/Command.cpp
@@ -625,6 +625,11 @@
             bool actImeService = false;
             bool actWallpaperService = false;
 
+            // These two implement the implicit permissions that are granted
+            // to pre-1.6 applications.
+            bool hasWriteExternalStoragePermission = false;
+            bool hasReadPhoneStatePermission = false;
+
             // This next group of variables is used to implement a group of
             // backward-compatibility heuristics necessitated by the addition of
             // some new uses-feature constants in 2.1 and 2.2. In most cases, the
@@ -986,6 +991,10 @@
                                        name == "android.permission.WRITE_APN_SETTINGS" ||
                                        name == "android.permission.WRITE_SMS") {
                                 hasTelephonyPermission = true;
+                            } else if (name == "android.permission.WRITE_EXTERNAL_STORAGE") {
+                                hasWriteExternalStoragePermission = true;
+                            } else if (name == "android.permission.READ_PHONE_STATE") {
+                                hasReadPhoneStatePermission = true;
                             }
                             printf("uses-permission:'%s'\n", name.string());
                         } else {
@@ -1144,6 +1153,16 @@
                 }
             }
 
+            // Pre-1.6 implicitly granted permission compatibility logic
+            if (targetSdk < 4) {
+                if (!hasWriteExternalStoragePermission) {
+                    printf("uses-permission:'android.permission.WRITE_EXTERNAL_STORAGE'\n");
+                }
+                if (!hasReadPhoneStatePermission) {
+                    printf("uses-permission:'android.permission.READ_PHONE_STATE'\n");
+                }
+            }
+
             /* The following blocks handle printing "inferred" uses-features, based
              * on whether related features or permissions are used by the app.
              * Note that the various spec*Feature variables denote whether the
diff --git a/tools/layoutlib/bridge/src/android/animation/AnimationThread.java b/tools/layoutlib/bridge/src/android/animation/AnimationThread.java
index 2b5e4fa..af83c61 100644
--- a/tools/layoutlib/bridge/src/android/animation/AnimationThread.java
+++ b/tools/layoutlib/bridge/src/android/animation/AnimationThread.java
@@ -86,8 +86,11 @@
         try {
             Handler_Delegate.setCallback(new IHandlerCallback() {
                 public void sendMessageAtTime(Handler handler, Message msg, long uptimeMillis) {
-                    if (msg.what == ValueAnimator.ANIMATION_START ||
-                            msg.what == ValueAnimator.ANIMATION_FRAME) {
+                    if (msg.what == ValueAnimator.ANIMATION_START /*||
+                            FIXME: The ANIMATION_FRAME message no longer exists.  Instead,
+                            the animation timing loop is based on a Choreographer object
+                            that schedules animation and drawing frames.
+                            msg.what == ValueAnimator.ANIMATION_FRAME*/) {
                         mQueue.add(new MessageBundle(handler, msg, uptimeMillis));
                     } else {
                         // just ignore.
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowSession.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowSession.java
index 1d97e15..a640a91 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowSession.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowSession.java
@@ -79,12 +79,16 @@
     }
 
     public int relayout(IWindow arg0, int seq, LayoutParams arg1, int arg2, int arg3, int arg4,
-            boolean arg4_5, Rect arg5, Rect arg6, Rect arg7, Configuration arg7b, Surface arg8)
+            int arg4_5, Rect arg5, Rect arg6, Rect arg7, Configuration arg7b, Surface arg8)
             throws RemoteException {
         // pass for now.
         return 0;
     }
 
+    public void performDeferredDestroy(IWindow window) {
+        // pass for now.
+    }
+
     public boolean outOfMemory(IWindow window) throws RemoteException {
         return false;
     }
diff --git a/tools/layoutlib/create/.classpath b/tools/layoutlib/create/.classpath
index 0c60f6a..734ebdc 100644
--- a/tools/layoutlib/create/.classpath
+++ b/tools/layoutlib/create/.classpath
@@ -4,6 +4,6 @@
 	<classpathentry excluding="mock_android/" kind="src" path="tests"/>
 	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
 	<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
-	<classpathentry kind="var" path="ANDROID_SRC/prebuilt/common/asm/asm-3.1.jar"/>
+	<classpathentry kind="var" path="ANDROID_SRC/prebuilt/common/asm/asm-4.0.jar"/>
 	<classpathentry kind="output" path="bin"/>
 </classpath>
diff --git a/tools/layoutlib/create/Android.mk b/tools/layoutlib/create/Android.mk
index 310fae5..9bd48ab 100644
--- a/tools/layoutlib/create/Android.mk
+++ b/tools/layoutlib/create/Android.mk
@@ -20,7 +20,7 @@
 
 LOCAL_JAR_MANIFEST := manifest.txt
 LOCAL_STATIC_JAVA_LIBRARIES := \
-	asm-3.1
+	asm-4.0
 
 LOCAL_MODULE := layoutlib_create
 
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmAnalyzer.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmAnalyzer.java
index b197ea7..412695f 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmAnalyzer.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmAnalyzer.java
@@ -23,6 +23,7 @@
 import org.objectweb.asm.FieldVisitor;
 import org.objectweb.asm.Label;
 import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
 import org.objectweb.asm.Type;
 import org.objectweb.asm.signature.SignatureReader;
 import org.objectweb.asm.signature.SignatureVisitor;
@@ -32,8 +33,8 @@
 import java.util.Enumeration;
 import java.util.List;
 import java.util.Map;
-import java.util.TreeMap;
 import java.util.Map.Entry;
+import java.util.TreeMap;
 import java.util.regex.Pattern;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipFile;
@@ -45,7 +46,7 @@
 public class AsmAnalyzer {
 
     // Note: a bunch of stuff has package-level access for unit tests. Consider it private.
-    
+
     /** Output logger. */
     private final Log mLog;
     /** The input source JAR to parse. */
@@ -59,11 +60,11 @@
 
     /**
      * Creates a new analyzer.
-     * 
+     *
      * @param log The log output.
      * @param osJarPath The input source JARs to parse.
      * @param gen The generator to fill with the class list and dependency list.
-     * @param deriveFrom Keep all classes that derive from these one (these included). 
+     * @param deriveFrom Keep all classes that derive from these one (these included).
      * @param includeGlobs Glob patterns of classes to keep, e.g. "com.foo.*"
      *        ("*" does not matches dots whilst "**" does, "." and "$" are interpreted as-is)
      */
@@ -83,14 +84,14 @@
     public void analyze() throws IOException, LogAbortException {
 
         AsmAnalyzer visitor = this;
-        
+
         Map<String, ClassReader> zipClasses = parseZip(mOsSourceJar);
         mLog.info("Found %d classes in input JAR%s.", zipClasses.size(),
                 mOsSourceJar.size() > 1 ? "s" : "");
-        
+
         Map<String, ClassReader> found = findIncludes(zipClasses);
         Map<String, ClassReader> deps = findDeps(zipClasses, found);
-        
+
         if (mGen != null) {
             mGen.setKeep(found);
             mGen.setDeps(deps);
@@ -117,10 +118,10 @@
                 }
             }
         }
-        
+
         return classes;
     }
-    
+
     /**
      * Utility that returns the fully qualified binary class name for a ClassReader.
      * E.g. it returns something like android.view.View.
@@ -132,7 +133,7 @@
             return classReader.getClassName().replace('/', '.');
         }
     }
-    
+
     /**
      * Utility that returns the fully qualified binary class name from a path-like FQCN.
      * E.g. it returns android.view.View from android/view/View.
@@ -144,7 +145,7 @@
             return className.replace('/', '.');
         }
     }
-    
+
     /**
      * Process the "includes" arrays.
      * <p/>
@@ -162,11 +163,11 @@
         for (String s : mDeriveFrom) {
             findClassesDerivingFrom(s, zipClasses, found);
         }
-        
+
         return found;
     }
 
-    
+
     /**
      * Uses ASM to find the class reader for the given FQCN class name.
      * If found, insert it in the in_out_found map.
@@ -215,7 +216,7 @@
         globPattern += "$";
 
         Pattern regexp = Pattern.compile(globPattern);
-        
+
         for (Entry<String, ClassReader> entry : zipClasses.entrySet()) {
             String class_name = entry.getKey();
             if (regexp.matcher(class_name).matches()) {
@@ -284,7 +285,7 @@
         for (ClassReader cr : inOutKeepClasses.values()) {
             cr.accept(visitor, 0 /* flags */);
         }
-        
+
         while (new_deps.size() > 0 || new_keep.size() > 0) {
             deps.putAll(new_deps);
             inOutKeepClasses.putAll(new_keep);
@@ -308,15 +309,14 @@
         return deps;
     }
 
-    
+
 
     // ----------------------------------
-    
+
     /**
-     * Visitor to collect all the type dependencies from a class. 
+     * Visitor to collect all the type dependencies from a class.
      */
-    public class DependencyVisitor
-        implements ClassVisitor, FieldVisitor, MethodVisitor, SignatureVisitor, AnnotationVisitor {
+    public class DependencyVisitor extends ClassVisitor {
 
         /** All classes found in the source JAR. */
         private final Map<String, ClassReader> mZipClasses;
@@ -333,7 +333,7 @@
          * Creates a new visitor that will find all the dependencies for the visited class.
          * Types which are already in the zipClasses, keepClasses or inDeps are not marked.
          * New dependencies are marked in outDeps.
-         * 
+         *
          * @param zipClasses All classes found in the source JAR.
          * @param inKeep Classes from which dependencies are to be found.
          * @param inDeps Dependencies already known.
@@ -344,13 +344,14 @@
                 Map<String, ClassReader> outKeep,
                 Map<String,ClassReader> inDeps,
                 Map<String,ClassReader> outDeps) {
+            super(Opcodes.ASM4);
             mZipClasses = zipClasses;
             mInKeep = inKeep;
             mOutKeep = outKeep;
             mInDeps = inDeps;
             mOutDeps = outDeps;
         }
-        
+
         /**
          * Considers the given class name as a dependency.
          * If it does, add to the mOutDeps map.
@@ -361,7 +362,7 @@
             }
 
             className = internalToBinaryClassName(className);
-            
+
             // exclude classes that have already been found
             if (mInKeep.containsKey(className) ||
                     mOutKeep.containsKey(className) ||
@@ -384,7 +385,7 @@
             } catch (ClassNotFoundException e) {
                 // ignore
             }
-            
+
             // accept this class:
             // - android classes are added to dependencies
             // - non-android classes are added to the list of classes to keep as-is (they don't need
@@ -395,7 +396,7 @@
                 mOutKeep.put(className, cr);
             }
         }
-        
+
         /**
          * Considers this array of names using considerName().
          */
@@ -416,7 +417,7 @@
                 SignatureReader sr = new SignatureReader(signature);
                 // SignatureReader.accept will call accessType so we don't really have
                 // to differentiate where the signature comes from.
-                sr.accept(this);
+                sr.accept(new MySignatureVisitor());
             }
         }
 
@@ -450,17 +451,18 @@
             }
         }
 
-        
+
         // ---------------------------------------------------
         // --- ClassVisitor, FieldVisitor
         // ---------------------------------------------------
 
         // Visits a class header
+        @Override
         public void visit(int version, int access, String name,
                 String signature, String superName, String[] interfaces) {
             // signature is the signature of this class. May be null if the class is not a generic
             // one, and does not extend or implement generic classes or interfaces.
-            
+
             if (signature != null) {
                 considerSignature(signature);
             }
@@ -468,27 +470,57 @@
             // superName is the internal of name of the super class (see getInternalName).
             // For interfaces, the super class is Object. May be null but only for the Object class.
             considerName(superName);
-            
+
             // interfaces is the internal names of the class's interfaces (see getInternalName).
             // May be null.
             considerNames(interfaces);
         }
 
+
+        @Override
         public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
             // desc is the class descriptor of the annotation class.
             considerDesc(desc);
-            return this; // return this to visit annotion values
+            return new MyAnnotationVisitor();
         }
 
+        @Override
         public void visitAttribute(Attribute attr) {
             // pass
         }
 
         // Visits the end of a class
+        @Override
         public void visitEnd() {
             // pass
         }
 
+        private class MyFieldVisitor extends FieldVisitor {
+
+            public MyFieldVisitor() {
+                super(Opcodes.ASM4);
+            }
+
+            @Override
+            public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
+                // desc is the class descriptor of the annotation class.
+                considerDesc(desc);
+                return new MyAnnotationVisitor();
+            }
+
+            @Override
+            public void visitAttribute(Attribute attr) {
+                // pass
+            }
+
+            // Visits the end of a class
+            @Override
+            public void visitEnd() {
+                // pass
+            }
+        }
+
+        @Override
         public FieldVisitor visitField(int access, String name, String desc,
                 String signature, Object value) {
             // desc is the field's descriptor (see Type).
@@ -498,14 +530,16 @@
             // generic types.
             considerSignature(signature);
 
-            return this; // a visitor to visit field annotations and attributes
+            return new MyFieldVisitor();
         }
 
+        @Override
         public void visitInnerClass(String name, String outerName, String innerName, int access) {
             // name is the internal name of an inner class (see getInternalName).
             considerName(name);
         }
 
+        @Override
         public MethodVisitor visitMethod(int access, String name, String desc,
                 String signature, String[] exceptions) {
             // desc is the method's descriptor (see Type).
@@ -513,239 +547,299 @@
             // signature is the method's signature. May be null if the method parameters, return
             // type and exceptions do not use generic types.
             considerSignature(signature);
-            
-            return this; // returns this to visit the method
+
+            return new MyMethodVisitor();
         }
 
+        @Override
         public void visitOuterClass(String owner, String name, String desc) {
             // pass
         }
 
+        @Override
         public void visitSource(String source, String debug) {
             // pass
         }
 
-        
+
         // ---------------------------------------------------
         // --- MethodVisitor
         // ---------------------------------------------------
 
-        public AnnotationVisitor visitAnnotationDefault() {
-            return this; // returns this to visit the default value
-        }
+        private class MyMethodVisitor extends MethodVisitor {
+
+            public MyMethodVisitor() {
+                super(Opcodes.ASM4);
+            }
 
 
-        public void visitCode() {
-            // pass
-        }
+            @Override
+            public AnnotationVisitor visitAnnotationDefault() {
+                return new MyAnnotationVisitor();
+            }
 
-        // field instruction
-        public void visitFieldInsn(int opcode, String owner, String name, String desc) {
-            // name is the field's name.
-            considerName(name);
-            // desc is the field's descriptor (see Type).
-            considerDesc(desc);
-        }
+            @Override
+            public void visitCode() {
+                // pass
+            }
 
-        public void visitFrame(int type, int local, Object[] local2, int stack, Object[] stack2) {
-            // pass
-        }
+            // field instruction
+            @Override
+            public void visitFieldInsn(int opcode, String owner, String name, String desc) {
+                // name is the field's name.
+                considerName(name);
+                // desc is the field's descriptor (see Type).
+                considerDesc(desc);
+            }
 
-        public void visitIincInsn(int var, int increment) {
-            // pass -- an IINC instruction
-        }
+            @Override
+            public void visitFrame(int type, int local, Object[] local2, int stack, Object[] stack2) {
+                // pass
+            }
 
-        public void visitInsn(int opcode) {
-            // pass -- a zero operand instruction
-        }
+            @Override
+            public void visitIincInsn(int var, int increment) {
+                // pass -- an IINC instruction
+            }
 
-        public void visitIntInsn(int opcode, int operand) {
-            // pass -- a single int operand instruction
-        }
+            @Override
+            public void visitInsn(int opcode) {
+                // pass -- a zero operand instruction
+            }
 
-        public void visitJumpInsn(int opcode, Label label) {
-            // pass -- a jump instruction
-        }
+            @Override
+            public void visitIntInsn(int opcode, int operand) {
+                // pass -- a single int operand instruction
+            }
 
-        public void visitLabel(Label label) {
-            // pass -- a label target
-        }
+            @Override
+            public void visitJumpInsn(int opcode, Label label) {
+                // pass -- a jump instruction
+            }
 
-        // instruction to load a constant from the stack
-        public void visitLdcInsn(Object cst) {
-            if (cst instanceof Type) {
-                considerType((Type) cst);
+            @Override
+            public void visitLabel(Label label) {
+                // pass -- a label target
+            }
+
+            // instruction to load a constant from the stack
+            @Override
+            public void visitLdcInsn(Object cst) {
+                if (cst instanceof Type) {
+                    considerType((Type) cst);
+                }
+            }
+
+            @Override
+            public void visitLineNumber(int line, Label start) {
+                // pass
+            }
+
+            @Override
+            public void visitLocalVariable(String name, String desc,
+                    String signature, Label start, Label end, int index) {
+                // desc is the type descriptor of this local variable.
+                considerDesc(desc);
+                // signature is the type signature of this local variable. May be null if the local
+                // variable type does not use generic types.
+                considerSignature(signature);
+            }
+
+            @Override
+            public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) {
+                // pass -- a lookup switch instruction
+            }
+
+            @Override
+            public void visitMaxs(int maxStack, int maxLocals) {
+                // pass
+            }
+
+            // instruction that invokes a method
+            @Override
+            public void visitMethodInsn(int opcode, String owner, String name, String desc) {
+
+                // owner is the internal name of the method's owner class
+                considerName(owner);
+                // desc is the method's descriptor (see Type).
+                considerDesc(desc);
+            }
+
+            // instruction multianewarray, whatever that is
+            @Override
+            public void visitMultiANewArrayInsn(String desc, int dims) {
+
+                // desc an array type descriptor.
+                considerDesc(desc);
+            }
+
+            @Override
+            public AnnotationVisitor visitParameterAnnotation(int parameter, String desc,
+                    boolean visible) {
+                // desc is the class descriptor of the annotation class.
+                considerDesc(desc);
+                return new MyAnnotationVisitor();
+            }
+
+            @Override
+            public void visitTableSwitchInsn(int min, int max, Label dflt, Label[] labels) {
+                // pass -- table switch instruction
+
+            }
+
+            @Override
+            public void visitTryCatchBlock(Label start, Label end, Label handler, String type) {
+                // type is the internal name of the type of exceptions handled by the handler,
+                // or null to catch any exceptions (for "finally" blocks).
+                considerName(type);
+            }
+
+            // type instruction
+            @Override
+            public void visitTypeInsn(int opcode, String type) {
+                // type is the operand of the instruction to be visited. This operand must be the
+                // internal name of an object or array class.
+                considerName(type);
+            }
+
+            @Override
+            public void visitVarInsn(int opcode, int var) {
+                // pass -- local variable instruction
             }
         }
 
-        public void visitLineNumber(int line, Label start) {
-            // pass
-        }
+        private class MySignatureVisitor extends SignatureVisitor {
 
-        public void visitLocalVariable(String name, String desc,
-                String signature, Label start, Label end, int index) {
-            // desc is the type descriptor of this local variable.
-            considerDesc(desc);
-            // signature is the type signature of this local variable. May be null if the local
-            // variable type does not use generic types.
-            considerSignature(signature);
-        }
+            public MySignatureVisitor() {
+                super(Opcodes.ASM4);
+            }
 
-        public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) {
-            // pass -- a lookup switch instruction
-        }
+            // ---------------------------------------------------
+            // --- SignatureVisitor
+            // ---------------------------------------------------
 
-        public void visitMaxs(int maxStack, int maxLocals) {
-            // pass
-        }
+            private String mCurrentSignatureClass = null;
 
-        // instruction that invokes a method
-        public void visitMethodInsn(int opcode, String owner, String name, String desc) {
-            
-            // owner is the internal name of the method's owner class
-            considerName(owner);
-            // desc is the method's descriptor (see Type).
-            considerDesc(desc);
-        }
+            // Starts the visit of a signature corresponding to a class or interface type
+            @Override
+            public void visitClassType(String name) {
+                mCurrentSignatureClass = name;
+                considerName(name);
+            }
 
-        // instruction multianewarray, whatever that is
-        public void visitMultiANewArrayInsn(String desc, int dims) {
-            
-            // desc an array type descriptor.
-            considerDesc(desc);
-        }
+            // Visits an inner class
+            @Override
+            public void visitInnerClassType(String name) {
+                if (mCurrentSignatureClass != null) {
+                    mCurrentSignatureClass += "$" + name;
+                    considerName(mCurrentSignatureClass);
+                }
+            }
 
-        public AnnotationVisitor visitParameterAnnotation(int parameter, String desc,
-                boolean visible) {
-            // desc is the class descriptor of the annotation class.
-            considerDesc(desc);
-            return this; // return this to visit annotation values
-        }
+            @Override
+            public SignatureVisitor visitArrayType() {
+                return new MySignatureVisitor();
+            }
 
-        public void visitTableSwitchInsn(int min, int max, Label dflt, Label[] labels) {
-            // pass -- table switch instruction
-            
-        }
+            @Override
+            public void visitBaseType(char descriptor) {
+                // pass -- a primitive type, ignored
+            }
 
-        public void visitTryCatchBlock(Label start, Label end, Label handler, String type) {
-            // type is the internal name of the type of exceptions handled by the handler,
-            // or null to catch any exceptions (for "finally" blocks).
-            considerName(type);
-        }
+            @Override
+            public SignatureVisitor visitClassBound() {
+                return new MySignatureVisitor();
+            }
 
-        // type instruction
-        public void visitTypeInsn(int opcode, String type) {
-            // type is the operand of the instruction to be visited. This operand must be the
-            // internal name of an object or array class.
-            considerName(type);
-        }
+            @Override
+            public SignatureVisitor visitExceptionType() {
+                return new MySignatureVisitor();
+            }
 
-        public void visitVarInsn(int opcode, int var) {
-            // pass -- local variable instruction 
-        }
+            @Override
+            public void visitFormalTypeParameter(String name) {
+                // pass
+            }
 
-        
-        // ---------------------------------------------------
-        // --- SignatureVisitor
-        // ---------------------------------------------------
+            @Override
+            public SignatureVisitor visitInterface() {
+                return new MySignatureVisitor();
+            }
 
-        private String mCurrentSignatureClass = null;
+            @Override
+            public SignatureVisitor visitInterfaceBound() {
+                return new MySignatureVisitor();
+            }
 
-        // Starts the visit of a signature corresponding to a class or interface type
-        public void visitClassType(String name) {
-            mCurrentSignatureClass = name;
-            considerName(name);
-        }
+            @Override
+            public SignatureVisitor visitParameterType() {
+                return new MySignatureVisitor();
+            }
 
-        // Visits an inner class
-        public void visitInnerClassType(String name) {
-            if (mCurrentSignatureClass != null) {
-                mCurrentSignatureClass += "$" + name;
-                considerName(mCurrentSignatureClass);
+            @Override
+            public SignatureVisitor visitReturnType() {
+                return new MySignatureVisitor();
+            }
+
+            @Override
+            public SignatureVisitor visitSuperclass() {
+                return new MySignatureVisitor();
+            }
+
+            @Override
+            public SignatureVisitor visitTypeArgument(char wildcard) {
+                return new MySignatureVisitor();
+            }
+
+            @Override
+            public void visitTypeVariable(String name) {
+                // pass
+            }
+
+            @Override
+            public void visitTypeArgument() {
+                // pass
             }
         }
 
-        public SignatureVisitor visitArrayType() {
-            return this; // returns this to visit the signature of the array element type
-        }
 
-        public void visitBaseType(char descriptor) {
-            // pass -- a primitive type, ignored
-        }
-
-        public SignatureVisitor visitClassBound() {
-            return this; // returns this to visit the signature of the class bound
-        }
-
-        public SignatureVisitor visitExceptionType() {
-            return this; // return this to visit the signature of the exception type.
-        }
-
-        public void visitFormalTypeParameter(String name) {
-            // pass
-        }
-
-        public SignatureVisitor visitInterface() {
-            return this; // returns this to visit the signature of the interface type
-        }
-
-        public SignatureVisitor visitInterfaceBound() {
-            return this; // returns this to visit the signature of the interface bound
-        }
-
-        public SignatureVisitor visitParameterType() {
-            return this; // returns this to visit the signature of the parameter type
-        }
-
-        public SignatureVisitor visitReturnType() {
-            return this; // returns this to visit the signature of the return type
-        }
-
-        public SignatureVisitor visitSuperclass() {
-            return this; // returns this to visit the signature of the super class type
-        }
-
-        public SignatureVisitor visitTypeArgument(char wildcard) {
-            return this; // returns this to visit the signature of the type argument
-        }
-
-        public void visitTypeVariable(String name) {
-            // pass
-        }
-
-        public void visitTypeArgument() {
-            // pass
-        }
-        
-        
         // ---------------------------------------------------
         // --- AnnotationVisitor
         // ---------------------------------------------------
 
+        private class MyAnnotationVisitor extends AnnotationVisitor {
 
-        // Visits a primitive value of an annotation
-        public void visit(String name, Object value) {
-            // value is the actual value, whose type must be Byte, Boolean, Character, Short,
-            // Integer, Long, Float, Double, String or Type
-            if (value instanceof Type) {
-                considerType((Type) value);
+            public MyAnnotationVisitor() {
+                super(Opcodes.ASM4);
+            }
+
+            // Visits a primitive value of an annotation
+            @Override
+            public void visit(String name, Object value) {
+                // value is the actual value, whose type must be Byte, Boolean, Character, Short,
+                // Integer, Long, Float, Double, String or Type
+                if (value instanceof Type) {
+                    considerType((Type) value);
+                }
+            }
+
+            @Override
+            public AnnotationVisitor visitAnnotation(String name, String desc) {
+                // desc is the class descriptor of the nested annotation class.
+                considerDesc(desc);
+                return new MyAnnotationVisitor();
+            }
+
+            @Override
+            public AnnotationVisitor visitArray(String name) {
+                return new MyAnnotationVisitor();
+            }
+
+            @Override
+            public void visitEnum(String name, String desc, String value) {
+                // desc is the class descriptor of the enumeration class.
+                considerDesc(desc);
             }
         }
-
-        public AnnotationVisitor visitAnnotation(String name, String desc) {
-            // desc is the class descriptor of the nested annotation class.
-            considerDesc(desc);
-            return this; // returns this to visit the actual nested annotation value
-        }
-
-        public AnnotationVisitor visitArray(String name) {
-            return this; // returns this to visit the actual array value elements
-        }
-
-        public void visitEnum(String name, String desc, String value) {
-            // desc is the class descriptor of the enumeration class.
-            considerDesc(desc);
-        }
-        
     }
 }
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/ClassHasNativeVisitor.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/ClassHasNativeVisitor.java
index 722dce2..2c955fd 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/ClassHasNativeVisitor.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/ClassHasNativeVisitor.java
@@ -29,7 +29,10 @@
 /**
  * Indicates if a class contains any native methods.
  */
-public class ClassHasNativeVisitor implements ClassVisitor {
+public class ClassHasNativeVisitor extends ClassVisitor {
+    public ClassHasNativeVisitor() {
+        super(Opcodes.ASM4);
+    }
 
     private boolean mHasNativeMethods = false;
 
@@ -42,35 +45,42 @@
         mHasNativeMethods = hasNativeMethods;
     }
 
+    @Override
     public void visit(int version, int access, String name, String signature,
             String superName, String[] interfaces) {
         // pass
     }
 
+    @Override
     public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
         // pass
         return null;
     }
 
+    @Override
     public void visitAttribute(Attribute attr) {
         // pass
     }
 
+    @Override
     public void visitEnd() {
         // pass
     }
 
+    @Override
     public FieldVisitor visitField(int access, String name, String desc,
             String signature, Object value) {
         // pass
         return null;
     }
 
+    @Override
     public void visitInnerClass(String name, String outerName,
             String innerName, int access) {
         // pass
     }
 
+    @Override
     public MethodVisitor visitMethod(int access, String name, String desc,
             String signature, String[] exceptions) {
         if ((access & Opcodes.ACC_NATIVE) != 0) {
@@ -79,10 +89,12 @@
         return null;
     }
 
+    @Override
     public void visitOuterClass(String owner, String name, String desc) {
         // pass
     }
 
+    @Override
     public void visitSource(String source, String debug) {
         // pass
     }
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/DelegateClassAdapter.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/DelegateClassAdapter.java
index 0e24cc0..927be97 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/DelegateClassAdapter.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/DelegateClassAdapter.java
@@ -16,7 +16,6 @@
 
 package com.android.tools.layoutlib.create;
 
-import org.objectweb.asm.ClassAdapter;
 import org.objectweb.asm.ClassVisitor;
 import org.objectweb.asm.MethodVisitor;
 import org.objectweb.asm.Opcodes;
@@ -29,7 +28,7 @@
  * <p/>
  * This is used to override specific methods and or all native methods in classes.
  */
-public class DelegateClassAdapter extends ClassAdapter {
+public class DelegateClassAdapter extends ClassVisitor {
 
     /** Suffix added to original methods. */
     private static final String ORIGINAL_SUFFIX = "_Original";
@@ -59,7 +58,7 @@
             ClassVisitor cv,
             String className,
             Set<String> delegateMethods) {
-        super(cv);
+        super(Opcodes.ASM4, cv);
         mLog = log;
         mClassName = className;
         mDelegateMethods = delegateMethods;
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/DelegateMethodAdapter2.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/DelegateMethodAdapter2.java
index 89b53ab..0000b22 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/DelegateMethodAdapter2.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/DelegateMethodAdapter2.java
@@ -71,7 +71,7 @@
  * Instances of this class are not re-usable.
  * The class adapter creates a new instance for each method.
  */
-class DelegateMethodAdapter2 implements MethodVisitor {
+class DelegateMethodAdapter2 extends MethodVisitor {
 
     /** Suffix added to delegate classes. */
     public static final String DELEGATE_SUFFIX = "_Delegate";
@@ -121,6 +121,7 @@
             String methodName,
             String desc,
             boolean isStatic) {
+        super(Opcodes.ASM4);
         mLog = log;
         mOrgWriter = mvOriginal;
         mDelWriter = mvDelegate;
@@ -265,6 +266,7 @@
     }
 
     /* Pass down to visitor writer. In this implementation, either do nothing. */
+    @Override
     public void visitCode() {
         if (mOrgWriter != null) {
             mOrgWriter.visitCode();
@@ -274,6 +276,7 @@
     /*
      * visitMaxs is called just before visitEnd if there was any code to rewrite.
      */
+    @Override
     public void visitMaxs(int maxStack, int maxLocals) {
         if (mOrgWriter != null) {
             mOrgWriter.visitMaxs(maxStack, maxLocals);
@@ -281,6 +284,7 @@
     }
 
     /** End of visiting. Generate the delegating code. */
+    @Override
     public void visitEnd() {
         if (mOrgWriter != null) {
             mOrgWriter.visitEnd();
@@ -289,6 +293,7 @@
     }
 
     /* Writes all annotation from the original method. */
+    @Override
     public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
         if (mOrgWriter != null) {
             return mOrgWriter.visitAnnotation(desc, visible);
@@ -298,6 +303,7 @@
     }
 
     /* Writes all annotation default values from the original method. */
+    @Override
     public AnnotationVisitor visitAnnotationDefault() {
         if (mOrgWriter != null) {
             return mOrgWriter.visitAnnotationDefault();
@@ -306,6 +312,7 @@
         }
     }
 
+    @Override
     public AnnotationVisitor visitParameterAnnotation(int parameter, String desc,
             boolean visible) {
         if (mOrgWriter != null) {
@@ -316,6 +323,7 @@
     }
 
     /* Writes all attributes from the original method. */
+    @Override
     public void visitAttribute(Attribute attr) {
         if (mOrgWriter != null) {
             mOrgWriter.visitAttribute(attr);
@@ -326,6 +334,7 @@
      * Only writes the first line number present in the original code so that source
      * viewers can direct to the correct method, even if the content doesn't match.
      */
+    @Override
     public void visitLineNumber(int line, Label start) {
         // Capture the first line values for the new delegate method
         if (mDelegateLineNumber == null) {
@@ -336,66 +345,77 @@
         }
     }
 
+    @Override
     public void visitInsn(int opcode) {
         if (mOrgWriter != null) {
             mOrgWriter.visitInsn(opcode);
         }
     }
 
+    @Override
     public void visitLabel(Label label) {
         if (mOrgWriter != null) {
             mOrgWriter.visitLabel(label);
         }
     }
 
+    @Override
     public void visitTryCatchBlock(Label start, Label end, Label handler, String type) {
         if (mOrgWriter != null) {
             mOrgWriter.visitTryCatchBlock(start, end, handler, type);
         }
     }
 
+    @Override
     public void visitMethodInsn(int opcode, String owner, String name, String desc) {
         if (mOrgWriter != null) {
             mOrgWriter.visitMethodInsn(opcode, owner, name, desc);
         }
     }
 
+    @Override
     public void visitFieldInsn(int opcode, String owner, String name, String desc) {
         if (mOrgWriter != null) {
             mOrgWriter.visitFieldInsn(opcode, owner, name, desc);
         }
     }
 
+    @Override
     public void visitFrame(int type, int nLocal, Object[] local, int nStack, Object[] stack) {
         if (mOrgWriter != null) {
             mOrgWriter.visitFrame(type, nLocal, local, nStack, stack);
         }
     }
 
+    @Override
     public void visitIincInsn(int var, int increment) {
         if (mOrgWriter != null) {
             mOrgWriter.visitIincInsn(var, increment);
         }
     }
 
+    @Override
     public void visitIntInsn(int opcode, int operand) {
         if (mOrgWriter != null) {
             mOrgWriter.visitIntInsn(opcode, operand);
         }
     }
 
+    @Override
     public void visitJumpInsn(int opcode, Label label) {
         if (mOrgWriter != null) {
             mOrgWriter.visitJumpInsn(opcode, label);
         }
     }
 
+    @Override
     public void visitLdcInsn(Object cst) {
         if (mOrgWriter != null) {
             mOrgWriter.visitLdcInsn(cst);
         }
     }
 
+    @Override
     public void visitLocalVariable(String name, String desc, String signature,
             Label start, Label end, int index) {
         if (mOrgWriter != null) {
@@ -403,30 +423,35 @@
         }
     }
 
+    @Override
     public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) {
         if (mOrgWriter != null) {
             mOrgWriter.visitLookupSwitchInsn(dflt, keys, labels);
         }
     }
 
+    @Override
     public void visitMultiANewArrayInsn(String desc, int dims) {
         if (mOrgWriter != null) {
             mOrgWriter.visitMultiANewArrayInsn(desc, dims);
         }
     }
 
+    @Override
     public void visitTableSwitchInsn(int min, int max, Label dflt, Label[] labels) {
         if (mOrgWriter != null) {
             mOrgWriter.visitTableSwitchInsn(min, max, dflt, labels);
         }
     }
 
+    @Override
     public void visitTypeInsn(int opcode, String type) {
         if (mOrgWriter != null) {
             mOrgWriter.visitTypeInsn(opcode, type);
         }
     }
 
+    @Override
     public void visitVarInsn(int opcode, int var) {
         if (mOrgWriter != null) {
             mOrgWriter.visitVarInsn(opcode, var);
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/RenameClassAdapter.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/RenameClassAdapter.java
index 0956b92..383cbb8 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/RenameClassAdapter.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/RenameClassAdapter.java
@@ -17,12 +17,12 @@
 package com.android.tools.layoutlib.create;
 
 import org.objectweb.asm.AnnotationVisitor;
-import org.objectweb.asm.ClassAdapter;
+import org.objectweb.asm.ClassVisitor;
 import org.objectweb.asm.ClassWriter;
 import org.objectweb.asm.FieldVisitor;
 import org.objectweb.asm.Label;
-import org.objectweb.asm.MethodAdapter;
 import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
 import org.objectweb.asm.Type;
 import org.objectweb.asm.signature.SignatureReader;
 import org.objectweb.asm.signature.SignatureVisitor;
@@ -32,13 +32,13 @@
  * This class visitor renames a class from a given old name to a given new name.
  * The class visitor will also rename all inner classes and references in the methods.
  * <p/>
- * 
+ *
  * For inner classes, this handles only the case where the outer class name changes.
- * The inner class name should remain the same. 
+ * The inner class name should remain the same.
  */
-public class RenameClassAdapter extends ClassAdapter {
+public class RenameClassAdapter extends ClassVisitor {
 
-    
+
     private final String mOldName;
     private final String mNewName;
     private String mOldBase;
@@ -50,10 +50,10 @@
      * The names must be full qualified internal ASM names (e.g. com/blah/MyClass$InnerClass).
      */
     public RenameClassAdapter(ClassWriter cv, String oldName, String newName) {
-        super(cv);
+        super(Opcodes.ASM4, cv);
         mOldBase = mOldName = oldName;
         mNewBase = mNewName = newName;
-        
+
         int pos = mOldName.indexOf('$');
         if (pos > 0) {
             mOldBase = mOldName.substring(0, pos);
@@ -62,7 +62,7 @@
         if (pos > 0) {
             mNewBase = mNewName.substring(0, pos);
         }
-        
+
         assert (mOldBase == null && mNewBase == null) || (mOldBase != null && mNewBase != null);
     }
 
@@ -78,7 +78,7 @@
 
         return renameType(Type.getType(desc));
     }
-    
+
     /**
      * Renames an object type, e.g. "Lcom.package.MyClass;" or an array type that has an
      * object element, e.g. "[Lcom.package.MyClass;"
@@ -150,7 +150,7 @@
         if (mOldBase != mOldName && type.equals(mOldBase)) {
             return mNewBase;
         }
-    
+
         int pos = type.indexOf('$');
         if (pos == mOldBase.length() && type.startsWith(mOldBase)) {
             return mNewBase + type.substring(pos);
@@ -183,7 +183,7 @@
             sb.append(name);
         }
         sb.append(')');
-        
+
         Type ret = Type.getReturnType(desc);
         String name = renameType(ret);
         sb.append(name);
@@ -191,9 +191,9 @@
         return sb.toString();
     }
 
-    
+
     /**
-     * Renames the ClassSignature handled by ClassVisitor.visit 
+     * Renames the ClassSignature handled by ClassVisitor.visit
      * or the MethodTypeSignature handled by ClassVisitor.visitMethod.
      */
     String renameTypeSignature(String sig) {
@@ -207,7 +207,7 @@
         return sig;
     }
 
-    
+
     /**
      * Renames the FieldTypeSignature handled by ClassVisitor.visitField
      * or MethodVisitor.visitLocalVariable.
@@ -223,17 +223,17 @@
         return sig;
     }
 
-    
+
     //----------------------------------
     // Methods from the ClassAdapter
-    
+
     @Override
     public void visit(int version, int access, String name, String signature,
             String superName, String[] interfaces) {
         name = renameInternalType(name);
         superName = renameInternalType(superName);
         signature = renameTypeSignature(signature);
-        
+
         super.visit(version, access, name, signature, superName, interfaces);
     }
 
@@ -259,7 +259,7 @@
         desc = renameTypeDesc(desc);
         return super.visitAnnotation(desc, visible);
     }
-    
+
     @Override
     public FieldVisitor visitField(int access, String name, String desc,
             String signature, Object value) {
@@ -267,14 +267,14 @@
         signature = renameFieldSignature(signature);
         return super.visitField(access, name, desc, signature, value);
     }
-    
-    
+
+
     //----------------------------------
 
     /**
      * A method visitor that renames all references from an old class name to a new class name.
      */
-    public class RenameMethodAdapter extends MethodAdapter {
+    public class RenameMethodAdapter extends MethodVisitor {
 
         /**
          * Creates a method visitor that renames all references from a given old name to a given new
@@ -282,13 +282,13 @@
          * The names must be full qualified internal ASM names (e.g. com/blah/MyClass$InnerClass).
          */
         public RenameMethodAdapter(MethodVisitor mv) {
-            super(mv);
+            super(Opcodes.ASM4, mv);
         }
 
         @Override
         public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
             desc = renameTypeDesc(desc);
-            
+
             return super.visitAnnotation(desc, visible);
         }
 
@@ -302,7 +302,7 @@
         @Override
         public void visitTypeInsn(int opcode, String type) {
             type = renameInternalType(type);
-            
+
             super.visitTypeInsn(opcode, type);
         }
 
@@ -321,7 +321,7 @@
 
             super.visitMethodInsn(opcode, owner, name, desc);
         }
-        
+
         @Override
         public void visitLdcInsn(Object cst) {
             // If cst is a Type, this means the code is trying to pull the .class constant
@@ -335,14 +335,14 @@
         @Override
         public void visitMultiANewArrayInsn(String desc, int dims) {
             desc = renameTypeDesc(desc);
-         
+
             super.visitMultiANewArrayInsn(desc, dims);
         }
 
         @Override
         public void visitTryCatchBlock(Label start, Label end, Label handler, String type) {
             type = renameInternalType(type);
-            
+
             super.visitTryCatchBlock(start, end, handler, type);
         }
 
@@ -351,96 +351,113 @@
                 Label start, Label end, int index) {
             desc = renameTypeDesc(desc);
             signature = renameFieldSignature(signature);
-            
+
             super.visitLocalVariable(name, desc, signature, start, end, index);
         }
 
     }
 
     //----------------------------------
-    
-    public class RenameSignatureAdapter implements SignatureVisitor {
+
+    public class RenameSignatureAdapter extends SignatureVisitor {
 
         private final SignatureVisitor mSv;
 
         public RenameSignatureAdapter(SignatureVisitor sv) {
+            super(Opcodes.ASM4);
             mSv = sv;
         }
 
+        @Override
         public void visitClassType(String name) {
             name = renameInternalType(name);
             mSv.visitClassType(name);
         }
 
+        @Override
         public void visitInnerClassType(String name) {
             name = renameInternalType(name);
             mSv.visitInnerClassType(name);
         }
 
+        @Override
         public SignatureVisitor visitArrayType() {
             SignatureVisitor sv = mSv.visitArrayType();
             return new RenameSignatureAdapter(sv);
         }
 
+        @Override
         public void visitBaseType(char descriptor) {
             mSv.visitBaseType(descriptor);
         }
 
+        @Override
         public SignatureVisitor visitClassBound() {
             SignatureVisitor sv = mSv.visitClassBound();
             return new RenameSignatureAdapter(sv);
         }
 
+        @Override
         public void visitEnd() {
             mSv.visitEnd();
         }
 
+        @Override
         public SignatureVisitor visitExceptionType() {
             SignatureVisitor sv = mSv.visitExceptionType();
             return new RenameSignatureAdapter(sv);
         }
 
+        @Override
         public void visitFormalTypeParameter(String name) {
             mSv.visitFormalTypeParameter(name);
         }
 
+        @Override
         public SignatureVisitor visitInterface() {
             SignatureVisitor sv = mSv.visitInterface();
             return new RenameSignatureAdapter(sv);
         }
 
+        @Override
         public SignatureVisitor visitInterfaceBound() {
             SignatureVisitor sv = mSv.visitInterfaceBound();
             return new RenameSignatureAdapter(sv);
         }
 
+        @Override
         public SignatureVisitor visitParameterType() {
             SignatureVisitor sv = mSv.visitParameterType();
             return new RenameSignatureAdapter(sv);
         }
 
+        @Override
         public SignatureVisitor visitReturnType() {
             SignatureVisitor sv = mSv.visitReturnType();
             return new RenameSignatureAdapter(sv);
         }
 
+        @Override
         public SignatureVisitor visitSuperclass() {
             SignatureVisitor sv = mSv.visitSuperclass();
             return new RenameSignatureAdapter(sv);
         }
 
+        @Override
         public void visitTypeArgument() {
             mSv.visitTypeArgument();
         }
 
+        @Override
         public SignatureVisitor visitTypeArgument(char wildcard) {
             SignatureVisitor sv = mSv.visitTypeArgument(wildcard);
             return new RenameSignatureAdapter(sv);
         }
 
+        @Override
         public void visitTypeVariable(String name) {
             mSv.visitTypeVariable(name);
         }
-        
+
     }
 }
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/StubMethodAdapter.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/StubMethodAdapter.java
index d70d028..51e7535 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/StubMethodAdapter.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/StubMethodAdapter.java
@@ -27,7 +27,7 @@
  * This method adapter rewrites a method by discarding the original code and generating
  * a stub depending on the return type. Original annotations are passed along unchanged.
  */
-class StubMethodAdapter implements MethodVisitor {
+class StubMethodAdapter extends MethodVisitor {
 
     private static String CONSTRUCTOR = "<init>";
     private static String CLASS_INIT = "<clinit>";
@@ -50,6 +50,7 @@
 
     public StubMethodAdapter(MethodVisitor mv, String methodName, Type returnType,
             String invokeSignature, boolean isStatic, boolean isNative) {
+        super(Opcodes.ASM4);
         mParentVisitor = mv;
         mReturnType = returnType;
         mInvokeSignature = invokeSignature;
@@ -172,6 +173,7 @@
     }
 
     /* Pass down to visitor writer. In this implementation, either do nothing. */
+    @Override
     public void visitCode() {
         mParentVisitor.visitCode();
     }
@@ -181,6 +183,7 @@
      * For non-constructor, generate the messaging code and the return statement
      * if it hasn't been done before.
      */
+    @Override
     public void visitMaxs(int maxStack, int maxLocals) {
         if (!mIsInitMethod && !mMessageGenerated) {
             generateInvoke();
@@ -194,6 +197,7 @@
      * For non-constructor, generate the messaging code and the return statement
      * if it hasn't been done before.
      */
+    @Override
     public void visitEnd() {
         if (!mIsInitMethod && !mMessageGenerated) {
             generateInvoke();
@@ -204,21 +208,25 @@
     }
 
     /* Writes all annotation from the original method. */
+    @Override
     public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
         return mParentVisitor.visitAnnotation(desc, visible);
     }
 
     /* Writes all annotation default values from the original method. */
+    @Override
     public AnnotationVisitor visitAnnotationDefault() {
         return mParentVisitor.visitAnnotationDefault();
     }
 
+    @Override
     public AnnotationVisitor visitParameterAnnotation(int parameter, String desc,
             boolean visible) {
         return mParentVisitor.visitParameterAnnotation(parameter, desc, visible);
     }
 
     /* Writes all attributes from the original method. */
+    @Override
     public void visitAttribute(Attribute attr) {
         mParentVisitor.visitAttribute(attr);
     }
@@ -227,6 +235,7 @@
      * Only writes the first line number present in the original code so that source
      * viewers can direct to the correct method, even if the content doesn't match.
      */
+    @Override
     public void visitLineNumber(int line, Label start) {
         if (mIsInitMethod || mOutputFirstLineNumber) {
             mParentVisitor.visitLineNumber(line, start);
@@ -237,6 +246,7 @@
     /**
      * For non-constructor, rewrite existing "return" instructions to write the message.
      */
+    @Override
     public void visitInsn(int opcode) {
         if (mIsInitMethod) {
             switch (opcode) {
@@ -257,60 +267,70 @@
         }
     }
 
+    @Override
     public void visitLabel(Label label) {
         if (mIsInitMethod) {
             mParentVisitor.visitLabel(label);
         }
     }
 
+    @Override
     public void visitTryCatchBlock(Label start, Label end, Label handler, String type) {
         if (mIsInitMethod) {
             mParentVisitor.visitTryCatchBlock(start, end, handler, type);
         }
     }
 
+    @Override
     public void visitMethodInsn(int opcode, String owner, String name, String desc) {
         if (mIsInitMethod) {
             mParentVisitor.visitMethodInsn(opcode, owner, name, desc);
         }
     }
 
+    @Override
     public void visitFieldInsn(int opcode, String owner, String name, String desc) {
         if (mIsInitMethod) {
             mParentVisitor.visitFieldInsn(opcode, owner, name, desc);
         }
     }
 
+    @Override
     public void visitFrame(int type, int nLocal, Object[] local, int nStack, Object[] stack) {
         if (mIsInitMethod) {
             mParentVisitor.visitFrame(type, nLocal, local, nStack, stack);
         }
     }
 
+    @Override
     public void visitIincInsn(int var, int increment) {
         if (mIsInitMethod) {
             mParentVisitor.visitIincInsn(var, increment);
         }
     }
 
+    @Override
     public void visitIntInsn(int opcode, int operand) {
         if (mIsInitMethod) {
             mParentVisitor.visitIntInsn(opcode, operand);
         }
     }
 
+    @Override
     public void visitJumpInsn(int opcode, Label label) {
         if (mIsInitMethod) {
             mParentVisitor.visitJumpInsn(opcode, label);
         }
     }
 
+    @Override
     public void visitLdcInsn(Object cst) {
         if (mIsInitMethod) {
             mParentVisitor.visitLdcInsn(cst);
         }
     }
 
+    @Override
     public void visitLocalVariable(String name, String desc, String signature,
             Label start, Label end, int index) {
         if (mIsInitMethod) {
@@ -318,30 +338,35 @@
         }
     }
 
+    @Override
     public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) {
         if (mIsInitMethod) {
             mParentVisitor.visitLookupSwitchInsn(dflt, keys, labels);
         }
     }
 
+    @Override
     public void visitMultiANewArrayInsn(String desc, int dims) {
         if (mIsInitMethod) {
             mParentVisitor.visitMultiANewArrayInsn(desc, dims);
         }
     }
 
+    @Override
     public void visitTableSwitchInsn(int min, int max, Label dflt, Label[] labels) {
         if (mIsInitMethod) {
             mParentVisitor.visitTableSwitchInsn(min, max, dflt, labels);
         }
     }
 
+    @Override
     public void visitTypeInsn(int opcode, String type) {
         if (mIsInitMethod) {
             mParentVisitor.visitTypeInsn(opcode, type);
         }
     }
 
+    @Override
     public void visitVarInsn(int opcode, int var) {
         if (mIsInitMethod) {
             mParentVisitor.visitVarInsn(opcode, var);
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/TransformClassAdapter.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/TransformClassAdapter.java
index 5a0a44a4..d45a183 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/TransformClassAdapter.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/TransformClassAdapter.java
@@ -16,7 +16,6 @@
 
 package com.android.tools.layoutlib.create;
 
-import org.objectweb.asm.ClassAdapter;
 import org.objectweb.asm.ClassVisitor;
 import org.objectweb.asm.FieldVisitor;
 import org.objectweb.asm.MethodVisitor;
@@ -28,7 +27,7 @@
 /**
  * Class adapter that can stub some or all of the methods of the class.
  */
-class TransformClassAdapter extends ClassAdapter {
+class TransformClassAdapter extends ClassVisitor {
 
     /** True if all methods should be stubbed, false if only native ones must be stubbed. */
     private final boolean mStubAll;
@@ -54,7 +53,7 @@
     public TransformClassAdapter(Log logger, Set<String> stubMethods,
             Set<String> deleteReturns, String className, ClassVisitor cv,
             boolean stubNativesOnly, boolean hasNative) {
-        super(cv);
+        super(Opcodes.ASM4, cv);
         mLog = logger;
         mStubMethods = stubMethods;
         mClassName = className;
diff --git a/wifi/java/android/net/wifi/WifiMonitor.java b/wifi/java/android/net/wifi/WifiMonitor.java
index 2ccc8a2..80963a8 100644
--- a/wifi/java/android/net/wifi/WifiMonitor.java
+++ b/wifi/java/android/net/wifi/WifiMonitor.java
@@ -20,6 +20,7 @@
 import android.net.wifi.p2p.WifiP2pConfig;
 import android.net.wifi.p2p.WifiP2pDevice;
 import android.net.wifi.p2p.WifiP2pGroup;
+import android.net.wifi.p2p.WifiP2pProvDiscEvent;
 import android.net.wifi.StateChangeResult;
 import android.os.Message;
 import android.util.Log;
@@ -181,6 +182,10 @@
        pri_dev_type=1-0050F204-1 name='p2p-TEST2' config_methods=0x188 dev_capab=0x27
        group_capab=0x0 */
     private static final String P2P_PROV_DISC_PBC_REQ_STR = "P2P-PROV-DISC-PBC-REQ";
+
+    /* P2P-PROV-DISC-PBC-RESP 02:12:47:f2:5a:36 */
+    private static final String P2P_PROV_DISC_PBC_RSP_STR = "P2P-PROV-DISC-PBC-RESP";
+
     /* P2P-PROV-DISC-ENTER-PIN 42:fc:89:e1:e2:27 p2p_dev_addr=42:fc:89:e1:e2:27
        pri_dev_type=1-0050F204-1 name='p2p-TEST2' config_methods=0x188 dev_capab=0x27
        group_capab=0x0 */
@@ -233,8 +238,9 @@
     public static final int P2P_INVITATION_RECEIVED_EVENT        = BASE + 31;
     public static final int P2P_INVITATION_RESULT_EVENT          = BASE + 32;
     public static final int P2P_PROV_DISC_PBC_REQ_EVENT          = BASE + 33;
-    public static final int P2P_PROV_DISC_ENTER_PIN_EVENT        = BASE + 34;
-    public static final int P2P_PROV_DISC_SHOW_PIN_EVENT         = BASE + 35;
+    public static final int P2P_PROV_DISC_PBC_RSP_EVENT          = BASE + 34;
+    public static final int P2P_PROV_DISC_ENTER_PIN_EVENT        = BASE + 35;
+    public static final int P2P_PROV_DISC_SHOW_PIN_EVENT         = BASE + 36;
 
     /* hostap events */
     public static final int AP_STA_DISCONNECTED_EVENT            = BASE + 41;
@@ -480,10 +486,16 @@
                 mStateMachine.sendMessage(P2P_INVITATION_RESULT_EVENT, nameValue[1]);
             } else if (dataString.startsWith(P2P_PROV_DISC_PBC_REQ_STR)) {
                 mStateMachine.sendMessage(P2P_PROV_DISC_PBC_REQ_EVENT,
-                        new WifiP2pDevice(dataString));
+                        new WifiP2pProvDiscEvent(dataString));
+            } else if (dataString.startsWith(P2P_PROV_DISC_PBC_RSP_STR)) {
+                mStateMachine.sendMessage(P2P_PROV_DISC_PBC_RSP_EVENT,
+                        new WifiP2pProvDiscEvent(dataString));
             } else if (dataString.startsWith(P2P_PROV_DISC_ENTER_PIN_STR)) {
                 mStateMachine.sendMessage(P2P_PROV_DISC_ENTER_PIN_EVENT,
-                        new WifiP2pDevice(dataString));
+                        new WifiP2pProvDiscEvent(dataString));
+            } else if (dataString.startsWith(P2P_PROV_DISC_SHOW_PIN_STR)) {
+                mStateMachine.sendMessage(P2P_PROV_DISC_SHOW_PIN_EVENT,
+                        new WifiP2pProvDiscEvent(dataString));
             }
         }
 
diff --git a/wifi/java/android/net/wifi/WifiNative.java b/wifi/java/android/net/wifi/WifiNative.java
index 6ff1bc2..0fc0a45 100644
--- a/wifi/java/android/net/wifi/WifiNative.java
+++ b/wifi/java/android/net/wifi/WifiNative.java
@@ -19,6 +19,7 @@
 import android.net.wifi.p2p.WifiP2pConfig;
 import android.net.wifi.p2p.WifiP2pGroup;
 import android.net.wifi.p2p.WifiP2pDevice;
+import android.text.TextUtils;
 import android.util.Log;
 
 import java.io.InputStream;
@@ -234,6 +235,14 @@
         return WifiNative.doBooleanCommand("SET device_type " + type);
     }
 
+    public static boolean setConfigMethods(String cfg) {
+        return WifiNative.doBooleanCommand("SET config_methods " + cfg);
+    }
+
+    public static boolean setP2pSsidPostfix(String postfix) {
+        return WifiNative.doBooleanCommand("SET p2p_ssid_postfix " + postfix);
+    }
+
     public static boolean p2pFind() {
         return doBooleanCommand("P2P_FIND");
     }
@@ -273,8 +282,11 @@
                 args.add("pbc");
                 break;
             case WpsInfo.DISPLAY:
-                //TODO: pass the pin back for display
-                args.add("pin");
+                if (TextUtils.isEmpty(wps.pin)) {
+                    args.add("pin");
+                } else {
+                    args.add(wps.pin);
+                }
                 args.add("display");
                 break;
             case WpsInfo.KEYPAD:
@@ -311,6 +323,24 @@
         return doBooleanCommand("P2P_CANCEL");
     }
 
+    public static boolean p2pProvisionDiscovery(WifiP2pConfig config) {
+        if (config == null) return false;
+
+        switch (config.wps.setup) {
+            case WpsInfo.PBC:
+                return doBooleanCommand("P2P_PROV_DISC " + config.deviceAddress + " pbc");
+            case WpsInfo.DISPLAY:
+                //We are doing display, so provision discovery is keypad
+                return doBooleanCommand("P2P_PROV_DISC " + config.deviceAddress + " keypad");
+            case WpsInfo.KEYPAD:
+                //We are doing keypad, so provision discovery is display
+                return doBooleanCommand("P2P_PROV_DISC " + config.deviceAddress + " display");
+            default:
+                break;
+        }
+        return false;
+    }
+
     public static boolean p2pGroupAdd() {
         return doBooleanCommand("P2P_GROUP_ADD");
     }
diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java
index 23b726e..920947f 100644
--- a/wifi/java/android/net/wifi/WifiStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiStateMachine.java
@@ -123,6 +123,8 @@
     private final LruCache<String, ScanResult> mScanResultCache;
 
     private String mInterfaceName;
+    /* Tethering interface could be seperate from wlan interface */
+    private String mTetherInterfaceName;
 
     private int mLastSignalLevel = -1;
     private String mLastBssid;
@@ -156,6 +158,14 @@
     /* Tracks sequence number on stop failure message */
     private int mSupplicantStopFailureToken = 0;
 
+    /**
+     * Tether state change notification time out
+     */
+    private static final int TETHER_NOTIFICATION_TIME_OUT_MSECS = 5000;
+
+    /* Tracks sequence number on a tether notification time out */
+    private int mTetherToken = 0;
+
     private LinkProperties mLinkProperties;
 
     // Wakelock held during wifi start/stop and driver load/unload
@@ -240,10 +250,12 @@
     static final int CMD_REQUEST_AP_CONFIG                = BASE + 27;
     /* Response to access point configuration request */
     static final int CMD_RESPONSE_AP_CONFIG               = BASE + 28;
-    /* Set configuration on tether interface */
-    static final int CMD_TETHER_INTERFACE                 = BASE + 29;
+    /* Invoked when getting a tether state change notification */
+    static final int CMD_TETHER_STATE_CHANGE              = BASE + 29;
+    /* A delayed message sent to indicate tether state change failed to arrive */
+    static final int CMD_TETHER_NOTIFICATION_TIMED_OUT    = BASE + 30;
 
-    static final int CMD_BLUETOOTH_ADAPTER_STATE_CHANGE   = BASE + 30;
+    static final int CMD_BLUETOOTH_ADAPTER_STATE_CHANGE   = BASE + 31;
 
     /* Supplicant commands */
     /* Is supplicant alive ? */
@@ -294,8 +306,6 @@
     static final int CMD_SET_HIGH_PERF_MODE               = BASE + 77;
     /* Set the country code */
     static final int CMD_SET_COUNTRY_CODE                 = BASE + 80;
-    /* Request connectivity manager wake lock before driver stop */
-    static final int CMD_REQUEST_CM_WAKELOCK              = BASE + 81;
     /* Enables RSSI poll */
     static final int CMD_ENABLE_RSSI_POLL                 = BASE + 82;
     /* RSSI poll */
@@ -455,12 +465,25 @@
     private State mSoftApStartingState = new SoftApStartingState();
     /* Soft ap is running */
     private State mSoftApStartedState = new SoftApStartedState();
+    /* Soft ap is running and we are waiting for tether notification */
+    private State mTetheringState = new TetheringState();
     /* Soft ap is running and we are tethered through connectivity service */
     private State mTetheredState = new TetheredState();
+    /* Waiting for untether confirmation to stop soft Ap */
+    private State mSoftApStoppingState = new SoftApStoppingState();
 
     /* Wait till p2p is disabled */
     private State mWaitForP2pDisableState = new WaitForP2pDisableState();
 
+    private class TetherStateChange {
+        ArrayList<String> available;
+        ArrayList<String> active;
+        TetherStateChange(ArrayList<String> av, ArrayList<String> ac) {
+            available = av;
+            active = ac;
+        }
+    }
+
 
     /**
      * One of  {@link WifiManager#WIFI_STATE_DISABLED},
@@ -562,7 +585,9 @@
                 public void onReceive(Context context, Intent intent) {
                     ArrayList<String> available = intent.getStringArrayListExtra(
                             ConnectivityManager.EXTRA_AVAILABLE_TETHER);
-                    sendMessage(CMD_TETHER_INTERFACE, available);
+                    ArrayList<String> active = intent.getStringArrayListExtra(
+                            ConnectivityManager.EXTRA_ACTIVE_TETHER);
+                    sendMessage(CMD_TETHER_STATE_CHANGE, new TetherStateChange(available, active));
                 }
             },new IntentFilter(ConnectivityManager.ACTION_TETHER_STATE_CHANGED));
 
@@ -603,7 +628,9 @@
             addState(mSupplicantStoppingState, mDefaultState);
             addState(mSoftApStartingState, mDefaultState);
             addState(mSoftApStartedState, mDefaultState);
+                addState(mTetheringState, mSoftApStartedState);
                 addState(mTetheredState, mSoftApStartedState);
+            addState(mSoftApStoppingState, mDefaultState);
             addState(mWaitForP2pDisableState, mDefaultState);
 
         setInitialState(mInitialState);
@@ -1032,15 +1059,6 @@
         return result;
     }
 
-    /**
-     * Request a wakelock with connectivity service to
-     * keep the device awake until we hand-off from wifi
-     * to an alternate network
-     */
-    public void requestCmWakeLock() {
-        sendMessage(CMD_REQUEST_CM_WAKELOCK);
-    }
-
     public void updateBatteryWorkSource(WorkSource newSource) {
         synchronized (mRunningWifiUids) {
             try {
@@ -1124,9 +1142,9 @@
                         ifcg = mNwService.getInterfaceConfig(intf);
                         if (ifcg != null) {
                             /* IP/netmask: 192.168.43.1/255.255.255.0 */
-                            ifcg.addr = new LinkAddress(NetworkUtils.numericToInetAddress(
-                                    "192.168.43.1"), 24);
-                            ifcg.interfaceFlags = "[up]";
+                            ifcg.setLinkAddress(new LinkAddress(
+                                    NetworkUtils.numericToInetAddress("192.168.43.1"), 24));
+                            ifcg.setInterfaceUp();
 
                             mNwService.setInterfaceConfig(intf, ifcg);
                         }
@@ -1139,6 +1157,7 @@
                         loge("Error tethering on " + intf);
                         return false;
                     }
+                    mTetherInterfaceName = intf;
                     return true;
                 }
             }
@@ -1157,19 +1176,35 @@
         try {
             ifcg = mNwService.getInterfaceConfig(mInterfaceName);
             if (ifcg != null) {
-                ifcg.addr = new LinkAddress(NetworkUtils.numericToInetAddress(
-                            "0.0.0.0"), 0);
+                ifcg.setLinkAddress(
+                        new LinkAddress(NetworkUtils.numericToInetAddress("0.0.0.0"), 0));
                 mNwService.setInterfaceConfig(mInterfaceName, ifcg);
             }
         } catch (Exception e) {
             loge("Error resetting interface " + mInterfaceName + ", :" + e);
         }
 
-        if (mCm.untether(mInterfaceName) != ConnectivityManager.TETHER_ERROR_NO_ERROR) {
+        if (mCm.untether(mTetherInterfaceName) != ConnectivityManager.TETHER_ERROR_NO_ERROR) {
             loge("Untether initiate failed!");
         }
     }
 
+    private boolean isWifiTethered(ArrayList<String> active) {
+
+        checkAndSetConnectivityInstance();
+
+        String[] wifiRegexs = mCm.getTetherableWifiRegexs();
+        for (String intf : active) {
+            for (String regex : wifiRegexs) {
+                if (intf.matches(regex)) {
+                    return true;
+                }
+            }
+        }
+        // We found no interfaces that are tethered
+        return false;
+    }
+
     /**
      * Set the country code from the system setting value, if any.
      */
@@ -1797,7 +1832,8 @@
                 case CMD_START_AP_SUCCESS:
                 case CMD_START_AP_FAILURE:
                 case CMD_STOP_AP:
-                case CMD_TETHER_INTERFACE:
+                case CMD_TETHER_STATE_CHANGE:
+                case CMD_TETHER_NOTIFICATION_TIMED_OUT:
                 case CMD_START_SCAN:
                 case CMD_DISCONNECT:
                 case CMD_RECONNECT:
@@ -1817,7 +1853,6 @@
                 case CMD_SET_HIGH_PERF_MODE:
                 case CMD_SET_COUNTRY_CODE:
                 case CMD_SET_FREQUENCY_BAND:
-                case CMD_REQUEST_CM_WAKELOCK:
                 case CMD_CONNECT_NETWORK:
                 case CMD_SAVE_NETWORK:
                 case CMD_FORGET_NETWORK:
@@ -2861,8 +2896,8 @@
                 DhcpInfoInternal dhcpInfoInternal = WifiConfigStore.getIpConfiguration(
                         mLastNetworkId);
                 InterfaceConfiguration ifcg = new InterfaceConfiguration();
-                ifcg.addr = dhcpInfoInternal.makeLinkAddress();
-                ifcg.interfaceFlags = "[up]";
+                ifcg.setLinkAddress(dhcpInfoInternal.makeLinkAddress());
+                ifcg.setInterfaceUp();
                 try {
                     mNwService.setInterfaceConfig(mInterfaceName, ifcg);
                     if (DBG) log("Static IP configuration succeeded");
@@ -2974,10 +3009,6 @@
                     WifiNative.disconnectCommand();
                     transitionTo(mDisconnectingState);
                     break;
-                case CMD_REQUEST_CM_WAKELOCK:
-                    checkAndSetConnectivityInstance();
-                    mCm.requestNetworkTransitionWakelock(TAG);
-                    break;
                 case CMD_SET_SCAN_MODE:
                     if (message.arg1 == SCAN_ONLY_MODE) {
                         sendMessage(CMD_DISCONNECT);
@@ -3050,6 +3081,11 @@
         }
         @Override
         public void exit() {
+
+            /* Request a CS wakelock during transition to mobile */
+            checkAndSetConnectivityInstance();
+            mCm.requestNetworkTransitionWakelock(TAG);
+
             /* If a scan result is pending in connected state, the supplicant
              * is in SCAN_ONLY_MODE. Restore CONNECT_MODE on exit
              */
@@ -3281,7 +3317,7 @@
                 case CMD_SET_FREQUENCY_BAND:
                 case CMD_START_PACKET_FILTERING:
                 case CMD_STOP_PACKET_FILTERING:
-                case CMD_TETHER_INTERFACE:
+                case CMD_TETHER_STATE_CHANGE:
                 case WifiP2pService.P2P_ENABLE_PENDING:
                     deferMessage(message);
                     break;
@@ -3323,7 +3359,8 @@
                 case CMD_STOP_AP:
                     if (DBG) log("Stopping Soft AP");
                     setWifiApState(WIFI_AP_STATE_DISABLING);
-                    stopTethering();
+
+                    /* We have not tethered at this point, so we just shutdown soft Ap */
                     try {
                         mNwService.stopAccessPoint(mInterfaceName);
                     } catch(Exception e) {
@@ -3339,10 +3376,10 @@
                    loge("Cannot start supplicant with a running soft AP");
                     setWifiState(WIFI_STATE_UNKNOWN);
                     break;
-                case CMD_TETHER_INTERFACE:
-                    ArrayList<String> available = (ArrayList<String>) message.obj;
-                    if (startTethering(available)) {
-                        transitionTo(mTetheredState);
+                case CMD_TETHER_STATE_CHANGE:
+                    TetherStateChange stateChange = (TetherStateChange) message.obj;
+                    if (startTethering(stateChange.available)) {
+                        transitionTo(mTetheringState);
                     }
                     break;
                 case WifiP2pService.P2P_ENABLE_PENDING:
@@ -3402,6 +3439,58 @@
         }
     }
 
+    class TetheringState extends State {
+        @Override
+        public void enter() {
+            if (DBG) log(getName() + "\n");
+            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
+
+            /* Send ourselves a delayed message to shut down if tethering fails to notify */
+            sendMessageDelayed(obtainMessage(CMD_TETHER_NOTIFICATION_TIMED_OUT,
+                    ++mTetherToken, 0), TETHER_NOTIFICATION_TIME_OUT_MSECS);
+        }
+        @Override
+        public boolean processMessage(Message message) {
+            if (DBG) log(getName() + message.toString() + "\n");
+            switch(message.what) {
+                case CMD_TETHER_STATE_CHANGE:
+                    TetherStateChange stateChange = (TetherStateChange) message.obj;
+                    if (isWifiTethered(stateChange.active)) {
+                        transitionTo(mTetheredState);
+                    }
+                    return HANDLED;
+                case CMD_TETHER_NOTIFICATION_TIMED_OUT:
+                    if (message.arg1 == mTetherToken) {
+                        loge("Failed to get tether update, shutdown soft access point");
+                        setWifiApEnabled(null, false);
+                    }
+                    break;
+                case CMD_LOAD_DRIVER:
+                case CMD_UNLOAD_DRIVER:
+                case CMD_START_SUPPLICANT:
+                case CMD_STOP_SUPPLICANT:
+                case CMD_START_AP:
+                case CMD_STOP_AP:
+                case CMD_START_DRIVER:
+                case CMD_STOP_DRIVER:
+                case CMD_SET_SCAN_MODE:
+                case CMD_SET_SCAN_TYPE:
+                case CMD_SET_HIGH_PERF_MODE:
+                case CMD_SET_COUNTRY_CODE:
+                case CMD_SET_FREQUENCY_BAND:
+                case CMD_START_PACKET_FILTERING:
+                case CMD_STOP_PACKET_FILTERING:
+                case WifiP2pService.P2P_ENABLE_PENDING:
+                    deferMessage(message);
+                    break;
+                default:
+                    return NOT_HANDLED;
+            }
+            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
+            return HANDLED;
+        }
+    }
+
     class TetheredState extends State {
         @Override
         public void enter() {
@@ -3412,13 +3501,89 @@
         public boolean processMessage(Message message) {
             if (DBG) log(getName() + message.toString() + "\n");
             switch(message.what) {
-               case CMD_TETHER_INTERFACE:
-                    // Ignore any duplicate interface available notifications
-                    // when in tethered state
+                case CMD_TETHER_STATE_CHANGE:
+                    TetherStateChange stateChange = (TetherStateChange) message.obj;
+                    if (!isWifiTethered(stateChange.active)) {
+                        loge("Tethering reports wifi as untethered!, shut down soft Ap");
+                        setWifiApEnabled(null, false);
+                    }
                     return HANDLED;
+                case CMD_STOP_AP:
+                    if (DBG) log("Untethering before stopping AP");
+                    setWifiApState(WIFI_AP_STATE_DISABLING);
+                    stopTethering();
+                    transitionTo(mSoftApStoppingState);
+                    break;
                 default:
                     return NOT_HANDLED;
             }
+            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
+            return HANDLED;
+        }
+    }
+
+    class SoftApStoppingState extends State {
+        @Override
+        public void enter() {
+            if (DBG) log(getName() + "\n");
+            EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
+
+            /* Send ourselves a delayed message to shut down if tethering fails to notify */
+            sendMessageDelayed(obtainMessage(CMD_TETHER_NOTIFICATION_TIMED_OUT,
+                    ++mTetherToken, 0), TETHER_NOTIFICATION_TIME_OUT_MSECS);
+
+        }
+        @Override
+        public boolean processMessage(Message message) {
+            if (DBG) log(getName() + message.toString() + "\n");
+            switch(message.what) {
+                case CMD_TETHER_STATE_CHANGE:
+                    TetherStateChange stateChange = (TetherStateChange) message.obj;
+
+                    /* Wait till wifi is untethered */
+                    if (isWifiTethered(stateChange.active)) break;
+
+                    try {
+                        mNwService.stopAccessPoint(mInterfaceName);
+                    } catch(Exception e) {
+                        loge("Exception in stopAccessPoint()");
+                    }
+                    transitionTo(mDriverLoadedState);
+                    break;
+                case CMD_TETHER_NOTIFICATION_TIMED_OUT:
+                    if (message.arg1 == mTetherToken) {
+                        loge("Failed to get tether update, force stop access point");
+                        try {
+                            mNwService.stopAccessPoint(mInterfaceName);
+                        } catch(Exception e) {
+                            loge("Exception in stopAccessPoint()");
+                        }
+                        transitionTo(mDriverLoadedState);
+                    }
+                    break;
+                case CMD_LOAD_DRIVER:
+                case CMD_UNLOAD_DRIVER:
+                case CMD_START_SUPPLICANT:
+                case CMD_STOP_SUPPLICANT:
+                case CMD_START_AP:
+                case CMD_STOP_AP:
+                case CMD_START_DRIVER:
+                case CMD_STOP_DRIVER:
+                case CMD_SET_SCAN_MODE:
+                case CMD_SET_SCAN_TYPE:
+                case CMD_SET_HIGH_PERF_MODE:
+                case CMD_SET_COUNTRY_CODE:
+                case CMD_SET_FREQUENCY_BAND:
+                case CMD_START_PACKET_FILTERING:
+                case CMD_STOP_PACKET_FILTERING:
+                case WifiP2pService.P2P_ENABLE_PENDING:
+                    deferMessage(message);
+                    break;
+                default:
+                    return NOT_HANDLED;
+            }
+            EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
+            return HANDLED;
         }
     }
 
diff --git a/wifi/java/android/net/wifi/WifiWatchdogStateMachine.java b/wifi/java/android/net/wifi/WifiWatchdogStateMachine.java
index f330c32..b27c60f 100644
--- a/wifi/java/android/net/wifi/WifiWatchdogStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiWatchdogStateMachine.java
@@ -150,6 +150,7 @@
     private ConnectedState mConnectedState = new ConnectedState();
     private DnsCheckingState mDnsCheckingState = new DnsCheckingState();
     private OnlineWatchState mOnlineWatchState = new OnlineWatchState();
+    private OnlineState mOnlineState = new OnlineState();
     private DnsCheckFailureState mDnsCheckFailureState = new DnsCheckFailureState();
     private DelayWalledGardenState mDelayWalledGardenState = new DelayWalledGardenState();
     private WalledGardenState mWalledGardenState = new WalledGardenState();
@@ -163,6 +164,7 @@
     private int mMinDnsResponses;
     private int mDnsPingTimeoutMs;
     private long mBlacklistFollowupIntervalMs;
+    private boolean mPoorNetworkDetectionEnabled;
     private boolean mWalledGardenTestEnabled;
     private String mWalledGardenUrl;
 
@@ -226,6 +228,7 @@
                     addState(mWalledGardenState, mConnectedState);
                     addState(mBlacklistedApState, mConnectedState);
                     addState(mOnlineWatchState, mConnectedState);
+                    addState(mOnlineState, mConnectedState);
 
         setInitialState(mWatchdogDisabledState);
         updateSettings();
@@ -411,6 +414,10 @@
         mBlacklistFollowupIntervalMs = Secure.getLong(mContentResolver,
                 Settings.Secure.WIFI_WATCHDOG_BLACKLIST_FOLLOWUP_INTERVAL_MS,
                 DEFAULT_BLACKLIST_FOLLOWUP_INTERVAL_MS);
+        //TODO: enable this by default after changing watchdog behavior
+        //Also, update settings description
+        mPoorNetworkDetectionEnabled = getSettingsBoolean(mContentResolver,
+                Settings.Secure.WIFI_WATCHDOG_POOR_NETWORK_TEST_ENABLED, false);
         mWalledGardenTestEnabled = getSettingsBoolean(mContentResolver,
                 Settings.Secure.WIFI_WATCHDOG_WALLED_GARDEN_TEST_ENABLED, true);
         mWalledGardenUrl = getSettingsStr(mContentResolver,
@@ -623,9 +630,13 @@
 
                             initConnection(wifiInfo);
                             mConnectionInfo = wifiInfo;
-                            updateBssids();
-                            transitionTo(mDnsCheckingState);
                             mNetEventCounter++;
+                            if (mPoorNetworkDetectionEnabled) {
+                                updateBssids();
+                                transitionTo(mDnsCheckingState);
+                            } else {
+                                transitionTo(mDelayWalledGardenState);
+                            }
                             break;
                         default:
                             mNetEventCounter++;
@@ -677,12 +688,18 @@
         public boolean processMessage(Message msg) {
             switch (msg.what) {
                 case EVENT_SCAN_RESULTS_AVAILABLE:
-                    updateBssids();
+                    if (mPoorNetworkDetectionEnabled) {
+                        updateBssids();
+                    }
                     return HANDLED;
                 case EVENT_WATCHDOG_SETTINGS_CHANGE:
-                    // Stop current checks, but let state update
-                    transitionTo(mOnlineWatchState);
-                    return NOT_HANDLED;
+                    updateSettings();
+                    if (mPoorNetworkDetectionEnabled) {
+                        transitionTo(mOnlineWatchState);
+                    } else {
+                        transitionTo(mOnlineState);
+                    }
+                    return HANDLED;
             }
             return NOT_HANDLED;
         }
@@ -829,7 +846,11 @@
                         transitionTo(mWalledGardenState);
                     } else {
                         if (DBG) log("Walled garden test complete - online");
-                        transitionTo(mOnlineWatchState);
+                        if (mPoorNetworkDetectionEnabled) {
+                            transitionTo(mOnlineWatchState);
+                        } else {
+                            transitionTo(mOnlineState);
+                        }
                     }
                     return HANDLED;
                 default:
@@ -961,6 +982,13 @@
         }
     }
 
+
+    /* Child state of ConnectedState indicating that we are online
+     * and there is nothing to do
+     */
+    class OnlineState extends State {
+    }
+
     class DnsCheckFailureState extends State {
 
         @Override
@@ -1037,7 +1065,11 @@
                 return HANDLED;
             }
             setWalledGardenNotificationVisible(true);
-            transitionTo(mOnlineWatchState);
+            if (mPoorNetworkDetectionEnabled) {
+                transitionTo(mOnlineWatchState);
+            } else {
+                transitionTo(mOnlineState);
+            }
             return HANDLED;
         }
     }
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java b/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java
index e0c1b13..6aea090 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java
@@ -84,19 +84,19 @@
             } catch (NumberFormatException e) {
                 devPasswdId = 0;
             }
-            //As defined in wps/wps_defs.h
+            //Based on definitions in wps/wps_defs.h
             switch (devPasswdId) {
-                case 0x00:
-                    wps.setup = WpsInfo.LABEL;
-                    break;
+                //DEV_PW_USER_SPECIFIED = 0x0001,
                 case 0x01:
-                    wps.setup = WpsInfo.KEYPAD;
+                    wps.setup = WpsInfo.DISPLAY;
                     break;
+                //DEV_PW_PUSHBUTTON = 0x0004,
                 case 0x04:
                     wps.setup = WpsInfo.PBC;
                     break;
+                //DEV_PW_REGISTRAR_SPECIFIED = 0x0005
                 case 0x05:
-                    wps.setup = WpsInfo.DISPLAY;
+                    wps.setup = WpsInfo.KEYPAD;
                     break;
                 default:
                     wps.setup = WpsInfo.PBC;
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pDevice.java b/wifi/java/android/net/wifi/p2p/WifiP2pDevice.java
index 1b0c301..b47e098 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pDevice.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pDevice.java
@@ -130,18 +130,6 @@
      *
      *  fa:7b:7a:42:02:13
      *
-     *  P2P-PROV-DISC-PBC-REQ 42:fc:89:e1:e2:27 p2p_dev_addr=42:fc:89:e1:e2:27
-     *  pri_dev_type=1-0050F204-1 name='p2p-TEST2' config_methods=0x188 dev_capab=0x27
-     *  group_capab=0x0
-     *
-     *  P2P-PROV-DISC-ENTER-PIN 42:fc:89:e1:e2:27 p2p_dev_addr=42:fc:89:e1:e2:27
-     *  pri_dev_type=1-0050F204-1 name='p2p-TEST2' config_methods=0x188 dev_capab=0x27
-     *  group_capab=0x0
-     *
-     *  P2P-PROV-DISC-SHOW-PIN 42:fc:89:e1:e2:27 44490607 p2p_dev_addr=42:fc:89:e1:e2:27
-     *  pri_dev_type=1-0050F204-1 name='p2p-TEST2' config_methods=0x188 dev_capab=0x27
-     *  group_capab=0x0
-     *
      *  Note: The events formats can be looked up in the wpa_supplicant code
      * @hide
      */
@@ -160,7 +148,13 @@
 
         for (String token : tokens) {
             String[] nameValue = token.split("=");
-            if (nameValue.length != 2) continue;
+            if (nameValue.length != 2) {
+                //mac address without key is device address
+                if (token.matches("(([0-9a-f]{2}:){5}[0-9a-f]{2})")) {
+                    deviceAddress = token;
+                }
+                continue;
+            }
 
             if (nameValue[0].equals("p2p_dev_addr")) {
                 deviceAddress = nameValue[1];
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pGroup.java b/wifi/java/android/net/wifi/p2p/WifiP2pGroup.java
index 9473993..e141aba 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pGroup.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pGroup.java
@@ -172,6 +172,12 @@
         return mClients.size() == 0;
     }
 
+    /** @hide Returns {@code true} if the device is part of the group */
+    public boolean contains(WifiP2pDevice device) {
+        if (mOwner.equals(device) || mClients.contains(device)) return true;
+        return false;
+    }
+
     /** Get the list of clients currently part of the p2p group */
     public Collection<WifiP2pDevice> getClientList() {
         return Collections.unmodifiableCollection(mClients);
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pProvDiscEvent.java b/wifi/java/android/net/wifi/p2p/WifiP2pProvDiscEvent.java
new file mode 100644
index 0000000..f70abe8
--- /dev/null
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pProvDiscEvent.java
@@ -0,0 +1,161 @@
+/*
+ * 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.net.wifi.p2p;
+
+import android.os.Parcelable;
+import android.os.Parcel;
+import android.util.Log;
+
+/**
+ * A class representing a Wi-Fi p2p provisional discovery request/response
+ * See {@link #WifiP2pProvDiscEvent} for supported types
+ *
+ * @hide
+ */
+public class WifiP2pProvDiscEvent {
+
+    private static final String TAG = "WifiP2pProvDiscEvent";
+
+    public static final int PBC_REQ     = 1;
+    public static final int PBC_RSP     = 2;
+    public static final int ENTER_PIN   = 3;
+    public static final int SHOW_PIN    = 4;
+
+    /* One of PBC_REQ, PBC_RSP, ENTER_PIN or SHOW_PIN */
+    public int event;
+
+    public WifiP2pDevice device;
+
+    /* Valid when event = SHOW_PIN */
+    public String pin;
+
+    public WifiP2pProvDiscEvent() {
+        device = new WifiP2pDevice();
+    }
+
+    /**
+     * @param string formats supported include
+     *
+     *  P2P-PROV-DISC-PBC-REQ 42:fc:89:e1:e2:27 p2p_dev_addr=42:fc:89:e1:e2:27
+     *  pri_dev_type=1-0050F204-1 name='p2p-TEST2' config_methods=0x188 dev_capab=0x27
+     *  group_capab=0x0
+     *
+     *  P2P-PROV-DISC-PBC-RESP 02:12:47:f2:5a:36
+     *
+     *  P2P-PROV-DISC-ENTER-PIN 42:fc:89:e1:e2:27 p2p_dev_addr=42:fc:89:e1:e2:27
+     *  pri_dev_type=1-0050F204-1 name='p2p-TEST2' config_methods=0x188 dev_capab=0x27
+     *  group_capab=0x0
+     *
+     *  P2P-PROV-DISC-SHOW-PIN 42:fc:89:e1:e2:27 44490607 p2p_dev_addr=42:fc:89:e1:e2:27
+     *  pri_dev_type=1-0050F204-1 name='p2p-TEST2' config_methods=0x188 dev_capab=0x27
+     *  group_capab=0x0
+     *
+     *  Note: The events formats can be looked up in the wpa_supplicant code
+     * @hide
+     */
+    public WifiP2pProvDiscEvent(String string) throws IllegalArgumentException {
+        String[] tokens = string.split(" ");
+
+        if (tokens.length < 2) {
+            throw new IllegalArgumentException("Malformed event " + string);
+        }
+
+        if (tokens[0].endsWith("PBC-REQ")) event = PBC_REQ;
+        else if (tokens[0].endsWith("PBC-RESP")) event = PBC_RSP;
+        else if (tokens[0].endsWith("ENTER-PIN")) event = ENTER_PIN;
+        else if (tokens[0].endsWith("SHOW-PIN")) event = SHOW_PIN;
+        else throw new IllegalArgumentException("Malformed event " + string);
+
+        device = new WifiP2pDevice();
+
+        for (String token : tokens) {
+            String[] nameValue = token.split("=");
+            if (nameValue.length != 2) {
+                //mac address without key is device address
+                if (token.matches("(([0-9a-f]{2}:){5}[0-9a-f]{2})")) {
+                    device.deviceAddress = token;
+                } else if (token.matches("[0-9]+")) {
+                    pin = token;
+                } else {
+                    //ignore;
+                }
+                continue;
+            }
+
+            if (nameValue[0].equals("p2p_dev_addr")) {
+                device.deviceAddress = nameValue[1];
+                continue;
+            }
+
+            if (nameValue[0].equals("pri_dev_type")) {
+                device.primaryDeviceType = nameValue[1];
+                continue;
+            }
+
+            if (nameValue[0].equals("name")) {
+                device.deviceName = trimQuotes(nameValue[1]);
+                continue;
+            }
+
+            if (nameValue[0].equals("config_methods")) {
+                device.wpsConfigMethodsSupported = parseHex(nameValue[1]);
+                continue;
+            }
+
+            if (nameValue[0].equals("dev_capab")) {
+                device.deviceCapability = parseHex(nameValue[1]);
+                continue;
+            }
+
+            if (nameValue[0].equals("group_capab")) {
+                device.groupCapability = parseHex(nameValue[1]);
+                continue;
+            }
+        }
+    }
+
+    public String toString() {
+        StringBuffer sbuf = new StringBuffer();
+        sbuf.append(device);
+        sbuf.append("\n event: ").append(event);
+        sbuf.append("\n pin: ").append(pin);
+        return sbuf.toString();
+    }
+
+    private String trimQuotes(String str) {
+        str = str.trim();
+        if (str.startsWith("'") && str.endsWith("'")) {
+            return str.substring(1, str.length()-1);
+        }
+        return str;
+    }
+
+    //supported formats: 0x1abc, 0X1abc, 1abc
+    private int parseHex(String hexString) {
+        int num = 0;
+        if (hexString.startsWith("0x") || hexString.startsWith("0X")) {
+            hexString = hexString.substring(2);
+        }
+
+        try {
+            num = Integer.parseInt(hexString, 16);
+        } catch(NumberFormatException e) {
+            Log.e(TAG, "Failed to parse hex string " + hexString);
+        }
+        return num;
+    }
+}
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pService.java b/wifi/java/android/net/wifi/p2p/WifiP2pService.java
index 6bb22a4..dede1b5 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pService.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pService.java
@@ -52,11 +52,14 @@
 import android.os.ServiceManager;
 import android.os.SystemProperties;
 import android.provider.Settings;
+import android.text.TextUtils;
 import android.util.Slog;
 import android.view.LayoutInflater;
 import android.view.View;
+import android.view.ViewGroup;
 import android.view.WindowManager;
 import android.widget.EditText;
+import android.widget.TextView;
 
 import com.android.internal.R;
 import com.android.internal.telephony.TelephonyIntents;
@@ -81,7 +84,7 @@
  */
 public class WifiP2pService extends IWifiP2pManager.Stub {
     private static final String TAG = "WifiP2pService";
-    private static final boolean DBG = false;
+    private static final boolean DBG = true;
     private static final String NETWORKTYPE = "WIFI_P2P";
 
     private Context mContext;
@@ -100,9 +103,12 @@
     private AsyncChannel mReplyChannel = new AsyncChannel();
     private AsyncChannel mWifiChannel;
 
+    private static final Boolean JOIN_GROUP = true;
+    private static final Boolean FORM_GROUP = false;
+
     /* Two minutes comes from the wpa_supplicant setting */
-    private static final int GROUP_NEGOTIATION_WAIT_TIME_MS = 120 * 1000;
-    private static int mGroupNegotiationTimeoutIndex = 0;
+    private static final int GROUP_CREATING_WAIT_TIME_MS = 120 * 1000;
+    private static int mGroupCreatingTimeoutIndex = 0;
 
     /**
      * Delay between restarts upon failure to setup connection with supplicant
@@ -123,30 +129,23 @@
     /* Message sent to WifiStateMachine to indicate Wi-Fi client/hotspot operation can proceed */
     public static final int WIFI_ENABLE_PROCEED             =   BASE + 2;
 
-    /* Delayed message to timeout of group negotiation */
-    public static final int GROUP_NEGOTIATION_TIMED_OUT     =   BASE + 3;
+    /* Delayed message to timeout group creation */
+    public static final int GROUP_CREATING_TIMED_OUT        =   BASE + 3;
 
     /* User accepted to disable Wi-Fi in order to enable p2p */
     private static final int WIFI_DISABLE_USER_ACCEPT       =   BASE + 4;
     /* User rejected to disable Wi-Fi in order to enable p2p */
     private static final int WIFI_DISABLE_USER_REJECT       =   BASE + 5;
 
-    /* User accepted a group negotiation request */
-    private static final int GROUP_NEGOTIATION_USER_ACCEPT  =   BASE + 6;
-    /* User rejected a group negotiation request */
-    private static final int GROUP_NEGOTIATION_USER_REJECT  =   BASE + 7;
-
-    /* User accepted a group invitation request */
-    private static final int GROUP_INVITATION_USER_ACCEPT   =   BASE + 8;
-    /* User rejected a group invitation request */
-    private static final int GROUP_INVITATION_USER_REJECT   =   BASE + 9;
+    /* User accepted a peer request */
+    private static final int PEER_CONNECTION_USER_ACCEPT    =   BASE + 6;
+    /* User rejected a peer request */
+    private static final int PEER_CONNECTION_USER_REJECT    =   BASE + 7;
 
     /* Airplane mode changed */
-    private static final int AIRPLANE_MODE_CHANGED          =   BASE + 10;
+    private static final int AIRPLANE_MODE_CHANGED          =   BASE + 8;
     /* Emergency callback mode */
-    private static final int EMERGENCY_CALLBACK_MODE        =   BASE + 11;
-    private static final int WPS_PBC                        =   BASE + 12;
-    private static final int WPS_PIN                        =   BASE + 13;
+    private static final int EMERGENCY_CALLBACK_MODE        =   BASE + 9;
 
     private final boolean mP2pSupported;
 
@@ -270,12 +269,14 @@
         private P2pEnabledState mP2pEnabledState = new P2pEnabledState();
         // Inactive is when p2p is enabled with no connectivity
         private InactiveState mInactiveState = new InactiveState();
-        private UserAuthorizingGroupNegotiationState mUserAuthorizingGroupNegotiationState
-                = new UserAuthorizingGroupNegotiationState();
-        private UserAuthorizingGroupInvitationState mUserAuthorizingGroupInvitationState
-                = new UserAuthorizingGroupInvitationState();
+        private GroupCreatingState mGroupCreatingState = new GroupCreatingState();
+        private UserAuthorizingInvitationState mUserAuthorizingInvitationState
+                = new UserAuthorizingInvitationState();
+        private ProvisionDiscoveryState mProvisionDiscoveryState = new ProvisionDiscoveryState();
         private GroupNegotiationState mGroupNegotiationState = new GroupNegotiationState();
+
         private GroupCreatedState mGroupCreatedState = new GroupCreatedState();
+        private UserAuthorizingJoinState mUserAuthorizingJoinState = new UserAuthorizingJoinState();
 
         private WifiMonitor mWifiMonitor = new WifiMonitor(this);
 
@@ -283,11 +284,8 @@
         private WifiP2pInfo mWifiP2pInfo = new WifiP2pInfo();
         private WifiP2pGroup mGroup;
 
-        // Saved WifiP2pConfig from GO negotiation request
-        private WifiP2pConfig mSavedGoNegotiationConfig;
-
-        // Saved WifiP2pConfig from connect request
-        private WifiP2pConfig mSavedConnectConfig;
+        // Saved WifiP2pConfig for a peer connection
+        private WifiP2pConfig mSavedPeerConfig;
 
         // Saved WifiP2pGroup from invitation request
         private WifiP2pGroup mSavedP2pGroup;
@@ -304,10 +302,12 @@
                 addState(mP2pEnablingState, mDefaultState);
                 addState(mP2pEnabledState, mDefaultState);
                     addState(mInactiveState, mP2pEnabledState);
-                        addState(mUserAuthorizingGroupNegotiationState, mInactiveState);
-                        addState(mUserAuthorizingGroupInvitationState, mInactiveState);
-                    addState(mGroupNegotiationState, mP2pEnabledState);
+                    addState(mGroupCreatingState, mP2pEnabledState);
+                        addState(mUserAuthorizingInvitationState, mGroupCreatingState);
+                        addState(mProvisionDiscoveryState, mGroupCreatingState);
+                        addState(mGroupNegotiationState, mGroupCreatingState);
                     addState(mGroupCreatedState, mP2pEnabledState);
+                        addState(mUserAuthorizingJoinState, mGroupCreatedState);
 
             if (p2pSupported) {
                 setInitialState(mP2pDisabledState);
@@ -393,13 +393,12 @@
                     sendMessage(WifiP2pManager.DISABLE_P2P);
                     break;
                     // Ignore
+                case WifiMonitor.P2P_INVITATION_RESULT_EVENT:
                 case WIFI_DISABLE_USER_ACCEPT:
                 case WIFI_DISABLE_USER_REJECT:
-                case GROUP_NEGOTIATION_USER_ACCEPT:
-                case GROUP_NEGOTIATION_USER_REJECT:
-                case GROUP_INVITATION_USER_ACCEPT:
-                case GROUP_INVITATION_USER_REJECT:
-                case GROUP_NEGOTIATION_TIMED_OUT:
+                case PEER_CONNECTION_USER_ACCEPT:
+                case PEER_CONNECTION_USER_REJECT:
+                case GROUP_CREATING_TIMED_OUT:
                     break;
                 default:
                     loge("Unhandled message " + message);
@@ -691,31 +690,7 @@
                     device = (WifiP2pDevice) message.obj;
                     if (mPeers.remove(device)) sendP2pPeersChangedBroadcast();
                     break;
-                case WifiP2pManager.CONNECT:
-                    if (DBG) logd(getName() + " sending connect");
-                    mSavedConnectConfig = (WifiP2pConfig) message.obj;
-                    mPersistGroup = false;
-                    int netId = configuredNetworkId(mSavedConnectConfig.deviceAddress);
-                    if (netId >= 0) {
-                        //TODO: if failure, remove config and do a regular p2pConnect()
-                        WifiNative.p2pReinvoke(netId, mSavedConnectConfig.deviceAddress);
-                    } else {
-                        boolean join = false;
-                        if (isGroupOwner(mSavedConnectConfig.deviceAddress)) join = true;
-                        String pin = WifiNative.p2pConnect(mSavedConnectConfig, join);
-                        try {
-                            Integer.parseInt(pin);
-                            notifyWpsPin(pin, mSavedConnectConfig.deviceAddress);
-                        } catch (NumberFormatException ignore) {
-                            // do nothing if p2pConnect did not return a pin
-                        }
-                    }
-                    updateDeviceStatus(mSavedConnectConfig.deviceAddress, WifiP2pDevice.INVITED);
-                    sendP2pPeersChangedBroadcast();
-                    replyToMessage(message, WifiP2pManager.CONNECT_SUCCEEDED);
-                    transitionTo(mGroupNegotiationState);
-                    break;
-                case WifiMonitor.SUP_DISCONNECTION_EVENT:  /* Supplicant died */
+               case WifiMonitor.SUP_DISCONNECTION_EVENT:  /* Supplicant died */
                     loge("Connection lost, restart p2p");
                     WifiNative.killSupplicant();
                     WifiNative.closeSupplicantConnection();
@@ -723,21 +698,6 @@
                     transitionTo(mP2pDisabledState);
                     sendMessageDelayed(WifiP2pManager.ENABLE_P2P, P2P_RESTART_INTERVAL_MSECS);
                     break;
-                case WifiMonitor.P2P_GROUP_STARTED_EVENT:
-                    mGroup = (WifiP2pGroup) message.obj;
-                    if (DBG) logd(getName() + " group started");
-                    if (mGroup.isGroupOwner()) {
-                        startDhcpServer(mGroup.getInterface());
-                    } else {
-                        mDhcpStateMachine = DhcpStateMachine.makeDhcpStateMachine(mContext,
-                                P2pStateMachine.this, mGroup.getInterface());
-                        mDhcpStateMachine.sendMessage(DhcpStateMachine.CMD_START_DHCP);
-                        WifiP2pDevice groupOwner = mGroup.getOwner();
-                        updateDeviceStatus(groupOwner.deviceAddress, WifiP2pDevice.CONNECTED);
-                        sendP2pPeersChangedBroadcast();
-                    }
-                    transitionTo(mGroupCreatedState);
-                    break;
                 default:
                     return NOT_HANDLED;
             }
@@ -764,10 +724,62 @@
         public boolean processMessage(Message message) {
             if (DBG) logd(getName() + message.toString());
             switch (message.what) {
+                case WifiP2pManager.CONNECT:
+                    if (DBG) logd(getName() + " sending connect");
+                    mSavedPeerConfig = (WifiP2pConfig) message.obj;
+                    mPersistGroup = false;
+                    int netId = configuredNetworkId(mSavedPeerConfig.deviceAddress);
+                    if (netId >= 0) {
+                        //TODO: if failure, remove config and do a regular p2pConnect()
+                        WifiNative.p2pReinvoke(netId, mSavedPeerConfig.deviceAddress);
+                    } else {
+                        //If peer is a GO, we do not need to send provisional discovery,
+                        //the supplicant takes care of it.
+                        if (isGroupOwner(mSavedPeerConfig.deviceAddress)) {
+                            String pin = WifiNative.p2pConnect(mSavedPeerConfig, JOIN_GROUP);
+                            try {
+                                Integer.parseInt(pin);
+                                notifyInvitationSent(pin, mSavedPeerConfig.deviceAddress);
+                            } catch (NumberFormatException ignore) {
+                                // do nothing if p2pConnect did not return a pin
+                            }
+                            transitionTo(mGroupNegotiationState);
+                        } else {
+                            transitionTo(mProvisionDiscoveryState);
+                        }
+                    }
+                    updateDeviceStatus(mSavedPeerConfig.deviceAddress, WifiP2pDevice.INVITED);
+                    sendP2pPeersChangedBroadcast();
+                    replyToMessage(message, WifiP2pManager.CONNECT_SUCCEEDED);
+                    break;
                 case WifiMonitor.P2P_GO_NEGOTIATION_REQUEST_EVENT:
-                    mSavedGoNegotiationConfig = (WifiP2pConfig) message.obj;
-                    notifyP2pGoNegotationRequest(mSavedGoNegotiationConfig);
-                    transitionTo(mUserAuthorizingGroupNegotiationState);
+                    mSavedPeerConfig = (WifiP2pConfig) message.obj;
+                    transitionTo(mUserAuthorizingInvitationState);
+                    break;
+                case WifiMonitor.P2P_INVITATION_RECEIVED_EVENT:
+                    WifiP2pGroup group = (WifiP2pGroup) message.obj;
+                    //TODO: fix p2p invitation to handle as a regular config
+                    //and update mSavedPeerConfig
+                    transitionTo(mUserAuthorizingInvitationState);
+                    break;
+                case WifiMonitor.P2P_PROV_DISC_PBC_REQ_EVENT:
+                case WifiMonitor.P2P_PROV_DISC_ENTER_PIN_EVENT:
+                case WifiMonitor.P2P_PROV_DISC_SHOW_PIN_EVENT:
+                    WifiP2pProvDiscEvent provDisc = (WifiP2pProvDiscEvent) message.obj;
+                    mSavedPeerConfig = new WifiP2pConfig();
+                    mSavedPeerConfig.deviceAddress = provDisc.device.deviceAddress;
+                    if (message.what == WifiMonitor.P2P_PROV_DISC_ENTER_PIN_EVENT) {
+                        mSavedPeerConfig.wps.setup = WpsInfo.KEYPAD;
+                        if (DBG) logd("Keypad prov disc request");
+                    } else if (message.what == WifiMonitor.P2P_PROV_DISC_SHOW_PIN_EVENT) {
+                        mSavedPeerConfig.wps.setup = WpsInfo.DISPLAY;
+                        mSavedPeerConfig.wps.pin = provDisc.pin;
+                        if (DBG) logd("Display prov disc request");
+                    } else {
+                        mSavedPeerConfig.wps.setup = WpsInfo.PBC;
+                        if (DBG) logd("PBC prov disc request");
+                    }
+                    transitionTo(mUserAuthorizingInvitationState);
                     break;
                 case WifiP2pManager.CREATE_GROUP:
                     mPersistGroup = true;
@@ -779,113 +791,30 @@
                     }
                     transitionTo(mGroupNegotiationState);
                     break;
-                case WifiMonitor.P2P_INVITATION_RECEIVED_EVENT:
-                    WifiP2pGroup group = (WifiP2pGroup) message.obj;
-                    notifyP2pInvitationReceived(group);
-                    transitionTo(mUserAuthorizingGroupInvitationState);
-                    break;
-                default:
+               default:
                     return NOT_HANDLED;
             }
             return HANDLED;
         }
     }
 
-    class UserAuthorizingGroupNegotiationState extends State {
+    class GroupCreatingState extends State {
         @Override
         public void enter() {
             if (DBG) logd(getName());
+            sendMessageDelayed(obtainMessage(GROUP_CREATING_TIMED_OUT,
+                    ++mGroupCreatingTimeoutIndex, 0), GROUP_CREATING_WAIT_TIME_MS);
         }
 
         @Override
         public boolean processMessage(Message message) {
             if (DBG) logd(getName() + message.toString());
             switch (message.what) {
-                case WifiMonitor.P2P_GO_NEGOTIATION_REQUEST_EVENT:
-                case WifiMonitor.P2P_INVITATION_RECEIVED_EVENT:
-                    //Ignore additional connection requests
-                    break;
-                case GROUP_NEGOTIATION_USER_ACCEPT:
-                    sendMessage(WifiP2pManager.CONNECT, mSavedGoNegotiationConfig);
-                    mSavedGoNegotiationConfig = null;
-                    break;
-                case GROUP_NEGOTIATION_USER_REJECT:
-                    if (DBG) logd("User rejected incoming negotiation request");
-                    mSavedGoNegotiationConfig = null;
-                    transitionTo(mInactiveState);
-                    break;
-                default:
-                    return NOT_HANDLED;
-            }
-            return HANDLED;
-        }
-    }
-
-    class UserAuthorizingGroupInvitationState extends State {
-        @Override
-        public void enter() {
-            if (DBG) logd(getName());
-        }
-
-        @Override
-        public boolean processMessage(Message message) {
-            if (DBG) logd(getName() + message.toString());
-            switch (message.what) {
-                case WifiMonitor.P2P_GO_NEGOTIATION_REQUEST_EVENT:
-                case WifiMonitor.P2P_INVITATION_RECEIVED_EVENT:
-                    //Ignore additional connection requests
-                    break;
-                case GROUP_INVITATION_USER_ACCEPT:
-                    if (DBG) logd(getName() + " connect to invited group");
-                    WifiP2pConfig config = new WifiP2pConfig();
-                    config.deviceAddress = mSavedP2pGroup.getOwner().deviceAddress;
-                    sendMessage(WifiP2pManager.CONNECT, config);
-                    mSavedP2pGroup = null;
-                    break;
-                case GROUP_INVITATION_USER_REJECT:
-                    if (DBG) logd("User rejected incoming invitation request");
-                    mSavedP2pGroup = null;
-                    transitionTo(mInactiveState);
-                    break;
-                default:
-                    return NOT_HANDLED;
-            }
-            return HANDLED;
-        }
-    }
-
-
-    class GroupNegotiationState extends State {
-        @Override
-        public void enter() {
-            if (DBG) logd(getName());
-            sendMessageDelayed(obtainMessage(GROUP_NEGOTIATION_TIMED_OUT,
-                    ++mGroupNegotiationTimeoutIndex, 0), GROUP_NEGOTIATION_WAIT_TIME_MS);
-        }
-
-        @Override
-        public boolean processMessage(Message message) {
-            if (DBG) logd(getName() + message.toString());
-            switch (message.what) {
-                // We ignore these right now, since we get a GROUP_STARTED notification
-                // afterwards
-                case WifiMonitor.P2P_GO_NEGOTIATION_SUCCESS_EVENT:
-                case WifiMonitor.P2P_GROUP_FORMATION_SUCCESS_EVENT:
-                    if (DBG) logd(getName() + " go success");
-                    break;
-                case WifiMonitor.P2P_GO_NEGOTIATION_FAILURE_EVENT:
-                case WifiMonitor.P2P_GROUP_FORMATION_FAILURE_EVENT:
-                    if (DBG) logd(getName() + " go failure");
-                    updateDeviceStatus(mSavedConnectConfig.deviceAddress, WifiP2pDevice.FAILED);
-                    mSavedConnectConfig = null;
-                    sendP2pPeersChangedBroadcast();
-                    transitionTo(mInactiveState);
-                    break;
-                case GROUP_NEGOTIATION_TIMED_OUT:
-                    if (mGroupNegotiationTimeoutIndex == message.arg1) {
+               case GROUP_CREATING_TIMED_OUT:
+                    if (mGroupCreatingTimeoutIndex == message.arg1) {
                         if (DBG) logd("Group negotiation timed out");
-                        updateDeviceStatus(mSavedConnectConfig.deviceAddress, WifiP2pDevice.FAILED);
-                        mSavedConnectConfig = null;
+                        updateDeviceStatus(mSavedPeerConfig.deviceAddress, WifiP2pDevice.FAILED);
+                        mSavedPeerConfig = null;
                         sendP2pPeersChangedBroadcast();
                         transitionTo(mInactiveState);
                     }
@@ -910,6 +839,154 @@
         }
     }
 
+    class UserAuthorizingInvitationState extends State {
+        @Override
+        public void enter() {
+            if (DBG) logd(getName());
+            notifyInvitationReceived();
+        }
+
+        @Override
+        public boolean processMessage(Message message) {
+            if (DBG) logd(getName() + message.toString());
+            switch (message.what) {
+                case PEER_CONNECTION_USER_ACCEPT:
+                    //TODO: handle persistence
+                    if (isGroupOwner(mSavedPeerConfig.deviceAddress)) {
+                        WifiNative.p2pConnect(mSavedPeerConfig, JOIN_GROUP);
+                    } else {
+                        WifiNative.p2pConnect(mSavedPeerConfig, FORM_GROUP);
+                    }
+                    updateDeviceStatus(mSavedPeerConfig.deviceAddress, WifiP2pDevice.INVITED);
+                    sendP2pPeersChangedBroadcast();
+                    transitionTo(mGroupNegotiationState);
+                    break;
+                case PEER_CONNECTION_USER_REJECT:
+                    if (DBG) logd("User rejected invitation " + mSavedPeerConfig);
+                    mSavedPeerConfig = null;
+                    transitionTo(mInactiveState);
+                    break;
+                default:
+                    return NOT_HANDLED;
+            }
+            return HANDLED;
+        }
+
+        @Override
+        public void exit() {
+            //TODO: dismiss dialog if not already done
+        }
+    }
+
+    class ProvisionDiscoveryState extends State {
+        @Override
+        public void enter() {
+            if (DBG) logd(getName());
+            WifiNative.p2pProvisionDiscovery(mSavedPeerConfig);
+        }
+
+        @Override
+        public boolean processMessage(Message message) {
+            if (DBG) logd(getName() + message.toString());
+            WifiP2pProvDiscEvent provDisc;
+            WifiP2pDevice device;
+            switch (message.what) {
+                case WifiMonitor.P2P_PROV_DISC_PBC_RSP_EVENT:
+                    provDisc = (WifiP2pProvDiscEvent) message.obj;
+                    device = provDisc.device;
+                    if (!device.deviceAddress.equals(mSavedPeerConfig.deviceAddress)) break;
+
+                    if (mSavedPeerConfig.wps.setup == WpsInfo.PBC) {
+                        if (DBG) logd("Found a match " + mSavedPeerConfig);
+                        WifiNative.p2pConnect(mSavedPeerConfig, FORM_GROUP);
+                        transitionTo(mGroupNegotiationState);
+                    }
+                    break;
+                case WifiMonitor.P2P_PROV_DISC_ENTER_PIN_EVENT:
+                    provDisc = (WifiP2pProvDiscEvent) message.obj;
+                    device = provDisc.device;
+                    if (!device.deviceAddress.equals(mSavedPeerConfig.deviceAddress)) break;
+
+                    if (mSavedPeerConfig.wps.setup == WpsInfo.KEYPAD) {
+                        if (DBG) logd("Found a match " + mSavedPeerConfig);
+                        /* we already have the pin */
+                        if (!TextUtils.isEmpty(mSavedPeerConfig.wps.pin)) {
+                            WifiNative.p2pConnect(mSavedPeerConfig, FORM_GROUP);
+                            transitionTo(mGroupNegotiationState);
+                        } else {
+                            transitionTo(mUserAuthorizingInvitationState);
+                        }
+                    }
+                    break;
+                case WifiMonitor.P2P_PROV_DISC_SHOW_PIN_EVENT:
+                    provDisc = (WifiP2pProvDiscEvent) message.obj;
+                    device = provDisc.device;
+                    if (!device.deviceAddress.equals(mSavedPeerConfig.deviceAddress)) break;
+
+                    if (mSavedPeerConfig.wps.setup == WpsInfo.DISPLAY) {
+                        if (DBG) logd("Found a match " + mSavedPeerConfig);
+                        mSavedPeerConfig.wps.pin = provDisc.pin;
+                        WifiNative.p2pConnect(mSavedPeerConfig, FORM_GROUP);
+                        notifyInvitationSent(provDisc.pin, device.deviceAddress);
+                        transitionTo(mGroupNegotiationState);
+                    }
+                    break;
+                default:
+                    return NOT_HANDLED;
+            }
+            return HANDLED;
+        }
+    }
+
+    class GroupNegotiationState extends State {
+        @Override
+        public void enter() {
+            if (DBG) logd(getName());
+        }
+
+        @Override
+        public boolean processMessage(Message message) {
+            if (DBG) logd(getName() + message.toString());
+            switch (message.what) {
+                // We ignore these right now, since we get a GROUP_STARTED notification
+                // afterwards
+                case WifiMonitor.P2P_GO_NEGOTIATION_SUCCESS_EVENT:
+                case WifiMonitor.P2P_GROUP_FORMATION_SUCCESS_EVENT:
+                    if (DBG) logd(getName() + " go success");
+                    break;
+                case WifiMonitor.P2P_GROUP_STARTED_EVENT:
+                    mGroup = (WifiP2pGroup) message.obj;
+                    if (DBG) logd(getName() + " group started");
+                    if (mGroup.isGroupOwner()) {
+                        startDhcpServer(mGroup.getInterface());
+                    } else {
+                        mDhcpStateMachine = DhcpStateMachine.makeDhcpStateMachine(mContext,
+                                P2pStateMachine.this, mGroup.getInterface());
+                        mDhcpStateMachine.sendMessage(DhcpStateMachine.CMD_START_DHCP);
+                        WifiP2pDevice groupOwner = mGroup.getOwner();
+                        updateDeviceStatus(groupOwner.deviceAddress, WifiP2pDevice.CONNECTED);
+                        sendP2pPeersChangedBroadcast();
+                    }
+                    mSavedPeerConfig = null;
+                    transitionTo(mGroupCreatedState);
+                    break;
+                case WifiMonitor.P2P_GO_NEGOTIATION_FAILURE_EVENT:
+                case WifiMonitor.P2P_GROUP_FORMATION_FAILURE_EVENT:
+                    if (DBG) logd(getName() + " go failure");
+                    updateDeviceStatus(mSavedPeerConfig.deviceAddress, WifiP2pDevice.FAILED);
+                    mSavedPeerConfig = null;
+                    sendP2pPeersChangedBroadcast();
+                    transitionTo(mInactiveState);
+                    break;
+                default:
+                    return NOT_HANDLED;
+            }
+            return HANDLED;
+        }
+    }
+
+
+
     class GroupCreatedState extends State {
         @Override
         public void enter() {
@@ -1011,16 +1088,13 @@
                     break;
                 case WifiMonitor.P2P_DEVICE_LOST_EVENT:
                     WifiP2pDevice device = (WifiP2pDevice) message.obj;
-                    if (device.equals(mGroup.getOwner())) {
-                        logd("Lost the group owner, killing p2p connection");
-                        WifiNative.p2pGroupRemove(mGroup.getInterface());
-                    } else if (mGroup.removeClient(device)) {
-                        if (!mPersistGroup && mGroup.isClientListEmpty()) {
-                            Slog.d(TAG, "Client list empty, removing a non-persistent p2p group");
-                            WifiNative.p2pGroupRemove(mGroup.getInterface());
-                        }
+                    //Device loss for a connected device indicates it is not in discovery any more
+                    if (mGroup.contains(device)) {
+                        if (DBG) logd("Lost " + device +" , do nothing");
+                        return HANDLED;
                     }
-                    return NOT_HANDLED; // Do the regular device lost handling
+                    // Do the regular device lost handling
+                    return NOT_HANDLED;
                 case WifiP2pManager.DISABLE_P2P:
                     sendMessage(WifiP2pManager.REMOVE_GROUP);
                     deferMessage(message);
@@ -1038,24 +1112,25 @@
                     }
                     // TODO: figure out updating the status to declined when invitation is rejected
                     break;
-                case WifiMonitor.P2P_INVITATION_RESULT_EVENT:
-                    logd("===> INVITATION RESULT EVENT : " + message.obj);
-                    break;
                 case WifiMonitor.P2P_PROV_DISC_PBC_REQ_EVENT:
-                    notifyP2pProvDiscPbcRequest((WifiP2pDevice) message.obj);
-                    break;
                 case WifiMonitor.P2P_PROV_DISC_ENTER_PIN_EVENT:
-                    notifyP2pProvDiscPinRequest((WifiP2pDevice) message.obj);
+                case WifiMonitor.P2P_PROV_DISC_SHOW_PIN_EVENT:
+                    WifiP2pProvDiscEvent provDisc = (WifiP2pProvDiscEvent) message.obj;
+                    mSavedPeerConfig = new WifiP2pConfig();
+                    mSavedPeerConfig.deviceAddress = provDisc.device.deviceAddress;
+                    if (message.what == WifiMonitor.P2P_PROV_DISC_ENTER_PIN_EVENT) {
+                        mSavedPeerConfig.wps.setup = WpsInfo.KEYPAD;
+                    } else if (message.what == WifiMonitor.P2P_PROV_DISC_SHOW_PIN_EVENT) {
+                        mSavedPeerConfig.wps.setup = WpsInfo.DISPLAY;
+                        mSavedPeerConfig.wps.pin = provDisc.pin;
+                    } else {
+                        mSavedPeerConfig.wps.setup = WpsInfo.PBC;
+                    }
+                    transitionTo(mUserAuthorizingJoinState);
                     break;
                 case WifiMonitor.P2P_GROUP_STARTED_EVENT:
                     Slog.e(TAG, "Duplicate group creation event notice, ignore");
                     break;
-                case WPS_PBC:
-                    WifiNative.wpsPbc();
-                    break;
-                case WPS_PIN:
-                    WifiNative.wpsPin((String) message.obj);
-                    break;
                 default:
                     return NOT_HANDLED;
             }
@@ -1070,6 +1145,48 @@
         }
     }
 
+    class UserAuthorizingJoinState extends State {
+        @Override
+        public void enter() {
+            if (DBG) logd(getName());
+            notifyInvitationReceived();
+        }
+
+        @Override
+        public boolean processMessage(Message message) {
+            if (DBG) logd(getName() + message.toString());
+            switch (message.what) {
+                case WifiMonitor.P2P_PROV_DISC_PBC_REQ_EVENT:
+                case WifiMonitor.P2P_PROV_DISC_ENTER_PIN_EVENT:
+                case WifiMonitor.P2P_PROV_DISC_SHOW_PIN_EVENT:
+                    //Ignore more client requests
+                    break;
+                case PEER_CONNECTION_USER_ACCEPT:
+                    if (mSavedPeerConfig.wps.setup == WpsInfo.PBC) {
+                        WifiNative.wpsPbc();
+                    } else {
+                        WifiNative.wpsPin(mSavedPeerConfig.wps.pin);
+                    }
+                    mSavedPeerConfig = null;
+                    transitionTo(mGroupCreatedState);
+                    break;
+                case PEER_CONNECTION_USER_REJECT:
+                    if (DBG) logd("User rejected incoming request");
+                    mSavedPeerConfig = null;
+                    transitionTo(mGroupCreatedState);
+                    break;
+                default:
+                    return NOT_HANDLED;
+            }
+            return HANDLED;
+        }
+
+        @Override
+        public void exit() {
+            //TODO: dismiss dialog if not already done
+        }
+    }
+
     private void sendP2pStateChangedBroadcast(boolean enabled) {
         final Intent intent = new Intent(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION);
         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
@@ -1110,9 +1227,9 @@
         InterfaceConfiguration ifcg = null;
         try {
             ifcg = mNwService.getInterfaceConfig(intf);
-            ifcg.addr = new LinkAddress(NetworkUtils.numericToInetAddress(
-                        SERVER_ADDRESS), 24);
-            ifcg.interfaceFlags = "[up]";
+            ifcg.setLinkAddress(new LinkAddress(NetworkUtils.numericToInetAddress(
+                        SERVER_ADDRESS), 24));
+            ifcg.setInterfaceUp();
             mNwService.setInterfaceConfig(intf, ifcg);
             /* This starts the dnsmasq server */
             mNwService.startTethering(DHCP_RANGE);
@@ -1146,145 +1263,85 @@
         dialog.show();
     }
 
-    private void notifyWpsPin(String pin, String peerAddress) {
+    private void addRowToDialog(ViewGroup group, int stringId, String value) {
         Resources r = Resources.getSystem();
+        View row = LayoutInflater.from(mContext).inflate(R.layout.wifi_p2p_dialog_row,
+                group, false);
+        ((TextView) row.findViewById(R.id.name)).setText(r.getString(stringId));
+        ((TextView) row.findViewById(R.id.value)).setText(value);
+        group.addView(row);
+    }
+
+    private void notifyInvitationSent(String pin, String peerAddress) {
+        Resources r = Resources.getSystem();
+
+        final View textEntryView = LayoutInflater.from(mContext)
+                .inflate(R.layout.wifi_p2p_dialog, null);
+
+        ViewGroup group = (ViewGroup) textEntryView.findViewById(R.id.info);
+        addRowToDialog(group, R.string.wifi_p2p_to_message, getDeviceName(peerAddress));
+        addRowToDialog(group, R.string.wifi_p2p_show_pin_message, pin);
+
         AlertDialog dialog = new AlertDialog.Builder(mContext)
-            .setTitle(r.getString(R.string.wifi_p2p_dialog_title))
-            .setMessage(r.getString(R.string.wifi_p2p_pin_display_message, pin, peerAddress))
+            .setTitle(r.getString(R.string.wifi_p2p_invitation_sent_title))
+            .setView(textEntryView)
             .setPositiveButton(r.getString(R.string.ok), null)
             .create();
         dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
         dialog.show();
     }
 
-    private void notifyP2pGoNegotationRequest(WifiP2pConfig config) {
+    private void notifyInvitationReceived() {
         Resources r = Resources.getSystem();
-        WpsInfo wps = config.wps;
+        final WpsInfo wps = mSavedPeerConfig.wps;
         final View textEntryView = LayoutInflater.from(mContext)
-                .inflate(R.layout.wifi_p2p_go_negotiation_request_alert, null);
-        final EditText pin = (EditText) textEntryView .findViewById(R.id.wifi_p2p_wps_pin);
+                .inflate(R.layout.wifi_p2p_dialog, null);
+
+        ViewGroup group = (ViewGroup) textEntryView.findViewById(R.id.info);
+        addRowToDialog(group, R.string.wifi_p2p_from_message, getDeviceName(
+                mSavedPeerConfig.deviceAddress));
+
+        final EditText pin = (EditText) textEntryView.findViewById(R.id.wifi_p2p_wps_pin);
 
         AlertDialog dialog = new AlertDialog.Builder(mContext)
-            .setTitle(r.getString(R.string.wifi_p2p_dialog_title))
+            .setTitle(r.getString(R.string.wifi_p2p_invitation_to_connect_title))
             .setView(textEntryView)
-            .setPositiveButton(r.getString(R.string.ok), new OnClickListener() {
+            .setPositiveButton(r.getString(R.string.accept), new OnClickListener() {
                         public void onClick(DialogInterface dialog, int which) {
-                            if (DBG) logd(getName() + " connect " + pin.getText());
-
-                            if (pin.getVisibility() == View.GONE) {
-                                mSavedGoNegotiationConfig.wps.setup = WpsInfo.PBC;
-                            } else {
-                                mSavedGoNegotiationConfig.wps.setup = WpsInfo.KEYPAD;
-                                mSavedGoNegotiationConfig.wps.pin = pin.getText().toString();
+                            if (wps.setup == WpsInfo.KEYPAD) {
+                                mSavedPeerConfig.wps.pin = pin.getText().toString();
                             }
-                            sendMessage(GROUP_NEGOTIATION_USER_ACCEPT);
+                            if (DBG) logd(getName() + " accept invitation " + mSavedPeerConfig);
+                            sendMessage(PEER_CONNECTION_USER_ACCEPT);
                         }
                     })
-            .setNegativeButton(r.getString(R.string.cancel), new OnClickListener() {
+            .setNegativeButton(r.getString(R.string.decline), new OnClickListener() {
                         @Override
                         public void onClick(DialogInterface dialog, int which) {
                             if (DBG) logd(getName() + " ignore connect");
-                            sendMessage(GROUP_NEGOTIATION_USER_REJECT);
+                            sendMessage(PEER_CONNECTION_USER_REJECT);
                         }
                     })
             .create();
 
-        if (wps.setup == WpsInfo.PBC) {
-            pin.setVisibility(View.GONE);
-            dialog.setMessage(r.getString(R.string.wifi_p2p_pbc_go_negotiation_request_message,
-                        config.deviceAddress));
-        } else {
-            dialog.setMessage(r.getString(R.string.wifi_p2p_pin_go_negotiation_request_message,
-                        config.deviceAddress));
+        //make the enter pin area or the display pin area visible
+        switch (wps.setup) {
+            case WpsInfo.KEYPAD:
+                if (DBG) logd("Enter pin section visible");
+                textEntryView.findViewById(R.id.enter_pin_section).setVisibility(View.VISIBLE);
+                break;
+            case WpsInfo.DISPLAY:
+                if (DBG) logd("Shown pin section visible");
+                addRowToDialog(group, R.string.wifi_p2p_show_pin_message, wps.pin);
+                break;
+            default:
+                break;
         }
 
         dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
         dialog.show();
     }
 
-    private void notifyP2pProvDiscPbcRequest(WifiP2pDevice peer) {
-        Resources r = Resources.getSystem();
-        final View textEntryView = LayoutInflater.from(mContext)
-                .inflate(R.layout.wifi_p2p_go_negotiation_request_alert, null);
-        final EditText pin = (EditText) textEntryView .findViewById(R.id.wifi_p2p_wps_pin);
-
-        AlertDialog dialog = new AlertDialog.Builder(mContext)
-            .setTitle(r.getString(R.string.wifi_p2p_dialog_title))
-            .setView(textEntryView)
-            .setPositiveButton(r.getString(R.string.ok), new OnClickListener() {
-                        public void onClick(DialogInterface dialog, int which) {
-                                if (DBG) logd(getName() + " wps_pbc");
-                                sendMessage(WPS_PBC);
-                        }
-                    })
-            .setNegativeButton(r.getString(R.string.cancel), null)
-            .create();
-
-        pin.setVisibility(View.GONE);
-        dialog.setMessage(r.getString(R.string.wifi_p2p_pbc_go_negotiation_request_message,
-                        peer.deviceAddress));
-
-        dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
-        dialog.show();
-    }
-
-    private void notifyP2pProvDiscPinRequest(WifiP2pDevice peer) {
-        Resources r = Resources.getSystem();
-        final View textEntryView = LayoutInflater.from(mContext)
-                .inflate(R.layout.wifi_p2p_go_negotiation_request_alert, null);
-        final EditText pin = (EditText) textEntryView .findViewById(R.id.wifi_p2p_wps_pin);
-
-        AlertDialog dialog = new AlertDialog.Builder(mContext)
-            .setTitle(r.getString(R.string.wifi_p2p_dialog_title))
-            .setView(textEntryView)
-            .setPositiveButton(r.getString(R.string.ok), new OnClickListener() {
-                    public void onClick(DialogInterface dialog, int which) {
-                        if (DBG) logd(getName() + " wps_pin");
-                        sendMessage(WPS_PIN, pin.getText().toString());
-                    }
-                    })
-            .setNegativeButton(r.getString(R.string.cancel), null)
-            .create();
-
-        dialog.setMessage(r.getString(R.string.wifi_p2p_pin_go_negotiation_request_message,
-                        peer.deviceAddress));
-
-        dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
-        dialog.show();
-    }
-
-    private void notifyP2pInvitationReceived(WifiP2pGroup group) {
-        mSavedP2pGroup = group;
-        Resources r = Resources.getSystem();
-        final View textEntryView = LayoutInflater.from(mContext)
-                .inflate(R.layout.wifi_p2p_go_negotiation_request_alert, null);
-        final EditText pin = (EditText) textEntryView .findViewById(R.id.wifi_p2p_wps_pin);
-
-        AlertDialog dialog = new AlertDialog.Builder(mContext)
-            .setTitle(r.getString(R.string.wifi_p2p_dialog_title))
-            .setView(textEntryView)
-            .setPositiveButton(r.getString(R.string.ok), new OnClickListener() {
-                        public void onClick(DialogInterface dialog, int which) {
-                            sendMessage(GROUP_INVITATION_USER_ACCEPT);
-                        }
-                    })
-            .setNegativeButton(r.getString(R.string.cancel), new OnClickListener() {
-                        @Override
-                        public void onClick(DialogInterface dialog, int which) {
-                            if (DBG) logd(getName() + " ignore invite");
-                            sendMessage(GROUP_INVITATION_USER_REJECT);
-                        }
-                    })
-            .create();
-
-        pin.setVisibility(View.GONE);
-        dialog.setMessage(r.getString(R.string.wifi_p2p_pbc_go_negotiation_request_message,
-                        group.getOwner().deviceAddress));
-
-        dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
-        dialog.show();
-    }
-
     private void updateDeviceStatus(String deviceAddress, int status) {
         for (WifiP2pDevice d : mPeers.getDeviceList()) {
             if (d.deviceAddress.equals(deviceAddress)) {
@@ -1319,6 +1376,16 @@
         mWifiP2pInfo.groupOwnerAddress = null;
     }
 
+    private String getDeviceName(String deviceAddress) {
+        for (WifiP2pDevice d : mPeers.getDeviceList()) {
+            if (d.deviceAddress.equals(deviceAddress)) {
+                return d.deviceName;
+            }
+        }
+        //Treat the address as name if there is no match
+        return deviceAddress;
+    }
+
     private String getDeviceAddress(String interfaceAddress) {
         for (WifiP2pDevice d : mPeers.getDeviceList()) {
             if (interfaceAddress.equals(WifiNative.p2pGetInterfaceAddress(d.deviceAddress))) {
@@ -1331,7 +1398,12 @@
     private void initializeP2pSettings() {
         WifiNative.setPersistentReconnect(true);
         WifiNative.setDeviceName(mThisDevice.deviceName);
+        //DIRECT-XY-DEVICENAME (XY is randomly generated)
+        WifiNative.setP2pSsidPostfix("-" + mThisDevice.deviceName);
         WifiNative.setDeviceType(mThisDevice.primaryDeviceType);
+        //The supplicant default is to support everything, but a bug necessitates
+        //the framework to specify this explicitly
+        WifiNative.setConfigMethods("keypad display push_button");
 
         mThisDevice.deviceAddress = WifiNative.p2pGetDeviceAddress();
         updateThisDevice(WifiP2pDevice.AVAILABLE);