Merge "Improve Wi-Fi hand-off"
diff --git a/Android.mk b/Android.mk
index 79f6220..5572c50 100644
--- a/Android.mk
+++ b/Android.mk
@@ -127,6 +127,7 @@
 	core/java/android/os/IPermissionController.aidl \
 	core/java/android/os/IPowerManager.aidl \
 	core/java/android/os/IRemoteCallback.aidl \
+	core/java/android/os/IUpdateLock.aidl \
 	core/java/android/os/IVibratorService.aidl \
 	core/java/android/service/wallpaper/IWallpaperConnection.aidl \
 	core/java/android/service/wallpaper/IWallpaperEngine.aidl \
diff --git a/api/16.txt b/api/16.txt
index be544de..357d618 100644
--- a/api/16.txt
+++ b/api/16.txt
@@ -27303,7 +27303,6 @@
     method public boolean onTextContextMenuItem(int);
     method public void removeTextChangedListener(android.text.TextWatcher);
     method protected void resetResolvedDrawables();
-    method protected void resetResolvedLayoutDirection();
     method protected void resolveDrawables();
     method protected void resolveTextDirection();
     method public void setAllCaps(boolean);
diff --git a/api/current.txt b/api/current.txt
index 6290d30..cce28a4 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -6195,6 +6195,8 @@
     method public int describeContents();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator CREATOR;
+    field public static final int REQUESTED_PERMISSION_GRANTED = 2; // 0x2
+    field public static final int REQUESTED_PERMISSION_REQUIRED = 1; // 0x1
     field public android.content.pm.ActivityInfo[] activities;
     field public android.content.pm.ApplicationInfo applicationInfo;
     field public android.content.pm.ConfigurationInfo[] configPreferences;
@@ -6208,6 +6210,7 @@
     field public android.content.pm.ActivityInfo[] receivers;
     field public android.content.pm.FeatureInfo[] reqFeatures;
     field public java.lang.String[] requestedPermissions;
+    field public int[] requestedPermissionsFlags;
     field public android.content.pm.ServiceInfo[] services;
     field public java.lang.String sharedUserId;
     field public int sharedUserLabel;
@@ -6430,6 +6433,10 @@
     method public java.lang.CharSequence loadDescription(android.content.pm.PackageManager);
     field public static final android.os.Parcelable.Creator CREATOR;
     field public static final int PROTECTION_DANGEROUS = 1; // 0x1
+    field public static final int PROTECTION_FLAG_DEVELOPMENT = 32; // 0x20
+    field public static final int PROTECTION_FLAG_SYSTEM = 16; // 0x10
+    field public static final int PROTECTION_MASK_BASE = 15; // 0xf
+    field public static final int PROTECTION_MASK_FLAGS = 240; // 0xf0
     field public static final int PROTECTION_NORMAL = 0; // 0x0
     field public static final int PROTECTION_SIGNATURE = 2; // 0x2
     field public static final int PROTECTION_SIGNATURE_OR_SYSTEM = 3; // 0x3
@@ -7609,11 +7616,11 @@
   }
 
   public class DrmStore {
-    ctor public DrmStore();
+    ctor public deprecated DrmStore();
   }
 
   public static class DrmStore.Action {
-    ctor public DrmStore.Action();
+    ctor public deprecated DrmStore.Action();
     field public static final int DEFAULT = 0; // 0x0
     field public static final int DISPLAY = 7; // 0x7
     field public static final int EXECUTE = 6; // 0x6
@@ -7634,7 +7641,7 @@
   }
 
   public static class DrmStore.DrmObjectType {
-    ctor public DrmStore.DrmObjectType();
+    ctor public deprecated DrmStore.DrmObjectType();
     field public static final int CONTENT = 1; // 0x1
     field public static final int RIGHTS_OBJECT = 2; // 0x2
     field public static final int TRIGGER_OBJECT = 3; // 0x3
@@ -7642,7 +7649,7 @@
   }
 
   public static class DrmStore.Playback {
-    ctor public DrmStore.Playback();
+    ctor public deprecated DrmStore.Playback();
     field public static final int PAUSE = 2; // 0x2
     field public static final int RESUME = 3; // 0x3
     field public static final int START = 0; // 0x0
@@ -7650,7 +7657,7 @@
   }
 
   public static class DrmStore.RightsStatus {
-    ctor public DrmStore.RightsStatus();
+    ctor public deprecated DrmStore.RightsStatus();
     field public static final int RIGHTS_EXPIRED = 2; // 0x2
     field public static final int RIGHTS_INVALID = 1; // 0x1
     field public static final int RIGHTS_NOT_ACQUIRED = 3; // 0x3
@@ -7661,7 +7668,8 @@
     ctor public DrmSupportInfo();
     method public void addFileSuffix(java.lang.String);
     method public void addMimeType(java.lang.String);
-    method public java.lang.String getDescriprition();
+    method public deprecated java.lang.String getDescriprition();
+    method public java.lang.String getDescription();
     method public java.util.Iterator<java.lang.String> getFileSuffixIterator();
     method public java.util.Iterator<java.lang.String> getMimeTypeIterator();
     method public void setDescription(java.lang.String);
@@ -8629,14 +8637,14 @@
     method public static void getPixelFormatInfo(int, android.graphics.PixelFormat);
     field public static final int A_8 = 8; // 0x8
     field public static final deprecated int JPEG = 256; // 0x100
-    field public static final int LA_88 = 10; // 0xa
+    field public static final deprecated int LA_88 = 10; // 0xa
     field public static final int L_8 = 9; // 0x9
     field public static final int OPAQUE = -1; // 0xffffffff
-    field public static final int RGBA_4444 = 7; // 0x7
-    field public static final int RGBA_5551 = 6; // 0x6
+    field public static final deprecated int RGBA_4444 = 7; // 0x7
+    field public static final deprecated int RGBA_5551 = 6; // 0x6
     field public static final int RGBA_8888 = 1; // 0x1
     field public static final int RGBX_8888 = 2; // 0x2
-    field public static final int RGB_332 = 11; // 0xb
+    field public static final deprecated int RGB_332 = 11; // 0xb
     field public static final int RGB_565 = 4; // 0x4
     field public static final int RGB_888 = 3; // 0x3
     field public static final int TRANSLUCENT = -3; // 0xfffffffd
@@ -15336,6 +15344,7 @@
     method public abstract void acquired();
     method public void cleanup(android.os.IBinder, boolean);
     method public void dump();
+    method public void dump(java.io.PrintWriter);
     method public boolean isAcquired();
     method public void release(android.os.IBinder);
     method public abstract void released();
@@ -16074,6 +16083,7 @@
   protected static abstract interface CalendarContract.RemindersColumns {
     field public static final java.lang.String EVENT_ID = "event_id";
     field public static final java.lang.String METHOD = "method";
+    field public static final int METHOD_ALARM = 4; // 0x4
     field public static final int METHOD_ALERT = 1; // 0x1
     field public static final int METHOD_DEFAULT = 0; // 0x0
     field public static final int METHOD_EMAIL = 2; // 0x2
@@ -21936,12 +21946,14 @@
     method public java.lang.Object getTag();
     method public abstract java.lang.CharSequence getTitle();
     method public abstract void invalidate();
+    method public boolean isTitleOptional();
     method public abstract void setCustomView(android.view.View);
     method public abstract void setSubtitle(java.lang.CharSequence);
     method public abstract void setSubtitle(int);
     method public void setTag(java.lang.Object);
     method public abstract void setTitle(java.lang.CharSequence);
     method public abstract void setTitle(int);
+    method public void setTitleOptionalHint(boolean);
   }
 
   public static abstract interface ActionMode.Callback {
@@ -27650,7 +27662,6 @@
     method public boolean onTextContextMenuItem(int);
     method public void removeTextChangedListener(android.text.TextWatcher);
     method protected void resetResolvedDrawables();
-    method protected void resetResolvedLayoutDirection();
     method protected void resolveDrawables();
     method public void setAllCaps(boolean);
     method public final void setAutoLinkMask(int);
diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp
index 3545ace..0ab6aa3 100644
--- a/cmds/bootanimation/BootAnimation.cpp
+++ b/cmds/bootanimation/BootAnimation.cpp
@@ -38,8 +38,8 @@
 #include <ui/DisplayInfo.h>
 #include <ui/FramebufferNativeWindow.h>
 
-#include <surfaceflinger/ISurfaceComposer.h>
-#include <surfaceflinger/ISurfaceComposerClient.h>
+#include <gui/Surface.h>
+#include <gui/SurfaceComposerClient.h>
 
 #include <core/SkBitmap.h>
 #include <core/SkStream.h>
diff --git a/cmds/bootanimation/BootAnimation.h b/cmds/bootanimation/BootAnimation.h
index c85d72c..62da82f 100644
--- a/cmds/bootanimation/BootAnimation.h
+++ b/cmds/bootanimation/BootAnimation.h
@@ -23,9 +23,6 @@
 #include <androidfw/AssetManager.h>
 #include <utils/threads.h>
 
-#include <surfaceflinger/ISurfaceComposer.h>
-#include <surfaceflinger/SurfaceComposerClient.h>
-
 #include <EGL/egl.h>
 #include <GLES/gl.h>
 
@@ -33,7 +30,9 @@
 
 namespace android {
 
-class AssetManager;
+class Surface;
+class SurfaceComposerClient;
+class SurfaceControl;
 
 // ---------------------------------------------------------------------------
 
diff --git a/cmds/bootanimation/bootanimation_main.cpp b/cmds/bootanimation/bootanimation_main.cpp
index ff809d3..417e138 100644
--- a/cmds/bootanimation/bootanimation_main.cpp
+++ b/cmds/bootanimation/bootanimation_main.cpp
@@ -25,8 +25,6 @@
 #include <utils/Log.h>
 #include <utils/threads.h>
 
-#include <surfaceflinger/ISurfaceComposer.h>
-
 #if defined(HAVE_PTHREADS)
 # include <pthread.h>
 # include <sys/resource.h>
diff --git a/cmds/content/src/com/android/commands/content/Content.java b/cmds/content/src/com/android/commands/content/Content.java
index 1dcba70..bd9eb9a 100644
--- a/cmds/content/src/com/android/commands/content/Content.java
+++ b/cmds/content/src/com/android/commands/content/Content.java
@@ -69,6 +69,7 @@
         + "  <COLUMN_NAME>:<TYPE>:<COLUMN_VALUE> where:\n"
         + "  <TYPE> specifies data type such as:\n"
         + "  b - boolean, s - string, i - integer, l - long, f - float, d - double\n"
+        + "  Note: Omit the value for passing an empty string, e.g column:s:\n"
         + "  Example:\n"
         + "  # Add \"new_setting\" secure setting with value \"new_value\".\n"
         + "  adb shell content insert --uri content://settings/secure --bind name:s:new_setting"
@@ -245,13 +246,17 @@
             if (TextUtils.isEmpty(argument)) {
                 throw new IllegalArgumentException("Binding not well formed: " + argument);
             }
-            String[] binding = argument.split(COLON);
-            if (binding.length != 3) {
+            final int firstColonIndex = argument.indexOf(COLON);
+            if (firstColonIndex < 0) {
                 throw new IllegalArgumentException("Binding not well formed: " + argument);
             }
-            String column = binding[0];
-            String type = binding[1];
-            String value = binding[2];
+            final int secondColonIndex = argument.indexOf(COLON, firstColonIndex + 1);
+            if (secondColonIndex < 0) {
+                throw new IllegalArgumentException("Binding not well formed: " + argument);
+            }
+            String column = argument.substring(0, firstColonIndex);
+            String type = argument.substring(firstColonIndex + 1, secondColonIndex);
+            String value = argument.substring(secondColonIndex + 1);
             if (TYPE_STRING.equals(type)) {
                 values.put(column, value);
             } else if (TYPE_BOOLEAN.equalsIgnoreCase(type)) {
diff --git a/cmds/dumpstate/dumpstate.c b/cmds/dumpstate/dumpstate.c
index 16dc517..ebe28db 100644
--- a/cmds/dumpstate/dumpstate.c
+++ b/cmds/dumpstate/dumpstate.c
@@ -88,11 +88,11 @@
 
     if (screenshot_path[0]) {
         ALOGI("taking screenshot\n");
-        run_command(NULL, 5, "su", "root", "screenshot", screenshot_path, NULL);
+        run_command(NULL, 5, SU_PATH, "root", "screenshot", screenshot_path, NULL);
         ALOGI("wrote screenshot: %s\n", screenshot_path);
     }
 
-    run_command("SYSTEM SETTINGS", 20, "su", "root", "sqlite3",
+    run_command("SYSTEM SETTINGS", 20, SU_PATH, "root", "sqlite3",
             "/data/data/com.android.providers.settings/databases/settings.db",
             "pragma user_version; select * from system; select * from secure;", NULL);
     run_command("SYSTEM LOG", 20, "logcat", "-v", "threadtime", "-d", "*:v", NULL);
@@ -118,7 +118,7 @@
     run_command("EVENT LOG", 20, "logcat", "-b", "events", "-v", "threadtime", "-d", "*:v", NULL);
     run_command("RADIO LOG", 20, "logcat", "-b", "radio", "-v", "threadtime", "-d", "*:v", NULL);
 
-    run_command("NETWORK INTERFACES", 10, "su", "root", "netcfg", NULL);
+    run_command("NETWORK INTERFACES", 10, SU_PATH, "root", "netcfg", NULL);
     dump_file("NETWORK DEV INFO", "/proc/net/dev");
     dump_file("QTAGUID NETWORK INTERFACES INFO", "/proc/net/xt_qtaguid/iface_stat_all");
     dump_file("QTAGUID CTRL INFO", "/proc/net/xt_qtaguid/ctrl");
@@ -133,28 +133,28 @@
     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);
-    run_command("IPTABLE NAT", 10, "su", "root", "iptables", "-t", "nat", "-L", "-n", NULL);
-    run_command("IPT6ABLE NAT", 10, "su", "root", "ip6tables", "-t", "nat", "-L", "-n", NULL);
+    run_command("IPTABLES", 10, SU_PATH, "root", "iptables", "-L", "-nvx", NULL);
+    run_command("IP6TABLES", 10, SU_PATH, "root", "ip6tables", "-L", "-nvx", NULL);
+    run_command("IPTABLE NAT", 10, SU_PATH, "root", "iptables", "-t", "nat", "-L", "-n", NULL);
+    run_command("IPT6ABLE NAT", 10, SU_PATH, "root", "ip6tables", "-t", "nat", "-L", "-n", NULL);
 
     run_command("WIFI NETWORKS", 20,
-            "su", "root", "wpa_cli", "list_networks", NULL);
+            SU_PATH, "root", "wpa_cli", "list_networks", NULL);
 
     property_get("dhcp.wlan0.gateway", network, "");
     if (network[0])
-        run_command("PING GATEWAY", 10, "su", "root", "ping", "-c", "3", "-i", ".5", network, NULL);
+        run_command("PING GATEWAY", 10, SU_PATH, "root", "ping", "-c", "3", "-i", ".5", network, NULL);
     property_get("dhcp.wlan0.dns1", network, "");
     if (network[0])
-        run_command("PING DNS1", 10, "su", "root", "ping", "-c", "3", "-i", ".5", network, NULL);
+        run_command("PING DNS1", 10, SU_PATH, "root", "ping", "-c", "3", "-i", ".5", network, NULL);
     property_get("dhcp.wlan0.dns2", network, "");
     if (network[0])
-        run_command("PING DNS2", 10, "su", "root", "ping", "-c", "3", "-i", ".5", network, NULL);
+        run_command("PING DNS2", 10, SU_PATH, "root", "ping", "-c", "3", "-i", ".5", network, NULL);
 #ifdef FWDUMP_bcm4329
     run_command("DUMP WIFI STATUS", 20,
-            "su", "root", "dhdutil", "-i", "wlan0", "dump", NULL);
+            SU_PATH, "root", "dhdutil", "-i", "wlan0", "dump", NULL);
     run_command("DUMP WIFI INTERNAL COUNTERS", 20,
-            "su", "root", "wlutil", "counters", NULL);
+            SU_PATH, "root", "wlutil", "counters", NULL);
 #endif
 
     char ril_dumpstate_timeout[PROPERTY_VALUE_MAX] = {0};
@@ -168,7 +168,7 @@
                     "vril-dump", NULL);
         } else {
             run_command("DUMP VENDOR RIL LOGS", atoi(ril_dumpstate_timeout),
-                    "su", "root", "vril-dump", NULL);
+                    SU_PATH, "root", "vril-dump", NULL);
         }
     }
 
@@ -192,7 +192,7 @@
     dump_file("BINDER STATS", "/sys/kernel/debug/binder/stats");
     dump_file("BINDER STATE", "/sys/kernel/debug/binder/state");
 
-    run_command("FILESYSTEMS & FREE SPACE", 10, "su", "root", "df", NULL);
+    run_command("FILESYSTEMS & FREE SPACE", 10, SU_PATH, "root", "df", NULL);
 
     dump_file("PACKAGE SETTINGS", "/data/system/packages.xml");
     dump_file("PACKAGE UID ERRORS", "/data/system/uiderrors.txt");
@@ -218,7 +218,7 @@
     dump_file(NULL, "/sys/class/leds/lcd-backlight/registers");
     printf("\n");
 
-    run_command("LIST OF OPEN FILES", 10, "su", "root", "lsof", NULL);
+    run_command("LIST OF OPEN FILES", 10, SU_PATH, "root", "lsof", NULL);
 
     for_each_pid(do_showmap, "SMAPS OF ALL PROCESSES");
 
diff --git a/cmds/dumpstate/dumpstate.h b/cmds/dumpstate/dumpstate.h
index b02db0b..c1c2ad8 100644
--- a/cmds/dumpstate/dumpstate.h
+++ b/cmds/dumpstate/dumpstate.h
@@ -21,6 +21,8 @@
 #include <unistd.h>
 #include <stdio.h>
 
+#define SU_PATH "/system/xbin/su"
+
 /* prints the contents of a file */
 int dump_file(const char *title, const char* path);
 
diff --git a/cmds/dumpstate/utils.c b/cmds/dumpstate/utils.c
index 21526f9..0d5ab90 100644
--- a/cmds/dumpstate/utils.c
+++ b/cmds/dumpstate/utils.c
@@ -127,7 +127,7 @@
 
     sprintf(title, "SHOW MAP %d (%s)", pid, name);
     sprintf(arg, "%d", pid);
-    run_command(title, 10, "su", "root", "showmap", arg, NULL);
+    run_command(title, 10, SU_PATH, "root", "showmap", arg, NULL);
 }
 
 /* prints the contents of a file */
diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java
index f457842..ac5bffe 100644
--- a/cmds/pm/src/com/android/commands/pm/Pm.java
+++ b/cmds/pm/src/com/android/commands/pm/Pm.java
@@ -126,6 +126,16 @@
             return;
         }
 
+        if ("grant".equals(op)) {
+            runGrantRevokePermission(true);
+            return;
+        }
+
+        if ("revoke".equals(op)) {
+            runGrantRevokePermission(false);
+            return;
+        }
+
         if ("set-install-location".equals(op)) {
             runSetInstallLocation();
             return;
@@ -596,8 +606,9 @@
                 if (groups && groupName == null && pi.group != null) {
                     continue;
                 }
-                if (pi.protectionLevel < startProtectionLevel
-                        || pi.protectionLevel > endProtectionLevel) {
+                final int base = pi.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE;
+                if (base < startProtectionLevel
+                        || base > endProtectionLevel) {
                     continue;
                 }
                 if (summary) {
@@ -627,22 +638,8 @@
                                     + loadText(pi, pi.descriptionRes,
                                             pi.nonLocalizedDescription));
                         }
-                        String protLevel = "unknown";
-                        switch(pi.protectionLevel) {
-                            case PermissionInfo.PROTECTION_DANGEROUS:
-                                protLevel = "dangerous";
-                                break;
-                            case PermissionInfo.PROTECTION_NORMAL:
-                                protLevel = "normal";
-                                break;
-                            case PermissionInfo.PROTECTION_SIGNATURE:
-                                protLevel = "signature";
-                                break;
-                            case PermissionInfo.PROTECTION_SIGNATURE_OR_SYSTEM:
-                                protLevel = "signatureOrSystem";
-                                break;
-                        }
-                        System.out.println(prefix + "  protectionLevel:" + protLevel);
+                        System.out.println(prefix + "  protectionLevel:"
+                                + PermissionInfo.protectionToString(pi.protectionLevel));
                     }
                 }
             }
@@ -1063,6 +1060,36 @@
         }
     }
 
+    private void runGrantRevokePermission(boolean grant) {
+        String pkg = nextArg();
+        if (pkg == null) {
+            System.err.println("Error: no package specified");
+            showUsage();
+            return;
+        }
+        String perm = nextArg();
+        if (perm == null) {
+            System.err.println("Error: no permission specified");
+            showUsage();
+            return;
+        }
+        try {
+            if (grant) {
+                mPm.grantPermission(pkg, perm);
+            } else {
+                mPm.revokePermission(pkg, perm);
+            }
+        } catch (RemoteException e) {
+            System.err.println(e.toString());
+            System.err.println(PM_NOT_RUNNING_ERR);
+        } catch (IllegalArgumentException e) {
+            System.err.println("Bad argument: " + e.toString());
+            showUsage();
+        } catch (SecurityException e) {
+            System.err.println("Operation not allowed: " + e.toString());
+        }
+    }
+
     /**
      * Displays the package file for a package.
      * @param pckg
@@ -1158,6 +1185,8 @@
         System.err.println("       pm enable PACKAGE_OR_COMPONENT");
         System.err.println("       pm disable PACKAGE_OR_COMPONENT");
         System.err.println("       pm disable-user PACKAGE_OR_COMPONENT");
+        System.err.println("       pm grant PACKAGE PERMISSION");
+        System.err.println("       pm revoke PACKAGE PERMISSION");
         System.err.println("       pm set-install-location [0/auto] [1/internal] [2/external]");
         System.err.println("       pm get-install-location");
         System.err.println("       pm create-profile USER_NAME");
@@ -1208,6 +1237,10 @@
         System.err.println("pm enable, disable, disable-user: these commands change the enabled state");
         System.err.println("  of a given package or component (written as \"package/class\").");
         System.err.println("");
+        System.err.println("pm grant, revoke: these commands either grant or revoke permissions");
+        System.err.println("  to applications.  Only optional permissions the application has");
+        System.err.println("  declared can be granted or revoked.");
+        System.err.println("");
         System.err.println("pm get-install-location: returns the current install location.");
         System.err.println("    0 [auto]: Let system decide the best location");
         System.err.println("    1 [internal]: Install on internal device storage");
diff --git a/cmds/screencap/screencap.cpp b/cmds/screencap/screencap.cpp
index 90dfe76..46e41e3 100644
--- a/cmds/screencap/screencap.cpp
+++ b/cmds/screencap/screencap.cpp
@@ -24,7 +24,7 @@
 #include <sys/mman.h>
 
 #include <binder/IMemory.h>
-#include <surfaceflinger/SurfaceComposerClient.h>
+#include <gui/SurfaceComposerClient.h>
 
 #include <SkImageEncoder.h>
 #include <SkBitmap.h>
diff --git a/cmds/stagefright/SimplePlayer.cpp b/cmds/stagefright/SimplePlayer.cpp
index f269e80..fac3a8c6 100644
--- a/cmds/stagefright/SimplePlayer.cpp
+++ b/cmds/stagefright/SimplePlayer.cpp
@@ -396,7 +396,7 @@
     for (size_t i = 0; i < mStateByTrackIndex.size(); ++i) {
         CodecState *state = &mStateByTrackIndex.editValueAt(i);
 
-        CHECK_EQ(state->mCodec->stop(), (status_t)OK);
+        CHECK_EQ(state->mCodec->release(), (status_t)OK);
     }
 
     mStartTimeRealUs = -1ll;
diff --git a/cmds/stagefright/codec.cpp b/cmds/stagefright/codec.cpp
index ad246d2..fbf800c 100644
--- a/cmds/stagefright/codec.cpp
+++ b/cmds/stagefright/codec.cpp
@@ -30,7 +30,7 @@
 #include <media/stagefright/MediaCodec.h>
 #include <media/stagefright/MediaDefs.h>
 #include <media/stagefright/NuMediaExtractor.h>
-#include <surfaceflinger/SurfaceComposerClient.h>
+#include <gui/SurfaceComposerClient.h>
 
 static void usage(const char *me) {
     fprintf(stderr, "usage: %s [-a] use audio\n"
@@ -107,9 +107,8 @@
         CHECK_EQ(err, (status_t)OK);
 
         size_t j = 0;
-        sp<RefBase> obj;
-        while (format->findObject(StringPrintf("csd-%d", j).c_str(), &obj)) {
-            sp<ABuffer> buffer = static_cast<ABuffer *>(obj.get());
+        sp<ABuffer> buffer;
+        while (format->findBuffer(StringPrintf("csd-%d", j).c_str(), &buffer)) {
             state->mCSD.push_back(buffer);
 
             ++j;
@@ -296,7 +295,7 @@
     for (size_t i = 0; i < stateByTrack.size(); ++i) {
         CodecState *state = &stateByTrack.editValueAt(i);
 
-        CHECK_EQ((status_t)OK, state->mCodec->stop());
+        CHECK_EQ((status_t)OK, state->mCodec->release());
     }
 
     return 0;
diff --git a/cmds/stagefright/sf2.cpp b/cmds/stagefright/sf2.cpp
index 18e2532..1d28793 100644
--- a/cmds/stagefright/sf2.cpp
+++ b/cmds/stagefright/sf2.cpp
@@ -32,8 +32,7 @@
 #include <media/stagefright/NativeWindowWrapper.h>
 #include <media/stagefright/Utils.h>
 
-#include <surfaceflinger/ISurfaceComposer.h>
-#include <surfaceflinger/SurfaceComposerClient.h>
+#include <gui/SurfaceComposerClient.h>
 
 #include "include/ESDS.h"
 
@@ -358,7 +357,7 @@
             buffer->meta()->setInt32("csd", true);
             mCSD.push(buffer);
 
-            msg->setObject("csd", buffer);
+            msg->setBuffer("csd", buffer);
         } else if (meta->findData(kKeyESDS, &type, &data, &size)) {
             ESDS esds((const char *)data, size);
             CHECK_EQ(esds.InitCheck(), (status_t)OK);
@@ -408,9 +407,8 @@
             return;
         }
 
-        sp<RefBase> obj;
-        CHECK(msg->findObject("buffer", &obj));
-        sp<ABuffer> outBuffer = static_cast<ABuffer *>(obj.get());
+        sp<ABuffer> outBuffer;
+        CHECK(msg->findBuffer("buffer", &outBuffer));
 
         if (mCSDIndex < mCSD.size()) {
             outBuffer = mCSD.editItemAt(mCSDIndex++);
@@ -509,15 +507,14 @@
             }
         }
 
-        reply->setObject("buffer", outBuffer);
+        reply->setBuffer("buffer", outBuffer);
         reply->post();
     }
 
     void onDrainThisBuffer(const sp<AMessage> &msg) {
-        sp<RefBase> obj;
-        CHECK(msg->findObject("buffer", &obj));
+        sp<ABuffer> buffer;
+        CHECK(msg->findBuffer("buffer", &buffer));
 
-        sp<ABuffer> buffer = static_cast<ABuffer *>(obj.get());
         mTotalBytesReceived += buffer->size();
 
         sp<AMessage> reply;
diff --git a/cmds/stagefright/stagefright.cpp b/cmds/stagefright/stagefright.cpp
index 7cb8f62..dab2e0f 100644
--- a/cmds/stagefright/stagefright.cpp
+++ b/cmds/stagefright/stagefright.cpp
@@ -55,9 +55,7 @@
 #include <fcntl.h>
 
 #include <gui/SurfaceTextureClient.h>
-
-#include <surfaceflinger/ISurfaceComposer.h>
-#include <surfaceflinger/SurfaceComposerClient.h>
+#include <gui/SurfaceComposerClient.h>
 
 using namespace android;
 
diff --git a/cmds/stagefright/stream.cpp b/cmds/stagefright/stream.cpp
index 0d6c738..efa1445 100644
--- a/cmds/stagefright/stream.cpp
+++ b/cmds/stagefright/stream.cpp
@@ -32,8 +32,7 @@
 
 #include <binder/IServiceManager.h>
 #include <media/IMediaPlayerService.h>
-#include <surfaceflinger/ISurfaceComposer.h>
-#include <surfaceflinger/SurfaceComposerClient.h>
+#include <gui/SurfaceComposerClient.h>
 
 #include <fcntl.h>
 
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index bf632a9..1230c81 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -78,6 +78,7 @@
 import android.view.Window;
 import android.view.WindowManager;
 import android.view.WindowManagerImpl;
+import android.renderscript.RenderScript;
 
 import com.android.internal.os.BinderInternal;
 import com.android.internal.os.RuntimeInit;
@@ -3779,6 +3780,7 @@
                 appContext.init(info, null, this);
 
                 HardwareRenderer.setupDiskCache(appContext.getCacheDir());
+                RenderScript.setupDiskCache(appContext.getCacheDir());
             }
         } catch (RemoteException e) {
             // Ignore
@@ -3984,31 +3986,39 @@
             dalvik.system.VMRuntime.getRuntime().clearGrowthLimit();
         }
 
-        // If the app is being launched for full backup or restore, bring it up in
-        // a restricted environment with the base application class.
-        Application app = data.info.makeApplication(data.restrictedBackupMode, null);
-        mInitialApplication = app;
-
-        // don't bring up providers in restricted mode; they may depend on the
-        // app's custom Application class
-        if (!data.restrictedBackupMode){ 
-            List<ProviderInfo> providers = data.providers;
-            if (providers != null) {
-                installContentProviders(app, providers);
-                // For process that contains content providers, we want to
-                // ensure that the JIT is enabled "at some point".
-                mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000);
-            }
-        }
-
+        // Allow disk access during application and provider setup. This could
+        // block processing ordered broadcasts, but later processing would
+        // probably end up doing the same disk access.
+        final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskWrites();
         try {
-            mInstrumentation.callApplicationOnCreate(app);
-        } catch (Exception e) {
-            if (!mInstrumentation.onException(app, e)) {
-                throw new RuntimeException(
-                    "Unable to create application " + app.getClass().getName()
-                    + ": " + e.toString(), e);
+            // If the app is being launched for full backup or restore, bring it up in
+            // a restricted environment with the base application class.
+            Application app = data.info.makeApplication(data.restrictedBackupMode, null);
+            mInitialApplication = app;
+
+            // don't bring up providers in restricted mode; they may depend on the
+            // app's custom Application class
+            if (!data.restrictedBackupMode) {
+                List<ProviderInfo> providers = data.providers;
+                if (providers != null) {
+                    installContentProviders(app, providers);
+                    // For process that contains content providers, we want to
+                    // ensure that the JIT is enabled "at some point".
+                    mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000);
+                }
             }
+
+            try {
+                mInstrumentation.callApplicationOnCreate(app);
+            } catch (Exception e) {
+                if (!mInstrumentation.onException(app, e)) {
+                    throw new RuntimeException(
+                        "Unable to create application " + app.getClass().getName()
+                        + ": " + e.toString(), e);
+                }
+            }
+        } finally {
+            StrictMode.setThreadPolicy(savedPolicy);
         }
     }
 
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index fee2beb..758ce09 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -332,6 +332,24 @@
     }
 
     @Override
+    public void grantPermission(String packageName, String permissionName) {
+        try {
+            mPM.grantPermission(packageName, permissionName);
+        } catch (RemoteException e) {
+            throw new RuntimeException("Package manager has died", e);
+        }
+    }
+
+    @Override
+    public void revokePermission(String packageName, String permissionName) {
+        try {
+            mPM.revokePermission(packageName, permissionName);
+        } catch (RemoteException e) {
+            throw new RuntimeException("Package manager has died", e);
+        }
+    }
+
+    @Override
     public int checkSignatures(String pkg1, String pkg2) {
         try {
             return mPM.checkSignatures(pkg1, pkg2);
diff --git a/core/java/android/app/Fragment.java b/core/java/android/app/Fragment.java
index f427e78..492fcc7 100644
--- a/core/java/android/app/Fragment.java
+++ b/core/java/android/app/Fragment.java
@@ -149,7 +149,7 @@
  * {@link Fragment#getFragmentManager() Fragment.getFragmentManager()}.
  *
  * <p>The Fragment class can be used many ways to achieve a wide variety of
- * results.  It is core, it represents a particular operation or interface
+ * results. In its core, it represents a particular operation or interface
  * that is running within a larger {@link Activity}.  A Fragment is closely
  * tied to the Activity it is in, and can not be used apart from one.  Though
  * Fragment defines its own lifecycle, that lifecycle is dependent on its
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index a1198de..111f45e 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -1646,6 +1646,17 @@
 
     /**
      * Use with {@link #getSystemService} to retrieve a {@link
+     * android.os.IUpdateLock} for managing runtime sequences that
+     * must not be interrupted by headless OTA application or similar.
+     *
+     * @hide
+     * @see #getSystemService
+     * @see android.os.UpdateLock
+     */
+    public static final String UPDATE_LOCK_SERVICE = "updatelock";
+
+    /**
+     * Use with {@link #getSystemService} to retrieve a {@link
      * android.net.NetworkManagementService} for handling management of
      * system network services
      *
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index bb35c29..95b6fee 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -81,7 +81,11 @@
     boolean addPermission(in PermissionInfo info);
     
     void removePermission(String name);
-    
+
+    void grantPermission(String packageName, String permissionName);
+
+    void revokePermission(String packageName, String permissionName);
+
     boolean isProtectedBroadcast(String actionName);
     
     int checkSignatures(String pkg1, String pkg2);
diff --git a/core/java/android/content/pm/PackageInfo.java b/core/java/android/content/pm/PackageInfo.java
index eb05d76..415d58a 100644
--- a/core/java/android/content/pm/PackageInfo.java
+++ b/core/java/android/content/pm/PackageInfo.java
@@ -141,6 +141,30 @@
     public String[] requestedPermissions;
     
     /**
+     * Array of flags of all {@link android.R.styleable#AndroidManifestUsesPermission
+     * &lt;uses-permission&gt;} tags included under &lt;manifest&gt;,
+     * or null if there were none.  This is only filled in if the flag
+     * {@link PackageManager#GET_PERMISSIONS} was set.  Each value matches
+     * the corresponding entry in {@link #requestedPermissions}, and will have
+     * the flags {@link #REQUESTED_PERMISSION_REQUIRED} and
+     * {@link #REQUESTED_PERMISSION_GRANTED} set as appropriate.
+     */
+    public int[] requestedPermissionsFlags;
+
+    /**
+     * Flag for {@link #requestedPermissionsFlags}: the requested permission
+     * is required for the application to run; the user can not optionally
+     * disable it.
+     */
+    public static final int REQUESTED_PERMISSION_REQUIRED = 1<<0;
+
+    /**
+     * Flag for {@link #requestedPermissionsFlags}: the requested permission
+     * is currently granted to the application.
+     */
+    public static final int REQUESTED_PERMISSION_GRANTED = 1<<1;
+
+    /**
      * Array of all signatures read from the package file.  This is only filled
      * in if the flag {@link PackageManager#GET_SIGNATURES} was set.
      */
@@ -229,6 +253,7 @@
         dest.writeTypedArray(instrumentation, parcelableFlags);
         dest.writeTypedArray(permissions, parcelableFlags);
         dest.writeStringArray(requestedPermissions);
+        dest.writeIntArray(requestedPermissionsFlags);
         dest.writeTypedArray(signatures, parcelableFlags);
         dest.writeTypedArray(configPreferences, parcelableFlags);
         dest.writeTypedArray(reqFeatures, parcelableFlags);
@@ -266,6 +291,7 @@
         instrumentation = source.createTypedArray(InstrumentationInfo.CREATOR);
         permissions = source.createTypedArray(PermissionInfo.CREATOR);
         requestedPermissions = source.createStringArray();
+        requestedPermissionsFlags = source.createIntArray();
         signatures = source.createTypedArray(Signature.CREATOR);
         configPreferences = source.createTypedArray(ConfigurationInfo.CREATOR);
         reqFeatures = source.createTypedArray(FeatureInfo.CREATOR);
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 26a9181..f2133d8 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -1475,6 +1475,29 @@
     public abstract void removePermission(String name);
 
     /**
+     * Grant a permission to an application which the application does not
+     * already have.  The permission must have been requested by the application,
+     * but as an optional permission.  If the application is not allowed to
+     * hold the permission, a SecurityException is thrown.
+     * @hide
+     *
+     * @param packageName The name of the package that the permission will be
+     * granted to.
+     * @param permissionName The name of the permission.
+     */
+    public abstract void grantPermission(String packageName, String permissionName);
+
+    /**
+     * Revoke a permission that was previously granted by {@link #grantPermission}.
+     * @hide
+     *
+     * @param packageName The name of the package that the permission will be
+     * granted to.
+     * @param permissionName The name of the permission.
+     */
+    public abstract void revokePermission(String packageName, String permissionName);
+
+    /**
      * Compare the signatures of two packages to determine if the same
      * signature appears in both of them.  If they do contain the same
      * signature, then they are allowed special privileges when working
@@ -2125,7 +2148,7 @@
         if ((flags & GET_SIGNATURES) != 0) {
             packageParser.collectCertificates(pkg, 0);
         }
-        return PackageParser.generatePackageInfo(pkg, null, flags, 0, 0);
+        return PackageParser.generatePackageInfo(pkg, null, flags, 0, 0, null);
     }
 
     /**
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 8029bd5..7b4a0ad 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -51,6 +51,7 @@
 import java.security.spec.X509EncodedKeySpec;
 import java.util.ArrayList;
 import java.util.Enumeration;
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.jar.Attributes;
@@ -211,7 +212,8 @@
      * @param flags indicating which optional information is included.
      */
     public static PackageInfo generatePackageInfo(PackageParser.Package p,
-            int gids[], int flags, long firstInstallTime, long lastUpdateTime) {
+            int gids[], int flags, long firstInstallTime, long lastUpdateTime,
+            HashSet<String> grantedPermissions) {
 
         final int userId = Binder.getOrigCallingUser();
 
@@ -346,8 +348,16 @@
             N = p.requestedPermissions.size();
             if (N > 0) {
                 pi.requestedPermissions = new String[N];
+                pi.requestedPermissionsFlags = new int[N];
                 for (int i=0; i<N; i++) {
-                    pi.requestedPermissions[i] = p.requestedPermissions.get(i);
+                    final String perm = p.requestedPermissions.get(i);
+                    pi.requestedPermissions[i] = perm;
+                    if (p.requestedPermissionsRequired.get(i)) {
+                        pi.requestedPermissionsFlags[i] |= PackageInfo.REQUESTED_PERMISSION_REQUIRED;
+                    }
+                    if (grantedPermissions != null && grantedPermissions.contains(perm)) {
+                        pi.requestedPermissionsFlags[i] |= PackageInfo.REQUESTED_PERMISSION_GRANTED;
+                    }
                 }
             }
         }
@@ -927,11 +937,14 @@
                 // that may change.
                 String name = sa.getNonResourceString(
                         com.android.internal.R.styleable.AndroidManifestUsesPermission_name);
+                boolean required = sa.getBoolean(
+                        com.android.internal.R.styleable.AndroidManifestUsesPermission_required, true);
 
                 sa.recycle();
 
                 if (name != null && !pkg.requestedPermissions.contains(name)) {
                     pkg.requestedPermissions.add(name.intern());
+                    pkg.requestedPermissionsRequired.add(required);
                 }
 
                 XmlUtils.skipCurrentTag(parser);
@@ -1419,12 +1432,24 @@
                 PermissionInfo.PROTECTION_NORMAL);
 
         sa.recycle();
-        
+
         if (perm.info.protectionLevel == -1) {
             outError[0] = "<permission> does not specify protectionLevel";
             mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
             return null;
         }
+
+        perm.info.protectionLevel = PermissionInfo.fixProtectionLevel(perm.info.protectionLevel);
+
+        if ((perm.info.protectionLevel&PermissionInfo.PROTECTION_MASK_FLAGS) != 0) {
+            if ((perm.info.protectionLevel&PermissionInfo.PROTECTION_MASK_BASE) !=
+                    PermissionInfo.PROTECTION_SIGNATURE) {
+                outError[0] = "<permission>  protectionLevel specifies a flag but is "
+                        + "not based on signature type";
+                mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
+                return null;
+            }
+        }
         
         if (!parseAllMetaData(res, parser, attrs, "<permission>", perm,
                 outError)) {
@@ -2951,6 +2976,7 @@
         public final ArrayList<Instrumentation> instrumentation = new ArrayList<Instrumentation>(0);
 
         public final ArrayList<String> requestedPermissions = new ArrayList<String>();
+        public final ArrayList<Boolean> requestedPermissionsRequired = new ArrayList<Boolean>();
 
         public ArrayList<String> protectedBroadcasts;
         
diff --git a/core/java/android/content/pm/PermissionInfo.java b/core/java/android/content/pm/PermissionInfo.java
index 3cc884b..69b812c 100644
--- a/core/java/android/content/pm/PermissionInfo.java
+++ b/core/java/android/content/pm/PermissionInfo.java
@@ -55,6 +55,30 @@
     public static final int PROTECTION_SIGNATURE_OR_SYSTEM = 3;
 
     /**
+     * Additional flag for {@link #protectionLevel}, corresponding
+     * to the <code>system</code> value of
+     * {@link android.R.attr#protectionLevel}.
+     */
+    public static final int PROTECTION_FLAG_SYSTEM = 0x10;
+
+    /**
+     * Additional flag for {@link #protectionLevel}, corresponding
+     * to the <code>development</code> value of
+     * {@link android.R.attr#protectionLevel}.
+     */
+    public static final int PROTECTION_FLAG_DEVELOPMENT = 0x20;
+
+    /**
+     * Mask for {@link #protectionLevel}: the basic protection type.
+     */
+    public static final int PROTECTION_MASK_BASE = 0xf;
+
+    /**
+     * Mask for {@link #protectionLevel}: additional flag bits.
+     */
+    public static final int PROTECTION_MASK_FLAGS = 0xf0;
+
+    /**
      * The group this permission is a part of, as per
      * {@link android.R.attr#permissionGroup}.
      */
@@ -79,10 +103,47 @@
      * The level of access this permission is protecting, as per
      * {@link android.R.attr#protectionLevel}.  Values may be
      * {@link #PROTECTION_NORMAL}, {@link #PROTECTION_DANGEROUS}, or
+     * {@link #PROTECTION_SIGNATURE}.  May also include the additional
+     * flags {@link #PROTECTION_FLAG_SYSTEM} or {@link #PROTECTION_FLAG_DEVELOPMENT}
+     * (which only make sense in combination with the base
      * {@link #PROTECTION_SIGNATURE}.
      */
     public int protectionLevel;
 
+    /** @hide */
+    public static int fixProtectionLevel(int level) {
+        if (level == PROTECTION_SIGNATURE_OR_SYSTEM) {
+            level = PROTECTION_SIGNATURE | PROTECTION_FLAG_SYSTEM;
+        }
+        return level;
+    }
+
+    /** @hide */
+    public static String protectionToString(int level) {
+        String protLevel = "????";
+        switch (level&PROTECTION_MASK_BASE) {
+            case PermissionInfo.PROTECTION_DANGEROUS:
+                protLevel = "dangerous";
+                break;
+            case PermissionInfo.PROTECTION_NORMAL:
+                protLevel = "normal";
+                break;
+            case PermissionInfo.PROTECTION_SIGNATURE:
+                protLevel = "signature";
+                break;
+            case PermissionInfo.PROTECTION_SIGNATURE_OR_SYSTEM:
+                protLevel = "signatureOrSystem";
+                break;
+        }
+        if ((level&PermissionInfo.PROTECTION_FLAG_SYSTEM) != 0) {
+            protLevel += "|system";
+        }
+        if ((level&PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) {
+            protLevel += "|development";
+        }
+        return protLevel;
+    }
+
     public PermissionInfo() {
     }
 
diff --git a/core/java/android/content/res/Configuration.java b/core/java/android/content/res/Configuration.java
index e04b2f7..079f739 100644
--- a/core/java/android/content/res/Configuration.java
+++ b/core/java/android/content/res/Configuration.java
@@ -20,6 +20,7 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.util.LocaleUtil;
+import android.view.View;
 
 import java.util.Locale;
 
@@ -280,9 +281,9 @@
     public int compatSmallestScreenWidthDp;
 
     /**
-     * @hide The text layout direction associated to the current Locale
+     * @hide The layout direction associated to the current Locale
      */
-    public int textLayoutDirection;
+    public int layoutDirection;
 
     /**
      * @hide Internal book-keeping.
@@ -310,7 +311,7 @@
         mnc = o.mnc;
         if (o.locale != null) {
             locale = (Locale) o.locale.clone();
-            textLayoutDirection = o.textLayoutDirection;
+            layoutDirection = o.layoutDirection;
         }
         userSetLocale = o.userSetLocale;
         touchscreen = o.touchscreen;
@@ -346,10 +347,10 @@
         } else {
             sb.append(" (no locale)");
         }
-        switch (textLayoutDirection) {
-            case LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE: /* ltr not interesting */ break;
-            case LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE: sb.append(" rtl"); break;
-            default: sb.append(" layoutdir="); sb.append(textLayoutDirection); break;
+        switch (layoutDirection) {
+            case View.LAYOUT_DIRECTION_LTR: /* ltr not interesting */ break;
+            case View.LAYOUT_DIRECTION_RTL: sb.append(" rtl"); break;
+            default: sb.append(" layoutDir="); sb.append(layoutDirection); break;
         }
         if (smallestScreenWidthDp != SMALLEST_SCREEN_WIDTH_DP_UNDEFINED) {
             sb.append(" sw"); sb.append(smallestScreenWidthDp); sb.append("dp");
@@ -472,7 +473,7 @@
         screenWidthDp = compatScreenWidthDp = SCREEN_WIDTH_DP_UNDEFINED;
         screenHeightDp = compatScreenHeightDp = SCREEN_HEIGHT_DP_UNDEFINED;
         smallestScreenWidthDp = compatSmallestScreenWidthDp = SMALLEST_SCREEN_WIDTH_DP_UNDEFINED;
-        textLayoutDirection = LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE;
+        layoutDirection = View.LAYOUT_DIRECTION_LTR;
         seq = 0;
     }
 
@@ -508,7 +509,7 @@
             changed |= ActivityInfo.CONFIG_LOCALE;
             locale = delta.locale != null
                     ? (Locale) delta.locale.clone() : null;
-            textLayoutDirection = LocaleUtil.getLayoutDirectionFromLocale(locale);
+            layoutDirection = LocaleUtil.getLayoutDirectionFromLocale(locale);
         }
         if (delta.userSetLocale && (!userSetLocale || ((changed & ActivityInfo.CONFIG_LOCALE) != 0)))
         {
@@ -776,7 +777,7 @@
         dest.writeInt(compatScreenWidthDp);
         dest.writeInt(compatScreenHeightDp);
         dest.writeInt(compatSmallestScreenWidthDp);
-        dest.writeInt(textLayoutDirection);
+        dest.writeInt(layoutDirection);
         dest.writeInt(seq);
     }
 
@@ -804,7 +805,7 @@
         compatScreenWidthDp = source.readInt();
         compatScreenHeightDp = source.readInt();
         compatSmallestScreenWidthDp = source.readInt();
-        textLayoutDirection = source.readInt();
+        layoutDirection = source.readInt();
         seq = source.readInt();
     }
     
diff --git a/core/java/android/database/sqlite/SQLiteConnectionPool.java b/core/java/android/database/sqlite/SQLiteConnectionPool.java
index 236948e..3562e89 100644
--- a/core/java/android/database/sqlite/SQLiteConnectionPool.java
+++ b/core/java/android/database/sqlite/SQLiteConnectionPool.java
@@ -92,13 +92,25 @@
             new ArrayList<SQLiteConnection>();
     private SQLiteConnection mAvailablePrimaryConnection;
 
+    // Describes what should happen to an acquired connection when it is returned to the pool.
+    enum AcquiredConnectionStatus {
+        // The connection should be returned to the pool as usual.
+        NORMAL,
+
+        // The connection must be reconfigured before being returned.
+        RECONFIGURE,
+
+        // The connection must be closed and discarded.
+        DISCARD,
+    }
+
     // Weak references to all acquired connections.  The associated value
-    // is a boolean that indicates whether the connection must be reconfigured
-    // before being returned to the available connection list.
+    // indicates whether the connection must be reconfigured before being
+    // returned to the available connection list or discarded.
     // For example, the prepared statement cache size may have changed and
-    // need to be updated.
-    private final WeakHashMap<SQLiteConnection, Boolean> mAcquiredConnections =
-            new WeakHashMap<SQLiteConnection, Boolean>();
+    // need to be updated in preparation for the next client.
+    private final WeakHashMap<SQLiteConnection, AcquiredConnectionStatus> mAcquiredConnections =
+            new WeakHashMap<SQLiteConnection, AcquiredConnectionStatus>();
 
     /**
      * Connection flag: Read-only.
@@ -168,7 +180,7 @@
     private void open() {
         // Open the primary connection.
         // This might throw if the database is corrupt.
-        mAvailablePrimaryConnection = openConnectionLocked(
+        mAvailablePrimaryConnection = openConnectionLocked(mConfiguration,
                 true /*primaryConnection*/); // might throw
 
         // Mark the pool as being open for business.
@@ -209,16 +221,7 @@
 
                 mIsOpen = false;
 
-                final int count = mAvailableNonPrimaryConnections.size();
-                for (int i = 0; i < count; i++) {
-                    closeConnectionAndLogExceptionsLocked(mAvailableNonPrimaryConnections.get(i));
-                }
-                mAvailableNonPrimaryConnections.clear();
-
-                if (mAvailablePrimaryConnection != null) {
-                    closeConnectionAndLogExceptionsLocked(mAvailablePrimaryConnection);
-                    mAvailablePrimaryConnection = null;
-                }
+                closeAvailableConnectionsAndLogExceptionsLocked();
 
                 final int pendingCount = mAcquiredConnections.size();
                 if (pendingCount != 0) {
@@ -254,21 +257,27 @@
         synchronized (mLock) {
             throwIfClosedLocked();
 
-            final boolean poolSizeChanged = mConfiguration.maxConnectionPoolSize
-                    != configuration.maxConnectionPoolSize;
-            mConfiguration.updateParametersFrom(configuration);
+            if (mConfiguration.openFlags != configuration.openFlags) {
+                // Try to reopen the primary connection using the new open flags then
+                // close and discard all existing connections.
+                // This might throw if the database is corrupt or cannot be opened in
+                // the new mode in which case existing connections will remain untouched.
+                SQLiteConnection newPrimaryConnection = openConnectionLocked(configuration,
+                        true /*primaryConnection*/); // might throw
 
-            if (poolSizeChanged) {
-                int availableCount = mAvailableNonPrimaryConnections.size();
-                while (availableCount-- > mConfiguration.maxConnectionPoolSize - 1) {
-                    SQLiteConnection connection =
-                            mAvailableNonPrimaryConnections.remove(availableCount);
-                    closeConnectionAndLogExceptionsLocked(connection);
-                }
+                closeAvailableConnectionsAndLogExceptionsLocked();
+                discardAcquiredConnectionsLocked();
+
+                mAvailablePrimaryConnection = newPrimaryConnection;
+                mConfiguration.updateParametersFrom(configuration);
+            } else {
+                // Reconfigure the database connections in place.
+                mConfiguration.updateParametersFrom(configuration);
+
+                closeExcessConnectionsAndLogExceptionsLocked();
+                reconfigureAllConnectionsLocked();
             }
 
-            reconfigureAllConnectionsLocked();
-
             wakeConnectionWaitersLocked();
         }
     }
@@ -310,8 +319,8 @@
      */
     public void releaseConnection(SQLiteConnection connection) {
         synchronized (mLock) {
-            Boolean mustReconfigure = mAcquiredConnections.remove(connection);
-            if (mustReconfigure == null) {
+            AcquiredConnectionStatus status = mAcquiredConnections.remove(connection);
+            if (status == null) {
                 throw new IllegalStateException("Cannot perform this operation "
                         + "because the specified connection was not acquired "
                         + "from this pool or has already been released.");
@@ -320,18 +329,8 @@
             if (!mIsOpen) {
                 closeConnectionAndLogExceptionsLocked(connection);
             } else if (connection.isPrimaryConnection()) {
-                assert mAvailablePrimaryConnection == null;
-                try {
-                    if (mustReconfigure == Boolean.TRUE) {
-                        connection.reconfigure(mConfiguration); // might throw
-                    }
-                } catch (RuntimeException ex) {
-                    Log.e(TAG, "Failed to reconfigure released primary connection, closing it: "
-                            + connection, ex);
-                    closeConnectionAndLogExceptionsLocked(connection);
-                    connection = null;
-                }
-                if (connection != null) {
+                if (recycleConnectionLocked(connection, status)) {
+                    assert mAvailablePrimaryConnection == null;
                     mAvailablePrimaryConnection = connection;
                 }
                 wakeConnectionWaitersLocked();
@@ -339,17 +338,7 @@
                     mConfiguration.maxConnectionPoolSize - 1) {
                 closeConnectionAndLogExceptionsLocked(connection);
             } else {
-                try {
-                    if (mustReconfigure == Boolean.TRUE) {
-                        connection.reconfigure(mConfiguration); // might throw
-                    }
-                } catch (RuntimeException ex) {
-                    Log.e(TAG, "Failed to reconfigure released non-primary connection, "
-                            + "closing it: " + connection, ex);
-                    closeConnectionAndLogExceptionsLocked(connection);
-                    connection = null;
-                }
-                if (connection != null) {
+                if (recycleConnectionLocked(connection, status)) {
                     mAvailableNonPrimaryConnections.add(connection);
                 }
                 wakeConnectionWaitersLocked();
@@ -357,6 +346,25 @@
         }
     }
 
+    // Can't throw.
+    private boolean recycleConnectionLocked(SQLiteConnection connection,
+            AcquiredConnectionStatus status) {
+        if (status == AcquiredConnectionStatus.RECONFIGURE) {
+            try {
+                connection.reconfigure(mConfiguration); // might throw
+            } catch (RuntimeException ex) {
+                Log.e(TAG, "Failed to reconfigure released connection, closing it: "
+                        + connection, ex);
+                status = AcquiredConnectionStatus.DISCARD;
+            }
+        }
+        if (status == AcquiredConnectionStatus.DISCARD) {
+            closeConnectionAndLogExceptionsLocked(connection);
+            return false;
+        }
+        return true;
+    }
+
     /**
      * Returns true if the session should yield the connection due to
      * contention over available database connections.
@@ -407,9 +415,10 @@
     }
 
     // Might throw.
-    private SQLiteConnection openConnectionLocked(boolean primaryConnection) {
+    private SQLiteConnection openConnectionLocked(SQLiteDatabaseConfiguration configuration,
+            boolean primaryConnection) {
         final int connectionId = mNextConnectionId++;
-        return SQLiteConnection.open(this, mConfiguration,
+        return SQLiteConnection.open(this, configuration,
                 connectionId, primaryConnection); // might throw
     }
 
@@ -443,6 +452,30 @@
     }
 
     // Can't throw.
+    private void closeAvailableConnectionsAndLogExceptionsLocked() {
+        final int count = mAvailableNonPrimaryConnections.size();
+        for (int i = 0; i < count; i++) {
+            closeConnectionAndLogExceptionsLocked(mAvailableNonPrimaryConnections.get(i));
+        }
+        mAvailableNonPrimaryConnections.clear();
+
+        if (mAvailablePrimaryConnection != null) {
+            closeConnectionAndLogExceptionsLocked(mAvailablePrimaryConnection);
+            mAvailablePrimaryConnection = null;
+        }
+    }
+
+    // Can't throw.
+    private void closeExcessConnectionsAndLogExceptionsLocked() {
+        int availableCount = mAvailableNonPrimaryConnections.size();
+        while (availableCount-- > mConfiguration.maxConnectionPoolSize - 1) {
+            SQLiteConnection connection =
+                    mAvailableNonPrimaryConnections.remove(availableCount);
+            closeConnectionAndLogExceptionsLocked(connection);
+        }
+    }
+
+    // Can't throw.
     private void closeConnectionAndLogExceptionsLocked(SQLiteConnection connection) {
         try {
             connection.close(); // might throw
@@ -453,8 +486,12 @@
     }
 
     // Can't throw.
+    private void discardAcquiredConnectionsLocked() {
+        markAcquiredConnectionsLocked(AcquiredConnectionStatus.DISCARD);
+    }
+
+    // Can't throw.
     private void reconfigureAllConnectionsLocked() {
-        boolean wake = false;
         if (mAvailablePrimaryConnection != null) {
             try {
                 mAvailablePrimaryConnection.reconfigure(mConfiguration); // might throw
@@ -463,7 +500,6 @@
                         + mAvailablePrimaryConnection, ex);
                 closeConnectionAndLogExceptionsLocked(mAvailablePrimaryConnection);
                 mAvailablePrimaryConnection = null;
-                wake = true;
             }
         }
 
@@ -478,27 +514,30 @@
                 closeConnectionAndLogExceptionsLocked(connection);
                 mAvailableNonPrimaryConnections.remove(i--);
                 count -= 1;
-                wake = true;
             }
         }
 
+        markAcquiredConnectionsLocked(AcquiredConnectionStatus.RECONFIGURE);
+    }
+
+    // Can't throw.
+    private void markAcquiredConnectionsLocked(AcquiredConnectionStatus status) {
         if (!mAcquiredConnections.isEmpty()) {
             ArrayList<SQLiteConnection> keysToUpdate = new ArrayList<SQLiteConnection>(
                     mAcquiredConnections.size());
-            for (Map.Entry<SQLiteConnection, Boolean> entry : mAcquiredConnections.entrySet()) {
-                if (entry.getValue() != Boolean.TRUE) {
+            for (Map.Entry<SQLiteConnection, AcquiredConnectionStatus> entry
+                    : mAcquiredConnections.entrySet()) {
+                AcquiredConnectionStatus oldStatus = entry.getValue();
+                if (status != oldStatus
+                        && oldStatus != AcquiredConnectionStatus.DISCARD) {
                     keysToUpdate.add(entry.getKey());
                 }
             }
             final int updateCount = keysToUpdate.size();
             for (int i = 0; i < updateCount; i++) {
-                mAcquiredConnections.put(keysToUpdate.get(i), Boolean.TRUE);
+                mAcquiredConnections.put(keysToUpdate.get(i), status);
             }
         }
-
-        if (wake) {
-            wakeConnectionWaitersLocked();
-        }
     }
 
     // Might throw.
@@ -658,8 +697,7 @@
         int activeConnections = 0;
         int idleConnections = 0;
         if (!mAcquiredConnections.isEmpty()) {
-            for (Map.Entry<SQLiteConnection, Boolean> entry : mAcquiredConnections.entrySet()) {
-                final SQLiteConnection connection = entry.getKey();
+            for (SQLiteConnection connection : mAcquiredConnections.keySet()) {
                 String description = connection.describeCurrentOperationUnsafe();
                 if (description != null) {
                     requests.add(description);
@@ -769,7 +807,8 @@
 
         // Uhoh.  No primary connection!  Either this is the first time we asked
         // for it, or maybe it leaked?
-        connection = openConnectionLocked(true /*primaryConnection*/); // might throw
+        connection = openConnectionLocked(mConfiguration,
+                true /*primaryConnection*/); // might throw
         finishAcquireConnectionLocked(connection, connectionFlags); // might throw
         return connection;
     }
@@ -807,7 +846,8 @@
         if (openConnections >= mConfiguration.maxConnectionPoolSize) {
             return null;
         }
-        connection = openConnectionLocked(false /*primaryConnection*/); // might throw
+        connection = openConnectionLocked(mConfiguration,
+                false /*primaryConnection*/); // might throw
         finishAcquireConnectionLocked(connection, connectionFlags); // might throw
         return connection;
     }
@@ -818,7 +858,7 @@
             final boolean readOnly = (connectionFlags & CONNECTION_FLAG_READ_ONLY) != 0;
             connection.setOnlyAllowReadOnlyOperations(readOnly);
 
-            mAcquiredConnections.put(connection, Boolean.FALSE);
+            mAcquiredConnections.put(connection, AcquiredConnectionStatus.NORMAL);
         } catch (RuntimeException ex) {
             Log.e(TAG, "Failed to prepare acquired connection for session, closing it: "
                     + connection +", connectionFlags=" + connectionFlags);
@@ -858,7 +898,7 @@
     private void throwIfClosedLocked() {
         if (!mIsOpen) {
             throw new IllegalStateException("Cannot perform this operation "
-                    + "because the connection pool have been closed.");
+                    + "because the connection pool has been closed.");
         }
     }
 
@@ -922,11 +962,11 @@
 
             printer.println("  Acquired connections:");
             if (!mAcquiredConnections.isEmpty()) {
-                for (Map.Entry<SQLiteConnection, Boolean> entry :
+                for (Map.Entry<SQLiteConnection, AcquiredConnectionStatus> entry :
                         mAcquiredConnections.entrySet()) {
                     final SQLiteConnection connection = entry.getKey();
                     connection.dumpUnsafe(indentedPrinter, verbose);
-                    indentedPrinter.println("  Pending reconfiguration: " + entry.getValue());
+                    indentedPrinter.println("  Status: " + entry.getValue());
                 }
             } else {
                 indentedPrinter.println("<none>");
diff --git a/core/java/android/database/sqlite/SQLiteDatabase.java b/core/java/android/database/sqlite/SQLiteDatabase.java
index 505f83e..36f678d 100644
--- a/core/java/android/database/sqlite/SQLiteDatabase.java
+++ b/core/java/android/database/sqlite/SQLiteDatabase.java
@@ -677,6 +677,38 @@
         return openDatabase(path, factory, CREATE_IF_NECESSARY, errorHandler);
     }
 
+    /**
+     * Reopens the database in read-write mode.
+     * If the database is already read-write, does nothing.
+     *
+     * @throws SQLiteException if the database could not be reopened as requested, in which
+     * case it remains open in read only mode.
+     * @throws IllegalStateException if the database is not open.
+     *
+     * @see #isReadOnly()
+     * @hide
+     */
+    public void reopenReadWrite() {
+        synchronized (mLock) {
+            throwIfNotOpenLocked();
+
+            if (!isReadOnlyLocked()) {
+                return; // nothing to do
+            }
+
+            // Reopen the database in read-write mode.
+            final int oldOpenFlags = mConfigurationLocked.openFlags;
+            mConfigurationLocked.openFlags = (mConfigurationLocked.openFlags & ~OPEN_READ_MASK)
+                    | OPEN_READWRITE;
+            try {
+                mConnectionPoolLocked.reconfigure(mConfigurationLocked);
+            } catch (RuntimeException ex) {
+                mConfigurationLocked.openFlags = oldOpenFlags;
+                throw ex;
+            }
+        }
+    }
+
     private void open() {
         try {
             try {
@@ -1902,28 +1934,6 @@
         return true;
     }
 
-    /**
-     * Prevent other threads from using the database's primary connection.
-     *
-     * This method is only used by {@link SQLiteOpenHelper} when transitioning from
-     * a readable to a writable database.  It should not be used in any other way.
-     *
-     * @see #unlockPrimaryConnection()
-     */
-    void lockPrimaryConnection() {
-        getThreadSession().beginTransaction(SQLiteSession.TRANSACTION_MODE_DEFERRED,
-                null, SQLiteConnectionPool.CONNECTION_FLAG_PRIMARY_CONNECTION_AFFINITY, null);
-    }
-
-    /**
-     * Allow other threads to use the database's primary connection.
-     *
-     * @see #lockPrimaryConnection()
-     */
-    void unlockPrimaryConnection() {
-        getThreadSession().endTransaction(null);
-    }
-
     @Override
     public String toString() {
         return "SQLiteDatabase: " + getPath();
diff --git a/core/java/android/database/sqlite/SQLiteDatabaseConfiguration.java b/core/java/android/database/sqlite/SQLiteDatabaseConfiguration.java
index bc79ad3..02ef671 100644
--- a/core/java/android/database/sqlite/SQLiteDatabaseConfiguration.java
+++ b/core/java/android/database/sqlite/SQLiteDatabaseConfiguration.java
@@ -51,17 +51,17 @@
     public final String path;
 
     /**
-     * The flags used to open the database.
-     */
-    public final int openFlags;
-
-    /**
      * The label to use to describe the database when it appears in logs.
      * This is derived from the path but is stripped to remove PII.
      */
     public final String label;
 
     /**
+     * The flags used to open the database.
+     */
+    public int openFlags;
+
+    /**
      * The maximum number of connections to retain in the connection pool.
      * Must be at least 1.
      *
@@ -103,8 +103,8 @@
         }
 
         this.path = path;
-        this.openFlags = openFlags;
         label = stripPathForLogs(path);
+        this.openFlags = openFlags;
 
         // Set default values for optional parameters.
         maxConnectionPoolSize = 1;
@@ -123,7 +123,6 @@
         }
 
         this.path = other.path;
-        this.openFlags = other.openFlags;
         this.label = other.label;
         updateParametersFrom(other);
     }
@@ -138,11 +137,12 @@
         if (other == null) {
             throw new IllegalArgumentException("other must not be null.");
         }
-        if (!path.equals(other.path) || openFlags != other.openFlags) {
+        if (!path.equals(other.path)) {
             throw new IllegalArgumentException("other configuration must refer to "
                     + "the same database.");
         }
 
+        openFlags = other.openFlags;
         maxConnectionPoolSize = other.maxConnectionPoolSize;
         maxSqlCacheSize = other.maxSqlCacheSize;
         locale = other.locale;
diff --git a/core/java/android/database/sqlite/SQLiteOpenHelper.java b/core/java/android/database/sqlite/SQLiteOpenHelper.java
index 46d9369..ffa4663 100644
--- a/core/java/android/database/sqlite/SQLiteOpenHelper.java
+++ b/core/java/android/database/sqlite/SQLiteOpenHelper.java
@@ -43,13 +43,21 @@
 public abstract class SQLiteOpenHelper {
     private static final String TAG = SQLiteOpenHelper.class.getSimpleName();
 
+    // When true, getReadableDatabase returns a read-only database if it is just being opened.
+    // The database handle is reopened in read/write mode when getWritableDatabase is called.
+    // We leave this behavior disabled in production because it is inefficient and breaks
+    // many applications.  For debugging purposes it can be useful to turn on strict
+    // read-only semantics to catch applications that call getReadableDatabase when they really
+    // wanted getWritableDatabase.
+    private static final boolean DEBUG_STRICT_READONLY = false;
+
     private final Context mContext;
     private final String mName;
     private final CursorFactory mFactory;
     private final int mNewVersion;
 
-    private SQLiteDatabase mDatabase = null;
-    private boolean mIsInitializing = false;
+    private SQLiteDatabase mDatabase;
+    private boolean mIsInitializing;
     private final DatabaseErrorHandler mErrorHandler;
 
     /**
@@ -127,76 +135,9 @@
      * @throws SQLiteException if the database cannot be opened for writing
      * @return a read/write database object valid until {@link #close} is called
      */
-    public synchronized SQLiteDatabase getWritableDatabase() {
-        if (mDatabase != null) {
-            if (!mDatabase.isOpen()) {
-                // darn! the user closed the database by calling mDatabase.close()
-                mDatabase = null;
-            } else if (!mDatabase.isReadOnly()) {
-                return mDatabase;  // The database is already open for business
-            }
-        }
-
-        if (mIsInitializing) {
-            throw new IllegalStateException("getWritableDatabase called recursively");
-        }
-
-        // If we have a read-only database open, someone could be using it
-        // (though they shouldn't), which would cause a lock to be held on
-        // the file, and our attempts to open the database read-write would
-        // fail waiting for the file lock.  To prevent that, we acquire a lock
-        // on the read-only database, which shuts out other users.
-
-        boolean success = false;
-        SQLiteDatabase db = null;
-        if (mDatabase != null) {
-            mDatabase.lockPrimaryConnection();
-        }
-        try {
-            mIsInitializing = true;
-            if (mName == null) {
-                db = SQLiteDatabase.create(null);
-            } else {
-                db = mContext.openOrCreateDatabase(mName, 0, mFactory, mErrorHandler);
-            }
-
-            int version = db.getVersion();
-            if (version != mNewVersion) {
-                db.beginTransaction();
-                try {
-                    if (version == 0) {
-                        onCreate(db);
-                    } else {
-                        if (version > mNewVersion) {
-                            onDowngrade(db, version, mNewVersion);
-                        } else {
-                            onUpgrade(db, version, mNewVersion);
-                        }
-                    }
-                    db.setVersion(mNewVersion);
-                    db.setTransactionSuccessful();
-                } finally {
-                    db.endTransaction();
-                }
-            }
-
-            onOpen(db);
-            success = true;
-            return db;
-        } finally {
-            mIsInitializing = false;
-            if (success) {
-                if (mDatabase != null) {
-                    try { mDatabase.close(); } catch (Exception e) { }
-                    mDatabase.unlockPrimaryConnection();
-                }
-                mDatabase = db;
-            } else {
-                if (mDatabase != null) {
-                    mDatabase.unlockPrimaryConnection();
-                }
-                if (db != null) db.close();
-            }
+    public SQLiteDatabase getWritableDatabase() {
+        synchronized (this) {
+            return getDatabaseLocked(true);
         }
     }
 
@@ -218,45 +159,95 @@
      * @return a database object valid until {@link #getWritableDatabase}
      *     or {@link #close} is called.
      */
-    public synchronized SQLiteDatabase getReadableDatabase() {
+    public SQLiteDatabase getReadableDatabase() {
+        synchronized (this) {
+            return getDatabaseLocked(false);
+        }
+    }
+
+    private SQLiteDatabase getDatabaseLocked(boolean writable) {
         if (mDatabase != null) {
             if (!mDatabase.isOpen()) {
-                // darn! the user closed the database by calling mDatabase.close()
+                // Darn!  The user closed the database by calling mDatabase.close().
                 mDatabase = null;
-            } else {
-                return mDatabase;  // The database is already open for business
+            } else if (!writable || !mDatabase.isReadOnly()) {
+                // The database is already open for business.
+                return mDatabase;
             }
         }
 
         if (mIsInitializing) {
-            throw new IllegalStateException("getReadableDatabase called recursively");
+            throw new IllegalStateException("getDatabase called recursively");
         }
 
-        try {
-            return getWritableDatabase();
-        } catch (SQLiteException e) {
-            if (mName == null) throw e;  // Can't open a temp database read-only!
-            Log.e(TAG, "Couldn't open " + mName + " for writing (will try read-only):", e);
-        }
-
-        SQLiteDatabase db = null;
+        SQLiteDatabase db = mDatabase;
         try {
             mIsInitializing = true;
-            String path = mContext.getDatabasePath(mName).getPath();
-            db = SQLiteDatabase.openDatabase(path, mFactory, SQLiteDatabase.OPEN_READONLY,
-                    mErrorHandler);
-            if (db.getVersion() != mNewVersion) {
-                throw new SQLiteException("Can't upgrade read-only database from version " +
-                        db.getVersion() + " to " + mNewVersion + ": " + path);
+
+            if (db != null) {
+                if (writable && db.isReadOnly()) {
+                    db.reopenReadWrite();
+                }
+            } else if (mName == null) {
+                db = SQLiteDatabase.create(null);
+            } else {
+                try {
+                    if (DEBUG_STRICT_READONLY && !writable) {
+                        final String path = mContext.getDatabasePath(mName).getPath();
+                        db = SQLiteDatabase.openDatabase(path, mFactory,
+                                SQLiteDatabase.OPEN_READONLY, mErrorHandler);
+                    } else {
+                        db = mContext.openOrCreateDatabase(mName, 0, mFactory, mErrorHandler);
+                    }
+                } catch (SQLiteException ex) {
+                    if (writable) {
+                        throw ex;
+                    }
+                    Log.e(TAG, "Couldn't open " + mName
+                            + " for writing (will try read-only):", ex);
+                    final String path = mContext.getDatabasePath(mName).getPath();
+                    db = SQLiteDatabase.openDatabase(path, mFactory,
+                            SQLiteDatabase.OPEN_READONLY, mErrorHandler);
+                }
             }
 
+            final int version = db.getVersion();
+            if (version != mNewVersion) {
+                if (db.isReadOnly()) {
+                    throw new SQLiteException("Can't upgrade read-only database from version " +
+                            db.getVersion() + " to " + mNewVersion + ": " + mName);
+                }
+
+                db.beginTransaction();
+                try {
+                    if (version == 0) {
+                        onCreate(db);
+                    } else {
+                        if (version > mNewVersion) {
+                            onDowngrade(db, version, mNewVersion);
+                        } else {
+                            onUpgrade(db, version, mNewVersion);
+                        }
+                    }
+                    db.setVersion(mNewVersion);
+                    db.setTransactionSuccessful();
+                } finally {
+                    db.endTransaction();
+                }
+            }
             onOpen(db);
-            Log.w(TAG, "Opened " + mName + " in read-only mode");
+
+            if (db.isReadOnly()) {
+                Log.w(TAG, "Opened " + mName + " in read-only mode");
+            }
+
             mDatabase = db;
-            return mDatabase;
+            return db;
         } finally {
             mIsInitializing = false;
-            if (db != null && db != mDatabase) db.close();
+            if (db != null && db != mDatabase) {
+                db.close();
+            }
         }
     }
 
diff --git a/core/java/android/inputmethodservice/ExtractEditLayout.java b/core/java/android/inputmethodservice/ExtractEditLayout.java
index 220214b..5696839 100644
--- a/core/java/android/inputmethodservice/ExtractEditLayout.java
+++ b/core/java/android/inputmethodservice/ExtractEditLayout.java
@@ -124,6 +124,12 @@
         }
 
         @Override
+        public boolean isTitleOptional() {
+            // Not only is it optional, it will *never* be shown.
+            return true;
+        }
+
+        @Override
         public void setCustomView(View view) {
             // Custom view is not supported here.
         }
diff --git a/include/ui/android_native_buffer.h b/core/java/android/os/IUpdateLock.aidl
similarity index 66%
copy from include/ui/android_native_buffer.h
copy to core/java/android/os/IUpdateLock.aidl
index b6e1db4..4492fb8 100644
--- a/include/ui/android_native_buffer.h
+++ b/core/java/android/os/IUpdateLock.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009 The Android Open Source Project
+ * Copyright (C) 2012 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,9 +14,14 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_ANDROID_NATIVES_PRIV_H
-#define ANDROID_ANDROID_NATIVES_PRIV_H
+package android.os;
 
-#include <ui/egl/android_natives.h>
-
-#endif /* ANDROID_ANDROID_NATIVES_PRIV_H */
+/**
+ * Direct interface to the UpdateLockService's functionality
+ *
+ * {@hide}
+ */
+interface IUpdateLock {
+    void acquireUpdateLock(IBinder token, String tag);
+    void releaseUpdateLock(IBinder token);
+}
diff --git a/core/java/android/os/TokenWatcher.java b/core/java/android/os/TokenWatcher.java
index ac3cc92..9b3a2d6 100755
--- a/core/java/android/os/TokenWatcher.java
+++ b/core/java/android/os/TokenWatcher.java
@@ -16,6 +16,8 @@
 
 package android.os;
 
+import java.io.PrintWriter;
+import java.util.ArrayList;
 import java.util.WeakHashMap;
 import java.util.Set;
 import android.util.Log;
@@ -115,15 +117,31 @@
 
     public void dump()
     {
+        ArrayList<String> a = dumpInternal();
+        for (String s : a) {
+            Log.i(mTag, s);
+        }
+    }
+
+    public void dump(PrintWriter pw) {
+        ArrayList<String> a = dumpInternal();
+        for (String s : a) {
+            pw.println(s);
+        }
+    }
+
+    private ArrayList<String> dumpInternal() {
+        ArrayList<String> a = new ArrayList<String>();
         synchronized (mTokens) {
             Set<IBinder> keys = mTokens.keySet();
-            Log.i(mTag, "Token count: " + mTokens.size());
+            a.add("Token count: " + mTokens.size());
             int i = 0;
             for (IBinder b: keys) {
-                Log.i(mTag, "[" + i + "] " + mTokens.get(b).tag + " - " + b);
+                a.add("[" + i + "] " + mTokens.get(b).tag + " - " + b);
                 i++;
             }
         }
+        return a;
     }
 
     private Runnable mNotificationTask = new Runnable() {
diff --git a/core/java/android/os/UpdateLock.java b/core/java/android/os/UpdateLock.java
new file mode 100644
index 0000000..4060326
--- /dev/null
+++ b/core/java/android/os/UpdateLock.java
@@ -0,0 +1,166 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.os;
+
+import android.content.Context;
+import android.util.Log;
+
+/**
+ * Advisory wakelock-like mechanism by which processes that should not be interrupted for
+ * OTA/update purposes can so advise the OS.  This is particularly relevant for headless
+ * or kiosk-like operation.
+ *
+ * @hide
+ */
+public class UpdateLock {
+    private static final boolean DEBUG = false;
+    private static final String TAG = "UpdateLock";
+
+    private static IUpdateLock sService;
+    private static void checkService() {
+        if (sService == null) {
+            sService = IUpdateLock.Stub.asInterface(
+                    ServiceManager.getService(Context.UPDATE_LOCK_SERVICE));
+        }
+    }
+
+    IBinder mToken;
+    int mCount = 0;
+    boolean mRefCounted = true;
+    boolean mHeld = false;
+    final String mTag;
+
+    /**
+     * Broadcast Intent action sent when the global update lock state changes,
+     * i.e. when the first locker acquires an update lock, or when the last
+     * locker releases theirs.  The broadcast is sticky but is sent only to
+     * registered receivers.
+     */
+    public static final String UPDATE_LOCK_CHANGED = "android.os.UpdateLock.UPDATE_LOCK_CHANGED";
+
+    /**
+     * Boolean Intent extra on the UPDATE_LOCK_CHANGED sticky broadcast, indicating
+     * whether now is an appropriate time to interrupt device activity with an
+     * update operation.  True means that updates are okay right now; false indicates
+     * that perhaps later would be a better time.
+     */
+    public static final String NOW_IS_CONVENIENT = "nowisconvenient";
+
+    /**
+     * Long Intent extra on the UPDATE_LOCK_CHANGED sticky broadcast, marking the
+     * wall-clock time [in UTC] at which the broadcast was sent.  Note that this is
+     * in the System.currentTimeMillis() time base, which may be non-monotonic especially
+     * around reboots.
+     */
+    public static final String TIMESTAMP = "timestamp";
+
+    /**
+     * Construct an UpdateLock instance.
+     * @param tag An arbitrary string used to identify this lock instance in dump output.
+     */
+    public UpdateLock(String tag) {
+        mTag = tag;
+        mToken = new Binder();
+    }
+
+    /**
+     * Change the refcount behavior of this update lock.
+     */
+    public void setReferenceCounted(boolean isRefCounted) {
+        if (DEBUG) {
+            Log.v(TAG, "setting refcounted=" + isRefCounted + " : " + this);
+        }
+        mRefCounted = isRefCounted;
+    }
+
+    /**
+     * Is this lock currently held?
+     */
+    public boolean isHeld() {
+        synchronized (mToken) {
+            return mHeld;
+        }
+    }
+
+    /**
+     * Acquire an update lock.
+     */
+    public void acquire() {
+        if (DEBUG) {
+            Log.v(TAG, "acquire() : " + this, new RuntimeException("here"));
+        }
+        checkService();
+        synchronized (mToken) {
+            acquireLocked();
+        }
+    }
+
+    private void acquireLocked() {
+        if (!mRefCounted || mCount++ == 0) {
+            if (sService != null) {
+                try {
+                    sService.acquireUpdateLock(mToken, mTag);
+                } catch (RemoteException e) {
+                    Log.e(TAG, "Unable to contact service to acquire");
+                }
+            }
+            mHeld = true;
+        }
+    }
+
+    /**
+     * Release this update lock.
+     */
+    public void release() {
+        if (DEBUG) Log.v(TAG, "release() : " + this, new RuntimeException("here"));
+        checkService();
+        synchronized (mToken) {
+            releaseLocked();
+        }
+    }
+
+    private void releaseLocked() {
+        if (!mRefCounted || --mCount == 0) {
+            if (sService != null) {
+                try {
+                    sService.releaseUpdateLock(mToken);
+                } catch (RemoteException e) {
+                    Log.e(TAG, "Unable to contact service to release");
+                }
+            }
+            mHeld = false;
+        }
+        if (mCount < 0) {
+            throw new RuntimeException("UpdateLock under-locked");
+        }
+    }
+
+    @Override
+    protected void finalize() throws Throwable {
+        synchronized (mToken) {
+            // if mHeld is true, sService must be non-null
+            if (mHeld) {
+                Log.wtf(TAG, "UpdateLock finalized while still held");
+                try {
+                    sService.releaseUpdateLock(mToken);
+                } catch (RemoteException e) {
+                    Log.e(TAG, "Unable to contact service to release");
+                }
+            }
+        }
+    }
+}
diff --git a/core/java/android/provider/CalendarContract.java b/core/java/android/provider/CalendarContract.java
index 413150b..fa59b32f 100644
--- a/core/java/android/provider/CalendarContract.java
+++ b/core/java/android/provider/CalendarContract.java
@@ -402,8 +402,8 @@
          * A comma separated list of reminder methods supported for this
          * calendar in the format "#,#,#". Valid types are
          * {@link Reminders#METHOD_DEFAULT}, {@link Reminders#METHOD_ALERT},
-         * {@link Reminders#METHOD_EMAIL}, {@link Reminders#METHOD_SMS}. Column
-         * name.
+         * {@link Reminders#METHOD_EMAIL}, {@link Reminders#METHOD_SMS},
+         * {@link Reminders#METHOD_ALARM}. Column name.
          * <P>Type: TEXT</P>
          */
         public static final String ALLOWED_REMINDERS = "allowedReminders";
@@ -1930,11 +1930,11 @@
 
         /**
          * The alarm method, as set on the server. {@link #METHOD_DEFAULT},
-         * {@link #METHOD_ALERT}, {@link #METHOD_EMAIL}, and {@link #METHOD_SMS}
-         * are possible values; the device will only process
-         * {@link #METHOD_DEFAULT} and {@link #METHOD_ALERT} reminders (the
-         * other types are simply stored so we can send the same reminder info
-         * back to the server when we make changes).
+         * {@link #METHOD_ALERT}, {@link #METHOD_EMAIL}, {@link #METHOD_SMS} and
+         * {@link #METHOD_ALARM} are possible values; the device will only
+         * process {@link #METHOD_DEFAULT} and {@link #METHOD_ALERT} reminders
+         * (the other types are simply stored so we can send the same reminder
+         * info back to the server when we make changes).
          */
         public static final String METHOD = "method";
 
@@ -1942,6 +1942,7 @@
         public static final int METHOD_ALERT = 1;
         public static final int METHOD_EMAIL = 2;
         public static final int METHOD_SMS = 3;
+        public static final int METHOD_ALARM = 4;
     }
 
     /**
diff --git a/core/java/android/text/Html.java b/core/java/android/text/Html.java
index ca7263c..8c97293 100644
--- a/core/java/android/text/Html.java
+++ b/core/java/android/text/Html.java
@@ -16,6 +16,7 @@
 
 package android.text;
 
+import com.android.internal.util.ArrayUtils;
 import org.ccil.cowan.tagsoup.HTMLSchema;
 import org.ccil.cowan.tagsoup.Parser;
 import org.xml.sax.Attributes;
@@ -45,13 +46,11 @@
 import android.text.style.TypefaceSpan;
 import android.text.style.URLSpan;
 import android.text.style.UnderlineSpan;
-import android.util.Log;
 
 import com.android.internal.util.XmlUtils;
 
 import java.io.IOException;
 import java.io.StringReader;
-import java.nio.CharBuffer;
 import java.util.HashMap;
 
 /**
@@ -203,9 +202,26 @@
         }
     }
 
+    private static String getOpenParaTagWithDirection(Spanned text, int start, int end) {
+        final int len = end - start;
+        final byte[] levels = new byte[ArrayUtils.idealByteArraySize(len)];
+        final char[] buffer = TextUtils.obtain(len);
+        TextUtils.getChars(text, start, end, buffer, 0);
+
+        int paraDir = AndroidBidi.bidi(Layout.DIR_REQUEST_DEFAULT_LTR, buffer, levels, len,
+                false /* no info */);
+        switch(paraDir) {
+            case Layout.DIR_RIGHT_TO_LEFT:
+                return "<p dir=rtl>";
+            case Layout.DIR_LEFT_TO_RIGHT:
+            default:
+                return "<p dir=ltr>";
+        }
+    }
+
     private static void withinBlockquote(StringBuilder out, Spanned text,
                                          int start, int end) {
-        out.append("<p>");
+        out.append(getOpenParaTagWithDirection(text, start, end));
 
         int next;
         for (int i = start; i < end; i = next) {
@@ -340,7 +356,7 @@
             }
         }
 
-        String p = last ? "" : "</p>\n<p>";
+        String p = last ? "" : "</p>\n" + getOpenParaTagWithDirection(text, start, end);
 
         if (nl == 1) {
             out.append("<br>\n");
@@ -350,7 +366,6 @@
             for (int i = 2; i < nl; i++) {
                 out.append("<br>");
             }
-
             out.append(p);
         }
     }
diff --git a/core/java/android/text/StaticLayout.java b/core/java/android/text/StaticLayout.java
index 1dd4c8a..299e115 100644
--- a/core/java/android/text/StaticLayout.java
+++ b/core/java/android/text/StaticLayout.java
@@ -716,7 +716,8 @@
             boolean currentLineIsTheLastVisibleOne = (j + 1 == mMaximumVisibleLineCount);
             boolean forceEllipsis = moreChars && (mLineCount + 1 == mMaximumVisibleLineCount);
 
-            boolean doEllipsis = (firstLine && !moreChars &&
+            boolean doEllipsis =
+                        (((mMaximumVisibleLineCount == 1 && moreChars) || (firstLine && !moreChars)) &&
                                 ellipsize != TextUtils.TruncateAt.MARQUEE) ||
                         (!firstLine && (currentLineIsTheLastVisibleOne || !moreChars) &&
                                 ellipsize == TextUtils.TruncateAt.END);
diff --git a/core/java/android/text/TextDirectionHeuristics.java b/core/java/android/text/TextDirectionHeuristics.java
index ae41eab..6ca6161 100644
--- a/core/java/android/text/TextDirectionHeuristics.java
+++ b/core/java/android/text/TextDirectionHeuristics.java
@@ -18,6 +18,7 @@
 
 
 import android.util.LocaleUtil;
+import android.view.View;
 
 /**
  * Some objects that implement TextDirectionHeuristic.
@@ -240,7 +241,7 @@
         @Override
         protected boolean defaultIsRtl() {
             final int dir = LocaleUtil.getLayoutDirectionFromLocale(java.util.Locale.getDefault());
-            return (dir == LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE);
+            return (dir == View.LAYOUT_DIRECTION_RTL);
         }
 
         public static final TextDirectionHeuristicLocale INSTANCE =
diff --git a/core/java/android/util/LocaleUtil.java b/core/java/android/util/LocaleUtil.java
index 4d773f6..9953252 100644
--- a/core/java/android/util/LocaleUtil.java
+++ b/core/java/android/util/LocaleUtil.java
@@ -18,6 +18,7 @@
 
 import java.util.Locale;
 
+import android.view.View;
 import libcore.icu.ICU;
 
 /**
@@ -29,16 +30,6 @@
 
     private LocaleUtil() { /* cannot be instantiated */ }
 
-    /**
-     * @hide Do not use. Implementation not finished.
-     */
-    public static final int TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE = 0;
-
-    /**
-     * @hide Do not use. Implementation not finished.
-     */
-    public static final int TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE = 1;
-
     private static String ARAB_SCRIPT_SUBTAG = "Arab";
     private static String HEBR_SCRIPT_SUBTAG = "Hebr";
 
@@ -47,8 +38,8 @@
      *
      * @param locale the Locale for which we want the layout direction. Can be null.
      * @return the layout direction. This may be one of:
-     * {@link #TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE} or
-     * {@link #TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE}.
+     * {@link View#LAYOUT_DIRECTION_LTR} or
+     * {@link View#LAYOUT_DIRECTION_RTL}.
      *
      * Be careful: this code will need to be changed when vertical scripts will be supported
      *
@@ -61,11 +52,11 @@
 
             if (scriptSubtag.equalsIgnoreCase(ARAB_SCRIPT_SUBTAG) ||
                     scriptSubtag.equalsIgnoreCase(HEBR_SCRIPT_SUBTAG)) {
-                return TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE;
+                return View.LAYOUT_DIRECTION_RTL;
             }
         }
 
-        return TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE;
+        return View.LAYOUT_DIRECTION_LTR;
     }
 
     /**
@@ -75,8 +66,8 @@
      *
      * @param locale
      * @return the layout direction. This may be one of:
-     * {@link #TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE} or
-     * {@link #TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE}.
+     * {@link View#LAYOUT_DIRECTION_LTR} or
+     * {@link View#LAYOUT_DIRECTION_RTL}.
      *
      * Be careful: this code will need to be changed when vertical scripts will be supported
      *
@@ -86,11 +77,11 @@
         switch(Character.getDirectionality(locale.getDisplayName(locale).charAt(0))) {
             case Character.DIRECTIONALITY_RIGHT_TO_LEFT:
             case Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC:
-                return TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE;
+                return View.LAYOUT_DIRECTION_RTL;
 
             case Character.DIRECTIONALITY_LEFT_TO_RIGHT:
             default:
-                return TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE;
+                return View.LAYOUT_DIRECTION_LTR;
         }
     }
 }
diff --git a/core/java/android/view/ActionMode.java b/core/java/android/view/ActionMode.java
index c1c7fe2..0ba5fdb 100644
--- a/core/java/android/view/ActionMode.java
+++ b/core/java/android/view/ActionMode.java
@@ -104,6 +104,32 @@
     public abstract void setSubtitle(int resId);
 
     /**
+     * Set whether or not the title/subtitle display for this action mode
+     * is optional.
+     *
+     * <p>In many cases the supplied title for an action mode is merely
+     * meant to add context and is not strictly required for the action
+     * mode to be useful. If the title is optional, the system may choose
+     * to hide the title entirely rather than truncate it due to a lack
+     * of available space.</p>
+     *
+     * <p>Note that this is merely a hint; the underlying implementation
+     * may choose to ignore this setting under some circumstances.</p>
+     *
+     * @param titleOptional true if the title only presents optional information.
+     */
+    public void setTitleOptionalHint(boolean titleOptional) {
+    }
+
+    /**
+     * @return true if this action mode considers the title and subtitle fields
+     *         as optional. Optional titles may not be displayed to the user.
+     */
+    public boolean isTitleOptional() {
+        return false;
+    }
+
+    /**
      * Set a custom view for this action mode. The custom view will take the place of
      * the title and subtitle. Useful for things like search boxes.
      *
diff --git a/core/java/android/view/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java
index f5fc708..ee0fa86 100644
--- a/core/java/android/view/GLES20Canvas.java
+++ b/core/java/android/view/GLES20Canvas.java
@@ -718,7 +718,7 @@
     @Override
     public void drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter,
             Paint paint) {
-        int modifiers = setupModifiers(paint);
+        int modifiers = setupModifiers(paint, MODIFIER_COLOR_FILTER | MODIFIER_SHADER);
         try {
             nDrawArc(mRenderer, oval.left, oval.top, oval.right, oval.bottom,
                     startAngle, sweepAngle, useCenter, paint.mNativePaint);
@@ -902,7 +902,7 @@
 
     @Override
     public void drawCircle(float cx, float cy, float radius, Paint paint) {
-        int modifiers = setupModifiers(paint);
+        int modifiers = setupModifiers(paint, MODIFIER_COLOR_FILTER | MODIFIER_SHADER);
         try {
             nDrawCircle(mRenderer, cx, cy, radius, paint.mNativePaint);
         } finally {
@@ -939,7 +939,7 @@
         if ((offset | count) < 0 || offset + count > pts.length) {
             throw new IllegalArgumentException("The lines array must contain 4 elements per line.");
         }
-        int modifiers = setupModifiers(paint);
+        int modifiers = setupModifiers(paint, MODIFIER_COLOR_FILTER | MODIFIER_SHADER);
         try {
             nDrawLines(mRenderer, pts, offset, count, paint.mNativePaint);
         } finally {
@@ -957,7 +957,7 @@
 
     @Override
     public void drawOval(RectF oval, Paint paint) {
-        int modifiers = setupModifiers(paint);
+        int modifiers = setupModifiers(paint, MODIFIER_COLOR_FILTER | MODIFIER_SHADER);
         try {
             nDrawOval(mRenderer, oval.left, oval.top, oval.right, oval.bottom, paint.mNativePaint);
         } finally {
@@ -977,7 +977,7 @@
 
     @Override
     public void drawPath(Path path, Paint paint) {
-        int modifiers = setupModifiers(paint);
+        int modifiers = setupModifiers(paint, MODIFIER_COLOR_FILTER | MODIFIER_SHADER);
         try {
             if (path.isSimplePath) {
                 if (path.rects != null) {
@@ -1048,7 +1048,7 @@
 
     @Override
     public void drawPoints(float[] pts, int offset, int count, Paint paint) {
-        int modifiers = setupModifiers(paint);
+        int modifiers = setupModifiers(paint, MODIFIER_COLOR_FILTER | MODIFIER_SHADER);
         try {
             nDrawPoints(mRenderer, pts, offset, count, paint.mNativePaint);
         } finally {
@@ -1097,7 +1097,8 @@
 
     @Override
     public void drawRect(float left, float top, float right, float bottom, Paint paint) {
-        int modifiers = setupModifiers(paint);
+        if (left == right || top == bottom) return;
+        int modifiers = setupModifiers(paint, MODIFIER_COLOR_FILTER | MODIFIER_SHADER);
         try {
             nDrawRect(mRenderer, left, top, right, bottom, paint.mNativePaint);
         } finally {
@@ -1125,7 +1126,7 @@
 
     @Override
     public void drawRoundRect(RectF rect, float rx, float ry, Paint paint) {
-        int modifiers = setupModifiers(paint);
+        int modifiers = setupModifiers(paint, MODIFIER_COLOR_FILTER | MODIFIER_SHADER);
         try {
             nDrawRoundRect(mRenderer, rect.left, rect.top, rect.right, rect.bottom,
                     rx, ry, paint.mNativePaint);
@@ -1208,14 +1209,38 @@
     @Override
     public void drawTextOnPath(char[] text, int index, int count, Path path, float hOffset,
             float vOffset, Paint paint) {
-        // TODO: Implement
+        if (index < 0 || index + count > text.length) {
+            throw new ArrayIndexOutOfBoundsException();
+        }
+
+        int modifiers = setupModifiers(paint);
+        try {
+            nDrawTextOnPath(mRenderer, text, index, count, path.mNativePath, hOffset, vOffset,
+                    paint.mBidiFlags, paint.mNativePaint);
+        } finally {
+            if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
+        }
     }
 
+    private static native void nDrawTextOnPath(int renderer, char[] text, int index, int count,
+            int path, float hOffset, float vOffset, int bidiFlags, int nativePaint);
+
     @Override
     public void drawTextOnPath(String text, Path path, float hOffset, float vOffset, Paint paint) {
-        // TODO: Implement
+        if (text.length() == 0) return;
+
+        int modifiers = setupModifiers(paint);
+        try {
+            nDrawTextOnPath(mRenderer, text, 0, text.length(), path.mNativePath, hOffset, vOffset,
+                    paint.mBidiFlags, paint.mNativePaint);
+        } finally {
+            if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
+        }
     }
 
+    private static native void nDrawTextOnPath(int renderer, String text, int start, int end,
+            int path, float hOffset, float vOffset, int bidiFlags, int nativePaint);
+
     @Override
     public void drawTextRun(char[] text, int index, int count, int contextIndex, int contextCount,
             float x, float y, int dir, Paint paint) {
@@ -1317,6 +1342,30 @@
         return modifiers;
     }
 
+    private int setupModifiers(Paint paint, int flags) {
+        int modifiers = MODIFIER_NONE;
+
+        if (paint.hasShadow && (flags & MODIFIER_SHADOW) != 0) {
+            nSetupShadow(mRenderer, paint.shadowRadius, paint.shadowDx, paint.shadowDy,
+                    paint.shadowColor);
+            modifiers |= MODIFIER_SHADOW;
+        }
+
+        final Shader shader = paint.getShader();
+        if (shader != null && (flags & MODIFIER_SHADER) != 0) {
+            nSetupShader(mRenderer, shader.native_shader);
+            modifiers |= MODIFIER_SHADER;
+        }
+
+        final ColorFilter filter = paint.getColorFilter();
+        if (filter != null && (flags & MODIFIER_COLOR_FILTER) != 0) {
+            nSetupColorFilter(mRenderer, filter.nativeColorFilter);
+            modifiers |= MODIFIER_COLOR_FILTER;
+        }
+
+        return modifiers;
+    }
+
     private int setupColorFilter(Paint paint) {
         final ColorFilter filter = paint.getColorFilter();
         if (filter != null) {
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 0675a74..5cf0459 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -40,7 +40,6 @@
 import android.graphics.drawable.Drawable;
 import android.os.Handler;
 import android.os.IBinder;
-import android.os.Message;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.RemoteException;
@@ -5048,16 +5047,17 @@
      *        the View's internal state from a previously set "pressed" state.
      */
     public void setPressed(boolean pressed) {
-        if (pressed == ((mPrivateFlags & PRESSED) == PRESSED)) {
-            return;
-        }
+        final boolean needsRefresh = pressed != ((mPrivateFlags & PRESSED) == PRESSED);
 
         if (pressed) {
             mPrivateFlags |= PRESSED;
         } else {
             mPrivateFlags &= ~PRESSED;
         }
-        refreshDrawableState();
+
+        if (needsRefresh) {
+            refreshDrawableState();
+        }
         dispatchSetPressed(pressed);
     }
 
@@ -9710,8 +9710,7 @@
      * @hide
      */
     protected static boolean isLayoutDirectionRtl(Locale locale) {
-        return (LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE ==
-                LocaleUtil.getLayoutDirectionFromLocale(locale));
+        return (LAYOUT_DIRECTION_RTL == LocaleUtil.getLayoutDirectionFromLocale(locale));
     }
 
     /**
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 2848e88..05c2b57 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -2770,7 +2770,13 @@
         final View[] children = mChildren;
         final int count = mChildrenCount;
         for (int i = 0; i < count; i++) {
-            children[i].setPressed(pressed);
+            final View child = children[i];
+            // Children that are clickable on their own should not
+            // show a pressed state when their parent view does.
+            // Clearing a pressed state always propagates.
+            if (!pressed || (!child.isClickable() && !child.isLongClickable())) {
+                child.setPressed(pressed);
+            }
         }
     }
 
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 31d874f..e0d0763 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -381,6 +381,8 @@
         mAccessibilityManager = AccessibilityManager.getInstance(context);
         mAccessibilityInteractionConnectionManager =
             new AccessibilityInteractionConnectionManager();
+        mAccessibilityManager.addAccessibilityStateChangeListener(
+                mAccessibilityInteractionConnectionManager);
         mAttachInfo = new View.AttachInfo(sWindowSession, mWindow, this, mHandler, this);
         mViewConfiguration = ViewConfiguration.get(context);
         mDensity = context.getResources().getDisplayMetrics().densityDpi;
diff --git a/core/java/android/view/animation/Animation.java b/core/java/android/view/animation/Animation.java
index e8c0239..dc8c71b7 100644
--- a/core/java/android/view/animation/Animation.java
+++ b/core/java/android/view/animation/Animation.java
@@ -913,7 +913,7 @@
      * 
      * @param interpolatedTime The value of the normalized time (0.0 to 1.0)
      *        after it has been run through the interpolation function.
-     * @param t The Transofrmation object to fill in with the current
+     * @param t The Transformation object to fill in with the current
      *        transforms.
      */
     protected void applyTransformation(float interpolatedTime, Transformation t) {
diff --git a/core/java/android/view/inputmethod/BaseInputConnection.java b/core/java/android/view/inputmethod/BaseInputConnection.java
index 89aba3c..7ec5398 100644
--- a/core/java/android/view/inputmethod/BaseInputConnection.java
+++ b/core/java/android/view/inputmethod/BaseInputConnection.java
@@ -152,6 +152,15 @@
     }
 
     /**
+     * Called when this InputConnection is no longer used by the InputMethodManager.
+     *
+     * @hide
+     */
+    protected void reportFinish() {
+        // Intentionaly empty
+    }
+
+    /**
      * Default implementation uses
      * {@link MetaKeyKeyListener#clearMetaKeyState(long, int)
      * MetaKeyKeyListener.clearMetaKeyState(long, int)} to clear the state.
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index c51d244..3b6ebbe 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -26,7 +26,6 @@
 import com.android.internal.view.InputBindResult;
 
 import android.content.Context;
-import android.content.pm.PackageManager;
 import android.graphics.Rect;
 import android.os.Bundle;
 import android.os.Handler;
@@ -198,7 +197,31 @@
 
     static final Object mInstanceSync = new Object();
     static InputMethodManager mInstance;
-    
+
+    /**
+     * @hide Flag for IInputMethodManager.windowGainedFocus: a view in
+     * the window has input focus.
+     */
+    public static final int CONTROL_WINDOW_VIEW_HAS_FOCUS = 1<<0;
+
+    /**
+     * @hide Flag for IInputMethodManager.windowGainedFocus: the focus
+     * is a text editor.
+     */
+    public static final int CONTROL_WINDOW_IS_TEXT_EDITOR = 1<<1;
+
+    /**
+     * @hide Flag for IInputMethodManager.windowGainedFocus: this is the first
+     * time the window has gotten focus.
+     */
+    public static final int CONTROL_WINDOW_FIRST = 1<<2;
+
+    /**
+     * @hide Flag for IInputMethodManager.startInput: this is the first
+     * time the window has gotten focus.
+     */
+    public static final int CONTROL_START_INITIAL = 1<<8;
+
     final IInputMethodManager mService;
     final Looper mMainLooper;
     
@@ -216,7 +239,7 @@
     
     /**
      * Set whenever this client becomes inactive, to know we need to reset
-     * state with the IME then next time we receive focus.
+     * state with the IME the next time we receive focus.
      */
     boolean mHasBeenInactive = true;
     
@@ -243,11 +266,6 @@
      */
     View mNextServedView;
     /**
-     * True if we should restart input in the next served view, even if the
-     * view hasn't actually changed from the current serve view.
-     */
-    boolean mNextServedNeedsStart;
-    /**
      * This is set when we are in the process of connecting, to determine
      * when we have actually finished.
      */
@@ -331,7 +349,7 @@
                         mCurId = res.id;
                         mBindSequence = res.sequence;
                     }
-                    startInputInner();
+                    startInputInner(null, 0, 0, 0);
                     return;
                 }
                 case MSG_UNBIND: {
@@ -362,7 +380,7 @@
                         }
                     }
                     if (startInput) {
-                        startInputInner();
+                        startInputInner(null, 0, 0, 0);
                     }
                     return;
                 }
@@ -690,6 +708,10 @@
     public void reportFinishInputConnection(InputConnection ic) {
         if (mServedInputConnection != ic) {
             ic.finishComposingText();
+            // To avoid modifying the public InputConnection interface
+            if (ic instanceof BaseInputConnection) {
+                ((BaseInputConnection) ic).reportFinish();
+            }
         }
     }
 
@@ -957,10 +979,11 @@
             mServedConnecting = true;
         }
         
-        startInputInner();
+        startInputInner(null, 0, 0, 0);
     }
     
-    void startInputInner() {
+    boolean startInputInner(IBinder windowGainingFocus, int controlFlags, int softInputMode,
+            int windowFlags) {
         final View view;
         synchronized (mH) {
             view = mServedView;
@@ -969,7 +992,7 @@
             if (DEBUG) Log.v(TAG, "Starting input: view=" + view);
             if (view == null) {
                 if (DEBUG) Log.v(TAG, "ABORT input: no served view!");
-                return;
+                return false;
             }
         }
         
@@ -982,7 +1005,7 @@
             // If the view doesn't have a handler, something has changed out
             // from under us, so just bail.
             if (DEBUG) Log.v(TAG, "ABORT input: no handler for view!");
-            return;
+            return false;
         }
         if (vh.getLooper() != Looper.myLooper()) {
             // The view is running on a different thread than our own, so
@@ -990,10 +1013,10 @@
             if (DEBUG) Log.v(TAG, "Starting input: reschedule to view thread");
             vh.post(new Runnable() {
                 public void run() {
-                    startInputInner();
+                    startInputInner(null, 0, 0, 0);
                 }
             });
-            return;
+            return false;
         }
         
         // Okay we are now ready to call into the served view and have it
@@ -1013,12 +1036,14 @@
                 if (DEBUG) Log.v(TAG, 
                         "Starting input: finished by someone else (view="
                         + mServedView + " conn=" + mServedConnecting + ")");
-                return;
+                return false;
             }
-            
+
             // If we already have a text box, then this view is already
             // connected so we want to restart it.
-            final boolean initial = mCurrentTextBoxAttribute == null;
+            if (mCurrentTextBoxAttribute == null) {
+                controlFlags |= CONTROL_START_INITIAL;
+            }
             
             // Hook 'em up and let 'er rip.
             mCurrentTextBoxAttribute = tba;
@@ -1040,9 +1065,17 @@
             
             try {
                 if (DEBUG) Log.v(TAG, "START INPUT: " + view + " ic="
-                        + ic + " tba=" + tba + " initial=" + initial);
-                InputBindResult res = mService.startInput(mClient,
-                        servedContext, tba, initial, true);
+                        + ic + " tba=" + tba + " controlFlags=#"
+                        + Integer.toHexString(controlFlags));
+                InputBindResult res;
+                if (windowGainingFocus != null) {
+                    res = mService.windowGainedFocus(mClient, windowGainingFocus,
+                            controlFlags, softInputMode, windowFlags,
+                            tba, servedContext);
+                } else {
+                    res = mService.startInput(mClient,
+                            servedContext, tba, controlFlags);
+                }
                 if (DEBUG) Log.v(TAG, "Starting input: Bind result=" + res);
                 if (res != null) {
                     if (res.id != null) {
@@ -1051,7 +1084,7 @@
                     } else if (mCurMethod == null) {
                         // This means there is no input method available.
                         if (DEBUG) Log.v(TAG, "ABORT input: no input method!");
-                        return;
+                        return true;
                     }
                 }
                 if (mCurMethod != null && mCompletions != null) {
@@ -1064,6 +1097,8 @@
                 Log.w(TAG, "IME died: " + mCurId, e);
             }
         }
+
+        return true;
     }
 
     /**
@@ -1139,27 +1174,26 @@
      * @hide
      */
     public void checkFocus() {
-        if (checkFocusNoStartInput()) {
-            startInputInner();
+        if (checkFocusNoStartInput(false)) {
+            startInputInner(null, 0, 0, 0);
         }
     }
 
-    private boolean checkFocusNoStartInput() {
+    private boolean checkFocusNoStartInput(boolean forceNewFocus) {
         // This is called a lot, so short-circuit before locking.
-        if (mServedView == mNextServedView && !mNextServedNeedsStart) {
+        if (mServedView == mNextServedView && !forceNewFocus) {
             return false;
         }
 
         InputConnection ic = null;
         synchronized (mH) {
-            if (mServedView == mNextServedView && !mNextServedNeedsStart) {
+            if (mServedView == mNextServedView && !forceNewFocus) {
                 return false;
             }
             if (DEBUG) Log.v(TAG, "checkFocus: view=" + mServedView
                     + " next=" + mNextServedView
-                    + " restart=" + mNextServedNeedsStart);
+                    + " forceNewFocus=" + forceNewFocus);
 
-            mNextServedNeedsStart = false;
             if (mNextServedView == null) {
                 finishInputLocked();
                 // In this case, we used to have a focused view on the window,
@@ -1190,13 +1224,14 @@
         } catch (RemoteException e) {
         }
     }
-    
+
     /**
      * Called by ViewAncestor when its window gets input focus.
      * @hide
      */
     public void onWindowFocus(View rootView, View focusedView, int softInputMode,
             boolean first, int windowFlags) {
+        boolean forceNewFocus = false;
         synchronized (mH) {
             if (DEBUG) Log.v(TAG, "onWindowFocus: " + focusedView
                     + " softInputMode=" + softInputMode
@@ -1205,26 +1240,41 @@
             if (mHasBeenInactive) {
                 if (DEBUG) Log.v(TAG, "Has been inactive!  Starting fresh");
                 mHasBeenInactive = false;
-                mNextServedNeedsStart = true;
+                forceNewFocus = true;
             }
             focusInLocked(focusedView != null ? focusedView : rootView);
         }
-        
-        boolean startInput = checkFocusNoStartInput();
-        
-        synchronized (mH) {
-            try {
-                final boolean isTextEditor = focusedView != null &&
-                        focusedView.onCheckIsTextEditor();
-                mService.windowGainedFocus(mClient, rootView.getWindowToken(),
-                        focusedView != null, isTextEditor, softInputMode, first,
-                        windowFlags);
-            } catch (RemoteException e) {
+
+        int controlFlags = 0;
+        if (focusedView != null) {
+            controlFlags |= CONTROL_WINDOW_VIEW_HAS_FOCUS;
+            if (focusedView.onCheckIsTextEditor()) {
+                controlFlags |= CONTROL_WINDOW_IS_TEXT_EDITOR;
             }
         }
-
-        if (startInput) {
-            startInputInner();
+        if (first) {
+            controlFlags |= CONTROL_WINDOW_FIRST;
+        }
+        
+        if (checkFocusNoStartInput(forceNewFocus)) {
+            // We need to restart input on the current focus view.  This
+            // should be done in conjunction with telling the system service
+            // about the window gaining focus, to help make the transition
+            // smooth.
+            if (startInputInner(rootView.getWindowToken(),
+                    controlFlags, softInputMode, windowFlags)) {
+                return;
+            }
+        }
+        
+        // For some reason we didn't do a startInput + windowFocusGain, so
+        // we'll just do a window focus gain and call it a day.
+        synchronized (mH) {
+            try {
+                mService.windowGainedFocus(mClient, rootView.getWindowToken(),
+                        controlFlags, softInputMode, windowFlags, null, null);
+            } catch (RemoteException e) {
+            }
         }
     }
     
@@ -1676,8 +1726,7 @@
         p.println("  mCurMethod=" + mCurMethod);
         p.println("  mCurRootView=" + mCurRootView);
         p.println("  mServedView=" + mServedView);
-        p.println("  mNextServedNeedsStart=" + mNextServedNeedsStart
-                + " mNextServedView=" + mNextServedView);
+        p.println("  mNextServedView=" + mNextServedView);
         p.println("  mServedConnecting=" + mServedConnecting);
         if (mCurrentTextBoxAttribute != null) {
             p.println("  mCurrentTextBoxAttribute:");
diff --git a/core/java/android/webkit/HTML5Audio.java b/core/java/android/webkit/HTML5Audio.java
index 0baf2eb..aedecf0 100644
--- a/core/java/android/webkit/HTML5Audio.java
+++ b/core/java/android/webkit/HTML5Audio.java
@@ -142,8 +142,7 @@
 
     // MediaPlayer.OnCompletionListener;
     public void onCompletion(MediaPlayer mp) {
-        resetMediaPlayer();
-        mState = IDLE;
+        mState = COMPLETE;
         nativeOnEnded(mNativePointer);
     }
 
@@ -265,7 +264,18 @@
 
 
     private void play() {
-        if ((mState >= ERROR && mState < PREPARED) && mUrl != null) {
+        if (mState == COMPLETE) {
+            // Play it again, Sam
+            mTimer.cancel();
+            mTimer = new Timer();
+            mAskToPlay = true;
+            mMediaPlayer.stop();
+            mState = STOPPED;
+            mMediaPlayer.prepareAsync();
+            return;
+        }
+
+        if (((mState >= ERROR && mState < PREPARED)) && mUrl != null) {
             resetMediaPlayer();
             setDataSource(mUrl);
             mAskToPlay = true;
@@ -296,6 +306,12 @@
     private void seek(int msec) {
         if (mState >= PREPARED) {
             mMediaPlayer.seekTo(msec);
+            if (mState == COMPLETE) {
+                // Seeking after the stream had completed will
+                // cause us to start playing again. This is to
+                // support audio tags that specify loop=true.
+                play();
+            }
         }
     }
 
diff --git a/core/java/android/webkit/SelectActionModeCallback.java b/core/java/android/webkit/SelectActionModeCallback.java
index cdf20f6..2a770f5 100644
--- a/core/java/android/webkit/SelectActionModeCallback.java
+++ b/core/java/android/webkit/SelectActionModeCallback.java
@@ -53,10 +53,8 @@
         mode.getMenuInflater().inflate(com.android.internal.R.menu.webview_copy, menu);
 
         final Context context = mWebView.getContext();
-        boolean allowText = context.getResources().getBoolean(
-                com.android.internal.R.bool.config_allowActionMenuItemTextWithIcon);
-        mode.setTitle(allowText ?
-                context.getString(com.android.internal.R.string.textSelectionCABTitle) : null);
+        mode.setTitle(context.getString(com.android.internal.R.string.textSelectionCABTitle));
+        mode.setTitleOptionalHint(true);
 
         // If the action mode UI we're running in isn't capable of taking window focus
         // the user won't be able to type into the find on page UI. Disable this functionality.
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index b9dfb2e..af3bb4d 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -68,6 +68,7 @@
 import android.text.Selection;
 import android.text.TextUtils;
 import android.util.AttributeSet;
+import android.util.DisplayMetrics;
 import android.util.EventLog;
 import android.util.Log;
 import android.view.Display;
@@ -111,6 +112,8 @@
 import android.widget.LinearLayout;
 import android.widget.ListView;
 import android.widget.OverScroller;
+import android.widget.PopupWindow;
+import android.widget.TextView;
 import android.widget.Toast;
 
 import junit.framework.Assert;
@@ -122,7 +125,6 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
-import java.io.UnsupportedEncodingException;
 import java.net.URLDecoder;
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -376,6 +378,7 @@
         private int mInputType;
         private int mImeOptions;
         private String mHint;
+        private int mMaxLength;
 
         public WebViewInputConnection() {
             super(WebView.this, true);
@@ -410,19 +413,28 @@
             Editable editable = getEditable();
             int selectionStart = Selection.getSelectionStart(editable);
             int selectionEnd = Selection.getSelectionEnd(editable);
+            text = limitReplaceTextByMaxLength(text, editable.length());
             editable.replace(0, editable.length(), text);
-            InputMethodManager imm = InputMethodManager.peekInstance();
-            if (imm != null) {
-                // Since the text has changed, do not allow the IME to replace the
-                // existing text as though it were a completion.
-                imm.restartInput(WebView.this);
-            }
+            restartInput();
             // Keep the previous selection.
             selectionStart = Math.min(selectionStart, editable.length());
             selectionEnd = Math.min(selectionEnd, editable.length());
             setSelection(selectionStart, selectionEnd);
         }
 
+        public void replaceSelection(CharSequence text) {
+            Editable editable = getEditable();
+            int selectionStart = Selection.getSelectionStart(editable);
+            int selectionEnd = Selection.getSelectionEnd(editable);
+            text = limitReplaceTextByMaxLength(text, selectionEnd - selectionStart);
+            setNewText(selectionStart, selectionEnd, text);
+            editable.replace(selectionStart, selectionEnd, text);
+            restartInput();
+            // Move caret to the end of the new text
+            int newCaret = selectionStart + text.length();
+            setSelection(newCaret, newCaret);
+        }
+
         @Override
         public boolean setComposingText(CharSequence text, int newCursorPosition) {
             Editable editable = getEditable();
@@ -437,8 +449,19 @@
                 end = start;
                 start = temp;
             }
-            setNewText(start, end, text);
-            return super.setComposingText(text, newCursorPosition);
+            CharSequence limitedText = limitReplaceTextByMaxLength(text, end - start);
+            setNewText(start, end, limitedText);
+            if (limitedText != text) {
+                newCursorPosition -= text.length() - limitedText.length();
+            }
+            super.setComposingText(limitedText, newCursorPosition);
+            if (limitedText != text) {
+                restartInput();
+                int lastCaret = start + limitedText.length();
+                finishComposingText();
+                setSelection(lastCaret, lastCaret);
+            }
+            return true;
         }
 
         @Override
@@ -460,6 +483,38 @@
             return super.deleteSurroundingText(leftLength, rightLength);
         }
 
+        @Override
+        public boolean performEditorAction(int editorAction) {
+
+            boolean handled = true;
+            switch (editorAction) {
+            case EditorInfo.IME_ACTION_NEXT:
+                WebView.this.requestFocus(FOCUS_FORWARD);
+                break;
+            case EditorInfo.IME_ACTION_PREVIOUS:
+                WebView.this.requestFocus(FOCUS_BACKWARD);
+                break;
+            case EditorInfo.IME_ACTION_DONE:
+                WebView.this.hideSoftKeyboard();
+                break;
+            case EditorInfo.IME_ACTION_GO:
+            case EditorInfo.IME_ACTION_SEARCH:
+                WebView.this.hideSoftKeyboard();
+                String text = getEditable().toString();
+                passToJavaScript(text, new KeyEvent(KeyEvent.ACTION_DOWN,
+                        KeyEvent.KEYCODE_ENTER));
+                passToJavaScript(text, new KeyEvent(KeyEvent.ACTION_UP,
+                        KeyEvent.KEYCODE_ENTER));
+                break;
+
+            default:
+                handled = super.performEditorAction(editorAction);
+                break;
+            }
+
+            return handled;
+        }
+
         public void initEditorInfo(WebViewCore.TextFieldInitData initData) {
             int type = initData.mType;
             int inputType = InputType.TYPE_CLASS_TEXT
@@ -522,6 +577,7 @@
             mHint = initData.mLabel;
             mInputType = inputType;
             mImeOptions = imeOptions;
+            mMaxLength = initData.mMaxLength;
         }
 
         public void setupEditorInfo(EditorInfo outAttrs) {
@@ -559,7 +615,7 @@
             if (isCharacterAdd) {
                 sendCharacter(text.charAt(textLength - 1));
             } else if (isCharacterDelete) {
-                sendDeleteKey();
+                sendKey(KeyEvent.KEYCODE_DEL);
             } else if ((textLength != originalLength) ||
                     !TextUtils.regionMatches(text, 0, original, 0,
                             textLength)) {
@@ -594,21 +650,118 @@
         }
 
         /**
-         * Send the delete character as a key down and up event.
+         * Send a key event for a specific key code, not a standard
+         * unicode character.
+         * @param keyCode The key code to send.
          */
-        private void sendDeleteKey() {
+        private void sendKey(int keyCode) {
             long eventTime = SystemClock.uptimeMillis();
             sendKeyEvent(new KeyEvent(eventTime, eventTime,
-                    KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL, 0, 0,
+                    KeyEvent.ACTION_DOWN, keyCode, 0, 0,
                     KeyCharacterMap.VIRTUAL_KEYBOARD, 0,
                     KeyEvent.FLAG_SOFT_KEYBOARD));
             sendKeyEvent(new KeyEvent(SystemClock.uptimeMillis(), eventTime,
-                    KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DEL, 0, 0,
+                    KeyEvent.ACTION_UP, keyCode, 0, 0,
                     KeyCharacterMap.VIRTUAL_KEYBOARD, 0,
                     KeyEvent.FLAG_SOFT_KEYBOARD));
         }
+
+        private CharSequence limitReplaceTextByMaxLength(CharSequence text,
+                int numReplaced) {
+            if (mMaxLength > 0) {
+                Editable editable = getEditable();
+                int maxReplace = mMaxLength - editable.length() + numReplaced;
+                if (maxReplace < text.length()) {
+                    maxReplace = Math.max(maxReplace, 0);
+                    // New length is greater than the maximum. trim it down.
+                    text = text.subSequence(0, maxReplace);
+                }
+            }
+            return text;
+        }
+
+        private void restartInput() {
+            InputMethodManager imm = InputMethodManager.peekInstance();
+            if (imm != null) {
+                // Since the text has changed, do not allow the IME to replace the
+                // existing text as though it were a completion.
+                imm.restartInput(WebView.this);
+            }
+        }
     }
 
+    private class PastePopupWindow extends PopupWindow implements OnClickListener {
+        private ViewGroup mContentView;
+        private TextView mPasteTextView;
+
+        public PastePopupWindow() {
+            super(WebView.this.mContext, null,
+                    com.android.internal.R.attr.textSelectHandleWindowStyle);
+            setClippingEnabled(true);
+            LinearLayout linearLayout = new LinearLayout(WebView.this.getContext());
+            linearLayout.setOrientation(LinearLayout.HORIZONTAL);
+            mContentView = linearLayout;
+            mContentView.setBackgroundResource(
+                    com.android.internal.R.drawable.text_edit_paste_window);
+
+            LayoutInflater inflater = (LayoutInflater)WebView.this.mContext.
+                    getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+
+            ViewGroup.LayoutParams wrapContent = new ViewGroup.LayoutParams(
+                    ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
+
+            mPasteTextView = (TextView) inflater.inflate(
+                    com.android.internal.R.layout.text_edit_action_popup_text, null);
+            mPasteTextView.setLayoutParams(wrapContent);
+            mContentView.addView(mPasteTextView);
+            mPasteTextView.setText(com.android.internal.R.string.paste);
+            mPasteTextView.setOnClickListener(this);
+            this.setContentView(mContentView);
+        }
+
+        public void show(Rect cursorRect, int windowLeft, int windowTop) {
+            measureContent();
+
+            int width = mContentView.getMeasuredWidth();
+            int height = mContentView.getMeasuredHeight();
+            int y = cursorRect.top - height;
+            if (y < windowTop) {
+                // There's not enough room vertically, move it below the
+                // handle.
+                // The selection handle is vertically offset by 1/4 of the
+                // line height.
+                y = cursorRect.bottom - (cursorRect.height() / 4) +
+                        mSelectHandleCenter.getIntrinsicHeight();
+            }
+            int x = cursorRect.centerX() - (width / 2);
+            if (x < windowLeft) {
+                x = windowLeft;
+            }
+            if (!isShowing()) {
+                showAtLocation(WebView.this, Gravity.NO_GRAVITY, x, y);
+            }
+            update(x, y, width, height);
+        }
+
+        public void hide() {
+            dismiss();
+        }
+
+        @Override
+        public void onClick(View view) {
+            pasteFromClipboard();
+            selectionDone();
+        }
+
+        protected void measureContent() {
+            final DisplayMetrics displayMetrics = mContext.getResources().getDisplayMetrics();
+            mContentView.measure(
+                    View.MeasureSpec.makeMeasureSpec(displayMetrics.widthPixels,
+                            View.MeasureSpec.AT_MOST),
+                    View.MeasureSpec.makeMeasureSpec(displayMetrics.heightPixels,
+                            View.MeasureSpec.AT_MOST));
+        }
+    }
 
     // The listener to capture global layout change event.
     private InnerGlobalLayoutListener mGlobalLayoutListener = null;
@@ -636,6 +789,7 @@
     private boolean mGLViewportEmpty = false;
     WebViewInputConnection mInputConnection = null;
     private int mFieldPointer;
+    private PastePopupWindow mPasteWindow;
 
     /**
      *  Transportation object for returning WebView across thread boundaries.
@@ -3018,7 +3172,7 @@
             return;
         }
         if (nativeHasCursorNode()) {
-            Rect cursorBounds = nativeGetCursorRingBounds();
+            Rect cursorBounds = cursorRingBounds();
             if (!cursorBounds.contains(contentX, contentY)) {
                 int slop = viewToContentDimension(mNavSlop);
                 cursorBounds.inset(-slop, -slop);
@@ -5219,7 +5373,11 @@
         }
     }
 
+    // TODO: Remove this
     WebViewCore.CursorData cursorData() {
+        if (sDisableNavcache) {
+            return new WebViewCore.CursorData(0, 0, 0, 0);
+        }
         WebViewCore.CursorData result = cursorDataNoPosition();
         Point position = nativeCursorPosition();
         result.mX = position.x;
@@ -5910,6 +6068,27 @@
         return true;
     }
 
+    private void showPasteWindow() {
+        ClipboardManager cm = (ClipboardManager)(mContext
+                .getSystemService(Context.CLIPBOARD_SERVICE));
+        if (cm.hasPrimaryClip()) {
+            Rect cursorRect = contentToViewRect(mSelectCursorBase);
+            int[] location = new int[2];
+            getLocationInWindow(location);
+            cursorRect.offset(location[0] - mScrollX, location[1] - mScrollY);
+            if (mPasteWindow == null) {
+                mPasteWindow = new PastePopupWindow();
+            }
+            mPasteWindow.show(cursorRect, location[0], location[1]);
+        }
+    }
+
+    private void hidePasteButton() {
+        if (mPasteWindow != null) {
+            mPasteWindow.hide();
+        }
+    }
+
     private void syncSelectionCursors() {
         mSelectCursorBaseLayerId =
                 nativeGetHandleLayerId(mNativeClass, HANDLE_ID_BASE, mSelectCursorBase);
@@ -5919,13 +6098,11 @@
 
     private boolean setupWebkitSelect() {
         syncSelectionCursors();
-        ClipboardManager cm = (ClipboardManager)(mContext
-                .getSystemService(Context.CLIPBOARD_SERVICE));
-        if (!mIsCaretSelection || cm.hasPrimaryClip()) {
-            if (!startSelectActionMode()) {
-                selectionDone();
-                return false;
-            }
+        if (mIsCaretSelection) {
+            showPasteWindow();
+        } else if (!startSelectActionMode()) {
+            selectionDone();
+            return false;
         }
         mSelectingText = true;
         mTouchMode = TOUCH_DRAG_MODE;
@@ -5982,6 +6159,7 @@
      */
     void selectionDone() {
         if (mSelectingText) {
+            hidePasteButton();
             mSelectingText = false;
             // finish is idempotent, so this is fine even if selectionDone was
             // called by mSelectCallback.onDestroyActionMode
@@ -6051,12 +6229,8 @@
         if (clipData != null) {
             ClipData.Item clipItem = clipData.getItemAt(0);
             CharSequence pasteText = clipItem.getText();
-            if (pasteText != null) {
-                int[] handles = new int[4];
-                getSelectionHandles(handles);
-                mWebViewCore.sendMessage(EventHub.DELETE_TEXT, handles);
-                mWebViewCore.sendMessage(EventHub.INSERT_TEXT,
-                        pasteText.toString());
+            if (mInputConnection != null) {
+                mInputConnection.replaceSelection(pasteText);
             }
         }
     }
@@ -6614,6 +6788,7 @@
                             mSelectionStarted = true;
                             mSelectDraggingCursor = mSelectCursorBase;
                             mPrivateHandler.removeMessages(CLEAR_CARET_HANDLE);
+                            hidePasteButton();
                         } else if (mSelectHandleLeft != null
                                 && mSelectHandleLeft.getBounds()
                                     .contains(shiftedX, shiftedY)) {
@@ -7276,10 +7451,11 @@
 
         if (mSelectingText) {
             mSelectionStarted = false;
+            syncSelectionCursors();
             if (mIsCaretSelection) {
                 resetCaretTimer();
+                showPasteWindow();
             }
-            syncSelectionCursors();
             invalidate();
         }
     }
@@ -7397,7 +7573,7 @@
                 return false;
             }
             if (time - mLastCursorTime <= TRACKBALL_TIMEOUT
-                    && !mLastCursorBounds.equals(nativeGetCursorRingBounds())) {
+                    && !mLastCursorBounds.equals(cursorRingBounds())) {
                 nativeSelectBestAt(mLastCursorBounds);
             }
             if (DebugFlags.WEB_VIEW) {
@@ -9977,7 +10153,7 @@
         }
         mInitialHitTestResult = null;
         mLastCursorTime = time;
-        mLastCursorBounds = nativeGetCursorRingBounds();
+        mLastCursorBounds = cursorRingBounds();
         boolean keyHandled
                 = nativeMoveCursor(keyCode, count, noScroll) == false;
         if (DebugFlags.WEB_VIEW) {
@@ -9988,7 +10164,7 @@
         if (keyHandled == false) {
             return keyHandled;
         }
-        Rect contentCursorRingBounds = nativeGetCursorRingBounds();
+        Rect contentCursorRingBounds = cursorRingBounds();
         if (contentCursorRingBounds.isEmpty()) return keyHandled;
         Rect viewCursorRingBounds = contentToViewRect(contentCursorRingBounds);
         // set last touch so that context menu related functions will work
@@ -10202,6 +10378,14 @@
         return isEditable;
     }
 
+    // TODO: Remove this
+    Rect cursorRingBounds() {
+        if (sDisableNavcache) {
+            return new Rect();
+        }
+        return nativeGetCursorRingBounds();
+    }
+
     private native int nativeCacheHitFramePointer();
     private native boolean  nativeCacheHitIsPlugin();
     private native Rect nativeCacheHitNodeBounds();
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index e7da1a8..93fd92b 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -923,13 +923,14 @@
     static class TextFieldInitData {
         public TextFieldInitData(int fieldPointer,
                 String text, int type, boolean isSpellCheckEnabled,
-                boolean isTextFieldNext, String label) {
+                boolean isTextFieldNext, String label, int maxLength) {
             mFieldPointer = fieldPointer;
             mText = text;
             mType = type;
             mIsSpellCheckEnabled = isSpellCheckEnabled;
             mIsTextFieldNext = isTextFieldNext;
             mLabel = label;
+            mMaxLength = maxLength;
         }
         int mFieldPointer;
         String mText;
@@ -937,6 +938,7 @@
         boolean mIsSpellCheckEnabled;
         boolean mIsTextFieldNext;
         String mLabel;
+        int mMaxLength;
     }
 
     // mAction of TouchEventData can be MotionEvent.getAction() which uses the
@@ -2826,12 +2828,13 @@
     // called by JNI
     private void initEditField(int pointer, String text, int inputType,
             boolean isSpellCheckEnabled, boolean nextFieldIsText,
-            String label, int start, int end, int selectionPtr) {
+            String label, int start, int end, int selectionPtr, int maxLength) {
         if (mWebView == null) {
             return;
         }
         TextFieldInitData initData = new TextFieldInitData(pointer,
-                text, inputType, isSpellCheckEnabled, nextFieldIsText, label);
+                text, inputType, isSpellCheckEnabled, nextFieldIsText, label,
+                maxLength);
         Message.obtain(mWebView.mPrivateHandler,
                 WebView.INIT_EDIT_FIELD, initData).sendToTarget();
         Message.obtain(mWebView.mPrivateHandler,
diff --git a/core/java/android/widget/AppSecurityPermissions.java b/core/java/android/widget/AppSecurityPermissions.java
index 988760d..e6184d5 100755
--- a/core/java/android/widget/AppSecurityPermissions.java
+++ b/core/java/android/widget/AppSecurityPermissions.java
@@ -26,6 +26,12 @@
 import android.content.pm.PermissionGroupInfo;
 import android.content.pm.PermissionInfo;
 import android.graphics.drawable.Drawable;
+import android.os.Parcel;
+import android.text.Spannable;
+import android.text.SpannableString;
+import android.text.SpannableStringBuilder;
+import android.text.TextUtils;
+import android.text.style.ForegroundColorSpan;
 import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -61,18 +67,52 @@
         BOTH
     }
 
+    static class MyPermissionInfo extends PermissionInfo {
+        /**
+         * PackageInfo.requestedPermissionsFlags for the new package being installed.
+         */
+        int mNewReqFlags;
+
+        /**
+         * PackageInfo.requestedPermissionsFlags for the currently installed
+         * package, if it is installed.
+         */
+        int mExistingReqFlags;
+
+        /**
+         * True if this should be considered a new permission.
+         */
+        boolean mNew;
+
+        MyPermissionInfo() {
+        }
+
+        MyPermissionInfo(PermissionInfo info) {
+            super(info);
+        }
+
+        MyPermissionInfo(MyPermissionInfo info) {
+            super(info);
+            mNewReqFlags = info.mNewReqFlags;
+            mExistingReqFlags = info.mExistingReqFlags;
+            mNew = info.mNew;
+        }
+    }
+
     private final static String TAG = "AppSecurityPermissions";
     private boolean localLOGV = false;
     private Context mContext;
     private LayoutInflater mInflater;
     private PackageManager mPm;
     private LinearLayout mPermsView;
-    private Map<String, String> mDangerousMap;
-    private Map<String, String> mNormalMap;
-    private List<PermissionInfo> mPermsList;
+    private Map<String, CharSequence> mNewMap;
+    private Map<String, CharSequence> mDangerousMap;
+    private Map<String, CharSequence> mNormalMap;
+    private List<MyPermissionInfo> mPermsList;
     private String mDefaultGrpLabel;
     private String mDefaultGrpName="DefaultGrp";
     private String mPermFormat;
+    private CharSequence mNewPermPrefix;
     private Drawable mNormalIcon;
     private Drawable mDangerousIcon;
     private boolean mExpanded;
@@ -84,20 +124,23 @@
     private State mCurrentState;
     private LinearLayout mNonDangerousList;
     private LinearLayout mDangerousList;
+    private LinearLayout mNewList;
     private HashMap<String, CharSequence> mGroupLabelCache;
     private View mNoPermsView;
-    
+
     public AppSecurityPermissions(Context context, List<PermissionInfo> permList) {
         mContext = context;
         mPm = mContext.getPackageManager();
-        mPermsList = permList;
+        for (PermissionInfo pi : permList) {
+            mPermsList.add(new MyPermissionInfo(pi));
+        }
     }
     
     public AppSecurityPermissions(Context context, String packageName) {
         mContext = context;
         mPm = mContext.getPackageManager();
-        mPermsList = new ArrayList<PermissionInfo>();
-        Set<PermissionInfo> permSet = new HashSet<PermissionInfo>();
+        mPermsList = new ArrayList<MyPermissionInfo>();
+        Set<MyPermissionInfo> permSet = new HashSet<MyPermissionInfo>();
         PackageInfo pkgInfo;
         try {
             pkgInfo = mPm.getPackageInfo(packageName, PackageManager.GET_PERMISSIONS);
@@ -109,7 +152,7 @@
         if((pkgInfo.applicationInfo != null) && (pkgInfo.applicationInfo.uid != -1)) {
             getAllUsedPermissions(pkgInfo.applicationInfo.uid, permSet);
         }
-        for(PermissionInfo tmpInfo : permSet) {
+        for(MyPermissionInfo tmpInfo : permSet) {
             mPermsList.add(tmpInfo);
         }
     }
@@ -117,21 +160,27 @@
     public AppSecurityPermissions(Context context, PackageParser.Package pkg) {
         mContext = context;
         mPm = mContext.getPackageManager();
-        mPermsList = new ArrayList<PermissionInfo>();
-        Set<PermissionInfo> permSet = new HashSet<PermissionInfo>();
+        mPermsList = new ArrayList<MyPermissionInfo>();
+        Set<MyPermissionInfo> permSet = new HashSet<MyPermissionInfo>();
         if(pkg == null) {
             return;
         }
+
+        // Convert to a PackageInfo
+        PackageInfo info = PackageParser.generatePackageInfo(pkg, null,
+                PackageManager.GET_PERMISSIONS, 0, 0, null);
+        PackageInfo installedPkgInfo = null;
         // Get requested permissions
-        if (pkg.requestedPermissions != null) {
-            ArrayList<String> strList = pkg.requestedPermissions;
-            int size = strList.size();
-            if (size > 0) {
-                extractPerms(strList.toArray(new String[size]), permSet);
+        if (info.requestedPermissions != null) {
+            try {
+                installedPkgInfo = mPm.getPackageInfo(info.packageName,
+                        PackageManager.GET_PERMISSIONS);
+            } catch (NameNotFoundException e) {
             }
+            extractPerms(info, permSet, installedPkgInfo);
         }
         // Get permissions related to  shared user if any
-        if(pkg.mSharedUserId != null) {
+        if (pkg.mSharedUserId != null) {
             int sharedUid;
             try {
                 sharedUid = mPm.getUidForSharedUser(pkg.mSharedUserId);
@@ -141,7 +190,7 @@
             }
         }
         // Retrieve list of permissions
-        for(PermissionInfo tmpInfo : permSet) {
+        for (MyPermissionInfo tmpInfo : permSet) {
             mPermsList.add(tmpInfo);
         }
     }
@@ -159,7 +208,7 @@
                 description, dangerous, icon);
     }
     
-    private void getAllUsedPermissions(int sharedUid, Set<PermissionInfo> permSet) {
+    private void getAllUsedPermissions(int sharedUid, Set<MyPermissionInfo> permSet) {
         String sharedPkgList[] = mPm.getPackagesForUid(sharedUid);
         if(sharedPkgList == null || (sharedPkgList.length == 0)) {
             return;
@@ -170,29 +219,65 @@
     }
     
     private void getPermissionsForPackage(String packageName, 
-            Set<PermissionInfo> permSet) {
+            Set<MyPermissionInfo> permSet) {
         PackageInfo pkgInfo;
         try {
             pkgInfo = mPm.getPackageInfo(packageName, PackageManager.GET_PERMISSIONS);
         } catch (NameNotFoundException e) {
-            Log.w(TAG, "Could'nt retrieve permissions for package:"+packageName);
+            Log.w(TAG, "Couldn't retrieve permissions for package:"+packageName);
             return;
         }
         if ((pkgInfo != null) && (pkgInfo.requestedPermissions != null)) {
-            extractPerms(pkgInfo.requestedPermissions, permSet);
+            extractPerms(pkgInfo, permSet, pkgInfo);
         }
     }
-    
-    private void extractPerms(String strList[], Set<PermissionInfo> permSet) {
-        if((strList == null) || (strList.length == 0)) {
+
+    private void extractPerms(PackageInfo info, Set<MyPermissionInfo> permSet,
+            PackageInfo installedPkgInfo) {
+        String[] strList = info.requestedPermissions;
+        int[] flagsList = info.requestedPermissionsFlags;
+        if ((strList == null) || (strList.length == 0)) {
             return;
         }
-        for(String permName:strList) {
+        for (int i=0; i<strList.length; i++) {
+            String permName = strList[i];
+            // If we are only looking at an existing app, then we only
+            // care about permissions that have actually been granted to it.
+            if (installedPkgInfo != null && info == installedPkgInfo) {
+                if ((flagsList[i]&PackageInfo.REQUESTED_PERMISSION_GRANTED) == 0) {
+                    continue;
+                }
+            }
             try {
                 PermissionInfo tmpPermInfo = mPm.getPermissionInfo(permName, 0);
-                if(tmpPermInfo != null) {
-                    permSet.add(tmpPermInfo);
+                if (tmpPermInfo == null) {
+                    continue;
                 }
+                int existingIndex = -1;
+                if (installedPkgInfo != null
+                        && installedPkgInfo.requestedPermissions != null) {
+                    for (int j=0; j<installedPkgInfo.requestedPermissions.length; j++) {
+                        if (permName.equals(installedPkgInfo.requestedPermissions[j])) {
+                            existingIndex = j;
+                            break;
+                        }
+                    }
+                }
+                final int existingFlags = existingIndex >= 0 ?
+                        installedPkgInfo.requestedPermissionsFlags[existingIndex] : 0;
+                if (!isDisplayablePermission(tmpPermInfo, flagsList[i], existingFlags)) {
+                    // This is not a permission that is interesting for the user
+                    // to see, so skip it.
+                    continue;
+                }
+                MyPermissionInfo myPerm = new MyPermissionInfo(tmpPermInfo);
+                myPerm.mNewReqFlags = flagsList[i];
+                myPerm.mExistingReqFlags = existingFlags;
+                // This is a new permission if the app is already installed and
+                // doesn't currently hold this permission.
+                myPerm.mNew = installedPkgInfo != null
+                        && (existingFlags&PackageInfo.REQUESTED_PERMISSION_GRANTED) == 0;
+                permSet.add(myPerm);
             } catch (NameNotFoundException e) {
                 Log.i(TAG, "Ignoring unknown permission:"+permName);
             }
@@ -210,6 +295,7 @@
         mShowMore = mPermsView.findViewById(R.id.show_more);
         mShowMoreIcon = (ImageView) mShowMore.findViewById(R.id.show_more_icon);
         mShowMoreText = (TextView) mShowMore.findViewById(R.id.show_more_text);
+        mNewList = (LinearLayout) mPermsView.findViewById(R.id.new_perms_list);
         mDangerousList = (LinearLayout) mPermsView.findViewById(R.id.dangerous_perms_list);
         mNonDangerousList = (LinearLayout) mPermsView.findViewById(R.id.non_dangerous_perms_list);
         mNoPermsView = mPermsView.findViewById(R.id.no_permissions);
@@ -222,6 +308,7 @@
         // Pick up from framework resources instead.
         mDefaultGrpLabel = mContext.getString(R.string.default_permission_group);
         mPermFormat = mContext.getString(R.string.permissions_format);
+        mNewPermPrefix = mContext.getText(R.string.perms_new_perm_prefix);
         mNormalIcon = mContext.getResources().getDrawable(R.drawable.ic_text_dot);
         mDangerousIcon = mContext.getResources().getDrawable(R.drawable.ic_bullet_key_permission);
         mShowMaxIcon = mContext.getResources().getDrawable(R.drawable.expander_close_holo_dark);
@@ -233,39 +320,56 @@
     }
 
     /**
-     * Canonicalizes the group description before it is displayed to the user.
-     *
-     * TODO check for internationalization issues remove trailing '.' in str1
-     */
-    private String canonicalizeGroupDesc(String groupDesc) {
-        if ((groupDesc == null) || (groupDesc.length() == 0)) {
-            return null;
-        }
-        // Both str1 and str2 are non-null and are non-zero in size.
-        int len = groupDesc.length();
-        if(groupDesc.charAt(len-1) == '.') {
-            groupDesc = groupDesc.substring(0, len-1);
-        }
-        return groupDesc;
-    }
-
-    /**
      * Utility method that concatenates two strings defined by mPermFormat.
      * a null value is returned if both str1 and str2 are null, if one of the strings
      * is null the other non null value is returned without formatting
      * this is to placate initial error checks
      */
-    private String formatPermissions(String groupDesc, CharSequence permDesc) {
-        if(groupDesc == null) {
-            if(permDesc == null) {
-                return null;
-            }
-            return permDesc.toString();
-        }
-        groupDesc = canonicalizeGroupDesc(groupDesc);
-        if(permDesc == null) {
+    private CharSequence formatPermissions(CharSequence groupDesc, CharSequence permDesc,
+            boolean newPerms) {
+        if (permDesc == null) {
             return groupDesc;
         }
+        // Sometimes people write permission names with a trailing period;
+        // strip that if it appears.
+        int len = permDesc.length();
+        if (len > 0 && permDesc.charAt(len-1) == '.') {
+            permDesc = (permDesc.toString()).substring(0, len-1);
+        }
+        if (newPerms) {
+            if (true) {
+                // If this is a new permission, format it appropriately.
+                SpannableStringBuilder builder = new SpannableStringBuilder();
+                if (groupDesc != null) {
+                    // The previous permissions go in front, with a newline
+                    // separating them.
+                    builder.append(groupDesc);
+                    builder.append("\n");
+                }
+                Parcel parcel = Parcel.obtain();
+                TextUtils.writeToParcel(mNewPermPrefix, parcel, 0);
+                parcel.setDataPosition(0);
+                CharSequence newStr = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel);
+                parcel.recycle();
+                builder.append(newStr);
+                builder.append(permDesc);
+                return builder;
+            } else {
+                // If this is a new permission, format it appropriately.
+                SpannableStringBuilder builder = new SpannableStringBuilder(permDesc);
+                builder.insert(0, mNewPermPrefix);
+                if (groupDesc != null) {
+                    // The previous permissions go in front, with a newline
+                    // separating them.
+                    builder.insert(0, "\n");
+                    builder.insert(0, groupDesc);
+                }
+                return builder;
+            }
+        }
+        if (groupDesc == null) {
+            return permDesc;
+        }
         // groupDesc and permDesc are non null
         return String.format(mPermFormat, groupDesc, permDesc.toString());
     }
@@ -295,9 +399,8 @@
      * Utility method that displays permissions from a map containing group name and
      * list of permission descriptions.
      */
-    private void displayPermissions(boolean dangerous) {
-        Map<String, String> permInfoMap = dangerous ? mDangerousMap : mNormalMap;
-        LinearLayout permListView = dangerous ? mDangerousList : mNonDangerousList;
+    private void displayPermissions(Map<String, CharSequence> permInfoMap,
+            LinearLayout permListView, boolean dangerous) {
         permListView.removeAllViews();
 
         Set<String> permInfoStrSet = permInfoMap.keySet();
@@ -349,17 +452,20 @@
             break;
 
         case DANGEROUS_ONLY:
-            displayPermissions(true);
+            displayPermissions(mNewMap, mNewList, true);
+            displayPermissions(mDangerousMap, mDangerousList, true);
             break;
 
         case NORMAL_ONLY:
-            displayPermissions(false);
+            displayPermissions(mNewMap, mNewList, true);
+            displayPermissions(mNormalMap, mNonDangerousList, false);
             break;
 
         case BOTH:
-            displayPermissions(true);
+            displayPermissions(mNewMap, mNewList, true);
+            displayPermissions(mDangerousMap, mDangerousList, true);
             if (mExpanded) {
-                displayPermissions(false);
+                displayPermissions(mNormalMap, mNonDangerousList, false);
                 mShowMoreIcon.setImageDrawable(mShowMaxIcon);
                 mShowMoreText.setText(R.string.perms_hide);
                 mNonDangerousList.setVisibility(View.VISIBLE);
@@ -372,22 +478,38 @@
             break;
         }
     }
-    
-    private boolean isDisplayablePermission(PermissionInfo pInfo) {
-        if(pInfo.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS ||
-                pInfo.protectionLevel == PermissionInfo.PROTECTION_NORMAL) {
+
+    private boolean isDisplayablePermission(PermissionInfo pInfo, int newReqFlags,
+            int existingReqFlags) {
+        final int base = pInfo.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE;
+        // Dangerous and normal permissions are always shown to the user.
+        if (base == PermissionInfo.PROTECTION_DANGEROUS ||
+                base == PermissionInfo.PROTECTION_NORMAL) {
+            return true;
+        }
+        // Development permissions are only shown to the user if they are already
+        // granted to the app -- if we are installing an app and they are not
+        // already granted, they will not be granted as part of the install.
+        // Note we also need the app to have specified this permission is not
+        // required -- this is not technically needed, but it helps various things
+        // if we ensure apps always mark development permissions as option, so that
+        // even not knowing what a permission is we can still know whether it will
+        // be granted to the app when it is installed.
+        if ((existingReqFlags&PackageInfo.REQUESTED_PERMISSION_GRANTED) != 0
+                && (newReqFlags&PackageInfo.REQUESTED_PERMISSION_REQUIRED) == 0
+                && (pInfo.protectionLevel & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) {
             return true;
         }
         return false;
     }
-    
+
     /*
      * Utility method that aggregates all permission descriptions categorized by group
      * Say group1 has perm11, perm12, perm13, the group description will be
      * perm11_Desc, perm12_Desc, perm13_Desc
      */
-    private void aggregateGroupDescs(
-            Map<String, List<PermissionInfo> > map, Map<String, String> retMap) {
+    private void aggregateGroupDescs(Map<String, List<MyPermissionInfo> > map,
+            Map<String, CharSequence> retMap, boolean newPerms) {
         if(map == null) {
             return;
         }
@@ -397,20 +519,20 @@
         Set<String> grpNames = map.keySet();
         Iterator<String> grpNamesIter = grpNames.iterator();
         while(grpNamesIter.hasNext()) {
-            String grpDesc = null;
+            CharSequence grpDesc = null;
             String grpNameKey = grpNamesIter.next();
-            List<PermissionInfo> grpPermsList = map.get(grpNameKey);
+            List<MyPermissionInfo> grpPermsList = map.get(grpNameKey);
             if(grpPermsList == null) {
                 continue;
             }
             for(PermissionInfo permInfo: grpPermsList) {
                 CharSequence permDesc = permInfo.loadLabel(mPm);
-                grpDesc = formatPermissions(grpDesc, permDesc);
+                grpDesc = formatPermissions(grpDesc, permDesc, newPerms);
             }
             // Insert grpDesc into map
             if(grpDesc != null) {
                 if(localLOGV) Log.i(TAG, "Group:"+grpNameKey+" description:"+grpDesc.toString());
-                retMap.put(grpNameKey, grpDesc.toString());
+                retMap.put(grpNameKey, grpDesc);
             }
         }
     }
@@ -428,42 +550,53 @@
         }
     }
     
-    private void setPermissions(List<PermissionInfo> permList) {
+    private void setPermissions(List<MyPermissionInfo> permList) {
         mGroupLabelCache = new HashMap<String, CharSequence>();
         //add the default label so that uncategorized permissions can go here
         mGroupLabelCache.put(mDefaultGrpName, mDefaultGrpLabel);
         
         // Map containing group names and a list of permissions under that group
+        // that are new from the current install
+        mNewMap = new HashMap<String, CharSequence>();
+        // Map containing group names and a list of permissions under that group
         // categorized as dangerous
-        mDangerousMap = new HashMap<String, String>();
+        mDangerousMap = new HashMap<String, CharSequence>();
         // Map containing group names and a list of permissions under that group
         // categorized as normal
-        mNormalMap = new HashMap<String, String>();
+        mNormalMap = new HashMap<String, CharSequence>();
         
         // Additional structures needed to ensure that permissions are unique under 
         // each group
-        Map<String, List<PermissionInfo>> dangerousMap = 
-            new HashMap<String,  List<PermissionInfo>>();
-        Map<String, List<PermissionInfo> > normalMap = 
-            new HashMap<String,  List<PermissionInfo>>();
+        Map<String, List<MyPermissionInfo>> newMap =
+            new HashMap<String,  List<MyPermissionInfo>>();
+        Map<String, List<MyPermissionInfo>> dangerousMap = 
+            new HashMap<String,  List<MyPermissionInfo>>();
+        Map<String, List<MyPermissionInfo> > normalMap = 
+            new HashMap<String,  List<MyPermissionInfo>>();
         PermissionInfoComparator permComparator = new PermissionInfoComparator(mPm);
         
         if (permList != null) {
             // First pass to group permissions
-            for (PermissionInfo pInfo : permList) {
+            for (MyPermissionInfo pInfo : permList) {
                 if(localLOGV) Log.i(TAG, "Processing permission:"+pInfo.name);
-                if(!isDisplayablePermission(pInfo)) {
+                if(!isDisplayablePermission(pInfo, pInfo.mNewReqFlags, pInfo.mExistingReqFlags)) {
                     if(localLOGV) Log.i(TAG, "Permission:"+pInfo.name+" is not displayable");
                     continue;
                 }
-                Map<String, List<PermissionInfo> > permInfoMap =
-                    (pInfo.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS) ?
-                            dangerousMap : normalMap;
+                Map<String, List<MyPermissionInfo> > permInfoMap;
+                if (pInfo.mNew) {
+                    permInfoMap = newMap;
+                } else if ((pInfo.protectionLevel&PermissionInfo.PROTECTION_MASK_BASE)
+                            == PermissionInfo.PROTECTION_DANGEROUS) {
+                    permInfoMap = dangerousMap;
+                } else {
+                    permInfoMap = normalMap;
+                }
                 String grpName = (pInfo.group == null) ? mDefaultGrpName : pInfo.group;
                 if(localLOGV) Log.i(TAG, "Permission:"+pInfo.name+" belongs to group:"+grpName);
-                List<PermissionInfo> grpPermsList = permInfoMap.get(grpName);
+                List<MyPermissionInfo> grpPermsList = permInfoMap.get(grpName);
                 if(grpPermsList == null) {
-                    grpPermsList = new ArrayList<PermissionInfo>();
+                    grpPermsList = new ArrayList<MyPermissionInfo>();
                     permInfoMap.put(grpName, grpPermsList);
                     grpPermsList.add(pInfo);
                 } else {
@@ -477,12 +610,13 @@
             }
             // Second pass to actually form the descriptions
             // Look at dangerous permissions first
-            aggregateGroupDescs(dangerousMap, mDangerousMap);
-            aggregateGroupDescs(normalMap, mNormalMap);
+            aggregateGroupDescs(newMap, mNewMap, true);
+            aggregateGroupDescs(dangerousMap, mDangerousMap, false);
+            aggregateGroupDescs(normalMap, mNormalMap, false);
         }
 
         mCurrentState = State.NO_PERMS;
-        if(mDangerousMap.size() > 0) {
+        if (mNewMap.size() > 0 || mDangerousMap.size() > 0) {
             mCurrentState = (mNormalMap.size() > 0) ? State.BOTH : State.DANGEROUS_ONLY;
         } else if(mNormalMap.size() > 0) {
             mCurrentState = State.NORMAL_ONLY;
diff --git a/core/java/android/widget/NumberPicker.java b/core/java/android/widget/NumberPicker.java
index 84e86af..6405ee9 100644
--- a/core/java/android/widget/NumberPicker.java
+++ b/core/java/android/widget/NumberPicker.java
@@ -49,6 +49,7 @@
 import android.view.accessibility.AccessibilityManager;
 import android.view.accessibility.AccessibilityNodeInfo;
 import android.view.animation.DecelerateInterpolator;
+import android.view.inputmethod.EditorInfo;
 import android.view.inputmethod.InputMethodManager;
 
 import com.android.internal.R;
@@ -373,9 +374,9 @@
     private float mLastMotionEventY;
 
     /**
-     * Flag if to begin edit on next up event.
+     * Flag if to check for double tap and potentially start edit.
      */
-    private boolean mBeginEditOnUpEvent;
+    private boolean mCheckBeginEditOnUpEvent;
 
     /**
      * Flag if to adjust the selector wheel on next up event.
@@ -453,6 +454,11 @@
     private boolean mScrollWheelAndFadingEdgesInitialized;
 
     /**
+     * The time of the last up event.
+     */
+    private long mLastUpEventTimeMillis;
+
+    /**
      * Interface to listen for changes of the current value.
      */
     public interface OnValueChangeListener {
@@ -628,10 +634,6 @@
             public void onFocusChange(View v, boolean hasFocus) {
                 if (hasFocus) {
                     mInputText.selectAll();
-                    InputMethodManager inputMethodManager = InputMethodManager.peekInstance();
-                    if (inputMethodManager != null) {
-                        inputMethodManager.showSoftInput(mInputText, 0);
-                    }
                 } else {
                     mInputText.setSelection(0, 0);
                     validateInputTextView(v);
@@ -643,6 +645,7 @@
         });
 
         mInputText.setRawInputType(InputType.TYPE_CLASS_NUMBER);
+        mInputText.setImeOptions(EditorInfo.IME_ACTION_DONE);
 
         // initialize constants
         mTouchSlop = ViewConfiguration.getTapTimeout();
@@ -777,7 +780,7 @@
                 removeAllCallbacks();
                 mShowInputControlsAnimator.cancel();
                 mDimSelectorWheelAnimator.cancel();
-                mBeginEditOnUpEvent = false;
+                mCheckBeginEditOnUpEvent = false;
                 mAdjustScrollerOnUpEvent = true;
                 if (mSelectorWheelState == SELECTOR_WHEEL_STATE_LARGE) {
                     mSelectorWheelPaint.setAlpha(SELECTOR_WHEEL_BRIGHT_ALPHA);
@@ -788,7 +791,7 @@
                         mAdjustScroller.forceFinished(true);
                         onScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE);
                     }
-                    mBeginEditOnUpEvent = scrollersFinished;
+                    mCheckBeginEditOnUpEvent = scrollersFinished;
                     mAdjustScrollerOnUpEvent = true;
                     hideSoftInput();
                     hideInputControls();
@@ -807,7 +810,7 @@
                 float currentMoveY = event.getY();
                 int deltaDownY = (int) Math.abs(currentMoveY - mLastDownEventY);
                 if (deltaDownY > mTouchSlop) {
-                    mBeginEditOnUpEvent = false;
+                    mCheckBeginEditOnUpEvent = false;
                     onScrollStateChange(OnScrollListener.SCROLL_STATE_TOUCH_SCROLL);
                     setSelectorWheelState(SELECTOR_WHEEL_STATE_LARGE);
                     hideSoftInput();
@@ -832,11 +835,11 @@
         switch (action) {
             case MotionEvent.ACTION_MOVE:
                 float currentMoveY = ev.getY();
-                if (mBeginEditOnUpEvent
+                if (mCheckBeginEditOnUpEvent
                         || mScrollState != OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) {
                     int deltaDownY = (int) Math.abs(currentMoveY - mLastDownEventY);
                     if (deltaDownY > mTouchSlop) {
-                        mBeginEditOnUpEvent = false;
+                        mCheckBeginEditOnUpEvent = false;
                         onScrollStateChange(OnScrollListener.SCROLL_STATE_TOUCH_SCROLL);
                     }
                 }
@@ -846,11 +849,20 @@
                 mLastMotionEventY = currentMoveY;
                 break;
             case MotionEvent.ACTION_UP:
-                if (mBeginEditOnUpEvent) {
-                    setSelectorWheelState(SELECTOR_WHEEL_STATE_SMALL);
-                    showInputControls(mShowInputControlsAnimimationDuration);
-                    mInputText.requestFocus();
-                    return true;
+                if (mCheckBeginEditOnUpEvent) {
+                    mCheckBeginEditOnUpEvent = false;
+                    final long deltaTapTimeMillis = ev.getEventTime() - mLastUpEventTimeMillis;
+                    if (deltaTapTimeMillis < ViewConfiguration.getDoubleTapTimeout()) {
+                        setSelectorWheelState(SELECTOR_WHEEL_STATE_SMALL);
+                        showInputControls(mShowInputControlsAnimimationDuration);
+                        mInputText.requestFocus();
+                        InputMethodManager inputMethodManager = InputMethodManager.peekInstance();
+                        if (inputMethodManager != null) {
+                            inputMethodManager.showSoftInput(mInputText, 0);
+                        }
+                        mLastUpEventTimeMillis = ev.getEventTime();
+                        return true;
+                    }
                 }
                 VelocityTracker velocityTracker = mVelocityTracker;
                 velocityTracker.computeCurrentVelocity(1000, mMaximumFlingVelocity);
@@ -869,6 +881,7 @@
                 }
                 mVelocityTracker.recycle();
                 mVelocityTracker = null;
+                mLastUpEventTimeMillis = ev.getEventTime();
                 break;
         }
         return true;
@@ -2017,4 +2030,22 @@
             postDelayed(this, mLongPressUpdateInterval);
         }
     }
+
+    /**
+     * @hide
+     */
+    public static class CustomEditText extends EditText {
+
+        public CustomEditText(Context context, AttributeSet attrs) {
+            super(context, attrs);
+        }
+
+        @Override
+        public void onEditorAction(int actionCode) {
+            super.onEditorAction(actionCode);
+            if (actionCode == EditorInfo.IME_ACTION_DONE) {
+                clearFocus();
+            }
+        }
+    }
 }
diff --git a/core/java/android/widget/Spinner.java b/core/java/android/widget/Spinner.java
index ecf19b3..2cacbdca 100644
--- a/core/java/android/widget/Spinner.java
+++ b/core/java/android/widget/Spinner.java
@@ -282,6 +282,13 @@
         throw new RuntimeException("setOnItemClickListener cannot be used with a spinner.");
     }
 
+    /**
+     * @hide internal use only
+     */
+    public void setOnItemClickListenerInt(OnItemClickListener l) {
+        super.setOnItemClickListener(l);
+    }
+
     @Override
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
         super.onMeasure(widthMeasureSpec, heightMeasureSpec);
@@ -707,6 +714,9 @@
         
         public void onClick(DialogInterface dialog, int which) {
             setSelection(which);
+            if (mOnItemClickListener != null) {
+                performItemClick(null, which, mListAdapter.getItemId(which));
+            }
             dismiss();
         }
     }
@@ -724,6 +734,9 @@
             setOnItemClickListener(new OnItemClickListener() {
                 public void onItemClick(AdapterView parent, View v, int position, long id) {
                     Spinner.this.setSelection(position);
+                    if (mOnItemClickListener != null) {
+                        Spinner.this.performItemClick(null, position, mAdapter.getItemId(position));
+                    }
                     dismiss();
                 }
             });
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index a4087d5..385c7c7 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -243,10 +243,6 @@
     private static final int SIGNED = 2;
     private static final int DECIMAL = 4;
 
-    private static enum TEXT_ALIGN {
-        INHERIT, GRAVITY, TEXT_START, TEXT_END, CENTER, VIEW_START, VIEW_END;
-    }
-
     /**
      * Draw marquee text with fading edges as usual
      */
@@ -329,9 +325,6 @@
     // The alignment to pass to Layout, or null if not resolved.
     private Layout.Alignment mLayoutAlignment;
 
-    // The default value for mTextAlign.
-    private TEXT_ALIGN mTextAlign = TEXT_ALIGN.INHERIT;
-
     private boolean mResolvedDrawables;
 
     /**
@@ -406,9 +399,15 @@
 
     private InputFilter[] mFilters = NO_FILTERS;
 
+    // It is possible to have a selection even when mEditor is null (programmatically set, like when
+    // a link is pressed). These highlight-related fields do not go in mEditor.
+    private int mHighlightColor = 0x6633B5E5;
+    private Path mHighlightPath;
+    private final Paint mHighlightPaint;
+    private boolean mHighlightPathBogus = true;
+
     // Although these fields are specific to editable text, they are not added to Editor because
     // they are defined by the TextView's style and are theme-dependent.
-    private int mHighlightColor = 0x6633B5E5;
     private int mCursorDrawableRes;
     // These four fields, could be moved to Editor, since we know their default values and we
     // could condition the creation of the Editor to a non standard value. This is however
@@ -477,6 +476,9 @@
         mTextPaint.density = res.getDisplayMetrics().density;
         mTextPaint.setCompatibilityScaling(compat.applicationScale);
 
+        mHighlightPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+        mHighlightPaint.setCompatibilityScaling(compat.applicationScale);
+
         mMovement = getDefaultMovementMethod();
 
         mTransformation = null;
@@ -2980,8 +2982,7 @@
                           "/" + ss.selEnd + " out of range for " + restored +
                           "text " + mText);
                 } else {
-                    Selection.setSelection((Spannable) mText, ss.selStart,
-                                           ss.selEnd);
+                    Selection.setSelection((Spannable) mText, ss.selStart, ss.selEnd);
 
                     if (ss.frozenWithFocus) {
                         createEditorIfNeeded("restore instance with focus");
@@ -4065,7 +4066,7 @@
     }
 
     private void invalidateCursorPath() {
-        if (getEditor().mHighlightPathBogus) {
+        if (mHighlightPathBogus) {
             invalidateCursor();
         } else {
             final int horizontalPadding = getCompoundPaddingLeft();
@@ -4089,7 +4090,8 @@
 
                     thick /= 2.0f;
 
-                    getEditor().mHighlightPath.computeBounds(TEMP_RECTF, false);
+                    // mHighlightPath is guaranteed to be non null at that point.
+                    mHighlightPath.computeBounds(TEMP_RECTF, false);
 
                     invalidate((int) FloatMath.floor(horizontalPadding + TEMP_RECTF.left - thick),
                             (int) FloatMath.floor(verticalPadding + TEMP_RECTF.top - thick),
@@ -4151,7 +4153,8 @@
 
                 int bottom = mLayout.getLineBottom(lineEnd);
 
-                if (invalidateCursor) {
+                // mEditor can be null in case selection is set programmatically.
+                if (invalidateCursor && mEditor != null) {
                     for (int i = 0; i < getEditor().mCursorCount; i++) {
                         Rect bounds = getEditor().mCursorDrawable[i].getBounds();
                         top = Math.min(top, bounds.top);
@@ -4516,6 +4519,55 @@
         return drawableState;
     }
 
+    private Path getUpdatedHighlightPath() {
+        Path highlight = null;
+        Paint highlightPaint = mHighlightPaint;
+
+        final int selStart = getSelectionStart();
+        final int selEnd = getSelectionEnd();
+        if (mMovement != null && (isFocused() || isPressed()) && selStart >= 0) {
+            if (selStart == selEnd) {
+                if (mEditor != null && isCursorVisible() &&
+                        (SystemClock.uptimeMillis() - getEditor().mShowCursor) % (2 * BLINK) < BLINK) {
+                    if (mHighlightPathBogus) {
+                        if (mHighlightPath == null) mHighlightPath = new Path();
+                        mHighlightPath.reset();
+                        mLayout.getCursorPath(selStart, mHighlightPath, mText);
+                        getEditor().updateCursorsPositions();
+                        mHighlightPathBogus = false;
+                    }
+
+                    // XXX should pass to skin instead of drawing directly
+                    highlightPaint.setColor(mCurTextColor);
+                    if (mCurrentAlpha != 255) {
+                        highlightPaint.setAlpha(
+                                (mCurrentAlpha * Color.alpha(mCurTextColor)) / 255);
+                    }
+                    highlightPaint.setStyle(Paint.Style.STROKE);
+                    highlight = mHighlightPath;
+                }
+            } else {
+                if (mHighlightPathBogus) {
+                    if (mHighlightPath == null) mHighlightPath = new Path();
+                    mHighlightPath.reset();
+                    mLayout.getSelectionPath(selStart, selEnd, mHighlightPath);
+                    mHighlightPathBogus = false;
+                }
+
+                // XXX should pass to skin instead of drawing directly
+                highlightPaint.setColor(mHighlightColor);
+                if (mCurrentAlpha != 255) {
+                    highlightPaint.setAlpha(
+                            (mCurrentAlpha * Color.alpha(mHighlightColor)) / 255);
+                }
+                highlightPaint.setStyle(Paint.Style.FILL);
+
+                highlight = mHighlightPath;
+            }
+        }
+        return highlight;
+    }
+
     @Override
     protected void onDraw(Canvas canvas) {
         if (mCurrentAlpha <= ViewConfiguration.ALPHA_THRESHOLD_INT) return;
@@ -4667,68 +4719,21 @@
 
         final int cursorOffsetVertical = voffsetCursor - voffsetText;
 
+        Path highlight = getUpdatedHighlightPath();
         if (mEditor != null) {
-            getEditor().onDraw(canvas, layout, cursorOffsetVertical);
+            getEditor().onDraw(canvas, layout, highlight, cursorOffsetVertical);
         } else {
-            layout.draw(canvas, null, null, cursorOffsetVertical);
+            layout.draw(canvas, highlight, mHighlightPaint, cursorOffsetVertical);
 
             if (mMarquee != null && mMarquee.shouldDrawGhost()) {
                 canvas.translate((int) mMarquee.getGhostOffset(), 0.0f);
-                layout.draw(canvas, null, null, cursorOffsetVertical);
+                layout.draw(canvas, highlight, mHighlightPaint, cursorOffsetVertical);
             }
         }
 
         canvas.restore();
     }
 
-    private void updateCursorsPositions() {
-        if (mCursorDrawableRes == 0) {
-            getEditor().mCursorCount = 0;
-            return; 
-        }
-
-        final int offset = getSelectionStart();
-        final int line = mLayout.getLineForOffset(offset);
-        final int top = mLayout.getLineTop(line);
-        final int bottom = mLayout.getLineTop(line + 1);
-
-        getEditor().mCursorCount = mLayout.isLevelBoundary(offset) ? 2 : 1;
-
-        int middle = bottom;
-        if (getEditor().mCursorCount == 2) {
-            // Similar to what is done in {@link Layout.#getCursorPath(int, Path, CharSequence)}
-            middle = (top + bottom) >> 1;
-        }
-
-        updateCursorPosition(0, top, middle, mLayout.getPrimaryHorizontal(offset));
-
-        if (getEditor().mCursorCount == 2) {
-            updateCursorPosition(1, middle, bottom, mLayout.getSecondaryHorizontal(offset));
-        }
-    }
-
-    private void updateCursorPosition(int cursorIndex, int top, int bottom, float horizontal) {
-        if (getEditor().mCursorDrawable[cursorIndex] == null)
-            getEditor().mCursorDrawable[cursorIndex] = mContext.getResources().getDrawable(mCursorDrawableRes);
-
-        if (mTempRect == null) mTempRect = new Rect();
-        getEditor().mCursorDrawable[cursorIndex].getPadding(mTempRect);
-        final int width = getEditor().mCursorDrawable[cursorIndex].getIntrinsicWidth();
-        horizontal = Math.max(0.5f, horizontal - 0.5f);
-        final int left = (int) (horizontal) - mTempRect.left;
-        getEditor().mCursorDrawable[cursorIndex].setBounds(left, top - mTempRect.top, left + width,
-                bottom + mTempRect.bottom);
-    }
-
-    private void drawCursor(Canvas canvas, int cursorOffsetVertical) {
-        final boolean translate = cursorOffsetVertical != 0;
-        if (translate) canvas.translate(0, cursorOffsetVertical);
-        for (int i = 0; i < getEditor().mCursorCount; i++) {
-            getEditor().mCursorDrawable[i].draw(canvas);
-        }
-        if (translate) canvas.translate(0, -cursorOffsetVertical);
-    }
-
     @Override
     public void getFocusedRect(Rect r) {
         if (mLayout == null) {
@@ -4760,21 +4765,16 @@
             } else {
                 // Selection extends across multiple lines -- make the focused
                 // rect cover the entire width.
-                if (mEditor != null) {
-                    if (getEditor().mHighlightPath == null) getEditor().mHighlightPath = new Path();
-                    if (getEditor().mHighlightPathBogus) {
-                        getEditor().mHighlightPath.reset();
-                        mLayout.getSelectionPath(selStart, selEnd, getEditor().mHighlightPath);
-                        getEditor().mHighlightPathBogus = false;
-                    }
-                    synchronized (TEMP_RECTF) {
-                        getEditor().mHighlightPath.computeBounds(TEMP_RECTF, true);
-                        r.left = (int)TEMP_RECTF.left-1;
-                        r.right = (int)TEMP_RECTF.right+1;
-                    }
-                } else {
-                    r.left = 0;
-                    r.right = getMeasuredWidth();
+                if (mHighlightPathBogus) {
+                    if (mHighlightPath == null) mHighlightPath = new Path();
+                    mHighlightPath.reset();
+                    mLayout.getSelectionPath(selStart, selEnd, mHighlightPath);
+                    mHighlightPathBogus = false;
+                }
+                synchronized (TEMP_RECTF) {
+                    mHighlightPath.computeBounds(TEMP_RECTF, true);
+                    r.left = (int)TEMP_RECTF.left-1;
+                    r.right = (int)TEMP_RECTF.right+1;
                 }
             }
         }
@@ -5585,7 +5585,7 @@
         }
 
         if (curs >= 0) {
-            getEditor().mHighlightPathBogus = true;
+            mHighlightPathBogus = true;
             makeBlink();
             bringPointIntoView(curs);
         }
@@ -5660,69 +5660,28 @@
                       physicalWidth, false);
     }
 
-    @Override
-    protected void resetResolvedLayoutDirection() {
-        super.resetResolvedLayoutDirection();
-
-        if (mLayoutAlignment != null &&
-                (mTextAlign == TEXT_ALIGN.VIEW_START ||
-                mTextAlign == TEXT_ALIGN.VIEW_END)) {
-            mLayoutAlignment = null;
-        }
-    }
-
     private Layout.Alignment getLayoutAlignment() {
         if (mLayoutAlignment == null) {
-            Layout.Alignment alignment;
-            TEXT_ALIGN textAlign = mTextAlign;
-            switch (textAlign) {
-                case INHERIT:
-                    // fall through to gravity temporarily
-                    // intention is to inherit value through view hierarchy.
-                case GRAVITY:
-                    switch (mGravity & Gravity.RELATIVE_HORIZONTAL_GRAVITY_MASK) {
-                        case Gravity.START:
-                            alignment = Layout.Alignment.ALIGN_NORMAL;
-                            break;
-                        case Gravity.END:
-                            alignment = Layout.Alignment.ALIGN_OPPOSITE;
-                            break;
-                        case Gravity.LEFT:
-                            alignment = Layout.Alignment.ALIGN_LEFT;
-                            break;
-                        case Gravity.RIGHT:
-                            alignment = Layout.Alignment.ALIGN_RIGHT;
-                            break;
-                        case Gravity.CENTER_HORIZONTAL:
-                            alignment = Layout.Alignment.ALIGN_CENTER;
-                            break;
-                        default:
-                            alignment = Layout.Alignment.ALIGN_NORMAL;
-                            break;
-                    }
+            switch (mGravity & Gravity.RELATIVE_HORIZONTAL_GRAVITY_MASK) {
+                case Gravity.START:
+                    mLayoutAlignment = Layout.Alignment.ALIGN_NORMAL;
                     break;
-                case TEXT_START:
-                    alignment = Layout.Alignment.ALIGN_NORMAL;
+                case Gravity.END:
+                    mLayoutAlignment = Layout.Alignment.ALIGN_OPPOSITE;
                     break;
-                case TEXT_END:
-                    alignment = Layout.Alignment.ALIGN_OPPOSITE;
+                case Gravity.LEFT:
+                    mLayoutAlignment = Layout.Alignment.ALIGN_LEFT;
                     break;
-                case CENTER:
-                    alignment = Layout.Alignment.ALIGN_CENTER;
+                case Gravity.RIGHT:
+                    mLayoutAlignment = Layout.Alignment.ALIGN_RIGHT;
                     break;
-                case VIEW_START:
-                    alignment = (getResolvedLayoutDirection() == LAYOUT_DIRECTION_RTL) ?
-                            Layout.Alignment.ALIGN_RIGHT : Layout.Alignment.ALIGN_LEFT;
-                    break;
-                case VIEW_END:
-                    alignment = (getResolvedLayoutDirection() == LAYOUT_DIRECTION_RTL) ?
-                            Layout.Alignment.ALIGN_LEFT : Layout.Alignment.ALIGN_RIGHT;
+                case Gravity.CENTER_HORIZONTAL:
+                    mLayoutAlignment = Layout.Alignment.ALIGN_CENTER;
                     break;
                 default:
-                    alignment = Layout.Alignment.ALIGN_NORMAL;
+                    mLayoutAlignment = Layout.Alignment.ALIGN_NORMAL;
                     break;
             }
-            mLayoutAlignment = alignment;
         }
         return mLayoutAlignment;
     }
@@ -5742,7 +5701,7 @@
         mOldMaximum = mMaximum;
         mOldMaxMode = mMaxMode;
 
-        if (mEditor != null) getEditor().mHighlightPathBogus = true;
+        mHighlightPathBogus = true;
 
         if (wantWidth < 0) {
             wantWidth = 0;
@@ -6037,7 +5996,6 @@
                 if (des < 0) {
                     des = (int) FloatMath.ceil(Layout.getDesiredWidth(mTransformed, mTextPaint));
                 }
-
                 width = des;
             } else {
                 width = boring.width;
@@ -6058,7 +6016,7 @@
                 }
 
                 if (hintDes < 0) {
-                    hintBoring = BoringLayout.isBoring(mHint, mTextPaint, mHintBoring);
+                    hintBoring = BoringLayout.isBoring(mHint, mTextPaint, mTextDir, mHintBoring);
                     if (hintBoring != null) {
                         mHintBoring = hintBoring;
                     }
@@ -6066,10 +6024,8 @@
 
                 if (hintBoring == null || hintBoring == UNKNOWN_BORING) {
                     if (hintDes < 0) {
-                        hintDes = (int) FloatMath.ceil(
-                                Layout.getDesiredWidth(mHint, mTextPaint));
+                        hintDes = (int) FloatMath.ceil(Layout.getDesiredWidth(mHint, mTextPaint));
                     }
-
                     hintWidth = hintDes;
                 } else {
                     hintWidth = hintBoring.width;
@@ -6333,20 +6289,25 @@
         if (changed && mEditor != null) getEditor().mTextDisplayListIsValid = false;
     }
 
+    private boolean isShowingHint() {
+        return TextUtils.isEmpty(mText) && !TextUtils.isEmpty(mHint);
+    }
+
     /**
      * Returns true if anything changed.
      */
     private boolean bringTextIntoView() {
+        Layout layout = isShowingHint() ? mHintLayout : mLayout;
         int line = 0;
         if ((mGravity & Gravity.VERTICAL_GRAVITY_MASK) == Gravity.BOTTOM) {
-            line = mLayout.getLineCount() - 1;
+            line = layout.getLineCount() - 1;
         }
 
-        Layout.Alignment a = mLayout.getParagraphAlignment(line);
-        int dir = mLayout.getParagraphDirection(line);
+        Layout.Alignment a = layout.getParagraphAlignment(line);
+        int dir = layout.getParagraphDirection(line);
         int hspace = mRight - mLeft - getCompoundPaddingLeft() - getCompoundPaddingRight();
         int vspace = mBottom - mTop - getExtendedPaddingTop() - getExtendedPaddingBottom();
-        int ht = mLayout.getHeight();
+        int ht = layout.getHeight();
 
         int scrollx, scrolly;
 
@@ -6365,8 +6326,8 @@
              * keep leading edge in view.
              */
 
-            int left = (int) FloatMath.floor(mLayout.getLineLeft(line));
-            int right = (int) FloatMath.ceil(mLayout.getLineRight(line));
+            int left = (int) FloatMath.floor(layout.getLineLeft(line));
+            int right = (int) FloatMath.ceil(layout.getLineRight(line));
 
             if (right - left < hspace) {
                 scrollx = (right + left) / 2 - hspace / 2;
@@ -6378,10 +6339,10 @@
                 }
             }
         } else if (a == Layout.Alignment.ALIGN_RIGHT) {
-            int right = (int) FloatMath.ceil(mLayout.getLineRight(line));
+            int right = (int) FloatMath.ceil(layout.getLineRight(line));
             scrollx = right - hspace;
         } else { // a == Layout.Alignment.ALIGN_LEFT (will also be the default)
-            scrollx = (int) FloatMath.floor(mLayout.getLineLeft(line));
+            scrollx = (int) FloatMath.floor(layout.getLineLeft(line));
         }
 
         if (ht < vspace) {
@@ -6409,22 +6370,24 @@
     public boolean bringPointIntoView(int offset) {
         boolean changed = false;
 
-        if (mLayout == null) return changed;
+        Layout layout = isShowingHint() ? mHintLayout: mLayout;
 
-        int line = mLayout.getLineForOffset(offset);
+        if (layout == null) return changed;
+
+        int line = layout.getLineForOffset(offset);
 
         // FIXME: Is it okay to truncate this, or should we round?
-        final int x = (int)mLayout.getPrimaryHorizontal(offset);
-        final int top = mLayout.getLineTop(line);
-        final int bottom = mLayout.getLineTop(line + 1);
+        final int x = (int)layout.getPrimaryHorizontal(offset);
+        final int top = layout.getLineTop(line);
+        final int bottom = layout.getLineTop(line + 1);
 
-        int left = (int) FloatMath.floor(mLayout.getLineLeft(line));
-        int right = (int) FloatMath.ceil(mLayout.getLineRight(line));
-        int ht = mLayout.getHeight();
+        int left = (int) FloatMath.floor(layout.getLineLeft(line));
+        int right = (int) FloatMath.ceil(layout.getLineRight(line));
+        int ht = layout.getHeight();
 
         int grav;
 
-        switch (mLayout.getParagraphAlignment(line)) {
+        switch (layout.getParagraphAlignment(line)) {
             case ALIGN_LEFT:
                 grav = 1;
                 break;
@@ -6432,10 +6395,10 @@
                 grav = -1;
                 break;
             case ALIGN_NORMAL:
-                grav = mLayout.getParagraphDirection(line);
+                grav = layout.getParagraphDirection(line);
                 break;
             case ALIGN_OPPOSITE:
-                grav = -mLayout.getParagraphDirection(line);
+                grav = -layout.getParagraphDirection(line);
                 break;
             case ALIGN_CENTER:
             default:
@@ -6983,7 +6946,7 @@
      */
     protected void onSelectionChanged(int selStart, int selEnd) {
         sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_TEXT_SELECTION_CHANGED);
-        getEditor().mTextDisplayListIsValid = false;
+        if (mEditor != null) getEditor().mTextDisplayListIsValid = false;
     }
 
     /**
@@ -7139,10 +7102,8 @@
         }
 
         if (selChanged) {
-            if (mEditor != null) {
-                getEditor().mHighlightPathBogus = true;
-                if (!isFocused()) getEditor().mSelectionMoved = true;
-            }
+            mHighlightPathBogus = true;
+            if (mEditor != null && !isFocused()) getEditor().mSelectionMoved = true;
 
             if ((buf.getSpanFlags(what)&Spanned.SPAN_INTERMEDIATE) == 0) {
                 if (newSelStart < 0) {
@@ -7159,7 +7120,7 @@
                 what instanceof CharacterStyle) {
             if (ims == null || ims.mBatchEditNesting == 0) {
                 invalidate();
-                if (mEditor != null) getEditor().mHighlightPathBogus = true;
+                mHighlightPathBogus = true;
                 checkForResize();
             } else {
                 ims.mContentChanged = true;
@@ -7168,7 +7129,7 @@
         }
 
         if (MetaKeyKeyListener.isMetaTracker(buf, what)) {
-            if (mEditor != null) getEditor().mHighlightPathBogus = true;
+            mHighlightPathBogus = true;
             if (ims != null && MetaKeyKeyListener.isSelectingMetaTracker(buf, what)) {
                 ims.mSelectionModeChanged = true;
             }
@@ -8184,24 +8145,26 @@
     @Override
     public boolean performLongClick() {
         boolean handled = false;
-        boolean vibrate = true;
 
         if (super.performLongClick()) {
             handled = true;
         }
 
+        if (mEditor == null) {
+            return handled;
+        }
+
         // Long press in empty space moves cursor and shows the Paste affordance if available.
-        if (!handled && mEditor != null && !isPositionOnText(getEditor().mLastDownPositionX, getEditor().mLastDownPositionY) &&
+        if (!handled && !isPositionOnText(getEditor().mLastDownPositionX, getEditor().mLastDownPositionY) &&
                 getEditor().mInsertionControllerEnabled) {
             final int offset = getOffsetForPosition(getEditor().mLastDownPositionX, getEditor().mLastDownPositionY);
             stopSelectionActionMode();
             Selection.setSelection((Spannable) mText, offset);
             getInsertionController().showWithActionPopup();
             handled = true;
-            vibrate = false;
         }
 
-        if (!handled && (mEditor == null || getEditor().mSelectionActionMode != null)) {
+        if (!handled && getEditor().mSelectionActionMode != null) {
             if (touchPositionIsInSelection()) {
                 // Start a drag
                 final int start = getSelectionStart();
@@ -8221,14 +8184,11 @@
 
         // Start a new selection
         if (!handled) {
-            vibrate = handled = startSelectionActionMode();
+            handled = startSelectionActionMode();
         }
 
-        if (vibrate) {
+        if (handled) {
             performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
-        }
-
-        if (handled && mEditor != null) {
             getEditor().mDiscardNextActionUp = true;
         }
 
@@ -8320,8 +8280,11 @@
     @Override
     protected void onScrollChanged(int horiz, int vert, int oldHoriz, int oldVert) {
         super.onScrollChanged(horiz, vert, oldHoriz, oldVert);
-        if (mEditor != null && getEditor().mPositionListener != null) {
-            getEditor().mPositionListener.onScrollChanged();
+        if (mEditor != null) {
+            if (getEditor().mPositionListener != null) {
+                getEditor().mPositionListener.onScrollChanged();
+            }
+            getEditor().mTextDisplayListIsValid = false;
         }
     }
 
@@ -8617,7 +8580,7 @@
     public boolean onDragEvent(DragEvent event) {
         switch (event.getAction()) {
             case DragEvent.ACTION_DRAG_STARTED:
-                return hasInsertionController();
+                return mEditor != null && hasInsertionController();
 
             case DragEvent.ACTION_DRAG_ENTERED:
                 TextView.this.requestFocus();
@@ -8754,6 +8717,8 @@
     @Override
     public void onResolveTextDirection() {
         if (hasPasswordTransformationMethod()) {
+            // TODO: take care of the content direction to show the password text and dots justified
+            // to the left or to the right
             mTextDir = TextDirectionHeuristics.LOCALE;
             return;
         }
@@ -10363,9 +10328,9 @@
             boolean allowText = getContext().getResources().getBoolean(
                     com.android.internal.R.bool.config_allowActionMenuItemTextWithIcon);
 
-            mode.setTitle(allowText ?
-                    mContext.getString(com.android.internal.R.string.textSelectionCABTitle) : null);
+            mode.setTitle(mContext.getString(com.android.internal.R.string.textSelectionCABTitle));
             mode.setSubtitle(null);
+            mode.setTitleOptionalHint(true);
 
             int selectAllIconId = 0; // No icon by default
             if (!allowText) {
@@ -10728,9 +10693,12 @@
                 return;
             }
 
-            if (offset != mPreviousOffset || parentScrolled) {
-                updateSelection(offset);
-                addPositionToTouchUpFilter(offset);
+            boolean offsetChanged = offset != mPreviousOffset;
+            if (offsetChanged || parentScrolled) {
+                if (offsetChanged) {
+                    updateSelection(offset);
+                    addPositionToTouchUpFilter(offset);
+                }
                 final int line = mLayout.getLineForOffset(offset);
 
                 mPositionX = (int) (mLayout.getPrimaryHorizontal(offset) - 0.5f - mHotspotX);
@@ -11328,12 +11296,6 @@
     }
 
     private class Editor {
-        Editor() {
-            mHighlightPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
-            final CompatibilityInfo compat = TextView.this.getResources().getCompatibilityInfo();
-            mHighlightPaint.setCompatibilityScaling(compat.applicationScale);
-        }
-
         // Cursor Controllers.
         InsertionPointCursorController mInsertionPointCursorController;
         SelectionModifierCursorController mSelectionModifierCursorController;
@@ -11347,10 +11309,6 @@
         InputContentType mInputContentType;
         InputMethodState mInputMethodState;
 
-        Path mHighlightPath;
-        boolean mHighlightPathBogus = true;
-        final Paint mHighlightPaint;
-
         DisplayList mTextDisplayList;
         boolean mTextDisplayListIsValid;
 
@@ -11389,7 +11347,7 @@
         Runnable mShowSuggestionRunnable;
 
         final Drawable[] mCursorDrawable = new Drawable[2];
-        int mCursorCount; // Actual current number of used mCursorDrawable: 0, 1 or 2 (split)
+        int mCursorCount; // Current number of used mCursorDrawable: 0 (resource=0), 1 or 2 (split)
 
         Drawable mSelectHandleLeft;
         Drawable mSelectHandleRight;
@@ -11647,65 +11605,9 @@
             }
         }
 
-        void onDraw(Canvas canvas, Layout layout, int cursorOffsetVertical) {
-            Path highlight = null;
-            Paint highlightPaint = null;
-
-            int selStart = -1, selEnd = -1;
-            boolean drawCursor = false;
-
-            highlightPaint = mHighlightPaint;
-            //  If there is no movement method, then there can be no selection.
-            //  Check that first and attempt to skip everything having to do with
-            //  the cursor.
-            //  XXX This is not strictly true -- a program could set the
-            //  selection manually if it really wanted to.
-            if (mMovement != null && (isFocused() || isPressed())) {
-                selStart = getSelectionStart();
-                selEnd = getSelectionEnd();
-
-                if (selStart >= 0) {
-                    if (mHighlightPath == null) mHighlightPath = new Path();
-
-                    if (selStart == selEnd) {
-                        if (isCursorVisible() &&
-                                (SystemClock.uptimeMillis() - mShowCursor) % (2 * BLINK) < BLINK) {
-                            if (mHighlightPathBogus) {
-                                mHighlightPath.reset();
-                                mLayout.getCursorPath(selStart, mHighlightPath, mText);
-                                updateCursorsPositions();
-                                mHighlightPathBogus = false;
-                            }
-
-                            // XXX should pass to skin instead of drawing directly
-                            highlightPaint.setColor(mCurTextColor);
-                            if (mCurrentAlpha != 255) {
-                                highlightPaint.setAlpha(
-                                        (mCurrentAlpha * Color.alpha(mCurTextColor)) / 255);
-                            }
-                            highlightPaint.setStyle(Paint.Style.STROKE);
-                            highlight = mHighlightPath;
-                            drawCursor = mCursorCount > 0;
-                        }
-                    } else if (textCanBeSelected()) {
-                        if (mHighlightPathBogus) {
-                            mHighlightPath.reset();
-                            mLayout.getSelectionPath(selStart, selEnd, mHighlightPath);
-                            mHighlightPathBogus = false;
-                        }
-
-                        // XXX should pass to skin instead of drawing directly
-                        highlightPaint.setColor(mHighlightColor);
-                        if (mCurrentAlpha != 255) {
-                            highlightPaint.setAlpha(
-                                    (mCurrentAlpha * Color.alpha(mHighlightColor)) / 255);
-                        }
-                        highlightPaint.setStyle(Paint.Style.FILL);
-
-                        highlight = mHighlightPath;
-                    }
-                }
-            }
+        void onDraw(Canvas canvas, Layout layout, Path highlight, int cursorOffsetVertical) {
+            final int selectionStart = getSelectionStart();
+            final int selectionEnd = getSelectionEnd();
 
             final InputMethodState ims = mInputMethodState;
             if (ims != null && ims.mBatchEditNesting == 0) {
@@ -11727,7 +11629,8 @@
                                 candStart = EditableInputConnection.getComposingSpanStart(sp);
                                 candEnd = EditableInputConnection.getComposingSpanEnd(sp);
                             }
-                            imm.updateSelection(TextView.this, selStart, selEnd, candStart, candEnd);
+                            imm.updateSelection(TextView.this,
+                                    selectionStart, selectionEnd, candStart, candEnd);
                         }
                     }
 
@@ -11756,7 +11659,7 @@
                 mCorrectionHighlighter.draw(canvas, cursorOffsetVertical);
             }
 
-            if (drawCursor) {
+            if (highlight != null && selectionStart == selectionEnd && mCursorCount > 0) {
                 drawCursor(canvas, cursorOffsetVertical);
                 // Rely on the drawable entirely, do not draw the cursor line.
                 // Has to be done after the IMM related code above which relies on the highlight.
@@ -11779,7 +11682,7 @@
                         // The dirty rect should always be null for a display list
                         hardwareCanvas.onPreDraw(null);
                         hardwareCanvas.translate(-mScrollX, -mScrollY);
-                        layout.draw(hardwareCanvas, highlight, highlightPaint, cursorOffsetVertical);
+                        layout.draw(hardwareCanvas, highlight, mHighlightPaint, cursorOffsetVertical);
                         hardwareCanvas.translate(mScrollX, mScrollY);
                     } finally {
                         hardwareCanvas.onPostDraw();
@@ -11792,13 +11695,61 @@
                         DisplayList.FLAG_CLIP_CHILDREN);
                 canvas.translate(-mScrollX, -mScrollY);
             } else {
-                layout.draw(canvas, highlight, highlightPaint, cursorOffsetVertical);
+                layout.draw(canvas, highlight, mHighlightPaint, cursorOffsetVertical);
             }
 
             if (mMarquee != null && mMarquee.shouldDrawGhost()) {
                 canvas.translate((int) mMarquee.getGhostOffset(), 0.0f);
-                layout.draw(canvas, highlight, highlightPaint, cursorOffsetVertical);
+                layout.draw(canvas, highlight, mHighlightPaint, cursorOffsetVertical);
             }
         }
+
+        private void drawCursor(Canvas canvas, int cursorOffsetVertical) {
+            final boolean translate = cursorOffsetVertical != 0;
+            if (translate) canvas.translate(0, cursorOffsetVertical);
+            for (int i = 0; i < getEditor().mCursorCount; i++) {
+                mCursorDrawable[i].draw(canvas);
+            }
+            if (translate) canvas.translate(0, -cursorOffsetVertical);
+        }
+
+        private void updateCursorsPositions() {
+            if (mCursorDrawableRes == 0) {
+                mCursorCount = 0;
+                return;
+            }
+
+            final int offset = getSelectionStart();
+            final int line = mLayout.getLineForOffset(offset);
+            final int top = mLayout.getLineTop(line);
+            final int bottom = mLayout.getLineTop(line + 1);
+
+            mCursorCount = mLayout.isLevelBoundary(offset) ? 2 : 1;
+
+            int middle = bottom;
+            if (mCursorCount == 2) {
+                // Similar to what is done in {@link Layout.#getCursorPath(int, Path, CharSequence)}
+                middle = (top + bottom) >> 1;
+            }
+
+            updateCursorPosition(0, top, middle, mLayout.getPrimaryHorizontal(offset));
+
+            if (mCursorCount == 2) {
+                updateCursorPosition(1, middle, bottom, mLayout.getSecondaryHorizontal(offset));
+            }
+        }
+
+        private void updateCursorPosition(int cursorIndex, int top, int bottom, float horizontal) {
+            if (mCursorDrawable[cursorIndex] == null)
+                mCursorDrawable[cursorIndex] = mContext.getResources().getDrawable(mCursorDrawableRes);
+
+            if (mTempRect == null) mTempRect = new Rect();
+            mCursorDrawable[cursorIndex].getPadding(mTempRect);
+            final int width = mCursorDrawable[cursorIndex].getIntrinsicWidth();
+            horizontal = Math.max(0.5f, horizontal - 0.5f);
+            final int left = (int) (horizontal) - mTempRect.left;
+            mCursorDrawable[cursorIndex].setBounds(left, top - mTempRect.top, left + width,
+                    bottom + mTempRect.bottom);
+        }
     }
 }
diff --git a/core/java/com/android/internal/app/ActionBarImpl.java b/core/java/com/android/internal/app/ActionBarImpl.java
index afb5bf1..f3486bd 100644
--- a/core/java/com/android/internal/app/ActionBarImpl.java
+++ b/core/java/com/android/internal/app/ActionBarImpl.java
@@ -748,6 +748,16 @@
         }
         
         @Override
+        public void setTitleOptionalHint(boolean titleOptional) {
+            mContextView.setTitleOptional(titleOptional);
+        }
+
+        @Override
+        public boolean isTitleOptional() {
+            return mContextView.isTitleOptional();
+        }
+
+        @Override
         public View getCustomView() {
             return mCustomView != null ? mCustomView.get() : null;
         }
diff --git a/core/java/com/android/internal/net/NetworkStatsFactory.java b/core/java/com/android/internal/net/NetworkStatsFactory.java
index 41993c4..ccd2763 100644
--- a/core/java/com/android/internal/net/NetworkStatsFactory.java
+++ b/core/java/com/android/internal/net/NetworkStatsFactory.java
@@ -22,12 +22,12 @@
 import static com.android.server.NetworkManagementSocketTagger.kernelToTag;
 
 import android.net.NetworkStats;
+import android.os.StrictMode;
 import android.os.SystemClock;
 import android.util.Slog;
 
 import com.android.internal.util.ProcFileReader;
 import com.google.android.collect.Lists;
-import com.google.android.collect.Maps;
 import com.google.android.collect.Sets;
 
 import java.io.BufferedReader;
@@ -36,7 +36,6 @@
 import java.io.FileReader;
 import java.io.IOException;
 import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.HashSet;
 import java.util.StringTokenizer;
 
@@ -62,22 +61,6 @@
     /** Path to {@code /proc/net/xt_qtaguid/stats}. */
     private final File mStatsXtUid;
 
-    /** {@link #mStatsXtUid} and {@link #mStatsXtIfaceAll} headers. */
-    private static final String KEY_IDX = "idx";
-    private static final String KEY_IFACE = "iface";
-    private static final String KEY_ACTIVE = "active";
-    private static final String KEY_UID = "uid_tag_int";
-    private static final String KEY_COUNTER_SET = "cnt_set";
-    private static final String KEY_TAG_HEX = "acct_tag_hex";
-    private static final String KEY_SNAP_RX_BYTES = "snap_rx_bytes";
-    private static final String KEY_SNAP_RX_PACKETS = "snap_rx_packets";
-    private static final String KEY_SNAP_TX_BYTES = "snap_tx_bytes";
-    private static final String KEY_SNAP_TX_PACKETS = "snap_tx_packets";
-    private static final String KEY_RX_BYTES = "rx_bytes";
-    private static final String KEY_RX_PACKETS = "rx_packets";
-    private static final String KEY_TX_BYTES = "tx_bytes";
-    private static final String KEY_TX_PACKETS = "tx_packets";
-
     public NetworkStatsFactory() {
         this(new File("/proc/"));
     }
@@ -106,47 +89,39 @@
     }
 
     private NetworkStats readNetworkStatsSummarySingleFile() {
+        final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskReads();
+
         final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 6);
         final NetworkStats.Entry entry = new NetworkStats.Entry();
 
-        // TODO: transition to ProcFileReader
-        // TODO: read directly from proc once headers are added
-        final ArrayList<String> keys = Lists.newArrayList(KEY_IFACE, KEY_ACTIVE, KEY_SNAP_RX_BYTES,
-                KEY_SNAP_RX_PACKETS, KEY_SNAP_TX_BYTES, KEY_SNAP_TX_PACKETS, KEY_RX_BYTES,
-                KEY_RX_PACKETS, KEY_TX_BYTES, KEY_TX_PACKETS);
-        final ArrayList<String> values = Lists.newArrayList();
-        final HashMap<String, String> parsed = Maps.newHashMap();
-
-        BufferedReader reader = null;
+        ProcFileReader reader = null;
         try {
-            reader = new BufferedReader(new FileReader(mStatsXtIfaceAll));
+            reader = new ProcFileReader(new FileInputStream(mStatsXtIfaceAll));
 
-            String line;
-            while ((line = reader.readLine()) != null) {
-                splitLine(line, values);
-                parseLine(keys, values, parsed);
-
-                entry.iface = parsed.get(KEY_IFACE);
+            while (reader.hasMoreData()) {
+                entry.iface = reader.nextString();
                 entry.uid = UID_ALL;
                 entry.set = SET_DEFAULT;
                 entry.tag = TAG_NONE;
 
+                final boolean active = reader.nextInt() != 0;
+
                 // always include snapshot values
-                entry.rxBytes = getParsedLong(parsed, KEY_SNAP_RX_BYTES);
-                entry.rxPackets = getParsedLong(parsed, KEY_SNAP_RX_PACKETS);
-                entry.txBytes = getParsedLong(parsed, KEY_SNAP_TX_BYTES);
-                entry.txPackets = getParsedLong(parsed, KEY_SNAP_TX_PACKETS);
+                entry.rxBytes = reader.nextLong();
+                entry.rxPackets = reader.nextLong();
+                entry.txBytes = reader.nextLong();
+                entry.txPackets = reader.nextLong();
 
                 // fold in active numbers, but only when active
-                final boolean active = getParsedInt(parsed, KEY_ACTIVE) != 0;
                 if (active) {
-                    entry.rxBytes += getParsedLong(parsed, KEY_RX_BYTES);
-                    entry.rxPackets += getParsedLong(parsed, KEY_RX_PACKETS);
-                    entry.txBytes += getParsedLong(parsed, KEY_TX_BYTES);
-                    entry.txPackets += getParsedLong(parsed, KEY_TX_PACKETS);
+                    entry.rxBytes += reader.nextLong();
+                    entry.rxPackets += reader.nextLong();
+                    entry.txBytes += reader.nextLong();
+                    entry.txPackets += reader.nextLong();
                 }
 
                 stats.addValues(entry);
+                reader.finishLine();
             }
         } catch (NullPointerException e) {
             throw new IllegalStateException("problem parsing stats: " + e);
@@ -156,6 +131,7 @@
             throw new IllegalStateException("problem parsing stats: " + e);
         } finally {
             IoUtils.closeQuietly(reader);
+            StrictMode.setThreadPolicy(savedPolicy);
         }
         return stats;
     }
@@ -165,6 +141,8 @@
      */
     @Deprecated
     private NetworkStats readNetworkStatsSummaryMultipleFiles() {
+        final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskReads();
+
         final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 6);
         final NetworkStats.Entry entry = new NetworkStats.Entry();
 
@@ -241,6 +219,7 @@
             throw new IllegalStateException("problem parsing stats: " + e);
         } finally {
             IoUtils.closeQuietly(reader);
+            StrictMode.setThreadPolicy(savedPolicy);
         }
 
         return stats;
@@ -257,6 +236,8 @@
      * @throws IllegalStateException when problem parsing stats.
      */
     public NetworkStats readNetworkStatsDetail(int limitUid) throws IllegalStateException {
+        final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskReads();
+
         final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 24);
         final NetworkStats.Entry entry = new NetworkStats.Entry();
 
@@ -300,23 +281,12 @@
             throw new IllegalStateException("problem parsing idx " + idx, e);
         } finally {
             IoUtils.closeQuietly(reader);
+            StrictMode.setThreadPolicy(savedPolicy);
         }
 
         return stats;
     }
 
-    @Deprecated
-    private static int getParsedInt(HashMap<String, String> parsed, String key) {
-        final String value = parsed.get(key);
-        return value != null ? Integer.parseInt(value) : 0;
-    }
-
-    @Deprecated
-    private static long getParsedLong(HashMap<String, String> parsed, String key) {
-        final String value = parsed.get(key);
-        return value != null ? Long.parseLong(value) : 0;
-    }
-
     /**
      * Split given line into {@link ArrayList}.
      */
@@ -331,21 +301,6 @@
     }
 
     /**
-     * Zip the two given {@link ArrayList} as key and value pairs into
-     * {@link HashMap}.
-     */
-    @Deprecated
-    private static void parseLine(
-            ArrayList<String> keys, ArrayList<String> values, HashMap<String, String> outParsed) {
-        outParsed.clear();
-
-        final int size = Math.min(keys.size(), values.size());
-        for (int i = 0; i < size; i++) {
-            outParsed.put(keys.get(i), values.get(i));
-        }
-    }
-
-    /**
      * Utility method to read a single plain-text {@link Long} from the given
      * {@link File}, usually from a {@code /proc/} filesystem.
      */
diff --git a/core/java/com/android/internal/util/FileRotator.java b/core/java/com/android/internal/util/FileRotator.java
index 8a8f315..6cfb97d 100644
--- a/core/java/com/android/internal/util/FileRotator.java
+++ b/core/java/com/android/internal/util/FileRotator.java
@@ -48,7 +48,7 @@
  */
 public class FileRotator {
     private static final String TAG = "FileRotator";
-    private static final boolean LOGD = true;
+    private static final boolean LOGD = false;
 
     private final File mBasePath;
     private final String mPrefix;
diff --git a/core/java/com/android/internal/view/IInputMethodManager.aidl b/core/java/com/android/internal/view/IInputMethodManager.aidl
index 5d80b79..82b2654 100644
--- a/core/java/com/android/internal/view/IInputMethodManager.aidl
+++ b/core/java/com/android/internal/view/IInputMethodManager.aidl
@@ -43,16 +43,17 @@
     void removeClient(in IInputMethodClient client);
             
     InputBindResult startInput(in IInputMethodClient client,
-            IInputContext inputContext, in EditorInfo attribute,
-            boolean initial, boolean needResult);
+            IInputContext inputContext, in EditorInfo attribute, int controlFlags);
     void finishInput(in IInputMethodClient client);
     boolean showSoftInput(in IInputMethodClient client, int flags,
             in ResultReceiver resultReceiver);
     boolean hideSoftInput(in IInputMethodClient client, int flags,
             in ResultReceiver resultReceiver);
-    void windowGainedFocus(in IInputMethodClient client, in IBinder windowToken,
-            boolean viewHasFocus, boolean isTextEditor,
-            int softInputMode, boolean first, int windowFlags);
+    // Report that a window has gained focus.  If 'attribute' is non-null,
+    // this will also do a startInput.
+    InputBindResult windowGainedFocus(in IInputMethodClient client, in IBinder windowToken,
+            int controlFlags, int softInputMode, int windowFlags,
+            in EditorInfo attribute, IInputContext inputContext);
             
     void showInputMethodPickerFromClient(in IInputMethodClient client);
     void showInputMethodAndSubtypeEnablerFromClient(in IInputMethodClient client, String topId);
diff --git a/core/java/com/android/internal/view/StandaloneActionMode.java b/core/java/com/android/internal/view/StandaloneActionMode.java
index edf4443..4b681ec 100644
--- a/core/java/com/android/internal/view/StandaloneActionMode.java
+++ b/core/java/com/android/internal/view/StandaloneActionMode.java
@@ -72,6 +72,16 @@
     }
 
     @Override
+    public void setTitleOptionalHint(boolean titleOptional) {
+        mContextView.setTitleOptional(titleOptional);
+    }
+
+    @Override
+    public boolean isTitleOptional() {
+        return mContextView.isTitleOptional();
+    }
+
+    @Override
     public void setCustomView(View view) {
         mContextView.setCustomView(view);
         mCustomView = view != null ? new WeakReference<View>(view) : null;
diff --git a/core/java/com/android/internal/widget/ActionBarContextView.java b/core/java/com/android/internal/widget/ActionBarContextView.java
index fa16527..16f08f5 100644
--- a/core/java/com/android/internal/widget/ActionBarContextView.java
+++ b/core/java/com/android/internal/widget/ActionBarContextView.java
@@ -56,6 +56,7 @@
     private int mTitleStyleRes;
     private int mSubtitleStyleRes;
     private Drawable mSplitBackground;
+    private boolean mTitleOptional;
 
     private Animator mCurrentAnimation;
     private boolean mAnimateInOnLayout;
@@ -354,7 +355,18 @@
         }
 
         if (mTitleLayout != null && mCustomView == null) {
-            availableWidth = measureChildView(mTitleLayout, availableWidth, childSpecHeight, 0);
+            if (mTitleOptional) {
+                final int titleWidthSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
+                mTitleLayout.measure(titleWidthSpec, childSpecHeight);
+                final int titleWidth = mTitleLayout.getMeasuredWidth();
+                final boolean titleFits = titleWidth <= availableWidth;
+                if (titleFits) {
+                    availableWidth -= titleWidth;
+                }
+                mTitleLayout.setVisibility(titleFits ? VISIBLE : GONE);
+            } else {
+                availableWidth = measureChildView(mTitleLayout, availableWidth, childSpecHeight, 0);
+            }
         }
 
         if (mCustomView != null) {
@@ -460,7 +472,7 @@
             }
         }
 
-        if (mTitleLayout != null && mCustomView == null) {
+        if (mTitleLayout != null && mCustomView == null && mTitleLayout.getVisibility() != GONE) {
             x += positionChild(mTitleLayout, x, y, contentHeight);
         }
         
@@ -512,4 +524,15 @@
             super.onInitializeAccessibilityEvent(event);
         }
     }
+
+    public void setTitleOptional(boolean titleOptional) {
+        if (titleOptional != mTitleOptional) {
+            requestLayout();
+        }
+        mTitleOptional = titleOptional;
+    }
+
+    public boolean isTitleOptional() {
+        return mTitleOptional;
+    }
 }
diff --git a/core/java/com/android/internal/widget/EditableInputConnection.java b/core/java/com/android/internal/widget/EditableInputConnection.java
index 9579bce..4cbdf78 100644
--- a/core/java/com/android/internal/widget/EditableInputConnection.java
+++ b/core/java/com/android/internal/widget/EditableInputConnection.java
@@ -70,7 +70,7 @@
     public boolean endBatchEdit() {
         synchronized(this) {
             if (mBatchEditNesting > 0) {
-                // When the connection is reset by the InputMethodManager and finishComposingText
+                // When the connection is reset by the InputMethodManager and reportFinish
                 // is called, some endBatchEdit calls may still be asynchronously received from the
                 // IME. Do not take these into account, thus ensuring that this IC's final
                 // contribution to mTextView's nested batch edit count is zero.
@@ -83,6 +83,19 @@
     }
 
     @Override
+    protected void reportFinish() {
+        super.reportFinish();
+
+        synchronized(this) {
+            while (mBatchEditNesting > 0) {
+                endBatchEdit();
+            }
+            // Will prevent any further calls to begin or endBatchEdit
+            mBatchEditNesting = -1;
+        }
+    }
+
+    @Override
     public boolean clearMetaKeyStates(int states) {
         final Editable content = getEditable();
         if (content == null) return false;
@@ -99,23 +112,6 @@
     }
 
     @Override
-    public boolean finishComposingText() {
-        final boolean superResult = super.finishComposingText();
-        synchronized(this) {
-            if (mBatchEditNesting < 0) {
-                // The connection was already finished
-                return false;
-            }
-            while (mBatchEditNesting > 0) {
-                endBatchEdit();
-            }
-            // Will prevent any further calls to begin or endBatchEdit
-            mBatchEditNesting = -1;
-        }
-        return superResult;
-    }
-
-    @Override
     public boolean commitCompletion(CompletionInfo text) {
         if (DEBUG) Log.v(TAG, "commitCompletion " + text);
         mTextView.beginBatchEdit();
diff --git a/core/java/com/android/internal/widget/ScrollingTabContainerView.java b/core/java/com/android/internal/widget/ScrollingTabContainerView.java
index 25b0065..1767d68 100644
--- a/core/java/com/android/internal/widget/ScrollingTabContainerView.java
+++ b/core/java/com/android/internal/widget/ScrollingTabContainerView.java
@@ -45,7 +45,7 @@
  * across different configurations or circumstances.
  */
 public class ScrollingTabContainerView extends HorizontalScrollView
-        implements AdapterView.OnItemSelectedListener {
+        implements AdapterView.OnItemClickListener {
     private static final String TAG = "ScrollingTabContainerView";
     Runnable mTabSelector;
     private TabClickListener mTabClickListener;
@@ -197,7 +197,7 @@
                 com.android.internal.R.attr.actionDropDownStyle);
         spinner.setLayoutParams(new LinearLayout.LayoutParams(
                 LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.MATCH_PARENT));
-        spinner.setOnItemSelectedListener(this);
+        spinner.setOnItemClickListenerInt(this);
         return spinner;
     }
 
@@ -347,15 +347,11 @@
     }
 
     @Override
-    public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
+    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
         TabView tabView = (TabView) view;
         tabView.getTab().select();
     }
 
-    @Override
-    public void onNothingSelected(AdapterView<?> parent) {
-    }
-
     private class TabView extends LinearLayout {
         private ActionBar.Tab mTab;
         private TextView mTextView;
diff --git a/core/jni/android/graphics/TextLayout.cpp b/core/jni/android/graphics/TextLayout.cpp
index 2241f60..2beedad 100644
--- a/core/jni/android/graphics/TextLayout.cpp
+++ b/core/jni/android/graphics/TextLayout.cpp
@@ -101,11 +101,6 @@
     SkScalar h_ = SkFloatToScalar(hOffset);
     SkScalar v_ = SkFloatToScalar(vOffset);
 
-    if (!needsLayout(text, count, bidiFlags)) {
-        canvas->drawTextOnPathHV(text, count << 1, *path, h_, v_, *paint);
-        return;
-    }
-
     sp<TextLayoutValue> value = TextLayoutEngine::getInstance().getValue(paint,
             text, 0, count, count, bidiFlags);
     if (value == NULL) {
diff --git a/core/jni/android/graphics/TextLayoutCache.cpp b/core/jni/android/graphics/TextLayoutCache.cpp
index 7f5d54d..efeba5c 100644
--- a/core/jni/android/graphics/TextLayoutCache.cpp
+++ b/core/jni/android/graphics/TextLayoutCache.cpp
@@ -36,6 +36,8 @@
 #define TYPE_FACE_HEBREW_REGULAR "/system/fonts/DroidSansHebrew-Regular.ttf"
 #define TYPE_FACE_HEBREW_BOLD "/system/fonts/DroidSansHebrew-Bold.ttf"
 #define TYPEFACE_BENGALI "/system/fonts/Lohit-Bengali.ttf"
+#define TYPEFACE_DEVANAGARI "/system/fonts/Lohit-Devanagari.ttf"
+#define TYPEFACE_TAMIL "/system/fonts/Lohit-Tamil.ttf"
 #define TYPEFACE_THAI "/system/fonts/DroidSansThai.ttf"
 
 ANDROID_SINGLETON_STATIC_INSTANCE(TextLayoutEngine);
@@ -828,6 +830,20 @@
 #endif
         break;
 
+    case HB_Script_Devanagari:
+        typeface = getCachedTypeface(&mDevanagariTypeface, TYPEFACE_DEVANAGARI);
+#if DEBUG_GLYPHS
+        ALOGD("Using Devanagari Typeface");
+#endif
+        break;
+
+    case HB_Script_Tamil:
+        typeface = getCachedTypeface(&mTamilTypeface, TYPEFACE_TAMIL);
+#if DEBUG_GLYPHS
+        ALOGD("Using Tamil Typeface");
+#endif
+        break;
+
     default:
         if (!typeface) {
             typeface = mDefaultTypeface;
@@ -859,6 +875,8 @@
     case HB_Script_Arabic:
     case HB_Script_Hebrew:
     case HB_Script_Bengali:
+    case HB_Script_Devanagari:
+    case HB_Script_Tamil:
     case HB_Script_Thai:{
         const uint16_t* text16 = (const uint16_t*)(mShaperItem.string + mShaperItem.item.pos);
         SkUnichar firstUnichar = SkUTF16_NextUnichar(&text16);
diff --git a/core/jni/android/graphics/TextLayoutCache.h b/core/jni/android/graphics/TextLayoutCache.h
index 7ac2f18..3c834a4 100644
--- a/core/jni/android/graphics/TextLayoutCache.h
+++ b/core/jni/android/graphics/TextLayoutCache.h
@@ -194,6 +194,8 @@
     SkTypeface* mHebrewBoldTypeface;
     SkTypeface* mBengaliTypeface;
     SkTypeface* mThaiTypeface;
+    SkTypeface* mDevanagariTypeface;
+    SkTypeface* mTamilTypeface;
 
     /**
      * Cache of Harfbuzz faces
diff --git a/core/jni/android_app_NativeActivity.cpp b/core/jni/android_app_NativeActivity.cpp
index 4b3324b..088062a 100644
--- a/core/jni/android_app_NativeActivity.cpp
+++ b/core/jni/android_app_NativeActivity.cpp
@@ -21,13 +21,16 @@
 #include <dlfcn.h>
 #include <fcntl.h>
 
-#include <android_runtime/AndroidRuntime.h>
-#include <android_runtime/android_view_Surface.h>
 #include <android_runtime/android_app_NativeActivity.h>
 #include <android_runtime/android_util_AssetManager.h>
-#include <surfaceflinger/Surface.h>
-#include <ui/egl/android_natives.h>
+#include <android_runtime/android_view_Surface.h>
+#include <android_runtime/AndroidRuntime.h>
 #include <androidfw/InputTransport.h>
+
+#include <gui/Surface.h>
+
+#include <system/window.h>
+
 #include <utils/Looper.h>
 
 #include "JNIHelp.h"
diff --git a/core/jni/android_database_CursorWindow.cpp b/core/jni/android_database_CursorWindow.cpp
index d53644d..579d6ad 100644
--- a/core/jni/android_database_CursorWindow.cpp
+++ b/core/jni/android_database_CursorWindow.cpp
@@ -30,7 +30,7 @@
 #include <string.h>
 #include <unistd.h>
 
-#include "binder/CursorWindow.h"
+#include <androidfw/CursorWindow.h>
 #include "android_util_Binder.h"
 #include "android_database_SQLiteCommon.h"
 
diff --git a/core/jni/android_database_SQLiteConnection.cpp b/core/jni/android_database_SQLiteConnection.cpp
index e061ac3..f47dc8a 100644
--- a/core/jni/android_database_SQLiteConnection.cpp
+++ b/core/jni/android_database_SQLiteConnection.cpp
@@ -29,7 +29,7 @@
 #include <string.h>
 #include <unistd.h>
 
-#include "binder/CursorWindow.h"
+#include <androidfw/CursorWindow.h>
 
 #include <sqlite3.h>
 #include <sqlite3_android.h>
@@ -426,11 +426,11 @@
     SQLiteConnection* connection = reinterpret_cast<SQLiteConnection*>(connectionPtr);
     sqlite3_stmt* statement = reinterpret_cast<sqlite3_stmt*>(statementPtr);
 
+    // We ignore the result of sqlite3_finalize because it is really telling us about
+    // whether any errors occurred while executing the statement.  The statement itself
+    // is always finalized regardless.
     ALOGV("Finalized statement %p on connection %p", statement, connection->db);
-    int err = sqlite3_finalize(statement);
-    if (err != SQLITE_OK) {
-        throw_sqlite3_exception(env, connection->db, NULL);
-    }
+    sqlite3_finalize(statement);
 }
 
 static jint nativeGetParameterCount(JNIEnv* env, jclass clazz, jint connectionPtr,
diff --git a/core/jni/android_hardware_Camera.cpp b/core/jni/android_hardware_Camera.cpp
index b89273b..599211e 100644
--- a/core/jni/android_hardware_Camera.cpp
+++ b/core/jni/android_hardware_Camera.cpp
@@ -26,7 +26,7 @@
 #include <utils/Vector.h>
 
 #include <gui/SurfaceTexture.h>
-#include <surfaceflinger/Surface.h>
+#include <gui/Surface.h>
 #include <camera/Camera.h>
 #include <binder/IMemory.h>
 
diff --git a/core/jni/android_view_Display.cpp b/core/jni/android_view_Display.cpp
index f076cc8..aedf1e4 100644
--- a/core/jni/android_view_Display.cpp
+++ b/core/jni/android_view_Display.cpp
@@ -19,7 +19,7 @@
 
 #include <cutils/properties.h>
 
-#include <surfaceflinger/SurfaceComposerClient.h>
+#include <gui/SurfaceComposerClient.h>
 #include <ui/PixelFormat.h>
 #include <ui/DisplayInfo.h>
 
diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp
index cdce4f9..f0560c1 100644
--- a/core/jni/android_view_GLES20Canvas.cpp
+++ b/core/jni/android_view_GLES20Canvas.cpp
@@ -521,6 +521,20 @@
     renderer->drawText((const char*) glyphs, bytesCount, glyphsCount, x, y, paint);
 }
 
+static void renderTextOnPath(OpenGLRenderer* renderer, const jchar* text, int count,
+        SkPath* path, jfloat hOffset, jfloat vOffset, int flags, SkPaint* paint) {
+    sp<TextLayoutValue> value = TextLayoutEngine::getInstance().getValue(paint,
+            text, 0, count, count, flags);
+    if (value == NULL) {
+        return;
+    }
+    const jchar* glyphs = value->getGlyphs();
+    size_t glyphsCount = value->getGlyphsCount();
+    int bytesCount = glyphsCount * sizeof(jchar);
+    renderer->drawTextOnPath((const char*) glyphs, bytesCount, glyphsCount, path,
+            hOffset, vOffset, paint);
+}
+
 static void renderTextRun(OpenGLRenderer* renderer, const jchar* text,
         jint start, jint count, jint contextCount, jfloat x, jfloat y,
         int flags, SkPaint* paint) {
@@ -551,6 +565,24 @@
     env->ReleaseStringChars(text, textArray);
 }
 
+static void android_view_GLES20Canvas_drawTextArrayOnPath(JNIEnv* env, jobject clazz,
+        OpenGLRenderer* renderer, jcharArray text, jint index, jint count,
+        SkPath* path, jfloat hOffset, jfloat vOffset, jint flags, SkPaint* paint) {
+    jchar* textArray = env->GetCharArrayElements(text, NULL);
+    renderTextOnPath(renderer, textArray + index, count, path,
+            hOffset, vOffset, flags, paint);
+    env->ReleaseCharArrayElements(text, textArray, JNI_ABORT);
+}
+
+static void android_view_GLES20Canvas_drawTextOnPath(JNIEnv* env, jobject clazz,
+        OpenGLRenderer* renderer, jstring text, jint start, jint end,
+        SkPath* path, jfloat hOffset, jfloat vOffset, jint flags, SkPaint* paint) {
+    const jchar* textArray = env->GetStringChars(text, NULL);
+    renderTextOnPath(renderer, textArray + start, end - start, path,
+            hOffset, vOffset, flags, paint);
+    env->ReleaseStringChars(text, textArray);
+}
+
 static void android_view_GLES20Canvas_drawTextRunArray(JNIEnv* env, jobject clazz,
         OpenGLRenderer* renderer, jcharArray text, jint index, jint count,
         jint contextIndex, jint contextCount, jfloat x, jfloat y, jint dirFlags,
@@ -885,6 +917,10 @@
     { "nDrawText",          "(ILjava/lang/String;IIFFII)V",
             (void*) android_view_GLES20Canvas_drawText },
 
+    { "nDrawTextOnPath",    "(I[CIIIFFII)V",   (void*) android_view_GLES20Canvas_drawTextArrayOnPath },
+    { "nDrawTextOnPath",    "(ILjava/lang/String;IIIFFII)V",
+            (void*) android_view_GLES20Canvas_drawTextOnPath },
+
     { "nDrawTextRun",       "(I[CIIIIFFII)V",  (void*) android_view_GLES20Canvas_drawTextRunArray },
     { "nDrawTextRun",       "(ILjava/lang/String;IIIIFFII)V",
             (void*) android_view_GLES20Canvas_drawTextRun },
diff --git a/core/jni/android_view_Surface.cpp b/core/jni/android_view_Surface.cpp
index 18bcea1..c387752 100644
--- a/core/jni/android_view_Surface.cpp
+++ b/core/jni/android_view_Surface.cpp
@@ -22,11 +22,13 @@
 #include "android/graphics/GraphicsJNI.h"
 
 #include <binder/IMemory.h>
+
+#include <gui/Surface.h>
+#include <gui/SurfaceComposerClient.h>
 #include <gui/SurfaceTexture.h>
-#include <surfaceflinger/SurfaceComposerClient.h>
-#include <surfaceflinger/Surface.h>
-#include <ui/Region.h>
+
 #include <ui/Rect.h>
+#include <ui/Region.h>
 
 #include <EGL/egl.h>
 
diff --git a/core/jni/com_google_android_gles_jni_EGLImpl.cpp b/core/jni/com_google_android_gles_jni_EGLImpl.cpp
index 4fe7600..5483867 100644
--- a/core/jni/com_google_android_gles_jni_EGLImpl.cpp
+++ b/core/jni/com_google_android_gles_jni_EGLImpl.cpp
@@ -21,17 +21,19 @@
 #include <android_runtime/android_graphics_SurfaceTexture.h>
 #include <utils/misc.h>
 
+
+#include <EGL/egl_display.h>
 #include <EGL/egl.h>
 #include <GLES/gl.h>
 
-#include <EGL/egl_display.h>
+#include <gui/Surface.h>
+#include <gui/SurfaceTexture.h>
+#include <gui/SurfaceTextureClient.h>
 
-#include <surfaceflinger/Surface.h>
 #include <SkBitmap.h>
 #include <SkPixelRef.h>
 
-#include <gui/SurfaceTexture.h>
-#include <gui/SurfaceTextureClient.h>
+#include <ui/ANativeObjectBase.h>
 
 namespace android {
 
@@ -44,7 +46,6 @@
 static jfieldID gSurface_EGLSurfaceFieldID;
 static jfieldID gSurface_NativePixelRefFieldID;
 static jfieldID gConfig_EGLConfigFieldID;
-static jfieldID gSurface_SurfaceFieldID;
 static jfieldID gBitmap_NativeBitmapFieldID;
 
 static inline EGLDisplay getDisplay(JNIEnv* env, jobject o) {
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index a2b1117..17d2212 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -121,6 +121,7 @@
     <protected-broadcast android:name="android.intent.action.CLEAR_DNS_CACHE" />
     <protected-broadcast android:name="android.intent.action.PROXY_CHANGE" />
 
+    <protected-broadcast android:name="android.os.UpdateLock.UPDATE_LOCK_CHANGED" />
 
     <!-- ====================================== -->
     <!-- Permissions for things that cost money -->
@@ -147,7 +148,7 @@
          @hide -->
     <permission android:name="android.permission.SEND_SMS_NO_CONFIRMATION"
         android:permissionGroup="android.permission-group.COST_MONEY"
-        android:protectionLevel="signatureOrSystem"
+        android:protectionLevel="signature|system"
         android:label="@string/permlab_sendSmsNoConfirmation"
         android:description="@string/permdesc_sendSmsNoConfirmation" />
 
@@ -194,7 +195,7 @@
          @hide Pending API council approval -->
     <permission android:name="android.permission.RECEIVE_EMERGENCY_BROADCAST"
         android:permissionGroup="android.permission-group.MESSAGES"
-        android:protectionLevel="signatureOrSystem"
+        android:protectionLevel="signature|system"
         android:label="@string/permlab_receiveEmergencyBroadcast"
         android:description="@string/permdesc_receiveEmergencyBroadcast" />
 
@@ -383,7 +384,7 @@
 
     <!-- Allows an application to install a location provider into the Location Manager -->
     <permission android:name="android.permission.INSTALL_LOCATION_PROVIDER"
-        android:protectionLevel="signatureOrSystem"
+        android:protectionLevel="signature|system"
         android:label="@string/permlab_installLocationProvider"
         android:description="@string/permdesc_installLocationProvider" />
 
@@ -461,7 +462,7 @@
         @hide -->
     <permission android:name="android.permission.CONNECTIVITY_INTERNAL"
         android:permissionGroup="android.permission-group.NETWORK"
-        android:protectionLevel="signatureOrSystem" />
+        android:protectionLevel="signature|system" />
 
     <!-- ================================== -->
     <!-- Permissions for accessing accounts -->
@@ -559,7 +560,7 @@
          @hide -->
     <permission android:name="android.permission.MANAGE_USB"
         android:permissionGroup="android.permission-group.HARDWARE_CONTROLS"
-        android:protectionLevel="signatureOrSystem"
+        android:protectionLevel="signature|system"
         android:label="@string/permlab_manageUsb"
         android:description="@string/permdesc_manageUsb" />
 
@@ -568,7 +569,7 @@
          @hide -->
     <permission android:name="android.permission.ACCESS_MTP"
         android:permissionGroup="android.permission-group.HARDWARE_CONTROLS"
-        android:protectionLevel="signatureOrSystem"
+        android:protectionLevel="signature|system"
         android:label="@string/permlab_accessMtp"
         android:description="@string/permdesc_accessMtp" />
 
@@ -611,7 +612,7 @@
          Does not include placing calls. -->
     <permission android:name="android.permission.MODIFY_PHONE_STATE"
         android:permissionGroup="android.permission-group.PHONE_CALLS"
-        android:protectionLevel="signatureOrSystem"
+        android:protectionLevel="signature|system"
         android:label="@string/permlab_modifyPhoneState"
         android:description="@string/permdesc_modifyPhoneState" />
 
@@ -626,7 +627,7 @@
          @hide Used internally. -->
     <permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE"
         android:permissionGroup="android.permission-group.PHONE_CALLS"
-        android:protectionLevel="signatureOrSystem" />
+        android:protectionLevel="signature|system" />
 
     <!-- ================================== -->
     <!-- Permissions for sdcard interaction -->
@@ -651,7 +652,7 @@
         android:permissionGroup="android.permission-group.STORAGE"
         android:label="@string/permlab_mediaStorageWrite"
         android:description="@string/permdesc_mediaStorageWrite"
-        android:protectionLevel="signatureOrSystem" />
+        android:protectionLevel="signature|system" />
 
     <!-- ============================================ -->
     <!-- Permissions for low-level system interaction -->
@@ -675,15 +676,9 @@
         android:label="@string/permlab_writeSettings"
         android:description="@string/permdesc_writeSettings" />
 
-    <!-- Allows an application to read or write the secure system settings. -->
-    <permission android:name="android.permission.WRITE_SECURE_SETTINGS"
-        android:protectionLevel="signatureOrSystem"
-        android:label="@string/permlab_writeSecureSettings"
-        android:description="@string/permdesc_writeSecureSettings" />
-
     <!-- Allows an application to modify the Google service map. -->
     <permission android:name="android.permission.WRITE_GSERVICES"
-        android:protectionLevel="signatureOrSystem"
+        android:protectionLevel="signature|system"
         android:label="@string/permlab_writeGservices"
         android:description="@string/permdesc_writeGservices" />
 
@@ -757,19 +752,11 @@
         android:label="@string/permlab_forceStopPackages"
         android:description="@string/permdesc_forceStopPackages" />
 
-    <!-- Allows an application to retrieve state dump information from system
-         services. -->
-    <permission android:name="android.permission.DUMP"
-        android:permissionGroup="android.permission-group.PERSONAL_INFO"
-        android:protectionLevel="signatureOrSystem"
-        android:label="@string/permlab_dump"
-        android:description="@string/permdesc_dump" />
-
     <!-- @hide Allows an application to retrieve the content of the active window
          An active window is the window that has fired an accessibility event. -->
     <permission android:name="android.permission.RETRIEVE_WINDOW_CONTENT"
         android:permissionGroup="android.permission-group.PERSONAL_INFO"
-        android:protectionLevel="signatureOrSystem"
+        android:protectionLevel="signature|system"
         android:label="@string/permlab_retrieve_window_content"
         android:description="@string/permdesc_retrieve_window_content" />
 
@@ -868,7 +855,7 @@
 
     <!-- Allows applications to set the system time -->
     <permission android:name="android.permission.SET_TIME"
-        android:protectionLevel="signatureOrSystem"
+        android:protectionLevel="signature|system"
         android:label="@string/permlab_setTime"
         android:description="@string/permdesc_setTime" />
 
@@ -964,7 +951,7 @@
     <!-- Allows applications to write the apn settings -->
     <permission android:name="android.permission.WRITE_APN_SETTINGS"
                 android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
-                android:protectionLevel="signatureOrSystem"
+                android:protectionLevel="signature|system"
                 android:description="@string/permdesc_writeApnSettings"
                 android:label="@string/permlab_writeApnSettings" />
 
@@ -1035,7 +1022,7 @@
     <!-- Allows an application to use any media decoder when decoding for playback
          @hide -->
     <permission android:name="android.permission.ALLOW_ANY_CODEC_FOR_PLAYBACK"
-        android:protectionLevel="signatureOrSystem"
+        android:protectionLevel="signature|system"
         android:label="@string/permlab_anyCodecForPlayback"
         android:description="@string/permdesc_anyCodecForPlayback" />
 
@@ -1052,6 +1039,21 @@
         android:label="@string/permgrouplab_developmentTools"
         android:description="@string/permgroupdesc_developmentTools" />
 
+    <!-- Allows an application to read or write the secure system settings. -->
+    <permission android:name="android.permission.WRITE_SECURE_SETTINGS"
+        android:permissionGroup="android.permission-group.DEVELOPMENT_TOOLS"
+        android:protectionLevel="signature|system|development"
+        android:label="@string/permlab_writeSecureSettings"
+        android:description="@string/permdesc_writeSecureSettings" />
+
+    <!-- Allows an application to retrieve state dump information from system
+         services. -->
+    <permission android:name="android.permission.DUMP"
+        android:permissionGroup="android.permission-group.DEVELOPMENT_TOOLS"
+        android:protectionLevel="signature|system|development"
+        android:label="@string/permlab_dump"
+        android:description="@string/permdesc_dump" />
+
     <!-- Configure an application for debugging. -->
     <permission android:name="android.permission.SET_DEBUG_APP"
         android:permissionGroup="android.permission-group.DEVELOPMENT_TOOLS"
@@ -1099,7 +1101,7 @@
     <permission android:name="android.permission.STATUS_BAR"
         android:label="@string/permlab_statusBar"
         android:description="@string/permdesc_statusBar"
-        android:protectionLevel="signatureOrSystem" />
+        android:protectionLevel="signature|system" />
 
     <!-- Allows an application to be the status bar.  Currently used only by SystemUI.apk
     @hide -->
@@ -1120,7 +1122,7 @@
     <permission android:name="android.permission.UPDATE_DEVICE_STATS"
         android:label="@string/permlab_batteryStats"
         android:description="@string/permdesc_batteryStats"
-        android:protectionLevel="signatureOrSystem" />
+        android:protectionLevel="signature|system" />
 
     <!-- Allows an application to open windows that are for use by parts
          of the system user interface.  Not for use by third party apps. -->
@@ -1160,7 +1162,7 @@
     <permission android:name="android.permission.SHUTDOWN"
         android:label="@string/permlab_shutdown"
         android:description="@string/permdesc_shutdown"
-        android:protectionLevel="signatureOrSystem" />
+        android:protectionLevel="signature|system" />
 
     <!-- Allows an application to tell the activity manager to temporarily
          stop application switches, putting it into a special mode that
@@ -1170,7 +1172,7 @@
     <permission android:name="android.permission.STOP_APP_SWITCHES"
         android:label="@string/permlab_stopAppSwitches"
         android:description="@string/permdesc_stopAppSwitches"
-        android:protectionLevel="signatureOrSystem" />
+        android:protectionLevel="signature|system" />
 
     <!-- Allows an application to retrieve the current state of keys and
          switches.  This is only for use by the system.-->
@@ -1205,7 +1207,7 @@
     <permission android:name="android.permission.BIND_WALLPAPER"
         android:label="@string/permlab_bindWallpaper"
         android:description="@string/permdesc_bindWallpaper"
-        android:protectionLevel="signatureOrSystem" />
+        android:protectionLevel="signature|system" />
 
     <!-- Must be required by device administration receiver, to ensure that only the
          system can interact with it. -->
@@ -1232,7 +1234,7 @@
     <permission android:name="android.permission.INSTALL_PACKAGES"
         android:label="@string/permlab_installPackages"
         android:description="@string/permdesc_installPackages"
-        android:protectionLevel="signatureOrSystem" />
+        android:protectionLevel="signature|system" />
 
     <!-- Allows an application to clear user data -->
     <permission android:name="android.permission.CLEAR_APP_USER_DATA"
@@ -1244,27 +1246,33 @@
     <permission android:name="android.permission.DELETE_CACHE_FILES"
         android:label="@string/permlab_deleteCacheFiles"
         android:description="@string/permdesc_deleteCacheFiles"
-        android:protectionLevel="signatureOrSystem" />
+        android:protectionLevel="signature|system" />
 
     <!-- Allows an application to delete packages. -->
     <permission android:name="android.permission.DELETE_PACKAGES"
         android:label="@string/permlab_deletePackages"
         android:description="@string/permdesc_deletePackages"
-        android:protectionLevel="signatureOrSystem" />
+        android:protectionLevel="signature|system" />
 
     <!-- Allows an application to move location of installed package.
          @hide -->
     <permission android:name="android.permission.MOVE_PACKAGE"
         android:label="@string/permlab_movePackage"
         android:description="@string/permdesc_movePackage"
-        android:protectionLevel="signatureOrSystem" />
+        android:protectionLevel="signature|system" />
 
     <!-- Allows an application to change whether an application component (other than its own) is
          enabled or not. -->
     <permission android:name="android.permission.CHANGE_COMPONENT_ENABLED_STATE"
         android:label="@string/permlab_changeComponentState"
         android:description="@string/permdesc_changeComponentState"
-        android:protectionLevel="signatureOrSystem" />
+        android:protectionLevel="signature|system" />
+
+    <!-- @hide Allows an application to grant or revoke specific permissions. -->
+    <permission android:name="android.permission.GRANT_REVOKE_PERMISSIONS"
+        android:label="@string/permlab_grantRevokePermissions"
+        android:description="@string/permdesc_grantRevokePermissions"
+        android:protectionLevel="signature" />
 
     <!-- Allows an application to use SurfaceFlinger's low level features -->
     <permission android:name="android.permission.ACCESS_SURFACE_FLINGER"
@@ -1277,7 +1285,7 @@
     <permission android:name="android.permission.READ_FRAME_BUFFER"
         android:label="@string/permlab_readFrameBuffer"
         android:description="@string/permdesc_readFrameBuffer"
-        android:protectionLevel="signatureOrSystem" />
+        android:protectionLevel="signature|system" />
 
     <!-- Required to be able to disable the device (very dangerous!). -->
     <permission android:name="android.permission.BRICK"
@@ -1289,7 +1297,7 @@
     <permission android:name="android.permission.REBOOT"
         android:label="@string/permlab_reboot"
         android:description="@string/permdesc_reboot"
-        android:protectionLevel="signatureOrSystem" />
+        android:protectionLevel="signature|system" />
 
    <!-- Allows low-level access to power management -->
     <permission android:name="android.permission.DEVICE_POWER"
@@ -1329,7 +1337,7 @@
     <permission android:name="android.permission.MASTER_CLEAR"
         android:label="@string/permlab_masterClear"
         android:description="@string/permdesc_masterClear"
-        android:protectionLevel="signatureOrSystem" />
+        android:protectionLevel="signature|system" />
 
     <!-- Allows an application to call any phone number, including emergency
          numbers, without going through the Dialer user interface for the user
@@ -1337,34 +1345,34 @@
     <permission android:name="android.permission.CALL_PRIVILEGED"
         android:label="@string/permlab_callPrivileged"
         android:description="@string/permdesc_callPrivileged"
-        android:protectionLevel="signatureOrSystem" />
+        android:protectionLevel="signature|system" />
 
     <!-- Allows an application to perform CDMA OTA provisioning @hide -->
     <permission android:name="android.permission.PERFORM_CDMA_PROVISIONING"
         android:label="@string/permlab_performCdmaProvisioning"
         android:description="@string/permdesc_performCdmaProvisioning"
-        android:protectionLevel="signatureOrSystem" />
+        android:protectionLevel="signature|system" />
 
     <!-- Allows enabling/disabling location update notifications from
          the radio. Not for use by normal applications. -->
     <permission android:name="android.permission.CONTROL_LOCATION_UPDATES"
         android:label="@string/permlab_locationUpdates"
         android:description="@string/permdesc_locationUpdates"
-        android:protectionLevel="signatureOrSystem" />
+        android:protectionLevel="signature|system" />
 
     <!-- Allows read/write access to the "properties" table in the checkin
          database, to change values that get uploaded. -->
     <permission android:name="android.permission.ACCESS_CHECKIN_PROPERTIES"
         android:label="@string/permlab_checkinProperties"
         android:description="@string/permdesc_checkinProperties"
-        android:protectionLevel="signatureOrSystem" />
+        android:protectionLevel="signature|system" />
 
     <!-- Allows an application to collect component usage
          statistics @hide -->
     <permission android:name="android.permission.PACKAGE_USAGE_STATS"
         android:label="@string/permlab_pkgUsageStats"
         android:description="@string/permdesc_pkgUsageStats"
-        android:protectionLevel="signatureOrSystem" />
+        android:protectionLevel="signature|system" />
 
     <!-- Allows an application to collect battery statistics -->
     <permission android:name="android.permission.BATTERY_STATS"
@@ -1377,7 +1385,7 @@
     <permission android:name="android.permission.BACKUP"
         android:label="@string/permlab_backup"
         android:description="@string/permdesc_backup"
-        android:protectionLevel="signatureOrSystem" />
+        android:protectionLevel="signature|system" />
 
     <!-- Allows a package to launch the secure full-backup confirmation UI.
          ONLY the system process may hold this permission.
@@ -1392,7 +1400,7 @@
     <permission android:name="android.permission.BIND_REMOTEVIEWS"
         android:label="@string/permlab_bindRemoteViews"
         android:description="@string/permdesc_bindRemoteViews"
-        android:protectionLevel="signatureOrSystem" />
+        android:protectionLevel="signature|system" />
 
     <!-- Allows an application to tell the AppWidget service which application
          can access AppWidget's data.  The normal user flow is that a user
@@ -1404,7 +1412,7 @@
         android:permissionGroup="android.permission-group.PERSONAL_INFO"
         android:label="@string/permlab_bindGadget"
         android:description="@string/permdesc_bindGadget"
-        android:protectionLevel="signatureOrSystem" />
+        android:protectionLevel="signature|system" />
 
     <!-- Allows applications to change the background data setting
          @hide pending API council -->
@@ -1424,7 +1432,7 @@
          besides global search. -->
     <permission android:name="android.permission.GLOBAL_SEARCH"
         android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
-        android:protectionLevel="signatureOrSystem" />
+        android:protectionLevel="signature|system" />
 
     <!-- Internal permission protecting access to the global search
          system: ensures that only the system can access the provider
@@ -1442,14 +1450,14 @@
          own apk as Ghod Intended. -->
     <permission android:name="android.permission.SET_WALLPAPER_COMPONENT"
         android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
-        android:protectionLevel="signatureOrSystem" />
+        android:protectionLevel="signature|system" />
 
     <!-- Allow an application to read and write the cache partition.
          @hide -->
     <permission android:name="android.permission.ACCESS_CACHE_FILESYSTEM"
         android:label="@string/permlab_cache_filesystem"
         android:description="@string/permdesc_cache_filesystem"
-        android:protectionLevel="signatureOrSystem" />
+        android:protectionLevel="signature|system" />
 
     <!-- Must be required by default container service so that only
          the system can bind to it and use it to copy
@@ -1465,14 +1473,14 @@
         @hide
     -->
     <permission android:name="android.permission.CRYPT_KEEPER"
-        android:protectionLevel="signatureOrSystem" />
+        android:protectionLevel="signature|system" />
 
     <!-- Allows an application to read historical network usage for
          specific networks and applications. @hide -->
     <permission android:name="android.permission.READ_NETWORK_USAGE_HISTORY"
         android:label="@string/permlab_readNetworkUsageHistory"
         android:description="@string/permdesc_readNetworkUsageHistory"
-        android:protectionLevel="signatureOrSystem" />
+        android:protectionLevel="signature|system" />
 
     <!-- Allows an application to manage network policies (such as warning and disable
          limits) and to define application-specific rules. @hide -->
@@ -1487,7 +1495,7 @@
     <permission android:name="android.permission.MODIFY_NETWORK_ACCOUNTING"
         android:label="@string/permlab_modifyNetworkAccounting"
         android:description="@string/permdesc_modifyNetworkAccounting"
-        android:protectionLevel="signatureOrSystem" />
+        android:protectionLevel="signature|system" />
 
     <!-- C2DM permission.
          @hide Used internally.
@@ -1503,7 +1511,7 @@
     <permission android:name="android.permission.PACKAGE_VERIFICATION_AGENT"
         android:label="@string/permlab_packageVerificationAgent"
         android:description="@string/permdesc_packageVerificationAgent"
-        android:protectionLevel="signatureOrSystem" />
+        android:protectionLevel="signature|system" />
 
     <!-- Must be required by package verifier receiver, to ensure that only the
          system can interact with it.
@@ -1531,6 +1539,13 @@
         android:label="@string/permlab_accessContentProvidersExternally"
         android:description="@string/permdesc_accessContentProvidersExternally"
         android:protectionLevel="signature" />
+    <!-- Allows an application to hold an UpdateLock, recommending that a headless
+         OTA reboot *not* occur while the lock is held.
+         @hide -->
+    <permission android:name="android.permission.UPDATE_LOCK"
+        android:label="@string/permlab_updateLock"
+        android:description="@string/permdesc_updateLock"
+        android:protectionLevel="signatureOrSystem" />
 
     <!-- The system process is explicitly the only one allowed to launch the
          confirmation UI for full backup/restore -->
diff --git a/core/res/res/layout/app_perms_summary.xml b/core/res/res/layout/app_perms_summary.xml
index 3f99dde..77dbc2e 100755
--- a/core/res/res/layout/app_perms_summary.xml
+++ b/core/res/res/layout/app_perms_summary.xml
@@ -32,6 +32,15 @@
         android:layout_width="wrap_content"
         android:layout_height="wrap_content" />
 
+    <!-- List view containing list of new permissions categorized by groups. -->
+    <LinearLayout
+        android:id="@+id/new_perms_list"
+        android:orientation="vertical"
+        android:layout_width="match_parent"
+        android:paddingLeft="16dip"
+        android:paddingRight="12dip"
+        android:layout_height="wrap_content" />
+
     <!-- List view containing list of dangerous permissions categorized by groups. -->
     <LinearLayout
         android:id="@+id/dangerous_perms_list"
diff --git a/core/res/res/layout/number_picker.xml b/core/res/res/layout/number_picker.xml
index 807daf2..2967696 100644
--- a/core/res/res/layout/number_picker.xml
+++ b/core/res/res/layout/number_picker.xml
@@ -25,7 +25,8 @@
         style="?android:attr/numberPickerUpButtonStyle"
         android:contentDescription="@string/number_picker_increment_button" />
 
-    <EditText android:id="@+id/numberpicker_input"
+    <view class="android.widget.NumberPicker$CustomEditText"
+        android:id="@+id/numberpicker_input"
         android:layout_width="fill_parent"
         android:layout_height="wrap_content"
         style="?android:attr/numberPickerInputTextStyle" />
diff --git a/core/res/res/layout/simple_list_item_multiple_choice.xml b/core/res/res/layout/simple_list_item_multiple_choice.xml
index 0305427..cb23dfd 100644
--- a/core/res/res/layout/simple_list_item_multiple_choice.xml
+++ b/core/res/res/layout/simple_list_item_multiple_choice.xml
@@ -17,10 +17,10 @@
 <CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@android:id/text1"
     android:layout_width="match_parent"
-    android:layout_height="?android:attr/listPreferredItemHeight"
-    android:textAppearance="?android:attr/textAppearanceListItem"
+    android:layout_height="?android:attr/listPreferredItemHeightSmall"
+    android:textAppearance="?android:attr/textAppearanceListItemSmall"
     android:gravity="center_vertical"
     android:checkMark="?android:attr/listChoiceIndicatorMultiple"
-    android:paddingLeft="8dip"
-    android:paddingRight="8dip"
+    android:paddingLeft="?android:attr/listPreferredItemPaddingLeft"
+    android:paddingRight="?android:attr/listPreferredItemPaddingRight"
 />
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index abf6676..1de0390 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -315,6 +315,8 @@
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"aktiveer of deaktiveer programkomponente"</string>
     <string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Laat die program toe om te verander of \'n komponent van ander program geaktiveer is of nie. Kwaadwillige programme kan dit dalk gebruik om belangrike tabletvermoëns te deaktiveer. Wees versigtig met hierdie toestemming, want dit kan programkomponente tot \'n onbruikbare, inkonsekwente of onstabiele toestand bring."</string>
     <string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Laat die program toe om te verander of \'n komponent van ander program geaktiveer is of nie. Kwaadwillige programme kan dit gebruik om belangrike foonvermoëns te deaktiveer. Wees versigtig met hierdie toestemming, want dit kan programkomponente tot \'n onbruikbare, inkonsekwente of onstabiele toestand bring."</string>
+    <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"toestemmings te verleen of te herroep"</string>
+    <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"Laat \'n program toe om spesifieke toestemmings te verleen of te herroep vir die betrokke program of ander programme. Skadelike programme kan dit gebruik om toegang te verkry tot kenmerke waarvoor jy nie toestemming verleen het nie."</string>
     <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"stel voorkeurprogramme"</string>
     <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Laat die program toe om jou voorkeur-programme te verander. Kwaadwillige programme kan stilweg die programme wat loop, verander, wat jou bestaande programme bedrieg om private data oor jou in te samel."</string>
     <string name="permlab_writeSettings" msgid="1365523497395143704">"verander globale stelselinstellings"</string>
@@ -1006,6 +1008,7 @@
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"Stel datum"</string>
     <string name="date_time_set" msgid="5777075614321087758">"Stel"</string>
     <string name="default_permission_group" msgid="2690160991405646128">"Verstek"</string>
+    <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"NUUT: "</font></string>
     <string name="no_permissions" msgid="7283357728219338112">"Geen toestemmings benodig nie"</string>
     <string name="perms_hide" msgid="7283915391320676226"><b>"Versteek"</b></string>
     <string name="perms_show_all" msgid="2671791163933091180"><b>"Wys alle"</b></string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index bb175e7..262a102 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -313,6 +313,8 @@
     <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>
+    <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"ፍቃዶች ስጥ ወይም ከልክል"</string>
+    <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"የተወሰነ ፍቃዶች እንዲሰጥ ወይም እንዲከለክል ለመተግበሪያ ይፈቅዳል ወይም ሌላ መተግበሪያዎች፡፡ ተንኮል አዘል መተግበሪያዎች ያልፈቀድክላቸውን ባህሪያት ላይ ለመድረስ ይሄንን ሊጠቀሙት ይችላሉ፡፡"</string>
     <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"ተመራጭ መተግበሪያዎች አዘጋጅ"</string>
     <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"ተመራጭ መተግበሪያዎችህን ለመቀየር ለመተግበሪያው ይፈቅዳሉ፡፡ ካንተ የግል ውሂብ ለመሰብሰብ ያሉትን መተግበሪያዎች በመላክ፤ በመሄድ ላይ ያሉ መተግበሪያዎችን  ተንኮል አዘል መተግበሪያዎች በዝምታ ሊለውጡ ይችላሉ፡፡"</string>
     <string name="permlab_writeSettings" msgid="1365523497395143704">"የሁሉንም ስርዓት ቅንብሮች ቀይር"</string>
@@ -1004,6 +1006,7 @@
     <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="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"አዲስ፦ "</font></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>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index a98a7d4b..abdda71 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -313,6 +313,8 @@
     <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>
+    <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"منح الأذونات أو إلغائها"</string>
+    <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"للسماح لأحد التطبيقات بمنح أذونات محددة أو إلغائها لنفسه أو لتطبيقات أخرى. قد تستخدم التطبيقات الضارة هذا للدخول إلى ميزات لم تمنحها إذنًا لدخولها."</string>
     <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"تعيين التطبيقات المفضلة"</string>
     <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"للسماح للتطبيق بتعديل التطبيقات المفضلة. يمكن أن تغيّر التطبيقات الضارة التطبيقات قيد التشغيل بشكل غير ملحوظ، وانتحال صفة التطبيقات الحالية لجمع بيانات خاصة منك."</string>
     <string name="permlab_writeSettings" msgid="1365523497395143704">"تعديل إعدادات النظام العمومية"</string>
@@ -1004,6 +1006,7 @@
     <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="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"جديد: "</font></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>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index 233d5a9..5cfa349 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -313,6 +313,8 @@
     <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>
+    <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"прадаставiць або адмяніць дазвол"</string>
+    <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"Дазваляе прыкладанню прадастаўляць або адмяняць пэўныя дазволы для гэтага або іншых прыкладанняў. Шкоднасныя прыкладаннi могуць выкарыстоўваць гэта, каб атрымаць доступ да функцый, якiя вы iм не прадаставiлi."</string>
     <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"усталяваць пажаданыя прыкладанні"</string>
     <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Дазваляе прыкладанням змяняць вашы пажаданыя прыкладанні. Шкоднасныя прыкладанні могуць непрыкметна змяняць запушчаныя прыкладанні, падмяняючы існуючыя прыкладанні, каб збiраць вашы асабістыя дадзеныя."</string>
     <string name="permlab_writeSettings" msgid="1365523497395143704">"змена глабальных параметраў сістэмы"</string>
@@ -1004,6 +1006,7 @@
     <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="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"НОВАЕ: "</font></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>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 66516b9..06a2577 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -313,6 +313,10 @@
     <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>
+    <!-- no translation found for permlab_grantRevokePermissions (4627315351093508795) -->
+    <skip />
+    <!-- no translation found for permdesc_grantRevokePermissions (4088642654085850662) -->
+    <skip />
     <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"задаване на предпочитани приложения"</string>
     <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Разрешава на приложението да променя предпочитаните ви приложения. Злонамерените приложения могат скрито да променят приложенията, които се изпълняват, като ги фалшифицират, за да се сдобият с ваши лични данни."</string>
     <string name="permlab_writeSettings" msgid="1365523497395143704">"промяна на глобалните системни настройки"</string>
@@ -1004,6 +1008,8 @@
     <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>
+    <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
+    <skip />
     <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>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index b848c2c..c66451a 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -313,6 +313,8 @@
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"activa o desactiva els components de l\'aplicació"</string>
     <string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Permet que l\'aplicació canviï si un component d\'una altra aplicació està activat o no. Les aplicacions malicioses poden utilitzar aquesta funció per desactivar funcions importants de la tauleta. Cal anar amb compte amb aquest permís, ja que és possible que els components de l\'aplicació esdevinguin inutilitzables, incoherents o inestables."</string>
     <string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Permet que l\'aplicació canviï si un component d\'una altra aplicació està activat o no. Les aplicacions malicioses poden utilitzar aquesta funció per desactivar funcions importants del telèfon. Cal anar amb compte amb aquest permís, perquè és possible que els components de l\'aplicació esdevinguin inutilitzables, incoherents o inestables."</string>
+    <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"concedeix o denega permisos"</string>
+    <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"Permet que una aplicació concedeixi o denegui permisos específics per a aquesta o per a altres aplicacions. És possible que les aplicacions malicioses ho facin servir per accedir a funcions a les quals no heu concedit accés."</string>
     <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"defineix les aplicacions preferides"</string>
     <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Permet que l\'aplicació modifiqui les aplicacions preferides. Les aplicacions malicioses poden canviar silenciosament les aplicacions que s\'executen, falsejar les aplicacions existents o recollir dades privades de l\'usuari."</string>
     <string name="permlab_writeSettings" msgid="1365523497395143704">"modificar la configuració global del sistema"</string>
@@ -1004,6 +1006,7 @@
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"Establiment de data"</string>
     <string name="date_time_set" msgid="5777075614321087758">"Defineix"</string>
     <string name="default_permission_group" msgid="2690160991405646128">"Predeterminat"</string>
+    <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"NOU: "</font></string>
     <string name="no_permissions" msgid="7283357728219338112">"No cal cap permís"</string>
     <string name="perms_hide" msgid="7283915391320676226"><b>"Amaga"</b></string>
     <string name="perms_show_all" msgid="2671791163933091180"><b>"Mostra\'ls tots"</b></string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 544395f..89ff9cff3 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -313,6 +313,8 @@
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"aktivace či deaktivace komponent aplikací"</string>
     <string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Umožňuje aplikaci změnit, zda je komponenta jiné aplikace povolena nebo ne. Škodlivé aplikace mohou toto oprávnění použít k vypnutí důležitých funkcí tabletu. Toto oprávnění je třeba používat opatrně, protože může dojít k nepoužitelnosti, nekonzistenci nebo nestabilitě komponent aplikací."</string>
     <string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Umožňuje aplikaci změnit, zda je komponenta jiné aplikace povolena nebo ne. Škodlivé aplikace mohou toto oprávnění použít k vypnutí důležitých funkcí telefonu. Toto oprávnění je třeba používat opatrně, protože může dojít k nepoužitelnosti, nekonzistenci nebo nestabilitě komponent aplikací."</string>
+    <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"udělení nebo odebrání oprávnění"</string>
+    <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"Umožňuje aplikaci udělit nebo odebrat sobě samotné nebo jiným aplikacím určitá oprávnění. Škodlivé aplikace pomocí tohoto oprávnění mohou získat přístup k funkcím, které jste jim nepovolili."</string>
     <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"nastavení upřednostňovaných aplikací"</string>
     <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Umožňuje aplikaci upravit preferované aplikace. Škodlivé aplikace mohou tajně měnit běžící aplikace a přinutit stávající aplikace, aby shromažďovaly vaše soukromé údaje."</string>
     <string name="permlab_writeSettings" msgid="1365523497395143704">"změna globálních nastavení systému"</string>
@@ -1004,6 +1006,7 @@
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"Nastavení data"</string>
     <string name="date_time_set" msgid="5777075614321087758">"Nastavit"</string>
     <string name="default_permission_group" msgid="2690160991405646128">"Výchozí"</string>
+    <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"NOVÉ: "</font></string>
     <string name="no_permissions" msgid="7283357728219338112">"Nejsou vyžadována žádná oprávnění"</string>
     <string name="perms_hide" msgid="7283915391320676226"><b>"Skrýt"</b></string>
     <string name="perms_show_all" msgid="2671791163933091180"><b>"Zobrazit vše"</b></string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index ceefe1d..114cac2 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -313,6 +313,8 @@
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"aktivere eller deaktivere appkomponenter"</string>
     <string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Tillader, at appen kan ændre, om en komponent i en anden app er aktiveret eller ej. Ondsindede apps kan bruge dette til at deaktivere vigtige tabletfunktioner. Man skal være forsigtig med denne tilladelse, da det er muligt at bringe appkomponenter ind i en ubrugelig, inkonsekvent eller ustabil tilstand."</string>
     <string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Tillader, at appen kan ændre, om en komponent i en anden app er aktiveret eller ej. Ondsindede apps kan bruge dette til at deaktivere vigtige funktioner på telefonen. Denne tilladelse skal anvendes med forsigtighed, da det kan forårsage ubrugelige eller ustabile appkomponenter."</string>
+    <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"udsted eller tilbagekald tilladelser"</string>
+    <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"Tillader, at en applikation udsteder eller tilbagekalder særlige tilladelser til den selv eller andre applikationer. Ondsindede applikationer kan bruge dette til at få adgang til funktioner uden din tilladelse."</string>
     <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"angive foretrukne apps"</string>
     <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Tillader, at appen kan ændre dine foretrukne apps. Ondsindede apps kan ubemærket ændre kørende apps derved udgive sig for at være dine eksisterende apps og på den måde indsamle private data fra dig."</string>
     <string name="permlab_writeSettings" msgid="1365523497395143704">"rediger globale systemindstillinger"</string>
@@ -364,7 +366,7 @@
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Tillader, at appen kan læse indholdet fra rammebufferen."</string>
     <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"skift dine lydindstillinger"</string>
     <string name="permdesc_modifyAudioSettings" msgid="7343951185408396919">"Tillader, at appen kan ændre globale lydindstillinger, f.eks. lydstyrke og kanalisering."</string>
-    <string name="permlab_recordAudio" msgid="3876049771427466323">"optag lyd"</string>
+    <string name="permlab_recordAudio" msgid="3876049771427466323">"optage lyd"</string>
     <string name="permdesc_recordAudio" msgid="2387462233976248635">"Tillader, at appen får adgang til stien til lydoptagelse."</string>
     <string name="permlab_camera" msgid="3616391919559751192">"tag billeder og optag video"</string>
     <string name="permdesc_camera" msgid="1507407407002492176">"Tillader, at appen kan tage billeder og optage video med kameraet. Dette tillader, at appen når som helst kan indsamle billeder, som kameraet kan se."</string>
@@ -390,7 +392,7 @@
     <string name="permdesc_asec_mount_unmount" msgid="3451360114902490929">"Tillader, at appen kan montere/demontere det interne lager."</string>
     <string name="permlab_asec_rename" msgid="7496633954080472417">"omdøbe internt lager"</string>
     <string name="permdesc_asec_rename" msgid="1794757588472127675">"Tillader, at appen kan omdøbe det interne lager."</string>
-    <string name="permlab_vibrate" msgid="7768356019980849603">"kontroller vibrator"</string>
+    <string name="permlab_vibrate" msgid="7768356019980849603">"kontrollere vibrator"</string>
     <string name="permdesc_vibrate" msgid="6284989245902300945">"Tillader, at appen kan kontrollere vibratoren."</string>
     <string name="permlab_flashlight" msgid="2155920810121984215">"kontroller lommelygte"</string>
     <string name="permdesc_flashlight" msgid="6522284794568368310">"Tillader, at appen kan kontrollere lommelygten."</string>
@@ -418,7 +420,7 @@
     <string name="permlab_readPhoneState" msgid="2326172951448691631">"læs telefontilstand og identitet"</string>
     <string name="permdesc_readPhoneState" msgid="5127767618743602782">"Tillader, at appen kan få adgang til enhedens telefonfunktioner. En app med denne tilladelse kan fastlægge telefonens telefon- og serienummer, om et opkald er aktivt, det nummer, som opkaldet er tilknyttet osv."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"afhold tabletcomputeren fra at gå i dvale"</string>
-    <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"afhold telefonen fra at gå i dvale"</string>
+    <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"afholde telefonen fra at gå i dvale"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Tillader, at appen kan forhindre tabletten i at gå i dvale."</string>
     <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Tillader, at appen kan forhindre, at telefonen går i dvale."</string>
     <string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"tænd eller sluk for tabletcomputeren"</string>
@@ -447,11 +449,11 @@
     <string name="permdesc_getAccounts" product="default" msgid="2735689364629830348">"Tillader, at appen kan hente listen over konti, der er kendt af telefonen."</string>
     <string name="permlab_authenticateAccounts" msgid="3940505577982882450">"fungerer som en kontogodkender"</string>
     <string name="permdesc_authenticateAccounts" msgid="5472124296908977260">"Tillader, at en app kan bruge kontoadministratorens kontogodkendelsesegenskaber, bl.a. oprettelse af konti samt hentning og angivelse af deres adgangskoder."</string>
-    <string name="permlab_manageAccounts" msgid="4440380488312204365">"administrer kontolisten"</string>
+    <string name="permlab_manageAccounts" msgid="4440380488312204365">"administrere kontolisten"</string>
     <string name="permdesc_manageAccounts" msgid="8698295625488292506">"Tillader, at appen kan foretage handlinger såsom at tilføje og fjerne konti og slette adgangskoden."</string>
-    <string name="permlab_useCredentials" msgid="6401886092818819856">"brug en kontos godkendelsesoplysninger"</string>
+    <string name="permlab_useCredentials" msgid="6401886092818819856">"bruge en kontos godkendelsesoplysninger"</string>
     <string name="permdesc_useCredentials" msgid="7984227147403346422">"Tillader, at appen kan anmode om godkendelsestokens."</string>
-    <string name="permlab_accessNetworkState" msgid="6865575199464405769">"vis netværkstilstand"</string>
+    <string name="permlab_accessNetworkState" msgid="6865575199464405769">"vise netværkstilstand"</string>
     <string name="permdesc_accessNetworkState" msgid="479772796952547198">"Tillader, at appen kan vise tilstanden for alle netværk."</string>
     <string name="permlab_createNetworkSockets" msgid="9121633680349549585">"fuld internetadgang"</string>
     <string name="permdesc_createNetworkSockets" msgid="5963922297444265950">"Tillader, at appen kan skabe netværkssockets."</string>
@@ -483,11 +485,11 @@
     <string name="permdesc_nfc" msgid="7120611819401789907">"Tillader, at appen kan kommunikere med NFC-tags (Near Field Communication), -kort og -læsere."</string>
     <string name="permlab_disableKeyguard" msgid="4977406164311535092">"deaktiver tastaturlås"</string>
     <string name="permdesc_disableKeyguard" msgid="6231611286892232626">"Tillader, at appen kan deaktivere tastaturlåsen og al associeret adgangskodesikkerhed. Et legitimt eksempel på dette er, at telefonen deaktiverer tastaturlåsen ved indgående telefonopkald, og aktiverer tastaturlåsen igen, når opkaldet er afsluttet."</string>
-    <string name="permlab_readSyncSettings" msgid="6201810008230503052">"læs indstillinger for synkronisering"</string>
+    <string name="permlab_readSyncSettings" msgid="6201810008230503052">"læse indstillinger for synkronisering"</string>
     <string name="permdesc_readSyncSettings" msgid="5464056785274229278">"Tillader, at appen kan læse synkroniseringsindstillingerne, f.eks. om synkronisering er aktiveret for appen Personer."</string>
-    <string name="permlab_writeSyncSettings" msgid="6297138566442486462">"skriv indstillinger for synkronisering"</string>
+    <string name="permlab_writeSyncSettings" msgid="6297138566442486462">"skrive indstillinger for synkronisering"</string>
     <string name="permdesc_writeSyncSettings" msgid="1466056564502117130">"Tillader, at appen kan ændre indstillingerne for synkronisering, f.eks. om appen Personer skal synkroniseres."</string>
-    <string name="permlab_readSyncStats" msgid="7396577451360202448">"læs synkroniseringsstatistikker"</string>
+    <string name="permlab_readSyncStats" msgid="7396577451360202448">"læse synkroniseringsstatistikker"</string>
     <string name="permdesc_readSyncStats" msgid="3801971839939951678">"Tillader, at appen kan læse synkroniseringsstatistikker, f.eks. synkroniseringshistorikken."</string>
     <string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"læs abonnerede feeds"</string>
     <string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Tillader, at appen kan hente oplysninger om de feeds, der synkroniseres."</string>
@@ -747,9 +749,9 @@
     <string name="autofill_parish" msgid="8202206105468820057">"Sogn"</string>
     <string name="autofill_area" msgid="3547409050889952423">"Område"</string>
     <string name="autofill_emirate" msgid="2893880978835698818">"Emirat"</string>
-    <string name="permlab_readHistoryBookmarks" msgid="1284843728203412135">"læs browserens oversigt og bogmærker"</string>
+    <string name="permlab_readHistoryBookmarks" msgid="1284843728203412135">"læse browserens oversigt og bogmærker"</string>
     <string name="permdesc_readHistoryBookmarks" msgid="4577476392604595921">"Tillader, at appen kan læse alle de webadresser, som Browser har besøgt, og alle bogmærker i Browser."</string>
-    <string name="permlab_writeHistoryBookmarks" msgid="9009434109836280374">"skriv browserens oversigt og bogmærker"</string>
+    <string name="permlab_writeHistoryBookmarks" msgid="9009434109836280374">"skrive i browserens oversigt og bogmærker"</string>
     <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="1757103804824209530">"Tillader, at appen kan ændre historik eller bogmærker i Browser, som er gemt på din tablet. Ondsindede apps kan bruge dette til at slette eller ændre dine browserdata."</string>
     <string name="permdesc_writeHistoryBookmarks" product="default" msgid="6693764355720719197">"Tillader, at appen kan ændre browserhistorikken eller bogmærker, der er gemt på din telefon. Ondsindede apps kan bruge dette til at slette eller ændre dine browserdata."</string>
     <string name="permlab_setAlarm" msgid="5924401328803615165">"angiv alarm i alarmprogram"</string>
@@ -1004,6 +1006,7 @@
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"Angiv dato"</string>
     <string name="date_time_set" msgid="5777075614321087758">"Angiv"</string>
     <string name="default_permission_group" msgid="2690160991405646128">"Standard"</string>
+    <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"NYHED! "</font></string>
     <string name="no_permissions" msgid="7283357728219338112">"Der kræves ingen tilladelser"</string>
     <string name="perms_hide" msgid="7283915391320676226"><b>"Skjul"</b></string>
     <string name="perms_show_all" msgid="2671791163933091180"><b>"Vis alle"</b></string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 3b3d08d..426a8c8 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -313,6 +313,8 @@
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"App-Komponenten aktivieren oder deaktivieren"</string>
     <string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Ermöglicht der App, Komponenten einer anderen App zu aktivieren oder zu deaktivieren. Schädliche Apps können so wichtige Tabletfunktionen deaktivieren. Bei der Erteilung dieser Berechtigung ist Vorsicht geboten, da die App-Komponenten unbrauchbar, inkonsistent oder instabil werden können."</string>
     <string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Ermöglicht der App, Komponenten einer anderen App zu aktivieren oder zu deaktivieren. Schädliche Apps können so wichtige Telefonfunktionen deaktivieren. Bei der Erteilung dieser Berechtigung ist Vorsicht geboten, da die App-Komponenten unbrauchbar, inkonsistent oder instabil werden können."</string>
+    <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"Berechtigungen erteilen oder entziehen"</string>
+    <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"Hiermit kann eine App sich selbst oder anderen Apps bestimmte Berechtigungen erteilen oder entziehen. Schädliche Apps können hierdurch Zugriff auf Funktionen erlangen, den Sie nicht gewährt haben."</string>
     <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"Bevorzugte Apps festlegen"</string>
     <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Ermöglicht der App, Änderungen an Ihren bevorzugten Apps vorzunehmen. Schädliche Apps können so aktive Apps ohne Ihr Wissen ändern, damit die vorhandenen Apps private Daten von Ihnen erfassen."</string>
     <string name="permlab_writeSettings" msgid="1365523497395143704">"allgemeine Systemeinstellungen ändern"</string>
@@ -1004,6 +1006,7 @@
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"Datum festlegen"</string>
     <string name="date_time_set" msgid="5777075614321087758">"Speichern"</string>
     <string name="default_permission_group" msgid="2690160991405646128">"Standard"</string>
+    <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"Neu: "</font></string>
     <string name="no_permissions" msgid="7283357728219338112">"Keine Berechtigungen erforderlich"</string>
     <string name="perms_hide" msgid="7283915391320676226"><b>"Ausblenden"</b></string>
     <string name="perms_show_all" msgid="2671791163933091180"><b>"Alle anzeigen"</b></string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index e2bc244..91da279 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -313,6 +313,8 @@
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"ενεργοποίηση ή απενεργοποίηση στοιχείων εφαρμογής"</string>
     <string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Επιτρέπει στην εφαρμογή την αλλαγή της κατάστασης ενεργοποίησης κάποιου στοιχείου. Τυχόν κακόβουλες εφαρμογές μπορούν να χρησιμοποιήσουν αυτήν τη δυνατότητα για την απενεργοποίηση σημαντικών δυνατοτήτων του tablet. Αυτή η άδεια θα πρέπει να χρησιμοποιείται προσεκτικά, καθώς είναι πιθανό να θέσει τα στοιχεία εφαρμογών σε κατάσταση αχρηστίας, μη συνοχής και αστάθειας."</string>
     <string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Επιτρέπει στην εφαρμογή την αλλαγή της κατάστασης ενεργοποίησης κάποιου στοιχείου. Τυχόν κακόβουλες εφαρμογές μπορούν να χρησιμοποιήσουν αυτήν τη δυνατότητα για την απενεργοποίηση σημαντικών δυνατοτήτων του τηλεφώνου. Αυτή η άδεια θα πρέπει να χρησιμοποιείται προσεκτικά, καθώς είναι πιθανό να θέσει τα στοιχεία εφαρμογών σε κατάσταση αχρηστίας, μη συνοχής και αστάθειας."</string>
+    <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"εκχώρηση ή ανάκληση δικαιωμάτων"</string>
+    <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"Επιτρέπει σε μια εφαρμογή να εκχωρήσει ή να ανακαλέσει ειδικά δικαιώματα για αυτήν ή για άλλες εφαρμογές. Οι κακόβουλες εφαρμογές μπορεί να το χρησιμοποιήσουν αυτό ώστε να αποκτήσουν πρόσβαση σε λειτουργίες για τις οποίες δεν τους έχει εκχωρηθεί δικαίωμα."</string>
     <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"ορισμός προτιμώμενων εφαρμογών"</string>
     <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Επιτρέπει στην εφαρμογή την τροποποίηση των εφαρμογών της προτίμησής σας. Τυχόν κακόβουλες εφαρμογές ενδέχεται να να αλλάξουν χωρίς ειδοποίηση τις εφαρμογές που εκτελούνται, \"ξεγελώντας\" τις υπάρχουσες εφαρμογές ώστε να συλλέξουν ιδιωτικά δεδομένα από εσάς."</string>
     <string name="permlab_writeSettings" msgid="1365523497395143704">"τροποποίηση καθολικών ρυθμίσεων συστήματος"</string>
@@ -1004,6 +1006,7 @@
     <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="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"ΝΕΟ: "</font></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>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index bed4de2..cfd9965 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -313,6 +313,8 @@
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"enable or disable app components"</string>
     <string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Allows the app to change whether a component of another app is enabled or not. Malicious apps may use this to disable important tablet capabilities. Care must be taken with this permission, as it is possible to get app components into an unusable, inconsistent or unstable state."</string>
     <string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Allows the app to change whether a component of another app is enabled or not. Malicious apps may use this to disable important phone capabilities. Care must be taken with this permission, as it is possible to get app components into an unusable, inconsistent or unstable state."</string>
+    <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"grant or revoke permissions"</string>
+    <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"Allows an application to grant or revoke specific permissions for it or other applications. Malicious applications may use this to access features for which you have not granted them permission."</string>
     <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"set preferred apps"</string>
     <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Allows the app to modify your preferred apps. Malicious apps may silently change the apps that are run, spoofing your existing apps to collect private data from you."</string>
     <string name="permlab_writeSettings" msgid="1365523497395143704">"modify global system settings"</string>
@@ -1004,6 +1006,7 @@
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"Set date"</string>
     <string name="date_time_set" msgid="5777075614321087758">"Set"</string>
     <string name="default_permission_group" msgid="2690160991405646128">"Default"</string>
+    <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"NEW: "</font></string>
     <string name="no_permissions" msgid="7283357728219338112">"No permission required"</string>
     <string name="perms_hide" msgid="7283915391320676226"><b>"Hide"</b></string>
     <string name="perms_show_all" msgid="2671791163933091180"><b>"Show all"</b></string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 58df147..fe292e6 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -313,6 +313,8 @@
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"activar o desactivar componentes de la aplicación"</string>
     <string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Permite que la aplicación determine si un componente de otra aplicación está habilitado o no. Las aplicaciones maliciosas pueden utilizar este permiso para desactivar funciones importantes de la tableta. Es necesario ser precavido con este permiso, ya que es posible que los componentes de la aplicación queden inservibles, incoherentes o inestables."</string>
     <string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Permite que la aplicación determine si un componente de otra aplicación está habilitado o no. Las aplicaciones maliciosas pueden utilizar este permiso para desactivar funciones importantes del dispositivo. Es necesario ser precavido con este permiso, ya que es posible que los componentes de la aplicación queden inservibles, incoherentes o inestables."</string>
+    <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"Otorgar o revocar permisos"</string>
+    <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"Permite a una aplicación otorgar permisos específicos a otras aplicaciones, autoconcedérselos o revocarlos. Las aplicaciones maliciosas pueden así acceder a funciones para las que no les otorgaste permiso."</string>
     <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"establecer aplicaciones preferidas"</string>
     <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Permite que la aplicación modifique tus aplicaciones preferidas. Las aplicaciones maliciosas pueden modificar sin aviso las aplicaciones que se ejecutan y así engañar a tus aplicaciones existentes para que recopilen tu información privada."</string>
     <string name="permlab_writeSettings" msgid="1365523497395143704">"modificar la configuración global del sistema"</string>
@@ -1004,6 +1006,7 @@
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"Configurar fecha"</string>
     <string name="date_time_set" msgid="5777075614321087758">"Establecer"</string>
     <string name="default_permission_group" msgid="2690160991405646128">"Predeterminado"</string>
+    <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"NUEVO: "</font></string>
     <string name="no_permissions" msgid="7283357728219338112">"No se requieren permisos"</string>
     <string name="perms_hide" msgid="7283915391320676226"><b>"Ocultar"</b></string>
     <string name="perms_show_all" msgid="2671791163933091180"><b>"Mostrar todos"</b></string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 9499214..d0c0cb9 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -313,6 +313,8 @@
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"habilitar o inhabilitar componentes de la aplicación"</string>
     <string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Permite que la aplicación determine si un componente de otra aplicación está habilitado o inhabilitado. Las aplicaciones malintencionadas pueden usar este permiso para inhabilitar funciones importantes del tablet. Este permiso se debe usar con precaución, ya que los componentes de las aplicaciones se pueden volver inestables, incoherentes o inservibles."</string>
     <string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Permite que la aplicación determine si un componente de otra aplicación está habilitado o inhabilitado. Las aplicaciones malintencionadas pueden usar este permiso para inhabilitar funciones importantes del teléfono. Este permiso se debe usar con precaución, ya que los componentes de las aplicaciones se pueden volver inestables, incoherentes o inservibles."</string>
+    <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"conceder o revocar permisos"</string>
+    <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"Permite que una aplicación conceda o revoque permisos específicos para sí misma o para otras aplicaciones. Las aplicaciones malintencionadas pueden aprovechar este permiso para acceder a funciones sin tu autorización."</string>
     <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"establecer aplicaciones preferidas"</string>
     <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Permite que la aplicación modifique las aplicaciones preferidas del usuario. De esta forma, las aplicaciones malintencionadas pueden cambiar sin aviso las aplicaciones que se están ejecutando y falsificarlas para obtener datos privados del usuario."</string>
     <string name="permlab_writeSettings" msgid="1365523497395143704">"modificar la configuración global del sistema"</string>
@@ -1004,6 +1006,7 @@
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"Establecer fecha"</string>
     <string name="date_time_set" msgid="5777075614321087758">"Establecer"</string>
     <string name="default_permission_group" msgid="2690160991405646128">"Predeterminado"</string>
+    <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"NUEVO:"</font></string>
     <string name="no_permissions" msgid="7283357728219338112">"No es necesario ningún permiso"</string>
     <string name="perms_hide" msgid="7283915391320676226"><b>"Ocultar"</b></string>
     <string name="perms_show_all" msgid="2671791163933091180"><b>"Mostrar todos"</b></string>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index da06538..2a4352d 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -313,6 +313,8 @@
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"Rakenduse komponentide lubamine või keelamine"</string>
     <string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Võimaldab rakendusel määrata, kas teise rakenduse komponent on lubatud või mitte. Pahatahtlikud rakendused võivad kasutada seda oluliste tahvelarvutirakenduste keelamiseks. Nende õiguste puhul peab olema ettevaatlik, kuna need võimaldavad muuta rakenduse komponente kasutuks, ebaühtlaseks või ebastabiilseks."</string>
     <string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Võimaldab rakendusel määrata, kas teise rakenduse komponent on lubatud või mitte. Pahatahtlikud rakendused võivad kasutada seda oluliste telefonirakenduste keelamiseks. Nende õiguste puhul peab olema ettevaatlik, kuna need võimaldavad muuta rakenduse komponente kasutuks, ebaühtlaseks või ebastabiilseks."</string>
+    <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"lubade andmine või tühistamine"</string>
+    <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"Võimaldab rakendusel anda või tühistada teatud lubasid endale või teistele rakendustele. Pahatahtlikud rakendused võivad kasutada seda juurdepääsu hankimiseks sellistele funktsioonidele, mille jaoks te pole luba andnud."</string>
     <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"Eelistatud rakenduste määramine"</string>
     <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Võimaldab rakendusel muuta teie eelistatud rakendusi. Pahatahtlikud rakendused võivad salaja muuta töötavaid rakendusi, pettes teie olemasolevad rakendused koguma teilt privaatseid andmeid."</string>
     <string name="permlab_writeSettings" msgid="1365523497395143704">"muuda üldisi süsteemiseadeid"</string>
@@ -1004,6 +1006,7 @@
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"Kuupäeva määramine"</string>
     <string name="date_time_set" msgid="5777075614321087758">"Määra"</string>
     <string name="default_permission_group" msgid="2690160991405646128">"Vaikimisi"</string>
+    <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"UUS: "</font></string>
     <string name="no_permissions" msgid="7283357728219338112">"Lube pole vaja"</string>
     <string name="perms_hide" msgid="7283915391320676226"><b>"Peida"</b></string>
     <string name="perms_show_all" msgid="2671791163933091180"><b>"Näita kõiki"</b></string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 9a6a293..084e16d 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -313,6 +313,10 @@
     <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>
+    <!-- no translation found for permlab_grantRevokePermissions (4627315351093508795) -->
+    <skip />
+    <!-- no translation found for permdesc_grantRevokePermissions (4088642654085850662) -->
+    <skip />
     <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"تنظیم برنامه‎های ترجیحی"</string>
     <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"به برنامه اجازه می‎دهد تا برنامه‎های ترجیحی شما را تغییر دهد. برنامه‎های مخرب می‎توانند بدون اعلان برنامه‎هایی را که اجرا می‎شوند، تغییر دهند خود را به جای برنامه‎های کنونی قلمداد کنند تا داده‎های شخصی را از شما جمع آوری کنند."</string>
     <string name="permlab_writeSettings" msgid="1365523497395143704">"اصلاح کردن تنظیمات سیستم کلی"</string>
@@ -765,7 +769,7 @@
     <string name="permlab_serialPort" msgid="546083327654631076">"دسترسی به درگاه‌های سریال"</string>
     <string name="permdesc_serialPort" msgid="2991639985224598193">"به دارنده اجازه می‌دهد با استفاده از SerialManager API به درگاه‌های سریال دسترسی داشته باشد."</string>
     <string name="permlab_accessContentProvidersExternally" msgid="5077774297943409285">"دسترسی خارجی به ارائه‌دهندگان محتوا"</string>
-    <string name="permdesc_accessContentProvidersExternally" msgid="4544346486697853685">"به دارنده اجازه می‌دهد تا از خارج برنامه به ارائه دهندگان محتوا دسترسی داشته باشد. هرگز برای برنامه‌های معمولی به آن نیازی نیست."</string>
+    <string name="permdesc_accessContentProvidersExternally" msgid="4544346486697853685">"به دارنده اجازه می‌دهد تا از خارج برنامه به ارائه‌دهندگان محتوا دسترسی داشته باشد. هرگز برای برنامه‌های معمولی به آن نیازی نیست."</string>
     <string name="save_password_message" msgid="767344687139195790">"می خواهید مرورگر این رمز ورود را به خاطر داشته باشد؟"</string>
     <string name="save_password_notnow" msgid="6389675316706699758">"اکنون خیر"</string>
     <string name="save_password_remember" msgid="6491879678996749466">"به خاطر سپردن"</string>
@@ -1004,6 +1008,8 @@
     <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>
+    <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
+    <skip />
     <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>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 2fe9b4e..ee7efc8 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -313,6 +313,8 @@
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"sovelluskomponenttien ottaminen käyttöön tai pois käytöstä"</string>
     <string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Antaa sovelluksen muuttaa, onko toisen sovelluksen komponentti käytössä vai ei. Haitalliset sovellukset voivat käyttää tätä tablet-laitteen tärkeiden ominaisuuksien poistamiseen käytöstä. Tämän luvan käyttöönotto edellyttää varovaisuutta, sillä sen avulla sovelluskomponentit on mahdollista saada epäkäytettävään, epäyhtenäiseen tai epävakaaseen tilaan."</string>
     <string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Antaa sovelluksen muuttaa sitä, onko toisen sovelluksen komponentti käytössä vai ei. Haitalliset sovellukset voivat käyttää tätä puhelimen tärkeiden ominaisuuksien poistamiseen käytöstä. Tämän luvan käyttöönotto edellyttää varovaisuutta, sillä sen avulla sovelluskomponentit on mahdollista saada epäkäytettävään, epäyhtenäiseen tai epävakaaseen tilaan."</string>
+    <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"myönnä tai kiellä käyttöluvat"</string>
+    <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"Antaa sovelluksen myöntää tai kieltää tiettyjä käyttööoikeuksia itselleen tai muille sovelluksille. Haittaohjelmat voivat käyttää tämän ominaisuuden avulla toimintoja, joiden käyttöön et ole antanut lupaa."</string>
     <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"ensisijaisten sovellusten asettaminen"</string>
     <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Antaa sovelluksen muokata ensisijaisia sovelluksia. Haitalliset sovellukset voivat muuttaa käynnistettäviä sovelluksia huomaamattomasti ja kerätä henkilökohtaisia tietoja matkimalla nykyisiä sovelluksia."</string>
     <string name="permlab_writeSettings" msgid="1365523497395143704">"muokkaa yleisiä järjestelmän asetuksia"</string>
@@ -1004,6 +1006,7 @@
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"Aseta päivämäärä"</string>
     <string name="date_time_set" msgid="5777075614321087758">"Aseta"</string>
     <string name="default_permission_group" msgid="2690160991405646128">"Oletus"</string>
+    <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"UUTTA: "</font></string>
     <string name="no_permissions" msgid="7283357728219338112">"Lupia ei tarvita"</string>
     <string name="perms_hide" msgid="7283915391320676226"><b>"Piilota"</b></string>
     <string name="perms_show_all" msgid="2671791163933091180"><b>"Näytä kaikki"</b></string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index d6e8f30..bca5701 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -313,6 +313,8 @@
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"activer ou désactiver les composants de l\'application"</string>
     <string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Permet à l\'application d\'activer ou de désactiver un composant d\'une autre application. Des applications malveillantes peuvent exploiter cette fonctionnalité pour désactiver les fonctionnalités principales de votre tablette. Cette autorisation doit être utilisée avec prudence, car elle peut rendre les composants d\'une application instables, voire inutilisables."</string>
     <string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Permet à l\'application d\'activer ou de désactiver un composant d\'une autre application. Des applications malveillantes peuvent exploiter cette fonctionnalité pour désactiver les fonctionnalités principales de votre téléphone. Cette autorisation doit être utilisée avec prudence, car elle peut rendre les composants d\'une application instables, voire inutilisables."</string>
+    <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"accorder ou révoquer des autorisations"</string>
+    <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"Permet à une application d\'accorder ou de révoquer des autorisations spécifiques pour celle-ci ou pour d\'autres applications. Des applications malveillantes peuvent exploiter cette autorisation pour accéder à des fonctionnalités auxquelles vous ne leur avez pas donné l\'accès."</string>
     <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"définir les applications préférées"</string>
     <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Permet à l\'application de modifier vos applications préférées. Des applications malveillantes peuvent exploiter cette fonctionnalité pour modifier les applications exécutées en usurpant l\'identité de vos applications existantes dans le but de recueillir des données privées."</string>
     <string name="permlab_writeSettings" msgid="1365523497395143704">"Modification des paramètres généraux du système"</string>
@@ -765,7 +767,7 @@
     <string name="permlab_serialPort" msgid="546083327654631076">"accéder aux ports série"</string>
     <string name="permdesc_serialPort" msgid="2991639985224598193">"Permet à l\'application autorisée d\'accéder aux ports série avec l\'API SerialManager."</string>
     <string name="permlab_accessContentProvidersExternally" msgid="5077774297943409285">"accès externe fournisseurs de contenu"</string>
-    <string name="permdesc_accessContentProvidersExternally" msgid="4544346486697853685">"Permettre à l\'application titulaire d\'accéder à des fournisseurs de contenu depuis l\'interface. Les applications standards ne devraient jamais avoir recours à cette autorisation."</string>
+    <string name="permdesc_accessContentProvidersExternally" msgid="4544346486697853685">"Permettre à l\'application titulaire d\'accéder à des fournisseurs de contenu depuis la commande shell. Les applications standards ne devraient jamais avoir recours à cette autorisation."</string>
     <string name="save_password_message" msgid="767344687139195790">"Voulez-vous que le navigateur se souvienne de ce mot de passe ?"</string>
     <string name="save_password_notnow" msgid="6389675316706699758">"Pas maintenant"</string>
     <string name="save_password_remember" msgid="6491879678996749466">"Mémoriser"</string>
@@ -1004,6 +1006,7 @@
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"Définir la date"</string>
     <string name="date_time_set" msgid="5777075614321087758">"Définir"</string>
     <string name="default_permission_group" msgid="2690160991405646128">"Par défaut"</string>
+    <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"NOUVEAU"</font>" :"</string>
     <string name="no_permissions" msgid="7283357728219338112">"Aucune autorisation requise"</string>
     <string name="perms_hide" msgid="7283915391320676226"><b>"Masquer"</b></string>
     <string name="perms_show_all" msgid="2671791163933091180"><b>"Tout afficher"</b></string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index f5a3cb7..1454253 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -313,6 +313,8 @@
     <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>
+    <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"अनुमति दें या रद्द करें"</string>
+    <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"एप्लिकेशन को उसके या अन्य एप्लिकेशन के लिए विशेष अनुमतियां देने या रद्द करने देता है. दुर्भावनापूर्ण एप्लिकेशन इसका उपयोग उन विशेषताओं तक पहुंचने के लिए कर सकते हैं जो आपने उन्हें नहीं दी हैं."</string>
     <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"पसंदीदा एप्‍लिकेशन सेट करें"</string>
     <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"एप्लिकेशन को आपके पसंदीदा एप्लिकेशन को संशोधित करने देता है. दुर्भावनापूर्ण एप्लिकेशन आपसे निजी डेटा एकत्रित करने के लिए आपके मौजूदा एप्लिकेशन को स्पूफ़ करके, चलाए जाने वाले एप्लिकेशन को चुपचाप बदल सकते हैं."</string>
     <string name="permlab_writeSettings" msgid="1365523497395143704">"वैश्विक सिस्‍टम सेटिंग संशोधित करें"</string>
@@ -1004,6 +1006,7 @@
     <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="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"नया: "</font></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>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 01378666..1908840 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -313,6 +313,8 @@
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"omogućavanje ili onemogućavanje komponenti aplikacije"</string>
     <string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Omogućuje aplikaciji da promijeni hoće li komponenta neke druge aplikacije biti omogućena ili neće. Zlonamjerne aplikacije mogu to upotrijebiti da bi onemogućile važne mogućnosti tabletnog računala. Treba biti oprezan s tom dozvolom jer je moguće dovesti komponente aplikacija u neupotrebljivo, nedosljedno ili nestabilno stanje."</string>
     <string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Omogućuje aplikaciji da promijeni hoće li komponenta neke druge aplikacije biti omogućena. Zlonamjerne aplikacije mogu to upotrijebiti da bi onemogućile važne mogućnosti telefona. Treba biti oprezan s tom dozvolom jer je moguće dovesti komponente aplikacija u neupotrebljivo, nedosljedno ili nestabilno stanje."</string>
+    <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"dati ili oduzeti dopuštenja"</string>
+    <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"Aplikaciji omogućuje da odobri ili odbije određena dopuštenja za sebe ili druge aplikacije. Zlonamjerne aplikacije to mogu upotrijebiti za pristup značajkama za koje im niste odobrili pristup."</string>
     <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"postavljanje željenih aplikacija"</string>
     <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Omogućuje aplikaciji promjenu vaših željenih aplikacija. Zlonamjerne aplikacije mogu potajno promijeniti aplikacije koje su pokrenute, zavaravajući vaše postojeće aplikacije kako bi prikupljale privatne podatke od vas."</string>
     <string name="permlab_writeSettings" msgid="1365523497395143704">"izmjena postavki globalnog sustava"</string>
@@ -1004,6 +1006,7 @@
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"Postavi datum"</string>
     <string name="date_time_set" msgid="5777075614321087758">"Postavi"</string>
     <string name="default_permission_group" msgid="2690160991405646128">"Zadano"</string>
+    <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"NOVO: "</font></string>
     <string name="no_permissions" msgid="7283357728219338112">"Nije potrebno dopuštenje"</string>
     <string name="perms_hide" msgid="7283915391320676226"><b>"Sakrij"</b></string>
     <string name="perms_show_all" msgid="2671791163933091180"><b>"Pokaži sve"</b></string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 54e8b06..81f697b 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -313,6 +313,8 @@
     <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 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_grantRevokePermissions" msgid="4627315351093508795">"engedélyek megadása vagy visszavonása"</string>
+    <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"Lehetővé teszi, hogy egy alkalmazás engedélyeket adjon vagy vonjon vissza saját maga vagy más alkalmazás számára. A rosszindulatú alkalmazások olyan funkciókhoz való hozzáféréshez használhatják ezt, amelyeket nem engedélyezett számukra."</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>
@@ -1004,6 +1006,7 @@
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"Dátum beállítása"</string>
     <string name="date_time_set" msgid="5777075614321087758">"Beállítás"</string>
     <string name="default_permission_group" msgid="2690160991405646128">"Alapértelmezett"</string>
+    <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"ÚJ: "</font></string>
     <string name="no_permissions" msgid="7283357728219338112">"Nincs szükség engedélyre"</string>
     <string name="perms_hide" msgid="7283915391320676226"><b>"Elrejtés"</b></string>
     <string name="perms_show_all" msgid="2671791163933091180"><b>"Az összes megjelenítése"</b></string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index ac5d463..08b0f60 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -313,6 +313,8 @@
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"mengaktifkan atau menonaktifkan komponen apl"</string>
     <string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Mengizinkan apl mengubah apakah komponen apl lain diaktifkan atau tidak. Apl berbahaya dapat menggunakan ini untuk menonaktifkan kemampuan tablet yang penting. Izin ini harus digunakan dengan hati-hati karena dapat menjadikan komponen apl tidak dapat digunakan, tidak konsisten, atau tidak stabil."</string>
     <string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Mengizinkan apl mengubah apakah komponen apl lain diaktifkan atau tidak. Apl berbahaya dapat menggunakan izin ini untuk menonaktifkan kemampuan ponsel yang penting. Izin ini harus digunakan dengan hati-hati, karena mungkin saja menjadikan komponen apl tidak dapat digunakan, tidak konsisten, atau tidak stabil."</string>
+    <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"memberi atau mencabut izin"</string>
+    <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"Memungkinkan aplikasi memberikan atau mencabut izin khusus untuk aplikasi tersebut atau aplikasi lainnya. Aplikasi berbahaya dapat menggunakannya untuk mengakses fitur yang tidak Anda beri izin."</string>
     <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"menyetel apl yang disukai"</string>
     <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Mengizinkan apl memodifikasi apl pilihan Anda. Apl berbahaya dapat diam-diam mengubah apl yang berjalan, menipu apl yang ada untuk mengumpulkan data pribadi dari Anda."</string>
     <string name="permlab_writeSettings" msgid="1365523497395143704">"ubah setelan sistem global"</string>
@@ -1004,6 +1006,7 @@
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"Setel tanggal"</string>
     <string name="date_time_set" msgid="5777075614321087758">"Setel"</string>
     <string name="default_permission_group" msgid="2690160991405646128">"Bawaan"</string>
+    <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"BARU: "</font></string>
     <string name="no_permissions" msgid="7283357728219338112">"Tidak perlu izin"</string>
     <string name="perms_hide" msgid="7283915391320676226"><b>"Sembunyikan"</b></string>
     <string name="perms_show_all" msgid="2671791163933091180"><b>"Tampilkan semua"</b></string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 77733b3..21855eb6 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -313,6 +313,8 @@
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"attivazione/disattivazione componenti applicazioni"</string>
     <string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Consente all\'applicazione di cambiare lo stato di attivazione o disattivazione del componente di un\'altra applicazione. Le applicazioni dannose potrebbero farne uso per disattivare importanti funzionalità del tablet. È necessario prestare attenzione con questa autorizzazione perché è possibile rendere inutilizzabili, incoerenti o instabili i componenti delle applicazioni."</string>
     <string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Consente all\'applicazione di cambiare lo stato di attivazione o disattivazione del componente di un\'altra applicazione. Le applicazioni dannose potrebbero farne uso per disattivare importanti funzionalità del telefono. È necessario prestare attenzione con questa autorizzazione perché è possibile rendere inutilizzabili, incoerenti o instabili i componenti delle applicazioni."</string>
+    <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"concessione o revoca di autorizzazioni"</string>
+    <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"Consente a un\'applicazione di concedere o revocare autorizzazioni specifiche per essa o per altre applicazioni. Le applicazioni dannose potrebbero utilizzare questa autorizzazione per accedere a funzioni che non hai concesso loro."</string>
     <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"impostazione applicazioni preferite"</string>
     <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Consente all\'applicazione di modificare le tue applicazioni preferite. Le applicazioni dannose potrebbero cambiare di nascosto le applicazioni che vengono eseguite, facendo in modo che le applicazioni esistenti raccolgano dati riservati su di te."</string>
     <string name="permlab_writeSettings" msgid="1365523497395143704">"modifica impostazioni di sistema globali"</string>
@@ -1004,6 +1006,7 @@
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"Imposta data"</string>
     <string name="date_time_set" msgid="5777075614321087758">"Imposta"</string>
     <string name="default_permission_group" msgid="2690160991405646128">"Predefinito"</string>
+    <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"NUOVA: "</font></string>
     <string name="no_permissions" msgid="7283357728219338112">"Nessuna autorizzazione richiesta"</string>
     <string name="perms_hide" msgid="7283915391320676226"><b>"Nascondi"</b></string>
     <string name="perms_show_all" msgid="2671791163933091180"><b>"Mostra tutto"</b></string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index a232c69..b009ea1 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -313,6 +313,8 @@
     <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>
+    <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"הענק או בטל הרשאות"</string>
+    <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"מאפשר ליישום להעניק או לבטל הרשאות ספציפיות ביחס לעצמו או ליישומים אחרים. יישומים זדוניים עלולים להשתמש באפשרות זו על מנת לקבל גישה לתכונות שלא אישרת להם."</string>
     <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"הגדרת יישומים מועדפים"</string>
     <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"מאפשר ליישום לשנות את היישומים המועדפים עליך. יישומים זדוניים עלולים לשנות בחשאי את היישומים שמופעלים, תוך שידול במרמה של היישומים הקיימים שלך לאסוף ממך נתונים פרטיים."</string>
     <string name="permlab_writeSettings" msgid="1365523497395143704">"שנה את הגדרות המערכת הכלליות"</string>
@@ -1004,6 +1006,7 @@
     <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="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"חדש: "</font></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>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 66e847a..9898734 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -313,6 +313,8 @@
     <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>
+    <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"権限の許可または取り消し"</string>
+    <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"このアプリケーションや他のアプリケーションに対して特定の権限を許可したり取り消したりすることをアプリケーションに許可します。悪意のあるアプリケーションがユーザーの許可なく複数の機能にアクセスする恐れがあります。"</string>
     <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"優先アプリの設定"</string>
     <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"優先アプリを変更することをアプリに許可します。この許可を悪意のあるアプリに利用されると、実行中のアプリが密かに変更され、既存のアプリへのなりすましにより非公開データがだまし取られる恐れがあります。"</string>
     <string name="permlab_writeSettings" msgid="1365523497395143704">"システムの全般設定の変更"</string>
@@ -1004,6 +1006,7 @@
     <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="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"NEW: "</font></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>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 754f791..5eea0ba 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -313,6 +313,8 @@
     <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>
+    <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"권한 승인 또는 취소"</string>
+    <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"애플리케이션이 해당 애플리케이션 및 기타 애플리케이션에 대한 특정 권한을 승인 또는 취소하도록 허용합니다. 이 경우 악성 애플리케이션이 승인되지 않은 기능에 액세스할 수 있습니다."</string>
     <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"기본 앱 설정"</string>
     <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"앱이 기본 앱을 수정할 수 있도록 허용합니다. 이 경우 악성 앱이 실행되는 앱을 몰래 변경하고 기존 앱으로 위장하여 사용자의 개인 정보를 수집할 수 있습니다."</string>
     <string name="permlab_writeSettings" msgid="1365523497395143704">"전체 시스템 설정 수정"</string>
@@ -1004,6 +1006,7 @@
     <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="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"신규: "</font></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>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 43aa1d3..7ea172f 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -313,6 +313,8 @@
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"įgalinti programos komponentus arba jų neleisti"</string>
     <string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Leidžiama programai pakeisti, ar įgalintas kitos programos komponentas, ar ne. Kenkėjiškos programos gali tai naudoti, kad neleistų svarbių planšetinio kompiuterio funkcijų. Šį leidimą reikia naudoti atsargiai, nes programos komponentai gali tapti nenaudojami, nenuoseklūs ar nestabilūs."</string>
     <string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Leidžiama programai pakeisti nustatymą, ar įgalintas kitos programos komponentas, ar ne. Kenkėjiškos programos gali tai naudoti, kad neleistų svarbių telefono funkcijų. Šį leidimą reikia naudoti atsargiai, nes programos komponentai gali tapti nenaudojami, nenuoseklūs ar nestabilūs."</string>
+    <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"suteikti arba panaikinti leidimus"</string>
+    <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"Programai leidžiama suteikti arba panaikinti konkrečius savo arba kitų programų leidimus. Tuo pasinaudoję kenkėjiškos programos gali pasiekti funkcijas, kurių pasiekti joms neleidote."</string>
     <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"nustatyti pageidaujamas programas"</string>
     <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Leidžiama programai keisti jūsų pageidaujamas programas. Kenkėjiškos programos gali nepastebimai pakeisti vykdomas programas, klastodama esamas programas, kad rinktų jūsų privačius duomenis."</string>
     <string name="permlab_writeSettings" msgid="1365523497395143704">"keisti visuotinius sistemos nustatymus"</string>
@@ -1004,6 +1006,7 @@
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"Nustatyti datą"</string>
     <string name="date_time_set" msgid="5777075614321087758">"Nustatyti"</string>
     <string name="default_permission_group" msgid="2690160991405646128">"Numatytasis"</string>
+    <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"NAUJAS: "</font></string>
     <string name="no_permissions" msgid="7283357728219338112">"Nereikia leidimų"</string>
     <string name="perms_hide" msgid="7283915391320676226"><b>"Slėpti"</b></string>
     <string name="perms_show_all" msgid="2671791163933091180"><b>"Rodyti viską"</b></string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 5f84a48..1581341 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -313,6 +313,8 @@
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"iespējot vai atspējot lietotnes komponentus"</string>
     <string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Ļauj lietotnei mainīt to, vai tiek iespējots citas lietotnes komponents. Ļaunprātīgas lietotnes to var izmantot, lai atspējotu svarīgas planšetdatora iespējas. Izmantojiet šo atļauju uzmanīgi, jo pastāv iespēja, ka lietotnes komponenti var kļūt neizmantojami, neatbilstīgi vai nestabili."</string>
     <string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Ļauj lietotnei mainīt to, vai tiek iespējots citas lietotnes komponents. Ļaunprātīgas lietotnes to var izmantot, lai atspējotu svarīgas tālruņa iespējas. Izmantojiet šo atļauju uzmanīgi, jo pastāv iespēja, ka lietotnes komponenti var kļūt neizmantojami, neatbilstīgi vai nestabili."</string>
+    <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"atļauju piešķiršana vai atsaukšana"</string>
+    <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"Ļauj lietojumprogrammai piešķirt sev vai citām lietojumprogrammām noteiktas atļaujas un atsaukt tās. Ļaunprātīgas lietojumprogrammas var izmantot šo iespēju, lai piekļūtu funkcijām, kuras neesat atļāvis."</string>
     <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"iestatīt vēlamās lietotnes"</string>
     <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Ļauj lietotnei modificēt jūsu vēlamās lietotnes. Ļaunprātīgas lietotnes var nemanāmi mainīt izmantotās lietotnes, atveidojot esošās lietotnes, lai no jums iegūtu privātus datus."</string>
     <string name="permlab_writeSettings" msgid="1365523497395143704">"pārveidot globālos sistēmas iestatījumus"</string>
@@ -1004,6 +1006,7 @@
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"Datuma iestatīšana"</string>
     <string name="date_time_set" msgid="5777075614321087758">"Iestatīt"</string>
     <string name="default_permission_group" msgid="2690160991405646128">"Noklusējums"</string>
+    <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"JAUNA: "</font></string>
     <string name="no_permissions" msgid="7283357728219338112">"Atļaujas nav nepieciešamas."</string>
     <string name="perms_hide" msgid="7283915391320676226"><b>"Slēpt"</b></string>
     <string name="perms_show_all" msgid="2671791163933091180"><b>"Rādīt visu"</b></string>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index 3f240ab..d3c4885 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -313,6 +313,10 @@
     <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>
+    <!-- no translation found for permlab_grantRevokePermissions (4627315351093508795) -->
+    <skip />
+    <!-- no translation found for permdesc_grantRevokePermissions (4088642654085850662) -->
+    <skip />
     <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>
@@ -1004,6 +1008,8 @@
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"Tetapkan tarikh"</string>
     <string name="date_time_set" msgid="5777075614321087758">"Tetapkan"</string>
     <string name="default_permission_group" msgid="2690160991405646128">"Lalai"</string>
+    <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
+    <skip />
     <string name="no_permissions" msgid="7283357728219338112">"Tiada kebenaran diperlukan"</string>
     <string name="perms_hide" msgid="7283915391320676226"><b>"Sembunyikan"</b></string>
     <string name="perms_show_all" msgid="2671791163933091180"><b>"Tunjukkan semua"</b></string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 63df5f4..ee58558 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -313,6 +313,8 @@
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"aktivere eller deaktivere appkomponenter"</string>
     <string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Lar appen endre hvorvidt en komponent i en annen app er aktivert eller ikke. Ondsinnede apper kan bruke dette til å deaktivere viktige nettbrettfunksjoner. Denne tillatelsen må brukes med forsiktighet, ettersom det er mulig å få appkomponenter inn i en ubrukelig, inkonsistent eller ustabil tilstand."</string>
     <string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Lar appen endre hvorvidt en komponent i en annen app er aktivert eller ikke. Ondsinnede apper kan bruke dette til å deaktivere viktige telefonfunksjoner. Denne tillatelsen må brukes med forsiktighet, ettersom det er mulig å få appkomponenter inn i en ubrukelig, inkonsistent eller ustabil tilstand."</string>
+    <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"gi eller trekke tilbake tillatelser"</string>
+    <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"Lar et program gi eller trekke tilbake spesielle tillatelser for eget bruk eller for andre programmer. Skadelige programmer kan bruke dette for å få tilgang til funksjoner de ikke skal ha tilgang til."</string>
     <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"angi foretrukne apper"</string>
     <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Lar appen endre de foretrukne appene dine. Ondsinnede apper kan ubemerket endre apper som kjøres, og forfalske eksisterende apper til å samle private data fra deg."</string>
     <string name="permlab_writeSettings" msgid="1365523497395143704">"endre globale systeminnstillinger"</string>
@@ -1004,6 +1006,7 @@
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"Angi dato"</string>
     <string name="date_time_set" msgid="5777075614321087758">"Lagre"</string>
     <string name="default_permission_group" msgid="2690160991405646128">"Standard"</string>
+    <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"NY: "</font></string>
     <string name="no_permissions" msgid="7283357728219338112">"Trenger ingen rettigheter"</string>
     <string name="perms_hide" msgid="7283915391320676226"><b>"Skjul"</b></string>
     <string name="perms_show_all" msgid="2671791163933091180"><b>"Vis alle"</b></string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 8e5e8bc..584a7d16 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -313,6 +313,8 @@
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"componenten van apps in- of uitschakelen"</string>
     <string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Hiermee kan de app wijzigen of een component van een andere app wel of niet is ingeschakeld. Schadelijke apps kunnen dit gebruiken om belangrijke tabletfuncties uit te schakelen. U moet voorzichtig omgaan met deze rechten, aangezien het mogelijk is dat onderdelen van apps onbruikbaar, inconsistent of instabiel worden."</string>
     <string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Hiermee kan de app wijzigen of een component van een andere app wel of niet is ingeschakeld. Schadelijke apps kunnen dit gebruiken om belangrijke telefoonfuncties uit te schakelen. U moet voorzichtig omgaan met deze rechten, aangezien het mogelijk is dat onderdelen van apps onbruikbaar, inconsistent of instabiel worden."</string>
+    <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"rechten verlenen of intrekken"</string>
+    <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"Toestaan dat een app specifieke rechten aan zichzelf of andere apps verleent of intrekt. Schadelijke apps kunnen dit gebruiken om toegang te krijgen tot functies waartoe u de apps geen toegang heeft gegeven."</string>
     <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"voorkeursapps instellen"</string>
     <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Hiermee kan de app uw voorkeursapps aanpassen. Schadelijke apps kunnen de apps die worden uitgevoerd zonder uw medeweten wijzigen om uw bestaande apps te imiteren en privégegevens van u te verzamelen."</string>
     <string name="permlab_writeSettings" msgid="1365523497395143704">"algemene systeeminstellingen wijzigen"</string>
@@ -1004,6 +1006,7 @@
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"Datum instellen"</string>
     <string name="date_time_set" msgid="5777075614321087758">"Instellen"</string>
     <string name="default_permission_group" msgid="2690160991405646128">"Standaard"</string>
+    <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"NIEUW: "</font></string>
     <string name="no_permissions" msgid="7283357728219338112">"Geen machtigingen vereist"</string>
     <string name="perms_hide" msgid="7283915391320676226"><b>"Verbergen"</b></string>
     <string name="perms_show_all" msgid="2671791163933091180"><b>"Alles weergeven"</b></string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index c17da8f..4d0e0fa 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -313,6 +313,8 @@
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"włączanie lub wyłączanie składników aplikacji"</string>
     <string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Pozwala aplikacji na włączenie lub wyłączenie składnika innej aplikacji. Złośliwe aplikacje mogą wykorzystać to uprawnienie do wyłączenia ważnych funkcji tabletu. W przypadku tego uprawnienia należy zachować ostrożność, ponieważ istnieje możliwość wprowadzenia składników aplikacji w stan nieużywalności, niespójności lub niestabilności."</string>
     <string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Pozwala aplikacji na włączenie lub wyłączenie składnika innej aplikacji. Złośliwe aplikacje mogą wykorzystać to uprawnienie do wyłączenia ważnych funkcji telefonu. W przypadku tego uprawnienia należy zachować ostrożność, ponieważ istnieje możliwość wprowadzenia składników aplikacji w stan nieużywalności, niespójności lub niestabilności."</string>
+    <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"przyznaj lub cofnij uprawnienia"</string>
+    <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"Pozwala aplikacji na przyznanie lub cofnięcie określonych uprawnień do niej lub do innych aplikacji. Złośliwe aplikacje mogą to wykorzystać, by uzyskać dostęp do nieprzyznanych im funkcji."</string>
     <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"ustawianie preferowanych aplikacji"</string>
     <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Pozwala aplikacji na zmianę Twoich preferowanych aplikacji. Złośliwe aplikacje mogą dyskretnie zmienić uruchamiane aplikacje, podszywając się pod dotychczasowe aplikacje w celu zebrania od Ciebie prywatnych danych."</string>
     <string name="permlab_writeSettings" msgid="1365523497395143704">"modyfikowanie ogólnych ustawień systemu"</string>
@@ -1004,6 +1006,7 @@
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"Ustaw datę"</string>
     <string name="date_time_set" msgid="5777075614321087758">"Ustaw"</string>
     <string name="default_permission_group" msgid="2690160991405646128">"Domyślne"</string>
+    <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"NOWE: "</font></string>
     <string name="no_permissions" msgid="7283357728219338112">"Nie są wymagane żadne uprawnienia"</string>
     <string name="perms_hide" msgid="7283915391320676226"><b>"Ukryj"</b></string>
     <string name="perms_show_all" msgid="2671791163933091180"><b>"Pokaż wszystko"</b></string>
@@ -1234,7 +1237,7 @@
     <string name="sha1_fingerprint" msgid="7930330235269404581">"Odcisk cyfrowy SHA-1:"</string>
     <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"Zobacz wszystkie"</string>
     <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"Wybierz działanie"</string>
-    <string name="share_action_provider_share_with" msgid="5247684435979149216">"Udostępnij"</string>
+    <string name="share_action_provider_share_with" msgid="5247684435979149216">"Udostępnij przez"</string>
     <string name="status_bar_device_locked" msgid="3092703448690669768">"Urządzenie zablokowane."</string>
     <string name="list_delimeter" msgid="3975117572185494152">", "</string>
     <string name="sending" msgid="3245653681008218030">"Wysyłanie..."</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 74870ff..9f1e053 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -313,6 +313,8 @@
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"ativar ou desativar componentes da aplicação"</string>
     <string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Permite que a aplicação mude a opção de ativar ou não um componente de outra aplicação. As aplicações maliciosas podem utilizar isto para desativar funcionalidades importantes do tablet. É necessário ter cuidado com esta autorização, uma vez que é possível colocar alguns componentes de aplicações num estado inutilizável, inconsistente ou instável."</string>
     <string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Permite que a aplicação mude a opção de ativar ou não um componente de outra aplicação. As aplicações maliciosas podem utilizar isto para desativar funcionalidades importantes do telemóvel. É necessário ter cuidado com esta autorização, uma vez que é possível colocar alguns componentes de aplicações num estado inutilizável, inconsistente ou instável."</string>
+    <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"conceder ou revogar permissões"</string>
+    <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"Permite que uma aplicação conceda ou revogue permissões específicas para si própria ou para outras aplicações. As aplicações maliciosas podem utilizar isto para aceder a funcionalidades para as quais não têm permissão."</string>
     <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"definir aplicações preferidas"</string>
     <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Permite ao aplicativo modificar as suas aplicações preferidas. As aplicações maliciosas podem alterar sem aviso as aplicações que são executadas, espiando as aplicações existentes para recolher os seus dados privados."</string>
     <string name="permlab_writeSettings" msgid="1365523497395143704">"modificar definições globais do sistema"</string>
@@ -1004,6 +1006,7 @@
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"Definir data"</string>
     <string name="date_time_set" msgid="5777075614321087758">"Definir"</string>
     <string name="default_permission_group" msgid="2690160991405646128">"Predefinido"</string>
+    <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"NOVA: "</font></string>
     <string name="no_permissions" msgid="7283357728219338112">"Não são necessárias permissões"</string>
     <string name="perms_hide" msgid="7283915391320676226"><b>"Ocultar"</b></string>
     <string name="perms_show_all" msgid="2671791163933091180"><b>"Mostrar tudo"</b></string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index efe6833..4826ddf 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -313,6 +313,8 @@
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"ativar ou desativar os componentes do aplicativo"</string>
     <string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Permite que o aplicativo ative ou desative um componente de outro aplicativo. Aplicativos maliciosos podem usar esse recurso para desativar recursos importantes do tablet. Tenha cuidado com essa permissão, pois é possível fazer com que os componentes do aplicativo fiquem inutilizáveis, inconsistentes ou instáveis."</string>
     <string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Permite que o aplicativo altere se um componente de outro aplicativo está ativado ou não. Aplicativos maliciosos podem usar esse recurso para desativar recursos importantes do telefone. Deve-se tomar cuidado com essa permissão, uma vez que isso pode deixar os componentes do aplicativo inutilizáveis, inconsistentes ou instáveis."</string>
+    <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"conceder ou revogar permissões"</string>
+    <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"Permite que um aplicativo conceda ou revogue permissões específicas para ele ou outros aplicativos. Aplicativos maliciosos podem usar isso para acessar recursos aos quais você não concedeu permissão."</string>
     <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"definir aplicativos preferidos"</string>
     <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Permite que o aplicativo modifique seus aplicativos preferidos. Aplicativos maliciosos podem alterar os aplicativos que são executados, falsificando seus aplicativos existentes para coletar seus dados particulares."</string>
     <string name="permlab_writeSettings" msgid="1365523497395143704">"modificar configurações globais do sistema"</string>
@@ -1004,6 +1006,7 @@
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"Definir data"</string>
     <string name="date_time_set" msgid="5777075614321087758">"Definir"</string>
     <string name="default_permission_group" msgid="2690160991405646128">"Padrão"</string>
+    <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"NOVO: "</font></string>
     <string name="no_permissions" msgid="7283357728219338112">"Nenhuma permissão necessária"</string>
     <string name="perms_hide" msgid="7283915391320676226"><b>"Ocultar"</b></string>
     <string name="perms_show_all" msgid="2671791163933091180"><b>"Mostrar todas"</b></string>
diff --git a/core/res/res/values-rm/strings.xml b/core/res/res/values-rm/strings.xml
index 5b8efa6..c7579de 100644
--- a/core/res/res/values-rm/strings.xml
+++ b/core/res/res/values-rm/strings.xml
@@ -451,6 +451,10 @@
     <skip />
     <!-- no translation found for permdesc_changeComponentState (1827232484416505615) -->
     <skip />
+    <!-- no translation found for permlab_grantRevokePermissions (4627315351093508795) -->
+    <skip />
+    <!-- no translation found for permdesc_grantRevokePermissions (4088642654085850662) -->
+    <skip />
     <!-- no translation found for permlab_setPreferredApplications (8463181628695396391) -->
     <skip />
     <!-- no translation found for permdesc_setPreferredApplications (4973986762241783712) -->
@@ -1474,6 +1478,8 @@
     <skip />
     <string name="date_time_set" msgid="5777075614321087758">"Definir"</string>
     <string name="default_permission_group" msgid="2690160991405646128">"Standard"</string>
+    <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
+    <skip />
     <string name="no_permissions" msgid="7283357728219338112">"Naginas permissiuns obligatoricas"</string>
     <string name="perms_hide" msgid="7283915391320676226"><b>"Zuppentar"</b></string>
     <string name="perms_show_all" msgid="2671791163933091180"><b>"Mussar tut"</b></string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 8ffa16e..0890cc0 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -313,6 +313,10 @@
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"activare sau dezactivare a componentelor aplicaţiei"</string>
     <string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Permite aplicaţiei să modifice starea activată sau dezactivată a unei componente a altei aplicaţii. Aplicaţiile rău intenţionate pot să utilizeze această permisiune pentru a dezactiva funcţii importante ale tabletei. Este necesar să utilizaţi cu atenţie această permisiune, deoarece este posibil să aduceţi componentele aplicaţiei într-o stare inutilizabilă, inconsecventă sau instabilă."</string>
     <string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Permite aplicaţiei să modifice starea activată sau dezactivată a unei componente a altei aplicaţii. Aplicaţiile rău intenţionate pot să utilizeze această permisiune pentru a dezactiva funcţii importante ale telefonului. Este necesar să utilizaţi cu atenţie această permisiune, deoarece este posibil să aduceţi componentele aplicaţiei într-o stare inutilizabilă, inconsecventă sau instabilă."</string>
+    <!-- no translation found for permlab_grantRevokePermissions (4627315351093508795) -->
+    <skip />
+    <!-- no translation found for permdesc_grantRevokePermissions (4088642654085850662) -->
+    <skip />
     <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"setare aplicaţii preferate"</string>
     <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Permite aplicaţiei să modifice aplicaţiile dvs. preferate. Aplicaţiile rău intenţionate pot să modifice fără a vă înştiinţa aplicaţiile care rulează, păcălind aplicaţiile existente să colecteze date private de la dvs."</string>
     <string name="permlab_writeSettings" msgid="1365523497395143704">"modificare setări sistem globale"</string>
@@ -1004,6 +1008,8 @@
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"Setaţi data"</string>
     <string name="date_time_set" msgid="5777075614321087758">"Setaţi"</string>
     <string name="default_permission_group" msgid="2690160991405646128">"Prestabilit"</string>
+    <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
+    <skip />
     <string name="no_permissions" msgid="7283357728219338112">"Nu se solicită nicio permisiune"</string>
     <string name="perms_hide" msgid="7283915391320676226"><b>"Ascundeţi"</b></string>
     <string name="perms_show_all" msgid="2671791163933091180"><b>"Afişaţi-le pe toate"</b></string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index a6644e5..662a54e 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -313,6 +313,8 @@
     <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>
+    <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"предоставление и отзыв разрешений"</string>
+    <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"Позволяет приложению предоставлять и отзывать разрешения самому себе и другим программам. Вредоносные приложения могут использовать эту функцию для получения прав, которых вы им не предоставляли."</string>
     <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"настройка предпочтительных приложений"</string>
     <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Приложение сможет изменять предпочтительные приложения. Вредоносные программы смогут незаметно изменять запускаемые вами программы и собирать ваши личные данные от имени существующих приложений."</string>
     <string name="permlab_writeSettings" msgid="1365523497395143704">"изменять общие настройки системы"</string>
@@ -1004,6 +1006,7 @@
     <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="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"НОВОЕ: "</font></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>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index df25ac7..98b829f 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -313,6 +313,8 @@
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"povoliť alebo zakázať súčasti aplikácie"</string>
     <string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Umožňuje aplikácii zmeniť to, či je súčasť inej aplikácie povolená alebo zakázaná. Škodlivé aplikácie môžu pomocou tohto nastavenia zakázať dôležité funkcie tabletu. S týmto povolením musíte zaobchádzať opatrne, pretože súčasti aplikácie môžete dostať do nepoužiteľného, nekonzistentného alebo nestabilného stavu."</string>
     <string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Umožňuje aplikácii zmeniť to, či je súčasť inej aplikácie povolená alebo zakázaná. Škodlivé aplikácie môžu pomocou tohto nastavenia zakázať dôležité funkcie telefónu. S týmto povolením musíte zaobchádzať opatrne, pretože súčasti aplikácie môžete dostať do nepoužiteľného, nekonzistentného alebo nestabilného stavu."</string>
+    <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"povoliť alebo zakázať povolenia"</string>
+    <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"Umožňuje aplikácii povoliť alebo zakázať konkrétne povolenia pre seba alebo iné aplikácie. Škodlivé aplikácie môžu použiť túto možnosť na pristupovanie k funkciám, ktoré ste im nepovolili."</string>
     <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"nastaviť preferované aplikácie"</string>
     <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Umožňuje aplikácii zmeniť vaše preferované aplikácie. Škodlivé aplikácie môžu v tichosti zmeniť spustené aplikácie a oklamať existujúce aplikácie, aby zhromažďovali vaše súkromné údaje."</string>
     <string name="permlab_writeSettings" msgid="1365523497395143704">"zmeny globálnych nastavení systému"</string>
@@ -1006,6 +1008,7 @@
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"Nastaviť dátum"</string>
     <string name="date_time_set" msgid="5777075614321087758">"Nastaviť"</string>
     <string name="default_permission_group" msgid="2690160991405646128">"Predvolené"</string>
+    <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"NOVINKA: "</font></string>
     <string name="no_permissions" msgid="7283357728219338112">"Nevyžadujú sa žiadne oprávnenia."</string>
     <string name="perms_hide" msgid="7283915391320676226"><b>"Skryť"</b></string>
     <string name="perms_show_all" msgid="2671791163933091180"><b>"Zobraziť všetky"</b></string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 159d504..9d99013 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -313,6 +313,8 @@
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"omogočanje ali onemogočanje komponent programa"</string>
     <string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Programu omogoča, da spremeni, ali je komponenta drugega programa omogočena ali ne. Zlonamerni programi lahko to uporabijo za onemogočanje pomembnih zmožnosti tabličnega računalnika. Pri dodeljevanju dovoljenja je treba biti previden, saj lahko komponente programa nastavite tako, da jih ni mogoče uporabiti, da niso dosledne ali da niso stabilne."</string>
     <string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Programu omogoča, da spremeni, ali je komponenta drugega programa omogočena ali ne. Zlonamerni programi lahko to uporabijo za onemogočanje pomembnih zmožnosti telefona. Pri dodeljevanju dovoljenja je treba biti previden, saj lahko komponente programa nastavite tako, da jih ni mogoče uporabiti, da niso dosledne ali da niso stabilne."</string>
+    <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"dodeljevanje ali preklic dovoljenj"</string>
+    <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"Programu omogoča dodeljevanje ali preklic posebnih dovoljenj zanj ali za druge programe. Zlonamerni programi lahko to uporabijo za dostop do funkcij, za katere jim niste dodelili pravic."</string>
     <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"nastavitev prednostnih programov"</string>
     <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Programu omogoča spreminjanje priljubljenih programov. Zlonamerni programi lahko s tem neopazno spremenijo programe, ki se izvajajo, tako da se izdajajo za obstoječe programe in zbirajo osebne podatke."</string>
     <string name="permlab_writeSettings" msgid="1365523497395143704">"spreminjanje splošnih nastavitev sistema"</string>
@@ -1004,6 +1006,7 @@
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"Nastavi datum"</string>
     <string name="date_time_set" msgid="5777075614321087758">"Nastavi"</string>
     <string name="default_permission_group" msgid="2690160991405646128">"Privzeto"</string>
+    <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"NOVO: "</font></string>
     <string name="no_permissions" msgid="7283357728219338112">"Ni zahtevanih dovoljenj"</string>
     <string name="perms_hide" msgid="7283915391320676226"><b>"Skrij"</b></string>
     <string name="perms_show_all" msgid="2671791163933091180"><b>"Pokaži vse"</b></string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 199d318..a9e7b9b 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -313,6 +313,8 @@
     <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>
+    <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"додела или опозив дозвола"</string>
+    <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"Омогућава апликацији да додели или опозове посебне дозволе за њу или друге апликације. Злонамерне апликације могу то да користе да би приступале функцијама које им нисте одобрили."</string>
     <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"подешавање жељених апликација"</string>
     <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Дозвољава апликацији да мења омиљене апликације. Злонамерне апликације могу без обавештења да промене апликације које су покренуте и да преко њих прикупљају ваше приватне податке."</string>
     <string name="permlab_writeSettings" msgid="1365523497395143704">"измена глобалних подешавања система"</string>
@@ -1004,6 +1006,7 @@
     <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="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"НОВО: "</font></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>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index be397b0..f780ca4 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -313,6 +313,10 @@
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"aktivera eller inaktivera appkomponenter"</string>
     <string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Tillåter att appen ändrar inställningen för om en komponent i en annan app ska aktiveras eller inte. Skadliga appar kan använda detta för att inaktivera viktiga funktioner i pekdatorn. Var försiktig med behörigheten, eftersom appkomponenter kan bli oanvändbara, inkonsekventa eller instabila."</string>
     <string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Tillåter att appen ändrar inställningen för om en komponent i en annan app ska aktiveras eller inte. Skadliga appar kan använda detta för att inaktivera viktiga funktioner i pekdatorn. Var försiktig med behörigheten, eftersom programkomponenter kan bli oanvändbara, inkonsekventa eller instabila."</string>
+    <!-- no translation found for permlab_grantRevokePermissions (4627315351093508795) -->
+    <skip />
+    <!-- no translation found for permdesc_grantRevokePermissions (4088642654085850662) -->
+    <skip />
     <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"ange önskade appar"</string>
     <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Tillåter att appen ändrar dina önskade appar. Skadliga appar kan utan förvarning ändra de appar som körs och kapa dina befintliga appar så att de börjar samla privata uppgifter från dig."</string>
     <string name="permlab_writeSettings" msgid="1365523497395143704">"ändra globala systeminställningar"</string>
@@ -1004,6 +1008,8 @@
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"Ange datum"</string>
     <string name="date_time_set" msgid="5777075614321087758">"Ställ in"</string>
     <string name="default_permission_group" msgid="2690160991405646128">"Standardinställning"</string>
+    <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
+    <skip />
     <string name="no_permissions" msgid="7283357728219338112">"Inga behörigheter krävs"</string>
     <string name="perms_hide" msgid="7283915391320676226"><b>"Dölj"</b></string>
     <string name="perms_show_all" msgid="2671791163933091180"><b>"Visa alla"</b></string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 4cb3a3a..c9e4692 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -313,6 +313,10 @@
     <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 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>
+    <!-- no translation found for permlab_grantRevokePermissions (4627315351093508795) -->
+    <skip />
+    <!-- no translation found for permdesc_grantRevokePermissions (4088642654085850662) -->
+    <skip />
     <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"kuweka programu zinazopendelewa"</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>
@@ -1004,6 +1008,8 @@
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"Weka tarehe"</string>
     <string name="date_time_set" msgid="5777075614321087758">"Weka"</string>
     <string name="default_permission_group" msgid="2690160991405646128">"Chaguo-msingi"</string>
+    <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
+    <skip />
     <string name="no_permissions" msgid="7283357728219338112">"Hakuna vibali vinavyohitajika"</string>
     <string name="perms_hide" msgid="7283915391320676226"><b>"Ficha"</b></string>
     <string name="perms_show_all" msgid="2671791163933091180"><b>"Onyesha zote"</b></string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 41c56f4..a787a2a 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -313,6 +313,8 @@
     <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>
+    <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"อนุญาตหรือยกเลิกการอนุญาต"</string>
+    <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"อนุญาตให้แอปพลิเคชันให้หรือยกเลิกการอนุญาตบางอย่างของตัวเองหรือแอปพลิเคชันอื่น แอปพลิเคชันที่เป็นอันตรายอาจใช้การทำงานนี้ในการเข้าถึงคุณลักษณะที่คุณไม่อนุญาต"</string>
     <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"ตั้งค่าแอปพลิเคชันที่ต้องการ"</string>
     <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"อนุญาตให้แอปพลิเคชันแก้ไขแอปพลิเคชันต่างๆ ที่คุณชอบใช้ แอปพลิเคชันที่เป็นอันตรายอาจจะแอบเปลี่ยนแอปพลิเคชันที่กำลังทำงาน ปลอมแปลงเป็นแอปพลิเคชันที่มีอยู่ของคุณเพื่อรวบรวมข้อมูลส่วนบุคคลจากคุณ"</string>
     <string name="permlab_writeSettings" msgid="1365523497395143704">"แก้ไขการตั้งค่าระบบสากล"</string>
@@ -1004,6 +1006,7 @@
     <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="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"ใหม่: "</font></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>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 9548fe9..99731af 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -313,6 +313,8 @@
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"paganahin o huwag paganahin ang mga bahagi ng app"</string>
     <string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Pinapayagan ang app na baguhin kung ang bahagi ng isa pang app ay pinagana o hindi. Maaari itong gamitin ng nakakahamak na apps upang huwag paganahin ang mahahalagang kakayahan ng tablet. Dapat na mayroong pag-iingat sa pahintulot na ito, dahil posibleng mailagay ng mga bahagi ng app sa isang hindi nagagamit, pabagu-bago, o hindi matatag na katayuan."</string>
     <string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Pinapayagan ang app na baguhin kung ang isang bahagi ng isa pang app ay pinapagana o hindi. Maaari itong gamitin ng nakakahamak na apps upang huwag paganahin ang mga mahalagang kakayahan ng telepono. Dapat na mayroong pag-iingat sa pahintulot na ito, dahil posibleng mailagay ang mga bahagi ng app sa isang hindi nagagamit, pabagu-bago, o hindi matatag na katayuan."</string>
+    <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"ibigay o bawiin ang mga pahintulot"</string>
+    <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"Binibigyang-daan ang isang application na ibigay o bawiin ang mga tukoy na pahintulot para dito o sa iba pang mga application. Maaari itong gamitin ng mga nakakapahamak na application upang i-access ang mga tampok na hindi mo ibinigay sa mga ito."</string>
     <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"itakda ang gustong apps"</string>
     <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Pinapayagan ang app na baguhin ang iyong gustong apps. Maaaring tahimik na baguhin ng nakakahamak na apps ang apps na tumatakbo, na dinadaya ang iyong umiiral nang apps upang mangolekta ng pribadong data mula sa iyo."</string>
     <string name="permlab_writeSettings" msgid="1365523497395143704">"baguhin ang mga setting ng global system"</string>
@@ -1004,6 +1006,7 @@
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"Itakda ang petsa"</string>
     <string name="date_time_set" msgid="5777075614321087758">"Itakda"</string>
     <string name="default_permission_group" msgid="2690160991405646128">"Default"</string>
+    <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"BAGO: "</font></string>
     <string name="no_permissions" msgid="7283357728219338112">"Walang mga kinakailangang pahintulot"</string>
     <string name="perms_hide" msgid="7283915391320676226"><b>"Itago"</b></string>
     <string name="perms_show_all" msgid="2671791163933091180"><b>"Ipakita lahat"</b></string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 6da7fcd..730c69f 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -313,6 +313,10 @@
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"uygulama bileşenlerini etkinleştir veya devre dışı bırak"</string>
     <string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Uygulamaya, başka bir uygulamanın bir bileşeninin etkin veya devre dışı olma durumunu değiştirme izni verir. Kötü amaçlı uygulamalar tabletin önemli özelliklerini devre dışı bırakmak için bunu kullanabilir. Uygulama bileşenlerini kullanılamaz, tutarsız ya da kararsız hale getirebileceğinden bu izin ayarlanırken dikkat edilmelidir."</string>
     <string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Uygulamaya, başka bir uygulamanın bir bileşeninin etkin veya devre dışı olma durumunu değiştirme izni verir. Kötü amaçlı uygulamalar telefonun önemli özelliklerini devre dışı bırakmak için bunu kullanabilir. Uygulama bileşenlerini kullanılamaz, tutarsız ya da kararsız getirebileceğinden bu izin ayarlanırken dikkat edilmelidir."</string>
+    <!-- no translation found for permlab_grantRevokePermissions (4627315351093508795) -->
+    <skip />
+    <!-- no translation found for permdesc_grantRevokePermissions (4088642654085850662) -->
+    <skip />
     <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"tercih edilen uygulamaları ayarla"</string>
     <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Uygulamaya, tercih edilen uygulamalarınızı değiştirme izni verir. Kötü amaçlı uygulamalar çalışmakta olan uygulamaları sessizce değiştirip gizli verilerinizi toplamak için mevcut uygulamalarınızı yanlış yönlendirebilir."</string>
     <string name="permlab_writeSettings" msgid="1365523497395143704">"genel sistem ayarlarını değiştir"</string>
@@ -1004,6 +1008,8 @@
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"Tarihi ayarla"</string>
     <string name="date_time_set" msgid="5777075614321087758">"Ayarla"</string>
     <string name="default_permission_group" msgid="2690160991405646128">"Varsayılan"</string>
+    <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
+    <skip />
     <string name="no_permissions" msgid="7283357728219338112">"İzin gerektirmez"</string>
     <string name="perms_hide" msgid="7283915391320676226"><b>"Gizle"</b></string>
     <string name="perms_show_all" msgid="2671791163933091180"><b>"Tümünü göster"</b></string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 3fd6264..4d3c8537 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -313,6 +313,8 @@
     <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>
+    <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"надавати або скасовувати дозволи"</string>
+    <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"Дозволяє програмі надавати або скасовувати певні дозволи для себе чи інших програм. Шкідливі програми можуть використовувати це для доступу до функцій, якого ви їм не надавали."</string>
     <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"установлювати потрібні програми"</string>
     <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Дозволяє програмі змінювати ваші вибрані програми. Шкідливі програми можуть непомітно змінювати запущені програми, примушуючи існуючі програми оманливим шляхом збирати ваші особисті дані."</string>
     <string name="permlab_writeSettings" msgid="1365523497395143704">"змін. загальні налашт-ня сист."</string>
@@ -1004,6 +1006,7 @@
     <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="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"НОВИЙ: "</font></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>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 8503dc5..c9b200d 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -313,6 +313,8 @@
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"bật hoặc tắt cấu phần ứng dụng"</string>
     <string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Cho phép ứng dụng thay đổi việc có bật cấu phần của ứng dụng khác hay không. Ứng dụng độc hại có thể sử dụng quyền này để vô hiệu hóa những tính năng quan trọng của máy tính bảng. Phải cẩn trọng khi sử dụng quyền này vì quyền này có thể khiến các cấu phần rơi vào trạng thái không sử dụng được, không đồng nhất hoặc không ổn định."</string>
     <string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Cho phép ứng dụng thay đổi việc có bật cấu phần của một ứng dụng khác hay không. Ứng dụng độc hại có thể sử dụng quyền này để tắt những tính năng quan trọng của điện thoại. Phải sử dụng quyền này thận trọng vì có thể khiến các cấu phần của ứng dụng rơi vào trạng thái không thể sử dụng được, không đồng nhất hoặc không ổn định."</string>
+    <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"cấp hoặc thu hồi quyền"</string>
+    <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"Cho phép ứng dụng cấp hoặc thu hồi quyền cụ thể đối với ứng dụng đó hoặc các ứng dụng khác. Các ứng dụng độc hại có thể lợi dụng điều này để truy cập các tính năng mà bạn không cấp."</string>
     <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"đặt ứng dụng ưa thích"</string>
     <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Cho phép ứng dụng sửa đổi ứng dụng ưa thích của bạn. Ứng dụng độc hại có thể ngầm thay đổi các ứng dụng đã được chạy, giả mạo các ứng dụng hiện có để thu thập dữ liệu cá nhân của bạn."</string>
     <string name="permlab_writeSettings" msgid="1365523497395143704">"sửa đổi cài đặt hệ thống chung"</string>
@@ -1004,6 +1006,7 @@
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"Đặt ngày"</string>
     <string name="date_time_set" msgid="5777075614321087758">"Đặt"</string>
     <string name="default_permission_group" msgid="2690160991405646128">"Mặc định"</string>
+    <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"MỚI: "</font></string>
     <string name="no_permissions" msgid="7283357728219338112">"Không yêu cầu quyền"</string>
     <string name="perms_hide" msgid="7283915391320676226"><b>"Ẩn"</b></string>
     <string name="perms_show_all" msgid="2671791163933091180"><b>"Hiển thị tất cả"</b></string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index bc74518..c2d59e9 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -313,6 +313,10 @@
     <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>
+    <!-- no translation found for permlab_grantRevokePermissions (4627315351093508795) -->
+    <skip />
+    <!-- no translation found for permdesc_grantRevokePermissions (4088642654085850662) -->
+    <skip />
     <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"设置首选应用程序"</string>
     <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"允许应用程序修改您的首选应用程序。恶意应用程序可能会在后台更改运行的应用程序,欺骗您现有的应用程序,以收集您的私人数据。"</string>
     <string name="permlab_writeSettings" msgid="1365523497395143704">"修改全局系统设置"</string>
@@ -765,7 +769,7 @@
     <string name="permlab_serialPort" msgid="546083327654631076">"访问串行端口"</string>
     <string name="permdesc_serialPort" msgid="2991639985224598193">"允许持有人使用 SerialManager API 访问串行端口。"</string>
     <string name="permlab_accessContentProvidersExternally" msgid="5077774297943409285">"从外部访问内容提供程序"</string>
-    <string name="permdesc_accessContentProvidersExternally" msgid="4544346486697853685">"允许持有者通过界面访问内容提供程序。普通应用程序绝不需要此权限。"</string>
+    <string name="permdesc_accessContentProvidersExternally" msgid="4544346486697853685">"允许持有者通过界面访问内容提供程序。普通应用绝不需要此权限。"</string>
     <string name="save_password_message" msgid="767344687139195790">"是否希望浏览器记住此密码?"</string>
     <string name="save_password_notnow" msgid="6389675316706699758">"暂不保存"</string>
     <string name="save_password_remember" msgid="6491879678996749466">"记住"</string>
@@ -1004,6 +1008,8 @@
     <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>
+    <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
+    <skip />
     <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>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 5c89004..18d0836 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -313,6 +313,10 @@
     <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>
+    <!-- no translation found for permlab_grantRevokePermissions (4627315351093508795) -->
+    <skip />
+    <!-- no translation found for permdesc_grantRevokePermissions (4088642654085850662) -->
+    <skip />
     <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"設定偏好的應用程式"</string>
     <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"允許應用程式修改您偏好的應用程式。請注意,惡意應用程式可能利用此功能擅自竄改執行的應用程式,並冒充現有的程式收集您的私人資料。"</string>
     <string name="permlab_writeSettings" msgid="1365523497395143704">"編輯全域系統設定"</string>
@@ -1004,6 +1008,8 @@
     <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>
+    <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
+    <skip />
     <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>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index 282fb91..6d61260 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -70,11 +70,11 @@
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"Isevisi ayilungiselelwe."</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="RestrictedOnData" msgid="8653794784690065540">"Isevisi yedatha ivaliwe."</string>
+    <string name="RestrictedOnEmergency" msgid="6581163779072833665">"Isevisi ephuthumayo ivimbelwe."</string>
+    <string name="RestrictedOnNormal" msgid="4953867011389750673">"Isevisi yezwi ivimbelwe."</string>
     <string name="RestrictedOnAllVoice" msgid="3396963652108151260">"Wonke amasevisi Wezwi avimbelwe."</string>
-    <string name="RestrictedOnSms" msgid="8314352327461638897">"Insizakalo ye-SMS ivaliwe."</string>
+    <string name="RestrictedOnSms" msgid="8314352327461638897">"Isevisi ye-SMS ivaliwe."</string>
     <string name="RestrictedOnVoiceData" msgid="996636487106171320">"Amasevisi Wezwi/Idatha avimbelwe."</string>
     <string name="RestrictedOnVoiceSms" msgid="1888588152792023873">"Amasevisi Wezwi/SMS avimbelwe."</string>
     <string name="RestrictedOnAll" msgid="5643028264466092821">"Wonke amasevisi Wezwi/Idatha/SMS avimbelwe."</string>
@@ -276,7 +276,7 @@
     <string name="permdesc_bindVpnService" msgid="2067845564581693905">"Ivumela umnini ukuthi abophele kwissekelo esingaphezulu sesevisi ye-Vpm. Ayidingakeli izinsiza ezejwayelekile."</string>
     <string name="permlab_bindWallpaper" msgid="8716400279937856462">"hlanganisa kwiphephadonga"</string>
     <string name="permdesc_bindWallpaper" msgid="7108428692595491668">"Ivumela umbambi ukuhlanganisa uxhumano nomsebenzisi kwezinga eliphezulu lwephephadonga. Akusoze kwadingeka kwezinhlelo zokusebenza ezivamile."</string>
-    <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"bophezela kube insizakalo yesinqunjana"</string>
+    <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"bophezela kube isevisi yesinqunjana"</string>
     <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Ivumela umbambi ukuhlanganisa uxhumano nomsebenzisi kwezinga eliphezulu lensizakalo yesinqunjwana. Akusoze kwadingeka kwezinhlelo zokusebenza ezivamile."</string>
     <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"xhumana nomphathi wedivaysi"</string>
     <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"Ivumela ummeli ukuthumela okuqukethwe kumphathi wedivaysi. Akusoze kwadingeka kwizinhlelo zokusebenza ezivamile."</string>
@@ -313,6 +313,8 @@
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"vumela noma vimbela izingxenye zensiza"</string>
     <string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Ivumela ukuthi insiza iguqule ukuthi okuqukethwe kwenye insiza kuyasebenza noma cha. Izinsiza ezinobungozi zingasebenzisa lokhu ukwenza ukuthi izinto ezisemqoka ekhompyutheni yepeni zingasebenzi. Kufanele kuqashelwe uma kukhishwa lemvume njengoba kungenzeka kwenze izinto zensiza zibe sesimweni esingazinzile, nesiguquguqukayo."</string>
     <string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Ivumela ukuthi insiza iguqule ukuthi okuqukethwe kwenye insiza kuyasebenza noma cha. Izinsiza ezinobungozi zingasebenzisa lokhu ukwenza ukuthi izinto ezisemqoka ocingweni zingasebenzi. Kufanele kuqashelwe uma kukhishwa lemvume njengoba kungenzeka kwenze izinto zensiza zibe sesmweni esingazinzile, nesiguquguqukayo."</string>
+    <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"nika noma buyisa izimvume"</string>
+    <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"Ivumela izinhlelo zokusebenza ukunika noma ukubuyisa izimvume ezithile zayo noma ezinye izinhlelo lokusebenza. Izinhlelo zokusebenza ezingalungile zingasebenzisa lokhu ukufinyelela izici ongazinikanga zona."</string>
     <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"setha izinsiza ezincamelwayo"</string>
     <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Ivuela insiza ukuthi iguqule izinsiza ezincanyelwayo. Izinsiza ezinobungozi zingashintsha izinsiz buthule ezisebenzyo okwenza ukuthi izinsiza zakho ezikhona zingasebenzi ukuthola ze zithole imininingwane yakho eyimfihlo."</string>
     <string name="permlab_writeSettings" msgid="1365523497395143704">"guqula izilungiselelo zohlelo jikelele"</string>
@@ -1004,6 +1006,7 @@
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"Setha idethi"</string>
     <string name="date_time_set" msgid="5777075614321087758">"Hlela"</string>
     <string name="default_permission_group" msgid="2690160991405646128">"Okuzenzakalelayo"</string>
+    <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ffffa3a3">"Okusha: "</font></string>
     <string name="no_permissions" msgid="7283357728219338112">"Ayikho imvume edingekayo"</string>
     <string name="perms_hide" msgid="7283915391320676226"><b>"Fihla "</b></string>
     <string name="perms_show_all" msgid="2671791163933091180"><b>"Bonisa konke"</b></string>
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 92c59ab..4aa7dde 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -157,7 +157,7 @@
              of permission to a requesting application at installation, without
              asking for the user's explicit approval (though the user always
              has the option to review these permissions before installing). -->
-        <enum name="normal" value="0" />
+        <flag name="normal" value="0" />
         <!-- A higher-risk permission that would give a requesting application
              access to private user data or control over the device that can
              negatively impact the user.  Because this type of permission
@@ -167,13 +167,13 @@
              user and require confirmation before proceeding, or some other
              approach may be taken to avoid the user automatically allowing
              the use of such facilities.  -->
-        <enum name="dangerous" value="1" />
+        <flag name="dangerous" value="1" />
         <!-- A permission that the system is to grant only if the requesting
              application is signed with the same certificate as the application
              that declared the permission. If the certificates match, the system
              automatically grants the permission without notifying the user or
              asking for the user's explicit approval. -->
-        <enum name="signature" value="2" />
+        <flag name="signature" value="2" />
         <!-- A permission that the system is to grant only to packages in the
              Android system image <em>or</em> that are signed with the same
              certificates. Please avoid using this option, as the
@@ -183,7 +183,20 @@
              vendors have applications built in to a system image which need
              to share specific features explicitly because they are being built
              together. -->
-        <enum name="signatureOrSystem" value="3" />
+        <flag name="signatureOrSystem" value="3" />
+        <!-- Additional flag from base permission type: this permission can also
+             be granted to any applications installed on the system image.
+             Please avoid using this option, as the
+             signature protection level should be sufficient for most needs and
+             works regardless of exactly where applications are installed.  This
+             permission flag is used for certain special situations where multiple
+             vendors have applications built in to a system image which need
+             to share specific features explicitly because they are being built
+             together. -->
+        <flag name="system" value="0x10" />
+        <!-- Additional flag from base permission type: this permission can also
+             (optionally) be granted to development applications. -->
+        <flag name="development" value="0x20" />
     </attr>
     
     <!-- Specified the name of a group that this permission is associated
@@ -924,6 +937,13 @@
         tag; often this is one of the {@link android.Manifest.permission standard
         system permissions}. -->
         <attr name="name" />
+        <!--  Specify whether this permission is required for the application.
+              The default is true, meaning the application requires the
+              permission, and it must always be granted when it is installed.
+              If you set this to false, then in some cases the application may
+              be installed with it being granted the permission, and it will
+              need to request the permission later if it needs it. -->
+        <attr name="required" format="boolean" />
     </declare-styleable>
 
     <!-- The <code>uses-configuration</code> tag specifies
@@ -966,7 +986,7 @@
               don't support it.  If you set this to false, then this will
               not impose a restriction on where the application can be
               installed. -->
-        <attr name="required" format="boolean" />
+        <attr name="required" />
     </declare-styleable>
 
     <!-- The <code>uses-sdk</code> tag describes the SDK features that the
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 1eab01a..806406d 100755
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -505,6 +505,7 @@
             0 - Nothing
             1 - Recent apps dialog
             2 - Recent apps view in SystemUI
+            3 - Voice search
          This needs to match the constants in
          policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
     -->
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 0950bdb..94a671d 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -115,6 +115,7 @@
   <java-symbol type="id" name="new_app_action" />
   <java-symbol type="id" name="new_app_description" />
   <java-symbol type="id" name="new_app_icon" />
+  <java-symbol type="id" name="new_perms_list" />
   <java-symbol type="id" name="no_permissions" />
   <java-symbol type="id" name="non_dangerous_perms_list" />
   <java-symbol type="id" name="numberpicker_input" />
@@ -629,6 +630,7 @@
   <java-symbol type="string" name="orgTypeWork" />
   <java-symbol type="string" name="passwordIncorrect" />
   <java-symbol type="string" name="permissions_format" />
+  <java-symbol type="string" name="perms_new_perm_prefix" />
   <java-symbol type="string" name="perms_hide" />
   <java-symbol type="string" name="perms_show_all" />
   <java-symbol type="string" name="petabyteShort" />
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 3c1f50d..c8df649 100755
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -861,6 +861,14 @@
         possible to get app components into an unusable, inconsistent, or unstable state.
     </string>
 
+    <!-- Title of an application permission for granting or revoking other permissions [CHAR LIMIT=NONE] -->
+    <string name="permlab_grantRevokePermissions">grant or revoke permissions</string>
+    <!-- Description of an application permission for granting or revoking other permissions [CHAR LIMIT=NONE] -->
+    <string name="permdesc_grantRevokePermissions">Allows an application to grant or revoke
+        specific permissions for it or other applications.  Malicious applications may use this
+        to access features you have not granted them.
+    </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_setPreferredApplications">set preferred apps</string>
     <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
@@ -2255,6 +2263,10 @@
          content providers from outside an ApplicationThread. [CHAR LIMIT=NONE] -->
     <string name="permdesc_accessContentProvidersExternally">Allows the holder to access content
      providers from the shell. Should never be needed for normal apps.</string>
+    <!-- Title of an application permission which allows the application to suggest that now is a bad time to reboot the device in order to apply an OTA.  [CHAR LIMIT=40] -->
+    <string name="permlab_updateLock">discourage automatic device updates</string>
+    <!-- Description of an application permission which allows the application to suggest that now is a bad time to reboot the device in order to apply an OTA.  [CHAR LIMIT=NONE] -->
+    <string name="permdesc_updateLock">Allows the holder to offer information to the system about when would be a good time for a noninteractive reboot to upgrade the device.</string>
 
     <!-- If the user enters a password in a form on a website, a dialog will come up asking if they want to save the password. Text in the save password dialog, asking if the browser should remember a password. -->
     <string name="save_password_message">Do you want the browser to remember this password?</string>
@@ -2775,6 +2787,8 @@
     <string name="default_permission_group">Default</string>
     <!-- Do not translate. -->
     <string name="permissions_format"><xliff:g id="perm_line1">%1$s</xliff:g>, <xliff:g id="perm_line2">%2$s</xliff:g></string>
+    <!-- Text that is placed at the front of a permission name that is being added to an app [CHAR LIMIT=NONE] -->
+    <string name="perms_new_perm_prefix"><font size="12" fgcolor="#ffffa3a3">NEW: </font></string>
     <!-- Shown for an application when it doesn't require any permission grants. -->
     <string name="no_permissions">No permissions required</string>
     <!-- When installing an application, the less-dangerous permissions are hidden.  If the user showed those, this is the text to hide them again.  -->
diff --git a/core/tests/coretests/src/android/util/LocaleUtilTest.java b/core/tests/coretests/src/android/util/LocaleUtilTest.java
index ff3d539..0ca6043 100644
--- a/core/tests/coretests/src/android/util/LocaleUtilTest.java
+++ b/core/tests/coretests/src/android/util/LocaleUtilTest.java
@@ -22,7 +22,8 @@
 import dalvik.annotation.TestLevel;
 import dalvik.annotation.TestTargetNew;
 
-import static android.util.LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE;
+import static android.view.View.LAYOUT_DIRECTION_LTR;
+import static android.view.View.LAYOUT_DIRECTION_RTL;
 
 public class LocaleUtilTest extends AndroidTestCase {
 
@@ -32,168 +33,168 @@
         args = {Locale.class}
     )
     public void testGetLayoutDirectionFromLocale() {
-        assertEquals(TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
+        assertEquals(LAYOUT_DIRECTION_LTR,
                 LocaleUtil.getLayoutDirectionFromLocale(null));
 
-        assertEquals(TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
+        assertEquals(LAYOUT_DIRECTION_LTR,
             LocaleUtil.getLayoutDirectionFromLocale(Locale.ENGLISH));
-        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
+        assertEquals(LAYOUT_DIRECTION_LTR,
             LocaleUtil.getLayoutDirectionFromLocale(Locale.CANADA));
-        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
+        assertEquals(LAYOUT_DIRECTION_LTR,
             LocaleUtil.getLayoutDirectionFromLocale(Locale.CANADA_FRENCH));
-        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
+        assertEquals(LAYOUT_DIRECTION_LTR,
             LocaleUtil.getLayoutDirectionFromLocale(Locale.FRANCE));
-        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
+        assertEquals(LAYOUT_DIRECTION_LTR,
             LocaleUtil.getLayoutDirectionFromLocale(Locale.FRENCH));
-        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
+        assertEquals(LAYOUT_DIRECTION_LTR,
             LocaleUtil.getLayoutDirectionFromLocale(Locale.GERMAN));
-        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
+        assertEquals(LAYOUT_DIRECTION_LTR,
             LocaleUtil.getLayoutDirectionFromLocale(Locale.GERMANY));
-        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
+        assertEquals(LAYOUT_DIRECTION_LTR,
             LocaleUtil.getLayoutDirectionFromLocale(Locale.ITALIAN));
-        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
+        assertEquals(LAYOUT_DIRECTION_LTR,
             LocaleUtil.getLayoutDirectionFromLocale(Locale.ITALY));
-        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
+        assertEquals(LAYOUT_DIRECTION_LTR,
             LocaleUtil.getLayoutDirectionFromLocale(Locale.UK));
-        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
+        assertEquals(LAYOUT_DIRECTION_LTR,
             LocaleUtil.getLayoutDirectionFromLocale(Locale.US));
 
-        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
+        assertEquals(LAYOUT_DIRECTION_LTR,
             LocaleUtil.getLayoutDirectionFromLocale(Locale.ROOT));
 
-        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
+        assertEquals(LAYOUT_DIRECTION_LTR,
             LocaleUtil.getLayoutDirectionFromLocale(Locale.CHINA));
-        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
+        assertEquals(LAYOUT_DIRECTION_LTR,
             LocaleUtil.getLayoutDirectionFromLocale(Locale.CHINESE));
-        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
+        assertEquals(LAYOUT_DIRECTION_LTR,
             LocaleUtil.getLayoutDirectionFromLocale(Locale.JAPAN));
-        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
+        assertEquals(LAYOUT_DIRECTION_LTR,
             LocaleUtil.getLayoutDirectionFromLocale(Locale.JAPANESE));
-        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
+        assertEquals(LAYOUT_DIRECTION_LTR,
             LocaleUtil.getLayoutDirectionFromLocale(Locale.KOREA));
-        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
+        assertEquals(LAYOUT_DIRECTION_LTR,
             LocaleUtil.getLayoutDirectionFromLocale(Locale.KOREAN));
-        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
+        assertEquals(LAYOUT_DIRECTION_LTR,
             LocaleUtil.getLayoutDirectionFromLocale(Locale.PRC));
-        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
+        assertEquals(LAYOUT_DIRECTION_LTR,
             LocaleUtil.getLayoutDirectionFromLocale(Locale.SIMPLIFIED_CHINESE));
-        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
+        assertEquals(LAYOUT_DIRECTION_LTR,
             LocaleUtil.getLayoutDirectionFromLocale(Locale.TAIWAN));
-        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
+        assertEquals(LAYOUT_DIRECTION_LTR,
             LocaleUtil.getLayoutDirectionFromLocale(Locale.TRADITIONAL_CHINESE));
 
         Locale locale = new Locale("ar");
-        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+        assertEquals(LAYOUT_DIRECTION_RTL,
             LocaleUtil.getLayoutDirectionFromLocale(locale));
         locale = new Locale("ar", "AE");
-        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+        assertEquals(LAYOUT_DIRECTION_RTL,
             LocaleUtil.getLayoutDirectionFromLocale(locale));
         locale = new Locale("ar", "BH");
-        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+        assertEquals(LAYOUT_DIRECTION_RTL,
             LocaleUtil.getLayoutDirectionFromLocale(locale));
         locale = new Locale("ar", "DZ");
-        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+        assertEquals(LAYOUT_DIRECTION_RTL,
             LocaleUtil.getLayoutDirectionFromLocale(locale));
         locale = new Locale("ar", "EG");
-        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+        assertEquals(LAYOUT_DIRECTION_RTL,
             LocaleUtil.getLayoutDirectionFromLocale(locale));
         locale = new Locale("ar", "IQ");
-        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+        assertEquals(LAYOUT_DIRECTION_RTL,
             LocaleUtil.getLayoutDirectionFromLocale(locale));
         locale = new Locale("ar", "JO");
-        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+        assertEquals(LAYOUT_DIRECTION_RTL,
             LocaleUtil.getLayoutDirectionFromLocale(locale));
         locale = new Locale("ar", "KW");
-        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+        assertEquals(LAYOUT_DIRECTION_RTL,
             LocaleUtil.getLayoutDirectionFromLocale(locale));
         locale = new Locale("ar", "LB");
-        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+        assertEquals(LAYOUT_DIRECTION_RTL,
             LocaleUtil.getLayoutDirectionFromLocale(locale));
         locale = new Locale("ar", "LY");
-        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+        assertEquals(LAYOUT_DIRECTION_RTL,
             LocaleUtil.getLayoutDirectionFromLocale(locale));
         locale = new Locale("ar", "MA");
-        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+        assertEquals(LAYOUT_DIRECTION_RTL,
             LocaleUtil.getLayoutDirectionFromLocale(locale));
         locale = new Locale("ar", "OM");
-        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+        assertEquals(LAYOUT_DIRECTION_RTL,
             LocaleUtil.getLayoutDirectionFromLocale(locale));
         locale = new Locale("ar", "QA");
-        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+        assertEquals(LAYOUT_DIRECTION_RTL,
             LocaleUtil.getLayoutDirectionFromLocale(locale));
         locale = new Locale("ar", "SA");
-        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+        assertEquals(LAYOUT_DIRECTION_RTL,
             LocaleUtil.getLayoutDirectionFromLocale(locale));
         locale = new Locale("ar", "SD");
-        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+        assertEquals(LAYOUT_DIRECTION_RTL,
             LocaleUtil.getLayoutDirectionFromLocale(locale));
         locale = new Locale("ar", "SY");
-        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+        assertEquals(LAYOUT_DIRECTION_RTL,
             LocaleUtil.getLayoutDirectionFromLocale(locale));
         locale = new Locale("ar", "TN");
-        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+        assertEquals(LAYOUT_DIRECTION_RTL,
             LocaleUtil.getLayoutDirectionFromLocale(locale));
         locale = new Locale("ar", "YE");
-        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+        assertEquals(LAYOUT_DIRECTION_RTL,
             LocaleUtil.getLayoutDirectionFromLocale(locale));
 
         locale = new Locale("fa");
-        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+        assertEquals(LAYOUT_DIRECTION_RTL,
             LocaleUtil.getLayoutDirectionFromLocale(locale));
         locale = new Locale("fa", "AF");
-        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+        assertEquals(LAYOUT_DIRECTION_RTL,
             LocaleUtil.getLayoutDirectionFromLocale(locale));
         locale = new Locale("fa", "IR");
-        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+        assertEquals(LAYOUT_DIRECTION_RTL,
             LocaleUtil.getLayoutDirectionFromLocale(locale));
 
         locale = new Locale("iw");
-        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+        assertEquals(LAYOUT_DIRECTION_RTL,
             LocaleUtil.getLayoutDirectionFromLocale(locale));
         locale = new Locale("iw", "IL");
-        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+        assertEquals(LAYOUT_DIRECTION_RTL,
             LocaleUtil.getLayoutDirectionFromLocale(locale));
         locale = new Locale("he");
-        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+        assertEquals(LAYOUT_DIRECTION_RTL,
             LocaleUtil.getLayoutDirectionFromLocale(locale));
         locale = new Locale("he", "IL");
-        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+        assertEquals(LAYOUT_DIRECTION_RTL,
             LocaleUtil.getLayoutDirectionFromLocale(locale));
 
         locale = new Locale("pa_Arab");
-        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+        assertEquals(LAYOUT_DIRECTION_RTL,
             LocaleUtil.getLayoutDirectionFromLocale(locale));
         locale = new Locale("pa_Arab", "PK");
-        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+        assertEquals(LAYOUT_DIRECTION_RTL,
             LocaleUtil.getLayoutDirectionFromLocale(locale));
 
         locale = new Locale("ps");
-        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+        assertEquals(LAYOUT_DIRECTION_RTL,
             LocaleUtil.getLayoutDirectionFromLocale(locale));
         locale = new Locale("ps", "AF");
-        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+        assertEquals(LAYOUT_DIRECTION_RTL,
             LocaleUtil.getLayoutDirectionFromLocale(locale));
 
         locale = new Locale("ur");
-        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+        assertEquals(LAYOUT_DIRECTION_RTL,
             LocaleUtil.getLayoutDirectionFromLocale(locale));
         locale = new Locale("ur", "IN");
-        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+        assertEquals(LAYOUT_DIRECTION_RTL,
             LocaleUtil.getLayoutDirectionFromLocale(locale));
         locale = new Locale("ur", "PK");
-        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+        assertEquals(LAYOUT_DIRECTION_RTL,
             LocaleUtil.getLayoutDirectionFromLocale(locale));
 
         locale = new Locale("uz_Arab");
-        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+        assertEquals(LAYOUT_DIRECTION_RTL,
             LocaleUtil.getLayoutDirectionFromLocale(locale));
         locale = new Locale("uz_Arab", "AF");
-        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE,
+        assertEquals(LAYOUT_DIRECTION_RTL,
             LocaleUtil.getLayoutDirectionFromLocale(locale));
 
         // Locale without a real language
         locale = new Locale("zz");
-        assertEquals(LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE,
+        assertEquals(LAYOUT_DIRECTION_LTR,
             LocaleUtil.getLayoutDirectionFromLocale(locale));
     }
 }
diff --git a/data/fonts/AndroidEmoji.ttf b/data/fonts/AndroidEmoji.ttf
index d543f75..4c017d5 100644
--- a/data/fonts/AndroidEmoji.ttf
+++ b/data/fonts/AndroidEmoji.ttf
Binary files differ
diff --git a/docs/html/guide/developing/projects/projects-cmdline.jd b/docs/html/guide/developing/projects/projects-cmdline.jd
index 81c2c58..b8db5f3 100644
--- a/docs/html/guide/developing/projects/projects-cmdline.jd
+++ b/docs/html/guide/developing/projects/projects-cmdline.jd
@@ -218,7 +218,7 @@
   <p>To add a reference to a library project, navigate to the <code>&lt;sdk&gt;/tools/</code>
   directory and use this command:</p>
   <pre>
-android update lib-project \
+android update project \
 --target <em>&lt;target_ID&gt;</em> \
 --path <em>path/to/your/project</em>
 --library <em>path/to/library_projectA</em>
diff --git a/docs/html/guide/topics/fundamentals/fragments.jd b/docs/html/guide/topics/fundamentals/fragments.jd
index d4f9342..281cb9d 100644
--- a/docs/html/guide/topics/fundamentals/fragments.jd
+++ b/docs/html/guide/topics/fundamentals/fragments.jd
@@ -659,7 +659,7 @@
 
 <div class="figure" style="width:350px">
 <img src="{@docRoot}images/activity_fragment_lifecycle.png" alt=""/>
-<p class="img-caption"><strong>Figure 3.</strong> The activity lifecycle's affect on the fragment
+<p class="img-caption"><strong>Figure 3.</strong> The effect of the activity lifecycle on the fragment
 lifecycle.</p>
 </div>
 
diff --git a/drm/drmserver/DrmManagerService.cpp b/drm/drmserver/DrmManagerService.cpp
index caeb026..8ba0203 100644
--- a/drm/drmserver/DrmManagerService.cpp
+++ b/drm/drmserver/DrmManagerService.cpp
@@ -159,12 +159,18 @@
 status_t DrmManagerService::consumeRights(
             int uniqueId, DecryptHandle* decryptHandle, int action, bool reserve) {
     ALOGV("Entering consumeRights");
+    if (!isProtectedCallAllowed()) {
+        return DRM_ERROR_NO_PERMISSION;
+    }
     return mDrmManager->consumeRights(uniqueId, decryptHandle, action, reserve);
 }
 
 status_t DrmManagerService::setPlaybackStatus(
             int uniqueId, DecryptHandle* decryptHandle, int playbackStatus, int64_t position) {
     ALOGV("Entering setPlaybackStatus");
+    if (!isProtectedCallAllowed()) {
+        return DRM_ERROR_NO_PERMISSION;
+    }
     return mDrmManager->setPlaybackStatus(uniqueId, decryptHandle, playbackStatus, position);
 }
 
@@ -229,12 +235,18 @@
 
 status_t DrmManagerService::closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle) {
     ALOGV("Entering closeDecryptSession");
+    if (!isProtectedCallAllowed()) {
+        return DRM_ERROR_NO_PERMISSION;
+    }
     return mDrmManager->closeDecryptSession(uniqueId, decryptHandle);
 }
 
 status_t DrmManagerService::initializeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle,
             int decryptUnitId, const DrmBuffer* headerInfo) {
     ALOGV("Entering initializeDecryptUnit");
+    if (!isProtectedCallAllowed()) {
+        return DRM_ERROR_NO_PERMISSION;
+    }
     return mDrmManager->initializeDecryptUnit(uniqueId,decryptHandle, decryptUnitId, headerInfo);
 }
 
@@ -242,18 +254,27 @@
             int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId,
             const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV) {
     ALOGV("Entering decrypt");
+    if (!isProtectedCallAllowed()) {
+        return DRM_ERROR_NO_PERMISSION;
+    }
     return mDrmManager->decrypt(uniqueId, decryptHandle, decryptUnitId, encBuffer, decBuffer, IV);
 }
 
 status_t DrmManagerService::finalizeDecryptUnit(
             int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId) {
     ALOGV("Entering finalizeDecryptUnit");
+    if (!isProtectedCallAllowed()) {
+        return DRM_ERROR_NO_PERMISSION;
+    }
     return mDrmManager->finalizeDecryptUnit(uniqueId, decryptHandle, decryptUnitId);
 }
 
 ssize_t DrmManagerService::pread(int uniqueId, DecryptHandle* decryptHandle,
             void* buffer, ssize_t numBytes, off64_t offset) {
     ALOGV("Entering pread");
+    if (!isProtectedCallAllowed()) {
+        return DRM_ERROR_NO_PERMISSION;
+    }
     return mDrmManager->pread(uniqueId, decryptHandle, buffer, numBytes, offset);
 }
 
diff --git a/drm/drmserver/main_drmserver.cpp b/drm/drmserver/main_drmserver.cpp
index e61b269..434d561 100644
--- a/drm/drmserver/main_drmserver.cpp
+++ b/drm/drmserver/main_drmserver.cpp
@@ -17,15 +17,10 @@
 #define LOG_TAG "drmserver"
 //#define LOG_NDEBUG 0
 
-#include <sys/types.h>
-#include <unistd.h>
-#include <grp.h>
-
 #include <binder/IPCThreadState.h>
 #include <binder/ProcessState.h>
 #include <binder/IServiceManager.h>
 #include <utils/Log.h>
-#include <private/android_filesystem_config.h>
 
 #include <DrmManagerService.h>
 
diff --git a/drm/java/android/drm/DrmErrorEvent.java b/drm/java/android/drm/DrmErrorEvent.java
index 2cb82e6..c61819d 100755
--- a/drm/java/android/drm/DrmErrorEvent.java
+++ b/drm/java/android/drm/DrmErrorEvent.java
@@ -24,6 +24,10 @@
  *
  */
 public class DrmErrorEvent extends DrmEvent {
+
+    // Please add newly defined type constants to the end of the list,
+    // and modify checkTypeValidity() accordingly.
+
     /**
      * Something went wrong installing the rights.
      */
@@ -60,28 +64,46 @@
      */
     public static final int TYPE_ACQUIRE_DRM_INFO_FAILED = 2008;
 
+    // Add more type constants here...
+
+    // FIXME:
+    // We may want to add a user-defined type constant, such as
+    // TYPE_VENDOR_SPECIFIC_FAILED, to take care vendor specific use
+    // cases.
+
+
     /**
      * Creates a <code>DrmErrorEvent</code> object with the specified parameters.
      *
      * @param uniqueId Unique session identifier.
-     * @param type Type of the event. Could be any of the event types defined above.
-     * @param message Message description.
+     * @param type Type of the event. Must be any of the event types defined above.
+     * @param message Message description. It can be null.
      */
     public DrmErrorEvent(int uniqueId, int type, String message) {
         super(uniqueId, type, message);
+        checkTypeValidity(type);
     }
 
     /**
      * Creates a <code>DrmErrorEvent</code> object with the specified parameters.
      *
      * @param uniqueId Unique session identifier.
-     * @param type Type of the event. Could be any of the event types defined above.
+     * @param type Type of the event. Must be any of the event types defined above.
      * @param message Message description.
      * @param attributes Attributes for extensible information. Could be any
-     * information provided by the plug-in.
+     * information provided by the plug-in. It can be null.
      */
     public DrmErrorEvent(int uniqueId, int type, String message,
                             HashMap<String, Object> attributes) {
         super(uniqueId, type, message, attributes);
+        checkTypeValidity(type);
+    }
+
+    private void checkTypeValidity(int type) {
+        if (type < TYPE_RIGHTS_NOT_INSTALLED ||
+            type > TYPE_ACQUIRE_DRM_INFO_FAILED) {
+            final String msg = "Unsupported type: " + type;
+            throw new IllegalArgumentException(msg);
+        }
     }
 }
diff --git a/drm/java/android/drm/DrmEvent.java b/drm/java/android/drm/DrmEvent.java
index 4053eb3..1a19f5c 100755
--- a/drm/java/android/drm/DrmEvent.java
+++ b/drm/java/android/drm/DrmEvent.java
@@ -23,6 +23,10 @@
  *
  */
 public class DrmEvent {
+
+    // Please do not add type constants in this class. More event type constants
+    // should go to DrmInfoEvent or DrmErrorEvent classes.
+
     /**
      * All of the rights information associated with all DRM schemes have been successfully removed.
      */
diff --git a/drm/java/android/drm/DrmInfoEvent.java b/drm/java/android/drm/DrmInfoEvent.java
index 67aa0a9..2826dce 100755
--- a/drm/java/android/drm/DrmInfoEvent.java
+++ b/drm/java/android/drm/DrmInfoEvent.java
@@ -24,6 +24,10 @@
  *
  */
 public class DrmInfoEvent extends DrmEvent {
+
+    // Please add newly defined type constants to the end of the list,
+    // and modify checkTypeValidity() accordingly.
+
     /**
      * The registration has already been done by another account ID.
      */
@@ -50,29 +54,57 @@
      */
     public static final int TYPE_RIGHTS_REMOVED = 6;
 
+    // Add more type constants here...
+
+    // FIXME:
+    // We may want to add a user-defined type constant, such as
+    // TYPE_VENDOR_SPECIFIC, to take care vendor specific use
+    // cases.
+
     /**
      * Creates a <code>DrmInfoEvent</code> object with the specified parameters.
      *
      * @param uniqueId Unique session identifier.
-     * @param type Type of the event. Could be any of the event types defined above.
-     * @param message Message description.
+     * @param type Type of the event. Must be any of the event types defined above,
+     * or the constants defined in {@link DrmEvent}.
+     * @param message Message description. It can be null.
      */
     public DrmInfoEvent(int uniqueId, int type, String message) {
         super(uniqueId, type, message);
+        checkTypeValidity(type);
     }
 
     /**
      * Creates a <code>DrmInfoEvent</code> object with the specified parameters.
      *
      * @param uniqueId Unique session identifier.
-     * @param type Type of the event. Could be any of the event types defined above.
-     * @param message Message description.
+     * @param type Type of the event. Must be any of the event types defined above,
+     * or the constants defined in {@link DrmEvent}
+     * @param message Message description. It can be null.
      * @param attributes Attributes for extensible information. Could be any
      * information provided by the plug-in.
      */
     public DrmInfoEvent(int uniqueId, int type, String message,
                             HashMap<String, Object> attributes) {
         super(uniqueId, type, message, attributes);
+        checkTypeValidity(type);
+    }
+
+    /*
+     * Check the validity of the given type.
+     * To overcome a design flaw, we need also accept the type constants
+     * defined in super class, DrmEvent.
+     */
+    private void checkTypeValidity(int type) {
+        if (type < TYPE_ALREADY_REGISTERED_BY_ANOTHER_ACCOUNT ||
+            type > TYPE_RIGHTS_REMOVED) {
+
+            if (type != TYPE_ALL_RIGHTS_REMOVED &&
+                type != TYPE_DRM_INFO_PROCESSED) {
+                final String msg = "Unsupported type: " + type;
+                throw new IllegalArgumentException(msg);
+            }
+        }
     }
 }
 
diff --git a/drm/java/android/drm/DrmManagerClient.java b/drm/java/android/drm/DrmManagerClient.java
index 9a7194c..14d5fae 100755
--- a/drm/java/android/drm/DrmManagerClient.java
+++ b/drm/java/android/drm/DrmManagerClient.java
@@ -317,6 +317,7 @@
      *
      * @return A {@link android.content.ContentValues} instance that contains
      * key-value pairs representing the constraints. Null in case of failure.
+     * The keys are defined in {@link DrmStore.ConstraintsColumns}.
      */
     public ContentValues getConstraints(String path, int action) {
         if (null == path || path.equals("") || !DrmStore.Action.isValid(action)) {
diff --git a/drm/java/android/drm/DrmRights.java b/drm/java/android/drm/DrmRights.java
index d4afed1..a9b4f05 100755
--- a/drm/java/android/drm/DrmRights.java
+++ b/drm/java/android/drm/DrmRights.java
@@ -30,19 +30,24 @@
  * A caller can also instantiate a {@link DrmRights} object by using the
  * {@link DrmRights#DrmRights(String, String)} constructor, which takes a path to a file
  * containing rights information instead of a <code>ProcessedData</code>.
+ *<p>
+ * Please note that the account id and subscription id is not mandatory by all DRM agents
+ * or plugins. When account id or subscription id is not required by the specific DRM
+ * agent or plugin, they can be either null, or an empty string, or any other don't-care
+ * string value.
  *
  */
 public class DrmRights {
     private byte[] mData;
     private String mMimeType;
-    private String mAccountId = "_NO_USER";
-    private String mSubscriptionId = "";
+    private String mAccountId;
+    private String mSubscriptionId;
 
     /**
      * Creates a <code>DrmRights</code> object with the given parameters.
      *
      * @param rightsFilePath Path to the file containing rights information.
-     * @param mimeType MIME type.
+     * @param mimeType MIME type. Must not be null or an empty string.
      */
     public DrmRights(String rightsFilePath, String mimeType) {
         File file = new File(rightsFilePath);
@@ -53,22 +58,20 @@
      * Creates a <code>DrmRights</code> object with the given parameters.
      *
      * @param rightsFilePath Path to the file containing rights information.
-     * @param mimeType MIME type.
+     * @param mimeType MIME type. Must not be null or an empty string.
      * @param accountId Account ID of the user.
      */
     public DrmRights(String rightsFilePath, String mimeType, String accountId) {
         this(rightsFilePath, mimeType);
 
-        if (null != accountId && !accountId.equals("")) {
-            mAccountId = accountId;
-        }
+        mAccountId = accountId;
     }
 
     /**
      * Creates a <code>DrmRights</code> object with the given parameters.
      *
      * @param rightsFilePath Path to the file containing rights information.
-     * @param mimeType MIME type.
+     * @param mimeType MIME type. Must not be null or an empty string.
      * @param accountId Account ID of the user.
      * @param subscriptionId Subscription ID of the user.
      */
@@ -76,20 +79,15 @@
             String rightsFilePath, String mimeType, String accountId, String subscriptionId) {
         this(rightsFilePath, mimeType);
 
-        if (null != accountId && !accountId.equals("")) {
-            mAccountId = accountId;
-        }
-
-        if (null != subscriptionId && !subscriptionId.equals("")) {
-            mSubscriptionId = subscriptionId;
-        }
+        mAccountId = accountId;
+        mSubscriptionId = subscriptionId;
     }
 
     /**
      * Creates a <code>DrmRights</code> object with the given parameters.
      *
      * @param rightsFile File containing rights information.
-     * @param mimeType MIME type.
+     * @param mimeType MIME type. Must not be null or an empty string.
      */
     public DrmRights(File rightsFile, String mimeType) {
         instantiate(rightsFile, mimeType);
@@ -114,28 +112,19 @@
      * Creates a <code>DrmRights</code> object with the given parameters.
      *
      * @param data A {@link ProcessedData} object containing rights information.
-     *             data could be null because it's optional for some DRM schemes.
-     * @param mimeType The MIME type.
+     *             Must not be null.
+     * @param mimeType The MIME type. It must not be null or an empty string.
      */
     public DrmRights(ProcessedData data, String mimeType) {
-        if (data != null) {
-            mData = data.getData();
-
-            String accountId = data.getAccountId();
-            if (null == accountId || !accountId.equals("")) {
-                throw new IllegalArgumentException("accountId: " + accountId);
-            }
-            mAccountId = accountId;
-
-            String subscriptionId = data.getSubscriptionId();
-            if (null == subscriptionId || !subscriptionId.equals("")) {
-                throw new IllegalArgumentException(
-                            "subscriptionId: " + subscriptionId);
-            }
-            mSubscriptionId = subscriptionId;
+        if (data == null) {
+            throw new IllegalArgumentException("data is null");
         }
 
+        mData = data.getData();
+        mAccountId = data.getAccountId();
+        mSubscriptionId = data.getSubscriptionId();
         mMimeType = mimeType;
+
         if (!isValid()) {
             final String msg = "mimeType: " + mMimeType + "," +
                                "data: " + mData;
diff --git a/drm/java/android/drm/DrmStore.java b/drm/java/android/drm/DrmStore.java
index ae311de..3a77ea1 100755
--- a/drm/java/android/drm/DrmStore.java
+++ b/drm/java/android/drm/DrmStore.java
@@ -23,45 +23,65 @@
 public class DrmStore {
     /**
      * Interface definition for the columns that represent DRM constraints.
+     * {@link android.drm.DrmManagerClient#getConstraints DrmManagerClient.getConstraints()}
+     * can be called by an application to find out the contraints on the
+     * {@link android.drm.DrmStore.Action actions} that can be performed
+     * on right-protected content. The constants defined in this interface
+     * represent three most common types of constraints: count-based,
+     * date-based, and duration-based. Two or more constraints can be used
+     * at the same time to represent more sophisticated constraints.
+     * In addition, user-defined constraint,
+     * {@link #EXTENDED_METADATA extended metadata}, can be
+     * used if these three types of constraints are not sufficient.
      */
     public interface ConstraintsColumns {
         /**
-         * The maximum repeat count.
+         * This is a count-based constraint. It represents the maximum
+         * repeat count that can be performed on an
+         * {@link android.drm.DrmStore.Action action}.
          * <p>
          * Type: INTEGER
          */
         public static final String MAX_REPEAT_COUNT = "max_repeat_count";
 
         /**
-         * The remaining repeat count.
+         * This is a count-based constraint. It represents the remaining
+         * repeat count that can be performed on an
+         * {@link android.drm.DrmStore.Action action}.
          * <p>
          * Type: INTEGER
          */
         public static final String REMAINING_REPEAT_COUNT = "remaining_repeat_count";
 
         /**
-         * The time before which the rights-protected file cannot be played/viewed.
+         * This is a date-based constraint. It represents the time before which
+         * an {@link android.drm.DrmStore.Action action} can be performed on
+         * the rights-protected content.
          * <p>
          * Type: TEXT
          */
         public static final String LICENSE_START_TIME = "license_start_time";
 
         /**
-         * The time after which the rights-protected file cannot be played/viewed.
+         * This is a date-based constaint. It represents the time after which
+         * an {@link android.drm.DrmStore.Action action} can not be performed on
+         * the rights-protected content.
          * <p>
          * Type: TEXT
          */
         public static final String LICENSE_EXPIRY_TIME = "license_expiry_time";
 
         /**
-         * The available time left before the license expires.
+         * This is a duration-based constaint. It represents the available time left
+         * before the license expires.
          * <p>
          * Type: TEXT
          */
         public static final String LICENSE_AVAILABLE_TIME = "license_available_time";
 
         /**
-         * The data stream for extended metadata.
+         * This is a user-defined constraint. It represents the additional constraint
+         * using extended metadata.
          * <p>
          * Type: TEXT
          */
@@ -88,6 +108,12 @@
          * A trigger information object type.
          */
         public static final int TRIGGER_OBJECT = 0x03;
+
+        /**
+         * @deprecated This class should have been an interface instead.
+         * The default constuctor should have not been exposed.
+         */
+        public DrmObjectType() {}
     }
 
     /**
@@ -123,6 +149,12 @@
             }
             return isValid;
         }
+
+        /**
+         * @deprecated This class should have been an interface instead.
+         * The default constuctor should have not been exposed.
+         */
+        public Playback() {}
     }
 
     /**
@@ -178,6 +210,12 @@
             }
             return isValid;
         }
+
+        /**
+         * @deprecated This class should have been an interface instead.
+         * The default constuctor should have not been exposed.
+         */
+        public Action() {}
     }
 
     /**
@@ -200,6 +238,18 @@
          * The digital rights have not been acquired for the rights-protected content.
          */
         public static final int RIGHTS_NOT_ACQUIRED = 0x03;
+
+        /**
+         * @deprecated This class should have been an interface instead.
+         * The default constuctor should have not been exposed.
+         */
+        public RightsStatus() {}
     }
+
+    /**
+     * @deprecated This class should have been an interface instead.
+     * The default constuctor should have not been exposed.
+     */
+    public DrmStore() {}
 }
 
diff --git a/drm/java/android/drm/DrmSupportInfo.java b/drm/java/android/drm/DrmSupportInfo.java
index 720c545..6484fa7 100755
--- a/drm/java/android/drm/DrmSupportInfo.java
+++ b/drm/java/android/drm/DrmSupportInfo.java
@@ -85,12 +85,23 @@
      * Retrieves the DRM plug-in (agent) description.
      *
      * @return The plug-in description.
+     * @deprecated The method name is mis-spelled, and it is replaced by
+     * {@link #getDescription()}.
      */
     public String getDescriprition() {
         return mDescription;
     }
 
     /**
+     * Retrieves the DRM plug-in (agent) description.
+     *
+     * @return The plug-in description.
+     */
+    public String getDescription() {
+        return mDescription;
+    }
+
+    /**
      * Overridden hash code implementation.
      *
      * @return The hash code value.
diff --git a/drm/java/android/drm/DrmUtils.java b/drm/java/android/drm/DrmUtils.java
index dc5f1fa..4f7cb22 100755
--- a/drm/java/android/drm/DrmUtils.java
+++ b/drm/java/android/drm/DrmUtils.java
@@ -55,8 +55,8 @@
                 bufferedStream.read(data);
              }
         } finally {
-            quiteDispose(bufferedStream);
-            quiteDispose(inputStream);
+            quietlyDispose(bufferedStream);
+            quietlyDispose(inputStream);
         }
         return data;
     }
@@ -70,7 +70,7 @@
                 outputStream = new FileOutputStream(path);
                 outputStream.write(data);
             } finally {
-                quiteDispose(outputStream);
+                quietlyDispose(outputStream);
             }
         }
     }
@@ -80,7 +80,7 @@
         file.delete();
     }
 
-    private static void quiteDispose(InputStream stream) {
+    private static void quietlyDispose(InputStream stream) {
         try {
             if (null != stream) {
                 stream.close();
@@ -90,7 +90,7 @@
         }
     }
 
-    private static void quiteDispose(OutputStream stream) {
+    private static void quietlyDispose(OutputStream stream) {
         try {
             if (null != stream) {
                 stream.close();
@@ -175,14 +175,34 @@
             }
         }
 
+        /**
+         * This method returns an iterator object that can be used to iterate over
+         * all values of the metadata.
+         *
+         * @return The iterator object.
+         */
         public Iterator<String> iterator() {
             return mMap.values().iterator();
         }
 
+        /**
+         * This method returns an iterator object that can be used to iterate over
+         * all keys of the metadata.
+         *
+         * @return The iterator object.
+         */
         public Iterator<String> keyIterator() {
             return mMap.keySet().iterator();
         }
 
+        /**
+         * This method retrieves the metadata value associated with a given key.
+         *
+         * @param key The key whose value is being retrieved.
+         *
+         * @return The metadata value associated with the given key. Returns null
+         * if the key is not found.
+         */
         public String get(String key) {
             return mMap.get(key);
         }
diff --git a/graphics/java/android/graphics/PixelFormat.java b/graphics/java/android/graphics/PixelFormat.java
index 182f14d..f7c202f 100644
--- a/graphics/java/android/graphics/PixelFormat.java
+++ b/graphics/java/android/graphics/PixelFormat.java
@@ -39,11 +39,15 @@
     public static final int RGB_888     = 3;
     public static final int RGB_565     = 4;
 
+    @Deprecated
     public static final int RGBA_5551   = 6;
+    @Deprecated
     public static final int RGBA_4444   = 7;
     public static final int A_8         = 8;
     public static final int L_8         = 9;
+    @Deprecated
     public static final int LA_88       = 0xA;
+    @Deprecated
     public static final int RGB_332     = 0xB;
 
 
diff --git a/graphics/java/android/renderscript/RenderScript.java b/graphics/java/android/renderscript/RenderScript.java
index 9517513..6921f37 100644
--- a/graphics/java/android/renderscript/RenderScript.java
+++ b/graphics/java/android/renderscript/RenderScript.java
@@ -17,6 +17,7 @@
 package android.renderscript;
 
 import java.lang.reflect.Field;
+import java.io.File;
 
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
@@ -82,6 +83,25 @@
     native void nContextInitToClient(int con);
     native void nContextDeinitToClient(int con);
 
+    /**
+     * Name of the file that holds the object cache.
+     */
+    private static final String CACHE_PATH = "com.android.renderscript.cache";
+    static String mCachePath;
+
+     /**
+     * Sets the directory to use as a persistent storage for the
+     * renderscript object file cache.
+     *
+     * @hide
+     * @param cacheDir A directory the current process can write to
+     */
+    public static void setupDiskCache(File cacheDir) {
+        File f = new File(cacheDir, CACHE_PATH);
+        mCachePath = f.getAbsolutePath();
+        f.mkdirs();
+    }
+
 
     // Methods below are wrapped to protect the non-threadsafe
     // lockless fifo.
@@ -884,7 +904,9 @@
     }
 
     RenderScript(Context ctx) {
-        mApplicationContext = ctx.getApplicationContext();
+        if (ctx != null) {
+            mApplicationContext = ctx.getApplicationContext();
+        }
     }
 
     /**
@@ -896,21 +918,16 @@
         return mApplicationContext;
     }
 
-    static int getTargetSdkVersion(Context ctx) {
-        return ctx.getApplicationInfo().targetSdkVersion;
-    }
-
     /**
      * Create a basic RenderScript context.
      *
+     * @hide
      * @param ctx The context.
      * @return RenderScript
      */
-    public static RenderScript create(Context ctx) {
+    public static RenderScript create(Context ctx, int sdkVersion) {
         RenderScript rs = new RenderScript(ctx);
 
-        int sdkVersion = getTargetSdkVersion(ctx);
-
         rs.mDev = rs.nDeviceCreate();
         rs.mContext = rs.nContextCreate(rs.mDev, 0, sdkVersion);
         if (rs.mContext == 0) {
@@ -922,6 +939,17 @@
     }
 
     /**
+     * Create a basic RenderScript context.
+     *
+     * @param ctx The context.
+     * @return RenderScript
+     */
+    public static RenderScript create(Context ctx) {
+        int v = ctx.getApplicationInfo().targetSdkVersion;
+        return create(ctx, v);
+    }
+
+    /**
      * Print the currently available debugging information about the state of
      * the RS context to the log.
      *
diff --git a/graphics/java/android/renderscript/RenderScriptGL.java b/graphics/java/android/renderscript/RenderScriptGL.java
index 2cfeb17..1b2ac90 100644
--- a/graphics/java/android/renderscript/RenderScriptGL.java
+++ b/graphics/java/android/renderscript/RenderScriptGL.java
@@ -166,7 +166,7 @@
         super(ctx);
         mSurfaceConfig = new SurfaceConfig(sc);
 
-        int sdkVersion = getTargetSdkVersion(ctx);
+        int sdkVersion = ctx.getApplicationInfo().targetSdkVersion;
 
         mWidth = 0;
         mHeight = 0;
diff --git a/graphics/java/android/renderscript/ScriptC.java b/graphics/java/android/renderscript/ScriptC.java
index 90f959f..108b230 100644
--- a/graphics/java/android/renderscript/ScriptC.java
+++ b/graphics/java/android/renderscript/ScriptC.java
@@ -92,13 +92,9 @@
             throw new Resources.NotFoundException();
         }
 
-        // E.g, /system/apps/Fountain.apk
-        //String packageName = rs.getApplicationContext().getPackageResourcePath();
-        // For res/raw/fountain.bc, it wil be /com.android.fountain:raw/fountain
         String resName = resources.getResourceEntryName(resourceID);
-        String cacheDir = rs.getApplicationContext().getCacheDir().toString();
 
         Log.v(TAG, "Create script for resource = " + resName);
-        return rs.nScriptCCreate(resName, cacheDir, pgm, pgmLength);
+        return rs.nScriptCCreate(resName, rs.mCachePath, pgm, pgmLength);
     }
 }
diff --git a/graphics/jni/android_renderscript_RenderScript.cpp b/graphics/jni/android_renderscript_RenderScript.cpp
index 27ea8f6..9fc4fd4 100644
--- a/graphics/jni/android_renderscript_RenderScript.cpp
+++ b/graphics/jni/android_renderscript_RenderScript.cpp
@@ -23,8 +23,6 @@
 #include <math.h>
 #include <utils/misc.h>
 
-#include <surfaceflinger/Surface.h>
-
 #include <core/SkBitmap.h>
 #include <core/SkPixelRef.h>
 #include <core/SkStream.h>
diff --git a/include/binder/CursorWindow.h b/include/androidfw/CursorWindow.h
similarity index 100%
rename from include/binder/CursorWindow.h
rename to include/androidfw/CursorWindow.h
diff --git a/include/binder/MemoryHeapPmem.h b/include/binder/MemoryHeapPmem.h
deleted file mode 100644
index e1660c4..0000000
--- a/include/binder/MemoryHeapPmem.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_MEMORY_HEAP_PMEM_H
-#define ANDROID_MEMORY_HEAP_PMEM_H
-
-#include <stdlib.h>
-#include <stdint.h>
-
-#include <binder/MemoryHeapBase.h>
-#include <binder/IMemory.h>
-#include <utils/SortedVector.h>
-#include <utils/threads.h>
-
-namespace android {
-
-class MemoryHeapBase;
-
-// ---------------------------------------------------------------------------
-
-class MemoryHeapPmem : public MemoryHeapBase
-{
-public:
-    class MemoryPmem : public BnMemory {
-    public:
-        MemoryPmem(const sp<MemoryHeapPmem>& heap);
-        ~MemoryPmem();
-    protected:
-        const sp<MemoryHeapPmem>&  getHeap() const { return mClientHeap; }
-    private:
-        friend class MemoryHeapPmem;
-        virtual void revoke() = 0;
-        sp<MemoryHeapPmem>  mClientHeap;
-    };
-    
-    MemoryHeapPmem(const sp<MemoryHeapBase>& pmemHeap, uint32_t flags = 0);
-    ~MemoryHeapPmem();
-
-    /* HeapInterface additions */
-    virtual sp<IMemory> mapMemory(size_t offset, size_t size);
-
-    /* make the whole heap visible (you know who you are) */
-    virtual status_t slap();
-    
-    /* hide (revoke) the whole heap (the client will see the garbage page) */
-    virtual status_t unslap();
-    
-    /* revoke all allocations made by this heap */
-    virtual void revoke();
-
-private:
-    /* use this to create your own IMemory for mapMemory */
-    virtual sp<MemoryPmem> createMemory(size_t offset, size_t size);
-    void remove(const wp<MemoryPmem>& memory);
-
-private:
-    sp<MemoryHeapBase>              mParentHeap;
-    mutable Mutex                   mLock;
-    SortedVector< wp<MemoryPmem> >  mAllocations;
-};
-
-
-// ---------------------------------------------------------------------------
-}; // namespace android
-
-#endif // ANDROID_MEMORY_HEAP_PMEM_H
diff --git a/include/camera/ICamera.h b/include/camera/ICamera.h
index 400d7f4..3d18837 100644
--- a/include/camera/ICamera.h
+++ b/include/camera/ICamera.h
@@ -20,15 +20,15 @@
 #include <utils/RefBase.h>
 #include <binder/IInterface.h>
 #include <binder/Parcel.h>
-#include <surfaceflinger/Surface.h>
 #include <binder/IMemory.h>
 #include <utils/String8.h>
 #include <camera/Camera.h>
-#include <gui/ISurfaceTexture.h>
 
 namespace android {
 
 class ICameraClient;
+class ISurfaceTexture;
+class Surface;
 
 class ICamera: public IInterface
 {
diff --git a/include/drm/drm_framework_common.h b/include/drm/drm_framework_common.h
index 2632cbd..637409c 100644
--- a/include/drm/drm_framework_common.h
+++ b/include/drm/drm_framework_common.h
@@ -43,6 +43,7 @@
     DRM_ERROR_DECRYPT                       = ERROR_BASE - 5,
     DRM_ERROR_CANNOT_HANDLE                 = ERROR_BASE - 6,
     DRM_ERROR_TAMPER_DETECTED               = ERROR_BASE - 7,
+    DRM_ERROR_NO_PERMISSION                 = ERROR_BASE - 8,
 
     DRM_NO_ERROR                            = NO_ERROR
 };
diff --git a/include/gui/BufferQueue.h b/include/gui/BufferQueue.h
index ae99160..8c21a28 100644
--- a/include/gui/BufferQueue.h
+++ b/include/gui/BufferQueue.h
@@ -19,9 +19,9 @@
 
 #include <EGL/egl.h>
 
+#include <gui/IGraphicBufferAlloc.h>
 #include <gui/ISurfaceTexture.h>
 
-#include <surfaceflinger/IGraphicBufferAlloc.h>
 #include <ui/GraphicBuffer.h>
 
 #include <utils/String8.h>
@@ -40,6 +40,7 @@
     };
     enum { NUM_BUFFER_SLOTS = 32 };
     enum { NO_CONNECTED_API = 0 };
+    enum { INVALID_BUFFER_SLOT = -1 };
 
     struct FrameAvailableListener : public virtual RefBase {
         // onFrameAvailable() is called from queueBuffer() each time an
@@ -119,8 +120,91 @@
     // connected to the specified client API.
     virtual status_t disconnect(int api);
 
-protected:
+    // dump our state in a String
+    virtual void dump(String8& result) const;
+    virtual void dump(String8& result, const char* prefix, char* buffer, size_t SIZE) const;
 
+    // public facing structure for BufferSlot
+    struct BufferItem {
+
+        BufferItem()
+         :
+           mTransform(0),
+           mScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
+           mTimestamp(0),
+           mFrameNumber(0),
+           mBuf(INVALID_BUFFER_SLOT) {
+             mCrop.makeInvalid();
+         }
+        // mGraphicBuffer points to the buffer allocated for this slot or is NULL
+        // if no buffer has been allocated.
+        sp<GraphicBuffer> mGraphicBuffer;
+
+        // mCrop is the current crop rectangle for this buffer slot. This gets
+        // set to mNextCrop each time queueBuffer gets called for this buffer.
+        Rect mCrop;
+
+        // mTransform is the current transform flags for this buffer slot. This
+        // gets set to mNextTransform each time queueBuffer gets called for this
+        // slot.
+        uint32_t mTransform;
+
+        // mScalingMode is the current scaling mode for this buffer slot. This
+        // gets set to mNextScalingMode each time queueBuffer gets called for
+        // this slot.
+        uint32_t mScalingMode;
+
+        // mTimestamp is the current timestamp for this buffer slot. This gets
+        // to set by queueBuffer each time this slot is queued.
+        int64_t mTimestamp;
+
+        // mFrameNumber is the number of the queued frame for this slot.
+        uint64_t mFrameNumber;
+
+        // buf is the slot index of this buffer
+        int mBuf;
+
+    };
+
+    // The following public functions is the consumer facing interface
+
+    // acquire consumes a buffer by transferring its ownership to a consumer.
+    // buffer contains the GraphicBuffer and its corresponding information.
+    // buffer.mGraphicsBuffer will be NULL when the buffer has been already
+    // acquired by the consumer.
+
+    status_t acquire(BufferItem *buffer);
+
+    // releaseBuffer releases a buffer slot from the consumer back to the
+    // BufferQueue pending a fence sync.
+    status_t releaseBuffer(int buf, EGLDisplay display, EGLSyncKHR fence);
+
+    // consumerDisconnect disconnects a consumer from the BufferQueue. All
+    // buffers will be freed.
+    status_t consumerDisconnect();
+
+    // setDefaultBufferSize is used to set the size of buffers returned by
+    // requestBuffers when a with and height of zero is requested.
+    status_t setDefaultBufferSize(uint32_t w, uint32_t h);
+
+    // setBufferCountServer set the buffer count. If the client has requested
+    // a buffer count using setBufferCount, the server-buffer count will
+    // take effect once the client sets the count back to zero.
+    status_t setBufferCountServer(int bufferCount);
+
+    // isSynchronousMode returns whether the SurfaceTexture is currently in
+    // synchronous mode.
+    bool isSynchronousMode() const;
+
+    // setConsumerName sets the name used in logging
+    void setConsumerName(const String8& name);
+
+    // setFrameAvailableListener sets the listener object that will be notified
+    // when a new frame becomes available.
+    void setFrameAvailableListener(const sp<FrameAvailableListener>& listener);
+
+
+private:
     // freeBufferLocked frees the resources (both GraphicBuffer and EGLImage)
     // for the given slot.
     void freeBufferLocked(int index);
@@ -145,20 +229,18 @@
 
     status_t setBufferCountServerLocked(int bufferCount);
 
-    enum { INVALID_BUFFER_SLOT = -1 };
-
     struct BufferSlot {
 
         BufferSlot()
-        : mEglImage(EGL_NO_IMAGE_KHR),
-          mEglDisplay(EGL_NO_DISPLAY),
+        : mEglDisplay(EGL_NO_DISPLAY),
           mBufferState(BufferSlot::FREE),
           mRequestBufferCalled(false),
           mTransform(0),
           mScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
           mTimestamp(0),
           mFrameNumber(0),
-          mFence(EGL_NO_SYNC_KHR) {
+          mFence(EGL_NO_SYNC_KHR),
+          mAcquireCalled(false) {
             mCrop.makeInvalid();
         }
 
@@ -166,9 +248,6 @@
         // if no buffer has been allocated.
         sp<GraphicBuffer> mGraphicBuffer;
 
-        // mEglImage is the EGLImage created from mGraphicBuffer.
-        EGLImageKHR mEglImage;
-
         // mEglDisplay is the EGLDisplay used to create mEglImage.
         EGLDisplay mEglDisplay;
 
@@ -178,6 +257,7 @@
             // FREE indicates that the buffer is not currently being used and
             // will not be used in the future until it gets dequeued and
             // subsequently queued by the client.
+            // aka "owned by BufferQueue, ready to be dequeued"
             FREE = 0,
 
             // DEQUEUED indicates that the buffer has been dequeued by the
@@ -190,6 +270,7 @@
             // dequeued by the client.  That means that the current buffer can
             // be in either the DEQUEUED or QUEUED state.  In asynchronous mode,
             // however, the current buffer is always in the QUEUED state.
+            // aka "owned by producer, ready to be queued"
             DEQUEUED = 1,
 
             // QUEUED indicates that the buffer has been queued by the client,
@@ -199,7 +280,11 @@
             // the current buffer may be dequeued by the client under some
             // circumstances. See the note about the current buffer in the
             // documentation for DEQUEUED.
+            // aka "owned by BufferQueue, ready to be acquired"
             QUEUED = 2,
+
+            // aka "owned by consumer, ready to be released"
+            ACQUIRED = 3
         };
 
         // mBufferState is the current state of this buffer slot.
@@ -236,6 +321,9 @@
         // 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;
+
+        // Indicates whether this buffer has been seen by a consumer yet
+        bool mAcquireCalled;
     };
 
     // mSlots is the array of buffer slots that must be mirrored on the client
@@ -245,7 +333,6 @@
     // for a slot when requestBuffer is called with that slot's index.
     BufferSlot mSlots[NUM_BUFFER_SLOTS];
 
-
     // mDefaultWidth holds the default width of allocated buffers. It is used
     // in requestBuffers() if a width and height of zero is specified.
     uint32_t mDefaultWidth;
@@ -271,14 +358,6 @@
     // mServerBufferCount buffer count requested by the server-side
     int mServerBufferCount;
 
-    // mCurrentTexture is the buffer slot index of the buffer that is currently
-    // bound to the OpenGL texture. It is initialized to INVALID_BUFFER_SLOT,
-    // indicating that no buffer slot is currently bound to the texture. Note,
-    // however, that a value of INVALID_BUFFER_SLOT does not necessarily mean
-    // that no buffer is bound to the texture. A call to setBufferCount will
-    // reset mCurrentTexture to INVALID_BUFFER_SLOT.
-    int mCurrentTexture;
-
     // mNextCrop is the crop rectangle that will be used for the next buffer
     // that gets queued. It is set by calling setCrop.
     Rect mNextCrop;
@@ -327,7 +406,7 @@
 
     // mName is a string used to identify the BufferQueue in log messages.
     // It is set by the setName method.
-    String8 mName;
+    String8 mConsumerName;
 
     // mMutex is the mutex used to prevent concurrent access to the member
     // variables of BufferQueue objects. It must be locked whenever the
@@ -337,6 +416,8 @@
     // mFrameCounter is the free running counter, incremented for every buffer queued
     // with the surface Texture.
     uint64_t mFrameCounter;
+
+    bool mBufferHasBeenQueued;
 };
 
 // ----------------------------------------------------------------------------
diff --git a/include/surfaceflinger/IGraphicBufferAlloc.h b/include/gui/IGraphicBufferAlloc.h
similarity index 90%
rename from include/surfaceflinger/IGraphicBufferAlloc.h
rename to include/gui/IGraphicBufferAlloc.h
index d3b2062..cee41d9 100644
--- a/include/surfaceflinger/IGraphicBufferAlloc.h
+++ b/include/gui/IGraphicBufferAlloc.h
@@ -14,15 +14,15 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_SF_IGRAPHIC_BUFFER_ALLOC_H
-#define ANDROID_SF_IGRAPHIC_BUFFER_ALLOC_H
+#ifndef ANDROID_GUI_IGRAPHIC_BUFFER_ALLOC_H
+#define ANDROID_GUI_IGRAPHIC_BUFFER_ALLOC_H
 
 #include <stdint.h>
 #include <sys/types.h>
 
-#include <utils/RefBase.h>
-
 #include <binder/IInterface.h>
+#include <ui/PixelFormat.h>
+#include <utils/RefBase.h>
 
 namespace android {
 // ----------------------------------------------------------------------------
@@ -55,4 +55,4 @@
 
 }; // namespace android
 
-#endif // ANDROID_SF_IGRAPHIC_BUFFER_ALLOC_H
+#endif // ANDROID_GUI_IGRAPHIC_BUFFER_ALLOC_H
diff --git a/include/surfaceflinger/ISurface.h b/include/gui/ISurface.h
similarity index 93%
rename from include/surfaceflinger/ISurface.h
rename to include/gui/ISurface.h
index 5fdf234..c0ff9fc 100644
--- a/include/surfaceflinger/ISurface.h
+++ b/include/gui/ISurface.h
@@ -14,8 +14,8 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_SF_ISURFACE_H
-#define ANDROID_SF_ISURFACE_H
+#ifndef ANDROID_GUI_ISURFACE_H
+#define ANDROID_GUI_ISURFACE_H
 
 #include <stdint.h>
 #include <sys/types.h>
@@ -61,4 +61,4 @@
 
 }; // namespace android
 
-#endif // ANDROID_SF_ISURFACE_H
+#endif // ANDROID_GUI_ISURFACE_H
diff --git a/include/surfaceflinger/ISurfaceComposer.h b/include/gui/ISurfaceComposer.h
similarity index 95%
rename from include/surfaceflinger/ISurfaceComposer.h
rename to include/gui/ISurfaceComposer.h
index 58fd89d..f3c0ecb 100644
--- a/include/surfaceflinger/ISurfaceComposer.h
+++ b/include/gui/ISurfaceComposer.h
@@ -14,8 +14,8 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_SF_ISURFACE_COMPOSER_H
-#define ANDROID_SF_ISURFACE_COMPOSER_H
+#ifndef ANDROID_GUI_ISURFACE_COMPOSER_H
+#define ANDROID_GUI_ISURFACE_COMPOSER_H
 
 #include <stdint.h>
 #include <sys/types.h>
@@ -27,8 +27,8 @@
 
 #include <ui/PixelFormat.h>
 
-#include <surfaceflinger/ISurfaceComposerClient.h>
-#include <surfaceflinger/IGraphicBufferAlloc.h>
+#include <gui/IGraphicBufferAlloc.h>
+#include <gui/ISurfaceComposerClient.h>
 
 namespace android {
 // ----------------------------------------------------------------------------
@@ -171,4 +171,4 @@
 
 }; // namespace android
 
-#endif // ANDROID_SF_ISURFACE_COMPOSER_H
+#endif // ANDROID_GUI_ISURFACE_COMPOSER_H
diff --git a/include/surfaceflinger/ISurfaceComposerClient.h b/include/gui/ISurfaceComposerClient.h
similarity index 92%
rename from include/surfaceflinger/ISurfaceComposerClient.h
rename to include/gui/ISurfaceComposerClient.h
index 02cabc1..c793933 100644
--- a/include/surfaceflinger/ISurfaceComposerClient.h
+++ b/include/gui/ISurfaceComposerClient.h
@@ -14,8 +14,8 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_SF_ISURFACE_COMPOSER_CLIENT_H
-#define ANDROID_SF_ISURFACE_COMPOSER_CLIENT_H
+#ifndef ANDROID_GUI_ISURFACE_COMPOSER_CLIENT_H
+#define ANDROID_GUI_ISURFACE_COMPOSER_CLIENT_H
 
 #include <stdint.h>
 #include <sys/types.h>
@@ -27,7 +27,7 @@
 
 #include <ui/PixelFormat.h>
 
-#include <surfaceflinger/ISurface.h>
+#include <gui/ISurface.h>
 
 namespace android {
 
@@ -81,4 +81,4 @@
 
 }; // namespace android
 
-#endif // ANDROID_SF_ISURFACE_COMPOSER_CLIENT_H
+#endif // ANDROID_GUI_ISURFACE_COMPOSER_CLIENT_H
diff --git a/include/surfaceflinger/Surface.h b/include/gui/Surface.h
similarity index 95%
rename from include/surfaceflinger/Surface.h
rename to include/gui/Surface.h
index 0460bbd..1f90c59 100644
--- a/include/surfaceflinger/Surface.h
+++ b/include/gui/Surface.h
@@ -14,8 +14,8 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_SF_SURFACE_H
-#define ANDROID_SF_SURFACE_H
+#ifndef ANDROID_GUI_SURFACE_H
+#define ANDROID_GUI_SURFACE_H
 
 #include <stdint.h>
 #include <sys/types.h>
@@ -26,12 +26,10 @@
 
 #include <ui/PixelFormat.h>
 #include <ui/Region.h>
-#include <ui/egl/android_natives.h>
 
 #include <gui/SurfaceTextureClient.h>
-
-#include <surfaceflinger/ISurface.h>
-#include <surfaceflinger/ISurfaceComposerClient.h>
+#include <gui/ISurface.h>
+#include <gui/ISurfaceComposerClient.h>
 
 #define ANDROID_VIEW_SURFACE_JNI_ID    "mNativeSurface"
 
@@ -174,4 +172,4 @@
 
 }; // namespace android
 
-#endif // ANDROID_SF_SURFACE_H
+#endif // ANDROID_GUI_SURFACE_H
diff --git a/include/surfaceflinger/SurfaceComposerClient.h b/include/gui/SurfaceComposerClient.h
similarity index 96%
rename from include/surfaceflinger/SurfaceComposerClient.h
rename to include/gui/SurfaceComposerClient.h
index 99affda..d971031 100644
--- a/include/surfaceflinger/SurfaceComposerClient.h
+++ b/include/gui/SurfaceComposerClient.h
@@ -14,8 +14,8 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_SF_SURFACE_COMPOSER_CLIENT_H
-#define ANDROID_SF_SURFACE_COMPOSER_CLIENT_H
+#ifndef ANDROID_GUI_SURFACE_COMPOSER_CLIENT_H
+#define ANDROID_GUI_SURFACE_COMPOSER_CLIENT_H
 
 #include <stdint.h>
 #include <sys/types.h>
@@ -29,7 +29,7 @@
 
 #include <ui/PixelFormat.h>
 
-#include <surfaceflinger/Surface.h>
+#include <gui/Surface.h>
 
 namespace android {
 
@@ -174,4 +174,4 @@
 // ---------------------------------------------------------------------------
 }; // namespace android
 
-#endif // ANDROID_SF_SURFACE_COMPOSER_CLIENT_H
+#endif // ANDROID_GUI_SURFACE_COMPOSER_CLIENT_H
diff --git a/include/gui/SurfaceTexture.h b/include/gui/SurfaceTexture.h
index dcab049..5531e53 100644
--- a/include/gui/SurfaceTexture.h
+++ b/include/gui/SurfaceTexture.h
@@ -153,8 +153,8 @@
     void setName(const String8& name);
 
     // dump our state in a String
-    void dump(String8& result) const;
-    void dump(String8& result, const char* prefix, char* buffer, size_t SIZE) const;
+    virtual void dump(String8& result) const;
+    virtual void dump(String8& result, const char* prefix, char* buffer, size_t SIZE) const;
 
 protected:
 
@@ -217,6 +217,56 @@
     // browser's tile cache exceeds.
     const GLenum mTexTarget;
 
+    // SurfaceTexture maintains EGL information about GraphicBuffers that corresponds
+    // directly with BufferQueue's buffers
+    struct EGLSlot {
+        EGLSlot()
+        : mEglImage(EGL_NO_IMAGE_KHR),
+          mEglDisplay(EGL_NO_DISPLAY),
+          mFence(EGL_NO_SYNC_KHR) {
+        }
+
+        sp<GraphicBuffer> mGraphicBuffer;
+
+        // mEglImage is the EGLImage created from mGraphicBuffer.
+        EGLImageKHR mEglImage;
+
+        // mEglDisplay is the EGLDisplay used to create mEglImage.
+        EGLDisplay mEglDisplay;
+
+        // 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;
+    };
+
+    EGLSlot mEGLSlots[NUM_BUFFER_SLOTS];
+
+    // mAbandoned indicates that the BufferQueue will no longer be used to
+    // consume images buffers pushed to it using the ISurfaceTexture interface.
+    // It is initialized to false, and set to true in the abandon method.  A
+    // BufferQueue that has been abandoned will return the NO_INIT error from
+    // all ISurfaceTexture methods capable of returning an error.
+    bool mAbandoned;
+
+    // mName is a string used to identify the SurfaceTexture in log messages.
+    // It can be set by the setName method.
+    String8 mName;
+
+    // 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.
+    mutable Mutex mMutex;
+
+    // mCurrentTexture is the buffer slot index of the buffer that is currently
+    // bound to the OpenGL texture. It is initialized to INVALID_BUFFER_SLOT,
+    // indicating that no buffer slot is currently bound to the texture. Note,
+    // however, that a value of INVALID_BUFFER_SLOT does not necessarily mean
+    // that no buffer is bound to the texture. A call to setBufferCount will
+    // reset mCurrentTexture to INVALID_BUFFER_SLOT.
+    int mCurrentTexture;
+
 };
 
 // ----------------------------------------------------------------------------
diff --git a/include/gui/SurfaceTextureClient.h b/include/gui/SurfaceTextureClient.h
index 971a1b8..aa7fe48 100644
--- a/include/gui/SurfaceTextureClient.h
+++ b/include/gui/SurfaceTextureClient.h
@@ -20,7 +20,7 @@
 #include <gui/ISurfaceTexture.h>
 #include <gui/SurfaceTexture.h>
 
-#include <ui/egl/android_natives.h>
+#include <ui/ANativeObjectBase.h>
 #include <ui/Region.h>
 
 #include <utils/RefBase.h>
@@ -31,7 +31,7 @@
 class Surface;
 
 class SurfaceTextureClient
-    : public EGLNativeBase<ANativeWindow, SurfaceTextureClient, RefBase>
+    : public ANativeObjectBase<ANativeWindow, SurfaceTextureClient, RefBase>
 {
 public:
     SurfaceTextureClient(const sp<ISurfaceTexture>& surfaceTexture);
diff --git a/include/media/AudioRecord.h b/include/media/AudioRecord.h
index 437a89c..b0c581a 100644
--- a/include/media/AudioRecord.h
+++ b/include/media/AudioRecord.h
@@ -225,7 +225,7 @@
 
     /* get sample rate for this record track
      */
-            uint32_t    getSampleRate();
+            uint32_t    getSampleRate() const;
 
     /* Sets marker position. When record reaches the number of frames specified,
      * a callback with event type EVENT_MARKER is called. Calling setMarkerPosition
@@ -242,7 +242,7 @@
      *  - INVALID_OPERATION: the AudioRecord has no callback installed.
      */
             status_t    setMarkerPosition(uint32_t marker);
-            status_t    getMarkerPosition(uint32_t *marker);
+            status_t    getMarkerPosition(uint32_t *marker) const;
 
 
     /* Sets position update period. Every time the number of frames specified has been recorded,
@@ -261,7 +261,7 @@
      *  - INVALID_OPERATION: the AudioRecord has no callback installed.
      */
             status_t    setPositionUpdatePeriod(uint32_t updatePeriod);
-            status_t    getPositionUpdatePeriod(uint32_t *updatePeriod);
+            status_t    getPositionUpdatePeriod(uint32_t *updatePeriod) const;
 
 
     /* Gets record head position. The position is the  total number of frames
@@ -275,7 +275,7 @@
      *  - NO_ERROR: successful operation
      *  - BAD_VALUE:  position is NULL
      */
-            status_t    getPosition(uint32_t *position);
+            status_t    getPosition(uint32_t *position) const;
 
     /* returns a handle on the audio input used by this AudioRecord.
      *
@@ -285,7 +285,7 @@
      * Returned value:
      *  handle on audio hardware input
      */
-            audio_io_handle_t    getInput();
+            audio_io_handle_t    getInput() const;
 
     /* returns the audio session ID associated to this AudioRecord.
      *
@@ -295,7 +295,7 @@
      * Returned value:
      *  AudioRecord session ID.
      */
-            int    getSessionId();
+            int    getSessionId() const;
 
     /* obtains a buffer of "frameCount" frames. The buffer must be
      * filled entirely. If the track is stopped, obtainBuffer() returns
@@ -326,7 +326,7 @@
      * Such loss typically occurs when the user space process is blocked longer than the capacity of audio driver buffers.
      * Unit: the number of input audio frames
      */
-            unsigned int  getInputFramesLost();
+            unsigned int  getInputFramesLost() const;
 
 private:
     /* copying audio tracks is not allowed */
@@ -360,7 +360,7 @@
     sp<IMemory>             mCblkMemory;
     sp<ClientRecordThread>  mClientRecordThread;
     status_t                mReadyToRun;
-    Mutex                   mLock;
+    mutable Mutex           mLock;
     Condition               mCondition;
 
     uint32_t                mFrameCount;
diff --git a/include/media/stagefright/ACodec.h b/include/media/stagefright/ACodec.h
index 70799a6..6735aff 100644
--- a/include/media/stagefright/ACodec.h
+++ b/include/media/stagefright/ACodec.h
@@ -49,7 +49,7 @@
     void initiateSetup(const sp<AMessage> &msg);
     void signalFlush();
     void signalResume();
-    void initiateShutdown();
+    void initiateShutdown(bool keepComponentAllocated = false);
 
     void initiateAllocateComponent(const sp<AMessage> &msg);
     void initiateConfigureComponent(const sp<AMessage> &msg);
@@ -61,6 +61,7 @@
 private:
     struct BaseState;
     struct UninitializedState;
+    struct LoadedState;
     struct LoadedToIdleState;
     struct IdleToExecutingState;
     struct ExecutingState;
@@ -107,6 +108,7 @@
     sp<AMessage> mNotify;
 
     sp<UninitializedState> mUninitializedState;
+    sp<LoadedState> mLoadedState;
     sp<LoadedToIdleState> mLoadedToIdleState;
     sp<IdleToExecutingState> mIdleToExecutingState;
     sp<ExecutingState> mExecutingState;
@@ -131,6 +133,12 @@
     bool mSentFormat;
     bool mIsEncoder;
 
+    bool mShutdownInProgress;
+
+    // If "mKeepComponentAllocated" we only transition back to Loaded state
+    // and do not release the component instance.
+    bool mKeepComponentAllocated;
+
     status_t allocateBuffersOnPort(OMX_U32 portIndex);
     status_t freeBuffersOnPort(OMX_U32 portIndex);
     status_t freeBuffer(OMX_U32 portIndex, size_t i);
diff --git a/include/media/stagefright/HardwareAPI.h b/include/media/stagefright/HardwareAPI.h
index 32eed3f..17efd35 100644
--- a/include/media/stagefright/HardwareAPI.h
+++ b/include/media/stagefright/HardwareAPI.h
@@ -19,7 +19,7 @@
 #define HARDWARE_API_H_
 
 #include <media/stagefright/OMXPluginBase.h>
-#include <ui/android_native_buffer.h>
+#include <system/window.h>
 #include <utils/RefBase.h>
 
 #include <OMX_Component.h>
diff --git a/include/media/stagefright/MediaCodec.h b/include/media/stagefright/MediaCodec.h
index 8c11c9c..72ac56a 100644
--- a/include/media/stagefright/MediaCodec.h
+++ b/include/media/stagefright/MediaCodec.h
@@ -53,8 +53,15 @@
             uint32_t flags);
 
     status_t start();
+
+    // Returns to a state in which the component remains allocated but
+    // unconfigured.
     status_t stop();
 
+    // Client MUST call release before releasing final reference to this
+    // object.
+    status_t release();
+
     status_t flush();
 
     status_t queueInputBuffer(
@@ -97,6 +104,7 @@
         STARTED,
         FLUSHING,
         STOPPING,
+        RELEASING,
     };
 
     enum {
@@ -109,6 +117,7 @@
         kWhatConfigure                  = 'conf',
         kWhatStart                      = 'strt',
         kWhatStop                       = 'stop',
+        kWhatRelease                    = 'rele',
         kWhatDequeueInputBuffer         = 'deqI',
         kWhatQueueInputBuffer           = 'queI',
         kWhatDequeueOutputBuffer        = 'deqO',
diff --git a/media/libstagefright/timedtext/TimedTextDriver.h b/include/media/stagefright/timedtext/TimedTextDriver.h
similarity index 100%
rename from media/libstagefright/timedtext/TimedTextDriver.h
rename to include/media/stagefright/timedtext/TimedTextDriver.h
diff --git a/include/private/surfaceflinger/LayerState.h b/include/private/gui/LayerState.h
similarity index 97%
rename from include/private/surfaceflinger/LayerState.h
rename to include/private/gui/LayerState.h
index 3eb5c99..ca277e0 100644
--- a/include/private/surfaceflinger/LayerState.h
+++ b/include/private/gui/LayerState.h
@@ -23,8 +23,7 @@
 #include <utils/Errors.h>
 
 #include <ui/Region.h>
-
-#include <surfaceflinger/ISurface.h>
+#include <gui/ISurface.h>
 
 namespace android {
 
diff --git a/include/private/surfaceflinger/SharedBufferStack.h b/include/private/gui/SharedBufferStack.h
similarity index 100%
rename from include/private/surfaceflinger/SharedBufferStack.h
rename to include/private/gui/SharedBufferStack.h
diff --git a/include/private/opengles/gl_context.h b/include/private/opengles/gl_context.h
deleted file mode 100644
index 6b1fa77..0000000
--- a/include/private/opengles/gl_context.h
+++ /dev/null
@@ -1,640 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_OPENGLES_CONTEXT_H
-#define ANDROID_OPENGLES_CONTEXT_H
-
-#include <stdint.h>
-#include <stddef.h>
-#include <sys/types.h>
-#include <pthread.h>
-#ifdef HAVE_ANDROID_OS
-#include <bionic_tls.h>
-#endif
-
-#include <private/pixelflinger/ggl_context.h>
-#include <hardware/gralloc.h>
-
-#include <GLES/gl.h>
-#include <GLES/glext.h>
-
-namespace android {
-
-
-const unsigned int OGLES_NUM_COMPRESSED_TEXTURE_FORMATS = 10
-#ifdef GL_OES_compressed_ETC1_RGB8_texture
-        + 1
-#endif
-        ;
-
-class EGLTextureObject;
-class EGLSurfaceManager;
-class EGLBufferObjectManager;
-
-namespace gl {
-
-struct ogles_context_t;
-struct matrixx_t;
-struct transform_t;
-struct buffer_t;
-
-ogles_context_t* getGlContext();
-
-template<typename T>
-static inline void swap(T& a, T& b) {
-    T t(a); a = b; b = t;
-}
-template<typename T>
-inline T max(T a, T b) {
-    return a<b ? b : a;
-}
-template<typename T>
-inline T max(T a, T b, T c) {
-    return max(a, max(b, c));
-}
-template<typename T>
-inline T min(T a, T b) {
-    return a<b ? a : b;
-}
-template<typename T>
-inline T min(T a, T b, T c) {
-    return min(a, min(b, c));
-}
-template<typename T>
-inline T min(T a, T b, T c, T d) {
-    return min(min(a,b), min(c,d));
-}
-
-// ----------------------------------------------------------------------------
-// vertices
-// ----------------------------------------------------------------------------
-
-struct vec3_t {
-    union {
-        struct { GLfixed x, y, z; };
-        struct { GLfixed r, g, b; };
-        struct { GLfixed S, T, R; };
-        GLfixed v[3];
-    };
-};
-
-struct vec4_t {
-    union {
-        struct { GLfixed x, y, z, w; };
-        struct { GLfixed r, g, b, a; };
-        struct { GLfixed S, T, R, Q; };
-        GLfixed v[4];
-    };
-};
-
-struct vertex_t {
-    enum {
-        // these constant matter for our clipping
-        CLIP_L          = 0x0001,   // clipping flags
-        CLIP_R          = 0x0002,
-        CLIP_B          = 0x0004,
-        CLIP_T          = 0x0008,
-        CLIP_N          = 0x0010,
-        CLIP_F          = 0x0020,
-
-        EYE             = 0x0040,
-        RESERVED        = 0x0080,
-
-        USER_CLIP_0     = 0x0100,   // user clipping flags
-        USER_CLIP_1     = 0x0200,
-        USER_CLIP_2     = 0x0400,
-        USER_CLIP_3     = 0x0800,
-        USER_CLIP_4     = 0x1000,
-        USER_CLIP_5     = 0x2000,
-
-        LIT             = 0x4000,   // lighting has been applied
-        TT              = 0x8000,   // texture coords transformed
-
-        FRUSTUM_CLIP_ALL= 0x003F,
-        USER_CLIP_ALL   = 0x3F00,
-        CLIP_ALL        = 0x3F3F,
-    };
-
-    // the fields below are arranged to minimize d-cache usage
-    // we group together, by cache-line, the fields most likely to be used
-
-    union {
-    vec4_t          obj;
-    vec4_t          eye;
-    };
-    vec4_t          clip;
-
-    uint32_t        flags;
-    size_t          index;  // cache tag, and vertex index
-    GLfixed         fog;
-    uint8_t         locked;
-    uint8_t         mru;
-    uint8_t         reserved[2];
-    vec4_t          window;
-
-    vec4_t          color;
-    vec4_t          texture[GGL_TEXTURE_UNIT_COUNT];
-    uint32_t        reserved1[4];
-
-    inline void clear() {
-        flags = index = locked = mru = 0;
-    }
-};
-
-struct point_size_t {
-    GGLcoord    size;
-    GLboolean   smooth;
-};
-
-struct line_width_t {
-    GGLcoord    width;
-    GLboolean   smooth;
-};
-
-struct polygon_offset_t {
-    GLfixed     factor;
-    GLfixed     units;
-    GLboolean   enable;
-};
-
-// ----------------------------------------------------------------------------
-// arrays
-// ----------------------------------------------------------------------------
-
-struct array_t {
-    typedef void (*fetcher_t)(ogles_context_t*, GLfixed*, const GLvoid*);
-    fetcher_t       fetch;
-    GLvoid const*   physical_pointer;
-    GLint           size;
-    GLsizei         stride;
-    GLvoid const*   pointer;
-    buffer_t const* bo;
-    uint16_t        type;
-    GLboolean       enable;
-    GLboolean       pad;
-    GLsizei         bounds;
-    void init(GLint, GLenum, GLsizei, const GLvoid *, const buffer_t*, GLsizei);
-    inline void resolve();
-    inline const GLubyte* element(GLint i) const {
-        return (const GLubyte*)physical_pointer + i * stride;
-    }
-};
-
-struct array_machine_t {
-    array_t         vertex;
-    array_t         normal;
-    array_t         color;
-    array_t         texture[GGL_TEXTURE_UNIT_COUNT];
-    uint8_t         activeTexture;
-    uint8_t         tmu;
-    uint16_t        cull;
-    uint32_t        flags;
-    GLenum          indicesType;
-    buffer_t const* array_buffer;
-    buffer_t const* element_array_buffer;
-
-    void (*compileElements)(ogles_context_t*, vertex_t*, GLint, GLsizei);
-    void (*compileElement)(ogles_context_t*, vertex_t*, GLint);
-
-    void (*mvp_transform)(transform_t const*, vec4_t*, vec4_t const*);
-    void (*mv_transform)(transform_t const*, vec4_t*, vec4_t const*);
-    void (*tex_transform[2])(transform_t const*, vec4_t*, vec4_t const*);
-    void (*perspective)(ogles_context_t*c, vertex_t* v);
-    void (*clipVertex)(ogles_context_t* c, vertex_t* nv,
-            GGLfixed t, const vertex_t* s, const vertex_t* p);
-    void (*clipEye)(ogles_context_t* c, vertex_t* nv,
-            GGLfixed t, const vertex_t* s, const vertex_t* p);
-};
-
-struct vertex_cache_t {
-    enum {
-        // must be at least 4
-        // 3 vertice for triangles
-        // or 2 + 2 for indexed triangles w/ cache contention
-        VERTEX_BUFFER_SIZE  = 8,
-        // must be a power of two and at least 3
-        VERTEX_CACHE_SIZE   = 64,   // 8 KB
-
-        INDEX_BITS      = 16,
-        INDEX_MASK      = ((1LU<<INDEX_BITS)-1),
-        INDEX_SEQ       = 1LU<<INDEX_BITS,
-    };
-    vertex_t*       vBuffer;
-    vertex_t*       vCache;
-    uint32_t        sequence;
-    void*           base;
-    uint32_t        total;
-    uint32_t        misses;
-    int64_t         startTime;
-    void init();
-    void uninit();
-    void clear();
-    void dump_stats(GLenum mode);
-};
-
-// ----------------------------------------------------------------------------
-// fog
-// ----------------------------------------------------------------------------
-
-struct fog_t {
-    GLfixed     density;
-    GLfixed     start;
-    GLfixed     end;
-    GLfixed     invEndMinusStart;
-    GLenum      mode;
-    GLfixed     (*fog)(ogles_context_t* c, GLfixed z);
-};
-
-// ----------------------------------------------------------------------------
-// user clip planes
-// ----------------------------------------------------------------------------
-
-const unsigned int OGLES_MAX_CLIP_PLANES = 6;
-
-struct clip_plane_t {
-    vec4_t      equation;
-};
-
-struct user_clip_planes_t {
-    clip_plane_t    plane[OGLES_MAX_CLIP_PLANES];
-    uint32_t        enable;
-};
-
-// ----------------------------------------------------------------------------
-// lighting
-// ----------------------------------------------------------------------------
-
-const unsigned int OGLES_MAX_LIGHTS = 8;
-
-struct light_t {
-    vec4_t      ambient;
-    vec4_t      diffuse;
-    vec4_t      specular;
-    vec4_t      implicitAmbient;
-    vec4_t      implicitDiffuse;
-    vec4_t      implicitSpecular;
-    vec4_t      position;       // position in eye space
-    vec4_t      objPosition;
-    vec4_t      normalizedObjPosition;
-    vec4_t      spotDir;
-    vec4_t      normalizedSpotDir;
-    GLfixed     spotExp;
-    GLfixed     spotCutoff;
-    GLfixed     spotCutoffCosine;
-    GLfixed     attenuation[3];
-    GLfixed     rConstAttenuation;
-    GLboolean   enable;
-};
-
-struct material_t {
-    vec4_t      ambient;
-    vec4_t      diffuse;
-    vec4_t      specular;
-    vec4_t      emission;
-    GLfixed     shininess;
-};
-
-struct light_model_t {
-    vec4_t      ambient;
-    GLboolean   twoSide;
-};
-
-struct color_material_t {
-    GLenum      face;
-    GLenum      mode;
-    GLboolean   enable;
-};
-
-struct lighting_t {
-    light_t             lights[OGLES_MAX_LIGHTS];
-    material_t          front;
-    light_model_t       lightModel;
-    color_material_t    colorMaterial;
-    vec4_t              implicitSceneEmissionAndAmbient;
-    vec4_t              objViewer;
-    uint32_t            enabledLights;
-    GLboolean           enable;
-    GLenum              shadeModel;
-    typedef void (*light_fct_t)(ogles_context_t*, vertex_t*);
-    void (*lightVertex)(ogles_context_t* c, vertex_t* v);
-    void (*lightTriangle)(ogles_context_t* c,
-            vertex_t* v0, vertex_t* v1, vertex_t* v2);
-};
-
-struct culling_t {
-    GLenum      cullFace;
-    GLenum      frontFace;
-    GLboolean   enable;
-};
-
-// ----------------------------------------------------------------------------
-// textures
-// ----------------------------------------------------------------------------
-
-struct texture_unit_t {
-    GLuint              name;
-    EGLTextureObject*   texture;
-    uint8_t             dirty;
-};
-
-struct texture_state_t
-{
-    texture_unit_t      tmu[GGL_TEXTURE_UNIT_COUNT];
-    int                 active;     // active tmu
-    EGLTextureObject*   defaultTexture;
-    GGLContext*         ggl;
-    uint8_t             packAlignment;
-    uint8_t             unpackAlignment;
-};
-
-// ----------------------------------------------------------------------------
-// transformation and matrices
-// ----------------------------------------------------------------------------
-
-struct matrixf_t;
-
-struct matrixx_t {
-    GLfixed m[16];
-    void load(const matrixf_t& rhs);
-};
-
-struct matrix_stack_t;
-
-
-struct matrixf_t {
-    void loadIdentity();
-    void load(const matrixf_t& rhs);
-
-    inline GLfloat* editElements() { return m; }
-    inline GLfloat const* elements() const { return m; }
-
-    void set(const GLfixed* rhs);
-    void set(const GLfloat* rhs);
-
-    static void multiply(matrixf_t& r,
-            const matrixf_t& lhs, const matrixf_t& rhs);
-
-    void dump(const char* what);
-
-private:
-    friend struct matrix_stack_t;
-    GLfloat     m[16];
-    void load(const GLfixed* rhs);
-    void load(const GLfloat* rhs);
-    void multiply(const matrixf_t& rhs);
-    void translate(GLfloat x, GLfloat y, GLfloat z);
-    void scale(GLfloat x, GLfloat y, GLfloat z);
-    void rotate(GLfloat a, GLfloat x, GLfloat y, GLfloat z);
-};
-
-enum {
-    OP_IDENTITY         = 0x00,
-    OP_TRANSLATE        = 0x01,
-    OP_UNIFORM_SCALE    = 0x02,
-    OP_SCALE            = 0x05,
-    OP_ROTATE           = 0x08,
-    OP_SKEW             = 0x10,
-    OP_ALL              = 0x1F
-};
-
-struct transform_t {
-    enum {
-        FLAGS_2D_PROJECTION = 0x1
-    };
-    matrixx_t       matrix;
-    uint32_t        flags;
-    uint32_t        ops;
-
-    union {
-        struct {
-            void (*point2)(transform_t const* t, vec4_t*, vec4_t const*);
-            void (*point3)(transform_t const* t, vec4_t*, vec4_t const*);
-            void (*point4)(transform_t const* t, vec4_t*, vec4_t const*);
-        };
-        void (*pointv[3])(transform_t const* t, vec4_t*, vec4_t const*);
-    };
-
-    void loadIdentity();
-    void picker();
-    void dump(const char* what);
-};
-
-struct mvui_transform_t : public transform_t
-{
-    void picker();
-};
-
-struct matrix_stack_t {
-    enum {
-        DO_PICKER           = 0x1,
-        DO_FLOAT_TO_FIXED   = 0x2
-    };
-    transform_t     transform;
-    uint8_t         maxDepth;
-    uint8_t         depth;
-    uint8_t         dirty;
-    uint8_t         reserved;
-    matrixf_t       *stack;
-    uint8_t         *ops;
-    void init(int depth);
-    void uninit();
-    void loadIdentity();
-    void load(const GLfixed* rhs);
-    void load(const GLfloat* rhs);
-    void multiply(const matrixf_t& rhs);
-    void translate(GLfloat x, GLfloat y, GLfloat z);
-    void scale(GLfloat x, GLfloat y, GLfloat z);
-    void rotate(GLfloat a, GLfloat x, GLfloat y, GLfloat z);
-    GLint push();
-    GLint pop();
-    void validate();
-    matrixf_t& top() { return stack[depth]; }
-    const matrixf_t& top() const { return stack[depth]; }
-    uint32_t top_ops() const { return ops[depth]; }
-    inline bool isRigidBody() const {
-        return !(ops[depth] & ~(OP_TRANSLATE|OP_UNIFORM_SCALE|OP_ROTATE));
-    }
-};
-
-struct vp_transform_t {
-    transform_t     transform;
-    matrixf_t       matrix;
-    GLfloat         zNear;
-    GLfloat         zFar;
-    void loadIdentity();
-};
-
-struct transform_state_t {
-    enum {
-        MODELVIEW           = 0x01,
-        PROJECTION          = 0x02,
-        VIEWPORT            = 0x04,
-        TEXTURE             = 0x08,
-        MVUI                = 0x10,
-        MVIT                = 0x20,
-        MVP                 = 0x40,
-    };
-    matrix_stack_t      *current;
-    matrix_stack_t      modelview;
-    matrix_stack_t      projection;
-    matrix_stack_t      texture[GGL_TEXTURE_UNIT_COUNT];
-
-    // modelview * projection
-    transform_t         mvp     __attribute__((aligned(32)));
-    // viewport transformation
-    vp_transform_t      vpt     __attribute__((aligned(32)));
-    // same for 4-D vertices
-    transform_t         mvp4;
-    // full modelview inverse transpose
-    transform_t         mvit4;
-    // upper 3x3 of mv-inverse-transpose (for normals)
-    mvui_transform_t    mvui;
-
-    GLenum              matrixMode;
-    GLenum              rescaleNormals;
-    uint32_t            dirty;
-    void invalidate();
-    void update_mvp();
-    void update_mvit();
-    void update_mvui();
-};
-
-struct viewport_t {
-    GLint       x;
-    GLint       y;
-    GLsizei     w;
-    GLsizei     h;
-    struct {
-        GLint       x;
-        GLint       y;
-    } surfaceport;
-    struct {
-        GLint       x;
-        GLint       y;
-        GLsizei     w;
-        GLsizei     h;
-    } scissor;
-};
-
-// ----------------------------------------------------------------------------
-// Lerping
-// ----------------------------------------------------------------------------
-
-struct compute_iterators_t
-{
-    void initTriangle(
-            vertex_t const* v0,
-            vertex_t const* v1,
-            vertex_t const* v2);
-
-    void initLine(
-            vertex_t const* v0,
-            vertex_t const* v1);
-
-    inline void initLerp(vertex_t const* v0, uint32_t enables);
-
-    int iteratorsScale(int32_t it[3],
-            int32_t c0, int32_t c1, int32_t c2) const;
-
-    void iterators1616(GGLfixed it[3],
-            GGLfixed c0, GGLfixed c1, GGLfixed c2) const;
-
-    void iterators0032(int32_t it[3],
-            int32_t c0, int32_t c1, int32_t c2) const;
-
-    void iterators0032(int64_t it[3],
-            int32_t c0, int32_t c1, int32_t c2) const;
-
-    GGLcoord area() const { return m_area; }
-
-private:
-    // don't change order of members here -- used by iterators.S
-    GGLcoord m_dx01, m_dy10, m_dx20, m_dy02;
-    GGLcoord m_x0, m_y0;
-    GGLcoord m_area;
-    uint8_t m_scale;
-    uint8_t m_area_scale;
-    uint8_t m_reserved[2];
-
-};
-
-// ----------------------------------------------------------------------------
-// state
-// ----------------------------------------------------------------------------
-
-#ifdef HAVE_ANDROID_OS
-    // We have a dedicated TLS slot in bionic
-    inline void setGlThreadSpecific(ogles_context_t *value) {
-        ((uint32_t *)__get_tls())[TLS_SLOT_OPENGL] = (uint32_t)value;
-    }
-    inline ogles_context_t* getGlThreadSpecific() {
-        return (ogles_context_t *)(((unsigned *)__get_tls())[TLS_SLOT_OPENGL]);
-    }
-#else
-    extern pthread_key_t gGLKey;
-    inline void setGlThreadSpecific(ogles_context_t *value) {
-        pthread_setspecific(gGLKey, value);
-    }
-    inline ogles_context_t* getGlThreadSpecific() {
-        return static_cast<ogles_context_t*>(pthread_getspecific(gGLKey));
-    }
-#endif
-
-
-struct prims_t {
-    typedef ogles_context_t* GL;
-    void (*renderPoint)(GL, vertex_t*);
-    void (*renderLine)(GL, vertex_t*, vertex_t*);
-    void (*renderTriangle)(GL, vertex_t*, vertex_t*, vertex_t*);
-};
-
-struct ogles_context_t {
-    context_t               rasterizer;
-    array_machine_t         arrays         __attribute__((aligned(32)));
-    texture_state_t         textures;
-    transform_state_t       transforms;
-    vertex_cache_t          vc;
-    prims_t                 prims;
-    culling_t               cull;
-    lighting_t              lighting;
-    user_clip_planes_t      clipPlanes;
-    compute_iterators_t     lerp;           __attribute__((aligned(32)));
-    vertex_t                current;
-    vec4_t                  currentColorClamped;
-    vec3_t                  currentNormal;
-    viewport_t              viewport;
-    point_size_t            point;
-    line_width_t            line;
-    polygon_offset_t        polygonOffset;
-    fog_t                   fog;
-    uint32_t                perspective : 1;
-    uint32_t                transformTextures : 1;
-    EGLSurfaceManager*      surfaceManager;
-    EGLBufferObjectManager* bufferObjectManager;
-
-    GLenum                  error;
-
-    static inline ogles_context_t* get() {
-        return getGlThreadSpecific();
-    }
-
-};
-
-}; // namespace gl
-}; // namespace android
-
-#endif // ANDROID_OPENGLES_CONTEXT_H
-
diff --git a/include/ui/egl/android_natives.h b/include/ui/ANativeObjectBase.h
similarity index 84%
rename from include/ui/egl/android_natives.h
rename to include/ui/ANativeObjectBase.h
index 9ac50a5..76e850f 100644
--- a/include/ui/egl/android_natives.h
+++ b/include/ui/ANativeObjectBase.h
@@ -22,8 +22,7 @@
 
 #include <hardware/gralloc.h>
 #include <system/window.h>
-// FIXME: remove this header, it's for legacy use.  native_window is pulled from frameworks/base/native/include/android/
-#include <android/native_window.h>
+
 // ---------------------------------------------------------------------------
 
 /* FIXME: this is legacy for pixmaps */
@@ -52,11 +51,11 @@
 namespace android {
 
 /*
- * This helper class turns an EGL android_native_xxx type into a C++
+ * This helper class turns a ANativeXXX object type into a C++
  * reference-counted object; with proper type conversions.
  */
 template <typename NATIVE_TYPE, typename TYPE, typename REF>
-class EGLNativeBase : public NATIVE_TYPE, public REF
+class ANativeObjectBase : public NATIVE_TYPE, public REF
 {
 public:
     // Disambiguate between the incStrong in REF and NATIVE_TYPE
@@ -68,8 +67,8 @@
     }
 
 protected:
-    typedef EGLNativeBase<NATIVE_TYPE, TYPE, REF> BASE;
-    EGLNativeBase() : NATIVE_TYPE(), REF() {
+    typedef ANativeObjectBase<NATIVE_TYPE, TYPE, REF> BASE;
+    ANativeObjectBase() : NATIVE_TYPE(), REF() {
         NATIVE_TYPE::common.incRef = incRef;
         NATIVE_TYPE::common.decRef = decRef;
     }
@@ -86,11 +85,11 @@
         return getSelf(reinterpret_cast<NATIVE_TYPE const*>(base));
     }
     static void incRef(android_native_base_t* base) {
-        EGLNativeBase* self = getSelf(base);
+        ANativeObjectBase* self = getSelf(base);
         self->incStrong(self);
     }
     static void decRef(android_native_base_t* base) {
-        EGLNativeBase* self = getSelf(base);
+        ANativeObjectBase* self = getSelf(base);
         self->decStrong(self);
     }
 };
diff --git a/include/ui/EGLNativeSurface.h b/include/ui/EGLNativeSurface.h
deleted file mode 100644
index 7964e7c..0000000
--- a/include/ui/EGLNativeSurface.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_EGL_NATIVE_SURFACE_H
-#define ANDROID_EGL_NATIVE_SURFACE_H
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <cutils/atomic.h>
-#include <utils/RefBase.h>
-
-#include <EGL/eglnatives.h>
-
-// ---------------------------------------------------------------------------
-namespace android {
-// ---------------------------------------------------------------------------
-
-template <class TYPE>
-class EGLNativeSurface : public egl_native_window_t, public LightRefBase<TYPE>
-{
-public:
-    EGLNativeSurface() { 
-        memset(egl_native_window_t::reserved, 0, 
-                sizeof(egl_native_window_t::reserved));
-        memset(egl_native_window_t::reserved_proc, 0, 
-                sizeof(egl_native_window_t::reserved_proc));
-        memset(egl_native_window_t::oem, 0, 
-                sizeof(egl_native_window_t::oem));
-    }
-protected:
-    EGLNativeSurface& operator = (const EGLNativeSurface& rhs);
-    EGLNativeSurface(const EGLNativeSurface& rhs);
-    inline ~EGLNativeSurface() { };
-};
-
-// ---------------------------------------------------------------------------
-}; // namespace android
-// ---------------------------------------------------------------------------
-
-#endif // ANDROID_EGL_SURFACE_H
-
diff --git a/include/ui/EGLUtils.h b/include/ui/EGLUtils.h
deleted file mode 100644
index a5bff81..0000000
--- a/include/ui/EGLUtils.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2009 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_UI_EGLUTILS_H
-#define ANDROID_UI_EGLUTILS_H
-
-#include <utils/Errors.h>
-#include <ui/PixelFormat.h>
-#include <EGL/egl.h>
-
-
-// ----------------------------------------------------------------------------
-namespace android {
-// ----------------------------------------------------------------------------
-
-class EGLUtils
-{
-public:
-
-    static const char *strerror(EGLint err);
-
-    static status_t selectConfigForPixelFormat(
-            EGLDisplay dpy,
-            EGLint const* attrs,
-            PixelFormat format,
-            EGLConfig* outConfig);
-
-    static status_t selectConfigForNativeWindow(
-            EGLDisplay dpy,
-            EGLint const* attrs,
-            EGLNativeWindowType window,
-            EGLConfig* outConfig);
-};
-
-// ----------------------------------------------------------------------------
-}; // namespace android
-// ----------------------------------------------------------------------------
-
-#endif /* ANDROID_UI_EGLUTILS_H */
diff --git a/include/ui/FramebufferNativeWindow.h b/include/ui/FramebufferNativeWindow.h
index 302d012..b202b95 100644
--- a/include/ui/FramebufferNativeWindow.h
+++ b/include/ui/FramebufferNativeWindow.h
@@ -24,12 +24,10 @@
 
 #include <utils/threads.h>
 #include <utils/String8.h>
+
+#include <ui/ANativeObjectBase.h>
 #include <ui/Rect.h>
 
-#include <pixelflinger/pixelflinger.h>
-
-#include <ui/egl/android_natives.h>
-
 #define NUM_FRAME_BUFFERS  2
 
 extern "C" EGLNativeWindowType android_createDisplaySurface(void);
@@ -44,7 +42,7 @@
 // ---------------------------------------------------------------------------
 
 class FramebufferNativeWindow 
-    : public EGLNativeBase<
+    : public ANativeObjectBase<
         ANativeWindow, 
         FramebufferNativeWindow, 
         LightRefBase<FramebufferNativeWindow> >
diff --git a/include/ui/GraphicBuffer.h b/include/ui/GraphicBuffer.h
index 6ab01f4..f318cd8 100644
--- a/include/ui/GraphicBuffer.h
+++ b/include/ui/GraphicBuffer.h
@@ -20,11 +20,11 @@
 #include <stdint.h>
 #include <sys/types.h>
 
-#include <ui/android_native_buffer.h>
+#include <ui/ANativeObjectBase.h>
 #include <ui/PixelFormat.h>
 #include <ui/Rect.h>
 #include <utils/Flattenable.h>
-#include <pixelflinger/pixelflinger.h>
+
 
 struct ANativeWindowBuffer;
 
@@ -37,7 +37,7 @@
 // ===========================================================================
 
 class GraphicBuffer
-    : public EGLNativeBase<
+    : public ANativeObjectBase<
         ANativeWindowBuffer,
         GraphicBuffer, 
         LightRefBase<GraphicBuffer> >, public Flattenable
@@ -93,7 +93,6 @@
 
     status_t lock(uint32_t usage, void** vaddr);
     status_t lock(uint32_t usage, const Rect& rect, void** vaddr);
-    status_t lock(GGLSurface* surface, uint32_t usage);
     status_t unlock();
 
     ANativeWindowBuffer* getNativeBuffer() const;
diff --git a/include/ui/PixelFormat.h b/include/ui/PixelFormat.h
index fc260c4..9f3e267 100644
--- a/include/ui/PixelFormat.h
+++ b/include/ui/PixelFormat.h
@@ -64,9 +64,6 @@
     PIXEL_FORMAT_RGBA_5551   = HAL_PIXEL_FORMAT_RGBA_5551,  // 16-bit ARGB
     PIXEL_FORMAT_RGBA_4444   = HAL_PIXEL_FORMAT_RGBA_4444,  // 16-bit ARGB
     PIXEL_FORMAT_A_8         = 8,                           // 8-bit A
-
-    // New formats can be added if they're also defined in
-    // pixelflinger/format.h
 };
 
 typedef int32_t PixelFormat;
@@ -80,10 +77,12 @@
     };
 
     enum { // components
-        ALPHA               = 1,
-        RGB                 = 2,
-        RGBA                = 3,
-        OTHER               = 0xFF
+        ALPHA   = 1,
+        RGB     = 2,
+        RGBA    = 3,
+        L       = 4,
+        LA      = 5,
+        OTHER   = 0xFF
     };
 
     struct szinfo {
diff --git a/include/utils/AndroidThreads.h b/include/utils/AndroidThreads.h
new file mode 100644
index 0000000..f9f7aa4
--- /dev/null
+++ b/include/utils/AndroidThreads.h
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _LIBS_UTILS_ANDROID_THREADS_H
+#define _LIBS_UTILS_ANDROID_THREADS_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#if defined(HAVE_PTHREADS)
+# include <pthread.h>
+#endif
+
+#include <utils/ThreadDefs.h>
+
+// ---------------------------------------------------------------------------
+// C API
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Create and run a new thread.
+extern int androidCreateThread(android_thread_func_t, void *);
+
+// Create thread with lots of parameters
+extern int androidCreateThreadEtc(android_thread_func_t entryFunction,
+                                  void *userData,
+                                  const char* threadName,
+                                  int32_t threadPriority,
+                                  size_t threadStackSize,
+                                  android_thread_id_t *threadId);
+
+// Get some sort of unique identifier for the current thread.
+extern android_thread_id_t androidGetThreadId();
+
+// Low-level thread creation -- never creates threads that can
+// interact with the Java VM.
+extern int androidCreateRawThreadEtc(android_thread_func_t entryFunction,
+                                     void *userData,
+                                     const char* threadName,
+                                     int32_t threadPriority,
+                                     size_t threadStackSize,
+                                     android_thread_id_t *threadId);
+
+// Used by the Java Runtime to control how threads are created, so that
+// they can be proper and lovely Java threads.
+typedef int (*android_create_thread_fn)(android_thread_func_t entryFunction,
+                                        void *userData,
+                                        const char* threadName,
+                                        int32_t threadPriority,
+                                        size_t threadStackSize,
+                                        android_thread_id_t *threadId);
+
+extern void androidSetCreateThreadFunc(android_create_thread_fn func);
+
+// ------------------------------------------------------------------
+// Extra functions working with raw pids.
+
+// Get pid for the current thread.
+extern pid_t androidGetTid();
+
+// Change the scheduling group of a particular thread.  The group
+// should be one of the ANDROID_TGROUP constants.  Returns BAD_VALUE if
+// grp is out of range, else another non-zero value with errno set if
+// the operation failed.  Thread ID zero means current thread.
+extern int androidSetThreadSchedulingGroup(pid_t tid, int grp);
+
+// Change the priority AND scheduling group of a particular thread.  The priority
+// should be one of the ANDROID_PRIORITY constants.  Returns INVALID_OPERATION
+// if the priority set failed, else another value if just the group set failed;
+// in either case errno is set.  Thread ID zero means current thread.
+extern int androidSetThreadPriority(pid_t tid, int prio);
+
+// Get the current priority of a particular thread. Returns one of the
+// ANDROID_PRIORITY constants or a negative result in case of error.
+extern int androidGetThreadPriority(pid_t tid);
+
+// Get the current scheduling group of a particular thread. Normally returns
+// one of the ANDROID_TGROUP constants other than ANDROID_TGROUP_DEFAULT.
+// Returns ANDROID_TGROUP_DEFAULT if no pthread support (e.g. on host) or if
+// scheduling groups are disabled.  Returns INVALID_OPERATION if unexpected error.
+// Thread ID zero means current thread.
+extern int androidGetThreadSchedulingGroup(pid_t tid);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+// ----------------------------------------------------------------------------
+// C++ API
+#ifdef __cplusplus
+namespace android {
+// ----------------------------------------------------------------------------
+
+// Create and run a new thread.
+inline bool createThread(thread_func_t f, void *a) {
+    return androidCreateThread(f, a) ? true : false;
+}
+
+// Create thread with lots of parameters
+inline bool createThreadEtc(thread_func_t entryFunction,
+                            void *userData,
+                            const char* threadName = "android:unnamed_thread",
+                            int32_t threadPriority = PRIORITY_DEFAULT,
+                            size_t threadStackSize = 0,
+                            thread_id_t *threadId = 0)
+{
+    return androidCreateThreadEtc(entryFunction, userData, threadName,
+        threadPriority, threadStackSize, threadId) ? true : false;
+}
+
+// Get some sort of unique identifier for the current thread.
+inline thread_id_t getThreadId() {
+    return androidGetThreadId();
+}
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+#endif  // __cplusplus
+// ----------------------------------------------------------------------------
+
+#endif // _LIBS_UTILS_ANDROID_THREADS_H
diff --git a/include/utils/Condition.h b/include/utils/Condition.h
new file mode 100644
index 0000000..8852d53
--- /dev/null
+++ b/include/utils/Condition.h
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _LIBS_UTILS_CONDITION_H
+#define _LIBS_UTILS_CONDITION_H
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <time.h>
+
+#if defined(HAVE_PTHREADS)
+# include <pthread.h>
+#endif
+
+#include <utils/Errors.h>
+#include <utils/Mutex.h>
+#include <utils/Timers.h>
+
+// ---------------------------------------------------------------------------
+namespace android {
+// ---------------------------------------------------------------------------
+
+/*
+ * Condition variable class.  The implementation is system-dependent.
+ *
+ * Condition variables are paired up with mutexes.  Lock the mutex,
+ * call wait(), then either re-wait() if things aren't quite what you want,
+ * or unlock the mutex and continue.  All threads calling wait() must
+ * use the same mutex for a given Condition.
+ */
+class Condition {
+public:
+    enum {
+        PRIVATE = 0,
+        SHARED = 1
+    };
+
+    Condition();
+    Condition(int type);
+    ~Condition();
+    // Wait on the condition variable.  Lock the mutex before calling.
+    status_t wait(Mutex& mutex);
+    // same with relative timeout
+    status_t waitRelative(Mutex& mutex, nsecs_t reltime);
+    // Signal the condition variable, allowing one thread to continue.
+    void signal();
+    // Signal the condition variable, allowing all threads to continue.
+    void broadcast();
+
+private:
+#if defined(HAVE_PTHREADS)
+    pthread_cond_t mCond;
+#else
+    void*   mState;
+#endif
+};
+
+// ---------------------------------------------------------------------------
+
+#if defined(HAVE_PTHREADS)
+
+inline Condition::Condition() {
+    pthread_cond_init(&mCond, NULL);
+}
+inline Condition::Condition(int type) {
+    if (type == SHARED) {
+        pthread_condattr_t attr;
+        pthread_condattr_init(&attr);
+        pthread_condattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
+        pthread_cond_init(&mCond, &attr);
+        pthread_condattr_destroy(&attr);
+    } else {
+        pthread_cond_init(&mCond, NULL);
+    }
+}
+inline Condition::~Condition() {
+    pthread_cond_destroy(&mCond);
+}
+inline status_t Condition::wait(Mutex& mutex) {
+    return -pthread_cond_wait(&mCond, &mutex.mMutex);
+}
+inline status_t Condition::waitRelative(Mutex& mutex, nsecs_t reltime) {
+#if defined(HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE)
+    struct timespec ts;
+    ts.tv_sec  = reltime/1000000000;
+    ts.tv_nsec = reltime%1000000000;
+    return -pthread_cond_timedwait_relative_np(&mCond, &mutex.mMutex, &ts);
+#else // HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE
+    struct timespec ts;
+#if defined(HAVE_POSIX_CLOCKS)
+    clock_gettime(CLOCK_REALTIME, &ts);
+#else // HAVE_POSIX_CLOCKS
+    // we don't support the clocks here.
+    struct timeval t;
+    gettimeofday(&t, NULL);
+    ts.tv_sec = t.tv_sec;
+    ts.tv_nsec= t.tv_usec*1000;
+#endif // HAVE_POSIX_CLOCKS
+    ts.tv_sec += reltime/1000000000;
+    ts.tv_nsec+= reltime%1000000000;
+    if (ts.tv_nsec >= 1000000000) {
+        ts.tv_nsec -= 1000000000;
+        ts.tv_sec  += 1;
+    }
+    return -pthread_cond_timedwait(&mCond, &mutex.mMutex, &ts);
+#endif // HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE
+}
+inline void Condition::signal() {
+    pthread_cond_signal(&mCond);
+}
+inline void Condition::broadcast() {
+    pthread_cond_broadcast(&mCond);
+}
+
+#endif // HAVE_PTHREADS
+
+// ---------------------------------------------------------------------------
+}; // namespace android
+// ---------------------------------------------------------------------------
+
+#endif // _LIBS_UTILS_CONDITON_H
diff --git a/include/utils/Mutex.h b/include/utils/Mutex.h
new file mode 100644
index 0000000..de6fb39
--- /dev/null
+++ b/include/utils/Mutex.h
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _LIBS_UTILS_MUTEX_H
+#define _LIBS_UTILS_MUTEX_H
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <time.h>
+
+#if defined(HAVE_PTHREADS)
+# include <pthread.h>
+#endif
+
+#include <utils/Errors.h>
+
+// ---------------------------------------------------------------------------
+namespace android {
+// ---------------------------------------------------------------------------
+
+class Condition;
+
+/*
+ * Simple mutex class.  The implementation is system-dependent.
+ *
+ * The mutex must be unlocked by the thread that locked it.  They are not
+ * recursive, i.e. the same thread can't lock it multiple times.
+ */
+class Mutex {
+public:
+    enum {
+        PRIVATE = 0,
+        SHARED = 1
+    };
+    
+                Mutex();
+                Mutex(const char* name);
+                Mutex(int type, const char* name = NULL);
+                ~Mutex();
+
+    // lock or unlock the mutex
+    status_t    lock();
+    void        unlock();
+
+    // lock if possible; returns 0 on success, error otherwise
+    status_t    tryLock();
+
+    // Manages the mutex automatically. It'll be locked when Autolock is
+    // constructed and released when Autolock goes out of scope.
+    class Autolock {
+    public:
+        inline Autolock(Mutex& mutex) : mLock(mutex)  { mLock.lock(); }
+        inline Autolock(Mutex* mutex) : mLock(*mutex) { mLock.lock(); }
+        inline ~Autolock() { mLock.unlock(); }
+    private:
+        Mutex& mLock;
+    };
+
+private:
+    friend class Condition;
+    
+    // A mutex cannot be copied
+                Mutex(const Mutex&);
+    Mutex&      operator = (const Mutex&);
+    
+#if defined(HAVE_PTHREADS)
+    pthread_mutex_t mMutex;
+#else
+    void    _init();
+    void*   mState;
+#endif
+};
+
+// ---------------------------------------------------------------------------
+
+#if defined(HAVE_PTHREADS)
+
+inline Mutex::Mutex() {
+    pthread_mutex_init(&mMutex, NULL);
+}
+inline Mutex::Mutex(const char* name) {
+    pthread_mutex_init(&mMutex, NULL);
+}
+inline Mutex::Mutex(int type, const char* name) {
+    if (type == SHARED) {
+        pthread_mutexattr_t attr;
+        pthread_mutexattr_init(&attr);
+        pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
+        pthread_mutex_init(&mMutex, &attr);
+        pthread_mutexattr_destroy(&attr);
+    } else {
+        pthread_mutex_init(&mMutex, NULL);
+    }
+}
+inline Mutex::~Mutex() {
+    pthread_mutex_destroy(&mMutex);
+}
+inline status_t Mutex::lock() {
+    return -pthread_mutex_lock(&mMutex);
+}
+inline void Mutex::unlock() {
+    pthread_mutex_unlock(&mMutex);
+}
+inline status_t Mutex::tryLock() {
+    return -pthread_mutex_trylock(&mMutex);
+}
+
+#endif // HAVE_PTHREADS
+
+// ---------------------------------------------------------------------------
+
+/*
+ * Automatic mutex.  Declare one of these at the top of a function.
+ * When the function returns, it will go out of scope, and release the
+ * mutex.
+ */
+ 
+typedef Mutex::Autolock AutoMutex;
+
+// ---------------------------------------------------------------------------
+}; // namespace android
+// ---------------------------------------------------------------------------
+
+#endif // _LIBS_UTILS_MUTEX_H
diff --git a/include/utils/RWLock.h b/include/utils/RWLock.h
new file mode 100644
index 0000000..a5abea2
--- /dev/null
+++ b/include/utils/RWLock.h
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _LIBS_UTILS_RWLOCK_H
+#define _LIBS_UTILS_RWLOCK_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#if defined(HAVE_PTHREADS)
+# include <pthread.h>
+#endif
+
+#include <utils/Errors.h>
+#include <utils/ThreadDefs.h>
+
+// ---------------------------------------------------------------------------
+namespace android {
+// ---------------------------------------------------------------------------
+
+#if defined(HAVE_PTHREADS)
+
+/*
+ * Simple mutex class.  The implementation is system-dependent.
+ *
+ * The mutex must be unlocked by the thread that locked it.  They are not
+ * recursive, i.e. the same thread can't lock it multiple times.
+ */
+class RWLock {
+public:
+    enum {
+        PRIVATE = 0,
+        SHARED = 1
+    };
+
+                RWLock();
+                RWLock(const char* name);
+                RWLock(int type, const char* name = NULL);
+                ~RWLock();
+
+    status_t    readLock();
+    status_t    tryReadLock();
+    status_t    writeLock();
+    status_t    tryWriteLock();
+    void        unlock();
+
+    class AutoRLock {
+    public:
+        inline AutoRLock(RWLock& rwlock) : mLock(rwlock)  { mLock.readLock(); }
+        inline ~AutoRLock() { mLock.unlock(); }
+    private:
+        RWLock& mLock;
+    };
+
+    class AutoWLock {
+    public:
+        inline AutoWLock(RWLock& rwlock) : mLock(rwlock)  { mLock.writeLock(); }
+        inline ~AutoWLock() { mLock.unlock(); }
+    private:
+        RWLock& mLock;
+    };
+
+private:
+    // A RWLock cannot be copied
+                RWLock(const RWLock&);
+   RWLock&      operator = (const RWLock&);
+
+   pthread_rwlock_t mRWLock;
+};
+
+inline RWLock::RWLock() {
+    pthread_rwlock_init(&mRWLock, NULL);
+}
+inline RWLock::RWLock(const char* name) {
+    pthread_rwlock_init(&mRWLock, NULL);
+}
+inline RWLock::RWLock(int type, const char* name) {
+    if (type == SHARED) {
+        pthread_rwlockattr_t attr;
+        pthread_rwlockattr_init(&attr);
+        pthread_rwlockattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
+        pthread_rwlock_init(&mRWLock, &attr);
+        pthread_rwlockattr_destroy(&attr);
+    } else {
+        pthread_rwlock_init(&mRWLock, NULL);
+    }
+}
+inline RWLock::~RWLock() {
+    pthread_rwlock_destroy(&mRWLock);
+}
+inline status_t RWLock::readLock() {
+    return -pthread_rwlock_rdlock(&mRWLock);
+}
+inline status_t RWLock::tryReadLock() {
+    return -pthread_rwlock_tryrdlock(&mRWLock);
+}
+inline status_t RWLock::writeLock() {
+    return -pthread_rwlock_wrlock(&mRWLock);
+}
+inline status_t RWLock::tryWriteLock() {
+    return -pthread_rwlock_trywrlock(&mRWLock);
+}
+inline void RWLock::unlock() {
+    pthread_rwlock_unlock(&mRWLock);
+}
+
+#endif // HAVE_PTHREADS
+
+// ---------------------------------------------------------------------------
+}; // namespace android
+// ---------------------------------------------------------------------------
+
+#endif // _LIBS_UTILS_RWLOCK_H
diff --git a/include/utils/Thread.h b/include/utils/Thread.h
new file mode 100644
index 0000000..4a34abd
--- /dev/null
+++ b/include/utils/Thread.h
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _LIBS_UTILS_THREAD_H
+#define _LIBS_UTILS_THREAD_H
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <time.h>
+
+#if defined(HAVE_PTHREADS)
+# include <pthread.h>
+#endif
+
+#include <utils/Condition.h>
+#include <utils/Errors.h>
+#include <utils/Mutex.h>
+#include <utils/RefBase.h>
+#include <utils/Timers.h>
+#include <utils/ThreadDefs.h>
+
+// ---------------------------------------------------------------------------
+namespace android {
+// ---------------------------------------------------------------------------
+
+class Thread : virtual public RefBase
+{
+public:
+    // Create a Thread object, but doesn't create or start the associated
+    // thread. See the run() method.
+                        Thread(bool canCallJava = true);
+    virtual             ~Thread();
+
+    // Start the thread in threadLoop() which needs to be implemented.
+    virtual status_t    run(    const char* name = 0,
+                                int32_t priority = PRIORITY_DEFAULT,
+                                size_t stack = 0);
+    
+    // Ask this object's thread to exit. This function is asynchronous, when the
+    // function returns the thread might still be running. Of course, this
+    // function can be called from a different thread.
+    virtual void        requestExit();
+
+    // Good place to do one-time initializations
+    virtual status_t    readyToRun();
+    
+    // Call requestExit() and wait until this object's thread exits.
+    // BE VERY CAREFUL of deadlocks. In particular, it would be silly to call
+    // this function from this object's thread. Will return WOULD_BLOCK in
+    // that case.
+            status_t    requestExitAndWait();
+
+    // Wait until this object's thread exits. Returns immediately if not yet running.
+    // Do not call from this object's thread; will return WOULD_BLOCK in that case.
+            status_t    join();
+
+#ifdef HAVE_ANDROID_OS
+    // Return the thread's kernel ID, same as the thread itself calling gettid() or
+    // androidGetTid(), or -1 if the thread is not running.
+            pid_t       getTid() const;
+#endif
+
+protected:
+    // exitPending() returns true if requestExit() has been called.
+            bool        exitPending() const;
+    
+private:
+    // Derived class must implement threadLoop(). The thread starts its life
+    // here. There are two ways of using the Thread object:
+    // 1) loop: if threadLoop() returns true, it will be called again if
+    //          requestExit() wasn't called.
+    // 2) once: if threadLoop() returns false, the thread will exit upon return.
+    virtual bool        threadLoop() = 0;
+
+private:
+    Thread& operator=(const Thread&);
+    static  int             _threadLoop(void* user);
+    const   bool            mCanCallJava;
+    // always hold mLock when reading or writing
+            thread_id_t     mThread;
+    mutable Mutex           mLock;
+            Condition       mThreadExitedCondition;
+            status_t        mStatus;
+    // note that all accesses of mExitPending and mRunning need to hold mLock
+    volatile bool           mExitPending;
+    volatile bool           mRunning;
+            sp<Thread>      mHoldSelf;
+#ifdef HAVE_ANDROID_OS
+    // legacy for debugging, not used by getTid() as it is set by the child thread
+    // and so is not initialized until the child reaches that point
+            pid_t           mTid;
+#endif
+};
+
+
+}; // namespace android
+
+// ---------------------------------------------------------------------------
+#endif // _LIBS_UTILS_THREAD_H
+// ---------------------------------------------------------------------------
diff --git a/include/utils/ThreadDefs.h b/include/utils/ThreadDefs.h
new file mode 100644
index 0000000..3e56373
--- /dev/null
+++ b/include/utils/ThreadDefs.h
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _LIBS_UTILS_THREAD_DEFS_H
+#define _LIBS_UTILS_THREAD_DEFS_H
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <system/graphics.h>
+
+// ---------------------------------------------------------------------------
+// C API
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef void* android_thread_id_t;
+
+typedef int (*android_thread_func_t)(void*);
+
+enum {
+    /*
+     * ***********************************************
+     * ** Keep in sync with android.os.Process.java **
+     * ***********************************************
+     * 
+     * This maps directly to the "nice" priorities we use in Android.
+     * A thread priority should be chosen inverse-proportionally to
+     * the amount of work the thread is expected to do. The more work
+     * a thread will do, the less favorable priority it should get so that 
+     * it doesn't starve the system. Threads not behaving properly might
+     * be "punished" by the kernel.
+     * Use the levels below when appropriate. Intermediate values are
+     * acceptable, preferably use the {MORE|LESS}_FAVORABLE constants below.
+     */
+    ANDROID_PRIORITY_LOWEST         =  19,
+
+    /* use for background tasks */
+    ANDROID_PRIORITY_BACKGROUND     =  10,
+    
+    /* most threads run at normal priority */
+    ANDROID_PRIORITY_NORMAL         =   0,
+    
+    /* threads currently running a UI that the user is interacting with */
+    ANDROID_PRIORITY_FOREGROUND     =  -2,
+
+    /* the main UI thread has a slightly more favorable priority */
+    ANDROID_PRIORITY_DISPLAY        =  -4,
+    
+    /* ui service treads might want to run at a urgent display (uncommon) */
+    ANDROID_PRIORITY_URGENT_DISPLAY =  HAL_PRIORITY_URGENT_DISPLAY,
+    
+    /* all normal audio threads */
+    ANDROID_PRIORITY_AUDIO          = -16,
+    
+    /* service audio threads (uncommon) */
+    ANDROID_PRIORITY_URGENT_AUDIO   = -19,
+
+    /* should never be used in practice. regular process might not 
+     * be allowed to use this level */
+    ANDROID_PRIORITY_HIGHEST        = -20,
+
+    ANDROID_PRIORITY_DEFAULT        = ANDROID_PRIORITY_NORMAL,
+    ANDROID_PRIORITY_MORE_FAVORABLE = -1,
+    ANDROID_PRIORITY_LESS_FAVORABLE = +1,
+};
+
+enum {
+    ANDROID_TGROUP_DEFAULT          = 0,
+    ANDROID_TGROUP_BG_NONINTERACT   = 1,
+    ANDROID_TGROUP_FG_BOOST         = 2,
+    ANDROID_TGROUP_MAX              = ANDROID_TGROUP_FG_BOOST,
+};
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+// ---------------------------------------------------------------------------
+// C++ API
+#ifdef __cplusplus
+namespace android {
+// ---------------------------------------------------------------------------
+
+typedef android_thread_id_t thread_id_t;
+typedef android_thread_func_t thread_func_t;
+
+enum {
+    PRIORITY_LOWEST         = ANDROID_PRIORITY_LOWEST,
+    PRIORITY_BACKGROUND     = ANDROID_PRIORITY_BACKGROUND,
+    PRIORITY_NORMAL         = ANDROID_PRIORITY_NORMAL,
+    PRIORITY_FOREGROUND     = ANDROID_PRIORITY_FOREGROUND,
+    PRIORITY_DISPLAY        = ANDROID_PRIORITY_DISPLAY,
+    PRIORITY_URGENT_DISPLAY = ANDROID_PRIORITY_URGENT_DISPLAY,
+    PRIORITY_AUDIO          = ANDROID_PRIORITY_AUDIO,
+    PRIORITY_URGENT_AUDIO   = ANDROID_PRIORITY_URGENT_AUDIO,
+    PRIORITY_HIGHEST        = ANDROID_PRIORITY_HIGHEST,
+    PRIORITY_DEFAULT        = ANDROID_PRIORITY_DEFAULT,
+    PRIORITY_MORE_FAVORABLE = ANDROID_PRIORITY_MORE_FAVORABLE,
+    PRIORITY_LESS_FAVORABLE = ANDROID_PRIORITY_LESS_FAVORABLE,
+};
+
+// ---------------------------------------------------------------------------
+}; // namespace android
+#endif  // __cplusplus
+// ---------------------------------------------------------------------------
+
+
+#endif // _LIBS_UTILS_THREAD_DEFS_H
diff --git a/include/utils/Trace.h b/include/utils/Trace.h
new file mode 100644
index 0000000..f33ddf6
--- /dev/null
+++ b/include/utils/Trace.h
@@ -0,0 +1,166 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_TRACE_H
+#define ANDROID_TRACE_H
+
+#include <fcntl.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <cutils/compiler.h>
+#include <utils/threads.h>
+
+// The ATRACE_TAG macro can be defined before including this header to trace
+// using one of the tags defined below.  It must be defined to one of the
+// following ATRACE_TAG_* macros.  The trace tag is used to filter tracing in
+// userland to avoid some of the runtime cost of tracing when it is not desired.
+//
+// Defining ATRACE_TAG to be ATRACE_TAG_ALWAYS will result in the tracing always
+// being enabled - this should ONLY be done for debug code, as userland tracing
+// has a performance cost even when the trace is not being recorded.  Defining
+// ATRACE_TAG to be ATRACE_TAG_NEVER or leaving ATRACE_TAG undefined will result
+// in the tracing always being disabled.
+#define ATRACE_TAG_NEVER    0           // The "never" tag is never enabled.
+#define ATRACE_TAG_ALWAYS   (1<<0)      // The "always" tag is always enabled.
+#define ATRACE_TAG_GRAPHICS (1<<1)
+#define ATRACE_TAG_LAST     (1<<1)
+
+#define ATRACE_TAG_INVALID (~((ATRACE_TAG_LAST - 1) | ATRACE_TAG_LAST))
+
+#ifndef ATRACE_TAG
+#define ATRACE_TAG ATRACE_TAG_NEVER
+#elif ATRACE_TAG > ATRACE_TAG_LAST
+#error ATRACE_TAG must be defined to be one of the tags defined in utils/Trace.h
+#endif
+
+// ATRACE_CALL traces the beginning and end of the current function.  To trace
+// the correct start and end times this macro should be the first line of the
+// function body.
+#define ATRACE_CALL() android::ScopedTrace ___tracer(ATRACE_TAG, __FUNCTION__)
+
+// ATRACE_INT traces a named integer value.  This can be used to track how the
+// value changes over time in a trace.
+#define ATRACE_INT(name, value) android::Tracer::traceCounter(ATRACE_TAG, name, value)
+
+namespace android {
+
+class Tracer {
+
+public:
+
+    static inline void traceCounter(uint64_t tag, const char* name,
+            int32_t value) {
+        if (!android_atomic_acquire_load(&sIsReady)) {
+            init();
+        }
+        int traceFD = sTraceFD;
+        if (CC_UNLIKELY(tagEnabled(tag) && traceFD != -1)) {
+            char buf[1024];
+            snprintf(buf, 1024, "C|%d|%s|%d", getpid(), name, value);
+            write(traceFD, buf, strlen(buf));
+        }
+    }
+
+    static inline void traceBegin(uint64_t tag, const char* name) {
+        if (CC_UNLIKELY(!android_atomic_acquire_load(&sIsReady))) {
+            init();
+        }
+        int traceFD = sTraceFD;
+        if (CC_UNLIKELY(tagEnabled(tag) && (traceFD != -1))) {
+            char buf[1024];
+            size_t len = snprintf(buf, 1024, "B|%d|%s", getpid(), name);
+            write(traceFD, buf, len);
+        }
+    }
+
+   static inline void traceEnd(uint64_t tag) {
+        if (CC_UNLIKELY(!android_atomic_acquire_load(&sIsReady))) {
+            init();
+        }
+        int traceFD = sTraceFD;
+        if (CC_UNLIKELY(tagEnabled(tag) && (traceFD != -1))) {
+            char buf = 'E';
+            write(traceFD, &buf, 1);
+        }
+    }
+
+private:
+
+    static inline bool tagEnabled(uint64_t tag) {
+        return !(tag & ATRACE_TAG_INVALID) && (tag & sEnabledTags);
+    }
+
+    // init opens the trace marker file for writing and reads the
+    // atrace.tags.enableflags system property.  It does this only the first
+    // time it is run, using sMutex for synchronization.
+    static void init();
+
+    // sIsReady is a boolean value indicating whether a call to init() has
+    // completed in this process.  It is initialized to 0 and set to 1 when the
+    // first init() call completes.  It is set to 1 even if a failure occurred
+    // in init (e.g. the trace marker file couldn't be opened).
+    //
+    // This should be checked by all tracing functions using an atomic acquire
+    // load operation before calling init().  This check avoids the need to lock
+    // a mutex each time a trace function gets called.
+    static volatile int32_t sIsReady;
+
+    // sTraceFD is the file descriptor used to write to the kernel's trace
+    // buffer.  It is initialized to -1 and set to an open file descriptor in
+    // init() while a lock on sMutex is held.
+    //
+    // This should only be used by a trace function after init() has
+    // successfully completed.
+    static int sTraceFD;
+
+    // sEnabledTags is the set of tag bits for which tracing is currently
+    // enabled.  It is initialized to 0 and set based on the
+    // atrace.tags.enableflags system property in init() while a lock on sMutex
+    // is held.
+    //
+    // This should only be used by a trace function after init() has
+    // successfully completed.
+    static uint64_t sEnabledTags;
+
+    // sMutex is used to protect the execution of init().
+    static Mutex sMutex;
+};
+
+class ScopedTrace {
+
+public:
+    inline ScopedTrace(uint64_t tag, const char* name) :
+            mTag(tag) {
+        Tracer::traceBegin(mTag, name);
+    }
+
+    inline ~ScopedTrace() {
+        Tracer::traceEnd(mTag);
+    }
+
+private:
+
+    uint64_t mTag;
+};
+
+}; // namespace android
+
+#endif // ANDROID_TRACE_H
diff --git a/include/utils/threads.h b/include/utils/threads.h
index b4a8b7c..9de33821 100644
--- a/include/utils/threads.h
+++ b/include/utils/threads.h
@@ -17,556 +17,22 @@
 #ifndef _LIBS_UTILS_THREADS_H
 #define _LIBS_UTILS_THREADS_H
 
-#include <stdint.h>
-#include <sys/types.h>
-#include <time.h>
-#include <system/graphics.h>
+/*
+ * Please, DO NOT USE!
+ *
+ * This file is here only for legacy reasons. Instead, include directly
+ * the headers you need below.
+ *
+ */
 
-#if defined(HAVE_PTHREADS)
-# include <pthread.h>
-#endif
-
-// ------------------------------------------------------------------
-// C API
+#include <utils/AndroidThreads.h>
 
 #ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef void* android_thread_id_t;
-
-typedef int (*android_thread_func_t)(void*);
-
-enum {
-    /*
-     * ***********************************************
-     * ** Keep in sync with android.os.Process.java **
-     * ***********************************************
-     * 
-     * This maps directly to the "nice" priorities we use in Android.
-     * A thread priority should be chosen inverse-proportionally to
-     * the amount of work the thread is expected to do. The more work
-     * a thread will do, the less favorable priority it should get so that 
-     * it doesn't starve the system. Threads not behaving properly might
-     * be "punished" by the kernel.
-     * Use the levels below when appropriate. Intermediate values are
-     * acceptable, preferably use the {MORE|LESS}_FAVORABLE constants below.
-     */
-    ANDROID_PRIORITY_LOWEST         =  19,
-
-    /* use for background tasks */
-    ANDROID_PRIORITY_BACKGROUND     =  10,
-    
-    /* most threads run at normal priority */
-    ANDROID_PRIORITY_NORMAL         =   0,
-    
-    /* threads currently running a UI that the user is interacting with */
-    ANDROID_PRIORITY_FOREGROUND     =  -2,
-
-    /* the main UI thread has a slightly more favorable priority */
-    ANDROID_PRIORITY_DISPLAY        =  -4,
-    
-    /* ui service treads might want to run at a urgent display (uncommon) */
-    ANDROID_PRIORITY_URGENT_DISPLAY =  HAL_PRIORITY_URGENT_DISPLAY,
-    
-    /* all normal audio threads */
-    ANDROID_PRIORITY_AUDIO          = -16,
-    
-    /* service audio threads (uncommon) */
-    ANDROID_PRIORITY_URGENT_AUDIO   = -19,
-
-    /* should never be used in practice. regular process might not 
-     * be allowed to use this level */
-    ANDROID_PRIORITY_HIGHEST        = -20,
-
-    ANDROID_PRIORITY_DEFAULT        = ANDROID_PRIORITY_NORMAL,
-    ANDROID_PRIORITY_MORE_FAVORABLE = -1,
-    ANDROID_PRIORITY_LESS_FAVORABLE = +1,
-};
-
-enum {
-    ANDROID_TGROUP_DEFAULT          = 0,
-    ANDROID_TGROUP_BG_NONINTERACT   = 1,
-    ANDROID_TGROUP_FG_BOOST         = 2,
-    ANDROID_TGROUP_MAX              = ANDROID_TGROUP_FG_BOOST,
-};
-
-// Create and run a new thread.
-extern int androidCreateThread(android_thread_func_t, void *);
-
-// Create thread with lots of parameters
-extern int androidCreateThreadEtc(android_thread_func_t entryFunction,
-                                  void *userData,
-                                  const char* threadName,
-                                  int32_t threadPriority,
-                                  size_t threadStackSize,
-                                  android_thread_id_t *threadId);
-
-// Get some sort of unique identifier for the current thread.
-extern android_thread_id_t androidGetThreadId();
-
-// Low-level thread creation -- never creates threads that can
-// interact with the Java VM.
-extern int androidCreateRawThreadEtc(android_thread_func_t entryFunction,
-                                     void *userData,
-                                     const char* threadName,
-                                     int32_t threadPriority,
-                                     size_t threadStackSize,
-                                     android_thread_id_t *threadId);
-
-// Used by the Java Runtime to control how threads are created, so that
-// they can be proper and lovely Java threads.
-typedef int (*android_create_thread_fn)(android_thread_func_t entryFunction,
-                                        void *userData,
-                                        const char* threadName,
-                                        int32_t threadPriority,
-                                        size_t threadStackSize,
-                                        android_thread_id_t *threadId);
-
-extern void androidSetCreateThreadFunc(android_create_thread_fn func);
-
-// ------------------------------------------------------------------
-// Extra functions working with raw pids.
-
-// Get pid for the current thread.
-extern pid_t androidGetTid();
-
-// Change the scheduling group of a particular thread.  The group
-// should be one of the ANDROID_TGROUP constants.  Returns BAD_VALUE if
-// grp is out of range, else another non-zero value with errno set if
-// the operation failed.  Thread ID zero means current thread.
-extern int androidSetThreadSchedulingGroup(pid_t tid, int grp);
-
-// Change the priority AND scheduling group of a particular thread.  The priority
-// should be one of the ANDROID_PRIORITY constants.  Returns INVALID_OPERATION
-// if the priority set failed, else another value if just the group set failed;
-// in either case errno is set.  Thread ID zero means current thread.
-extern int androidSetThreadPriority(pid_t tid, int prio);
-
-// Get the current priority of a particular thread. Returns one of the
-// ANDROID_PRIORITY constants or a negative result in case of error.
-extern int androidGetThreadPriority(pid_t tid);
-
-// Get the current scheduling group of a particular thread. Normally returns
-// one of the ANDROID_TGROUP constants other than ANDROID_TGROUP_DEFAULT.
-// Returns ANDROID_TGROUP_DEFAULT if no pthread support (e.g. on host) or if
-// scheduling groups are disabled.  Returns INVALID_OPERATION if unexpected error.
-// Thread ID zero means current thread.
-extern int androidGetThreadSchedulingGroup(pid_t tid);
-
-#ifdef __cplusplus
-}
-#endif
-
-// ------------------------------------------------------------------
-// C++ API
-
-#ifdef __cplusplus
-
+#include <utils/Condition.h>
 #include <utils/Errors.h>
-#include <utils/RefBase.h>
-#include <utils/Timers.h>
-
-namespace android {
-
-typedef android_thread_id_t thread_id_t;
-
-typedef android_thread_func_t thread_func_t;
-
-enum {
-    PRIORITY_LOWEST         = ANDROID_PRIORITY_LOWEST,
-    PRIORITY_BACKGROUND     = ANDROID_PRIORITY_BACKGROUND,
-    PRIORITY_NORMAL         = ANDROID_PRIORITY_NORMAL,
-    PRIORITY_FOREGROUND     = ANDROID_PRIORITY_FOREGROUND,
-    PRIORITY_DISPLAY        = ANDROID_PRIORITY_DISPLAY,
-    PRIORITY_URGENT_DISPLAY = ANDROID_PRIORITY_URGENT_DISPLAY,
-    PRIORITY_AUDIO          = ANDROID_PRIORITY_AUDIO,
-    PRIORITY_URGENT_AUDIO   = ANDROID_PRIORITY_URGENT_AUDIO,
-    PRIORITY_HIGHEST        = ANDROID_PRIORITY_HIGHEST,
-    PRIORITY_DEFAULT        = ANDROID_PRIORITY_DEFAULT,
-    PRIORITY_MORE_FAVORABLE = ANDROID_PRIORITY_MORE_FAVORABLE,
-    PRIORITY_LESS_FAVORABLE = ANDROID_PRIORITY_LESS_FAVORABLE,
-};
-
-// Create and run a new thread.
-inline bool createThread(thread_func_t f, void *a) {
-    return androidCreateThread(f, a) ? true : false;
-}
-
-// Create thread with lots of parameters
-inline bool createThreadEtc(thread_func_t entryFunction,
-                            void *userData,
-                            const char* threadName = "android:unnamed_thread",
-                            int32_t threadPriority = PRIORITY_DEFAULT,
-                            size_t threadStackSize = 0,
-                            thread_id_t *threadId = 0)
-{
-    return androidCreateThreadEtc(entryFunction, userData, threadName,
-        threadPriority, threadStackSize, threadId) ? true : false;
-}
-
-// Get some sort of unique identifier for the current thread.
-inline thread_id_t getThreadId() {
-    return androidGetThreadId();
-}
-
-/*****************************************************************************/
-
-/*
- * Simple mutex class.  The implementation is system-dependent.
- *
- * The mutex must be unlocked by the thread that locked it.  They are not
- * recursive, i.e. the same thread can't lock it multiple times.
- */
-class Mutex {
-public:
-    enum {
-        PRIVATE = 0,
-        SHARED = 1
-    };
-    
-                Mutex();
-                Mutex(const char* name);
-                Mutex(int type, const char* name = NULL);
-                ~Mutex();
-
-    // lock or unlock the mutex
-    status_t    lock();
-    void        unlock();
-
-    // lock if possible; returns 0 on success, error otherwise
-    status_t    tryLock();
-
-    // Manages the mutex automatically. It'll be locked when Autolock is
-    // constructed and released when Autolock goes out of scope.
-    class Autolock {
-    public:
-        inline Autolock(Mutex& mutex) : mLock(mutex)  { mLock.lock(); }
-        inline Autolock(Mutex* mutex) : mLock(*mutex) { mLock.lock(); }
-        inline ~Autolock() { mLock.unlock(); }
-    private:
-        Mutex& mLock;
-    };
-
-private:
-    friend class Condition;
-    
-    // A mutex cannot be copied
-                Mutex(const Mutex&);
-    Mutex&      operator = (const Mutex&);
-    
-#if defined(HAVE_PTHREADS)
-    pthread_mutex_t mMutex;
-#else
-    void    _init();
-    void*   mState;
+#include <utils/Mutex.h>
+#include <utils/RWLock.h>
+#include <utils/Thread.h>
 #endif
-};
-
-#if defined(HAVE_PTHREADS)
-
-inline Mutex::Mutex() {
-    pthread_mutex_init(&mMutex, NULL);
-}
-inline Mutex::Mutex(const char* name) {
-    pthread_mutex_init(&mMutex, NULL);
-}
-inline Mutex::Mutex(int type, const char* name) {
-    if (type == SHARED) {
-        pthread_mutexattr_t attr;
-        pthread_mutexattr_init(&attr);
-        pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
-        pthread_mutex_init(&mMutex, &attr);
-        pthread_mutexattr_destroy(&attr);
-    } else {
-        pthread_mutex_init(&mMutex, NULL);
-    }
-}
-inline Mutex::~Mutex() {
-    pthread_mutex_destroy(&mMutex);
-}
-inline status_t Mutex::lock() {
-    return -pthread_mutex_lock(&mMutex);
-}
-inline void Mutex::unlock() {
-    pthread_mutex_unlock(&mMutex);
-}
-inline status_t Mutex::tryLock() {
-    return -pthread_mutex_trylock(&mMutex);
-}
-
-#endif // HAVE_PTHREADS
-
-/*
- * Automatic mutex.  Declare one of these at the top of a function.
- * When the function returns, it will go out of scope, and release the
- * mutex.
- */
- 
-typedef Mutex::Autolock AutoMutex;
-
-/*****************************************************************************/
-
-#if defined(HAVE_PTHREADS)
-
-/*
- * Simple mutex class.  The implementation is system-dependent.
- *
- * The mutex must be unlocked by the thread that locked it.  They are not
- * recursive, i.e. the same thread can't lock it multiple times.
- */
-class RWLock {
-public:
-    enum {
-        PRIVATE = 0,
-        SHARED = 1
-    };
-
-                RWLock();
-                RWLock(const char* name);
-                RWLock(int type, const char* name = NULL);
-                ~RWLock();
-
-    status_t    readLock();
-    status_t    tryReadLock();
-    status_t    writeLock();
-    status_t    tryWriteLock();
-    void        unlock();
-
-    class AutoRLock {
-    public:
-        inline AutoRLock(RWLock& rwlock) : mLock(rwlock)  { mLock.readLock(); }
-        inline ~AutoRLock() { mLock.unlock(); }
-    private:
-        RWLock& mLock;
-    };
-
-    class AutoWLock {
-    public:
-        inline AutoWLock(RWLock& rwlock) : mLock(rwlock)  { mLock.writeLock(); }
-        inline ~AutoWLock() { mLock.unlock(); }
-    private:
-        RWLock& mLock;
-    };
-
-private:
-    // A RWLock cannot be copied
-                RWLock(const RWLock&);
-   RWLock&      operator = (const RWLock&);
-
-   pthread_rwlock_t mRWLock;
-};
-
-inline RWLock::RWLock() {
-    pthread_rwlock_init(&mRWLock, NULL);
-}
-inline RWLock::RWLock(const char* name) {
-    pthread_rwlock_init(&mRWLock, NULL);
-}
-inline RWLock::RWLock(int type, const char* name) {
-    if (type == SHARED) {
-        pthread_rwlockattr_t attr;
-        pthread_rwlockattr_init(&attr);
-        pthread_rwlockattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
-        pthread_rwlock_init(&mRWLock, &attr);
-        pthread_rwlockattr_destroy(&attr);
-    } else {
-        pthread_rwlock_init(&mRWLock, NULL);
-    }
-}
-inline RWLock::~RWLock() {
-    pthread_rwlock_destroy(&mRWLock);
-}
-inline status_t RWLock::readLock() {
-    return -pthread_rwlock_rdlock(&mRWLock);
-}
-inline status_t RWLock::tryReadLock() {
-    return -pthread_rwlock_tryrdlock(&mRWLock);
-}
-inline status_t RWLock::writeLock() {
-    return -pthread_rwlock_wrlock(&mRWLock);
-}
-inline status_t RWLock::tryWriteLock() {
-    return -pthread_rwlock_trywrlock(&mRWLock);
-}
-inline void RWLock::unlock() {
-    pthread_rwlock_unlock(&mRWLock);
-}
-
-#endif // HAVE_PTHREADS
-
-/*****************************************************************************/
-
-/*
- * Condition variable class.  The implementation is system-dependent.
- *
- * Condition variables are paired up with mutexes.  Lock the mutex,
- * call wait(), then either re-wait() if things aren't quite what you want,
- * or unlock the mutex and continue.  All threads calling wait() must
- * use the same mutex for a given Condition.
- */
-class Condition {
-public:
-    enum {
-        PRIVATE = 0,
-        SHARED = 1
-    };
-
-    Condition();
-    Condition(int type);
-    ~Condition();
-    // Wait on the condition variable.  Lock the mutex before calling.
-    status_t wait(Mutex& mutex);
-    // same with relative timeout
-    status_t waitRelative(Mutex& mutex, nsecs_t reltime);
-    // Signal the condition variable, allowing one thread to continue.
-    void signal();
-    // Signal the condition variable, allowing all threads to continue.
-    void broadcast();
-
-private:
-#if defined(HAVE_PTHREADS)
-    pthread_cond_t mCond;
-#else
-    void*   mState;
-#endif
-};
-
-#if defined(HAVE_PTHREADS)
-
-inline Condition::Condition() {
-    pthread_cond_init(&mCond, NULL);
-}
-inline Condition::Condition(int type) {
-    if (type == SHARED) {
-        pthread_condattr_t attr;
-        pthread_condattr_init(&attr);
-        pthread_condattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
-        pthread_cond_init(&mCond, &attr);
-        pthread_condattr_destroy(&attr);
-    } else {
-        pthread_cond_init(&mCond, NULL);
-    }
-}
-inline Condition::~Condition() {
-    pthread_cond_destroy(&mCond);
-}
-inline status_t Condition::wait(Mutex& mutex) {
-    return -pthread_cond_wait(&mCond, &mutex.mMutex);
-}
-inline status_t Condition::waitRelative(Mutex& mutex, nsecs_t reltime) {
-#if defined(HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE)
-    struct timespec ts;
-    ts.tv_sec  = reltime/1000000000;
-    ts.tv_nsec = reltime%1000000000;
-    return -pthread_cond_timedwait_relative_np(&mCond, &mutex.mMutex, &ts);
-#else // HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE
-    struct timespec ts;
-#if defined(HAVE_POSIX_CLOCKS)
-    clock_gettime(CLOCK_REALTIME, &ts);
-#else // HAVE_POSIX_CLOCKS
-    // we don't support the clocks here.
-    struct timeval t;
-    gettimeofday(&t, NULL);
-    ts.tv_sec = t.tv_sec;
-    ts.tv_nsec= t.tv_usec*1000;
-#endif // HAVE_POSIX_CLOCKS
-    ts.tv_sec += reltime/1000000000;
-    ts.tv_nsec+= reltime%1000000000;
-    if (ts.tv_nsec >= 1000000000) {
-        ts.tv_nsec -= 1000000000;
-        ts.tv_sec  += 1;
-    }
-    return -pthread_cond_timedwait(&mCond, &mutex.mMutex, &ts);
-#endif // HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE
-}
-inline void Condition::signal() {
-    pthread_cond_signal(&mCond);
-}
-inline void Condition::broadcast() {
-    pthread_cond_broadcast(&mCond);
-}
-
-#endif // HAVE_PTHREADS
-
-/*****************************************************************************/
-
-/*
- * This is our spiffy thread object!
- */
-
-class Thread : virtual public RefBase
-{
-public:
-    // Create a Thread object, but doesn't create or start the associated
-    // thread. See the run() method.
-                        Thread(bool canCallJava = true);
-    virtual             ~Thread();
-
-    // Start the thread in threadLoop() which needs to be implemented.
-    virtual status_t    run(    const char* name = 0,
-                                int32_t priority = PRIORITY_DEFAULT,
-                                size_t stack = 0);
-    
-    // Ask this object's thread to exit. This function is asynchronous, when the
-    // function returns the thread might still be running. Of course, this
-    // function can be called from a different thread.
-    virtual void        requestExit();
-
-    // Good place to do one-time initializations
-    virtual status_t    readyToRun();
-    
-    // Call requestExit() and wait until this object's thread exits.
-    // BE VERY CAREFUL of deadlocks. In particular, it would be silly to call
-    // this function from this object's thread. Will return WOULD_BLOCK in
-    // that case.
-            status_t    requestExitAndWait();
-
-    // Wait until this object's thread exits. Returns immediately if not yet running.
-    // Do not call from this object's thread; will return WOULD_BLOCK in that case.
-            status_t    join();
-
-#ifdef HAVE_ANDROID_OS
-    // Return the thread's kernel ID, same as the thread itself calling gettid() or
-    // androidGetTid(), or -1 if the thread is not running.
-            pid_t       getTid() const;
-#endif
-
-protected:
-    // exitPending() returns true if requestExit() has been called.
-            bool        exitPending() const;
-    
-private:
-    // Derived class must implement threadLoop(). The thread starts its life
-    // here. There are two ways of using the Thread object:
-    // 1) loop: if threadLoop() returns true, it will be called again if
-    //          requestExit() wasn't called.
-    // 2) once: if threadLoop() returns false, the thread will exit upon return.
-    virtual bool        threadLoop() = 0;
-
-private:
-    Thread& operator=(const Thread&);
-    static  int             _threadLoop(void* user);
-    const   bool            mCanCallJava;
-    // always hold mLock when reading or writing
-            thread_id_t     mThread;
-    mutable Mutex           mLock;
-            Condition       mThreadExitedCondition;
-            status_t        mStatus;
-    // note that all accesses of mExitPending and mRunning need to hold mLock
-    volatile bool           mExitPending;
-    volatile bool           mRunning;
-            sp<Thread>      mHoldSelf;
-#ifdef HAVE_ANDROID_OS
-    // legacy for debugging, not used by getTid() as it is set by the child thread
-    // and so is not initialized until the child reaches that point
-            pid_t           mTid;
-#endif
-};
-
-
-}; // namespace android
-
-#endif  // __cplusplus
 
 #endif // _LIBS_UTILS_THREADS_H
diff --git a/libs/androidfw/Android.mk b/libs/androidfw/Android.mk
index c5f8a87..4e89d87 100644
--- a/libs/androidfw/Android.mk
+++ b/libs/androidfw/Android.mk
@@ -67,6 +67,7 @@
 	$(commonSources) \
 	BackupData.cpp \
 	BackupHelpers.cpp \
+    CursorWindow.cpp \
 	InputTransport.cpp
 
 LOCAL_SHARED_LIBRARIES := \
diff --git a/libs/binder/CursorWindow.cpp b/libs/androidfw/CursorWindow.cpp
similarity index 99%
rename from libs/binder/CursorWindow.cpp
rename to libs/androidfw/CursorWindow.cpp
index a6e5f71..047a4c8 100644
--- a/libs/binder/CursorWindow.cpp
+++ b/libs/androidfw/CursorWindow.cpp
@@ -18,7 +18,7 @@
 #define LOG_TAG "CursorWindow"
 
 #include <utils/Log.h>
-#include <binder/CursorWindow.h>
+#include <androidfw/CursorWindow.h>
 
 #include <cutils/ashmem.h>
 #include <sys/mman.h>
diff --git a/libs/binder/Android.mk b/libs/binder/Android.mk
index 3a12e96..d449298 100644
--- a/libs/binder/Android.mk
+++ b/libs/binder/Android.mk
@@ -16,7 +16,6 @@
 sources := \
     Binder.cpp \
     BpBinder.cpp \
-    CursorWindow.cpp \
     IInterface.cpp \
     IMemory.cpp \
     IPCThreadState.cpp \
@@ -25,7 +24,6 @@
     MemoryDealer.cpp \
     MemoryBase.cpp \
     MemoryHeapBase.cpp \
-    MemoryHeapPmem.cpp \
     Parcel.cpp \
     PermissionCache.cpp \
     ProcessState.cpp \
diff --git a/libs/binder/MemoryHeapPmem.cpp b/libs/binder/MemoryHeapPmem.cpp
deleted file mode 100644
index 66bcf4d..0000000
--- a/libs/binder/MemoryHeapPmem.cpp
+++ /dev/null
@@ -1,248 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "MemoryHeapPmem"
-
-#include <stdlib.h>
-#include <stdint.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/ioctl.h>
-
-#include <cutils/log.h>
-
-#include <binder/MemoryHeapPmem.h>
-#include <binder/MemoryHeapBase.h>
-
-#ifdef HAVE_ANDROID_OS
-#include <linux/android_pmem.h>
-#endif
-
-namespace android {
-
-// ---------------------------------------------------------------------------
-
-MemoryHeapPmem::MemoryPmem::MemoryPmem(const sp<MemoryHeapPmem>& heap)
-    : BnMemory(), mClientHeap(heap)
-{
-}
-
-MemoryHeapPmem::MemoryPmem::~MemoryPmem() {
-    if (mClientHeap != NULL) {
-        mClientHeap->remove(this);
-    }
-}
-
-// ---------------------------------------------------------------------------
-
-class SubRegionMemory : public MemoryHeapPmem::MemoryPmem {
-public:
-    SubRegionMemory(const sp<MemoryHeapPmem>& heap, ssize_t offset, size_t size);
-    virtual ~SubRegionMemory();
-    virtual sp<IMemoryHeap> getMemory(ssize_t* offset, size_t* size) const;
-private:
-    friend class MemoryHeapPmem;
-    void revoke();
-    size_t              mSize;
-    ssize_t             mOffset;
-};
-
-SubRegionMemory::SubRegionMemory(const sp<MemoryHeapPmem>& heap,
-        ssize_t offset, size_t size)
-    : MemoryHeapPmem::MemoryPmem(heap), mSize(size), mOffset(offset)
-{
-#ifndef NDEBUG
-    void* const start_ptr = (void*)(intptr_t(getHeap()->base()) + offset);
-    memset(start_ptr, 0xda, size);
-#endif
-
-#ifdef HAVE_ANDROID_OS
-    if (size > 0) {
-        const size_t pagesize = getpagesize();
-        size = (size + pagesize-1) & ~(pagesize-1);
-        int our_fd = heap->heapID();
-        struct pmem_region sub = { offset, size };
-        int err = ioctl(our_fd, PMEM_MAP, &sub);
-        ALOGE_IF(err<0, "PMEM_MAP failed (%s), "
-                "mFD=%d, sub.offset=%lu, sub.size=%lu",
-                strerror(errno), our_fd, sub.offset, sub.len);
-}
-#endif
-}
-
-sp<IMemoryHeap> SubRegionMemory::getMemory(ssize_t* offset, size_t* size) const
-{
-    if (offset) *offset = mOffset;
-    if (size)   *size = mSize;
-    return getHeap();
-}
-
-SubRegionMemory::~SubRegionMemory()
-{
-    revoke();
-}
-
-
-void SubRegionMemory::revoke()
-{
-    // NOTE: revoke() doesn't need to be protected by a lock because it
-    // can only be called from MemoryHeapPmem::revoke(), which means
-    // that we can't be in ~SubRegionMemory(), or in ~SubRegionMemory(),
-    // which means MemoryHeapPmem::revoke() wouldn't have been able to 
-    // promote() it.
-    
-#ifdef HAVE_ANDROID_OS
-    if (mSize != 0) {
-        const sp<MemoryHeapPmem>& heap(getHeap());
-        int our_fd = heap->heapID();
-        struct pmem_region sub;
-        sub.offset = mOffset;
-        sub.len = mSize;
-        int err = ioctl(our_fd, PMEM_UNMAP, &sub);
-        ALOGE_IF(err<0, "PMEM_UNMAP failed (%s), "
-                "mFD=%d, sub.offset=%lu, sub.size=%lu",
-                strerror(errno), our_fd, sub.offset, sub.len);
-        mSize = 0;
-    }
-#endif
-}
-
-// ---------------------------------------------------------------------------
-
-MemoryHeapPmem::MemoryHeapPmem(const sp<MemoryHeapBase>& pmemHeap,
-        uint32_t flags)
-    : MemoryHeapBase()
-{
-    char const * const device = pmemHeap->getDevice();
-#ifdef HAVE_ANDROID_OS
-    if (device) {
-        int fd = open(device, O_RDWR | (flags & NO_CACHING ? O_SYNC : 0));
-        ALOGE_IF(fd<0, "couldn't open %s (%s)", device, strerror(errno));
-        if (fd >= 0) {
-            int err = ioctl(fd, PMEM_CONNECT, pmemHeap->heapID());
-            if (err < 0) {
-                ALOGE("PMEM_CONNECT failed (%s), mFD=%d, sub-fd=%d",
-                        strerror(errno), fd, pmemHeap->heapID());
-                close(fd);
-            } else {
-                // everything went well...
-                mParentHeap = pmemHeap;
-                MemoryHeapBase::init(fd, 
-                        pmemHeap->getBase(),
-                        pmemHeap->getSize(),
-                        pmemHeap->getFlags() | flags,
-                        device);
-            }
-        }
-    }
-#else
-    mParentHeap = pmemHeap;
-    MemoryHeapBase::init( 
-            dup(pmemHeap->heapID()),
-            pmemHeap->getBase(),
-            pmemHeap->getSize(),
-            pmemHeap->getFlags() | flags,
-            device);
-#endif
-}
-
-MemoryHeapPmem::~MemoryHeapPmem()
-{
-}
-
-sp<IMemory> MemoryHeapPmem::mapMemory(size_t offset, size_t size)
-{
-    sp<MemoryPmem> memory = createMemory(offset, size);
-    if (memory != 0) {
-        Mutex::Autolock _l(mLock);
-        mAllocations.add(memory);
-    }
-    return memory;
-}
-
-sp<MemoryHeapPmem::MemoryPmem> MemoryHeapPmem::createMemory(
-        size_t offset, size_t size)
-{
-    sp<SubRegionMemory> memory;
-    if (heapID() > 0) 
-        memory = new SubRegionMemory(this, offset, size);
-    return memory;
-}
-
-status_t MemoryHeapPmem::slap()
-{
-#ifdef HAVE_ANDROID_OS
-    size_t size = getSize();
-    const size_t pagesize = getpagesize();
-    size = (size + pagesize-1) & ~(pagesize-1);
-    int our_fd = getHeapID();
-    struct pmem_region sub = { 0, size };
-    int err = ioctl(our_fd, PMEM_MAP, &sub);
-    ALOGE_IF(err<0, "PMEM_MAP failed (%s), "
-            "mFD=%d, sub.offset=%lu, sub.size=%lu",
-            strerror(errno), our_fd, sub.offset, sub.len);
-    return -errno;
-#else
-    return NO_ERROR;
-#endif
-}
-
-status_t MemoryHeapPmem::unslap()
-{
-#ifdef HAVE_ANDROID_OS
-    size_t size = getSize();
-    const size_t pagesize = getpagesize();
-    size = (size + pagesize-1) & ~(pagesize-1);
-    int our_fd = getHeapID();
-    struct pmem_region sub = { 0, size };
-    int err = ioctl(our_fd, PMEM_UNMAP, &sub);
-    ALOGE_IF(err<0, "PMEM_UNMAP failed (%s), "
-            "mFD=%d, sub.offset=%lu, sub.size=%lu",
-            strerror(errno), our_fd, sub.offset, sub.len);
-    return -errno;
-#else
-    return NO_ERROR;
-#endif
-}
-
-void MemoryHeapPmem::revoke()
-{
-    SortedVector< wp<MemoryPmem> > allocations;
-
-    { // scope for lock
-        Mutex::Autolock _l(mLock);
-        allocations = mAllocations;
-    }
-    
-    ssize_t count = allocations.size();
-    for (ssize_t i=0 ; i<count ; i++) {
-        sp<MemoryPmem> memory(allocations[i].promote());
-        if (memory != 0)
-            memory->revoke();
-    }
-}
-
-void MemoryHeapPmem::remove(const wp<MemoryPmem>& memory)
-{
-    Mutex::Autolock _l(mLock);
-    mAllocations.remove(memory);
-}
-
-// ---------------------------------------------------------------------------
-}; // namespace android
diff --git a/libs/binder/ProcessState.cpp b/libs/binder/ProcessState.cpp
index f96fe50..9fa412c 100644
--- a/libs/binder/ProcessState.cpp
+++ b/libs/binder/ProcessState.cpp
@@ -286,8 +286,8 @@
 {
     if (mThreadPoolStarted) {
         int32_t s = android_atomic_add(1, &mThreadPoolSeq);
-        char buf[32];
-        sprintf(buf, "Binder Thread #%d", s);
+        char buf[16];
+        snprintf(buf, sizeof(buf), "Binder_%X", s);
         ALOGV("Spawning new pooled thread, name=%s\n", buf);
         sp<Thread> t = new PoolThread(isMain);
         t->run(buf);
diff --git a/libs/camera/Camera.cpp b/libs/camera/Camera.cpp
index ee458f1..d43cb0b 100644
--- a/libs/camera/Camera.cpp
+++ b/libs/camera/Camera.cpp
@@ -27,7 +27,8 @@
 #include <camera/ICameraRecordingProxyListener.h>
 #include <camera/ICameraService.h>
 
-#include <surfaceflinger/Surface.h>
+#include <gui/ISurfaceTexture.h>
+#include <gui/Surface.h>
 
 namespace android {
 
diff --git a/libs/camera/ICamera.cpp b/libs/camera/ICamera.cpp
index 70f5dbc..8d8408c 100644
--- a/libs/camera/ICamera.cpp
+++ b/libs/camera/ICamera.cpp
@@ -22,6 +22,8 @@
 #include <sys/types.h>
 #include <binder/Parcel.h>
 #include <camera/ICamera.h>
+#include <gui/ISurfaceTexture.h>
+#include <gui/Surface.h>
 
 namespace android {
 
diff --git a/libs/gui/BufferQueue.cpp b/libs/gui/BufferQueue.cpp
index 0791de2..d761680 100644
--- a/libs/gui/BufferQueue.cpp
+++ b/libs/gui/BufferQueue.cpp
@@ -15,6 +15,8 @@
  */
 
 #define LOG_TAG "BufferQueue"
+//#define LOG_NDEBUG 0
+#define ATRACE_TAG ATRACE_TAG_GRAPHICS
 
 #define GL_GLEXT_PROTOTYPES
 #define EGL_EGLEXT_PROTOTYPES
@@ -23,10 +25,12 @@
 #include <EGL/eglext.h>
 
 #include <gui/BufferQueue.h>
+#include <gui/ISurfaceComposer.h>
 #include <private/gui/ComposerService.h>
-#include <surfaceflinger/ISurfaceComposer.h>
 
 #include <utils/Log.h>
+#include <gui/SurfaceTexture.h>
+#include <utils/Trace.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
@@ -34,6 +38,10 @@
 // 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.
+
+// During refactoring, do not support dequeuing the current buffer
+#undef ALLOW_DEQUEUE_CURRENT_BUFFER
+
 #ifdef ALLOW_DEQUEUE_CURRENT_BUFFER
 #define FLAG_ALLOW_DEQUEUE_CURRENT_BUFFER    true
 #warning "ALLOW_DEQUEUE_CURRENT_BUFFER enabled"
@@ -42,11 +50,11 @@
 #endif
 
 // Macros for including the BufferQueue name in log messages
-#define ST_LOGV(x, ...) ALOGV("[%s] "x, mName.string(), ##__VA_ARGS__)
-#define ST_LOGD(x, ...) ALOGD("[%s] "x, mName.string(), ##__VA_ARGS__)
-#define ST_LOGI(x, ...) ALOGI("[%s] "x, mName.string(), ##__VA_ARGS__)
-#define ST_LOGW(x, ...) ALOGW("[%s] "x, mName.string(), ##__VA_ARGS__)
-#define ST_LOGE(x, ...) ALOGE("[%s] "x, mName.string(), ##__VA_ARGS__)
+#define ST_LOGV(x, ...) ALOGV("[%s] "x, mConsumerName.string(), ##__VA_ARGS__)
+#define ST_LOGD(x, ...) ALOGD("[%s] "x, mConsumerName.string(), ##__VA_ARGS__)
+#define ST_LOGI(x, ...) ALOGI("[%s] "x, mConsumerName.string(), ##__VA_ARGS__)
+#define ST_LOGW(x, ...) ALOGW("[%s] "x, mConsumerName.string(), ##__VA_ARGS__)
+#define ST_LOGE(x, ...) ALOGE("[%s] "x, mConsumerName.string(), ##__VA_ARGS__)
 
 namespace android {
 
@@ -63,17 +71,17 @@
     mBufferCount(MIN_ASYNC_BUFFER_SLOTS),
     mClientBufferCount(0),
     mServerBufferCount(MIN_ASYNC_BUFFER_SLOTS),
-    mCurrentTexture(INVALID_BUFFER_SLOT),
     mNextTransform(0),
     mNextScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
     mSynchronousMode(false),
     mAllowSynchronousMode(allowSynchronousMode),
     mConnectedApi(NO_CONNECTED_API),
     mAbandoned(false),
-    mFrameCounter(0)
+    mFrameCounter(0),
+    mBufferHasBeenQueued(false)
 {
     // Choose a name using the PID and a process-unique ID.
-    mName = String8::format("unnamed-%d-%d", getpid(), createProcessUniqueId());
+    mConsumerName = String8::format("unnamed-%d-%d", getpid(), createProcessUniqueId());
 
     ST_LOGV("BufferQueue");
     sp<ISurfaceComposer> composer(ComposerService::getComposerService());
@@ -119,6 +127,23 @@
     return OK;
 }
 
+bool BufferQueue::isSynchronousMode() const {
+    Mutex::Autolock lock(mMutex);
+    return mSynchronousMode;
+}
+
+void BufferQueue::setConsumerName(const String8& name) {
+    Mutex::Autolock lock(mMutex);
+    mConsumerName = name;
+}
+
+void BufferQueue::setFrameAvailableListener(
+        const sp<FrameAvailableListener>& listener) {
+    ST_LOGV("setFrameAvailableListener");
+    Mutex::Autolock lock(mMutex);
+    mFrameAvailableListener = listener;
+}
+
 status_t BufferQueue::setBufferCount(int bufferCount) {
     ST_LOGV("setBufferCount: count=%d", bufferCount);
     Mutex::Autolock lock(mMutex);
@@ -160,7 +185,7 @@
     freeAllBuffersLocked();
     mBufferCount = bufferCount;
     mClientBufferCount = bufferCount;
-    mCurrentTexture = INVALID_BUFFER_SLOT;
+    mBufferHasBeenQueued = false;
     mQueue.clear();
     mDequeueCondition.signal();
     return OK;
@@ -168,6 +193,7 @@
 
 int BufferQueue::query(int what, int* outValue)
 {
+    ATRACE_CALL();
     Mutex::Autolock lock(mMutex);
 
     if (mAbandoned) {
@@ -198,6 +224,7 @@
 }
 
 status_t BufferQueue::requestBuffer(int slot, sp<GraphicBuffer>* buf) {
+    ATRACE_CALL();
     ST_LOGV("requestBuffer: slot=%d", slot);
     Mutex::Autolock lock(mMutex);
     if (mAbandoned) {
@@ -216,6 +243,7 @@
 
 status_t BufferQueue::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h,
         uint32_t format, uint32_t usage) {
+    ATRACE_CALL();
     ST_LOGV("dequeueBuffer: w=%d h=%d fmt=%#x usage=%#x", w, h, format, usage);
 
     if ((w && !h) || (!w && h)) {
@@ -276,7 +304,7 @@
                 mBufferCount = mServerBufferCount;
                 if (mBufferCount < minBufferCountNeeded)
                     mBufferCount = minBufferCountNeeded;
-                mCurrentTexture = INVALID_BUFFER_SLOT;
+                mBufferHasBeenQueued = false;
                 returnFlags |= ISurfaceTexture::RELEASE_ALL_BUFFERS;
             }
 
@@ -290,19 +318,12 @@
                     dequeuedCount++;
                 }
 
-                // if buffer is FREE it CANNOT be current
-                ALOGW_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;
-                        if (i != mCurrentTexture) {
-                            found = i;
-                            break;
-                        }
-                    }
+                // this logic used to be if (FLAG_ALLOW_DEQUEUE_CURRENT_BUFFER)
+                // but dequeuing the current buffer is disabled.
+                if (false) {
+                    // This functionality has been temporarily removed so
+                    // BufferQueue and SurfaceTexture can be refactored into
+                    // separate objects
                 } else {
                     if (state == BufferSlot::FREE) {
                         /* We return the oldest of the free buffers to avoid
@@ -331,8 +352,7 @@
             // 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) {
+            if (mBufferHasBeenQueued) {
                 // make sure the client is not trying to dequeue more buffers
                 // than allowed.
                 const int avail = mBufferCount - (dequeuedCount+1);
@@ -404,27 +424,23 @@
             if (updateFormat) {
                 mPixelFormat = format;
             }
+
+            mSlots[buf].mAcquireCalled = false;
             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;
-            }
+            mSlots[buf].mEglDisplay = EGL_NO_DISPLAY;
+
+
+
+
             returnFlags |= ISurfaceTexture::BUFFER_NEEDS_REALLOCATION;
         }
 
         dpy = mSlots[buf].mEglDisplay;
         fence = mSlots[buf].mFence;
         mSlots[buf].mFence = EGL_NO_SYNC_KHR;
-    }
+    }  // end lock scope
 
     if (fence != EGL_NO_SYNC_KHR) {
         EGLint result = eglClientWaitSyncKHR(dpy, fence, 0, 1000000000);
@@ -437,6 +453,7 @@
             ALOGE("dequeueBuffer: timeout waiting for fence");
         }
         eglDestroySyncKHR(dpy, fence);
+
     }
 
     ST_LOGV("dequeueBuffer: returning slot=%d buf=%p flags=%#x", *outBuf,
@@ -446,6 +463,7 @@
 }
 
 status_t BufferQueue::setSynchronousMode(bool enabled) {
+    ATRACE_CALL();
     ST_LOGV("setSynchronousMode: enabled=%d", enabled);
     Mutex::Autolock lock(mMutex);
 
@@ -478,6 +496,7 @@
 
 status_t BufferQueue::queueBuffer(int buf, int64_t timestamp,
         uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransform) {
+    ATRACE_CALL();
     ST_LOGV("queueBuffer: slot=%d time=%lld", buf, timestamp);
 
     sp<FrameAvailableListener> listener;
@@ -496,9 +515,6 @@
             ST_LOGE("queueBuffer: slot %d is not owned by the client "
                     "(state=%d)", buf, mSlots[buf].mBufferState);
             return -EINVAL;
-        } else if (buf == mCurrentTexture) {
-            ST_LOGE("queueBuffer: slot %d is current!", buf);
-            return -EINVAL;
         } else if (!mSlots[buf].mRequestBufferCalled) {
             ST_LOGE("queueBuffer: slot %d was enqueued without requesting a "
                     "buffer", buf);
@@ -538,11 +554,14 @@
         mFrameCounter++;
         mSlots[buf].mFrameNumber = mFrameCounter;
 
+        mBufferHasBeenQueued = true;
         mDequeueCondition.signal();
 
         *outWidth = mDefaultWidth;
         *outHeight = mDefaultHeight;
         *outTransform = 0;
+
+        ATRACE_INT(mConsumerName.string(), mQueue.size());
     } // scope for the lock
 
     // call back without lock held
@@ -553,6 +572,7 @@
 }
 
 void BufferQueue::cancelBuffer(int buf) {
+    ATRACE_CALL();
     ST_LOGV("cancelBuffer: slot=%d", buf);
     Mutex::Autolock lock(mMutex);
 
@@ -576,6 +596,7 @@
 }
 
 status_t BufferQueue::setCrop(const Rect& crop) {
+    ATRACE_CALL();
     ST_LOGV("setCrop: crop=[%d,%d,%d,%d]", crop.left, crop.top, crop.right,
             crop.bottom);
 
@@ -589,6 +610,7 @@
 }
 
 status_t BufferQueue::setTransform(uint32_t transform) {
+    ATRACE_CALL();
     ST_LOGV("setTransform: xform=%#x", transform);
     Mutex::Autolock lock(mMutex);
     if (mAbandoned) {
@@ -600,6 +622,7 @@
 }
 
 status_t BufferQueue::setScalingMode(int mode) {
+    ATRACE_CALL();
     ST_LOGV("setScalingMode: mode=%d", mode);
 
     switch (mode) {
@@ -618,6 +641,7 @@
 
 status_t BufferQueue::connect(int api,
         uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransform) {
+    ATRACE_CALL();
     ST_LOGV("connect: api=%d", api);
     Mutex::Autolock lock(mMutex);
 
@@ -647,10 +671,14 @@
             err = -EINVAL;
             break;
     }
+
+    mBufferHasBeenQueued = false;
+
     return err;
 }
 
 status_t BufferQueue::disconnect(int api) {
+    ATRACE_CALL();
     ST_LOGV("disconnect: api=%d", api);
     Mutex::Autolock lock(mMutex);
 
@@ -687,26 +715,188 @@
     return err;
 }
 
+void BufferQueue::dump(String8& result) const
+{
+    char buffer[1024];
+    BufferQueue::dump(result, "", buffer, 1024);
+}
+
+void BufferQueue::dump(String8& result, const char* prefix,
+        char* buffer, size_t SIZE) const
+{
+    Mutex::Autolock _l(mMutex);
+    snprintf(buffer, SIZE,
+            "%snext   : {crop=[%d,%d,%d,%d], transform=0x%02x}\n"
+            ,prefix, mNextCrop.left, mNextCrop.top, mNextCrop.right,
+            mNextCrop.bottom, mNextTransform
+    );
+    result.append(buffer);
+
+    String8 fifo;
+    int fifoSize = 0;
+    Fifo::const_iterator i(mQueue.begin());
+    while (i != mQueue.end()) {
+       snprintf(buffer, SIZE, "%02d ", *i++);
+       fifoSize++;
+       fifo.append(buffer);
+    }
+
+    snprintf(buffer, SIZE,
+            "%s-BufferQueue mBufferCount=%d, mSynchronousMode=%d, default-size=[%dx%d], "
+            "mPixelFormat=%d, FIFO(%d)={%s}\n",
+            prefix, mBufferCount, mSynchronousMode, mDefaultWidth,
+            mDefaultHeight, mPixelFormat, fifoSize, fifo.string());
+    result.append(buffer);
+
+
+    struct {
+        const char * operator()(int state) const {
+            switch (state) {
+                case BufferSlot::DEQUEUED: return "DEQUEUED";
+                case BufferSlot::QUEUED: return "QUEUED";
+                case BufferSlot::FREE: return "FREE";
+                case BufferSlot::ACQUIRED: return "ACQUIRED";
+                default: return "Unknown";
+            }
+        }
+    } stateName;
+
+    for (int i=0 ; i<mBufferCount ; i++) {
+        const BufferSlot& slot(mSlots[i]);
+        snprintf(buffer, SIZE,
+                "%s%s[%02d] "
+                "state=%-8s, crop=[%d,%d,%d,%d], "
+                "transform=0x%02x, timestamp=%lld",
+                prefix, (slot.mBufferState == BufferSlot::ACQUIRED)?">":" ", i,
+                stateName(slot.mBufferState),
+                slot.mCrop.left, slot.mCrop.top, slot.mCrop.right,
+                slot.mCrop.bottom, slot.mTransform, slot.mTimestamp
+        );
+        result.append(buffer);
+
+        const sp<GraphicBuffer>& buf(slot.mGraphicBuffer);
+        if (buf != NULL) {
+            snprintf(buffer, SIZE,
+                    ", %p [%4ux%4u:%4u,%3X]",
+                    buf->handle, buf->width, buf->height, buf->stride,
+                    buf->format);
+            result.append(buffer);
+        }
+        result.append("\n");
+    }
+}
+
 void BufferQueue::freeBufferLocked(int i) {
     mSlots[i].mGraphicBuffer = 0;
     mSlots[i].mBufferState = BufferSlot::FREE;
     mSlots[i].mFrameNumber = 0;
-    if (mSlots[i].mEglImage != EGL_NO_IMAGE_KHR) {
-        eglDestroyImageKHR(mSlots[i].mEglDisplay, mSlots[i].mEglImage);
-        mSlots[i].mEglImage = EGL_NO_IMAGE_KHR;
-        mSlots[i].mEglDisplay = EGL_NO_DISPLAY;
+    mSlots[i].mAcquireCalled = false;
+
+    // destroy fence as BufferQueue now takes ownership
+    if (mSlots[i].mFence != EGL_NO_SYNC_KHR) {
+        eglDestroySyncKHR(mSlots[i].mEglDisplay, mSlots[i].mFence);
+        mSlots[i].mFence = EGL_NO_SYNC_KHR;
     }
 }
 
 void BufferQueue::freeAllBuffersLocked() {
     ALOGW_IF(!mQueue.isEmpty(),
             "freeAllBuffersLocked called but mQueue is not empty");
-    mCurrentTexture = INVALID_BUFFER_SLOT;
+    mQueue.clear();
+    mBufferHasBeenQueued = false;
     for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
         freeBufferLocked(i);
     }
 }
 
+status_t BufferQueue::acquire(BufferItem *buffer) {
+    Mutex::Autolock _l(mMutex);
+    // check if queue is empty
+    // In asynchronous mode the list is guaranteed to be one buffer
+    // deep, while in synchronous mode we use the oldest buffer.
+    if (!mQueue.empty()) {
+        Fifo::iterator front(mQueue.begin());
+        int buf = *front;
+
+        if (mSlots[buf].mAcquireCalled) {
+            buffer->mGraphicBuffer = NULL;
+        }
+        else {
+            buffer->mGraphicBuffer = mSlots[buf].mGraphicBuffer;
+        }
+        buffer->mCrop = mSlots[buf].mCrop;
+        buffer->mTransform = mSlots[buf].mTransform;
+        buffer->mScalingMode = mSlots[buf].mScalingMode;
+        buffer->mFrameNumber = mSlots[buf].mFrameNumber;
+        buffer->mBuf = buf;
+        mSlots[buf].mAcquireCalled = true;
+
+        mSlots[buf].mBufferState = BufferSlot::ACQUIRED;
+        mQueue.erase(front);
+
+        ATRACE_INT(mConsumerName.string(), mQueue.size());
+    }
+    else {
+        return -EINVAL; //should be a better return code
+    }
+
+    return OK;
+}
+
+status_t BufferQueue::releaseBuffer(int buf, EGLDisplay display,
+        EGLSyncKHR fence) {
+    Mutex::Autolock _l(mMutex);
+
+    if (buf == INVALID_BUFFER_SLOT) {
+        return -EINVAL;
+    }
+
+    mSlots[buf].mEglDisplay = display;
+    mSlots[buf].mFence = fence;
+
+    // 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[buf].mBufferState == BufferSlot::QUEUED
+            || mSlots[buf].mBufferState == BufferSlot::ACQUIRED) {
+        mSlots[buf].mBufferState = BufferSlot::FREE;
+    }
+    mDequeueCondition.signal();
+
+    return OK;
+}
+
+status_t BufferQueue::consumerDisconnect() {
+    Mutex::Autolock lock(mMutex);
+    // Once the SurfaceTexture disconnects, the BufferQueue
+    // is considered abandoned
+    mAbandoned = true;
+    freeAllBuffersLocked();
+    mDequeueCondition.signal();
+    return OK;
+}
+
+status_t BufferQueue::setDefaultBufferSize(uint32_t w, uint32_t h)
+{
+    ST_LOGV("setDefaultBufferSize: w=%d, h=%d", w, h);
+    if (!w || !h) {
+        ST_LOGE("setDefaultBufferSize: dimensions cannot be 0 (w=%d, h=%d)",
+                w, h);
+        return BAD_VALUE;
+    }
+
+    Mutex::Autolock lock(mMutex);
+    mDefaultWidth = w;
+    mDefaultHeight = h;
+    return OK;
+}
+
+status_t BufferQueue::setBufferCountServer(int bufferCount) {
+    ATRACE_CALL();
+    Mutex::Autolock lock(mMutex);
+    return setBufferCountServerLocked(bufferCount);
+}
+
 void BufferQueue::freeAllBuffersExceptHeadLocked() {
     ALOGW_IF(!mQueue.isEmpty(),
             "freeAllBuffersExceptCurrentLocked called but mQueue is not empty");
@@ -715,7 +905,7 @@
         Fifo::iterator front(mQueue.begin());
         head = *front;
     }
-    mCurrentTexture = INVALID_BUFFER_SLOT;
+    mBufferHasBeenQueued = false;
     for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
         if (i != head) {
             freeBufferLocked(i);
diff --git a/libs/gui/DisplayEventReceiver.cpp b/libs/gui/DisplayEventReceiver.cpp
index 6a4763d..a6790ad 100644
--- a/libs/gui/DisplayEventReceiver.cpp
+++ b/libs/gui/DisplayEventReceiver.cpp
@@ -21,11 +21,10 @@
 #include <gui/BitTube.h>
 #include <gui/DisplayEventReceiver.h>
 #include <gui/IDisplayEventConnection.h>
+#include <gui/ISurfaceComposer.h>
 
 #include <private/gui/ComposerService.h>
 
-#include <surfaceflinger/ISurfaceComposer.h>
-
 // ---------------------------------------------------------------------------
 
 namespace android {
diff --git a/libs/gui/IGraphicBufferAlloc.cpp b/libs/gui/IGraphicBufferAlloc.cpp
index 30f8d00..a70a5e8a 100644
--- a/libs/gui/IGraphicBufferAlloc.cpp
+++ b/libs/gui/IGraphicBufferAlloc.cpp
@@ -24,7 +24,7 @@
 
 #include <ui/GraphicBuffer.h>
 
-#include <surfaceflinger/IGraphicBufferAlloc.h>
+#include <gui/IGraphicBufferAlloc.h>
 
 // ---------------------------------------------------------------------------
 
diff --git a/libs/gui/ISurface.cpp b/libs/gui/ISurface.cpp
index 96155d7..c2ea183 100644
--- a/libs/gui/ISurface.cpp
+++ b/libs/gui/ISurface.cpp
@@ -22,8 +22,8 @@
 
 #include <binder/Parcel.h>
 
+#include <gui/ISurface.h>
 #include <gui/ISurfaceTexture.h>
-#include <surfaceflinger/ISurface.h>
 
 namespace android {
 
diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp
index 95b2379..1f1794c 100644
--- a/libs/gui/ISurfaceComposer.cpp
+++ b/libs/gui/ISurfaceComposer.cpp
@@ -25,17 +25,15 @@
 #include <binder/IPCThreadState.h>
 #include <binder/IServiceManager.h>
 
-#include <private/surfaceflinger/LayerState.h>
-
-#include <surfaceflinger/ISurfaceComposer.h>
-
 #include <gui/BitTube.h>
 #include <gui/IDisplayEventConnection.h>
+#include <gui/ISurfaceComposer.h>
+#include <gui/ISurfaceTexture.h>
+
+#include <private/gui/LayerState.h>
 
 #include <ui/DisplayInfo.h>
 
-#include <gui/ISurfaceTexture.h>
-
 #include <utils/Log.h>
 
 // ---------------------------------------------------------------------------
diff --git a/libs/gui/ISurfaceComposerClient.cpp b/libs/gui/ISurfaceComposerClient.cpp
index 8fe96b1..ca9ed5b 100644
--- a/libs/gui/ISurfaceComposerClient.cpp
+++ b/libs/gui/ISurfaceComposerClient.cpp
@@ -29,9 +29,9 @@
 #include <ui/Point.h>
 #include <ui/Rect.h>
 
-#include <surfaceflinger/ISurface.h>
-#include <surfaceflinger/ISurfaceComposerClient.h>
-#include <private/surfaceflinger/LayerState.h>
+#include <gui/ISurface.h>
+#include <gui/ISurfaceComposerClient.h>
+#include <private/gui/LayerState.h>
 
 // ---------------------------------------------------------------------------
 
diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp
index 87901e8..224c305 100644
--- a/libs/gui/LayerState.cpp
+++ b/libs/gui/LayerState.cpp
@@ -16,8 +16,8 @@
 
 #include <utils/Errors.h>
 #include <binder/Parcel.h>
-#include <private/surfaceflinger/LayerState.h>
-#include <surfaceflinger/ISurfaceComposerClient.h>
+#include <gui/ISurfaceComposerClient.h>
+#include <private/gui/LayerState.h>
 
 namespace android {
 
diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp
index 337950c..72b27ed 100644
--- a/libs/gui/Surface.cpp
+++ b/libs/gui/Surface.cpp
@@ -28,16 +28,15 @@
 
 #include <binder/IPCThreadState.h>
 
-#include <gui/SurfaceTextureClient.h>
-
 #include <ui/DisplayInfo.h>
 #include <ui/GraphicBuffer.h>
 #include <ui/Rect.h>
 
-#include <surfaceflinger/ISurface.h>
-#include <surfaceflinger/ISurfaceComposer.h>
-#include <surfaceflinger/Surface.h>
-#include <surfaceflinger/SurfaceComposerClient.h>
+#include <gui/ISurface.h>
+#include <gui/ISurfaceComposer.h>
+#include <gui/Surface.h>
+#include <gui/SurfaceComposerClient.h>
+#include <gui/SurfaceTextureClient.h>
 
 namespace android {
 
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 699438c..ceb1ba6 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -31,15 +31,14 @@
 
 #include <ui/DisplayInfo.h>
 
-#include <surfaceflinger/ISurface.h>
-#include <surfaceflinger/ISurfaceComposer.h>
-#include <surfaceflinger/ISurfaceComposerClient.h>
-#include <surfaceflinger/SurfaceComposerClient.h>
-
-#include <private/surfaceflinger/LayerState.h>
-#include <private/surfaceflinger/SharedBufferStack.h>
+#include <gui/ISurface.h>
+#include <gui/ISurfaceComposer.h>
+#include <gui/ISurfaceComposerClient.h>
+#include <gui/SurfaceComposerClient.h>
 
 #include <private/gui/ComposerService.h>
+#include <private/gui/LayerState.h>
+#include <private/gui/SharedBufferStack.h>
 
 namespace android {
 // ---------------------------------------------------------------------------
diff --git a/libs/gui/SurfaceTexture.cpp b/libs/gui/SurfaceTexture.cpp
index a7bfc61..b42aa34 100644
--- a/libs/gui/SurfaceTexture.cpp
+++ b/libs/gui/SurfaceTexture.cpp
@@ -15,6 +15,7 @@
  */
 
 #define LOG_TAG "SurfaceTexture"
+#define ATRACE_TAG ATRACE_TAG_GRAPHICS
 //#define LOG_NDEBUG 0
 
 #define GL_GLEXT_PROTOTYPES
@@ -25,18 +26,18 @@
 #include <GLES2/gl2.h>
 #include <GLES2/gl2ext.h>
 
-#include <gui/SurfaceTexture.h>
-
 #include <hardware/hardware.h>
 
+#include <gui/IGraphicBufferAlloc.h>
+#include <gui/ISurfaceComposer.h>
+#include <gui/SurfaceComposerClient.h>
+#include <gui/SurfaceTexture.h>
+
 #include <private/gui/ComposerService.h>
 
-#include <surfaceflinger/ISurfaceComposer.h>
-#include <surfaceflinger/SurfaceComposerClient.h>
-#include <surfaceflinger/IGraphicBufferAlloc.h>
-
 #include <utils/Log.h>
 #include <utils/String8.h>
+#include <utils/Trace.h>
 
 // This compile option makes SurfaceTexture use the EGL_KHR_fence_sync extension
 // to synchronize access to the buffers.  It will cause dequeueBuffer to stall,
@@ -97,6 +98,11 @@
 
 static void mtxMul(float out[16], const float a[16], const float b[16]);
 
+// Get an ID that's unique within this process.
+static int32_t createProcessUniqueId() {
+    static volatile int32_t globalCounter = 0;
+    return android_atomic_inc(&globalCounter);
+}
 
 SurfaceTexture::SurfaceTexture(GLuint tex, bool allowSynchronousMode,
         GLenum texTarget, bool useFenceSync) :
@@ -109,8 +115,13 @@
 #else
     mUseFenceSync(false),
 #endif
-    mTexTarget(texTarget)
+    mTexTarget(texTarget),
+    mAbandoned(false),
+    mCurrentTexture(BufferQueue::INVALID_BUFFER_SLOT)
 {
+    // Choose a name using the PID and a process-unique ID.
+    mName = String8::format("unnamed-%d-%d", getpid(), createProcessUniqueId());
+    BufferQueue::setConsumerName(mName);
 
     ST_LOGV("SurfaceTexture");
     memcpy(mCurrentTransformMatrix, mtxIdentity,
@@ -119,31 +130,22 @@
 
 SurfaceTexture::~SurfaceTexture() {
     ST_LOGV("~SurfaceTexture");
-    freeAllBuffersLocked();
+    abandon();
 }
 
 status_t SurfaceTexture::setBufferCountServer(int bufferCount) {
     Mutex::Autolock lock(mMutex);
-    return setBufferCountServerLocked(bufferCount);
+    return BufferQueue::setBufferCountServer(bufferCount);
 }
 
 
 status_t SurfaceTexture::setDefaultBufferSize(uint32_t w, uint32_t h)
 {
-    ST_LOGV("setDefaultBufferSize: w=%d, h=%d", w, h);
-    if (!w || !h) {
-        ST_LOGE("setDefaultBufferSize: dimensions cannot be 0 (w=%d, h=%d)",
-                w, h);
-        return BAD_VALUE;
-    }
-
-    Mutex::Autolock lock(mMutex);
-    mDefaultWidth = w;
-    mDefaultHeight = h;
-    return OK;
+    return BufferQueue::setDefaultBufferSize(w, h);
 }
 
 status_t SurfaceTexture::updateTexImage() {
+    ATRACE_CALL();
     ST_LOGV("updateTexImage");
     Mutex::Autolock lock(mMutex);
 
@@ -152,23 +154,35 @@
         return NO_INIT;
     }
 
+    BufferItem item;
+
     // In asynchronous mode the list is guaranteed to be one buffer
     // deep, while in synchronous mode we use the oldest buffer.
-    if (!mQueue.empty()) {
-        Fifo::iterator front(mQueue.begin());
-        int buf = *front;
+    if (acquire(&item) == NO_ERROR) {
+        int buf = item.mBuf;
+        // This buffer was newly allocated, so we need to clean up on our side
+        if (item.mGraphicBuffer != NULL) {
+            mEGLSlots[buf].mGraphicBuffer = 0;
+            if (mEGLSlots[buf].mEglImage != EGL_NO_IMAGE_KHR) {
+                eglDestroyImageKHR(mEGLSlots[buf].mEglDisplay,
+                        mEGLSlots[buf].mEglImage);
+                mEGLSlots[buf].mEglImage = EGL_NO_IMAGE_KHR;
+                mEGLSlots[buf].mEglDisplay = EGL_NO_DISPLAY;
+            }
+            mEGLSlots[buf].mGraphicBuffer = item.mGraphicBuffer;
+        }
 
         // Update the GL texture object.
-        EGLImageKHR image = mSlots[buf].mEglImage;
+        EGLImageKHR image = mEGLSlots[buf].mEglImage;
         EGLDisplay dpy = eglGetCurrentDisplay();
         if (image == EGL_NO_IMAGE_KHR) {
-            if (mSlots[buf].mGraphicBuffer == 0) {
+            if (item.mGraphicBuffer == 0) {
                 ST_LOGE("buffer at slot %d is null", buf);
                 return BAD_VALUE;
             }
-            image = createImage(dpy, mSlots[buf].mGraphicBuffer);
-            mSlots[buf].mEglImage = image;
-            mSlots[buf].mEglDisplay = dpy;
+            image = createImage(dpy, item.mGraphicBuffer);
+            mEGLSlots[buf].mEglImage = image;
+            mEGLSlots[buf].mEglDisplay = dpy;
             if (image == EGL_NO_IMAGE_KHR) {
                 // NOTE: if dpy was invalid, createImage() is guaranteed to
                 // fail. so we'd end up here.
@@ -191,6 +205,8 @@
             failed = true;
         }
         if (failed) {
+            releaseBuffer(buf, mEGLSlots[buf].mEglDisplay,
+                    mEGLSlots[buf].mFence);
             return -EINVAL;
         }
 
@@ -201,40 +217,37 @@
                 if (fence == EGL_NO_SYNC_KHR) {
                     ALOGE("updateTexImage: error creating fence: %#x",
                             eglGetError());
+                    releaseBuffer(buf, mEGLSlots[buf].mEglDisplay,
+                            mEGLSlots[buf].mFence);
                     return -EINVAL;
                 }
                 glFlush();
-                mSlots[mCurrentTexture].mFence = fence;
+                mEGLSlots[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);
+                buf, item.mGraphicBuffer != NULL ? item.mGraphicBuffer->handle : 0);
 
-        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) {
-                mSlots[mCurrentTexture].mBufferState = BufferSlot::FREE;
-            }
-        }
+        // release old buffer
+        releaseBuffer(mCurrentTexture,
+                mEGLSlots[mCurrentTexture].mEglDisplay,
+                mEGLSlots[mCurrentTexture].mFence);
 
         // Update the SurfaceTexture state.
         mCurrentTexture = buf;
-        mCurrentTextureBuf = mSlots[buf].mGraphicBuffer;
-        mCurrentCrop = mSlots[buf].mCrop;
-        mCurrentTransform = mSlots[buf].mTransform;
-        mCurrentScalingMode = mSlots[buf].mScalingMode;
-        mCurrentTimestamp = mSlots[buf].mTimestamp;
+        mCurrentTextureBuf = mEGLSlots[buf].mGraphicBuffer;
+        mCurrentCrop = item.mCrop;
+        mCurrentTransform = item.mTransform;
+        mCurrentScalingMode = item.mScalingMode;
+        mCurrentTimestamp = item.mTimestamp;
         computeCurrentTransformMatrix();
 
         // Now that we've passed the point at which failures can happen,
         // it's safe to remove the buffer from the front of the queue.
-        mQueue.erase(front);
-        mDequeueCondition.signal();
+
     } else {
         // We always bind the texture even if we don't update its contents.
         glBindTexture(mTexTarget, mTexName);
@@ -300,7 +313,7 @@
         }
     }
 
-    sp<GraphicBuffer>& buf(mSlots[mCurrentTexture].mGraphicBuffer);
+    sp<GraphicBuffer>& buf(mCurrentTextureBuf);
     float tx, ty, sx, sy;
     if (!mCurrentCrop.isEmpty()) {
         // In order to prevent bilinear sampling at the of the crop rectangle we
@@ -372,7 +385,7 @@
         const sp<FrameAvailableListener>& listener) {
     ST_LOGV("setFrameAvailableListener");
     Mutex::Autolock lock(mMutex);
-    mFrameAvailableListener = listener;
+    BufferQueue::setFrameAvailableListener(listener);
 }
 
 EGLImageKHR SurfaceTexture::createImage(EGLDisplay dpy,
@@ -413,22 +426,33 @@
 
 bool SurfaceTexture::isSynchronousMode() const {
     Mutex::Autolock lock(mMutex);
-    return mSynchronousMode;
+    return BufferQueue::isSynchronousMode();
 }
 
-
-
 void SurfaceTexture::abandon() {
     Mutex::Autolock lock(mMutex);
-    mQueue.clear();
     mAbandoned = true;
     mCurrentTextureBuf.clear();
-    freeAllBuffersLocked();
-    mDequeueCondition.signal();
+
+    // destroy all egl buffers
+    for (int i =0; i < NUM_BUFFER_SLOTS; i++) {
+        mEGLSlots[i].mGraphicBuffer = 0;
+        if (mEGLSlots[i].mEglImage != EGL_NO_IMAGE_KHR) {
+            eglDestroyImageKHR(mEGLSlots[i].mEglDisplay,
+                    mEGLSlots[i].mEglImage);
+            mEGLSlots[i].mEglImage = EGL_NO_IMAGE_KHR;
+            mEGLSlots[i].mEglDisplay = EGL_NO_DISPLAY;
+        }
+    }
+
+    // disconnect from the BufferQueue
+    BufferQueue::consumerDisconnect();
 }
 
 void SurfaceTexture::setName(const String8& name) {
+    Mutex::Autolock _l(mMutex);
     mName = name;
+    BufferQueue::setConsumerName(name);
 }
 
 void SurfaceTexture::dump(String8& result) const
@@ -441,68 +465,19 @@
         char* buffer, size_t SIZE) const
 {
     Mutex::Autolock _l(mMutex);
-    snprintf(buffer, SIZE,
-            "%smBufferCount=%d, mSynchronousMode=%d, default-size=[%dx%d], "
-            "mPixelFormat=%d, mTexName=%d\n",
-            prefix, mBufferCount, mSynchronousMode, mDefaultWidth,
-            mDefaultHeight, mPixelFormat, mTexName);
+    snprintf(buffer, SIZE, "%smTexName=%d\n", prefix, mTexName);
     result.append(buffer);
 
-    String8 fifo;
-    int fifoSize = 0;
-    Fifo::const_iterator i(mQueue.begin());
-    while (i != mQueue.end()) {
-        snprintf(buffer, SIZE, "%02d ", *i++);
-        fifoSize++;
-        fifo.append(buffer);
-    }
-
     snprintf(buffer, SIZE,
-            "%scurrent: {crop=[%d,%d,%d,%d], transform=0x%02x, current=%d}\n"
-            "%snext   : {crop=[%d,%d,%d,%d], transform=0x%02x, FIFO(%d)={%s}}\n"
-            ,
-            prefix, mCurrentCrop.left,
+            "%snext   : {crop=[%d,%d,%d,%d], transform=0x%02x, current=%d}\n"
+            ,prefix, mCurrentCrop.left,
             mCurrentCrop.top, mCurrentCrop.right, mCurrentCrop.bottom,
-            mCurrentTransform, mCurrentTexture,
-            prefix, mNextCrop.left, mNextCrop.top, mNextCrop.right,
-            mNextCrop.bottom, mNextTransform, fifoSize, fifo.string()
+            mCurrentTransform, mCurrentTexture
     );
     result.append(buffer);
 
-    struct {
-        const char * operator()(int state) const {
-            switch (state) {
-                case BufferSlot::DEQUEUED: return "DEQUEUED";
-                case BufferSlot::QUEUED: return "QUEUED";
-                case BufferSlot::FREE: return "FREE";
-                default: return "Unknown";
-            }
-        }
-    } stateName;
 
-    for (int i=0 ; i<mBufferCount ; i++) {
-        const BufferSlot& slot(mSlots[i]);
-        snprintf(buffer, SIZE,
-                "%s%s[%02d] "
-                "state=%-8s, crop=[%d,%d,%d,%d], "
-                "transform=0x%02x, timestamp=%lld",
-                prefix, (i==mCurrentTexture)?">":" ", i,
-                stateName(slot.mBufferState),
-                slot.mCrop.left, slot.mCrop.top, slot.mCrop.right,
-                slot.mCrop.bottom, slot.mTransform, slot.mTimestamp
-        );
-        result.append(buffer);
-
-        const sp<GraphicBuffer>& buf(slot.mGraphicBuffer);
-        if (buf != NULL) {
-            snprintf(buffer, SIZE,
-                    ", %p [%4ux%4u:%4u,%3X]",
-                    buf->handle, buf->width, buf->height, buf->stride,
-                    buf->format);
-            result.append(buffer);
-        }
-        result.append("\n");
-    }
+    BufferQueue::dump(result, prefix, buffer, SIZE);
 }
 
 static void mtxMul(float out[16], const float a[16], const float b[16]) {
diff --git a/libs/gui/SurfaceTextureClient.cpp b/libs/gui/SurfaceTextureClient.cpp
index d0934ba..f88dcaf 100644
--- a/libs/gui/SurfaceTextureClient.cpp
+++ b/libs/gui/SurfaceTextureClient.cpp
@@ -15,13 +15,15 @@
  */
 
 #define LOG_TAG "SurfaceTextureClient"
+#define ATRACE_TAG ATRACE_TAG_GRAPHICS
 //#define LOG_NDEBUG 0
 
-#include <gui/SurfaceTextureClient.h>
-#include <surfaceflinger/ISurfaceComposer.h>
-#include <surfaceflinger/SurfaceComposerClient.h>
-
 #include <utils/Log.h>
+#include <utils/Trace.h>
+
+#include <gui/ISurfaceComposer.h>
+#include <gui/SurfaceComposerClient.h>
+#include <gui/SurfaceTextureClient.h>
 
 #include <private/gui/ComposerService.h>
 
@@ -121,6 +123,7 @@
 }
 
 int SurfaceTextureClient::setSwapInterval(int interval) {
+    ATRACE_CALL();
     // EGL specification states:
     //  interval is silently clamped to minimum and maximum implementation
     //  dependent values before being stored.
@@ -138,6 +141,7 @@
 }
 
 int SurfaceTextureClient::dequeueBuffer(android_native_buffer_t** buffer) {
+    ATRACE_CALL();
     ALOGV("SurfaceTextureClient::dequeueBuffer");
     Mutex::Autolock lock(mMutex);
     int buf = -1;
@@ -167,6 +171,7 @@
 }
 
 int SurfaceTextureClient::cancelBuffer(android_native_buffer_t* buffer) {
+    ATRACE_CALL();
     ALOGV("SurfaceTextureClient::cancelBuffer");
     Mutex::Autolock lock(mMutex);
     int i = getSlotFromBufferLocked(buffer);
@@ -213,6 +218,7 @@
 }
 
 int SurfaceTextureClient::queueBuffer(android_native_buffer_t* buffer) {
+    ATRACE_CALL();
     ALOGV("SurfaceTextureClient::queueBuffer");
     Mutex::Autolock lock(mMutex);
     int64_t timestamp;
@@ -236,6 +242,7 @@
 }
 
 int SurfaceTextureClient::query(int what, int* value) const {
+    ATRACE_CALL();
     ALOGV("SurfaceTextureClient::query");
     { // scope for the lock
         Mutex::Autolock lock(mMutex);
@@ -404,6 +411,7 @@
 
 
 int SurfaceTextureClient::connect(int api) {
+    ATRACE_CALL();
     ALOGV("SurfaceTextureClient::connect");
     Mutex::Autolock lock(mMutex);
     int err = mSurfaceTexture->connect(api,
@@ -415,6 +423,7 @@
 }
 
 int SurfaceTextureClient::disconnect(int api) {
+    ATRACE_CALL();
     ALOGV("SurfaceTextureClient::disconnect");
     Mutex::Autolock lock(mMutex);
     freeAllBuffers();
@@ -441,6 +450,7 @@
 
 int SurfaceTextureClient::setCrop(Rect const* rect)
 {
+    ATRACE_CALL();
     ALOGV("SurfaceTextureClient::setCrop");
     Mutex::Autolock lock(mMutex);
 
@@ -459,6 +469,7 @@
 
 int SurfaceTextureClient::setBufferCount(int bufferCount)
 {
+    ATRACE_CALL();
     ALOGV("SurfaceTextureClient::setBufferCount");
     Mutex::Autolock lock(mMutex);
 
@@ -475,6 +486,7 @@
 
 int SurfaceTextureClient::setBuffersDimensions(int w, int h)
 {
+    ATRACE_CALL();
     ALOGV("SurfaceTextureClient::setBuffersDimensions");
     Mutex::Autolock lock(mMutex);
 
@@ -508,6 +520,7 @@
 
 int SurfaceTextureClient::setScalingMode(int mode)
 {
+    ATRACE_CALL();
     ALOGV("SurfaceTextureClient::setScalingMode(%d)", mode);
     Mutex::Autolock lock(mMutex);
     // mode is validated on the server
@@ -520,6 +533,7 @@
 
 int SurfaceTextureClient::setBuffersTransform(int transform)
 {
+    ATRACE_CALL();
     ALOGV("SurfaceTextureClient::setBuffersTransform");
     Mutex::Autolock lock(mMutex);
     status_t err = mSurfaceTexture->setTransform(transform);
diff --git a/libs/gui/tests/SurfaceTexture_test.cpp b/libs/gui/tests/SurfaceTexture_test.cpp
index b18e7b0..8c6defe 100644
--- a/libs/gui/tests/SurfaceTexture_test.cpp
+++ b/libs/gui/tests/SurfaceTexture_test.cpp
@@ -24,9 +24,9 @@
 #include <utils/String8.h>
 #include <utils/threads.h>
 
-#include <surfaceflinger/ISurfaceComposer.h>
-#include <surfaceflinger/Surface.h>
-#include <surfaceflinger/SurfaceComposerClient.h>
+#include <gui/ISurfaceComposer.h>
+#include <gui/Surface.h>
+#include <gui/SurfaceComposerClient.h>
 
 #include <EGL/egl.h>
 #include <EGL/eglext.h>
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index ea52750..b585d68 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -17,9 +17,9 @@
 #include <gtest/gtest.h>
 
 #include <binder/IMemory.h>
-#include <surfaceflinger/ISurfaceComposer.h>
-#include <surfaceflinger/Surface.h>
-#include <surfaceflinger/SurfaceComposerClient.h>
+#include <gui/ISurfaceComposer.h>
+#include <gui/Surface.h>
+#include <gui/SurfaceComposerClient.h>
 #include <utils/String8.h>
 
 #include <private/gui/ComposerService.h>
diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp
index f9088ac..8153823 100644
--- a/libs/hwui/DisplayListRenderer.cpp
+++ b/libs/hwui/DisplayListRenderer.cpp
@@ -61,6 +61,7 @@
     "DrawLines",
     "DrawPoints",
     "DrawText",
+    "DrawTextOnPath",
     "DrawPosText",
     "ResetShader",
     "SetupShader",
@@ -483,7 +484,7 @@
             break;
             case DrawText: {
                 getText(&text);
-                int count = getInt();
+                int32_t count = getInt();
                 float x = getFloat();
                 float y = getFloat();
                 SkPaint* paint = getPaint(renderer);
@@ -492,6 +493,17 @@
                     text.text(), text.length(), count, x, y, paint, length);
             }
             break;
+            case DrawTextOnPath: {
+                getText(&text);
+                int32_t count = getInt();
+                SkPath* path = getPath();
+                float hOffset = getFloat();
+                float vOffset = getFloat();
+                SkPaint* paint = getPaint(renderer);
+                ALOGD("%s%s %s, %d, %d, %p", (char*) indent, OP_NAMES[op],
+                    text.text(), text.length(), count, paint);
+            }
+            break;
             case DrawPosText: {
                 getText(&text);
                 int count = getInt();
@@ -890,6 +902,19 @@
                 renderer.drawText(text.text(), text.length(), count, x, y, paint, length);
             }
             break;
+            case DrawTextOnPath: {
+                getText(&text);
+                int32_t count = getInt();
+                SkPath* path = getPath();
+                float hOffset = getFloat();
+                float vOffset = getFloat();
+                SkPaint* paint = getPaint(renderer);
+                DISPLAY_LIST_LOGD("%s%s %s, %d, %d, %p", (char*) indent, OP_NAMES[op],
+                    text.text(), text.length(), count, paint);
+                renderer.drawTextOnPath(text.text(), text.length(), count, path,
+                        hOffset, vOffset, paint);
+            }
+            break;
             case DrawPosText: {
                 getText(&text);
                 int32_t count = getInt();
@@ -1331,6 +1356,19 @@
     addSkip(location);
 }
 
+void DisplayListRenderer::drawTextOnPath(const char* text, int bytesCount, int count,
+        SkPath* path, float hOffset, float vOffset, SkPaint* paint) {
+    if (!text || count <= 0) return;
+    addOp(DisplayList::DrawTextOnPath);
+    addText(text, bytesCount);
+    addInt(count);
+    addPath(path);
+    addFloat(hOffset);
+    addFloat(vOffset);
+    paint->setAntiAlias(true);
+    addPaint(paint);
+}
+
 void DisplayListRenderer::drawPosText(const char* text, int bytesCount, int count,
         const float* positions, SkPaint* paint) {
     if (!text || count <= 0) return;
diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h
index 4a299c6..5d1b460 100644
--- a/libs/hwui/DisplayListRenderer.h
+++ b/libs/hwui/DisplayListRenderer.h
@@ -99,6 +99,7 @@
         DrawLines,
         DrawPoints,
         DrawText,
+        DrawTextOnPath,
         DrawPosText,
         ResetShader,
         SetupShader,
@@ -310,6 +311,8 @@
     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, float length = 1.0f);
+    virtual void drawTextOnPath(const char* text, int bytesCount, int count, SkPath* path,
+            float hOffset, float vOffset, SkPaint* paint);
     virtual void drawPosText(const char* text, int bytesCount, int count, const float* positions,
             SkPaint* paint);
 
diff --git a/libs/hwui/FontRenderer.cpp b/libs/hwui/FontRenderer.cpp
index 3df105b..f2bb6ec 100644
--- a/libs/hwui/FontRenderer.cpp
+++ b/libs/hwui/FontRenderer.cpp
@@ -39,6 +39,8 @@
 #define MAX_TEXT_CACHE_WIDTH 2048
 #define TEXTURE_BORDER_SIZE 2
 
+#define AUTO_KERN(prev, next) (((next) - (prev) + 32) >> 6 << 16)
+
 ///////////////////////////////////////////////////////////////////////////////
 // CacheTextureLine
 ///////////////////////////////////////////////////////////////////////////////
@@ -163,6 +165,44 @@
     }
 }
 
+void Font::drawCachedGlyph(CachedGlyphInfo* glyph, float x, float hOffset, float vOffset,
+        SkPathMeasure& measure, SkPoint* position, SkVector* tangent) {
+    const float halfWidth = glyph->mBitmapWidth * 0.5f;
+    const float height = glyph->mBitmapHeight;
+
+    float nPenX = glyph->mBitmapLeft;
+    vOffset += glyph->mBitmapTop + height;
+
+    const float u1 = glyph->mBitmapMinU;
+    const float u2 = glyph->mBitmapMaxU;
+    const float v1 = glyph->mBitmapMinV;
+    const float v2 = glyph->mBitmapMaxV;
+
+    SkPoint destination[4];
+    measure.getPosTan(x + hOffset + nPenX + halfWidth, position, tangent);
+
+    // Move along the tangent and offset by the normal
+    destination[0].set(-tangent->fX * halfWidth - tangent->fY * vOffset,
+            -tangent->fY * halfWidth + tangent->fX * vOffset);
+    destination[1].set(tangent->fX * halfWidth - tangent->fY * vOffset,
+            tangent->fY * halfWidth + tangent->fX * vOffset);
+    destination[2].set(destination[1].fX + tangent->fY * height,
+            destination[1].fY - tangent->fX * height);
+    destination[3].set(destination[0].fX + tangent->fY * height,
+            destination[0].fY - tangent->fX * height);
+
+    mState->appendRotatedMeshQuad(
+            position->fX + destination[0].fX,
+            position->fY + destination[0].fY, u1, v2,
+            position->fX + destination[1].fX,
+            position->fY + destination[1].fY, u2, v2,
+            position->fX + destination[2].fX,
+            position->fY + destination[2].fY, u2, v1,
+            position->fX + destination[3].fX,
+            position->fY + destination[3].fY, u1, v1,
+            glyph->mCachedTextureLine->mCacheTexture);
+}
+
 CachedGlyphInfo* Font::getCachedGlyph(SkPaint* paint, glyph_t textUnit) {
     CachedGlyphInfo* cachedGlyph = NULL;
     ssize_t index = mCachedGlyphs.indexOfKey(textUnit);
@@ -198,6 +238,56 @@
             0, 0, NULL, positions);
 }
 
+void Font::render(SkPaint* paint, const char *text, uint32_t start, uint32_t len,
+        int numGlyphs, SkPath* path, float hOffset, float vOffset) {
+    if (numGlyphs == 0 || text == NULL || len == 0) {
+        return;
+    }
+
+    text += start;
+
+    int glyphsCount = 0;
+    SkFixed prevRsbDelta = 0;
+
+    float penX = 0.0f;
+
+    SkPoint position;
+    SkVector tangent;
+
+    SkPathMeasure measure(*path, false);
+    float pathLength = SkScalarToFloat(measure.getLength());
+
+    if (paint->getTextAlign() != SkPaint::kLeft_Align) {
+        float textWidth = SkScalarToFloat(paint->measureText(text, len));
+        float pathOffset = pathLength;
+        if (paint->getTextAlign() == SkPaint::kCenter_Align) {
+            textWidth *= 0.5f;
+            pathOffset *= 0.5f;
+        }
+        penX += pathOffset - textWidth;
+    }
+
+    while (glyphsCount < numGlyphs && penX <= pathLength) {
+        glyph_t glyph = GET_GLYPH(text);
+
+        if (IS_END_OF_STRING(glyph)) {
+            break;
+        }
+
+        CachedGlyphInfo* cachedGlyph = getCachedGlyph(paint, glyph);
+        penX += SkFixedToFloat(AUTO_KERN(prevRsbDelta, cachedGlyph->mLsbDelta));
+        prevRsbDelta = cachedGlyph->mRsbDelta;
+
+        if (cachedGlyph->mIsValid) {
+            drawCachedGlyph(cachedGlyph, roundf(penX), hOffset, vOffset, measure, &position, &tangent);
+        }
+
+        penX += SkFixedToFloat(cachedGlyph->mAdvanceX);
+
+        glyphsCount++;
+    }
+}
+
 void Font::measure(SkPaint* paint, const char* text, uint32_t start, uint32_t len,
         int numGlyphs, Rect *bounds) {
     if (bounds == NULL) {
@@ -208,19 +298,13 @@
     render(paint, text, start, len, numGlyphs, 0, 0, MEASURE, NULL, 0, 0, bounds, NULL);
 }
 
-#define SkAutoKern_AdjustF(prev, next) (((next) - (prev) + 32) >> 6 << 16)
-
 void Font::render(SkPaint* paint, const char* text, uint32_t start, uint32_t len,
         int numGlyphs, int x, int y, RenderMode mode, uint8_t *bitmap,
-        uint32_t bitmapW, uint32_t bitmapH, Rect *bounds, const float* positions) {
+        uint32_t bitmapW, uint32_t bitmapH, Rect* bounds, const float* positions) {
     if (numGlyphs == 0 || text == NULL || len == 0) {
         return;
     }
 
-    int glyphsCount = 0;
-
-    text += start;
-
     static RenderGlyph gRenderGlyph[] = {
             &android::uirenderer::Font::drawCachedGlyph,
             &android::uirenderer::Font::drawCachedGlyphBitmap,
@@ -228,14 +312,15 @@
     };
     RenderGlyph render = gRenderGlyph[mode];
 
+    text += start;
+    int glyphsCount = 0;
+
     if (CC_LIKELY(positions == NULL)) {
         SkFixed prevRsbDelta = 0;
 
-        float penX = x;
+        float penX = x + 0.5f;
         int penY = y;
 
-        penX += 0.5f;
-
         while (glyphsCount < numGlyphs) {
             glyph_t glyph = GET_GLYPH(text);
 
@@ -245,7 +330,7 @@
             }
 
             CachedGlyphInfo* cachedGlyph = getCachedGlyph(paint, glyph);
-            penX += SkFixedToFloat(SkAutoKern_AdjustF(prevRsbDelta, cachedGlyph->mLsbDelta));
+            penX += SkFixedToFloat(AUTO_KERN(prevRsbDelta, cachedGlyph->mLsbDelta));
             prevRsbDelta = cachedGlyph->mRsbDelta;
 
             // If it's still not valid, we couldn't cache it, so we shouldn't draw garbage
@@ -582,6 +667,7 @@
             cacheBuffer[cacheY * cacheWidth + cacheX] = mGammaTable[tempCol];
         }
     }
+
     cachedGlyph->mIsValid = true;
 }
 
@@ -758,15 +844,9 @@
     mDrawn = true;
 }
 
-void FontRenderer::appendMeshQuad(float x1, float y1, float u1, float v1,
-        float x2, float y2, float u2, float v2,
-        float x3, float y3, float u3, float v3,
+void FontRenderer::appendMeshQuadNoClip(float x1, float y1, float u1, float v1,
+        float x2, float y2, float u2, float v2, float x3, float y3, float u3, float v3,
         float x4, float y4, float u4, float v4, CacheTexture* texture) {
-
-    if (mClip &&
-            (x1 > mClip->right || y1 < mClip->top || x2 < mClip->left || y4 > mClip->bottom)) {
-        return;
-    }
     if (texture != mCurrentCacheTexture) {
         if (mCurrentQuadIndex != 0) {
             // First, draw everything stored already which uses the previous texture
@@ -802,6 +882,18 @@
     (*currentPos++) = v4;
 
     mCurrentQuadIndex++;
+}
+
+void FontRenderer::appendMeshQuad(float x1, float y1, float u1, float v1,
+        float x2, float y2, float u2, float v2, float x3, float y3, float u3, float v3,
+        float x4, float y4, float u4, float v4, CacheTexture* texture) {
+
+    if (mClip &&
+            (x1 > mClip->right || y1 < mClip->top || x2 < mClip->left || y4 > mClip->bottom)) {
+        return;
+    }
+
+    appendMeshQuadNoClip(x1, y1, u1, v1, x2, y2, u2, v2, x3, y3, u3, v3, x4, y4, u4, v4, texture);
 
     if (mBounds) {
         mBounds->left = fmin(mBounds->left, x1);
@@ -816,6 +908,25 @@
     }
 }
 
+void FontRenderer::appendRotatedMeshQuad(float x1, float y1, float u1, float v1,
+        float x2, float y2, float u2, float v2, float x3, float y3, float u3, float v3,
+        float x4, float y4, float u4, float v4, CacheTexture* texture) {
+
+    appendMeshQuadNoClip(x1, y1, u1, v1, x2, y2, u2, v2, x3, y3, u3, v3, x4, y4, u4, v4, texture);
+
+    if (mBounds) {
+        mBounds->left = fmin(mBounds->left, fmin(x1, fmin(x2, fmin(x3, x4))));
+        mBounds->top = fmin(mBounds->top, fmin(y1, fmin(y2, fmin(y3, y4))));
+        mBounds->right = fmax(mBounds->right, fmax(x1, fmax(x2, fmax(x3, x4))));
+        mBounds->bottom = fmax(mBounds->bottom, fmax(y1, fmax(y2, fmax(y3, y4))));
+    }
+
+    if (mCurrentQuadIndex == mMaxNumberOfQuads) {
+        issueDrawCommand();
+        mCurrentQuadIndex = 0;
+    }
+}
+
 uint32_t FontRenderer::getRemainingCacheCapacity() {
     uint32_t remainingCapacity = 0;
     float totalPixels = 0;
@@ -956,6 +1067,21 @@
     return mDrawn;
 }
 
+bool FontRenderer::renderTextOnPath(SkPaint* paint, const Rect* clip, const char *text,
+        uint32_t startIndex, uint32_t len, int numGlyphs, SkPath* path,
+        float hOffset, float vOffset, Rect* bounds) {
+    if (!mCurrentFont) {
+        ALOGE("No font set");
+        return false;
+    }
+
+    initRender(clip, bounds);
+    mCurrentFont->render(paint, text, startIndex, len, numGlyphs, path, hOffset, vOffset);
+    finishRender();
+
+    return mDrawn;
+}
+
 void FontRenderer::computeGaussianWeights(float* weights, int32_t radius) {
     // Compute gaussian weights for the blur
     // e is the euler's number
diff --git a/libs/hwui/FontRenderer.h b/libs/hwui/FontRenderer.h
index b767be5..4fc5862 100644
--- a/libs/hwui/FontRenderer.h
+++ b/libs/hwui/FontRenderer.h
@@ -24,6 +24,8 @@
 
 #include <SkScalerContext.h>
 #include <SkPaint.h>
+#include <SkPathMeasure.h>
+#include <SkPoint.h>
 
 #include <GLES2/gl2.h>
 
@@ -155,6 +157,9 @@
     void render(SkPaint* paint, const char *text, uint32_t start, uint32_t len,
             int numGlyphs, int x, int y, const float* positions);
 
+    void render(SkPaint* paint, const char *text, uint32_t start, uint32_t len,
+            int numGlyphs, SkPath* path, float hOffset, float vOffset);
+
     /**
      * Creates a new font associated with the specified font state.
      */
@@ -200,6 +205,8 @@
     void drawCachedGlyphBitmap(CachedGlyphInfo* glyph, int x, int y,
             uint8_t *bitmap, uint32_t bitmapW, uint32_t bitmapH,
             Rect* bounds, const float* pos);
+    void drawCachedGlyph(CachedGlyphInfo* glyph, float x, float hOffset, float vOffset,
+            SkPathMeasure& measure, SkPoint* position, SkVector* tangent);
 
     CachedGlyphInfo* getCachedGlyph(SkPaint* paint, glyph_t textUnit);
 
@@ -244,6 +251,9 @@
     // bounds is an out parameter
     bool renderPosText(SkPaint* paint, const Rect* clip, const char *text, uint32_t startIndex,
             uint32_t len, int numGlyphs, int x, int y, const float* positions, Rect* bounds);
+    // bounds is an out parameter
+    bool renderTextOnPath(SkPaint* paint, const Rect* clip, const char *text, uint32_t startIndex,
+            uint32_t len, int numGlyphs, SkPath* path, float hOffset, float vOffset, Rect* bounds);
 
     struct DropShadow {
         DropShadow() { };
@@ -305,7 +315,7 @@
     void allocateTextureMemory(CacheTexture* cacheTexture);
     void deallocateTextureMemory(CacheTexture* cacheTexture);
     void initTextTexture();
-    CacheTexture *createCacheTexture(int width, int height, bool allocate);
+    CacheTexture* createCacheTexture(int width, int height, bool allocate);
     void cacheBitmap(const SkGlyph& glyph, CachedGlyphInfo* cachedGlyph,
             uint32_t *retOriginX, uint32_t *retOriginY);
 
@@ -320,10 +330,18 @@
     void precacheLatin(SkPaint* paint);
 
     void issueDrawCommand();
+    void appendMeshQuadNoClip(float x1, float y1, float u1, float v1,
+            float x2, float y2, float u2, float v2,
+            float x3, float y3, float u3, float v3,
+            float x4, float y4, float u4, float v4, CacheTexture* texture);
     void appendMeshQuad(float x1, float y1, float u1, float v1,
             float x2, float y2, float u2, float v2,
             float x3, float y3, float u3, float v3,
             float x4, float y4, float u4, float v4, CacheTexture* texture);
+    void appendRotatedMeshQuad(float x1, float y1, float u1, float v1,
+            float x2, float y2, float u2, float v2,
+            float x3, float y3, float u3, float v3,
+            float x4, float y4, float u4, float v4, CacheTexture* texture);
 
     uint32_t mSmallCacheWidth;
     uint32_t mSmallCacheHeight;
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 55e2ca5..73625b7 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -21,6 +21,7 @@
 #include <sys/types.h>
 
 #include <SkCanvas.h>
+#include <SkPathMeasure.h>
 #include <SkTypeface.h>
 
 #include <utils/Log.h>
@@ -2292,6 +2293,56 @@
     drawTextDecorations(text, bytesCount, length, oldX, oldY, paint);
 }
 
+void OpenGLRenderer::drawTextOnPath(const char* text, int bytesCount, int count, SkPath* path,
+        float hOffset, float vOffset, SkPaint* paint) {
+    if (text == NULL || count == 0 || mSnapshot->isIgnored() ||
+            (paint->getAlpha() == 0 && paint->getXfermode() == NULL)) {
+        return;
+    }
+
+    FontRenderer& fontRenderer = mCaches.fontRenderer.getFontRenderer(paint);
+    fontRenderer.setFont(paint, SkTypeface::UniqueID(paint->getTypeface()),
+            paint->getTextSize());
+
+    int alpha;
+    SkXfermode::Mode mode;
+    getAlphaAndMode(paint, &alpha, &mode);
+
+    mCaches.activeTexture(0);
+    setupDraw();
+    setupDrawDirtyRegionsDisabled();
+    setupDrawWithTexture(true);
+    setupDrawAlpha8Color(paint->getColor(), alpha);
+    setupDrawColorFilter();
+    setupDrawShader();
+    setupDrawBlending(true, mode);
+    setupDrawProgram();
+    setupDrawModelView(0.0f, 0.0f, 0.0f, 0.0f, false, true);
+    setupDrawTexture(fontRenderer.getTexture(true));
+    setupDrawPureColorUniforms();
+    setupDrawColorFilterUniforms();
+    setupDrawShaderUniforms(false);
+
+    const Rect* clip = &mSnapshot->getLocalClip();
+    Rect bounds(FLT_MAX / 2.0f, FLT_MAX / 2.0f, FLT_MIN / 2.0f, FLT_MIN / 2.0f);
+
+#if RENDER_LAYERS_AS_REGIONS
+    const bool hasActiveLayer = hasLayer();
+#else
+    const bool hasActiveLayer = false;
+#endif
+
+    if (fontRenderer.renderTextOnPath(paint, clip, text, 0, bytesCount, count, path,
+            hOffset, vOffset, hasActiveLayer ? &bounds : NULL)) {
+#if RENDER_LAYERS_AS_REGIONS
+        if (hasActiveLayer) {
+            mSnapshot->transform->mapRect(bounds);
+            dirtyLayerUnchecked(bounds, getRegion());
+        }
+#endif
+    }
+}
+
 void OpenGLRenderer::drawPath(SkPath* path, SkPaint* paint) {
     if (mSnapshot->isIgnored()) return;
 
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index 3f63c3fe..4d7a491 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -124,8 +124,10 @@
     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, float length = -1.0f);
-    virtual void drawPosText(const char* text, int bytesCount, int count, const float* positions,
-            SkPaint* paint);
+    virtual void drawTextOnPath(const char* text, int bytesCount, int count, SkPath* path,
+            float hOffset, float vOffset, SkPaint* paint);
+    virtual void drawPosText(const char* text, int bytesCount, int count,
+            const float* positions, SkPaint* paint);
 
     virtual void resetShader();
     virtual void setupShader(SkiaShader* shader);
diff --git a/libs/rs/Allocation.cpp b/libs/rs/Allocation.cpp
index 46df171..d69c55f 100644
--- a/libs/rs/Allocation.cpp
+++ b/libs/rs/Allocation.cpp
@@ -14,6 +14,8 @@
  * limitations under the License.
  */
 
+#define LOG_TAG "libRS_cpp"
+
 #include <utils/Log.h>
 #include <malloc.h>
 
diff --git a/libs/rs/BaseObj.cpp b/libs/rs/BaseObj.cpp
index 66e6fac..82e51e7 100644
--- a/libs/rs/BaseObj.cpp
+++ b/libs/rs/BaseObj.cpp
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
+#define LOG_TAG "libRS_cpp"
 
 #include <rs.h>
 
diff --git a/libs/rs/Element.cpp b/libs/rs/Element.cpp
index d193892..f318d40 100644
--- a/libs/rs/Element.cpp
+++ b/libs/rs/Element.cpp
@@ -14,6 +14,8 @@
  * limitations under the License.
  */
 
+#define LOG_TAG "libRS_cpp"
+
 #include <utils/Log.h>
 #include <malloc.h>
 #include <string.h>
diff --git a/libs/rs/RenderScript.cpp b/libs/rs/RenderScript.cpp
index 39f1024..0b42055 100644
--- a/libs/rs/RenderScript.cpp
+++ b/libs/rs/RenderScript.cpp
@@ -14,6 +14,8 @@
  * limitations under the License.
  */
 
+#define LOG_TAG "libRS_cpp"
+
 #include <utils/Log.h>
 #include <malloc.h>
 #include <string.h>
diff --git a/libs/rs/Script.cpp b/libs/rs/Script.cpp
index b6112dd..25fa673 100644
--- a/libs/rs/Script.cpp
+++ b/libs/rs/Script.cpp
@@ -14,6 +14,8 @@
  * limitations under the License.
  */
 
+#define LOG_TAG "libRS_cpp"
+
 #include <utils/Log.h>
 #include <malloc.h>
 
diff --git a/libs/rs/ScriptC.cpp b/libs/rs/ScriptC.cpp
index 53d75b8..ad82ff4 100644
--- a/libs/rs/ScriptC.cpp
+++ b/libs/rs/ScriptC.cpp
@@ -14,6 +14,8 @@
  * limitations under the License.
  */
 
+#define LOG_TAG "libRS_cpp"
+
 #include <utils/Log.h>
 #include <malloc.h>
 
diff --git a/libs/rs/ScriptC.h b/libs/rs/ScriptC.h
index 25f00ec..dcbbe10 100644
--- a/libs/rs/ScriptC.h
+++ b/libs/rs/ScriptC.h
@@ -24,7 +24,6 @@
 
 class ScriptC : public Script {
 protected:
-    ScriptC(RenderScript *rs, void *txt, size_t len);
     ScriptC(RenderScript *rs,
             const char *codeTxt, size_t codeLength,
             const char *cachedName, size_t cachedNameLength,
diff --git a/libs/rs/Type.cpp b/libs/rs/Type.cpp
index 3249f97..1352bd7 100644
--- a/libs/rs/Type.cpp
+++ b/libs/rs/Type.cpp
@@ -14,6 +14,8 @@
  * limitations under the License.
  */
 
+#define LOG_TAG "libRS_cpp"
+
 #include <utils/Log.h>
 #include <malloc.h>
 #include <string.h>
@@ -124,7 +126,6 @@
 }
 
 const Type * Type::Builder::create() {
-    ALOGE(" %i %i %i %i %i", mDimX, mDimY, mDimZ, mDimFaces, mDimMipmaps);
     if (mDimZ > 0) {
         if ((mDimX < 1) || (mDimY < 1)) {
             ALOGE("Both X and Y dimension required when Z is present.");
diff --git a/libs/rs/driver/rsdGL.cpp b/libs/rs/driver/rsdGL.cpp
index b136cc7..1b12235 100644
--- a/libs/rs/driver/rsdGL.cpp
+++ b/libs/rs/driver/rsdGL.cpp
@@ -16,8 +16,8 @@
 
 #include <ui/FramebufferNativeWindow.h>
 #include <ui/PixelFormat.h>
-#include <ui/EGLUtils.h>
-#include <ui/egl/android_natives.h>
+
+#include <system/window.h>
 
 #include <sys/types.h>
 #include <sys/resource.h>
@@ -47,6 +47,29 @@
 static int32_t gGLContextCount = 0;
 
 static void checkEglError(const char* op, EGLBoolean returnVal = EGL_TRUE) {
+    struct EGLUtils {
+        static const char *strerror(EGLint err) {
+            switch (err){
+                case EGL_SUCCESS:           return "EGL_SUCCESS";
+                case EGL_NOT_INITIALIZED:   return "EGL_NOT_INITIALIZED";
+                case EGL_BAD_ACCESS:        return "EGL_BAD_ACCESS";
+                case EGL_BAD_ALLOC:         return "EGL_BAD_ALLOC";
+                case EGL_BAD_ATTRIBUTE:     return "EGL_BAD_ATTRIBUTE";
+                case EGL_BAD_CONFIG:        return "EGL_BAD_CONFIG";
+                case EGL_BAD_CONTEXT:       return "EGL_BAD_CONTEXT";
+                case EGL_BAD_CURRENT_SURFACE: return "EGL_BAD_CURRENT_SURFACE";
+                case EGL_BAD_DISPLAY:       return "EGL_BAD_DISPLAY";
+                case EGL_BAD_MATCH:         return "EGL_BAD_MATCH";
+                case EGL_BAD_NATIVE_PIXMAP: return "EGL_BAD_NATIVE_PIXMAP";
+                case EGL_BAD_NATIVE_WINDOW: return "EGL_BAD_NATIVE_WINDOW";
+                case EGL_BAD_PARAMETER:     return "EGL_BAD_PARAMETER";
+                case EGL_BAD_SURFACE:       return "EGL_BAD_SURFACE";
+                case EGL_CONTEXT_LOST:      return "EGL_CONTEXT_LOST";
+                default: return "UNKNOWN";
+            }
+        }
+    };
+
     if (returnVal != EGL_TRUE) {
         fprintf(stderr, "%s() returned %d\n", op, returnVal);
     }
@@ -455,3 +478,37 @@
     }
 
 }
+
+void rsdGLClearColor(const android::renderscript::Context *rsc,
+                     float r, float g, float b, float a) {
+    RSD_CALL_GL(glClearColor, r, g, b, a);
+    RSD_CALL_GL(glClear, GL_COLOR_BUFFER_BIT);
+}
+
+void rsdGLClearDepth(const android::renderscript::Context *rsc, float v) {
+    RSD_CALL_GL(glClearDepthf, v);
+    RSD_CALL_GL(glClear, GL_DEPTH_BUFFER_BIT);
+}
+
+void rsdGLFinish(const android::renderscript::Context *rsc) {
+    RSD_CALL_GL(glFinish);
+}
+
+void rsdGLDrawQuadTexCoords(const android::renderscript::Context *rsc,
+                            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) {
+
+    float vtx[] = {x1,y1,z1, x2,y2,z2, x3,y3,z3, x4,y4,z4};
+    const float tex[] = {u1,v1, u2,v2, u3,v3, u4,v4};
+
+    RsdVertexArray::Attrib attribs[2];
+    attribs[0].set(GL_FLOAT, 3, 12, false, (uint32_t)vtx, "ATTRIB_position");
+    attribs[1].set(GL_FLOAT, 2, 8, false, (uint32_t)tex, "ATTRIB_texture0");
+
+    RsdVertexArray va(attribs, 2);
+    va.setup(rsc);
+
+    RSD_CALL_GL(glDrawArrays, GL_TRIANGLE_FAN, 0, 4);
+}
diff --git a/libs/rs/driver/rsdGL.h b/libs/rs/driver/rsdGL.h
index e015cb1..1e5b40f 100644
--- a/libs/rs/driver/rsdGL.h
+++ b/libs/rs/driver/rsdGL.h
@@ -84,6 +84,15 @@
                      const char *msg, bool isFatal = false);
 void rsdGLSetPriority(const android::renderscript::Context *rsc,
                       int32_t priority);
+void rsdGLClearColor(const android::renderscript::Context *rsc,
+                     float r, float g, float b, float a);
+void rsdGLClearDepth(const android::renderscript::Context *rsc, float v);
+void rsdGLFinish(const android::renderscript::Context *rsc);
+void rsdGLDrawQuadTexCoords(const android::renderscript::Context *rsc,
+                            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);
 
 #endif
 
diff --git a/libs/rs/driver/rsdRuntimeStubs.cpp b/libs/rs/driver/rsdRuntimeStubs.cpp
index 44bfb1c..aa9f159 100644
--- a/libs/rs/driver/rsdRuntimeStubs.cpp
+++ b/libs/rs/driver/rsdRuntimeStubs.cpp
@@ -257,17 +257,19 @@
 
 static void SC_Finish() {
     GET_TLS();
-    rsrFinish(rsc, sc);
+    rsdGLFinish(rsc);
 }
 
 static void SC_ClearColor(float r, float g, float b, float a) {
     GET_TLS();
-    rsrClearColor(rsc, sc, r, g, b, a);
+    rsrPrepareClear(rsc, sc);
+    rsdGLClearColor(rsc, r, g, b, a);
 }
 
 static void SC_ClearDepth(float v) {
     GET_TLS();
-    rsrClearDepth(rsc, sc, v);
+    rsrPrepareClear(rsc, sc);
+    rsdGLClearDepth(rsc, v);
 }
 
 static uint32_t SC_GetWidth() {
diff --git a/libs/rs/rsRuntime.h b/libs/rs/rsRuntime.h
index 3bded62..64f2de8 100644
--- a/libs/rs/rsRuntime.h
+++ b/libs/rs/rsRuntime.h
@@ -86,7 +86,6 @@
 
 
 void rsrColor(Context *, Script *, float r, float g, float b, float a);
-void rsrFinish(Context *, Script *);
 void rsrAllocationSyncAll(Context *, Script *, Allocation *);
 
 void rsrAllocationCopy1DRange(Context *, Allocation *dstAlloc,
@@ -103,8 +102,7 @@
                               uint32_t srcXoff, uint32_t srcYoff,
                               uint32_t srcMip, uint32_t srcFace);
 
-void rsrClearColor(Context *, Script *, float r, float g, float b, float a);
-void rsrClearDepth(Context *, Script *, float v);
+void rsrPrepareClear(Context *, Script *);
 uint32_t rsrGetWidth(Context *, Script *);
 uint32_t rsrGetHeight(Context *, Script *);
 void rsrDrawTextAlloc(Context *, Script *, Allocation *, int x, int y);
diff --git a/libs/rs/rsScriptC_LibGL.cpp b/libs/rs/rsScriptC_LibGL.cpp
index 97469d3..bda18fd 100644
--- a/libs/rs/rsScriptC_LibGL.cpp
+++ b/libs/rs/rsScriptC_LibGL.cpp
@@ -269,25 +269,9 @@
     pf->setConstantColor(rsc, r, g, b, a);
 }
 
-void rsrFinish(Context *rsc, Script *sc) {
-    RSD_CALL_GL(glFinish);
-}
-
-
-void rsrClearColor(Context *rsc, Script *sc, float r, float g, float b, float a) {
+void rsrPrepareClear(Context *rsc, Script *sc) {
     rsc->mFBOCache.setup(rsc);
     rsc->setupProgramStore();
-
-    RSD_CALL_GL(glClearColor, r, g, b, a);
-    RSD_CALL_GL(glClear, GL_COLOR_BUFFER_BIT);
-}
-
-void rsrClearDepth(Context *rsc, Script *sc, float v) {
-    rsc->mFBOCache.setup(rsc);
-    rsc->setupProgramStore();
-
-    RSD_CALL_GL(glClearDepthf, v);
-    RSD_CALL_GL(glClear, GL_DEPTH_BUFFER_BIT);
 }
 
 uint32_t rsrGetWidth(Context *rsc, Script *sc) {
diff --git a/libs/rs/tests/Android.mk b/libs/rs/tests/Android.mk
index a773e84..197e862 100644
--- a/libs/rs/tests/Android.mk
+++ b/libs/rs/tests/Android.mk
@@ -2,7 +2,8 @@
 include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES:= \
-	compute.cpp
+	compute.cpp \
+	ScriptC_mono.cpp
 
 LOCAL_SHARED_LIBRARIES := \
 	libRS \
diff --git a/libs/rs/tests/ScriptC_mono.cpp b/libs/rs/tests/ScriptC_mono.cpp
new file mode 100644
index 0000000..7f83616a
--- /dev/null
+++ b/libs/rs/tests/ScriptC_mono.cpp
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2008-2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "ScriptC_mono.h"
+
+static const char mono[] = \
+    "\xDE\xC0\x17\x0B\x00\x00\x00\x00\x18\x00\x00\x00\xFC\x03\x00\x00\x00\x00\x00\x00" \
+    "\x10\x00\x00\x00\x42\x43\xC0\xDE\x21\x0C\x00\x00\xFC\x00\x00\x00\x01\x10\x00\x00" \
+    "\x12\x00\x00\x00\x07\x81\x23\x91\x41\xC8\x04\x49\x06\x10\x32\x39\x92\x01\x84\x0C" \
+    "\x25\x05\x08\x19\x1E\x04\x8B\x62\x80\x14\x45\x02\x42\x92\x0B\x42\xA4\x10\x32\x14" \
+    "\x38\x08\x18\x49\x0A\x32\x44\x24\x48\x0A\x90\x21\x23\xC4\x52\x80\x0C\x19\x21\x72" \
+    "\x24\x07\xC8\x48\x11\x62\xA8\xA0\xA8\x40\xC6\xF0\x01\x00\x00\x00\x49\x18\x00\x00" \
+    "\x08\x00\x00\x00\x0B\x8C\x00\x04\x41\x10\x04\x09\x01\x04\x41\x10\x04\x89\xFF\xFF" \
+    "\xFF\xFF\x1F\xC0\x60\x81\xF0\xFF\xFF\xFF\xFF\x03\x18\x00\x00\x00\x89\x20\x00\x00" \
+    "\x13\x00\x00\x00\x32\x22\x48\x09\x20\x64\x85\x04\x93\x22\xA4\x84\x04\x93\x22\xE3" \
+    "\x84\xA1\x90\x14\x12\x4C\x8A\x8C\x0B\x84\xA4\x4C\x10\x48\x23\x00\x73\x04\xC8\x30" \
+    "\x02\x11\x90\x28\x03\x18\x83\xC8\x0C\xC0\x30\x02\x61\x14\xE1\x08\x42\xC3\x08\x83" \
+    "\x51\x06\xA3\x14\xAD\x22\x08\x45\x6D\x20\x60\x8E\x00\x0C\x86\x11\x06\x08\x00\x00" \
+    "\x13\xB0\x70\x90\x87\x76\xB0\x87\x3B\x68\x03\x77\x78\x07\x77\x28\x87\x36\x60\x87" \
+    "\x74\x70\x87\x7A\xC0\x87\x36\x38\x07\x77\xA8\x87\x72\x08\x07\x71\x48\x87\x0D\xF2" \
+    "\x50\x0E\x6D\x00\x0F\x7A\x30\x07\x72\xA0\x07\x73\x20\x07\x7A\x30\x07\x72\xD0\x06" \
+    "\xE9\x10\x07\x7A\x80\x07\x7A\x80\x07\x6D\x90\x0E\x78\xA0\x07\x78\xA0\x07\x78\xD0" \
+    "\x06\xE9\x10\x07\x76\xA0\x07\x71\x60\x07\x7A\x10\x07\x76\xD0\x06\xE9\x30\x07\x72" \
+    "\xA0\x07\x73\x20\x07\x7A\x30\x07\x72\xD0\x06\xE9\x60\x07\x74\xA0\x07\x76\x40\x07" \
+    "\x7A\x60\x07\x74\xD0\x06\xE6\x30\x07\x72\xA0\x07\x73\x20\x07\x7A\x30\x07\x72\xD0" \
+    "\x06\xE6\x60\x07\x74\xA0\x07\x76\x40\x07\x7A\x60\x07\x74\xD0\x06\xF6\x60\x07\x74" \
+    "\xA0\x07\x76\x40\x07\x7A\x60\x07\x74\xD0\x06\xF6\x10\x07\x72\x80\x07\x7A\x60\x07" \
+    "\x74\xA0\x07\x71\x20\x07\x78\xD0\x06\xE1\x00\x07\x7A\x00\x07\x7A\x60\x07\x74\xD0" \
+    "\x06\xEE\x30\x07\x72\xD0\x06\xB3\x60\x07\x74\x30\x44\x29\x00\x00\x08\x00\x00\x00" \
+    "\x80\x21\x4A\x02\x04\x00\x00\x00\x00\x00\x0C\x51\x18\x20\x00\x00\x00\x00\x00\x60" \
+    "\x88\xE2\x00\x01\x00\x00\x00\x00\x00\x79\x18\x00\x45\x00\x00\x00\x43\x88\x27\x78" \
+    "\x84\x05\x87\x3D\x94\x83\x3C\xCC\x43\x3A\xBC\x83\x3B\x2C\x08\xE2\x60\x08\xF1\x10" \
+    "\x4F\xB1\x20\x52\x87\x70\xB0\x87\x70\xF8\x05\x78\x08\x87\x71\x58\x87\x70\x38\x87" \
+    "\x72\xF8\x05\x77\x08\x87\x76\x28\x87\x05\x63\x30\x0E\xEF\xD0\x0E\x6E\x50\x0E\xF8" \
+    "\x10\x0E\xED\x00\x0F\xEC\x50\x0E\x6E\x10\x0E\xEE\x40\x0E\xF2\xF0\x0E\xE9\x40\x0E" \
+    "\x6E\x20\x0F\xF3\xE0\x06\xE8\x50\x0E\xEC\xC0\x0E\xEF\x30\x0E\xEF\xD0\x0E\xF0\x50" \
+    "\x0F\xF4\x50\x0E\x43\x84\xE7\x58\x40\xC8\xC3\x3B\xBC\x03\x3D\x0C\x11\x9E\x64\x41" \
+    "\x30\x07\x43\x88\x67\x79\x98\x05\xCF\x3B\xB4\x83\x3B\xA4\x03\x3C\xBC\x03\x3D\x94" \
+    "\x83\x3B\xD0\x03\x18\x8C\x03\x3A\x84\x83\x3C\x0C\x21\x9E\x06\x00\x16\x44\xB3\x90" \
+    "\x0E\xED\x00\x0F\xEC\x50\x0E\x60\x30\x0A\x6F\x30\x0A\x6B\xB0\x06\x60\x40\x0B\xA2" \
+    "\x10\x0A\xA1\x30\xE2\x18\x03\x78\x90\x87\x70\x38\x87\x76\x08\x87\x29\x02\x30\x8C" \
+    "\xB8\xC6\x40\x1E\xE6\xE1\x17\xCA\x01\x1F\xE0\xE1\x1D\xE4\x81\x1E\x7E\xC1\x1C\xDE" \
+    "\x41\x1E\xCA\x21\x1C\xC6\x01\x1D\x7E\xC1\x1D\xC2\xA1\x1D\xCA\x61\x4A\x60\x8C\x90" \
+    "\xC6\x40\x1E\xE6\xE1\x17\xCA\x01\x1F\xE0\xE1\x1D\xE4\x81\x1E\x7E\xC1\x1C\xDE\x41" \
+    "\x1E\xCA\x21\x1C\xC6\x01\x1D\xA6\x04\x08\x00\x00\x61\x20\x00\x00\x24\x00\x00\x00" \
+    "\x13\x04\x41\x2C\x10\x00\x00\x00\x0C\x00\x00\x00\x04\x8B\xA0\x04\x46\x00\xE8\xCC" \
+    "\x00\x90\x9A\x01\x98\x63\x70\x1A\x86\xCC\x18\x41\x6D\xFA\xB2\xEF\x8D\x11\x88\x6D" \
+    "\xCC\xC6\xDF\x18\xC1\x49\x97\x72\xFA\x51\x9C\x63\x40\x0E\x63\x04\x00\x00\x00\x00" \
+    "\x44\x8C\x11\x03\x42\x08\x82\x68\x90\x41\x4A\x9E\x11\x83\x42\x08\x84\x69\x99\x63" \
+    "\x50\x28\x64\x90\xA1\x52\xA0\x11\x03\x42\x08\x06\x6B\x30\xA2\xB8\x06\x00\xC3\x81" \
+    "\x00\x00\x00\x00\x03\x00\x00\x00\x46\x40\x54\x3F\xD2\x58\x41\x51\xFD\x0E\x35\x01" \
+    "\x01\x31\x00\x00\x03\x00\x00\x00\x5B\x06\x20\x50\xB6\x0C\x47\xA0\x00\x00\x00\x00" \
+    "\x00\x00\x00\x00\x79\x18\x00\x00\x0B\x00\x00\x00\x33\x08\x80\x1C\xC4\xE1\x1C\x66" \
+    "\x14\x01\x3D\x88\x43\x38\x84\xC3\x8C\x42\x80\x07\x79\x78\x07\x73\x98\xB1\x0C\xE6" \
+    "\x00\x0F\xE1\x30\x0E\xE3\x50\x0F\xF2\x10\x0E\xE3\x90\x0F\x00\x00\x71\x20\x00\x00" \
+    "\x0E\x00\x00\x00\x06\x40\x44\x8E\x33\x59\x40\x14\x49\x6E\xF3\x00\x82\xC2\x39\x8B" \
+    "\x13\xF1\x3C\xCF\x9B\x40\xF3\xCF\xF7\xE0\x4C\x5D\x75\xFF\x05\xFB\xDB\x80\xF6\xCF" \
+    "\xF5\x1E\x49\x29\x20\x28\x9C\xB3\x38\x51\xEB\xF0\x3C\xCF\x77\xD5\xFD\x17\x00\x00" \
+    "\x00\x00\x00\x00";
+
+
+ScriptC_mono::ScriptC_mono(RenderScript *rs, const char *cacheDir, size_t cacheDirLength) :
+    ScriptC(rs, mono, sizeof(mono) - 1, "mono", 4, cacheDir, cacheDirLength) {
+
+    printf("sizeof text %i", sizeof(mono));
+
+
+
+}
+
+void ScriptC_mono::forEach_root(const Allocation *ain, const Allocation *aout) {
+    forEach(0, ain, aout, NULL, 0);
+}
+
diff --git a/include/ui/android_native_buffer.h b/libs/rs/tests/ScriptC_mono.h
similarity index 66%
rename from include/ui/android_native_buffer.h
rename to libs/rs/tests/ScriptC_mono.h
index b6e1db4..7e4f601 100644
--- a/include/ui/android_native_buffer.h
+++ b/libs/rs/tests/ScriptC_mono.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009 The Android Open Source Project
+ * Copyright (C) 2008-2012 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,9 +14,13 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_ANDROID_NATIVES_PRIV_H
-#define ANDROID_ANDROID_NATIVES_PRIV_H
+#include "ScriptC.h"
 
-#include <ui/egl/android_natives.h>
+class ScriptC_mono : protected ScriptC {
+public:
+    ScriptC_mono(RenderScript *rs, const char *cacheDir, size_t cacheDirLength);
 
-#endif /* ANDROID_ANDROID_NATIVES_PRIV_H */
+    void forEach_root(const Allocation *ain, const Allocation *aout);
+
+};
+
diff --git a/libs/rs/tests/compute.cpp b/libs/rs/tests/compute.cpp
index 28b135f..42eaa52 100644
--- a/libs/rs/tests/compute.cpp
+++ b/libs/rs/tests/compute.cpp
@@ -4,6 +4,8 @@
 #include "Type.h"
 #include "Allocation.h"
 
+#include "ScriptC_mono.h"
+
 int main(int argc, char** argv)
 {
 
@@ -23,12 +25,31 @@
     printf("Type %p\n", t);
 
 
-    const Allocation *a1 = Allocation::createSized(rs, e, 1000);
+    Allocation *a1 = Allocation::createSized(rs, e, 1000);
     printf("Allocation %p\n", a1);
 
+    Allocation *ain = Allocation::createTyped(rs, t);
+    Allocation *aout = Allocation::createTyped(rs, t);
+    printf("Allocation %p %p\n", ain, aout);
+
+    ScriptC_mono * sc = new ScriptC_mono(rs, NULL, 0);
+    printf("new script\n");
+
+    uint32_t *buf = new uint32_t[t->getCount()];
+    for (uint32_t ct=0; ct < t->getCount(); ct++) {
+        buf[ct] = ct | (ct << 16);
+    }
+    //ain->copy1DRangeFrom(0, 128*128, (int32_t *)buf, 128*128*4);
+    ain->copy1DRangeFromUnchecked(0, t->getCount(), buf, t->getCount()*4);
+
+
+
+    sc->forEach_root(ain, aout);
+    printf("for each done\n");
 
 
     printf("Deleting stuff\n");
+    delete sc;
     delete t;
     delete a1;
     delete e;
diff --git a/libs/surfaceflinger_client/Android.mk b/libs/surfaceflinger_client/Android.mk
deleted file mode 100644
index 5fca1ce..0000000
--- a/libs/surfaceflinger_client/Android.mk
+++ /dev/null
@@ -1,10 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:=
-
-LOCAL_SHARED_LIBRARIES := 
-
-LOCAL_MODULE:= libsurfaceflinger_client
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/libs/ui/Android.mk b/libs/ui/Android.mk
index c029291..5aff7a4 100644
--- a/libs/ui/Android.mk
+++ b/libs/ui/Android.mk
@@ -16,7 +16,6 @@
 include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES:= \
-	EGLUtils.cpp \
 	FramebufferNativeWindow.cpp \
 	GraphicBuffer.cpp \
 	GraphicBufferAllocator.cpp \
@@ -28,7 +27,6 @@
 LOCAL_SHARED_LIBRARIES := \
 	libcutils \
 	libutils \
-	libEGL \
 	libhardware
 
 ifneq ($(BOARD_FRAMEBUFFER_FORCE_FORMAT),)
diff --git a/libs/ui/FramebufferNativeWindow.cpp b/libs/ui/FramebufferNativeWindow.cpp
index 26d4823..dec99b6 100644
--- a/libs/ui/FramebufferNativeWindow.cpp
+++ b/libs/ui/FramebufferNativeWindow.cpp
@@ -27,25 +27,21 @@
 #include <utils/threads.h>
 #include <utils/RefBase.h>
 
-#include <ui/Rect.h>
+#include <ui/ANativeObjectBase.h>
 #include <ui/FramebufferNativeWindow.h>
+#include <ui/Rect.h>
 
 #include <EGL/egl.h>
 
-#include <pixelflinger/format.h>
-#include <pixelflinger/pixelflinger.h>
-
 #include <hardware/hardware.h>
 #include <hardware/gralloc.h>
 
-#include <private/ui/android_natives_priv.h>
-
 // ----------------------------------------------------------------------------
 namespace android {
 // ----------------------------------------------------------------------------
 
 class NativeBuffer 
-    : public EGLNativeBase<
+    : public ANativeObjectBase<
         ANativeWindowBuffer, 
         NativeBuffer, 
         LightRefBase<NativeBuffer> >
diff --git a/libs/ui/GraphicBuffer.cpp b/libs/ui/GraphicBuffer.cpp
index f549a37..57063e5 100644
--- a/libs/ui/GraphicBuffer.cpp
+++ b/libs/ui/GraphicBuffer.cpp
@@ -28,8 +28,6 @@
 #include <ui/GraphicBufferMapper.h>
 #include <ui/PixelFormat.h>
 
-#include <pixelflinger/pixelflinger.h>
-
 namespace android {
 
 // ===========================================================================
@@ -182,21 +180,6 @@
     return res;
 }
 
-status_t GraphicBuffer::lock(GGLSurface* sur, uint32_t usage) 
-{
-    void* vaddr;
-    status_t res = GraphicBuffer::lock(usage, &vaddr);
-    if (res == NO_ERROR && sur) {
-        sur->version = sizeof(GGLSurface);
-        sur->width = width;
-        sur->height = height;
-        sur->stride = stride;
-        sur->format = format;
-        sur->data = static_cast<GGLubyte*>(vaddr);
-    }
-    return res;
-}
-
 size_t GraphicBuffer::getFlattenedSize() const {
     return (8 + (handle ? handle->numInts : 0))*sizeof(int);
 }
diff --git a/libs/ui/PixelFormat.cpp b/libs/ui/PixelFormat.cpp
index 6993dac..fc1d3c2 100644
--- a/libs/ui/PixelFormat.cpp
+++ b/libs/ui/PixelFormat.cpp
@@ -48,7 +48,10 @@
         { 4, 32, {32,24,  24,16,  16, 8,   8, 0 }, PixelFormatInfo::RGBA },
         { 2, 16, { 1, 0,  16,11,  11, 6,   6, 1 }, PixelFormatInfo::RGBA },
         { 2, 16, { 4, 0,  16,12,  12, 8,   8, 4 }, PixelFormatInfo::RGBA },
-        { 1,  8, { 8, 0,   0, 0,   0, 0,   0, 0 }, PixelFormatInfo::ALPHA}
+        { 1,  8, { 8, 0,   0, 0,   0, 0,   0, 0 }, PixelFormatInfo::ALPHA},
+        { 1,  8, { 0, 0,   8, 0,   8, 0,   8, 0 }, PixelFormatInfo::L    },
+        { 2, 16, {16, 8,   8, 0,   8, 0,   8, 0 }, PixelFormatInfo::LA   },
+        { 1,  8, { 0, 0,   8, 5,   5, 2,   2, 0 }, PixelFormatInfo::RGB  },
 };
 
 static const Info* gGetPixelFormatTable(size_t* numEntries) {
diff --git a/libs/utils/Android.mk b/libs/utils/Android.mk
index a96c8e6..57c048a 100644
--- a/libs/utils/Android.mk
+++ b/libs/utils/Android.mk
@@ -77,7 +77,8 @@
 # we have the common sources, plus some device-specific stuff
 LOCAL_SRC_FILES:= \
 	$(commonSources) \
-	Looper.cpp
+	Looper.cpp \
+	Trace.cpp
 
 ifeq ($(TARGET_OS),linux)
 LOCAL_LDLIBS += -lrt -ldl
diff --git a/libs/utils/BlobCache.cpp b/libs/utils/BlobCache.cpp
index e52cf2f..be398ee4 100644
--- a/libs/utils/BlobCache.cpp
+++ b/libs/utils/BlobCache.cpp
@@ -183,7 +183,7 @@
 status_t BlobCache::flatten(void* buffer, size_t size, int fds[], size_t count)
         const {
     if (count != 0) {
-        ALOGE("flatten: nonzero fd count: %d", count);
+        ALOGE("flatten: nonzero fd count: %zu", count);
         return BAD_VALUE;
     }
 
@@ -234,7 +234,7 @@
     mCacheEntries.clear();
 
     if (count != 0) {
-        ALOGE("unflatten: nonzero fd count: %d", count);
+        ALOGE("unflatten: nonzero fd count: %zu", count);
         return BAD_VALUE;
     }
 
diff --git a/libs/utils/Debug.cpp b/libs/utils/Debug.cpp
index f7988ec..e8ac983 100644
--- a/libs/utils/Debug.cpp
+++ b/libs/utils/Debug.cpp
@@ -199,7 +199,7 @@
     if ((int32_t)length < 0) {
         if (singleLineBytesCutoff < 0) func(cookie, "\n");
         char buf[64];
-        sprintf(buf, "(bad length: %d)", length);
+        sprintf(buf, "(bad length: %zu)", length);
         func(cookie, buf);
         return;
     }
diff --git a/libs/utils/Static.cpp b/libs/utils/Static.cpp
index bfcb2da..624e917 100644
--- a/libs/utils/Static.cpp
+++ b/libs/utils/Static.cpp
@@ -57,8 +57,8 @@
     virtual status_t writeLines(const struct iovec& vec, size_t N)
     {
         //android_writevLog(&vec, N);       <-- this is now a no-op
-        if (N != 1) ALOGI("WARNING: writeLines N=%d\n", N);
-        ALOGI("%.*s", vec.iov_len, (const char*) vec.iov_base);
+        if (N != 1) ALOGI("WARNING: writeLines N=%zu\n", N);
+        ALOGI("%.*s", (int)vec.iov_len, (const char*) vec.iov_base);
         return NO_ERROR;
     }
 };
diff --git a/libs/utils/StopWatch.cpp b/libs/utils/StopWatch.cpp
index 595aec3..b1708d62 100644
--- a/libs/utils/StopWatch.cpp
+++ b/libs/utils/StopWatch.cpp
@@ -20,6 +20,10 @@
 #include <stdlib.h>
 #include <stdio.h>
 
+/* for PRId64 */
+#define __STDC_FORMAT_MACROS 1
+#include <inttypes.h>
+
 #include <utils/Log.h>
 #include <utils/Errors.h>
 #include <utils/StopWatch.h>
@@ -39,11 +43,11 @@
 {
     nsecs_t elapsed = elapsedTime();
     const int n = mNumLaps;
-    ALOGD("StopWatch %s (us): %lld ", mName, ns2us(elapsed));
+    ALOGD("StopWatch %s (us): %" PRId64 " ", mName, ns2us(elapsed));
     for (int i=0 ; i<n ; i++) {
         const nsecs_t soFar = mLaps[i].soFar;
         const nsecs_t thisLap = mLaps[i].thisLap;
-        ALOGD(" [%d: %lld, %lld]", i, ns2us(soFar), ns2us(thisLap));
+        ALOGD(" [%d: %" PRId64 ", %" PRId64, i, ns2us(soFar), ns2us(thisLap));
     }
 }
 
diff --git a/libs/utils/Trace.cpp b/libs/utils/Trace.cpp
new file mode 100644
index 0000000..c49278a
--- /dev/null
+++ b/libs/utils/Trace.cpp
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <cutils/properties.h>
+#include <utils/Log.h>
+#include <utils/Trace.h>
+
+namespace android {
+
+volatile int32_t Tracer::sIsReady = 0;
+int Tracer::sTraceFD = -1;
+uint64_t Tracer::sEnabledTags = 0;
+Mutex Tracer::sMutex;
+
+void Tracer::init() {
+    Mutex::Autolock lock(sMutex);
+
+    if (!sIsReady) {
+        const char* const traceFileName =
+                "/sys/kernel/debug/tracing/trace_marker";
+        sTraceFD = open(traceFileName, O_WRONLY);
+        if (sTraceFD == -1) {
+            ALOGE("error opening trace file: %s (%d)", strerror(errno), errno);
+        } else {
+            char value[PROPERTY_VALUE_MAX];
+            property_get("atrace.tags.enableflags", value, "0");
+            sEnabledTags = strtoll(value, NULL, 0) | ATRACE_TAG_ALWAYS;
+        }
+
+        android_atomic_release_store(1, &sIsReady);
+    }
+}
+
+} // namespace andoid
diff --git a/media/jni/android_media_MediaCodec.cpp b/media/jni/android_media_MediaCodec.cpp
index 43ca263..71e698f 100644
--- a/media/jni/android_media_MediaCodec.cpp
+++ b/media/jni/android_media_MediaCodec.cpp
@@ -26,13 +26,15 @@
 #include "jni.h"
 #include "JNIHelp.h"
 
+#include <gui/Surface.h>
+#include <gui/SurfaceTextureClient.h>
+
 #include <media/stagefright/MediaCodec.h>
 #include <media/stagefright/foundation/ABuffer.h>
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/foundation/ALooper.h>
 #include <media/stagefright/foundation/AMessage.h>
 #include <media/stagefright/MediaErrors.h>
-#include <surfaceflinger/Surface.h>
 
 namespace android {
 
@@ -82,7 +84,7 @@
 }
 
 JMediaCodec::~JMediaCodec() {
-    mCodec->stop();
+    mCodec->release();
 
     JNIEnv *env = AndroidRuntime::getJNIEnv();
 
diff --git a/media/jni/android_media_MediaPlayer.cpp b/media/jni/android_media_MediaPlayer.cpp
index 199d56e4..f3a5668 100644
--- a/media/jni/android_media_MediaPlayer.cpp
+++ b/media/jni/android_media_MediaPlayer.cpp
@@ -39,7 +39,7 @@
 #include "android_util_Binder.h"
 #include <binder/Parcel.h>
 #include <gui/ISurfaceTexture.h>
-#include <surfaceflinger/Surface.h>
+#include <gui/Surface.h>
 #include <binder/IPCThreadState.h>
 #include <binder/IServiceManager.h>
 
diff --git a/media/jni/android_media_MediaRecorder.cpp b/media/jni/android_media_MediaRecorder.cpp
index acc65f1..b6e6ceb 100644
--- a/media/jni/android_media_MediaRecorder.cpp
+++ b/media/jni/android_media_MediaRecorder.cpp
@@ -18,7 +18,7 @@
 #define LOG_TAG "MediaRecorderJNI"
 #include <utils/Log.h>
 
-#include <surfaceflinger/SurfaceComposerClient.h>
+#include <gui/Surface.h>
 #include <camera/ICameraService.h>
 #include <camera/Camera.h>
 #include <media/mediarecorder.h>
diff --git a/media/jni/mediaeditor/VideoEditorMain.cpp b/media/jni/mediaeditor/VideoEditorMain.cpp
index c84a883..b0c1c35 100755
--- a/media/jni/mediaeditor/VideoEditorMain.cpp
+++ b/media/jni/mediaeditor/VideoEditorMain.cpp
@@ -29,8 +29,7 @@
 #include <VideoEditorThumbnailMain.h>
 #include <M4OSA_Debug.h>
 #include <M4xVSS_Internal.h>
-#include <surfaceflinger/Surface.h>
-#include <surfaceflinger/ISurface.h>
+#include <gui/Surface.h>
 #include "VideoEditorPreviewController.h"
 
 #include "VideoEditorMain.h"
diff --git a/media/libeffects/preprocessing/PreProcessing.cpp b/media/libeffects/preprocessing/PreProcessing.cpp
index 098a1a2..dc27d38 100755
--- a/media/libeffects/preprocessing/PreProcessing.cpp
+++ b/media/libeffects/preprocessing/PreProcessing.cpp
@@ -845,6 +845,17 @@
          config->inputCfg.samplingRate, config->inputCfg.channels);
     int status;
 
+    // if at least one process is enabled, do not accept configuration changes
+    if (session->enabledMsk) {
+        if (session->samplingRate != config->inputCfg.samplingRate ||
+                session->inChannelCount != inCnl ||
+                session->outChannelCount != outCnl) {
+            return -ENOSYS;
+        } else {
+            return 0;
+        }
+    }
+
     // AEC implementation is limited to 16kHz
     if (config->inputCfg.samplingRate >= 32000 && !(session->createdMsk & (1 << PREPROC_AEC))) {
         session->apmSamplingRate = 32000;
@@ -1287,7 +1298,9 @@
             if (*(int *)pReplyData != 0) {
                 break;
             }
-            *(int *)pReplyData = Effect_SetState(effect, PREPROC_EFFECT_STATE_CONFIG);
+            if (effect->state != PREPROC_EFFECT_STATE_ACTIVE) {
+                *(int *)pReplyData = Effect_SetState(effect, PREPROC_EFFECT_STATE_CONFIG);
+            }
             break;
 
         case EFFECT_CMD_GET_CONFIG:
diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp
index a4068ff..943f3af 100644
--- a/media/libmedia/AudioRecord.cpp
+++ b/media/libmedia/AudioRecord.cpp
@@ -307,7 +307,7 @@
         pid_t tid;
         if (t != 0) {
             mReadyToRun = WOULD_BLOCK;
-            t->run("ClientRecordThread", ANDROID_PRIORITY_AUDIO);
+            t->run("AudioRecord", ANDROID_PRIORITY_AUDIO);
             tid = t->getTid();  // pid_t is unknown until run()
             ALOGV("getTid=%d", tid);
             if (tid == -1) {
@@ -386,7 +386,7 @@
     return !mActive;
 }
 
-uint32_t AudioRecord::getSampleRate()
+uint32_t AudioRecord::getSampleRate() const
 {
     AutoMutex lock(mLock);
     return mCblk->sampleRate;
@@ -402,7 +402,7 @@
     return NO_ERROR;
 }
 
-status_t AudioRecord::getMarkerPosition(uint32_t *marker)
+status_t AudioRecord::getMarkerPosition(uint32_t *marker) const
 {
     if (marker == NULL) return BAD_VALUE;
 
@@ -423,7 +423,7 @@
     return NO_ERROR;
 }
 
-status_t AudioRecord::getPositionUpdatePeriod(uint32_t *updatePeriod)
+status_t AudioRecord::getPositionUpdatePeriod(uint32_t *updatePeriod) const
 {
     if (updatePeriod == NULL) return BAD_VALUE;
 
@@ -432,7 +432,7 @@
     return NO_ERROR;
 }
 
-status_t AudioRecord::getPosition(uint32_t *position)
+status_t AudioRecord::getPosition(uint32_t *position) const
 {
     if (position == NULL) return BAD_VALUE;
 
@@ -442,7 +442,7 @@
     return NO_ERROR;
 }
 
-unsigned int AudioRecord::getInputFramesLost()
+unsigned int AudioRecord::getInputFramesLost() const
 {
     if (mActive)
         return AudioSystem::getInputFramesLost(mInput);
@@ -597,7 +597,7 @@
     mCblk->stepUser(audioBuffer->frameCount);
 }
 
-audio_io_handle_t AudioRecord::getInput()
+audio_io_handle_t AudioRecord::getInput() const
 {
     AutoMutex lock(mLock);
     return mInput;
@@ -615,7 +615,7 @@
     return mInput;
 }
 
-int AudioRecord::getSessionId()
+int AudioRecord::getSessionId() const
 {
     return mSessionId;
 }
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp
index 74c97ed..4890f05 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -370,7 +370,7 @@
         android_atomic_and(~CBLK_DISABLED_ON, &cblk->flags);
         pid_t tid;
         if (t != 0) {
-            t->run("AudioTrackThread", ANDROID_PRIORITY_AUDIO);
+            t->run("AudioTrack", ANDROID_PRIORITY_AUDIO);
             tid = t->getTid();  // pid_t is unknown until run()
             ALOGV("getTid=%d", tid);
             if (tid == -1) {
diff --git a/media/libmedia/IMediaPlayer.cpp b/media/libmedia/IMediaPlayer.cpp
index 64cc919..86d65db 100644
--- a/media/libmedia/IMediaPlayer.cpp
+++ b/media/libmedia/IMediaPlayer.cpp
@@ -23,8 +23,6 @@
 #include <media/IMediaPlayer.h>
 #include <media/IStreamSource.h>
 
-#include <surfaceflinger/ISurface.h>
-#include <surfaceflinger/Surface.h>
 #include <gui/ISurfaceTexture.h>
 #include <utils/String8.h>
 
diff --git a/media/libmedia/IMediaRecorder.cpp b/media/libmedia/IMediaRecorder.cpp
index 42f55c2..2f4e31a 100644
--- a/media/libmedia/IMediaRecorder.cpp
+++ b/media/libmedia/IMediaRecorder.cpp
@@ -19,10 +19,10 @@
 #define LOG_TAG "IMediaRecorder"
 #include <utils/Log.h>
 #include <binder/Parcel.h>
-#include <surfaceflinger/Surface.h>
 #include <camera/ICamera.h>
 #include <media/IMediaRecorderClient.h>
 #include <media/IMediaRecorder.h>
+#include <gui/Surface.h>
 #include <gui/ISurfaceTexture.h>
 #include <unistd.h>
 
diff --git a/media/libmedia/IOMX.cpp b/media/libmedia/IOMX.cpp
index 27c7e03..48e427a 100644
--- a/media/libmedia/IOMX.cpp
+++ b/media/libmedia/IOMX.cpp
@@ -22,8 +22,6 @@
 #include <binder/Parcel.h>
 #include <media/IOMX.h>
 #include <media/stagefright/foundation/ADebug.h>
-#include <surfaceflinger/ISurface.h>
-#include <surfaceflinger/Surface.h>
 
 namespace android {
 
diff --git a/media/libmedia/mediaplayer.cpp b/media/libmedia/mediaplayer.cpp
index 250425b..9d45907 100644
--- a/media/libmedia/mediaplayer.cpp
+++ b/media/libmedia/mediaplayer.cpp
@@ -32,8 +32,6 @@
 #include <media/mediaplayer.h>
 #include <media/AudioSystem.h>
 
-#include <surfaceflinger/Surface.h>
-
 #include <binder/MemoryBase.h>
 
 #include <utils/KeyedVector.h>
diff --git a/media/libmedia/mediarecorder.cpp b/media/libmedia/mediarecorder.cpp
index 8d947d8..cc73014 100644
--- a/media/libmedia/mediarecorder.cpp
+++ b/media/libmedia/mediarecorder.cpp
@@ -18,7 +18,6 @@
 //#define LOG_NDEBUG 0
 #define LOG_TAG "MediaRecorder"
 #include <utils/Log.h>
-#include <surfaceflinger/Surface.h>
 #include <media/mediarecorder.h>
 #include <binder/IServiceManager.h>
 #include <utils/String8.h>
diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp
index c5f4f86..ca79657 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.cpp
+++ b/media/libmediaplayerservice/StagefrightRecorder.cpp
@@ -40,7 +40,7 @@
 #include <media/MediaProfiles.h>
 #include <camera/ICamera.h>
 #include <camera/CameraParameters.h>
-#include <surfaceflinger/Surface.h>
+#include <gui/Surface.h>
 
 #include <utils/Errors.h>
 #include <sys/types.h>
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index dec1c08c..e618f67 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -38,7 +38,6 @@
 #include <media/stagefright/MediaDefs.h>
 #include <media/stagefright/MediaErrors.h>
 #include <media/stagefright/MetaData.h>
-#include <surfaceflinger/Surface.h>
 #include <gui/ISurfaceTexture.h>
 
 #include "avc_utils.h"
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.h b/media/libmediaplayerservice/nuplayer/NuPlayer.h
index ffc710e..6be14be 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.h
@@ -21,8 +21,6 @@
 #include <media/MediaPlayerInterface.h>
 #include <media/stagefright/foundation/AHandler.h>
 #include <media/stagefright/NativeWindowWrapper.h>
-#include <gui/SurfaceTextureClient.h>
-#include <surfaceflinger/Surface.h>
 
 namespace android {
 
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
index 2a51829..460fc98 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
@@ -29,8 +29,6 @@
 #include <media/stagefright/MediaDefs.h>
 #include <media/stagefright/MetaData.h>
 #include <media/stagefright/Utils.h>
-#include <surfaceflinger/Surface.h>
-#include <gui/ISurfaceTexture.h>
 
 namespace android {
 
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index c91fbe6..9a9d094 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -31,9 +31,6 @@
 #include <media/stagefright/OMXClient.h>
 #include <media/stagefright/OMXCodec.h>
 
-#include <surfaceflinger/Surface.h>
-#include <gui/SurfaceTextureClient.h>
-
 #include <OMX_Component.h>
 
 namespace android {
@@ -168,18 +165,36 @@
 
 protected:
     virtual bool onMessageReceived(const sp<AMessage> &msg);
+    virtual void stateEntered();
 
 private:
     void onSetup(const sp<AMessage> &msg);
-    void onAllocateComponent(const sp<AMessage> &msg);
-    void onConfigureComponent(const sp<AMessage> &msg);
-    void onStart();
+    bool onAllocateComponent(const sp<AMessage> &msg);
 
     DISALLOW_EVIL_CONSTRUCTORS(UninitializedState);
 };
 
 ////////////////////////////////////////////////////////////////////////////////
 
+struct ACodec::LoadedState : public ACodec::BaseState {
+    LoadedState(ACodec *codec);
+
+protected:
+    virtual bool onMessageReceived(const sp<AMessage> &msg);
+    virtual void stateEntered();
+
+private:
+    friend struct ACodec::UninitializedState;
+
+    bool onConfigureComponent(const sp<AMessage> &msg);
+    void onStart();
+    void onShutdown(bool keepComponentAllocated);
+
+    DISALLOW_EVIL_CONSTRUCTORS(LoadedState);
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
 struct ACodec::LoadedToIdleState : public ACodec::BaseState {
     LoadedToIdleState(ACodec *codec);
 
@@ -315,8 +330,10 @@
 ACodec::ACodec()
     : mNode(NULL),
       mSentFormat(false),
-      mIsEncoder(false) {
+      mIsEncoder(false),
+      mShutdownInProgress(false) {
     mUninitializedState = new UninitializedState(this);
+    mLoadedState = new LoadedState(this);
     mLoadedToIdleState = new LoadedToIdleState(this);
     mIdleToExecutingState = new IdleToExecutingState(this);
     mExecutingState = new ExecutingState(this);
@@ -372,8 +389,10 @@
     (new AMessage(kWhatResume, id()))->post();
 }
 
-void ACodec::initiateShutdown() {
-    (new AMessage(kWhatShutdown, id()))->post();
+void ACodec::initiateShutdown(bool keepComponentAllocated) {
+    sp<AMessage> msg = new AMessage(kWhatShutdown, id());
+    msg->setInt32("keepComponentAllocated", keepComponentAllocated);
+    msg->post();
 }
 
 status_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) {
@@ -2495,6 +2514,10 @@
     : BaseState(codec) {
 }
 
+void ACodec::UninitializedState::stateEntered() {
+    ALOGV("Now uninitialized");
+}
+
 bool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) {
     bool handled = false;
 
@@ -2514,22 +2537,13 @@
             break;
         }
 
-        case ACodec::kWhatConfigureComponent:
-        {
-            onConfigureComponent(msg);
-            handled = true;
-            break;
-        }
-
-        case ACodec::kWhatStart:
-        {
-            onStart();
-            handled = true;
-            break;
-        }
-
         case ACodec::kWhatShutdown:
         {
+            int32_t keepComponentAllocated;
+            CHECK(msg->findInt32(
+                        "keepComponentAllocated", &keepComponentAllocated));
+            CHECK(!keepComponentAllocated);
+
             sp<AMessage> notify = mCodec->mNotify->dup();
             notify->setInt32("what", ACodec::kWhatShutdownCompleted);
             notify->post();
@@ -2557,22 +2571,16 @@
 
 void ACodec::UninitializedState::onSetup(
         const sp<AMessage> &msg) {
-    onAllocateComponent(msg);
-    onConfigureComponent(msg);
-    onStart();
+    if (onAllocateComponent(msg)
+            && mCodec->mLoadedState->onConfigureComponent(msg)) {
+        mCodec->mLoadedState->onStart();
+    }
 }
 
-void ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
+bool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
     ALOGV("onAllocateComponent");
 
-    if (mCodec->mNode != NULL) {
-        CHECK_EQ(mCodec->mOMX->freeNode(mCodec->mNode), (status_t)OK);
-
-        mCodec->mNativeWindow.clear();
-        mCodec->mNode = NULL;
-        mCodec->mOMX.clear();
-        mCodec->mComponentName.clear();
-    }
+    CHECK(mCodec->mNode == NULL);
 
     OMXClient client;
     CHECK_EQ(client.connect(), (status_t)OK);
@@ -2631,7 +2639,7 @@
         }
 
         mCodec->signalError(OMX_ErrorComponentNotFound);
-        return;
+        return false;
     }
 
     sp<AMessage> notify = new AMessage(kWhatOMXMessage, mCodec->id());
@@ -2652,9 +2660,96 @@
         notify->setString("componentName", mCodec->mComponentName.c_str());
         notify->post();
     }
+
+    mCodec->changeState(mCodec->mLoadedState);
+
+    return true;
 }
 
-void ACodec::UninitializedState::onConfigureComponent(
+////////////////////////////////////////////////////////////////////////////////
+
+ACodec::LoadedState::LoadedState(ACodec *codec)
+    : BaseState(codec) {
+}
+
+void ACodec::LoadedState::stateEntered() {
+    ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str());
+
+    if (mCodec->mShutdownInProgress) {
+        bool keepComponentAllocated = mCodec->mKeepComponentAllocated;
+
+        mCodec->mShutdownInProgress = false;
+        mCodec->mKeepComponentAllocated = false;
+
+        onShutdown(keepComponentAllocated);
+    }
+}
+
+void ACodec::LoadedState::onShutdown(bool keepComponentAllocated) {
+    if (!keepComponentAllocated) {
+        CHECK_EQ(mCodec->mOMX->freeNode(mCodec->mNode), (status_t)OK);
+
+        mCodec->mNativeWindow.clear();
+        mCodec->mNode = NULL;
+        mCodec->mOMX.clear();
+        mCodec->mComponentName.clear();
+
+        mCodec->changeState(mCodec->mUninitializedState);
+    }
+
+    sp<AMessage> notify = mCodec->mNotify->dup();
+    notify->setInt32("what", ACodec::kWhatShutdownCompleted);
+    notify->post();
+}
+
+bool ACodec::LoadedState::onMessageReceived(const sp<AMessage> &msg) {
+    bool handled = false;
+
+    switch (msg->what()) {
+        case ACodec::kWhatConfigureComponent:
+        {
+            onConfigureComponent(msg);
+            handled = true;
+            break;
+        }
+
+        case ACodec::kWhatStart:
+        {
+            onStart();
+            handled = true;
+            break;
+        }
+
+        case ACodec::kWhatShutdown:
+        {
+            int32_t keepComponentAllocated;
+            CHECK(msg->findInt32(
+                        "keepComponentAllocated", &keepComponentAllocated));
+
+            onShutdown(keepComponentAllocated);
+
+            handled = true;
+            break;
+        }
+
+        case ACodec::kWhatFlush:
+        {
+            sp<AMessage> notify = mCodec->mNotify->dup();
+            notify->setInt32("what", ACodec::kWhatFlushCompleted);
+            notify->post();
+
+            handled = true;
+            break;
+        }
+
+        default:
+            return BaseState::onMessageReceived(msg);
+    }
+
+    return handled;
+}
+
+bool ACodec::LoadedState::onConfigureComponent(
         const sp<AMessage> &msg) {
     ALOGV("onConfigureComponent");
 
@@ -2667,7 +2762,7 @@
 
     if (err != OK) {
         mCodec->signalError(OMX_ErrorUndefined, err);
-        return;
+        return false;
     }
 
     sp<RefBase> obj;
@@ -2685,9 +2780,11 @@
         notify->setInt32("what", ACodec::kWhatComponentConfigured);
         notify->post();
     }
+
+    return true;
 }
 
-void ACodec::UninitializedState::onStart() {
+void ACodec::LoadedState::onStart() {
     ALOGV("onStart");
 
     CHECK_EQ(mCodec->mOMX->sendCommand(
@@ -2876,6 +2973,13 @@
     switch (msg->what()) {
         case kWhatShutdown:
         {
+            int32_t keepComponentAllocated;
+            CHECK(msg->findInt32(
+                        "keepComponentAllocated", &keepComponentAllocated));
+
+            mCodec->mShutdownInProgress = true;
+            mCodec->mKeepComponentAllocated = keepComponentAllocated;
+
             mActive = false;
 
             CHECK_EQ(mCodec->mOMX->sendCommand(
@@ -3213,20 +3317,7 @@
             CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
             CHECK_EQ(data2, (OMX_U32)OMX_StateLoaded);
 
-            ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str());
-
-            CHECK_EQ(mCodec->mOMX->freeNode(mCodec->mNode), (status_t)OK);
-
-            mCodec->mNativeWindow.clear();
-            mCodec->mNode = NULL;
-            mCodec->mOMX.clear();
-            mCodec->mComponentName.clear();
-
-            mCodec->changeState(mCodec->mUninitializedState);
-
-            sp<AMessage> notify = mCodec->mNotify->dup();
-            notify->setInt32("what", ACodec::kWhatShutdownCompleted);
-            notify->post();
+            mCodec->changeState(mCodec->mLoadedState);
 
             return true;
         }
diff --git a/media/libstagefright/Android.mk b/media/libstagefright/Android.mk
index cfb1e29..95bcada 100644
--- a/media/libstagefright/Android.mk
+++ b/media/libstagefright/Android.mk
@@ -58,6 +58,7 @@
 LOCAL_C_INCLUDES:= \
 	$(JNI_H_INCLUDE) \
         $(TOP)/frameworks/base/include/media/stagefright/openmax \
+        $(TOP)/frameworks/base/include/media/stagefright/timedtext \
         $(TOP)/external/flac/include \
         $(TOP)/external/tremolo \
         $(TOP)/external/openssl/include \
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index 70945e3..b21e86a 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -30,13 +30,12 @@
 #include "include/MPEG2TSExtractor.h"
 #include "include/WVMExtractor.h"
 
-#include "timedtext/TimedTextDriver.h"
-
 #include <binder/IPCThreadState.h>
 #include <binder/IServiceManager.h>
 #include <media/IMediaPlayerService.h>
 #include <media/stagefright/foundation/hexdump.h>
 #include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/timedtext/TimedTextDriver.h>
 #include <media/stagefright/AudioPlayer.h>
 #include <media/stagefright/DataSource.h>
 #include <media/stagefright/FileSource.h>
@@ -47,10 +46,8 @@
 #include <media/stagefright/MetaData.h>
 #include <media/stagefright/OMXCodec.h>
 
-#include <surfaceflinger/Surface.h>
 #include <gui/ISurfaceTexture.h>
 #include <gui/SurfaceTextureClient.h>
-#include <surfaceflinger/ISurfaceComposer.h>
 
 #include <media/stagefright/foundation/AMessage.h>
 
diff --git a/media/libstagefright/CameraSource.cpp b/media/libstagefright/CameraSource.cpp
index ed1d5f4..2df55282 100755
--- a/media/libstagefright/CameraSource.cpp
+++ b/media/libstagefright/CameraSource.cpp
@@ -27,7 +27,7 @@
 #include <media/stagefright/MetaData.h>
 #include <camera/Camera.h>
 #include <camera/CameraParameters.h>
-#include <surfaceflinger/Surface.h>
+#include <gui/Surface.h>
 #include <utils/String8.h>
 #include <cutils/properties.h>
 
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index ad2dfab..a9e7f360 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -164,6 +164,13 @@
     return PostAndAwaitResponse(msg, &response);
 }
 
+status_t MediaCodec::release() {
+    sp<AMessage> msg = new AMessage(kWhatRelease, id());
+
+    sp<AMessage> response;
+    return PostAndAwaitResponse(msg, &response);
+}
+
 status_t MediaCodec::queueInputBuffer(
         size_t index,
         size_t offset,
@@ -422,6 +429,7 @@
                         }
 
                         case STOPPING:
+                        case RELEASING:
                         {
                             // Ignore the error, assuming we'll still get
                             // the shutdown complete notification.
@@ -577,7 +585,9 @@
                 {
                     /* size_t index = */updateBuffers(kPortIndexInput, msg);
 
-                    if (mState == FLUSHING) {
+                    if (mState == FLUSHING
+                            || mState == STOPPING
+                            || mState == RELEASING) {
                         returnBuffersToCodecOnPort(kPortIndexInput);
                         break;
                     }
@@ -596,7 +606,9 @@
                 {
                     /* size_t index = */updateBuffers(kPortIndexOutput, msg);
 
-                    if (mState == FLUSHING) {
+                    if (mState == FLUSHING
+                            || mState == STOPPING
+                            || mState == RELEASING) {
                         returnBuffersToCodecOnPort(kPortIndexOutput);
                         break;
                     }
@@ -628,8 +640,12 @@
 
                 case ACodec::kWhatShutdownCompleted:
                 {
-                    CHECK_EQ(mState, STOPPING);
-                    setState(UNINITIALIZED);
+                    if (mState == STOPPING) {
+                        setState(INITIALIZED);
+                    } else {
+                        CHECK_EQ(mState, RELEASING);
+                        setState(UNINITIALIZED);
+                    }
 
                     (new AMessage)->postReply(mReplyID);
                     break;
@@ -767,6 +783,28 @@
             mReplyID = replyID;
             setState(STOPPING);
 
+            mCodec->initiateShutdown(true /* keepComponentAllocated */);
+            returnBuffersToCodec();
+            break;
+        }
+
+        case kWhatRelease:
+        {
+            uint32_t replyID;
+            CHECK(msg->senderAwaitsResponse(&replyID));
+
+            if (mState != INITIALIZED
+                    && mState != CONFIGURED && mState != STARTED) {
+                sp<AMessage> response = new AMessage;
+                response->setInt32("err", INVALID_OPERATION);
+
+                response->postReply(replyID);
+                break;
+            }
+
+            mReplyID = replyID;
+            setState(RELEASING);
+
             mCodec->initiateShutdown();
             returnBuffersToCodec();
             break;
diff --git a/media/libstagefright/SurfaceMediaSource.cpp b/media/libstagefright/SurfaceMediaSource.cpp
index aa047d6..ab2cff0 100644
--- a/media/libstagefright/SurfaceMediaSource.cpp
+++ b/media/libstagefright/SurfaceMediaSource.cpp
@@ -24,9 +24,8 @@
 #include <media/stagefright/MetadataBufferType.h>
 
 #include <ui/GraphicBuffer.h>
-#include <surfaceflinger/ISurfaceComposer.h>
-#include <surfaceflinger/SurfaceComposerClient.h>
-#include <surfaceflinger/IGraphicBufferAlloc.h>
+#include <gui/ISurfaceComposer.h>
+#include <gui/IGraphicBufferAlloc.h>
 #include <OMX_Component.h>
 
 #include <utils/Log.h>
diff --git a/media/libstagefright/codecs/aacenc/basic_op/typedefs.h b/media/libstagefright/codecs/aacenc/basic_op/typedefs.h
index 2d5d956..8ef43e2 100644
--- a/media/libstagefright/codecs/aacenc/basic_op/typedefs.h
+++ b/media/libstagefright/codecs/aacenc/basic_op/typedefs.h
@@ -48,9 +48,7 @@
 #define assert(_Expression)     ((void)0)
 #endif
 
-#ifdef LINUX
-#define __inline static __inline__
-#endif
+#define __inline static __inline
 
 #define INT_BITS   32
 /*
diff --git a/media/libstagefright/codecs/aacenc/src/qc_main.c b/media/libstagefright/codecs/aacenc/src/qc_main.c
index df6d46e..48ff300 100644
--- a/media/libstagefright/codecs/aacenc/src/qc_main.c
+++ b/media/libstagefright/codecs/aacenc/src/qc_main.c
@@ -163,7 +163,7 @@
    Word32 i;
    if(hQC)
    {
-      if(hQC->qcChannel[0].quantSpec);
+      if(hQC->qcChannel[0].quantSpec)
 		 mem_free(pMemOP, hQC->qcChannel[0].quantSpec, VO_INDEX_ENC_AAC);
 
       if(hQC->qcChannel[0].maxValueInSfb)
diff --git a/media/libstagefright/codecs/aacenc/src/sf_estim.c b/media/libstagefright/codecs/aacenc/src/sf_estim.c
index fe40137..bc320ec 100644
--- a/media/libstagefright/codecs/aacenc/src/sf_estim.c
+++ b/media/libstagefright/codecs/aacenc/src/sf_estim.c
@@ -400,7 +400,7 @@
                                 Word16 *minScfCalculated,
                                 Flag    restartOnSuccess)
 {
-	Word32 sfbLast, sfbAct, sfbNext, scfAct, scfMin;
+	Word16 sfbLast, sfbAct, sfbNext, scfAct, scfMin;
 	Word16 *scfLast, *scfNext;
 	Word32 sfbPeOld, sfbPeNew;
 	Word32 sfbDistNew;
diff --git a/media/libstagefright/codecs/aacenc/src/transform.c b/media/libstagefright/codecs/aacenc/src/transform.c
index a154a2f..a02336f 100644
--- a/media/libstagefright/codecs/aacenc/src/transform.c
+++ b/media/libstagefright/codecs/aacenc/src/transform.c
@@ -339,6 +339,12 @@
 		*buf1-- = MULHIGH(cosb, tr2) + MULHIGH(sinb, ti2);
 	}
 }
+#else
+void Radix4First(int *buf, int num);
+void Radix8First(int *buf, int num);
+void Radix4FFT(int *buf, int num, int bgn, int *twidTab);
+void PreMDCT(int *buf0, int num, const int *csptr);
+void PostMDCT(int *buf0, int num, const int *csptr);
 #endif
 
 
diff --git a/media/libstagefright/codecs/amrnb/common/include/az_lsp.h b/media/libstagefright/codecs/amrnb/common/include/az_lsp.h
index 3e15ba3..7c24ca9 100644
--- a/media/libstagefright/codecs/amrnb/common/include/az_lsp.h
+++ b/media/libstagefright/codecs/amrnb/common/include/az_lsp.h
@@ -83,7 +83,7 @@
     ; EXTERNAL VARIABLES REFERENCES
     ; Declare variables used in this module but defined elsewhere
     ----------------------------------------------------------------------------*/
-    extern Word16 grid[];
+    extern const Word16 grid[];
 
     /*----------------------------------------------------------------------------
     ; SIMPLE TYPEDEF'S
diff --git a/media/libstagefright/codecs/amrnb/common/include/inv_sqrt.h b/media/libstagefright/codecs/amrnb/common/include/inv_sqrt.h
index 4fb2b11..91ab3e4 100644
--- a/media/libstagefright/codecs/amrnb/common/include/inv_sqrt.h
+++ b/media/libstagefright/codecs/amrnb/common/include/inv_sqrt.h
@@ -85,7 +85,7 @@
     ; EXTERNAL VARIABLES REFERENCES
     ; Declare variables used in this module but defined elsewhere
     ----------------------------------------------------------------------------*/
-    extern Word16 inv_sqrt_tbl[];
+    extern const Word16 inv_sqrt_tbl[];
     /*----------------------------------------------------------------------------
     ; SIMPLE TYPEDEF'S
     ----------------------------------------------------------------------------*/
diff --git a/media/libstagefright/codecs/amrnb/common/include/log2_norm.h b/media/libstagefright/codecs/amrnb/common/include/log2_norm.h
index b104a69..46b4e4d 100644
--- a/media/libstagefright/codecs/amrnb/common/include/log2_norm.h
+++ b/media/libstagefright/codecs/amrnb/common/include/log2_norm.h
@@ -85,7 +85,7 @@
     ; EXTERNAL VARIABLES REFERENCES
     ; Declare variables used in this module but defined elsewhere
     ----------------------------------------------------------------------------*/
-    extern Word16 log2_tbl[];
+    extern const Word16 log2_tbl[];
     /*----------------------------------------------------------------------------
     ; SIMPLE TYPEDEF'S
     ----------------------------------------------------------------------------*/
diff --git a/media/libstagefright/codecs/amrnb/common/include/pow2.h b/media/libstagefright/codecs/amrnb/common/include/pow2.h
index c96fbdd..9b944eba 100644
--- a/media/libstagefright/codecs/amrnb/common/include/pow2.h
+++ b/media/libstagefright/codecs/amrnb/common/include/pow2.h
@@ -81,7 +81,7 @@
     ; EXTERNAL VARIABLES REFERENCES
     ; Declare variables used in this module but defined elsewhere
     ----------------------------------------------------------------------------*/
-    extern Word16 pow2_tbl[];
+    extern const Word16 pow2_tbl[];
     /*----------------------------------------------------------------------------
     ; SIMPLE TYPEDEF'S
     ----------------------------------------------------------------------------*/
diff --git a/media/libstagefright/codecs/amrnb/common/include/sqrt_l.h b/media/libstagefright/codecs/amrnb/common/include/sqrt_l.h
index 86209bd..a6a2ee5 100644
--- a/media/libstagefright/codecs/amrnb/common/include/sqrt_l.h
+++ b/media/libstagefright/codecs/amrnb/common/include/sqrt_l.h
@@ -82,7 +82,7 @@
     ; EXTERNAL VARIABLES REFERENCES
     ; Declare variables used in this module but defined elsewhere
     ----------------------------------------------------------------------------*/
-    extern Word16 sqrt_l_tbl[];
+    extern const Word16 sqrt_l_tbl[];
 
     /*----------------------------------------------------------------------------
     ; SIMPLE TYPEDEF'S
diff --git a/media/libstagefright/codecs/amrnb/common/src/bitno_tab.cpp b/media/libstagefright/codecs/amrnb/common/src/bitno_tab.cpp
index fed684d..4ee04a5 100644
--- a/media/libstagefright/codecs/amrnb/common/src/bitno_tab.cpp
+++ b/media/libstagefright/codecs/amrnb/common/src/bitno_tab.cpp
@@ -152,7 +152,7 @@
     ; Variable declaration - defined here and used outside this module
     ----------------------------------------------------------------------------*/
     /* number of parameters per modes (values must be <= MAX_PRM_SIZE!) */
-    extern const Word16 prmno[N_MODES] =
+    const Word16 prmno[N_MODES] =
     {
         PRMNO_MR475,
         PRMNO_MR515,
@@ -166,7 +166,7 @@
     };
 
     /* number of parameters to first subframe per modes */
-    extern const Word16 prmnofsf[N_MODES - 1] =
+    const Word16 prmnofsf[N_MODES - 1] =
     {
         PRMNOFSF_MR475,
         PRMNOFSF_MR515,
@@ -179,7 +179,7 @@
     };
 
     /* parameter sizes (# of bits), one table per mode */
-    extern const Word16 bitno_MR475[PRMNO_MR475] =
+    const Word16 bitno_MR475[PRMNO_MR475] =
     {
         8, 8, 7,                                 /* LSP VQ          */
         8, 7, 2, 8,                              /* first subframe  */
@@ -188,7 +188,7 @@
         4, 7, 2,                                 /* fourth subframe */
     };
 
-    extern const Word16 bitno_MR515[PRMNO_MR515] =
+    const Word16 bitno_MR515[PRMNO_MR515] =
     {
         8, 8, 7,                                 /* LSP VQ          */
         8, 7, 2, 6,                              /* first subframe  */
@@ -197,7 +197,7 @@
         4, 7, 2, 6,                              /* fourth subframe */
     };
 
-    extern const Word16 bitno_MR59[PRMNO_MR59] =
+    const Word16 bitno_MR59[PRMNO_MR59] =
     {
         8, 9, 9,                                 /* LSP VQ          */
         8, 9, 2, 6,                              /* first subframe  */
@@ -206,7 +206,7 @@
         4, 9, 2, 6,                              /* fourth subframe */
     };
 
-    extern const Word16 bitno_MR67[PRMNO_MR67] =
+    const Word16 bitno_MR67[PRMNO_MR67] =
     {
         8, 9, 9,                                 /* LSP VQ          */
         8, 11, 3, 7,                             /* first subframe  */
@@ -215,7 +215,7 @@
         4, 11, 3, 7,                             /* fourth subframe */
     };
 
-    extern const Word16 bitno_MR74[PRMNO_MR74] =
+    const Word16 bitno_MR74[PRMNO_MR74] =
     {
         8, 9, 9,                                 /* LSP VQ          */
         8, 13, 4, 7,                             /* first subframe  */
@@ -224,7 +224,7 @@
         5, 13, 4, 7,                             /* fourth subframe */
     };
 
-    extern const Word16 bitno_MR795[PRMNO_MR795] =
+    const Word16 bitno_MR795[PRMNO_MR795] =
     {
         9, 9, 9,                                 /* LSP VQ          */
         8, 13, 4, 4, 5,                          /* first subframe  */
@@ -233,7 +233,7 @@
         6, 13, 4, 4, 5,                          /* fourth subframe */
     };
 
-    extern const Word16 bitno_MR102[PRMNO_MR102] =
+    const Word16 bitno_MR102[PRMNO_MR102] =
     {
         8, 9, 9,                                 /* LSP VQ          */
         8, 1, 1, 1, 1, 10, 10, 7, 7,             /* first subframe  */
@@ -242,7 +242,7 @@
         5, 1, 1, 1, 1, 10, 10, 7, 7,             /* fourth subframe */
     };
 
-    extern const Word16 bitno_MR122[PRMNO_MR122] =
+    const Word16 bitno_MR122[PRMNO_MR122] =
     {
         7, 8, 9, 8, 6,                           /* LSP VQ          */
         9, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 5,   /* first subframe  */
@@ -251,7 +251,7 @@
         6, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 5    /* fourth subframe */
     };
 
-    extern const Word16 bitno_MRDTX[PRMNO_MRDTX] =
+    const Word16 bitno_MRDTX[PRMNO_MRDTX] =
     {
         3,
         8, 9, 9,
@@ -259,7 +259,7 @@
     };
 
     /* overall table with all parameter sizes for all modes */
-    extern const Word16 * const bitno[N_MODES] =
+    const Word16 * const bitno[N_MODES] =
     {
         bitno_MR475,
         bitno_MR515,
diff --git a/media/libstagefright/codecs/amrnb/common/src/bitreorder_tab.cpp b/media/libstagefright/codecs/amrnb/common/src/bitreorder_tab.cpp
index 69b20fb..e284bbc 100644
--- a/media/libstagefright/codecs/amrnb/common/src/bitreorder_tab.cpp
+++ b/media/libstagefright/codecs/amrnb/common/src/bitreorder_tab.cpp
@@ -123,6 +123,7 @@
 ; INCLUDES
 ----------------------------------------------------------------------------*/
 #include "typedef.h"
+#include "bitreorder_tab.h"
 
 /*--------------------------------------------------------------------------*/
 #ifdef __cplusplus
@@ -171,7 +172,7 @@
     ; Variable declaration - defined here and used outside this module
     ----------------------------------------------------------------------------*/
     /* number of parameters per modes (values must be <= MAX_PRM_SIZE!) */
-    extern const Word16 numOfBits[NUM_MODES] =
+    const Word16 numOfBits[NUM_MODES] =
     {
         NUMBIT_MR475,
         NUMBIT_MR515,
@@ -191,7 +192,7 @@
         NUMBIT_NO_DATA
     };
 
-    extern const Word16 reorderBits_MR475[NUMBIT_MR475] =
+    const Word16 reorderBits_MR475[NUMBIT_MR475] =
     {
         0,  1,  2,  3,  4,  5,  6,  7,  8,  9,
         10, 11, 12, 13, 14, 15, 23, 24, 25, 26,
@@ -205,7 +206,7 @@
         92, 31, 52, 65, 86
     };
 
-    extern const Word16 reorderBits_MR515[NUMBIT_MR515] =
+    const Word16 reorderBits_MR515[NUMBIT_MR515] =
     {
         7,  6,  5,  4,  3,  2,  1,  0, 15, 14,
         13, 12, 11, 10,  9,  8, 23, 24, 25, 26,
@@ -220,7 +221,7 @@
         53, 72, 91
     };
 
-    extern const Word16 reorderBits_MR59[NUMBIT_MR59] =
+    const Word16 reorderBits_MR59[NUMBIT_MR59] =
     {
         0,  1,  4,  5,  3,  6,  7,  2, 13, 15,
         8,  9, 11, 12, 14, 10, 16, 28, 74, 29,
@@ -236,7 +237,7 @@
         38, 59, 84, 105, 37, 58, 83, 104
     };
 
-    extern const Word16 reorderBits_MR67[NUMBIT_MR67] =
+    const Word16 reorderBits_MR67[NUMBIT_MR67] =
     {
         0,  1,  4,  3,  5,  6, 13,  7,  2,  8,
         9, 11, 15, 12, 14, 10, 28, 82, 29, 83,
@@ -254,7 +255,7 @@
         36, 61, 90, 115
     };
 
-    extern const Word16 reorderBits_MR74[NUMBIT_MR74] =
+    const Word16 reorderBits_MR74[NUMBIT_MR74] =
     {
         0,  1,  2,  3,  4,  5,  6,  7,  8,  9,
         10, 11, 12, 13, 14, 15, 16, 26, 87, 27,
@@ -273,7 +274,7 @@
         39, 68, 100, 129, 40, 69, 101, 130
     };
 
-    extern const Word16 reorderBits_MR795[NUMBIT_MR795] =
+    const Word16 reorderBits_MR795[NUMBIT_MR795] =
     {
         8,  7,  6,  5,  4,  3,  2, 14, 16,  9,
         10, 12, 13, 15, 11, 17, 20, 22, 24, 23,
@@ -293,7 +294,7 @@
         139, 37, 69, 103, 135, 38, 70, 104, 136
     };
 
-    extern const Word16 reorderBits_MR102[NUMBIT_MR102] =
+    const Word16 reorderBits_MR102[NUMBIT_MR102] =
     {
         7,  6,  5,  4,  3,  2,  1,  0, 16, 15,
         14, 13, 12, 11, 10,  9,  8, 26, 27, 28,
@@ -318,7 +319,7 @@
         63, 46, 55, 56
     };
 
-    extern const Word16 reorderBits_MR122[NUMBIT_MR122] =
+    const Word16 reorderBits_MR122[NUMBIT_MR122] =
     {
         0,  1,  2,  3,  4,  5,  6,  7,  8,  9,
         10, 11, 12, 13, 14, 23, 15, 16, 17, 18,
@@ -348,7 +349,7 @@
     };
 
     /* overall table with all parameter sizes for all modes */
-    extern const Word16 * const reorderBits[NUM_MODES-1] =
+    const Word16 * const reorderBits[NUM_MODES-1] =
     {
         reorderBits_MR475,
         reorderBits_MR515,
@@ -361,7 +362,7 @@
     };
 
     /* Number of Frames (16-bit segments sent for each mode */
-    extern const Word16 numCompressedBytes[16] =
+    const Word16 numCompressedBytes[16] =
     {
         13, /*4.75*/
         14, /*5.15*/
diff --git a/media/libstagefright/codecs/amrnb/common/src/bytesused.cpp b/media/libstagefright/codecs/amrnb/common/src/bytesused.cpp
index 9552206..b61bac4 100644
--- a/media/libstagefright/codecs/amrnb/common/src/bytesused.cpp
+++ b/media/libstagefright/codecs/amrnb/common/src/bytesused.cpp
@@ -152,7 +152,7 @@
     ; LOCAL STORE/BUFFER/POINTER DEFINITIONS
     ; Variable declaration - defined here and used outside this module
     ----------------------------------------------------------------------------*/
-    extern const short BytesUsed[16] =
+    const short BytesUsed[16] =
     {
         13, /* 4.75 */
         14, /* 5.15 */
diff --git a/media/libstagefright/codecs/amrnb/common/src/c2_9pf_tab.cpp b/media/libstagefright/codecs/amrnb/common/src/c2_9pf_tab.cpp
index 471bee8..20de9d6 100644
--- a/media/libstagefright/codecs/amrnb/common/src/c2_9pf_tab.cpp
+++ b/media/libstagefright/codecs/amrnb/common/src/c2_9pf_tab.cpp
@@ -86,7 +86,8 @@
     ; LOCAL VARIABLE DEFINITIONS
     ; [Variable declaration - defined here and used outside this module]
     ----------------------------------------------------------------------------*/
-    extern const Word16 startPos[2*4*2] = {0, 2, 0, 3,
+    extern const Word16 startPos[];
+    const Word16 startPos[2*4*2] = {0, 2, 0, 3,
         0, 2, 0, 3,
         1, 3, 2, 4,
         1, 4, 1, 4
diff --git a/media/libstagefright/codecs/amrnb/common/src/gains_tbl.cpp b/media/libstagefright/codecs/amrnb/common/src/gains_tbl.cpp
index a08dd2d..a7cd6fb 100644
--- a/media/libstagefright/codecs/amrnb/common/src/gains_tbl.cpp
+++ b/media/libstagefright/codecs/amrnb/common/src/gains_tbl.cpp
@@ -86,14 +86,16 @@
     ----------------------------------------------------------------------------*/
 
 
-    extern const Word16 qua_gain_pitch[NB_QUA_PITCH] =
+    extern const Word16 qua_gain_pitch[];
+    const Word16 qua_gain_pitch[NB_QUA_PITCH] =
     {
         0, 3277, 6556, 8192, 9830, 11469, 12288, 13107,
         13926, 14746, 15565, 16384, 17203, 18022, 18842, 19661
     };
 
 
-    extern const Word16 qua_gain_code[(NB_QUA_CODE+1)*3] =
+    extern const Word16 qua_gain_code[];
+    const Word16 qua_gain_code[(NB_QUA_CODE+1)*3] =
     {
         /* gain factor (g_fac) and quantized energy error (qua_ener_MR122, qua_ener)
          * are stored:
diff --git a/media/libstagefright/codecs/amrnb/common/src/gray_tbl.cpp b/media/libstagefright/codecs/amrnb/common/src/gray_tbl.cpp
index 99073d9..c4b2dbc 100644
--- a/media/libstagefright/codecs/amrnb/common/src/gray_tbl.cpp
+++ b/media/libstagefright/codecs/amrnb/common/src/gray_tbl.cpp
@@ -83,8 +83,10 @@
     ; [Variable declaration - defined here and used outside this module]
     ----------------------------------------------------------------------------*/
 
-    extern const Word16 gray[8]  = {0, 1, 3, 2, 6, 4, 5, 7};
-    extern const Word16 dgray[8] = {0, 1, 3, 2, 5, 6, 4, 7};
+    extern const Word16 gray[];
+    extern const Word16 dgray[];
+    const Word16 gray[8]  = {0, 1, 3, 2, 6, 4, 5, 7};
+    const Word16 dgray[8] = {0, 1, 3, 2, 5, 6, 4, 7};
 
     /*--------------------------------------------------------------------------*/
 #ifdef __cplusplus
diff --git a/media/libstagefright/codecs/amrnb/common/src/grid_tbl.cpp b/media/libstagefright/codecs/amrnb/common/src/grid_tbl.cpp
index cd81566..48566cc 100644
--- a/media/libstagefright/codecs/amrnb/common/src/grid_tbl.cpp
+++ b/media/libstagefright/codecs/amrnb/common/src/grid_tbl.cpp
@@ -63,6 +63,7 @@
 ; INCLUDES
 ----------------------------------------------------------------------------*/
 #include "typedef.h"
+#include "az_lsp.h"
 
 /*--------------------------------------------------------------------------*/
 #ifdef __cplusplus
@@ -91,7 +92,7 @@
     ; LOCAL VARIABLE DEFINITIONS
     ; [Variable declaration - defined here and used outside this module]
     ----------------------------------------------------------------------------*/
-    extern const Word16 grid[grid_points + 1] =
+    const Word16 grid[grid_points + 1] =
     {
         32760, 32723, 32588, 32364, 32051, 31651,
         31164, 30591, 29935, 29196, 28377, 27481,
diff --git a/media/libstagefright/codecs/amrnb/common/src/inv_sqrt_tbl.cpp b/media/libstagefright/codecs/amrnb/common/src/inv_sqrt_tbl.cpp
index bde2c4e..13c3b24 100644
--- a/media/libstagefright/codecs/amrnb/common/src/inv_sqrt_tbl.cpp
+++ b/media/libstagefright/codecs/amrnb/common/src/inv_sqrt_tbl.cpp
@@ -55,6 +55,7 @@
 ; INCLUDES
 ----------------------------------------------------------------------------*/
 #include "typedef.h"
+#include "inv_sqrt.h"
 
 /*--------------------------------------------------------------------------*/
 #ifdef __cplusplus
@@ -82,7 +83,7 @@
     ; LOCAL VARIABLE DEFINITIONS
     ; [Variable declaration - defined here and used outside this module]
     ----------------------------------------------------------------------------*/
-    extern const Word16 inv_sqrt_tbl[49] =
+    const Word16 inv_sqrt_tbl[49] =
     {
 
         32767, 31790, 30894, 30070, 29309, 28602, 27945, 27330, 26755, 26214,
diff --git a/media/libstagefright/codecs/amrnb/common/src/log2_tbl.cpp b/media/libstagefright/codecs/amrnb/common/src/log2_tbl.cpp
index 25d63b2..9b9b099 100644
--- a/media/libstagefright/codecs/amrnb/common/src/log2_tbl.cpp
+++ b/media/libstagefright/codecs/amrnb/common/src/log2_tbl.cpp
@@ -54,6 +54,7 @@
 ; INCLUDES
 ----------------------------------------------------------------------------*/
 #include "typedef.h"
+#include "log2_norm.h"
 
 /*--------------------------------------------------------------------------*/
 #ifdef __cplusplus
@@ -82,7 +83,7 @@
     ; [Variable declaration - defined here and used outside this module]
     ----------------------------------------------------------------------------*/
 
-    extern const Word16 log2_tbl[33] =
+    const Word16 log2_tbl[33] =
     {
         0, 1455, 2866, 4236, 5568, 6863, 8124, 9352, 10549, 11716,
         12855, 13967, 15054, 16117, 17156, 18172, 19167, 20142, 21097, 22033,
diff --git a/media/libstagefright/codecs/amrnb/common/src/lsp_lsf_tbl.cpp b/media/libstagefright/codecs/amrnb/common/src/lsp_lsf_tbl.cpp
index cee0f32..ddeeba4 100644
--- a/media/libstagefright/codecs/amrnb/common/src/lsp_lsf_tbl.cpp
+++ b/media/libstagefright/codecs/amrnb/common/src/lsp_lsf_tbl.cpp
@@ -77,7 +77,8 @@
     ; [Variable declaration - defined here and used outside this module]
     ----------------------------------------------------------------------------*/
 
-    extern const Word16 table[65] =
+    extern const Word16 table[];
+    const Word16 table[65] =
     {
         32767, 32729, 32610, 32413, 32138, 31786, 31357, 30853,
         30274, 29622, 28899, 28106, 27246, 26320, 25330, 24279,
@@ -94,7 +95,8 @@
 
     /* slope used to compute y = acos(x) */
 
-    extern const Word16 slope[64] =
+    extern const Word16 slope[];
+    const Word16 slope[64] =
     {
         -26887, -8812, -5323, -3813, -2979, -2444, -2081, -1811,
         -1608, -1450, -1322, -1219, -1132, -1059, -998, -946,
diff --git a/media/libstagefright/codecs/amrnb/common/src/lsp_tab.cpp b/media/libstagefright/codecs/amrnb/common/src/lsp_tab.cpp
index deded93..0a32dd7a 100644
--- a/media/libstagefright/codecs/amrnb/common/src/lsp_tab.cpp
+++ b/media/libstagefright/codecs/amrnb/common/src/lsp_tab.cpp
@@ -117,6 +117,7 @@
 ----------------------------------------------------------------------------*/
 #include    "typedef.h"
 #include    "cnst.h"
+#include    "lsp_tab.h"
 
 /*--------------------------------------------------------------------------*/
 #ifdef __cplusplus
@@ -146,7 +147,7 @@
     ; LOCAL STORE/BUFFER/POINTER DEFINITIONS
     ; Variable declaration - defined here and used outside this module
     ----------------------------------------------------------------------------*/
-    extern const Word16 lsp_init_data[M] = {30000, 26000, 21000, 15000, 8000,
+    const Word16 lsp_init_data[M] = {30000, 26000, 21000, 15000, 8000,
         0, -8000, -15000, -21000, -26000
     };
 
diff --git a/media/libstagefright/codecs/amrnb/common/src/overflow_tbl.cpp b/media/libstagefright/codecs/amrnb/common/src/overflow_tbl.cpp
index e5d42d6..c4a016d 100644
--- a/media/libstagefright/codecs/amrnb/common/src/overflow_tbl.cpp
+++ b/media/libstagefright/codecs/amrnb/common/src/overflow_tbl.cpp
@@ -81,7 +81,7 @@
     ; LOCAL VARIABLE DEFINITIONS
     ; [Variable declaration - defined here and used outside this module]
     ----------------------------------------------------------------------------*/
-    extern const Word32 overflow_tbl [32]   = {0x7fffffffL, 0x3fffffffL,
+    const Word32 overflow_tbl [32]   = {0x7fffffffL, 0x3fffffffL,
         0x1fffffffL, 0x0fffffffL,
         0x07ffffffL, 0x03ffffffL,
         0x01ffffffL, 0x00ffffffL,
diff --git a/media/libstagefright/codecs/amrnb/common/src/ph_disp_tab.cpp b/media/libstagefright/codecs/amrnb/common/src/ph_disp_tab.cpp
index 99725df..d568b78 100644
--- a/media/libstagefright/codecs/amrnb/common/src/ph_disp_tab.cpp
+++ b/media/libstagefright/codecs/amrnb/common/src/ph_disp_tab.cpp
@@ -81,14 +81,16 @@
     ; LOCAL VARIABLE DEFINITIONS
     ; [Variable declaration - defined here and used outside this module]
     ----------------------------------------------------------------------------*/
-    extern const Word16 ph_imp_low_MR795[40] =
+    extern const Word16 ph_imp_low_MR795[];
+    const Word16 ph_imp_low_MR795[40] =
     {
         26777,    801,   2505,   -683,  -1382,    582,    604,  -1274,   3511,  -5894,
         4534,   -499,  -1940,   3011,  -5058,   5614,  -1990,  -1061,  -1459,   4442,
         -700,  -5335,   4609,    452,   -589,  -3352,   2953,   1267,  -1212,  -2590,
         1731,   3670,  -4475,   -975,   4391,  -2537,    949,  -1363,   -979,   5734
     };
-    extern const Word16 ph_imp_mid_MR795[40] =
+    extern const Word16 ph_imp_mid_MR795[];
+    const Word16 ph_imp_mid_MR795[40] =
     {
         30274,   3831,  -4036,   2972,  -1048,  -1002,   2477,  -3043,   2815,  -2231,
         1753,  -1611,   1714,  -1775,   1543,  -1008,    429,   -169,    472,  -1264,
@@ -96,14 +98,16 @@
         -2063,   2644,  -3060,   2897,  -1978,    557,    780,  -1369,    842,    655
     };
 
-    extern const Word16 ph_imp_low[40] =
+    extern const Word16 ph_imp_low[];
+    const Word16 ph_imp_low[40] =
     {
         14690,  11518,   1268,  -2761,  -5671,   7514,    -35,  -2807,  -3040,   4823,
         2952,  -8424,   3785,   1455,   2179,  -8637,   8051,  -2103,  -1454,    777,
         1108,  -2385,   2254,   -363,   -674,  -2103,   6046,  -5681,   1072,   3123,
         -5058,   5312,  -2329,  -3728,   6924,  -3889,    675,  -1775,     29,  10145
     };
-    extern const Word16 ph_imp_mid[40] =
+    extern const Word16 ph_imp_mid[];
+    const Word16 ph_imp_mid[40] =
     {
         30274,   3831,  -4036,   2972,  -1048,  -1002,   2477,  -3043,   2815,  -2231,
         1753,  -1611,   1714,  -1775,   1543,  -1008,    429,   -169,    472,  -1264,
diff --git a/media/libstagefright/codecs/amrnb/common/src/pow2_tbl.cpp b/media/libstagefright/codecs/amrnb/common/src/pow2_tbl.cpp
index e0183a6..902ea0f 100644
--- a/media/libstagefright/codecs/amrnb/common/src/pow2_tbl.cpp
+++ b/media/libstagefright/codecs/amrnb/common/src/pow2_tbl.cpp
@@ -53,6 +53,7 @@
 ; INCLUDES
 ----------------------------------------------------------------------------*/
 #include "typedef.h"
+#include "pow2.h"
 
 /*--------------------------------------------------------------------------*/
 #ifdef __cplusplus
@@ -81,7 +82,7 @@
     ; [Variable declaration - defined here and used outside this module]
     ----------------------------------------------------------------------------*/
 
-    extern const Word16 pow2_tbl[33] =
+    const Word16 pow2_tbl[33] =
     {
         16384, 16743, 17109, 17484, 17867, 18258, 18658, 19066, 19484, 19911,
         20347, 20792, 21247, 21713, 22188, 22674, 23170, 23678, 24196, 24726,
diff --git a/media/libstagefright/codecs/amrnb/common/src/q_plsf_5_tbl.cpp b/media/libstagefright/codecs/amrnb/common/src/q_plsf_5_tbl.cpp
index ceb1e1e..caa81cb 100644
--- a/media/libstagefright/codecs/amrnb/common/src/q_plsf_5_tbl.cpp
+++ b/media/libstagefright/codecs/amrnb/common/src/q_plsf_5_tbl.cpp
@@ -56,6 +56,7 @@
 ; INCLUDES
 ----------------------------------------------------------------------------*/
 #include "typedef.h"
+#include "q_plsf_5_tbl.h"
 
 /*--------------------------------------------------------------------------*/
 #ifdef __cplusplus
@@ -94,7 +95,7 @@
     ----------------------------------------------------------------------------*/
     /* LSF means ->normalize frequency domain */
 
-    extern const Word16 mean_lsf_5[10] =
+    const Word16 mean_lsf_5[10] =
     {
         1384,
         2077,
@@ -108,7 +109,7 @@
         13701
     };
 
-    extern const Word16 dico1_lsf_5[DICO1_5_SIZE * 4] =
+    const Word16 dico1_lsf_5[DICO1_5_SIZE * 4] =
     {
         -451, -1065, -529, -1305,
         -450, -756, -497, -863,
@@ -240,7 +241,7 @@
         1469, 2181, 1443, 2016
     };
 
-    extern const Word16 dico2_lsf_5[DICO2_5_SIZE * 4] =
+    const Word16 dico2_lsf_5[DICO2_5_SIZE * 4] =
     {
         -1631, -1600, -1796, -2290,
         -1027, -1770, -1100, -2025,
@@ -500,7 +501,7 @@
         2374, 2787, 1821, 2788
     };
 
-    extern const Word16 dico3_lsf_5[DICO3_5_SIZE * 4] =
+    const Word16 dico3_lsf_5[DICO3_5_SIZE * 4] =
     {
         -1812, -2275, -1879, -2537,
         -1640, -1848, -1695, -2004,
@@ -760,7 +761,7 @@
         2180, 1975, 2326, 2020
     };
 
-    extern const Word16 dico4_lsf_5[DICO4_5_SIZE * 4] =
+    const Word16 dico4_lsf_5[DICO4_5_SIZE * 4] =
     {
         -1857, -1681, -1857, -1755,
         -2056, -1150, -2134, -1654,
@@ -1020,7 +1021,7 @@
         1716, 1376, 1948, 1465
     };
 
-    extern const Word16 dico5_lsf_5[DICO5_5_SIZE * 4] =
+    const Word16 dico5_lsf_5[DICO5_5_SIZE * 4] =
     {
         -1002, -929, -1096, -1203,
         -641, -931, -604, -961,
diff --git a/media/libstagefright/codecs/amrnb/common/src/qua_gain_tbl.cpp b/media/libstagefright/codecs/amrnb/common/src/qua_gain_tbl.cpp
index 52f77e9..2d913b8 100644
--- a/media/libstagefright/codecs/amrnb/common/src/qua_gain_tbl.cpp
+++ b/media/libstagefright/codecs/amrnb/common/src/qua_gain_tbl.cpp
@@ -54,6 +54,7 @@
 ----------------------------------------------------------------------------*/
 #include "typedef.h"
 #include "qua_gain.h"
+#include "qua_gain_tbl.h"
 
 /*--------------------------------------------------------------------------*/
 #ifdef __cplusplus
@@ -96,7 +97,7 @@
 
     /* table used in 'high' rates: MR67 MR74 */
 
-    extern const Word16 table_gain_highrates[VQ_SIZE_HIGHRATES*4] =
+    const Word16 table_gain_highrates[VQ_SIZE_HIGHRATES*4] =
     {
 
         /*
@@ -240,7 +241,7 @@
 
     /* table used in 'low' rates: MR475, MR515, MR59 */
 
-    extern const Word16 table_gain_lowrates[VQ_SIZE_LOWRATES*4] =
+    const Word16 table_gain_lowrates[VQ_SIZE_LOWRATES*4] =
     {
         /*g_pit,    g_fac,  qua_ener_MR122, qua_ener */
         10813,    28753,            2879,    17333,
diff --git a/media/libstagefright/codecs/amrnb/common/src/sqrt_l_tbl.cpp b/media/libstagefright/codecs/amrnb/common/src/sqrt_l_tbl.cpp
index 5e9898c..5a84b63 100644
--- a/media/libstagefright/codecs/amrnb/common/src/sqrt_l_tbl.cpp
+++ b/media/libstagefright/codecs/amrnb/common/src/sqrt_l_tbl.cpp
@@ -58,6 +58,7 @@
 ; INCLUDES
 ----------------------------------------------------------------------------*/
 #include "typedef.h"
+#include "sqrt_l.h"
 
 /*--------------------------------------------------------------------------*/
 #ifdef __cplusplus
@@ -85,7 +86,7 @@
     ; LOCAL VARIABLE DEFINITIONS
     ; [Variable declaration - defined here and used outside this module]
     ----------------------------------------------------------------------------*/
-    extern const Word16 sqrt_l_tbl[50] =
+    const Word16 sqrt_l_tbl[50] =
     {
         16384, 16888, 17378, 17854, 18318, 18770, 19212, 19644, 20066, 20480,
         20886, 21283, 21674, 22058, 22435, 22806, 23170, 23530, 23884, 24232,
diff --git a/media/libstagefright/codecs/amrnb/common/src/window_tab.cpp b/media/libstagefright/codecs/amrnb/common/src/window_tab.cpp
index fa5faa6..d8fc8cc 100644
--- a/media/libstagefright/codecs/amrnb/common/src/window_tab.cpp
+++ b/media/libstagefright/codecs/amrnb/common/src/window_tab.cpp
@@ -117,6 +117,7 @@
 ----------------------------------------------------------------------------*/
 #include    "typedef.h"
 #include    "cnst.h"
+#include    "window_tab.h"
 
 /*--------------------------------------------------------------------------*/
 #ifdef __cplusplus
@@ -154,7 +155,7 @@
 
     /* window for non-EFR modesm; uses 40 samples lookahead */
 
-    extern const Word16 window_200_40[L_WINDOW] =
+    const Word16 window_200_40[L_WINDOW] =
     {
         2621,  2623,  2629,  2638,  2651,  2668,  2689,  2713,  2741,  2772,
         2808,  2847,  2890,  2936,  2986,  3040,  3097,  3158,  3223,  3291,
@@ -185,7 +186,7 @@
 
     /* window for EFR, first two subframes, no lookahead */
 
-    extern const Word16 window_160_80[L_WINDOW] =
+    const Word16 window_160_80[L_WINDOW] =
     {
         2621, 2624, 2633, 2648, 2668, 2695, 2727, 2765, 2809, 2859,
         2915, 2976, 3043, 3116, 3194, 3279, 3368, 3464, 3565, 3671,
@@ -215,7 +216,7 @@
 
     /* window for EFR, last two subframes, no lookahead */
 
-    extern const Word16 window_232_8[L_WINDOW] =
+    const Word16 window_232_8[L_WINDOW] =
     {
         2621, 2623, 2627, 2634, 2644, 2656, 2671, 2689, 2710, 2734,
         2760, 2789, 2821, 2855, 2893, 2933, 2975, 3021, 3069, 3120,
diff --git a/media/libstagefright/codecs/amrnb/dec/src/dec_input_format_tab.cpp b/media/libstagefright/codecs/amrnb/dec/src/dec_input_format_tab.cpp
index a59f5fa..fffbbfd 100644
--- a/media/libstagefright/codecs/amrnb/dec/src/dec_input_format_tab.cpp
+++ b/media/libstagefright/codecs/amrnb/dec/src/dec_input_format_tab.cpp
@@ -121,6 +121,7 @@
 ; INCLUDES
 ----------------------------------------------------------------------------*/
 #include "typedef.h"
+#include "amrdecode.h"
 
 /*--------------------------------------------------------------------------*/
 #ifdef __cplusplus
@@ -152,7 +153,7 @@
     ----------------------------------------------------------------------------*/
     /* Table containing the number of core AMR data bytes for                */
     /* each codec mode for WMF input format(number excludes frame type byte) */
-    extern const Word16 WmfDecBytesPerFrame[16] =
+    const Word16 WmfDecBytesPerFrame[16] =
     {
         12, /* 4.75 */
         13, /* 5.15 */
@@ -174,7 +175,7 @@
 
     /* Table containing the number of core AMR data bytes for   */
     /* each codec mode for IF2 input format.                    */
-    extern const Word16 If2DecBytesPerFrame[16] =
+    const Word16 If2DecBytesPerFrame[16] =
     {
         13, /* 4.75 */
         14, /* 5.15 */
diff --git a/media/libstagefright/codecs/amrnb/dec/src/qgain475_tab.cpp b/media/libstagefright/codecs/amrnb/dec/src/qgain475_tab.cpp
index fbcd412..1a08efa 100644
--- a/media/libstagefright/codecs/amrnb/dec/src/qgain475_tab.cpp
+++ b/media/libstagefright/codecs/amrnb/dec/src/qgain475_tab.cpp
@@ -92,7 +92,7 @@
      *    g_fac(2)          (Q12) // frame 1 and 3
      *
      */
-    extern const Word16 table_gain_MR475[MR475_VQ_SIZE*4] =
+    const Word16 table_gain_MR475[MR475_VQ_SIZE*4] =
     {
         /*g_pit(0), g_fac(0),      g_pit(1), g_fac(1) */
         812,          128,           542,      140,
diff --git a/media/libstagefright/codecs/amrnb/enc/src/corrwght_tab.cpp b/media/libstagefright/codecs/amrnb/enc/src/corrwght_tab.cpp
index 769e7ba..b3ed02d 100644
--- a/media/libstagefright/codecs/amrnb/enc/src/corrwght_tab.cpp
+++ b/media/libstagefright/codecs/amrnb/enc/src/corrwght_tab.cpp
@@ -57,6 +57,7 @@
 ; INCLUDES
 ----------------------------------------------------------------------------*/
 #include "typedef.h"
+#include "p_ol_wgh.h"
 
 /*--------------------------------------------------------------------------*/
 #ifdef __cplusplus
@@ -84,7 +85,7 @@
     ; LOCAL VARIABLE DEFINITIONS
     ; [Variable declaration - defined here and used outside this module]
     ----------------------------------------------------------------------------*/
-    extern const Word16 corrweight[251] =
+    const Word16 corrweight[251] =
     {
         20473,  20506,  20539,  20572,  20605,  20644,  20677,
         20716,  20749,  20788,  20821,  20860,  20893,  20932,
diff --git a/media/libstagefright/codecs/amrnb/enc/src/enc_output_format_tab.cpp b/media/libstagefright/codecs/amrnb/enc/src/enc_output_format_tab.cpp
index 147989f8..4551fd7 100644
--- a/media/libstagefright/codecs/amrnb/enc/src/enc_output_format_tab.cpp
+++ b/media/libstagefright/codecs/amrnb/enc/src/enc_output_format_tab.cpp
@@ -117,6 +117,7 @@
 ; INCLUDES
 ----------------------------------------------------------------------------*/
 #include "typedef.h"
+#include "amrencode.h"
 
 /*--------------------------------------------------------------------------*/
 #ifdef __cplusplus
@@ -150,7 +151,7 @@
     /* for WMF output format.                                       */
     /* Each entry is the sum of the 3GPP frame type byte and the    */
     /* number of packed core AMR data bytes                         */
-    extern const Word16 WmfEncBytesPerFrame[16] =
+    const Word16 WmfEncBytesPerFrame[16] =
     {
         13, /* 4.75 */
         14, /* 5.15 */
@@ -173,7 +174,7 @@
 
     /* Number of data bytes in an encoder frame for each codec mode */
     /* for IF2 output format                                        */
-    extern const Word16 If2EncBytesPerFrame[16] =
+    const Word16 If2EncBytesPerFrame[16] =
     {
         13, /* 4.75 */
         14, /* 5.15 */
diff --git a/media/libstagefright/codecs/amrnb/enc/src/inter_36_tab.cpp b/media/libstagefright/codecs/amrnb/enc/src/inter_36_tab.cpp
index 27f33e9..c8d7b13 100644
--- a/media/libstagefright/codecs/amrnb/enc/src/inter_36_tab.cpp
+++ b/media/libstagefright/codecs/amrnb/enc/src/inter_36_tab.cpp
@@ -123,6 +123,7 @@
 ----------------------------------------------------------------------------*/
 #include    "typedef.h"
 #include    "cnst.h"
+#include    "inter_36_tab.h"
 
 /*--------------------------------------------------------------------------*/
 #ifdef __cplusplus
@@ -162,7 +163,7 @@
              inter_3[k] = inter_6[2*k], 0 <= k <= 3*L_INTER_SRCH
      */
 
-    extern const Word16 inter_6[FIR_SIZE] =
+    const Word16 inter_6[FIR_SIZE] =
     {
         29519,
         28316, 24906, 19838, 13896, 7945, 2755,
diff --git a/media/libstagefright/codecs/amrnb/enc/src/lag_wind_tab.cpp b/media/libstagefright/codecs/amrnb/enc/src/lag_wind_tab.cpp
index 53889bb..b0f5b3a 100644
--- a/media/libstagefright/codecs/amrnb/enc/src/lag_wind_tab.cpp
+++ b/media/libstagefright/codecs/amrnb/enc/src/lag_wind_tab.cpp
@@ -138,6 +138,7 @@
 ; INCLUDES
 ----------------------------------------------------------------------------*/
 #include    "typedef.h"
+#include    "lag_wind_tab.h"
 
 /*--------------------------------------------------------------------------*/
 #ifdef __cplusplus
@@ -167,7 +168,7 @@
     ; LOCAL STORE/BUFFER/POINTER DEFINITIONS
     ; Variable declaration - defined here and used outside this module
     ----------------------------------------------------------------------------*/
-    extern const Word16 lag_h[10] =
+    const Word16 lag_h[10] =
     {
         32728,
         32619,
@@ -181,7 +182,7 @@
         29321
     };
 
-    extern const Word16 lag_l[10] =
+    const Word16 lag_l[10] =
     {
         11904,
         17280,
diff --git a/media/libstagefright/codecs/amrnb/enc/src/ton_stab.cpp b/media/libstagefright/codecs/amrnb/enc/src/ton_stab.cpp
index 3c4494d..455a510 100644
--- a/media/libstagefright/codecs/amrnb/enc/src/ton_stab.cpp
+++ b/media/libstagefright/codecs/amrnb/enc/src/ton_stab.cpp
@@ -791,7 +791,8 @@
                        )
 {
     OSCL_UNUSED_ARG(pOverflow);
-    for (int i = 0; i < N_FRAME - 1; i++)
+    int i;
+    for (i = 0; i < N_FRAME - 1; i++)
     {
         st->gp[i] = st->gp[i+1];
     }
diff --git a/media/libstagefright/codecs/amrwb/include/pvamrwbdecoder_api.h b/media/libstagefright/codecs/amrwb/include/pvamrwbdecoder_api.h
index 457c21f..eca5ae0 100644
--- a/media/libstagefright/codecs/amrwb/include/pvamrwbdecoder_api.h
+++ b/media/libstagefright/codecs/amrwb/include/pvamrwbdecoder_api.h
@@ -106,7 +106,7 @@
 #define NUM_OF_MODES  10
 
 
-    const int16 AMR_WB_COMPRESSED[NUM_OF_MODES] =
+    static const int16 AMR_WB_COMPRESSED[NUM_OF_MODES] =
     {
         NBBITS_7k,
         NBBITS_9k,
diff --git a/media/libstagefright/codecs/amrwb/src/get_amr_wb_bits.cpp b/media/libstagefright/codecs/amrwb/src/get_amr_wb_bits.cpp
index d7287f3..b325e8f 100644
--- a/media/libstagefright/codecs/amrwb/src/get_amr_wb_bits.cpp
+++ b/media/libstagefright/codecs/amrwb/src/get_amr_wb_bits.cpp
@@ -119,8 +119,9 @@
 )
 {
     int16 value = 0;
+    int16 i;
 
-    for (int16 i = no_of_bits >> 1; i != 0; i--)
+    for (i = no_of_bits >> 1; i != 0; i--)
     {
         value <<= 2;
 
diff --git a/media/libstagefright/codecs/amrwb/src/homing_amr_wb_dec.cpp b/media/libstagefright/codecs/amrwb/src/homing_amr_wb_dec.cpp
index 59c6c0a..f032a08 100644
--- a/media/libstagefright/codecs/amrwb/src/homing_amr_wb_dec.cpp
+++ b/media/libstagefright/codecs/amrwb/src/homing_amr_wb_dec.cpp
@@ -134,7 +134,7 @@
 ; LOCAL STORE/BUFFER/POINTER DEFINITIONS
 ; Variable declaration - defined here and used outside this module
 ----------------------------------------------------------------------------*/
-const int16 prmnofsf[NUM_OF_SPMODES] =
+static const int16 prmnofsf[NUM_OF_SPMODES] =
 {
     63,  81, 100,
     108, 116, 128,
@@ -142,21 +142,21 @@
 };
 
 
-const int16 dfh_M7k[PRMN_7k] =
+static const int16 dfh_M7k[PRMN_7k] =
 {
     3168, 29954, 29213, 16121,
     64, 13440, 30624, 16430,
     19008
 };
 
-const int16 dfh_M9k[PRMN_9k] =
+static const int16 dfh_M9k[PRMN_9k] =
 {
     3168, 31665,  9943, 9123,
     15599,  4358, 20248, 2048,
     17040, 27787, 16816, 13888
 };
 
-const int16 dfh_M12k[PRMN_12k] =
+static const int16 dfh_M12k[PRMN_12k] =
 {
     3168, 31665,  9943,  9128,
     3647,  8129, 30930, 27926,
@@ -165,7 +165,7 @@
     13948
 };
 
-const int16 dfh_M14k[PRMN_14k] =
+static const int16 dfh_M14k[PRMN_14k] =
 {
     3168, 31665,  9943,  9131,
     24815,   655, 26616, 26764,
@@ -174,7 +174,7 @@
     221, 20321, 17823
 };
 
-const int16 dfh_M16k[PRMN_16k] =
+static const int16 dfh_M16k[PRMN_16k] =
 {
     3168, 31665,  9943,  9131,
     24815,   700,  3824,  7271,
@@ -184,7 +184,7 @@
     6759, 24576
 };
 
-const int16 dfh_M18k[PRMN_18k] =
+static const int16 dfh_M18k[PRMN_18k] =
 {
     3168, 31665,  9943,  9135,
     14787, 14423, 30477, 24927,
@@ -195,7 +195,7 @@
     0
 };
 
-const int16 dfh_M20k[PRMN_20k] =
+static const int16 dfh_M20k[PRMN_20k] =
 {
     3168, 31665,  9943,  9129,
     8637, 31807, 24646,   736,
@@ -206,7 +206,7 @@
     30249, 29123, 0
 };
 
-const int16 dfh_M23k[PRMN_23k] =
+static const int16 dfh_M23k[PRMN_23k] =
 {
     3168, 31665,  9943,  9132,
     16748,  3202, 28179, 16317,
@@ -218,7 +218,7 @@
     23392, 26053, 31216
 };
 
-const int16 dfh_M24k[PRMN_24k] =
+static const int16 dfh_M24k[PRMN_24k] =
 {
     3168, 31665,  9943,  9134,
     24776,  5857, 18475, 28535,
diff --git a/media/libstagefright/codecs/amrwb/src/isp_isf.cpp b/media/libstagefright/codecs/amrwb/src/isp_isf.cpp
index 41db7e3..0552733 100644
--- a/media/libstagefright/codecs/amrwb/src/isp_isf.cpp
+++ b/media/libstagefright/codecs/amrwb/src/isp_isf.cpp
@@ -108,7 +108,7 @@
 
 /* table of cos(x) in Q15 */
 
-const int16 table[129] =
+static const int16 table[129] =
 {
     32767,
     32758,  32729,  32679,  32610,  32522,  32413,  32286,  32138,
diff --git a/media/libstagefright/codecs/amrwb/src/oversamp_12k8_to_16k.cpp b/media/libstagefright/codecs/amrwb/src/oversamp_12k8_to_16k.cpp
index 143c26e..806851e 100644
--- a/media/libstagefright/codecs/amrwb/src/oversamp_12k8_to_16k.cpp
+++ b/media/libstagefright/codecs/amrwb/src/oversamp_12k8_to_16k.cpp
@@ -240,11 +240,11 @@
 {
 
     int32 i;
-    int16 frac;
+    int16 frac, j;
     int16 * pt_sig_u = sig_u;
 
     frac = 1;
-    for (int16 j = 0; j < L_frame; j++)
+    for (j = 0; j < L_frame; j++)
     {
         i = ((int32)j * INV_FAC5) >> 13;       /* integer part = pos * 1/5 */
 
@@ -337,6 +337,6 @@
 
     L_sum = shl_int32(L_sum, 2);               /* saturation can occur here */
 
-    return ((int16(L_sum >> 16)));
+    return ((int16)(L_sum >> 16));
 }
 
diff --git a/media/libstagefright/codecs/amrwb/src/phase_dispersion.cpp b/media/libstagefright/codecs/amrwb/src/phase_dispersion.cpp
index f90a5340..7b08a40 100644
--- a/media/libstagefright/codecs/amrwb/src/phase_dispersion.cpp
+++ b/media/libstagefright/codecs/amrwb/src/phase_dispersion.cpp
@@ -109,7 +109,7 @@
 /* impulse response with phase dispersion */
 
 /* 2.0 - 6.4 kHz phase dispersion */
-const int16 ph_imp_low[L_SUBFR] =
+static const int16 ph_imp_low[L_SUBFR] =
 {
     20182,  9693,  3270, -3437, 2864, -5240,  1589, -1357,
     600,  3893, -1497,  -698, 1203, -5249,  1199,  5371,
@@ -122,7 +122,7 @@
 };
 
 /* 3.2 - 6.4 kHz phase dispersion */
-const int16 ph_imp_mid[L_SUBFR] =
+static const int16 ph_imp_mid[L_SUBFR] =
 {
     24098, 10460, -5263,  -763,  2048,  -927,  1753, -3323,
     2212,   652, -2146,  2487, -3539,  4109, -2107,  -374,
diff --git a/media/libstagefright/codecs/amrwbenc/inc/isp_isf.tab b/media/libstagefright/codecs/amrwbenc/inc/isp_isf.tab
index 97c3b68..865eea0 100644
--- a/media/libstagefright/codecs/amrwbenc/inc/isp_isf.tab
+++ b/media/libstagefright/codecs/amrwbenc/inc/isp_isf.tab
@@ -21,7 +21,7 @@
 
 /* table of cos(x) in Q15 */
 
-const static Word16 table[129] = {
+static const Word16 table[129] = {
   32767,
   32758,  32729,  32679,  32610,  32522,  32413,  32286,  32138,
   31972,  31786,  31581,  31357,  31114,  30853,  30572,  30274,
@@ -42,7 +42,7 @@
 
 /* slope in Q11 used to compute y = acos(x) */
 
-const static Word16 slope[128] = {
+static const Word16 slope[128] = {
  -26214, -9039, -5243, -3799, -2979, -2405, -2064, -1771,
  -1579, -1409, -1279, -1170, -1079, -1004, -933, -880,
  -827, -783, -743, -708, -676, -647, -621, -599,
diff --git a/media/libstagefright/codecs/amrwbenc/src/voAMRWBEnc.c b/media/libstagefright/codecs/amrwbenc/src/voAMRWBEnc.c
index 0f4d689..ea9da52 100644
--- a/media/libstagefright/codecs/amrwbenc/src/voAMRWBEnc.c
+++ b/media/libstagefright/codecs/amrwbenc/src/voAMRWBEnc.c
@@ -1702,7 +1702,7 @@
 	gData = (Coder_State *)hCodec;
 	stream = gData->stream;
 
-	if(NULL == pInput || NULL == pInput->Buffer || 0 > pInput->Length)
+	if(NULL == pInput || NULL == pInput->Buffer)
 	{
 		return VO_ERR_INVALID_ARG;
 	}
diff --git a/media/libstagefright/colorconversion/SoftwareRenderer.cpp b/media/libstagefright/colorconversion/SoftwareRenderer.cpp
index e892f92..059d6b9 100644
--- a/media/libstagefright/colorconversion/SoftwareRenderer.cpp
+++ b/media/libstagefright/colorconversion/SoftwareRenderer.cpp
@@ -19,12 +19,9 @@
 
 #include "../include/SoftwareRenderer.h"
 
-#include <binder/MemoryHeapBase.h>
-#include <binder/MemoryHeapPmem.h>
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/MetaData.h>
-#include <surfaceflinger/Surface.h>
-#include <ui/android_native_buffer.h>
+#include <system/window.h>
 #include <ui/GraphicBufferMapper.h>
 #include <gui/ISurfaceTexture.h>
 
diff --git a/media/libstagefright/include/SoftwareRenderer.h b/media/libstagefright/include/SoftwareRenderer.h
index 8f2ea95..7ab0042 100644
--- a/media/libstagefright/include/SoftwareRenderer.h
+++ b/media/libstagefright/include/SoftwareRenderer.h
@@ -20,7 +20,7 @@
 
 #include <media/stagefright/ColorConverter.h>
 #include <utils/RefBase.h>
-#include <ui/android_native_buffer.h>
+#include <system/window.h>
 
 namespace android {
 
diff --git a/media/libstagefright/tests/SurfaceMediaSource_test.cpp b/media/libstagefright/tests/SurfaceMediaSource_test.cpp
index d7cec04..3dcd9fc 100644
--- a/media/libstagefright/tests/SurfaceMediaSource_test.cpp
+++ b/media/libstagefright/tests/SurfaceMediaSource_test.cpp
@@ -26,11 +26,11 @@
 #include <media/stagefright/SurfaceMediaSource.h>
 #include <media/mediarecorder.h>
 
-#include <gui/SurfaceTextureClient.h>
 #include <ui/GraphicBuffer.h>
-#include <surfaceflinger/ISurfaceComposer.h>
-#include <surfaceflinger/Surface.h>
-#include <surfaceflinger/SurfaceComposerClient.h>
+#include <gui/SurfaceTextureClient.h>
+#include <gui/ISurfaceComposer.h>
+#include <gui/Surface.h>
+#include <gui/SurfaceComposerClient.h>
 
 #include <binder/ProcessState.h>
 #include <ui/FramebufferNativeWindow.h>
diff --git a/media/libstagefright/timedtext/Android.mk b/media/libstagefright/timedtext/Android.mk
index dde2066..d2d5f7b 100644
--- a/media/libstagefright/timedtext/Android.mk
+++ b/media/libstagefright/timedtext/Android.mk
@@ -12,6 +12,7 @@
 LOCAL_CFLAGS += -Wno-multichar
 LOCAL_C_INCLUDES:= \
         $(JNI_H_INCLUDE) \
+        $(TOP)/frameworks/base/include/media/stagefright/timedtext \
         $(TOP)/frameworks/base/media/libstagefright
 
 LOCAL_MODULE:= libstagefright_timedtext
diff --git a/media/libstagefright/timedtext/TimedTextDriver.cpp b/media/libstagefright/timedtext/TimedTextDriver.cpp
index 9ec9415..c70870e 100644
--- a/media/libstagefright/timedtext/TimedTextDriver.cpp
+++ b/media/libstagefright/timedtext/TimedTextDriver.cpp
@@ -27,8 +27,7 @@
 #include <media/stagefright/Utils.h>
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/foundation/ALooper.h>
-
-#include "TimedTextDriver.h"
+#include <media/stagefright/timedtext/TimedTextDriver.h>
 
 #include "TextDescriptions.h"
 #include "TimedTextPlayer.h"
diff --git a/media/libstagefright/timedtext/TimedTextPlayer.cpp b/media/libstagefright/timedtext/TimedTextPlayer.cpp
index bf7cbf6..bda7b46 100644
--- a/media/libstagefright/timedtext/TimedTextPlayer.cpp
+++ b/media/libstagefright/timedtext/TimedTextPlayer.cpp
@@ -20,12 +20,12 @@
 
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/foundation/AMessage.h>
+#include <media/stagefright/timedtext/TimedTextDriver.h>
 #include <media/stagefright/MediaErrors.h>
 #include <media/MediaPlayerInterface.h>
 
 #include "TimedTextPlayer.h"
 
-#include "TimedTextDriver.h"
 #include "TimedTextSource.h"
 
 namespace android {
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaRecorderStressTestRunner.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaRecorderStressTestRunner.java
index e5ecd5c..95e7b5e 100755
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaRecorderStressTestRunner.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaRecorderStressTestRunner.java
@@ -44,7 +44,9 @@
     public static int mVideoHeight = profile.videoFrameHeight;
     public static int mBitRate = profile.videoBitRate;
     public static boolean mRemoveVideo = true;
-    public static int mDuration = 10000;
+    public static int mDuration = 10 * 1000; // 10 seconds
+    public static int mTimeLapseDuration = 180 * 1000; // 3 minutes
+    public static double mCaptureRate = 0.5; // 2 sec timelapse interval
 
     @Override
     public TestSuite getAllTests() {
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaRecorderStressTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaRecorderStressTest.java
index e6177ba..73ee4dd 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaRecorderStressTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaRecorderStressTest.java
@@ -22,11 +22,13 @@
 import java.io.BufferedWriter;
 import java.io.File;
 import java.io.FileWriter;
+import java.io.IOException;
 import java.io.Writer;
 import java.util.concurrent.Semaphore;
 import java.util.concurrent.TimeUnit;
 
 import android.hardware.Camera;
+import android.media.CamcorderProfile;
 import android.media.MediaPlayer;
 import android.media.MediaRecorder;
 import android.os.Handler;
@@ -39,21 +41,21 @@
 
 /**
  * Junit / Instrumentation test case for the media player api
- 
- */  
-public class MediaRecorderStressTest extends ActivityInstrumentationTestCase2<MediaFrameworkTest> {    
-    
-  
+ */
+public class MediaRecorderStressTest extends ActivityInstrumentationTestCase2<MediaFrameworkTest> {
+
     private String TAG = "MediaRecorderStressTest";
     private MediaRecorder mRecorder;
     private Camera mCamera;
-   
+
     private static final int NUMBER_OF_CAMERA_STRESS_LOOPS = 100;
     private static final int NUMBER_OF_RECORDER_STRESS_LOOPS = 100;
     private static final int NUMBER_OF_RECORDERANDPLAY_STRESS_LOOPS = 50;
     private static final int NUMBER_OF_SWTICHING_LOOPS_BW_CAMERA_AND_RECORDER = 200;
-    private static final long WAIT_TIME_CAMERA_TEST = 3000;  // 3 second
-    private static final long WAIT_TIME_RECORDER_TEST = 6000;  // 6 second
+    private static final int NUMBER_OF_TIME_LAPSE_LOOPS = 25;
+    private static final int TIME_LAPSE_PLAYBACK_WAIT_TIME = 5* 1000; // 5 seconds
+    private static final long WAIT_TIME_CAMERA_TEST = 3 * 1000; // 3 seconds
+    private static final long WAIT_TIME_RECORDER_TEST = 6 * 1000; // 6 seconds
     private static final String OUTPUT_FILE = "/sdcard/temp";
     private static final String OUTPUT_FILE_EXT = ".3gp";
     private static final String MEDIA_STRESS_OUTPUT =
@@ -61,7 +63,7 @@
     private final CameraErrorCallback mCameraErrorCallback = new CameraErrorCallback();
     private final RecorderErrorCallback mRecorderErrorCallback = new RecorderErrorCallback();
 
-    private final static int WAIT_TIMEOUT = 10000;
+    private final static int WAIT_TIMEOUT = 10 * 1000; // 10 seconds
     private Thread mLooperThread;
     private Handler mHandler;
 
@@ -306,7 +308,7 @@
         }
     }
 
-    public void removeRecodedVideo(String filename){
+    public void removeRecordedVideo(String filename){
         File video = new File(filename);
         Log.v(TAG, "remove recorded video " + filename);
         video.delete();
@@ -381,7 +383,7 @@
                 mp.release();
                 validateRecordedVideo(filename);
                 if (remove_video) {
-                    removeRecodedVideo(filename);
+                    removeRecordedVideo(filename);
                 }
                 output.write(", " + i);
             }
@@ -392,4 +394,90 @@
         output.write("\n\n");
         output.close();
     }
+
+    // Test case for stressing time lapse
+    @LargeTest
+    public void testStressTimeLapse() throws Exception {
+        SurfaceHolder mSurfaceHolder;
+        mSurfaceHolder = MediaFrameworkTest.mSurfaceView.getHolder();
+        int record_duration = MediaRecorderStressTestRunner.mTimeLapseDuration;
+        boolean remove_video = MediaRecorderStressTestRunner.mRemoveVideo;
+        double captureRate = MediaRecorderStressTestRunner.mCaptureRate;
+        String filename;
+        File stressOutFile = new File(MEDIA_STRESS_OUTPUT);
+        Writer output = new BufferedWriter(new FileWriter(stressOutFile, true));
+        output.write("Start camera time lapse stress:\n");
+        output.write("Total number of loops: " + NUMBER_OF_TIME_LAPSE_LOOPS + "\n");
+
+        try {
+            output.write("No of loop: ");
+            for (int i = 0; i < NUMBER_OF_TIME_LAPSE_LOOPS; i++) {
+                filename = OUTPUT_FILE + i + OUTPUT_FILE_EXT;
+                Log.v(TAG, filename);
+                runOnLooper(new Runnable() {
+                    @Override
+                    public void run() {
+                        mRecorder = new MediaRecorder();
+                    }
+                });
+
+                // Set callback
+                mRecorder.setOnErrorListener(mRecorderErrorCallback);
+
+                // Set video source
+                mRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
+
+                // Set camcorder profile for time lapse
+                CamcorderProfile profile =
+                        CamcorderProfile.get(CamcorderProfile.QUALITY_TIME_LAPSE_HIGH);
+                mRecorder.setProfile(profile);
+
+                // Set the timelapse setting; 0.1 = 10 sec timelapse, 0.5 = 2 sec timelapse, etc.
+                // http://developer.android.com/guide/topics/media/camera.html#time-lapse-video
+                mRecorder.setCaptureRate(captureRate);
+
+                // Set output file
+                mRecorder.setOutputFile(filename);
+
+                // Set the preview display
+                Log.v(TAG, "mediaRecorder setPreviewDisplay");
+                mRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());
+
+                mRecorder.prepare();
+                mRecorder.start();
+                Thread.sleep(record_duration);
+                Log.v(TAG, "Before stop");
+                mRecorder.stop();
+                mRecorder.release();
+
+                // Start the playback
+                MediaPlayer mp = new MediaPlayer();
+                mp.setDataSource(filename);
+                mp.setDisplay(mSurfaceHolder);
+                mp.prepare();
+                mp.start();
+                Thread.sleep(TIME_LAPSE_PLAYBACK_WAIT_TIME);
+                mp.release();
+                validateRecordedVideo(filename);
+                if(remove_video) {
+                  removeRecordedVideo(filename);
+                }
+                output.write(", " + i);
+            }
+        }
+        catch (IllegalStateException e) {
+            assertTrue("Camera time lapse stress test IllegalStateException", false);
+            Log.v(TAG, e.toString());
+        }
+        catch (IOException e) {
+            assertTrue("Camera time lapse stress test IOException", false);
+            Log.v(TAG, e.toString());
+        }
+        catch (Exception e) {
+            assertTrue("Camera time lapse stress test Exception", false);
+            Log.v(TAG, e.toString());
+        }
+        output.write("\n\n");
+        output.close();
+    }
 }
diff --git a/native/android/native_window.cpp b/native/android/native_window.cpp
index 6b37a12..c58ee00 100644
--- a/native/android/native_window.cpp
+++ b/native/android/native_window.cpp
@@ -18,7 +18,7 @@
 #include <utils/Log.h>
 
 #include <android/native_window_jni.h>
-#include <surfaceflinger/Surface.h>
+#include <gui/Surface.h>
 #include <android_runtime/android_view_Surface.h>
 #include <android_runtime/android_graphics_SurfaceTexture.h>
 
diff --git a/opengl/libagl/TextureObjectManager.cpp b/opengl/libagl/TextureObjectManager.cpp
index 6a006aa..06d45cc 100644
--- a/opengl/libagl/TextureObjectManager.cpp
+++ b/opengl/libagl/TextureObjectManager.cpp
@@ -19,8 +19,6 @@
 #include "context.h"
 #include "TextureObjectManager.h"
 
-#include <private/ui/android_natives_priv.h>
-
 namespace android {
 // ----------------------------------------------------------------------------
 
diff --git a/opengl/libagl/context.h b/opengl/libagl/context.h
index ef36b56..7065a30 100644
--- a/opengl/libagl/context.h
+++ b/opengl/libagl/context.h
@@ -1,20 +1,642 @@
-/* libs/opengles/context.h
-**
-** Copyright 2006, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License"); 
-** you may not use this file except in compliance with the License. 
-** You may obtain a copy of the License at 
-**
-**     http://www.apache.org/licenses/LICENSE-2.0 
-**
-** Unless required by applicable law or agreed to in writing, software 
-** distributed under the License is distributed on an "AS IS" BASIS, 
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
-** See the License for the specific language governing permissions and 
-** limitations under the License.
-*/
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-#include <private/opengles/gl_context.h>
+#ifndef ANDROID_OPENGLES_CONTEXT_H
+#define ANDROID_OPENGLES_CONTEXT_H
+
+#include <stdint.h>
+#include <stddef.h>
+#include <sys/types.h>
+#include <pthread.h>
+#ifdef HAVE_ANDROID_OS
+#include <bionic_tls.h>
+#endif
+
+#include <private/pixelflinger/ggl_context.h>
+#include <hardware/gralloc.h>
+
+#include <GLES/gl.h>
+#include <GLES/glext.h>
+
+namespace android {
+
+
+const unsigned int OGLES_NUM_COMPRESSED_TEXTURE_FORMATS = 10
+#ifdef GL_OES_compressed_ETC1_RGB8_texture
+        + 1
+#endif
+        ;
+
+class EGLTextureObject;
+class EGLSurfaceManager;
+class EGLBufferObjectManager;
+
+namespace gl {
+
+struct ogles_context_t;
+struct matrixx_t;
+struct transform_t;
+struct buffer_t;
+
+ogles_context_t* getGlContext();
+
+template<typename T>
+static inline void swap(T& a, T& b) {
+    T t(a); a = b; b = t;
+}
+template<typename T>
+inline T max(T a, T b) {
+    return a<b ? b : a;
+}
+template<typename T>
+inline T max(T a, T b, T c) {
+    return max(a, max(b, c));
+}
+template<typename T>
+inline T min(T a, T b) {
+    return a<b ? a : b;
+}
+template<typename T>
+inline T min(T a, T b, T c) {
+    return min(a, min(b, c));
+}
+template<typename T>
+inline T min(T a, T b, T c, T d) {
+    return min(min(a,b), min(c,d));
+}
+
+// ----------------------------------------------------------------------------
+// vertices
+// ----------------------------------------------------------------------------
+
+struct vec3_t {
+    union {
+        struct { GLfixed x, y, z; };
+        struct { GLfixed r, g, b; };
+        struct { GLfixed S, T, R; };
+        GLfixed v[3];
+    };
+};
+
+struct vec4_t {
+    union {
+        struct { GLfixed x, y, z, w; };
+        struct { GLfixed r, g, b, a; };
+        struct { GLfixed S, T, R, Q; };
+        GLfixed v[4];
+    };
+};
+
+struct vertex_t {
+    enum {
+        // these constant matter for our clipping
+        CLIP_L          = 0x0001,   // clipping flags
+        CLIP_R          = 0x0002,
+        CLIP_B          = 0x0004,
+        CLIP_T          = 0x0008,
+        CLIP_N          = 0x0010,
+        CLIP_F          = 0x0020,
+
+        EYE             = 0x0040,
+        RESERVED        = 0x0080,
+
+        USER_CLIP_0     = 0x0100,   // user clipping flags
+        USER_CLIP_1     = 0x0200,
+        USER_CLIP_2     = 0x0400,
+        USER_CLIP_3     = 0x0800,
+        USER_CLIP_4     = 0x1000,
+        USER_CLIP_5     = 0x2000,
+
+        LIT             = 0x4000,   // lighting has been applied
+        TT              = 0x8000,   // texture coords transformed
+
+        FRUSTUM_CLIP_ALL= 0x003F,
+        USER_CLIP_ALL   = 0x3F00,
+        CLIP_ALL        = 0x3F3F,
+    };
+
+    // the fields below are arranged to minimize d-cache usage
+    // we group together, by cache-line, the fields most likely to be used
+
+    union {
+    vec4_t          obj;
+    vec4_t          eye;
+    };
+    vec4_t          clip;
+
+    uint32_t        flags;
+    size_t          index;  // cache tag, and vertex index
+    GLfixed         fog;
+    uint8_t         locked;
+    uint8_t         mru;
+    uint8_t         reserved[2];
+    vec4_t          window;
+
+    vec4_t          color;
+    vec4_t          texture[GGL_TEXTURE_UNIT_COUNT];
+    uint32_t        reserved1[4];
+
+    inline void clear() {
+        flags = index = locked = mru = 0;
+    }
+};
+
+struct point_size_t {
+    GGLcoord    size;
+    GLboolean   smooth;
+};
+
+struct line_width_t {
+    GGLcoord    width;
+    GLboolean   smooth;
+};
+
+struct polygon_offset_t {
+    GLfixed     factor;
+    GLfixed     units;
+    GLboolean   enable;
+};
+
+// ----------------------------------------------------------------------------
+// arrays
+// ----------------------------------------------------------------------------
+
+struct array_t {
+    typedef void (*fetcher_t)(ogles_context_t*, GLfixed*, const GLvoid*);
+    fetcher_t       fetch;
+    GLvoid const*   physical_pointer;
+    GLint           size;
+    GLsizei         stride;
+    GLvoid const*   pointer;
+    buffer_t const* bo;
+    uint16_t        type;
+    GLboolean       enable;
+    GLboolean       pad;
+    GLsizei         bounds;
+    void init(GLint, GLenum, GLsizei, const GLvoid *, const buffer_t*, GLsizei);
+    inline void resolve();
+    inline const GLubyte* element(GLint i) const {
+        return (const GLubyte*)physical_pointer + i * stride;
+    }
+};
+
+struct array_machine_t {
+    array_t         vertex;
+    array_t         normal;
+    array_t         color;
+    array_t         texture[GGL_TEXTURE_UNIT_COUNT];
+    uint8_t         activeTexture;
+    uint8_t         tmu;
+    uint16_t        cull;
+    uint32_t        flags;
+    GLenum          indicesType;
+    buffer_t const* array_buffer;
+    buffer_t const* element_array_buffer;
+
+    void (*compileElements)(ogles_context_t*, vertex_t*, GLint, GLsizei);
+    void (*compileElement)(ogles_context_t*, vertex_t*, GLint);
+
+    void (*mvp_transform)(transform_t const*, vec4_t*, vec4_t const*);
+    void (*mv_transform)(transform_t const*, vec4_t*, vec4_t const*);
+    void (*tex_transform[2])(transform_t const*, vec4_t*, vec4_t const*);
+    void (*perspective)(ogles_context_t*c, vertex_t* v);
+    void (*clipVertex)(ogles_context_t* c, vertex_t* nv,
+            GGLfixed t, const vertex_t* s, const vertex_t* p);
+    void (*clipEye)(ogles_context_t* c, vertex_t* nv,
+            GGLfixed t, const vertex_t* s, const vertex_t* p);
+};
+
+struct vertex_cache_t {
+    enum {
+        // must be at least 4
+        // 3 vertice for triangles
+        // or 2 + 2 for indexed triangles w/ cache contention
+        VERTEX_BUFFER_SIZE  = 8,
+        // must be a power of two and at least 3
+        VERTEX_CACHE_SIZE   = 64,   // 8 KB
+
+        INDEX_BITS      = 16,
+        INDEX_MASK      = ((1LU<<INDEX_BITS)-1),
+        INDEX_SEQ       = 1LU<<INDEX_BITS,
+    };
+    vertex_t*       vBuffer;
+    vertex_t*       vCache;
+    uint32_t        sequence;
+    void*           base;
+    uint32_t        total;
+    uint32_t        misses;
+    int64_t         startTime;
+    void init();
+    void uninit();
+    void clear();
+    void dump_stats(GLenum mode);
+};
+
+// ----------------------------------------------------------------------------
+// fog
+// ----------------------------------------------------------------------------
+
+struct fog_t {
+    GLfixed     density;
+    GLfixed     start;
+    GLfixed     end;
+    GLfixed     invEndMinusStart;
+    GLenum      mode;
+    GLfixed     (*fog)(ogles_context_t* c, GLfixed z);
+};
+
+// ----------------------------------------------------------------------------
+// user clip planes
+// ----------------------------------------------------------------------------
+
+const unsigned int OGLES_MAX_CLIP_PLANES = 6;
+
+struct clip_plane_t {
+    vec4_t      equation;
+};
+
+struct user_clip_planes_t {
+    clip_plane_t    plane[OGLES_MAX_CLIP_PLANES];
+    uint32_t        enable;
+};
+
+// ----------------------------------------------------------------------------
+// lighting
+// ----------------------------------------------------------------------------
+
+const unsigned int OGLES_MAX_LIGHTS = 8;
+
+struct light_t {
+    vec4_t      ambient;
+    vec4_t      diffuse;
+    vec4_t      specular;
+    vec4_t      implicitAmbient;
+    vec4_t      implicitDiffuse;
+    vec4_t      implicitSpecular;
+    vec4_t      position;       // position in eye space
+    vec4_t      objPosition;
+    vec4_t      normalizedObjPosition;
+    vec4_t      spotDir;
+    vec4_t      normalizedSpotDir;
+    GLfixed     spotExp;
+    GLfixed     spotCutoff;
+    GLfixed     spotCutoffCosine;
+    GLfixed     attenuation[3];
+    GLfixed     rConstAttenuation;
+    GLboolean   enable;
+};
+
+struct material_t {
+    vec4_t      ambient;
+    vec4_t      diffuse;
+    vec4_t      specular;
+    vec4_t      emission;
+    GLfixed     shininess;
+};
+
+struct light_model_t {
+    vec4_t      ambient;
+    GLboolean   twoSide;
+};
+
+struct color_material_t {
+    GLenum      face;
+    GLenum      mode;
+    GLboolean   enable;
+};
+
+struct lighting_t {
+    light_t             lights[OGLES_MAX_LIGHTS];
+    material_t          front;
+    light_model_t       lightModel;
+    color_material_t    colorMaterial;
+    vec4_t              implicitSceneEmissionAndAmbient;
+    vec4_t              objViewer;
+    uint32_t            enabledLights;
+    GLboolean           enable;
+    GLenum              shadeModel;
+    typedef void (*light_fct_t)(ogles_context_t*, vertex_t*);
+    void (*lightVertex)(ogles_context_t* c, vertex_t* v);
+    void (*lightTriangle)(ogles_context_t* c,
+            vertex_t* v0, vertex_t* v1, vertex_t* v2);
+};
+
+struct culling_t {
+    GLenum      cullFace;
+    GLenum      frontFace;
+    GLboolean   enable;
+};
+
+// ----------------------------------------------------------------------------
+// textures
+// ----------------------------------------------------------------------------
+
+struct texture_unit_t {
+    GLuint              name;
+    EGLTextureObject*   texture;
+    uint8_t             dirty;
+};
+
+struct texture_state_t
+{
+    texture_unit_t      tmu[GGL_TEXTURE_UNIT_COUNT];
+    int                 active;     // active tmu
+    EGLTextureObject*   defaultTexture;
+    GGLContext*         ggl;
+    uint8_t             packAlignment;
+    uint8_t             unpackAlignment;
+};
+
+// ----------------------------------------------------------------------------
+// transformation and matrices
+// ----------------------------------------------------------------------------
+
+struct matrixf_t;
+
+struct matrixx_t {
+    GLfixed m[16];
+    void load(const matrixf_t& rhs);
+};
+
+struct matrix_stack_t;
+
+
+struct matrixf_t {
+    void loadIdentity();
+    void load(const matrixf_t& rhs);
+
+    inline GLfloat* editElements() { return m; }
+    inline GLfloat const* elements() const { return m; }
+
+    void set(const GLfixed* rhs);
+    void set(const GLfloat* rhs);
+
+    static void multiply(matrixf_t& r,
+            const matrixf_t& lhs, const matrixf_t& rhs);
+
+    void dump(const char* what);
+
+private:
+    friend struct matrix_stack_t;
+    GLfloat     m[16];
+    void load(const GLfixed* rhs);
+    void load(const GLfloat* rhs);
+    void multiply(const matrixf_t& rhs);
+    void translate(GLfloat x, GLfloat y, GLfloat z);
+    void scale(GLfloat x, GLfloat y, GLfloat z);
+    void rotate(GLfloat a, GLfloat x, GLfloat y, GLfloat z);
+};
+
+enum {
+    OP_IDENTITY         = 0x00,
+    OP_TRANSLATE        = 0x01,
+    OP_UNIFORM_SCALE    = 0x02,
+    OP_SCALE            = 0x05,
+    OP_ROTATE           = 0x08,
+    OP_SKEW             = 0x10,
+    OP_ALL              = 0x1F
+};
+
+struct transform_t {
+    enum {
+        FLAGS_2D_PROJECTION = 0x1
+    };
+    matrixx_t       matrix;
+    uint32_t        flags;
+    uint32_t        ops;
+
+    union {
+        struct {
+            void (*point2)(transform_t const* t, vec4_t*, vec4_t const*);
+            void (*point3)(transform_t const* t, vec4_t*, vec4_t const*);
+            void (*point4)(transform_t const* t, vec4_t*, vec4_t const*);
+        };
+        void (*pointv[3])(transform_t const* t, vec4_t*, vec4_t const*);
+    };
+
+    void loadIdentity();
+    void picker();
+    void dump(const char* what);
+};
+
+struct mvui_transform_t : public transform_t
+{
+    void picker();
+};
+
+struct matrix_stack_t {
+    enum {
+        DO_PICKER           = 0x1,
+        DO_FLOAT_TO_FIXED   = 0x2
+    };
+    transform_t     transform;
+    uint8_t         maxDepth;
+    uint8_t         depth;
+    uint8_t         dirty;
+    uint8_t         reserved;
+    matrixf_t       *stack;
+    uint8_t         *ops;
+    void init(int depth);
+    void uninit();
+    void loadIdentity();
+    void load(const GLfixed* rhs);
+    void load(const GLfloat* rhs);
+    void multiply(const matrixf_t& rhs);
+    void translate(GLfloat x, GLfloat y, GLfloat z);
+    void scale(GLfloat x, GLfloat y, GLfloat z);
+    void rotate(GLfloat a, GLfloat x, GLfloat y, GLfloat z);
+    GLint push();
+    GLint pop();
+    void validate();
+    matrixf_t& top() { return stack[depth]; }
+    const matrixf_t& top() const { return stack[depth]; }
+    uint32_t top_ops() const { return ops[depth]; }
+    inline bool isRigidBody() const {
+        return !(ops[depth] & ~(OP_TRANSLATE|OP_UNIFORM_SCALE|OP_ROTATE));
+    }
+};
+
+struct vp_transform_t {
+    transform_t     transform;
+    matrixf_t       matrix;
+    GLfloat         zNear;
+    GLfloat         zFar;
+    void loadIdentity();
+};
+
+struct transform_state_t {
+    enum {
+        MODELVIEW           = 0x01,
+        PROJECTION          = 0x02,
+        VIEWPORT            = 0x04,
+        TEXTURE             = 0x08,
+        MVUI                = 0x10,
+        MVIT                = 0x20,
+        MVP                 = 0x40,
+    };
+    matrix_stack_t      *current;
+    matrix_stack_t      modelview;
+    matrix_stack_t      projection;
+    matrix_stack_t      texture[GGL_TEXTURE_UNIT_COUNT];
+
+    // modelview * projection
+    transform_t         mvp     __attribute__((aligned(32)));
+    // viewport transformation
+    vp_transform_t      vpt     __attribute__((aligned(32)));
+    // same for 4-D vertices
+    transform_t         mvp4;
+    // full modelview inverse transpose
+    transform_t         mvit4;
+    // upper 3x3 of mv-inverse-transpose (for normals)
+    mvui_transform_t    mvui;
+
+    GLenum              matrixMode;
+    GLenum              rescaleNormals;
+    uint32_t            dirty;
+    void invalidate();
+    void update_mvp();
+    void update_mvit();
+    void update_mvui();
+};
+
+struct viewport_t {
+    GLint       x;
+    GLint       y;
+    GLsizei     w;
+    GLsizei     h;
+    struct {
+        GLint       x;
+        GLint       y;
+    } surfaceport;
+    struct {
+        GLint       x;
+        GLint       y;
+        GLsizei     w;
+        GLsizei     h;
+    } scissor;
+};
+
+// ----------------------------------------------------------------------------
+// Lerping
+// ----------------------------------------------------------------------------
+
+struct compute_iterators_t
+{
+    void initTriangle(
+            vertex_t const* v0,
+            vertex_t const* v1,
+            vertex_t const* v2);
+
+    void initLine(
+            vertex_t const* v0,
+            vertex_t const* v1);
+
+    inline void initLerp(vertex_t const* v0, uint32_t enables);
+
+    int iteratorsScale(int32_t it[3],
+            int32_t c0, int32_t c1, int32_t c2) const;
+
+    void iterators1616(GGLfixed it[3],
+            GGLfixed c0, GGLfixed c1, GGLfixed c2) const;
+
+    void iterators0032(int32_t it[3],
+            int32_t c0, int32_t c1, int32_t c2) const;
+
+    void iterators0032(int64_t it[3],
+            int32_t c0, int32_t c1, int32_t c2) const;
+
+    GGLcoord area() const { return m_area; }
+
+private:
+    // don't change order of members here -- used by iterators.S
+    GGLcoord m_dx01, m_dy10, m_dx20, m_dy02;
+    GGLcoord m_x0, m_y0;
+    GGLcoord m_area;
+    uint8_t m_scale;
+    uint8_t m_area_scale;
+    uint8_t m_reserved[2];
+
+};
+
+// ----------------------------------------------------------------------------
+// state
+// ----------------------------------------------------------------------------
+
+#ifdef HAVE_ANDROID_OS
+    // We have a dedicated TLS slot in bionic
+    inline void setGlThreadSpecific(ogles_context_t *value) {
+        ((uint32_t *)__get_tls())[TLS_SLOT_OPENGL] = (uint32_t)value;
+    }
+    inline ogles_context_t* getGlThreadSpecific() {
+        return (ogles_context_t *)(((unsigned *)__get_tls())[TLS_SLOT_OPENGL]);
+    }
+#else
+    extern pthread_key_t gGLKey;
+    inline void setGlThreadSpecific(ogles_context_t *value) {
+        pthread_setspecific(gGLKey, value);
+    }
+    inline ogles_context_t* getGlThreadSpecific() {
+        return static_cast<ogles_context_t*>(pthread_getspecific(gGLKey));
+    }
+#endif
+
+
+struct prims_t {
+    typedef ogles_context_t* GL;
+    void (*renderPoint)(GL, vertex_t*);
+    void (*renderLine)(GL, vertex_t*, vertex_t*);
+    void (*renderTriangle)(GL, vertex_t*, vertex_t*, vertex_t*);
+};
+
+struct ogles_context_t {
+    context_t               rasterizer;
+    array_machine_t         arrays         __attribute__((aligned(32)));
+    texture_state_t         textures;
+    transform_state_t       transforms;
+    vertex_cache_t          vc;
+    prims_t                 prims;
+    culling_t               cull;
+    lighting_t              lighting;
+    user_clip_planes_t      clipPlanes;
+    compute_iterators_t     lerp;           __attribute__((aligned(32)));
+    vertex_t                current;
+    vec4_t                  currentColorClamped;
+    vec3_t                  currentNormal;
+    viewport_t              viewport;
+    point_size_t            point;
+    line_width_t            line;
+    polygon_offset_t        polygonOffset;
+    fog_t                   fog;
+    uint32_t                perspective : 1;
+    uint32_t                transformTextures : 1;
+    EGLSurfaceManager*      surfaceManager;
+    EGLBufferObjectManager* bufferObjectManager;
+
+    GLenum                  error;
+
+    static inline ogles_context_t* get() {
+        return getGlThreadSpecific();
+    }
+
+};
+
+}; // namespace gl
+}; // namespace android
 
 using namespace android::gl;
+
+#endif // ANDROID_OPENGLES_CONTEXT_H
+
diff --git a/opengl/libagl/egl.cpp b/opengl/libagl/egl.cpp
index eb55bee..92d32a2 100644
--- a/opengl/libagl/egl.cpp
+++ b/opengl/libagl/egl.cpp
@@ -30,6 +30,7 @@
 #include <cutils/atomic.h>
 
 #include <utils/threads.h>
+#include <ui/ANativeObjectBase.h>
 
 #include <EGL/egl.h>
 #include <EGL/eglext.h>
@@ -39,8 +40,6 @@
 #include <pixelflinger/format.h>
 #include <pixelflinger/pixelflinger.h>
 
-#include <private/ui/android_natives_priv.h>
-
 #include "context.h"
 #include "state.h"
 #include "texture.h"
@@ -49,13 +48,14 @@
 #undef NELEM
 #define NELEM(x) (sizeof(x)/sizeof(*(x)))
 
+// ----------------------------------------------------------------------------
 
 EGLBoolean EGLAPI eglSetSwapRectangleANDROID(EGLDisplay dpy, EGLSurface draw,
         EGLint left, EGLint top, EGLint width, EGLint height);
 
-
 // ----------------------------------------------------------------------------
 namespace android {
+
 // ----------------------------------------------------------------------------
 
 const unsigned int NUM_DISPLAYS = 1;
diff --git a/opengl/libagl/texture.cpp b/opengl/libagl/texture.cpp
index 88e8651..08536df 100644
--- a/opengl/libagl/texture.cpp
+++ b/opengl/libagl/texture.cpp
@@ -23,7 +23,6 @@
 #include "texture.h"
 #include "TextureObjectManager.h"
 
-#include <private/ui/android_natives_priv.h>
 #include <ETC1/etc1.h>
 
 namespace android {
diff --git a/opengl/libs/EGL/eglApi.cpp b/opengl/libs/EGL/eglApi.cpp
index a5dc832..a1bd82d 100644
--- a/opengl/libs/EGL/eglApi.cpp
+++ b/opengl/libs/EGL/eglApi.cpp
@@ -14,6 +14,8 @@
  ** limitations under the License.
  */
 
+#define ATRACE_TAG ATRACE_TAG_GRAPHICS
+
 #include <ctype.h>
 #include <stdlib.h>
 #include <string.h>
@@ -34,6 +36,7 @@
 #include <utils/KeyedVector.h>
 #include <utils/SortedVector.h>
 #include <utils/String8.h>
+#include <utils/Trace.h>
 
 #include "egl_impl.h"
 #include "egl_tls.h"
@@ -348,6 +351,7 @@
 }
 
 void EGLAPI eglBeginFrame(EGLDisplay dpy, EGLSurface surface) {
+    ATRACE_CALL();
     clearError();
 
     egl_display_t const * const dp = validate_display(dpy);
@@ -712,6 +716,7 @@
 
 EGLBoolean eglSwapBuffers(EGLDisplay dpy, EGLSurface draw)
 {
+    ATRACE_CALL();
     clearError();
 
     egl_display_t const * const dp = validate_display(dpy);
diff --git a/opengl/libs/GLES_trace/src/gltrace_api.cpp b/opengl/libs/GLES_trace/src/gltrace_api.cpp
index 358bf54..cef6cbb 100644
--- a/opengl/libs/GLES_trace/src/gltrace_api.cpp
+++ b/opengl/libs/GLES_trace/src/gltrace_api.cpp
@@ -49,9 +49,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -80,9 +83,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -117,9 +123,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) name,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -148,9 +158,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -179,9 +192,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -210,9 +226,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -241,9 +260,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -284,9 +306,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -309,9 +334,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -340,9 +368,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -371,9 +402,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -414,9 +448,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -436,7 +473,7 @@
     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);
+    arg_size->add_intvalue(size);
 
     // copy argument data
     GLMessage_DataType *arg_data = glmsg.add_args();
@@ -457,9 +494,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) data,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -479,13 +520,13 @@
     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);
+    arg_offset->add_intvalue(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);
+    arg_size->add_intvalue(size);
 
     // copy argument data
     GLMessage_DataType *arg_data = glmsg.add_args();
@@ -500,9 +541,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) data,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -531,9 +576,12 @@
     rt->set_type(GLMessage::DataType::ENUM);
     rt->add_intvalue((int)retValue);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 
     return retValue;
@@ -558,9 +606,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -601,9 +652,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -626,9 +680,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -651,9 +708,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -694,9 +754,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -719,9 +782,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -786,9 +852,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) data,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -859,9 +929,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) data,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -926,9 +1000,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -993,9 +1070,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -1018,9 +1098,12 @@
     rt->set_type(GLMessage::DataType::INT);
     rt->add_intvalue(retValue);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 
     return retValue;
@@ -1051,9 +1134,12 @@
     rt->set_type(GLMessage::DataType::INT);
     rt->add_intvalue(retValue);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 
     return retValue;
@@ -1078,9 +1164,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -1109,9 +1198,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) buffers,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -1140,9 +1233,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) framebuffers,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -1165,9 +1262,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -1196,9 +1296,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) renderbuffers,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -1221,9 +1325,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -1252,9 +1359,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) textures,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -1277,9 +1388,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -1302,9 +1416,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -1333,9 +1450,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -1364,9 +1484,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -1389,9 +1512,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -1414,9 +1540,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -1451,9 +1580,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -1494,9 +1626,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) indices,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -1519,9 +1655,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -1544,9 +1683,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -1563,9 +1705,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -1582,9 +1727,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -1625,9 +1773,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -1674,9 +1825,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -1699,9 +1853,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -1730,9 +1887,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) buffers,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -1755,9 +1916,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -1786,9 +1950,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) framebuffers,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -1817,9 +1985,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) renderbuffers,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -1848,9 +2020,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) textures,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -1909,9 +2085,16 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) length,
+        (void *) size,
+        (void *) type,
+        (void *) name,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -1970,9 +2153,16 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) length,
+        (void *) size,
+        (void *) type,
+        (void *) name,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -2013,9 +2203,14 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) count,
+        (void *) shaders,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -2050,9 +2245,13 @@
     rt->set_type(GLMessage::DataType::INT);
     rt->add_intvalue(retValue);
 
+    void *pointerArgs[] = {
+        (void *) name,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 
     return retValue;
@@ -2083,9 +2282,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) params,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -2120,9 +2323,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) params,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -2145,9 +2352,12 @@
     rt->set_type(GLMessage::DataType::ENUM);
     rt->add_intvalue((int)retValue);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 
     return retValue;
@@ -2178,9 +2388,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) params,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -2221,9 +2435,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) params,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -2252,9 +2470,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) params,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -2289,9 +2511,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) params,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -2332,9 +2558,14 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) length,
+        (void *) infolog,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -2369,9 +2600,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) params,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -2406,9 +2641,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) params,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -2449,9 +2688,14 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) length,
+        (void *) infolog,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -2492,9 +2736,14 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) range,
+        (void *) precision,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -2535,9 +2784,14 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) length,
+        (void *) source,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -2566,9 +2820,13 @@
     rt->set_type(GLMessage::DataType::INT);
     rt->add_intvalue((int)retValue);
 
+    void *pointerArgs[] = {
+        (void *) retValue,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 
     return retValue;
@@ -2605,9 +2863,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) params,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -2642,9 +2904,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) params,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -2679,9 +2945,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) params,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -2716,9 +2986,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) params,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -2753,9 +3027,13 @@
     rt->set_type(GLMessage::DataType::INT);
     rt->add_intvalue(retValue);
 
+    void *pointerArgs[] = {
+        (void *) name,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 
     return retValue;
@@ -2792,9 +3070,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) params,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -2829,9 +3111,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) params,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -2866,9 +3152,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) pointer,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -2897,9 +3187,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -2928,9 +3221,12 @@
     rt->set_type(GLMessage::DataType::BOOL);
     rt->add_boolvalue(retValue);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 
     return retValue;
@@ -2961,9 +3257,12 @@
     rt->set_type(GLMessage::DataType::BOOL);
     rt->add_boolvalue(retValue);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 
     return retValue;
@@ -2994,9 +3293,12 @@
     rt->set_type(GLMessage::DataType::BOOL);
     rt->add_boolvalue(retValue);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 
     return retValue;
@@ -3027,9 +3329,12 @@
     rt->set_type(GLMessage::DataType::BOOL);
     rt->add_boolvalue(retValue);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 
     return retValue;
@@ -3060,9 +3365,12 @@
     rt->set_type(GLMessage::DataType::BOOL);
     rt->add_boolvalue(retValue);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 
     return retValue;
@@ -3093,9 +3401,12 @@
     rt->set_type(GLMessage::DataType::BOOL);
     rt->add_boolvalue(retValue);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 
     return retValue;
@@ -3126,9 +3437,12 @@
     rt->set_type(GLMessage::DataType::BOOL);
     rt->add_boolvalue(retValue);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 
     return retValue;
@@ -3153,9 +3467,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -3178,9 +3495,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -3209,9 +3529,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -3240,9 +3563,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -3301,9 +3627,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) pixels,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -3320,9 +3650,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -3363,9 +3696,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -3394,9 +3730,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -3437,9 +3776,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -3486,9 +3828,14 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) shaders,
+        (void *) binary,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -3529,9 +3876,14 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) string,
+        (void *) length,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -3566,9 +3918,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -3609,9 +3964,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -3634,9 +3992,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -3665,9 +4026,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -3702,9 +4066,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -3745,9 +4112,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -3818,9 +4188,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) pixels,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -3855,9 +4229,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -3892,9 +4269,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) params,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -3929,9 +4310,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -3966,9 +4350,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) params,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -4039,9 +4427,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) pixels,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -4070,9 +4462,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -4107,9 +4502,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) v,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -4138,9 +4537,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -4175,9 +4577,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) v,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -4212,9 +4618,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -4249,9 +4658,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) v,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -4286,9 +4699,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -4323,9 +4739,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) v,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -4366,9 +4786,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -4403,9 +4826,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) v,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -4446,9 +4873,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -4483,9 +4913,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) v,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -4532,9 +4966,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -4569,9 +5006,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) v,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -4618,9 +5059,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -4655,9 +5099,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) v,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -4698,9 +5146,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) value,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -4741,9 +5193,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) value,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -4784,9 +5240,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) value,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -4809,9 +5269,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -4834,9 +5297,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -4865,9 +5331,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -4896,9 +5365,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) values,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -4933,9 +5406,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -4964,9 +5440,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) values,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -5007,9 +5487,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -5038,9 +5521,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) values,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -5087,9 +5574,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -5118,9 +5608,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) values,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -5173,9 +5667,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) ptr,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -5216,9 +5714,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -5250,9 +5751,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) image,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -5281,9 +5786,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) image,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -5330,9 +5839,15 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) length,
+        (void *) binaryFormat,
+        (void *) binary,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -5373,9 +5888,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) binary,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -5410,9 +5929,13 @@
     rt->set_type(GLMessage::DataType::INT);
     rt->add_intvalue((int)retValue);
 
+    void *pointerArgs[] = {
+        (void *) retValue,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 
     return retValue;
@@ -5443,9 +5966,12 @@
     rt->set_type(GLMessage::DataType::BOOL);
     rt->add_boolvalue(retValue);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 
     return retValue;
@@ -5482,9 +6008,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) params,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -5561,9 +6091,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) pixels,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -5646,9 +6180,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) pixels,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -5719,9 +6257,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -5792,9 +6333,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) data,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -5877,9 +6422,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) data,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -5932,9 +6481,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -5957,9 +6509,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -5988,9 +6543,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) arrays,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -6019,9 +6578,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) arrays,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -6050,9 +6613,12 @@
     rt->set_type(GLMessage::DataType::BOOL);
     rt->add_boolvalue(retValue);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 
     return retValue;
@@ -6089,9 +6655,14 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) numGroups,
+        (void *) groups,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -6138,9 +6709,15 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) numCounters,
+        (void *) maxActiveCounters,
+        (void *) counters,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -6181,9 +6758,14 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) length,
+        (void *) groupString,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -6230,9 +6812,14 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) length,
+        (void *) counterString,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -6273,9 +6860,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) data,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -6304,9 +6895,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) monitors,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -6335,9 +6930,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) monitors,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -6384,9 +6983,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) countersList,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -6409,9 +7012,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -6434,9 +7040,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -6483,9 +7092,14 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) data,
+        (void *) bytesWritten,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -6562,9 +7176,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -6611,9 +7228,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -6660,9 +7280,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -6679,9 +7302,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -6722,9 +7348,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) label,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -6771,9 +7401,14 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) length,
+        (void *) label,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -6802,9 +7437,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) marker,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -6833,9 +7472,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) marker,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -6852,9 +7495,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -6889,9 +7535,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) attachments,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -6938,9 +7588,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -6993,9 +7646,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -7036,9 +7692,14 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) first,
+        (void *) count,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -7085,9 +7746,14 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) count,
+        (void *) indices,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -7116,9 +7782,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) ids,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -7147,9 +7817,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) ids,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -7178,9 +7852,12 @@
     rt->set_type(GLMessage::DataType::BOOL);
     rt->add_boolvalue(retValue);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 
     return retValue;
@@ -7211,9 +7888,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -7236,9 +7916,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -7273,9 +7956,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) params,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -7310,9 +7997,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) params,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -7335,9 +8026,12 @@
     rt->set_type(GLMessage::DataType::ENUM);
     rt->add_intvalue((int)retValue);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 
     return retValue;
@@ -7404,9 +8098,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) data,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -7447,9 +8145,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) params,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -7490,9 +8192,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) params,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -7527,9 +8233,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -7558,9 +8267,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -7601,9 +8313,13 @@
     rt->set_type(GLMessage::DataType::INT);
     rt->add_intvalue(retValue);
 
+    void *pointerArgs[] = {
+        (void *) strings,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 
     return retValue;
@@ -7628,9 +8344,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -7659,9 +8378,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) pipelines,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -7690,9 +8413,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) pipelines,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -7721,9 +8448,12 @@
     rt->set_type(GLMessage::DataType::BOOL);
     rt->add_boolvalue(retValue);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 
     return retValue;
@@ -7760,9 +8490,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -7797,9 +8530,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) params,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -7834,9 +8571,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -7877,9 +8617,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -7926,9 +8669,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -7981,9 +8727,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -8018,9 +8767,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -8061,9 +8813,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -8110,9 +8865,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -8165,9 +8923,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -8208,9 +8969,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) value,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -8251,9 +9016,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) value,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -8294,9 +9063,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) value,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -8337,9 +9110,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) value,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -8380,9 +9157,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) value,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -8423,9 +9204,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) value,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -8466,9 +9251,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) value,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -8509,9 +9298,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) value,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -8558,9 +9351,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) value,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -8607,9 +9404,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) value,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -8656,9 +9457,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) value,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -8681,9 +9486,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -8724,9 +9532,14 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) length,
+        (void *) infoLog,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -8767,9 +9580,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -8816,9 +9632,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -8871,9 +9690,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -8920,9 +9742,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -8975,9 +9800,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -9036,9 +9864,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -9085,9 +9916,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -9140,9 +9974,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -9165,9 +10002,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -9190,9 +10030,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -9221,9 +10064,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) bufs,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -9252,9 +10099,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) fences,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -9283,9 +10134,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) fences,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -9314,9 +10169,12 @@
     rt->set_type(GLMessage::DataType::BOOL);
     rt->add_boolvalue(retValue);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 
     return retValue;
@@ -9347,9 +10205,12 @@
     rt->set_type(GLMessage::DataType::BOOL);
     rt->add_boolvalue(retValue);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 
     return retValue;
@@ -9386,9 +10247,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) params,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -9411,9 +10276,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -9442,9 +10310,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -9467,9 +10338,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -9498,9 +10372,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -9535,9 +10412,14 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) num,
+        (void *) driverControls,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -9578,9 +10460,14 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) length,
+        (void *) driverControlString,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -9603,9 +10490,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -9628,9 +10518,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -9665,9 +10558,14 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) textures,
+        (void *) numTextures,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -9702,9 +10600,14 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) buffers,
+        (void *) numBuffers,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -9739,9 +10642,14 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) renderbuffers,
+        (void *) numRenderbuffers,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -9776,9 +10684,14 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) framebuffers,
+        (void *) numFramebuffers,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -9825,9 +10738,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) params,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -9862,9 +10779,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -9947,9 +10867,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) texels,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -9978,9 +10902,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) params,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -10015,9 +10943,14 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) shaders,
+        (void *) numShaders,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -10052,9 +10985,14 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) programs,
+        (void *) numPrograms,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -10083,9 +11021,12 @@
     rt->set_type(GLMessage::DataType::BOOL);
     rt->add_boolvalue(retValue);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 
     return retValue;
@@ -10128,9 +11069,14 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) source,
+        (void *) length,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -10177,9 +11123,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -10202,9 +11151,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -10236,9 +11188,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -10267,9 +11222,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) equation,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -10310,9 +11269,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -10341,9 +11303,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -10372,9 +11337,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) params,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -10427,9 +11396,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -10458,9 +11430,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) eqn,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -10495,9 +11471,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) params,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -10532,9 +11512,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) params,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -10569,9 +11553,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) params,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -10600,9 +11588,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -10631,9 +11622,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) params,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -10668,9 +11663,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -10705,9 +11703,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) params,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -10730,9 +11732,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) m,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -10767,9 +11773,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -10804,9 +11813,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) params,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -10829,9 +11842,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) m,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -10878,9 +11895,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -10915,9 +11935,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -10970,9 +11993,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -11001,9 +12027,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -11032,9 +12061,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) params,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -11057,9 +12090,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -11100,9 +12136,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -11137,9 +12176,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -11174,9 +12216,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -11211,9 +12256,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) params,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -11248,9 +12297,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -11279,9 +12331,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -11322,9 +12377,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -11347,9 +12405,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -11372,9 +12433,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -11403,9 +12467,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) equation,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -11446,9 +12514,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -11489,9 +12560,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -11532,9 +12606,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) pointer,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -11563,9 +12641,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -11588,9 +12669,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -11613,9 +12697,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -11644,9 +12731,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -11675,9 +12765,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) params,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -11730,9 +12824,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -11761,9 +12858,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) eqn,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -11792,9 +12893,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) params,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -11829,9 +12934,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) params,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -11866,9 +12975,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) params,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -11897,9 +13010,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) params,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -11934,9 +13051,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) params,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -11971,9 +13092,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) params,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -12008,9 +13133,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) params,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -12039,9 +13168,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -12070,9 +13202,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) params,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -12107,9 +13243,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -12144,9 +13283,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) params,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -12169,9 +13312,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -12188,9 +13334,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -12213,9 +13362,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) m,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -12238,9 +13391,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -12275,9 +13431,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -12312,9 +13471,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) params,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -12337,9 +13500,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -12362,9 +13528,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) m,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -12411,9 +13581,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -12448,9 +13621,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -12485,9 +13661,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) pointer,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -12540,9 +13720,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -12571,9 +13754,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -12602,9 +13788,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) params,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -12627,9 +13817,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -12658,9 +13851,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -12677,9 +13873,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -12696,9 +13895,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -12739,9 +13941,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -12770,9 +13975,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -12807,9 +14015,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -12832,9 +14043,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -12875,9 +14089,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) pointer,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -12912,9 +14130,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -12949,9 +14170,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -12986,9 +14210,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) params,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -13023,9 +14251,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) params,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -13060,9 +14292,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -13097,9 +14332,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) params,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -13134,9 +14373,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -13177,9 +14419,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) pointer,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -13214,9 +14460,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) pointer,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -13248,9 +14498,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -13291,9 +14544,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -13316,9 +14572,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -13365,9 +14624,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -13414,9 +14676,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -13463,9 +14728,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -13488,9 +14756,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) coords,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -13513,9 +14785,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) coords,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -13538,9 +14814,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) coords,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -13587,9 +14867,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -13612,9 +14895,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) coords,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -13643,9 +14930,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -13686,9 +14976,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -13711,9 +15004,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -13742,9 +15038,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) equation,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -13785,9 +15085,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -13816,9 +15119,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -13847,9 +15153,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -13878,9 +15187,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) params,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -13933,9 +15246,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -13964,9 +15280,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) eqn,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -13995,9 +15315,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) params,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -14032,9 +15356,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) params,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -14069,9 +15397,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) params,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -14106,9 +15438,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) params,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -14143,9 +15479,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) params,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -14174,9 +15514,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -14205,9 +15548,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) params,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -14242,9 +15589,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -14279,9 +15629,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) params,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -14304,9 +15658,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -14329,9 +15686,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) m,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -14366,9 +15727,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -14403,9 +15767,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) params,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -14428,9 +15796,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) m,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -14477,9 +15849,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -14514,9 +15889,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -14569,9 +15947,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -14600,9 +15981,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -14631,9 +16015,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) params,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -14656,9 +16044,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -14687,9 +16078,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -14730,9 +16124,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -14761,9 +16158,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -14798,9 +16198,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -14835,9 +16238,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -14872,9 +16278,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) params,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -14909,9 +16319,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -14946,9 +16359,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) params,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -14983,9 +16400,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -15014,9 +16434,12 @@
     rt->set_type(GLMessage::DataType::BOOL);
     rt->add_boolvalue(retValue);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 
     return retValue;
@@ -15047,9 +16470,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -15078,9 +16504,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) renderbuffers,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -15109,9 +16539,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) renderbuffers,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -15152,9 +16586,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -15189,9 +16626,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) params,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -15220,9 +16661,12 @@
     rt->set_type(GLMessage::DataType::BOOL);
     rt->add_boolvalue(retValue);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 
     return retValue;
@@ -15253,9 +16697,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -15284,9 +16731,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) framebuffers,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -15315,9 +16766,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) framebuffers,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -15346,9 +16801,12 @@
     rt->set_type(GLMessage::DataType::ENUM);
     rt->add_intvalue((int)retValue);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 
     return retValue;
@@ -15391,9 +16849,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -15440,9 +16901,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -15483,9 +16947,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) params,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -15508,9 +16976,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -15533,9 +17004,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -15552,9 +17026,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -15595,9 +17072,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) pointer,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -15638,9 +17119,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) pointer,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -15675,9 +17160,14 @@
     rt->set_type(GLMessage::DataType::INT);
     rt->add_intvalue(retValue);
 
+    void *pointerArgs[] = {
+        (void *) mantissa,
+        (void *) exponent,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 
     return retValue;
@@ -15708,9 +17198,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -15763,9 +17256,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -15818,9 +17314,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -15849,9 +17348,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) equation,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -15880,9 +17383,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) eqn,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -15905,9 +17412,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -15942,9 +17452,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -15979,9 +17492,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) params,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -16016,9 +17533,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -16053,9 +17573,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) params,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -16090,9 +17614,12 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -16127,9 +17654,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) params,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -16164,9 +17695,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) params,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -16201,9 +17736,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) params,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -16238,9 +17777,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) params,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -16269,9 +17812,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) eqn,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
@@ -16300,9 +17847,13 @@
     nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
     nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
+    void *pointerArgs[] = {
+        (void *) eqn,
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 }
 
diff --git a/opengl/libs/GLES_trace/src/gltrace_fixup.cpp b/opengl/libs/GLES_trace/src/gltrace_fixup.cpp
index 6c4feb5..c69ba5e1 100644
--- a/opengl/libs/GLES_trace/src/gltrace_fixup.cpp
+++ b/opengl/libs/GLES_trace/src/gltrace_fixup.cpp
@@ -76,21 +76,64 @@
     return 1;   // in doubt...
 }
 
+void fixup_GenericFloatArray(int argIndex, int nFloats, GLMessage *glmsg, void *src) {
+    GLMessage_DataType *arg_floatarray = glmsg->mutable_args(argIndex);
+    GLfloat *floatp = (GLfloat *)src;
+
+    if (floatp == NULL) {
+        return;
+    }
+
+    arg_floatarray->set_type(GLMessage::DataType::FLOAT);
+    arg_floatarray->set_isarray(true);
+    arg_floatarray->clear_floatvalue();
+
+    for (int i = 0; i < nFloats; i++, floatp++) {
+        arg_floatarray->add_floatvalue(*floatp);
+    }
+}
+
+void fixup_GenericIntArray(int argIndex, int nInts, GLMessage *glmsg, void *src) {
+    GLMessage_DataType *arg_intarray = glmsg->mutable_args(argIndex);
+    GLint *intp = (GLint *)src;
+
+    if (intp == NULL) {
+        return;
+    }
+
+    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_GenericEnumArray(int argIndex, int nEnums, GLMessage *glmsg, void *src) {
+    // fixup as if they were ints
+    fixup_GenericIntArray(argIndex, nEnums, glmsg, src);
+
+    // and then set the data type to be enum
+    GLMessage_DataType *arg_enumarray = glmsg->mutable_args(argIndex);
+    arg_enumarray->set_type(GLMessage::DataType::ENUM);
+}
+
 /** Generic helper function: extract pointer at argIndex and
     replace it with the C style string at *pointer */
-void fixup_CStringPtr(int argIndex, GLMessage *glmsg) {
+void fixup_CStringPtr(int argIndex, GLMessage *glmsg, void *src) {
     GLMessage_DataType *arg = glmsg->mutable_args(argIndex);
-    GLchar *ptr = (GLchar *)arg->intvalue(0);
+    GLchar *ptr = (GLchar *) src;
 
     arg->set_type(GLMessage::DataType::CHAR);
     arg->set_isarray(true);
     arg->add_charvalue(ptr);
 }
 
-void fixup_glGetString(GLMessage *glmsg) {
+void fixup_glGetString(GLMessage *glmsg, void *pointersToFixup[]) {
     /* const GLubyte* GLTrace_glGetString(GLenum name) */
     GLMessage_DataType *ret = glmsg->mutable_returnvalue();
-    GLchar *ptr = (GLchar *)ret->intvalue(0);
+    GLchar *ptr = (GLchar *) pointersToFixup[0];
 
     if (ptr != NULL) {
         ret->set_type(GLMessage::DataType::CHAR);
@@ -112,7 +155,7 @@
 }
 
 /** Common fixup routing for glTexImage2D & glTexSubImage2D. */
-void fixup_glTexImage(int widthIndex, int heightIndex, GLMessage *glmsg) {
+void fixup_glTexImage(int widthIndex, int heightIndex, GLMessage *glmsg, void *dataSrc) {
     GLMessage_DataType arg_width  = glmsg->args(widthIndex);
     GLMessage_DataType arg_height = glmsg->args(heightIndex);
 
@@ -124,7 +167,7 @@
     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);
+    void *data     = (void *) dataSrc;
 
     int bytesPerTexel = getBytesPerTexel(format, type);
 
@@ -141,7 +184,7 @@
 }
 
 
-void fixup_glTexImage2D(GLMessage *glmsg) {
+void fixup_glTexImage2D(GLMessage *glmsg, void *pointersToFixup[]) {
     /* void glTexImage2D(GLenum target,
                         GLint level,
                         GLint internalformat,
@@ -154,10 +197,10 @@
     */
     int widthIndex = 3;
     int heightIndex = 4;
-    fixup_glTexImage(widthIndex, heightIndex, glmsg);
+    fixup_glTexImage(widthIndex, heightIndex, glmsg, pointersToFixup[0]);
 }
 
-void fixup_glTexSubImage2D(GLMessage *glmsg) {
+void fixup_glTexSubImage2D(GLMessage *glmsg, void *pointersToFixup[]) {
     /*
     void glTexSubImage2D(GLenum target,
                         GLint level,
@@ -171,10 +214,10 @@
     */
     int widthIndex = 4;
     int heightIndex = 5;
-    fixup_glTexImage(widthIndex, heightIndex, glmsg);
+    fixup_glTexImage(widthIndex, heightIndex, glmsg, pointersToFixup[0]);
 }
 
-void fixup_glShaderSource(GLMessage *glmsg) {
+void fixup_glShaderSource(GLMessage *glmsg, void *pointersToFixup[]) {
     /* void glShaderSource(GLuint shader, GLsizei count, const GLchar** string, 
                                     const GLint* length) */
     GLMessage_DataType arg_count  = glmsg->args(1);
@@ -182,8 +225,8 @@
     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);
+    GLchar **stringpp = (GLchar **) pointersToFixup[0];
+    GLint *lengthp = (GLint *) pointersToFixup[1];
 
     arg_strpp->set_type(GLMessage::DataType::CHAR);
     arg_strpp->set_isarray(true);
@@ -202,87 +245,64 @@
     arg_strpp->add_charvalue(src);
 }
 
-void fixup_glUniformGenericInteger(int argIndex, int nIntegers, GLMessage *glmsg) {
+void fixup_glUniformGenericInteger(int argIndex, int nIntegers, GLMessage *glmsg,
+                                                                    void *pointersToFixup[]) {
     /* void glUniform?iv(GLint location, GLsizei count, const GLint *value); */
-    GLMessage_DataType *arg_values = glmsg->mutable_args(argIndex);
-    GLint *src = (GLint*)arg_values->intvalue(0);
-
-    arg_values->set_type(GLMessage::DataType::INT);
-    arg_values->set_isarray(true);
-    arg_values->clear_intvalue();
-
-    for (int i = 0; i < nIntegers; i++) {
-        arg_values->add_intvalue(*src++);
-    }
+    fixup_GenericIntArray(argIndex, nIntegers, glmsg, pointersToFixup[0]);
 }
 
-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_glUniformGeneric(int argIndex, int nFloats, GLMessage *glmsg, void *src) {
+    fixup_GenericFloatArray(argIndex, nFloats, glmsg, src);
 }
 
-void fixup_glUniformMatrixGeneric(int matrixSize, GLMessage *glmsg) {
+void fixup_glUniformMatrixGeneric(int matrixSize, GLMessage *glmsg, void *pointersToFixup[]) {
     /* 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);
+    fixup_glUniformGeneric(3, matrixSize * matrixSize * n_matrices, glmsg, pointersToFixup[0]);
 }
 
-void fixup_GenericIntArray(int argIndex, int nInts, GLMessage *glmsg) {
-    GLMessage_DataType *arg_intarray = glmsg->mutable_args(argIndex);
-    GLint *intp = (GLint *)arg_intarray->intvalue(0);
+void fixup_glBufferData(int sizeIndex, int dataIndex, GLMessage *glmsg, void *pointersToFixup[]) {
+    /* void glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data) */
+    /* void glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage) */
+    GLsizeiptr size = glmsg->args(sizeIndex).intvalue(0);
 
-    if (intp == NULL) {
+    GLMessage_DataType *arg_datap = glmsg->mutable_args(dataIndex);
+    GLvoid *datap = (GLvoid *) pointersToFixup[0];
+
+    if (datap == NULL) {
+        // glBufferData can be called with a NULL data pointer
         return;
     }
 
-    arg_intarray->set_type(GLMessage::DataType::INT);
-    arg_intarray->set_isarray(true);
-    arg_intarray->clear_intvalue();
+    arg_datap->set_type(GLMessage::DataType::VOID);
+    arg_datap->set_isarray(true);
+    arg_datap->clear_intvalue();
 
-    for (int i = 0; i < nInts; i++, intp++) {
-        arg_intarray->add_intvalue(*intp);
-    }
+    arg_datap->add_rawbytes(datap, size);
 }
 
-void fixup_GenericEnumArray(int argIndex, int nEnums, GLMessage *glmsg) {
-    // fixup as if they were ints
-    fixup_GenericIntArray(argIndex, nEnums, glmsg);
-
-    // and then set the data type to be enum
-    GLMessage_DataType *arg_enumarray = glmsg->mutable_args(argIndex);
-    arg_enumarray->set_type(GLMessage::DataType::ENUM);
-}
-
-void fixup_glGenGeneric(GLMessage *glmsg) {
+void fixup_glGenGeneric(GLMessage *glmsg, void *pointersToFixup[]) {
     /* void glGen*(GLsizei n, GLuint * buffers); */
     GLMessage_DataType arg_n  = glmsg->args(0);
     GLsizei n = arg_n.intvalue(0);
 
-    fixup_GenericIntArray(1, n, glmsg);
+    fixup_GenericIntArray(1, n, glmsg, pointersToFixup[0]);
 }
 
-void fixup_glDeleteGeneric(GLMessage *glmsg) {
+void fixup_glDeleteGeneric(GLMessage *glmsg, void *pointersToFixup[]) {
     /* void glDelete*(GLsizei n, GLuint *buffers); */
     GLMessage_DataType arg_n  = glmsg->args(0);
     GLsizei n = arg_n.intvalue(0);
 
-    fixup_GenericIntArray(1, n, glmsg);
+    fixup_GenericIntArray(1, n, glmsg, pointersToFixup[0]);
 }
 
-void fixup_glGetBooleanv(GLMessage *glmsg) {
+void fixup_glGetBooleanv(GLMessage *glmsg, void *pointersToFixup[]) {
     /* void glGetBooleanv(GLenum pname, GLboolean *params); */
     GLMessage_DataType *arg_params = glmsg->mutable_args(1);
-    GLboolean *src = (GLboolean*)arg_params->intvalue(0);
+    GLboolean *src = (GLboolean*) pointersToFixup[0];
 
     arg_params->set_type(GLMessage::DataType::BOOL);
     arg_params->set_isarray(true);
@@ -290,10 +310,10 @@
     arg_params->add_boolvalue(*src);
 }
 
-void fixup_glGetFloatv(GLMessage *glmsg) {
+void fixup_glGetFloatv(GLMessage *glmsg, void *pointersToFixup[]) {
     /* void glGetFloatv(GLenum pname, GLfloat *params); */
     GLMessage_DataType *arg_params = glmsg->mutable_args(1);
-    GLfloat *src = (GLfloat*)arg_params->intvalue(0);
+    GLfloat *src = (GLfloat*) pointersToFixup[0];
 
     arg_params->set_type(GLMessage::DataType::FLOAT);
     arg_params->set_isarray(true);
@@ -338,16 +358,15 @@
 }
 
 /** Given a glGetActive[Uniform|Attrib] call, obtain the location
- *  of the variable in the call.
+ *  of the variable of given name in the call.
  */
-int getShaderVariableLocation(GLTraceContext *context, GLMessage *glmsg) {
+int getShaderVariableLocation(GLTraceContext *context, GLMessage *glmsg, GLchar *name) {
     GLMessage_Function func = glmsg->function();
     if (func != GLMessage::glGetActiveAttrib && func != GLMessage::glGetActiveUniform) {
         return -1;
     }
 
     int program = glmsg->args(0).intvalue(0);
-    GLchar *name = (GLchar*) glmsg->args(6).intvalue(0);
 
     if (func == GLMessage::glGetActiveAttrib) {
         return context->hooks->gl.glGetAttribLocation(program, name);
@@ -356,16 +375,17 @@
     }
 }
 
-void fixup_glGetActiveAttribOrUniform(GLMessage *glmsg, int location) {
+void fixup_glGetActiveAttribOrUniform(GLTraceContext *context, GLMessage *glmsg, 
+                                                                void *pointersToFixup[]) {
     /* void glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize,
                 GLsizei* length, GLint* size, GLenum* type, GLchar* name); */
     /* void glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize,
                 GLsizei* length, GLint* size, GLenum* type, GLchar* name) */
 
-    fixup_GenericIntArray(3, 1, glmsg);     // length
-    fixup_GenericIntArray(4, 1, glmsg);     // size
-    fixup_GenericEnumArray(5, 1, glmsg);    // type
-    fixup_CStringPtr(6, glmsg);             // name
+    fixup_GenericIntArray(3, 1, glmsg, pointersToFixup[0]);     // length
+    fixup_GenericIntArray(4, 1, glmsg, pointersToFixup[1]);     // size
+    fixup_GenericEnumArray(5, 1, glmsg, pointersToFixup[2]);    // type
+    fixup_CStringPtr(6, glmsg, pointersToFixup[3]);             // name
 
     // The index argument in the glGetActive[Attrib|Uniform] functions
     // does not correspond to the actual location index as used in
@@ -373,6 +393,7 @@
     // In order to make things simpler for the debugger, we also pass
     // a hidden location argument that stores the actual location.
     // append the location value to the end of the argument list
+    int location = getShaderVariableLocation(context, glmsg, (GLchar*)pointersToFixup[3]);
     GLMessage_DataType *arg_location = glmsg->add_args();
     arg_location->set_isarray(false);
     arg_location->set_type(GLMessage::DataType::INT);
@@ -381,7 +402,7 @@
 
 void fixupGLMessage(GLTraceContext *context, nsecs_t wallStart, nsecs_t wallEnd,
                                              nsecs_t threadStart, nsecs_t threadEnd,
-                                             GLMessage *glmsg) {
+                                             GLMessage *glmsg, void *pointersToFixup[]) {
     // for all messages, set the current context id
     glmsg->set_context_id(context->getId());
 
@@ -396,41 +417,41 @@
     case GLMessage::glDeleteFramebuffers: /* glDeleteFramebuffers(GLsizei n, GLuint *buffers); */
     case GLMessage::glDeleteRenderbuffers:/* glDeleteRenderbuffers(GLsizei n, GLuint *buffers); */
     case GLMessage::glDeleteTextures:     /* glDeleteTextures(GLsizei n, GLuint *textures); */
-        fixup_glDeleteGeneric(glmsg);
+        fixup_glDeleteGeneric(glmsg, pointersToFixup);
         break;
     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 *textures); */
-        fixup_glGenGeneric(glmsg);
+        fixup_glGenGeneric(glmsg, pointersToFixup);
         break;
     case GLMessage::glLinkProgram:       /* void glLinkProgram(GLuint program); */
         fixup_glLinkProgram(glmsg);
         break;
     case GLMessage::glGetActiveAttrib:
-        fixup_glGetActiveAttribOrUniform(glmsg, getShaderVariableLocation(context, glmsg));
+        fixup_glGetActiveAttribOrUniform(context, glmsg, pointersToFixup);
         break;
     case GLMessage::glGetActiveUniform:
-        fixup_glGetActiveAttribOrUniform(glmsg, getShaderVariableLocation(context, glmsg));
+        fixup_glGetActiveAttribOrUniform(context, glmsg, pointersToFixup);
         break;
     case GLMessage::glBindAttribLocation:
         /* void glBindAttribLocation(GLuint program, GLuint index, const GLchar* name); */
-        fixup_CStringPtr(2, glmsg);
+        fixup_CStringPtr(2, glmsg, pointersToFixup[0]);
         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);
+        fixup_CStringPtr(1, glmsg, pointersToFixup[0]);
         break;
     case GLMessage::glGetBooleanv:
-        fixup_glGetBooleanv(glmsg);
+        fixup_glGetBooleanv(glmsg, pointersToFixup);
         break;
     case GLMessage::glGetFloatv:
-        fixup_glGetFloatv(glmsg);
+        fixup_glGetFloatv(glmsg, pointersToFixup);
         break;
     case GLMessage::glGetIntegerv:        /* void glGetIntegerv(GLenum pname, GLint *params); */
-        fixup_GenericIntArray(1, 1, glmsg);
+        fixup_GenericIntArray(1, 1, glmsg, pointersToFixup[0]);
         break;
     case GLMessage::glGetProgramiv:
     case GLMessage::glGetRenderbufferParameteriv:
@@ -438,70 +459,78 @@
         /* 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);
+        fixup_GenericIntArray(2, 1, glmsg, pointersToFixup[0]);
         break;
     case GLMessage::glGetString:
-        fixup_glGetString(glmsg);
+        fixup_glGetString(glmsg, pointersToFixup);
         break;
     case GLMessage::glTexImage2D:
         if (context->getGlobalTraceState()->shouldCollectTextureDataOnGlTexImage()) {
-            fixup_glTexImage2D(glmsg);
+            fixup_glTexImage2D(glmsg, pointersToFixup);
         }
         break;
     case GLMessage::glTexSubImage2D:
         if (context->getGlobalTraceState()->shouldCollectTextureDataOnGlTexImage()) {
-            fixup_glTexSubImage2D(glmsg);
+            fixup_glTexSubImage2D(glmsg, pointersToFixup);
         }
         break;
     case GLMessage::glShaderSource:
-        fixup_glShaderSource(glmsg);
+        fixup_glShaderSource(glmsg, pointersToFixup);
         break;
     case GLMessage::glUniform1iv:
         /* void glUniform1iv(GLint location, GLsizei count, const GLint *value); */
-        fixup_glUniformGenericInteger(2, 1, glmsg);
+        fixup_glUniformGenericInteger(2, 1, glmsg, pointersToFixup);
         break;
     case GLMessage::glUniform2iv:
         /* void glUniform2iv(GLint location, GLsizei count, const GLint *value); */
-        fixup_glUniformGenericInteger(2, 2, glmsg);
+        fixup_glUniformGenericInteger(2, 2, glmsg, pointersToFixup);
         break;
     case GLMessage::glUniform3iv:
         /* void glUniform3iv(GLint location, GLsizei count, const GLint *value); */
-        fixup_glUniformGenericInteger(2, 3, glmsg);
+        fixup_glUniformGenericInteger(2, 3, glmsg, pointersToFixup);
         break;
     case GLMessage::glUniform4iv:
         /* void glUniform4iv(GLint location, GLsizei count, const GLint *value); */
-        fixup_glUniformGenericInteger(2, 4, glmsg);
+        fixup_glUniformGenericInteger(2, 4, glmsg, pointersToFixup);
         break;
     case GLMessage::glUniform1fv:
         /* void glUniform1fv(GLint location, GLsizei count, const GLfloat *value); */
-        fixup_glUniformGeneric(2, 1, glmsg);
+        fixup_glUniformGeneric(2, 1, glmsg, pointersToFixup[0]);
         break;
     case GLMessage::glUniform2fv:
         /* void glUniform2fv(GLint location, GLsizei count, const GLfloat *value); */
-        fixup_glUniformGeneric(2, 2, glmsg);
+        fixup_glUniformGeneric(2, 2, glmsg, pointersToFixup[0]);
         break;
     case GLMessage::glUniform3fv:
         /* void glUniform3fv(GLint location, GLsizei count, const GLfloat *value); */
-        fixup_glUniformGeneric(2, 3, glmsg);
+        fixup_glUniformGeneric(2, 3, glmsg, pointersToFixup[0]);
         break;
     case GLMessage::glUniform4fv:
         /* void glUniform4fv(GLint location, GLsizei count, const GLfloat *value); */
-        fixup_glUniformGeneric(2, 4, glmsg);
+        fixup_glUniformGeneric(2, 4, glmsg, pointersToFixup[0]);
         break;
     case GLMessage::glUniformMatrix2fv:
         /* void glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose,
                                                                     const GLfloat* value) */
-        fixup_glUniformMatrixGeneric(2, glmsg);
+        fixup_glUniformMatrixGeneric(2, glmsg, pointersToFixup);
         break;
     case GLMessage::glUniformMatrix3fv:
         /* void glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose,
                                                                     const GLfloat* value) */
-        fixup_glUniformMatrixGeneric(3, glmsg);
+        fixup_glUniformMatrixGeneric(3, glmsg, pointersToFixup);
         break;
     case GLMessage::glUniformMatrix4fv:
         /* void glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose,
                                                                     const GLfloat* value) */
-        fixup_glUniformMatrixGeneric(4, glmsg);
+        fixup_glUniformMatrixGeneric(4, glmsg, pointersToFixup);
+        break;
+    case GLMessage::glBufferData:
+        /* void glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage) */
+        fixup_glBufferData(1, 2, glmsg, pointersToFixup);
+        break;
+    case GLMessage::glBufferSubData:
+        /* void glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data) */
+        fixup_glBufferData(2, 3, glmsg, pointersToFixup);
         break;
     case GLMessage::glDrawArrays:
         /* void glDrawArrays(GLenum mode, GLint first, GLsizei count) */
@@ -517,11 +546,11 @@
         break;
     case GLMessage::glPushGroupMarkerEXT:
         /* void PushGroupMarkerEXT(sizei length, const char *marker); */
-        fixup_CStringPtr(1, glmsg);
+        fixup_CStringPtr(1, glmsg, pointersToFixup[0]);
         break;
     case GLMessage::glInsertEventMarkerEXT:
         /* void InsertEventMarkerEXT(sizei length, const char *marker); */
-        fixup_CStringPtr(1, glmsg);
+        fixup_CStringPtr(1, glmsg, pointersToFixup[0]);
         break;
     default:
         break;
diff --git a/opengl/libs/GLES_trace/src/gltrace_fixup.h b/opengl/libs/GLES_trace/src/gltrace_fixup.h
index f63b056..fe30125 100644
--- a/opengl/libs/GLES_trace/src/gltrace_fixup.h
+++ b/opengl/libs/GLES_trace/src/gltrace_fixup.h
@@ -27,7 +27,7 @@
 
 void fixupGLMessage(GLTraceContext *curContext, nsecs_t wallStart, nsecs_t wallEnd,
                                                 nsecs_t threadStart, nsecs_t threadEnd,
-                                                GLMessage *message);
+                                                GLMessage *message, void *pointersToFixup[]);
 void fixup_addFBContents(GLTraceContext *curContext, GLMessage *message, FBBinding fbToRead);
 
 };
diff --git a/opengl/libs/GLES_trace/tools/genapi.py b/opengl/libs/GLES_trace/tools/genapi.py
index e1660be..24034c1 100755
--- a/opengl/libs/GLES_trace/tools/genapi.py
+++ b/opengl/libs/GLES_trace/tools/genapi.py
@@ -92,8 +92,8 @@
     "GLclampf":DataType.FLOAT,
     "GLfixed":DataType.INT,
     "GLclampx":DataType.INT,
-    "GLsizeiptr":DataType.POINTER,
-    "GLintptr":DataType.POINTER,
+    "GLsizeiptr":DataType.INT,
+    "GLintptr":DataType.INT,
     "GLeglImageOES":DataType.POINTER,
 }
 
@@ -180,9 +180,20 @@
     rt->$!retDataType.getProtobufCall()!$retValue);
 <!--(end)-->
 
+    void *pointerArgs[] = {
+<!--(for argname, argtype in parsedArgs)-->
+    <!--(if argtype == DataType.POINTER)-->
+        (void *) $!argname!$,
+    <!--(end)-->
+<!--(end)-->
+<!--(if retDataType == DataType.POINTER)-->
+        (void *) retValue,
+<!--(end)-->
+    };
+
     fixupGLMessage(glContext, wallStartTime, wallEndTime,
                               threadStartTime, threadEndTime,
-                              &glmsg);
+                              &glmsg, pointerArgs);
     glContext->traceGLMessage(&glmsg);
 <!--(if retType != "void")-->
 
diff --git a/opengl/tests/angeles/Android.mk b/opengl/tests/angeles/Android.mk
index d0c3221..84b754b 100644
--- a/opengl/tests/angeles/Android.mk
+++ b/opengl/tests/angeles/Android.mk
@@ -4,14 +4,7 @@
 include $(CLEAR_VARS)
 LOCAL_SRC_FILES:= app-linux.cpp demo.c.arm
 LOCAL_SHARED_LIBRARIES := libEGL libGLESv1_CM libui
+LOCAL_C_INCLUDES += frameworks/base/opengl/tests/include
 LOCAL_MODULE:= angeles
 LOCAL_MODULE_TAGS := optional
 include $(BUILD_EXECUTABLE)
-
-
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES:= gpustate.c
-LOCAL_SHARED_LIBRARIES := libEGL libGLESv1_CM
-LOCAL_MODULE:= gpustate
-LOCAL_MODULE_TAGS := optional
-include $(BUILD_EXECUTABLE)
diff --git a/opengl/tests/angeles/app-linux.cpp b/opengl/tests/angeles/app-linux.cpp
index 4d10ee5..6ac68a2 100644
--- a/opengl/tests/angeles/app-linux.cpp
+++ b/opengl/tests/angeles/app-linux.cpp
@@ -53,7 +53,7 @@
 #include <GLES/gl.h>
 
 #include <ui/FramebufferNativeWindow.h>
-#include <ui/EGLUtils.h>
+#include "EGLUtils.h"
 
 using namespace android;
 
diff --git a/opengl/tests/angeles/gpustate.c b/opengl/tests/angeles/gpustate.c
deleted file mode 100644
index 3c540c9..0000000
--- a/opengl/tests/angeles/gpustate.c
+++ /dev/null
@@ -1,39 +0,0 @@
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/mman.h>
-#include <unistd.h>
-#include <fcntl.h>
-
-static void *map_memory(const char *fn, unsigned base, unsigned size)
-{
-    int fd;
-    void *ptr;
-    
-    fd = open(fn, O_RDWR | O_SYNC);
-    if(fd < 0) {
-        perror("cannot open %s for mapping");
-        return MAP_FAILED;
-    }
-
-    ptr = mmap(0, size, PROT_READ | PROT_WRITE,
-               MAP_SHARED, fd, base);
-    close(fd);
-    
-    if(ptr == MAP_FAILED) {
-        fprintf(stderr,"cannot map %s (@%08x,%08x)\n", fn, base, size);
-    }
-    return ptr;    
-}
-
-
-int main(int argc, char** argv)
-{
-    void *grp_regs = map_memory("/dev/hw3d", 0, 1024 * 1024);
-    printf("GPU base mapped at %p\n", grp_regs);
-    int state_offset = 0x10140;
-    printf("GPU state = %08lx\n",
-            *((long*)((char*)grp_regs + state_offset))  );
-
-    return 0;
-}
diff --git a/opengl/tests/fillrate/Android.mk b/opengl/tests/fillrate/Android.mk
index 191c59b..835f858 100644
--- a/opengl/tests/fillrate/Android.mk
+++ b/opengl/tests/fillrate/Android.mk
@@ -11,6 +11,8 @@
     libGLESv1_CM \
     libui
 
+LOCAL_C_INCLUDES += frameworks/base/opengl/tests/include
+
 LOCAL_MODULE:= test-opengl-fillrate
 
 LOCAL_MODULE_TAGS := optional
diff --git a/opengl/tests/fillrate/fillrate.cpp b/opengl/tests/fillrate/fillrate.cpp
index 911d354..a708647 100644
--- a/opengl/tests/fillrate/fillrate.cpp
+++ b/opengl/tests/fillrate/fillrate.cpp
@@ -26,7 +26,7 @@
 
 #include <utils/StopWatch.h>
 #include <ui/FramebufferNativeWindow.h>
-#include <ui/EGLUtils.h>
+#include "EGLUtils.h"
 
 using namespace android;
 
diff --git a/opengl/tests/filter/Android.mk b/opengl/tests/filter/Android.mk
index a254127..d780362 100644
--- a/opengl/tests/filter/Android.mk
+++ b/opengl/tests/filter/Android.mk
@@ -10,6 +10,8 @@
     libGLESv1_CM \
     libui
 
+LOCAL_C_INCLUDES += frameworks/base/opengl/tests/include
+
 LOCAL_MODULE:= test-opengl-filter
 
 LOCAL_MODULE_TAGS := optional
diff --git a/opengl/tests/filter/filter.cpp b/opengl/tests/filter/filter.cpp
index 2351909..0067327 100644
--- a/opengl/tests/filter/filter.cpp
+++ b/opengl/tests/filter/filter.cpp
@@ -6,7 +6,7 @@
 #include <GLES/glext.h>
 
 #include <ui/FramebufferNativeWindow.h>
-#include <ui/EGLUtils.h>
+#include "EGLUtils.h"
 
 using namespace android;
 
diff --git a/opengl/tests/finish/Android.mk b/opengl/tests/finish/Android.mk
index aa607c6..8f4f9c3 100644
--- a/opengl/tests/finish/Android.mk
+++ b/opengl/tests/finish/Android.mk
@@ -11,6 +11,8 @@
     libGLESv1_CM \
     libui
 
+LOCAL_C_INCLUDES += frameworks/base/opengl/tests/include
+
 LOCAL_MODULE:= test-opengl-finish
 
 LOCAL_MODULE_TAGS := optional
diff --git a/opengl/tests/finish/finish.cpp b/opengl/tests/finish/finish.cpp
index 91f5c45..11f0c22 100644
--- a/opengl/tests/finish/finish.cpp
+++ b/opengl/tests/finish/finish.cpp
@@ -27,7 +27,7 @@
 #include <utils/Timers.h>
 
 #include <ui/FramebufferNativeWindow.h>
-#include <ui/EGLUtils.h>
+#include "EGLUtils.h"
 
 using namespace android;
 
diff --git a/opengl/tests/gl2_basic/Android.mk b/opengl/tests/gl2_basic/Android.mk
index a642eaf..07469a0 100644
--- a/opengl/tests/gl2_basic/Android.mk
+++ b/opengl/tests/gl2_basic/Android.mk
@@ -10,6 +10,8 @@
     libGLESv2 \
     libui
 
+LOCAL_C_INCLUDES += frameworks/base/opengl/tests/include
+
 LOCAL_MODULE:= test-opengl-gl2_basic
 
 LOCAL_MODULE_TAGS := optional
diff --git a/opengl/tests/gl2_basic/gl2_basic.cpp b/opengl/tests/gl2_basic/gl2_basic.cpp
index f274c7c..7007871 100644
--- a/opengl/tests/gl2_basic/gl2_basic.cpp
+++ b/opengl/tests/gl2_basic/gl2_basic.cpp
@@ -27,7 +27,7 @@
 #include <utils/Timers.h>
 
 #include <ui/FramebufferNativeWindow.h>
-#include <ui/EGLUtils.h>
+#include "EGLUtils.h"
 
 using namespace android;
 
diff --git a/opengl/tests/gl2_copyTexImage/Android.mk b/opengl/tests/gl2_copyTexImage/Android.mk
index bef1f90..b616428 100644
--- a/opengl/tests/gl2_copyTexImage/Android.mk
+++ b/opengl/tests/gl2_copyTexImage/Android.mk
@@ -10,6 +10,8 @@
     libGLESv2 \
     libui
 
+LOCAL_C_INCLUDES += frameworks/base/opengl/tests/include
+
 LOCAL_MODULE:= test-opengl-gl2_copyTexImage
 
 LOCAL_MODULE_TAGS := optional
diff --git a/opengl/tests/gl2_copyTexImage/gl2_copyTexImage.cpp b/opengl/tests/gl2_copyTexImage/gl2_copyTexImage.cpp
index c2bfdec..988d7ac 100644
--- a/opengl/tests/gl2_copyTexImage/gl2_copyTexImage.cpp
+++ b/opengl/tests/gl2_copyTexImage/gl2_copyTexImage.cpp
@@ -27,7 +27,7 @@
 #include <utils/Timers.h>
 
 #include <ui/FramebufferNativeWindow.h>
-#include <ui/EGLUtils.h>
+#include "EGLUtils.h"
 
 using namespace android;
 
diff --git a/opengl/tests/gl2_yuvtex/Android.mk b/opengl/tests/gl2_yuvtex/Android.mk
index 6304700..e36f319 100644
--- a/opengl/tests/gl2_yuvtex/Android.mk
+++ b/opengl/tests/gl2_yuvtex/Android.mk
@@ -10,6 +10,8 @@
     libGLESv2 \
     libui
 
+LOCAL_C_INCLUDES += frameworks/base/opengl/tests/include
+
 LOCAL_MODULE:= test-opengl-gl2_yuvtex
 
 LOCAL_MODULE_TAGS := optional
diff --git a/opengl/tests/gl2_yuvtex/gl2_yuvtex.cpp b/opengl/tests/gl2_yuvtex/gl2_yuvtex.cpp
index f0b8d12..d3e4932 100644
--- a/opengl/tests/gl2_yuvtex/gl2_yuvtex.cpp
+++ b/opengl/tests/gl2_yuvtex/gl2_yuvtex.cpp
@@ -29,7 +29,7 @@
 
 #include <ui/FramebufferNativeWindow.h>
 #include <ui/GraphicBuffer.h>
-#include <ui/EGLUtils.h>
+#include "EGLUtils.h"
 
 using namespace android;
 
diff --git a/opengl/tests/gl_basic/Android.mk b/opengl/tests/gl_basic/Android.mk
index 6b6341f..2ba327b 100644
--- a/opengl/tests/gl_basic/Android.mk
+++ b/opengl/tests/gl_basic/Android.mk
@@ -10,6 +10,8 @@
     libGLESv1_CM \
     libui
 
+LOCAL_C_INCLUDES += frameworks/base/opengl/tests/include
+
 LOCAL_MODULE:= test-opengl-gl_basic
 
 LOCAL_MODULE_TAGS := optional
diff --git a/opengl/tests/gl_basic/gl_basic.cpp b/opengl/tests/gl_basic/gl_basic.cpp
index 0cc8398..23ce934 100644
--- a/opengl/tests/gl_basic/gl_basic.cpp
+++ b/opengl/tests/gl_basic/gl_basic.cpp
@@ -6,7 +6,7 @@
 #include <GLES/glext.h>
 
 #include <ui/FramebufferNativeWindow.h>
-#include <ui/EGLUtils.h>
+#include "EGLUtils.h"
 
 #include <stdio.h>
 
diff --git a/opengl/tests/gl_perf/Android.mk b/opengl/tests/gl_perf/Android.mk
index 37647ca..f32abd3 100644
--- a/opengl/tests/gl_perf/Android.mk
+++ b/opengl/tests/gl_perf/Android.mk
@@ -11,6 +11,8 @@
     libGLESv2 \
     libui
 
+LOCAL_C_INCLUDES += frameworks/base/opengl/tests/include
+
 LOCAL_MODULE:= test-opengl-gl2_perf
 
 LOCAL_MODULE_TAGS := optional
diff --git a/opengl/tests/gl_perf/gl2_perf.cpp b/opengl/tests/gl_perf/gl2_perf.cpp
index 9dfcf1c..224acaf 100644
--- a/opengl/tests/gl_perf/gl2_perf.cpp
+++ b/opengl/tests/gl_perf/gl2_perf.cpp
@@ -27,7 +27,7 @@
 #include <utils/Timers.h>
 
 #include <ui/FramebufferNativeWindow.h>
-#include <ui/EGLUtils.h>
+#include "EGLUtils.h"
 
 using namespace android;
 
diff --git a/opengl/tests/gl_yuvtex/Android.mk b/opengl/tests/gl_yuvtex/Android.mk
index a78db25..5b87f2e 100644
--- a/opengl/tests/gl_yuvtex/Android.mk
+++ b/opengl/tests/gl_yuvtex/Android.mk
@@ -10,6 +10,8 @@
     libGLESv1_CM \
     libui
 
+LOCAL_C_INCLUDES += frameworks/base/opengl/tests/include
+
 LOCAL_MODULE:= test-opengl-gl_yuvtex
 
 LOCAL_MODULE_TAGS := optional
diff --git a/opengl/tests/gl_yuvtex/gl_yuvtex.cpp b/opengl/tests/gl_yuvtex/gl_yuvtex.cpp
index fbe65f12..7a00f76 100644
--- a/opengl/tests/gl_yuvtex/gl_yuvtex.cpp
+++ b/opengl/tests/gl_yuvtex/gl_yuvtex.cpp
@@ -29,7 +29,7 @@
 
 #include <ui/FramebufferNativeWindow.h>
 #include <ui/GraphicBuffer.h>
-#include <ui/EGLUtils.h>
+#include "EGLUtils.h"
 
 using namespace android;
 
diff --git a/opengl/tests/hwc/hwcColorEquiv.cpp b/opengl/tests/hwc/hwcColorEquiv.cpp
index 1d03948..bb305dc 100644
--- a/opengl/tests/hwc/hwcColorEquiv.cpp
+++ b/opengl/tests/hwc/hwcColorEquiv.cpp
@@ -87,7 +87,6 @@
 
 #include <ui/FramebufferNativeWindow.h>
 #include <ui/GraphicBuffer.h>
-#include <ui/EGLUtils.h>
 
 #define LOG_TAG "hwcColorEquivTest"
 #include <utils/Log.h>
diff --git a/opengl/tests/hwc/hwcCommit.cpp b/opengl/tests/hwc/hwcCommit.cpp
index 66ccdae..685dc5d 100644
--- a/opengl/tests/hwc/hwcCommit.cpp
+++ b/opengl/tests/hwc/hwcCommit.cpp
@@ -98,7 +98,6 @@
 
 #include <ui/FramebufferNativeWindow.h>
 #include <ui/GraphicBuffer.h>
-#include <ui/EGLUtils.h>
 
 #define LOG_TAG "hwcCommitTest"
 #include <utils/Log.h>
diff --git a/opengl/tests/hwc/hwcRects.cpp b/opengl/tests/hwc/hwcRects.cpp
index 523e3de..80cde23 100644
--- a/opengl/tests/hwc/hwcRects.cpp
+++ b/opengl/tests/hwc/hwcRects.cpp
@@ -106,7 +106,6 @@
 
 #include <ui/FramebufferNativeWindow.h>
 #include <ui/GraphicBuffer.h>
-#include <ui/EGLUtils.h>
 
 #define LOG_TAG "hwcRectsTest"
 #include <utils/Log.h>
diff --git a/opengl/tests/hwc/hwcStress.cpp b/opengl/tests/hwc/hwcStress.cpp
index 1cefb4b..7d7bc1f 100644
--- a/opengl/tests/hwc/hwcStress.cpp
+++ b/opengl/tests/hwc/hwcStress.cpp
@@ -103,7 +103,6 @@
 
 #include <ui/FramebufferNativeWindow.h>
 #include <ui/GraphicBuffer.h>
-#include <ui/EGLUtils.h>
 
 #define LOG_TAG "hwcStressTest"
 #include <utils/Log.h>
diff --git a/opengl/tests/hwc/hwcTestLib.cpp b/opengl/tests/hwc/hwcTestLib.cpp
index 925405e..63f42ba 100644
--- a/opengl/tests/hwc/hwcTestLib.cpp
+++ b/opengl/tests/hwc/hwcTestLib.cpp
@@ -27,6 +27,8 @@
 
 #include <hwc/hwcTestLib.h>
 
+#include "EGLUtils.h"
+
 // Defines
 #define NUMA(a) (sizeof(a) / sizeof(a [0]))
 
diff --git a/opengl/tests/hwc/hwcTestLib.h b/opengl/tests/hwc/hwcTestLib.h
index 99ee608..b0c3012 100644
--- a/opengl/tests/hwc/hwcTestLib.h
+++ b/opengl/tests/hwc/hwcTestLib.h
@@ -29,7 +29,6 @@
 
 #include <ui/FramebufferNativeWindow.h>
 #include <ui/GraphicBuffer.h>
-#include <ui/EGLUtils.h>
 
 #include <utils/Log.h>
 #include <testUtil.h>
diff --git a/libs/ui/EGLUtils.cpp b/opengl/tests/include/EGLUtils.h
similarity index 82%
rename from libs/ui/EGLUtils.cpp
rename to opengl/tests/include/EGLUtils.h
index f24a71d..014c261 100644
--- a/libs/ui/EGLUtils.cpp
+++ b/opengl/tests/include/EGLUtils.h
@@ -15,21 +15,42 @@
  */
 
 
-#define LOG_TAG "EGLUtils"
+#ifndef ANDROID_UI_EGLUTILS_H
+#define ANDROID_UI_EGLUTILS_H
 
-#include <cutils/log.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+#include <system/window.h>
 #include <utils/Errors.h>
-
-#include <ui/EGLUtils.h>
-
 #include <EGL/egl.h>
 
-#include <private/ui/android_natives_priv.h>
 
 // ----------------------------------------------------------------------------
 namespace android {
 // ----------------------------------------------------------------------------
 
+class EGLUtils
+{
+public:
+
+    static inline const char *strerror(EGLint err);
+
+    static inline status_t selectConfigForPixelFormat(
+            EGLDisplay dpy,
+            EGLint const* attrs,
+            int32_t format,
+            EGLConfig* outConfig);
+
+    static inline status_t selectConfigForNativeWindow(
+            EGLDisplay dpy,
+            EGLint const* attrs,
+            EGLNativeWindowType window,
+            EGLConfig* outConfig);
+};
+
+// ----------------------------------------------------------------------------
+
 const char *EGLUtils::strerror(EGLint err)
 {
     switch (err){
@@ -55,7 +76,7 @@
 status_t EGLUtils::selectConfigForPixelFormat(
         EGLDisplay dpy,
         EGLint const* attrs,
-        PixelFormat format,
+        int32_t format,
         EGLConfig* outConfig)
 {
     EGLint numConfigs = -1, n=0;
@@ -65,7 +86,7 @@
 
     if (outConfig == NULL)
         return BAD_VALUE;
-    
+
     // Get all the "potential match" configs...
     if (eglGetConfigs(dpy, NULL, 0, &numConfigs) == EGL_FALSE)
         return BAD_VALUE;
@@ -75,7 +96,7 @@
         free(configs);
         return BAD_VALUE;
     }
-    
+
     int i;
     EGLConfig config = NULL;
     for (i=0 ; i<n ; i++) {
@@ -88,7 +109,7 @@
     }
 
     free(configs);
-    
+
     if (i<n) {
         *outConfig = config;
         return NO_ERROR;
@@ -105,10 +126,10 @@
 {
     int err;
     int format;
-    
+
     if (!window)
         return BAD_VALUE;
-    
+
     if ((err = window->query(window, NATIVE_WINDOW_FORMAT, &format)) < 0) {
         return err;
     }
@@ -119,3 +140,5 @@
 // ----------------------------------------------------------------------------
 }; // namespace android
 // ----------------------------------------------------------------------------
+
+#endif /* ANDROID_UI_EGLUTILS_H */
diff --git a/opengl/tests/include/glTestLib.h b/opengl/tests/include/glTestLib.h
index 06fbf5d..c91c594 100644
--- a/opengl/tests/include/glTestLib.h
+++ b/opengl/tests/include/glTestLib.h
@@ -24,9 +24,7 @@
 #include <GLES2/gl2.h>
 #include <GLES2/gl2ext.h>
 
-//#include <ui/FramebufferNativeWindow.h>
-//#include <ui/GraphicBuffer.h>
-#include <ui/EGLUtils.h>
+#include "EGLUtils.h"
 
 void glTestPrintGLString(const char *name, GLenum s);
 void glTestCheckEglError(const char* op, EGLBoolean returnVal = EGL_TRUE);
diff --git a/opengl/tests/lib/glTestLib.cpp b/opengl/tests/lib/glTestLib.cpp
index 052cbd7..b434fc7 100644
--- a/opengl/tests/lib/glTestLib.cpp
+++ b/opengl/tests/lib/glTestLib.cpp
@@ -26,7 +26,7 @@
 #include <GLES2/gl2.h>
 #include <GLES2/gl2ext.h>
 
-#include <ui/EGLUtils.h>
+#include "EGLUtils.h"
 
 #include <utils/Log.h>
 #include <testUtil.h>
diff --git a/opengl/tests/linetex/Android.mk b/opengl/tests/linetex/Android.mk
index 6ff248d..261940e 100644
--- a/opengl/tests/linetex/Android.mk
+++ b/opengl/tests/linetex/Android.mk
@@ -10,6 +10,8 @@
     libGLESv1_CM \
     libui
 
+LOCAL_C_INCLUDES += frameworks/base/opengl/tests/include
+
 LOCAL_MODULE:= test-opengl-linetex
 
 LOCAL_MODULE_TAGS := optional
diff --git a/opengl/tests/linetex/linetex.cpp b/opengl/tests/linetex/linetex.cpp
index 6842940..8669492 100644
--- a/opengl/tests/linetex/linetex.cpp
+++ b/opengl/tests/linetex/linetex.cpp
@@ -27,7 +27,7 @@
 
 #include <utils/StopWatch.h>
 #include <ui/FramebufferNativeWindow.h>
-#include <ui/EGLUtils.h>
+#include "EGLUtils.h"
 
 using namespace android;
 
diff --git a/opengl/tests/swapinterval/Android.mk b/opengl/tests/swapinterval/Android.mk
index 9a4145e..d014cc9 100644
--- a/opengl/tests/swapinterval/Android.mk
+++ b/opengl/tests/swapinterval/Android.mk
@@ -11,6 +11,8 @@
     libGLESv1_CM \
     libui
 
+LOCAL_C_INCLUDES += frameworks/base/opengl/tests/include
+
 LOCAL_MODULE:= test-opengl-swapinterval
 
 LOCAL_MODULE_TAGS := optional
diff --git a/opengl/tests/swapinterval/swapinterval.cpp b/opengl/tests/swapinterval/swapinterval.cpp
index 8ca031b..a0f4bc4 100644
--- a/opengl/tests/swapinterval/swapinterval.cpp
+++ b/opengl/tests/swapinterval/swapinterval.cpp
@@ -24,7 +24,7 @@
 
 #include <utils/StopWatch.h>
 #include <ui/FramebufferNativeWindow.h>
-#include <ui/EGLUtils.h>
+#include "EGLUtils.h"
 
 using namespace android;
 
diff --git a/opengl/tests/textures/Android.mk b/opengl/tests/textures/Android.mk
index b2fa185..fe9f43c 100644
--- a/opengl/tests/textures/Android.mk
+++ b/opengl/tests/textures/Android.mk
@@ -10,6 +10,8 @@
     libGLESv1_CM \
     libui
 
+LOCAL_C_INCLUDES += frameworks/base/opengl/tests/include
+
 LOCAL_MODULE:= test-opengl-textures
 
 LOCAL_MODULE_TAGS := optional
diff --git a/opengl/tests/textures/textures.cpp b/opengl/tests/textures/textures.cpp
index cbe8ffd..5d3d94e 100644
--- a/opengl/tests/textures/textures.cpp
+++ b/opengl/tests/textures/textures.cpp
@@ -23,7 +23,7 @@
 #include <GLES/glext.h>
 
 #include <ui/FramebufferNativeWindow.h>
-#include <ui/EGLUtils.h>
+#include "EGLUtils.h"
 
 using namespace android;
 
diff --git a/opengl/tests/tritex/Android.mk b/opengl/tests/tritex/Android.mk
index 6db3f49..fc544e4 100644
--- a/opengl/tests/tritex/Android.mk
+++ b/opengl/tests/tritex/Android.mk
@@ -10,6 +10,8 @@
     libGLESv1_CM \
     libui
 
+LOCAL_C_INCLUDES += frameworks/base/opengl/tests/include
+
 LOCAL_MODULE:= test-opengl-tritex
 
 LOCAL_MODULE_TAGS := optional
diff --git a/opengl/tests/tritex/tritex.cpp b/opengl/tests/tritex/tritex.cpp
index 3365ab4..f183483 100644
--- a/opengl/tests/tritex/tritex.cpp
+++ b/opengl/tests/tritex/tritex.cpp
@@ -9,7 +9,7 @@
 #include <GLES/glext.h>
 
 #include <ui/FramebufferNativeWindow.h>
-#include <ui/EGLUtils.h>
+#include "EGLUtils.h"
 
 #include <stdio.h>

 #include <stdlib.h>
diff --git a/packages/FakeOemFeatures/Android.mk b/packages/FakeOemFeatures/Android.mk
new file mode 100644
index 0000000..b0b0eeb
--- /dev/null
+++ b/packages/FakeOemFeatures/Android.mk
@@ -0,0 +1,15 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := debug
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := FakeOemFeatures
+LOCAL_CERTIFICATE := platform
+
+LOCAL_PROGUARD_ENABLED := disabled
+
+include $(BUILD_PACKAGE)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/packages/FakeOemFeatures/AndroidManifest.xml b/packages/FakeOemFeatures/AndroidManifest.xml
new file mode 100644
index 0000000..57938ac
--- /dev/null
+++ b/packages/FakeOemFeatures/AndroidManifest.xml
@@ -0,0 +1,25 @@
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        package="com.android.fakeoemfeatures"
+        coreApp="true"
+        >
+
+    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
+
+    <application
+        android:persistent="true"
+        android:name=".FakeApp"
+        android:allowClearUserData="false"
+        android:allowBackup="false"
+        android:hardwareAccelerated="true"
+        android:label="Fake OEM Features">
+
+        <service android:name=".FakeCoreService" android:process=":core"
+                android:label="Fake OEM Core Service" />
+        <service android:name=".FakeCoreService2" android:process=":core"
+                android:label="Fake OEM Core Service Also" />
+        <service android:name=".FakeCoreService3" android:process=":core"
+                android:label="Fake OEM Core Service Me Too" />
+        <service android:name=".FakeBackgroundService" android:process=":background"
+                android:label="Fake OEM Bg Service" />
+    </application>
+</manifest>
diff --git a/packages/FakeOemFeatures/MODULE_LICENSE_APACHE2 b/packages/FakeOemFeatures/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/packages/FakeOemFeatures/MODULE_LICENSE_APACHE2
diff --git a/packages/FakeOemFeatures/NOTICE b/packages/FakeOemFeatures/NOTICE
new file mode 100644
index 0000000..c5b1efa
--- /dev/null
+++ b/packages/FakeOemFeatures/NOTICE
@@ -0,0 +1,190 @@
+
+   Copyright (c) 2005-2008, The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+
+   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.
+
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
diff --git a/packages/FakeOemFeatures/src/com/android/fakeoemfeatures/FakeApp.java b/packages/FakeOemFeatures/src/com/android/fakeoemfeatures/FakeApp.java
new file mode 100644
index 0000000..436e579
--- /dev/null
+++ b/packages/FakeOemFeatures/src/com/android/fakeoemfeatures/FakeApp.java
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.fakeoemfeatures;
+
+import android.app.ActivityManager;
+import android.app.ActivityThread;
+import android.app.AlertDialog;
+import android.app.Application;
+import android.app.Dialog;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Message;
+import android.util.Slog;
+import android.view.Display;
+import android.view.ViewGroup;
+import android.view.WindowManager;
+
+public class FakeApp extends Application {
+    // Stuffing of 20MB
+    static final int STUFFING_SIZE_BYTES = 20*1024*1024;
+    static final int STUFFING_SIZE_INTS = STUFFING_SIZE_BYTES/4;
+    int[] mStuffing;
+
+    // Assume 4k pages.
+    static final int PAGE_SIZE = 4*1024;
+
+    static final long TICK_DELAY = 4*60*60*1000; // One hour
+    static final int MSG_TICK = 1;
+    final Handler mHandler = new Handler() {
+        @Override public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case MSG_TICK:
+                    // Our service is IMPORTANT.  We know, we wrote it.
+                    // We need to keep that thing running.  Because WE KNOW.
+                    // Damn you users, STOP MESSING WITH US.
+                    startService(new Intent(FakeApp.this, FakeBackgroundService.class));
+                    sendEmptyMessageDelayed(MSG_TICK, TICK_DELAY);
+                    break;
+                default:
+                    super.handleMessage(msg);
+                    break;
+            }
+        }
+    };
+
+    // Always run another process for more per-process overhead.
+    ServiceConnection mServiceConnection = new ServiceConnection() {
+        @Override public void onServiceConnected(ComponentName name, IBinder service) {
+        }
+
+        @Override public void onServiceDisconnected(ComponentName name) {
+        }
+    };
+    ServiceConnection mServiceConnection2 = new ServiceConnection() {
+        @Override public void onServiceConnected(ComponentName name, IBinder service) {
+        }
+
+        @Override public void onServiceDisconnected(ComponentName name) {
+        }
+    };
+    ServiceConnection mServiceConnection3 = new ServiceConnection() {
+        @Override public void onServiceConnected(ComponentName name, IBinder service) {
+        }
+
+        @Override public void onServiceDisconnected(ComponentName name) {
+        }
+    };
+
+    @Override
+    public void onCreate() {
+        String processName = ActivityThread.currentPackageName();
+        Slog.i("FakeOEMFeatures", "Creating app in process: " + processName);
+        if (!getApplicationInfo().packageName.equals(processName)) {
+            // If we are not in the main process of the app, then don't do
+            // our extra overhead stuff.
+            return;
+        }
+
+        final WindowManager wm = (WindowManager)getSystemService(Context.WINDOW_SERVICE);
+        final Display display = wm.getDefaultDisplay();
+
+        // Check to make sure we are not running on a user build.  If this
+        // is a user build, WARN!  Do not want!
+        if ("user".equals(android.os.Build.TYPE)) {
+            AlertDialog.Builder builder = new AlertDialog.Builder(this);
+            builder.setTitle("Should not be on user build");
+            builder.setMessage("The app Fake OEM Features should not be installed on a "
+                    + "user build.  Please remove this .apk before shipping this build to "
+                    + " your customers!");
+            builder.setCancelable(false);
+            builder.setPositiveButton("I understand", null);
+            Dialog dialog = builder.create();
+            dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
+            dialog.show();
+        }
+
+        // Make a fake window that is always around eating graphics resources.
+        FakeView view = new FakeView(this);
+        WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
+                WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
+                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
+                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
+                | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
+        if (ActivityManager.isHighEndGfx(display)) {
+            lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
+        }
+        lp.width = ViewGroup.LayoutParams.MATCH_PARENT;
+        lp.height = ViewGroup.LayoutParams.MATCH_PARENT;
+        int maxSize = display.getMaximumSizeDimension();
+        maxSize *= 2;
+        lp.x = maxSize;
+        lp.y = maxSize;
+        lp.setTitle(getPackageName());
+        wm.addView(view, lp);
+
+        // Bind to a fake service we want to keep running in another process.
+        bindService(new Intent(this, FakeCoreService.class), mServiceConnection,
+                Context.BIND_AUTO_CREATE);
+        bindService(new Intent(this, FakeCoreService2.class), mServiceConnection2,
+                Context.BIND_AUTO_CREATE);
+        bindService(new Intent(this, FakeCoreService3.class), mServiceConnection3,
+                Context.BIND_AUTO_CREATE);
+
+        // Start to a fake service that should run in the background of
+        // another process.
+        mHandler.sendEmptyMessage(MSG_TICK);
+
+        // Make a fake allocation to consume some RAM.
+        mStuffing = new int[STUFFING_SIZE_INTS];
+        for (int i=0; i<STUFFING_SIZE_BYTES/PAGE_SIZE; i++) {
+            // Fill each page with a unique value.
+            final int VAL = i*2 + 100;
+            final int OFF = (i*PAGE_SIZE)/4;
+            for (int j=0; j<(PAGE_SIZE/4); j++) {
+                mStuffing[OFF+j] = VAL;
+            }
+        }
+    }
+}
diff --git a/packages/FakeOemFeatures/src/com/android/fakeoemfeatures/FakeBackgroundService.java b/packages/FakeOemFeatures/src/com/android/fakeoemfeatures/FakeBackgroundService.java
new file mode 100644
index 0000000..5d1a3980
--- /dev/null
+++ b/packages/FakeOemFeatures/src/com/android/fakeoemfeatures/FakeBackgroundService.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.fakeoemfeatures;
+
+import java.util.ArrayList;
+import java.util.Random;
+
+import android.app.Dialog;
+import android.app.Service;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Message;
+import android.view.Display;
+import android.view.ViewGroup;
+import android.view.WindowManager;
+
+public class FakeBackgroundService extends Service {
+    final ArrayList<int[]> mAllocs = new ArrayList<int[]>();
+
+    final Random mRandom = new Random();
+
+    static final long TICK_DELAY = 30*1000; // 30 seconds
+    static final int MSG_TICK = 1;
+    final Handler mHandler = new Handler() {
+        @Override public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case MSG_TICK:
+                    // We are awesome!  To prove we are doing awesome stuff,
+                    // we must use some memory!  It wouldn't be awesome if
+                    // we didn't use memory!
+                    for (int i=0; i<5; i++) {
+                        try {
+                            int[] alloc = new int[FakeApp.PAGE_SIZE/4];
+                            mAllocs.add(alloc);
+                            final int VAL = mRandom.nextInt();
+                            for (int j=0; j<FakeApp.PAGE_SIZE/4; j++) {
+                                alloc[j] = VAL;
+                            }
+                        } catch (OutOfMemoryError e) {
+                        }
+                    }
+                    sendEmptyMessageDelayed(MSG_TICK, TICK_DELAY);
+                    break;
+                default:
+                    super.handleMessage(msg);
+                    break;
+            }
+        }
+    };
+
+    @Override public void onCreate() {
+        super.onCreate();
+        mHandler.sendEmptyMessageDelayed(MSG_TICK, TICK_DELAY);
+
+        final WindowManager wm = (WindowManager)getSystemService(Context.WINDOW_SERVICE);
+        final Display display = wm.getDefaultDisplay();
+
+        // Make a fake window that is always around eating graphics resources.
+        FakeView view = new FakeView(this);
+        Dialog dialog = new Dialog(this, android.R.style.Theme_Holo_Dialog);
+        dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
+        dialog.getWindow().setFlags(
+                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
+                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
+                | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
+                | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
+                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
+                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
+                | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
+                | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED
+                | WindowManager.LayoutParams.FLAG_DIM_BEHIND);
+        dialog.getWindow().setDimAmount(0);
+        dialog.getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT,
+                ViewGroup.LayoutParams.MATCH_PARENT);
+        WindowManager.LayoutParams lp = dialog.getWindow().getAttributes();
+        int maxSize = display.getMaximumSizeDimension();
+        maxSize *= 2;
+        lp.x = maxSize;
+        lp.y = maxSize;
+        lp.setTitle(getPackageName() + ":background");
+        dialog.getWindow().setAttributes(lp);
+        dialog.getWindow().setContentView(view);
+        dialog.show();
+    }
+
+    @Override public void onDestroy() {
+        super.onDestroy();
+        mHandler.removeMessages(MSG_TICK);
+    }
+
+    @Override public IBinder onBind(Intent intent) {
+        return null;
+    }
+}
diff --git a/packages/FakeOemFeatures/src/com/android/fakeoemfeatures/FakeCoreService.java b/packages/FakeOemFeatures/src/com/android/fakeoemfeatures/FakeCoreService.java
new file mode 100644
index 0000000..86bc506
--- /dev/null
+++ b/packages/FakeOemFeatures/src/com/android/fakeoemfeatures/FakeCoreService.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.fakeoemfeatures;
+
+import android.app.Service;
+import android.content.Intent;
+import android.os.Binder;
+import android.os.IBinder;
+
+public class FakeCoreService extends Service {
+    final Binder mBinder = new Binder();
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        return mBinder;
+    }
+}
diff --git a/include/private/ui/android_natives_priv.h b/packages/FakeOemFeatures/src/com/android/fakeoemfeatures/FakeCoreService2.java
similarity index 78%
rename from include/private/ui/android_natives_priv.h
rename to packages/FakeOemFeatures/src/com/android/fakeoemfeatures/FakeCoreService2.java
index 6b9f524..f06988d 100644
--- a/include/private/ui/android_natives_priv.h
+++ b/packages/FakeOemFeatures/src/com/android/fakeoemfeatures/FakeCoreService2.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009 The Android Open Source Project
+ * Copyright (C) 2012 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,4 +14,7 @@
  * limitations under the License.
  */
 
-#include <ui/android_native_buffer.h>
+package com.android.fakeoemfeatures;
+
+public class FakeCoreService2 extends FakeCoreService {
+}
diff --git a/include/private/ui/android_natives_priv.h b/packages/FakeOemFeatures/src/com/android/fakeoemfeatures/FakeCoreService3.java
similarity index 78%
copy from include/private/ui/android_natives_priv.h
copy to packages/FakeOemFeatures/src/com/android/fakeoemfeatures/FakeCoreService3.java
index 6b9f524..a35adb2 100644
--- a/include/private/ui/android_natives_priv.h
+++ b/packages/FakeOemFeatures/src/com/android/fakeoemfeatures/FakeCoreService3.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009 The Android Open Source Project
+ * Copyright (C) 2012 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,4 +14,7 @@
  * limitations under the License.
  */
 
-#include <ui/android_native_buffer.h>
+package com.android.fakeoemfeatures;
+
+public class FakeCoreService3 extends FakeCoreService {
+}
diff --git a/packages/FakeOemFeatures/src/com/android/fakeoemfeatures/FakeView.java b/packages/FakeOemFeatures/src/com/android/fakeoemfeatures/FakeView.java
new file mode 100644
index 0000000..276d55ee
--- /dev/null
+++ b/packages/FakeOemFeatures/src/com/android/fakeoemfeatures/FakeView.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.fakeoemfeatures;
+
+import java.util.Random;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.os.Handler;
+import android.os.Message;
+import android.view.View;
+
+/**
+ * Dummy view to emulate stuff an OEM may want to do.
+ */
+public class FakeView extends View {
+    static final long TICK_DELAY = 30*1000; // 30 seconds
+    static final int MSG_TICK = 1;
+
+    final Handler mHandler = new Handler() {
+        @Override public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case MSG_TICK:
+                    invalidate();
+                    sendEmptyMessageDelayed(MSG_TICK, TICK_DELAY);
+                    break;
+                default:
+                    super.handleMessage(msg);
+                    break;
+            }
+        }
+    };
+
+    final Paint mPaint = new Paint();
+    final Random mRandom = new Random();
+
+    public FakeView(Context context) {
+        super(context);
+    }
+
+    @Override
+    protected void onAttachedToWindow() {
+        super.onAttachedToWindow();
+        mHandler.sendEmptyMessageDelayed(MSG_TICK, TICK_DELAY);
+    }
+
+    @Override
+    protected void onDetachedFromWindow() {
+        super.onDetachedFromWindow();
+        mHandler.removeMessages(MSG_TICK);
+    }
+
+    @Override
+    protected void onDraw(Canvas canvas) {
+        super.onDraw(canvas);
+        canvas.drawColor(0xff000000);
+        mPaint.setTextSize(mRandom.nextInt(40) + 10);
+        mPaint.setColor(0xff000000 + mRandom.nextInt(0x1000000));
+        int x = mRandom.nextInt(getWidth()) - (getWidth()/2);
+        int y = mRandom.nextInt(getHeight());
+        canvas.drawText("abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ",
+                x, y, mPaint);
+    }
+}
diff --git a/packages/SystemUI/res/layout/navigation_bar.xml b/packages/SystemUI/res/layout/navigation_bar.xml
index d19fd81..82fcc88 100644
--- a/packages/SystemUI/res/layout/navigation_bar.xml
+++ b/packages/SystemUI/res/layout/navigation_bar.xml
@@ -68,7 +68,7 @@
                 android:layout_height="match_parent"
                 android:src="@drawable/ic_sysbar_home"
                 systemui:keyCode="3"
-                systemui:keyRepeat="false"
+                systemui:keyRepeat="true"
                 android:layout_weight="0"
                 systemui:glowBackground="@drawable/ic_sysbar_highlight"
                 android:contentDescription="@string/accessibility_home"
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index 3a2ea65..a08b99a 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -22,7 +22,6 @@
     <drawable name="notification_item_background_color_pressed">#ff257390</drawable>
     <drawable name="ticker_background_color">#ff1d1d1d</drawable>
     <drawable name="status_bar_background">#ff000000</drawable>
-    <drawable name="status_bar_recents_background_solid">#b3000000</drawable>
     <drawable name="status_bar_recents_app_thumbnail_background">#88000000</drawable>
     <color name="status_bar_recents_app_label_color">#ffffffff</color>
     <drawable name="status_bar_notification_row_background_color">#ff090909</drawable>
diff --git a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
index 14ce266..276ca21 100644
--- a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
@@ -53,6 +53,7 @@
                                                  // where fade starts
     static final float ALPHA_FADE_END = 0.5f; // fraction of thumbnail width
                                               // beyond which alpha->0
+    private float mMinAlpha = 0f;
 
     private float mPagingTouchSlop;
     private Callback mCallback;
@@ -120,6 +121,10 @@
                 v.getMeasuredHeight();
     }
 
+    public void setMinAlpha(float minAlpha) {
+        mMinAlpha = minAlpha;
+    }
+
     private float getAlphaForOffset(View view) {
         float viewSize = getSize(view);
         final float fadeSize = ALPHA_FADE_END * viewSize;
@@ -130,10 +135,7 @@
         } else if (pos < viewSize * (1.0f - ALPHA_FADE_START)) {
             result = 1.0f + (viewSize * ALPHA_FADE_START + pos) / fadeSize;
         }
-        // Make .03 alpha the minimum so you always see the item a bit-- slightly below
-        // .03, the item disappears entirely (as if alpha = 0) and that discontinuity looks
-        // a bit jarring
-        return Math.max(0.03f, result);
+        return Math.max(mMinAlpha, result);
     }
 
     // invalidate the view's own bounds all the way up the view hierarchy
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsCallback.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsCallback.java
index 78050a2..deb5670 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsCallback.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsCallback.java
@@ -27,9 +27,5 @@
     void handleOnClick(View selectedView);
     void handleSwipe(View selectedView);
     void handleLongPress(View selectedView, View anchorView, View thumbnailView);
-    void handleShowBackground(boolean show);
     void dismiss();
-
-    // TODO: find another way to get this info from RecentsPanelView
-    boolean isRecentsVisible();
 }
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java
index 4dc3e33..97c9553 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java
@@ -44,7 +44,7 @@
 import java.util.ArrayList;
 
 public class RecentsHorizontalScrollView extends HorizontalScrollView
-    implements SwipeHelper.Callback {
+        implements SwipeHelper.Callback, RecentsPanelView.RecentsScrollView {
     private static final String TAG = RecentsPanelView.TAG;
     private static final boolean DEBUG = RecentsPanelView.DEBUG;
     private LinearLayout mLinearLayout;
@@ -65,6 +65,10 @@
         mRecycledViews = new ArrayList<View>();
     }
 
+    public void setMinSwipeAlpha(float minAlpha) {
+        mSwipeHelper.setMinAlpha(minAlpha);
+    }
+
     private int scrollPositionOfMostRecent() {
         return mLinearLayout.getWidth() - getWidth();
     }
@@ -217,14 +221,6 @@
     }
 
     @Override
-    protected void onLayout (boolean changed, int left, int top, int right, int bottom) {
-        super.onLayout(changed, left, top, right, bottom);
-        if (mPerformanceHelper != null) {
-            mPerformanceHelper.onLayoutCallback();
-        }
-    }
-
-    @Override
     public void draw(Canvas canvas) {
         super.draw(canvas);
 
@@ -327,12 +323,6 @@
         });
     }
 
-    public void onRecentsVisibilityChanged() {
-        if (mPerformanceHelper != null) {
-            mPerformanceHelper.updateShowBackground();
-        }
-    }
-
     @Override
     protected void onVisibilityChanged(View changedView, int visibility) {
         super.onVisibilityChanged(changedView, visibility);
@@ -379,9 +369,6 @@
 
     @Override
     public void setLayoutTransition(LayoutTransition transition) {
-        if (mPerformanceHelper != null) {
-            mPerformanceHelper.setLayoutTransitionCallback(transition);
-        }
         // The layout transition applies to our embedded LinearLayout
         mLinearLayout.setLayoutTransition(transition);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
index 7896720..61aaa43 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
@@ -32,13 +32,14 @@
 import android.provider.Settings;
 import android.util.AttributeSet;
 import android.util.Log;
+import android.view.Display;
 import android.view.KeyEvent;
 import android.view.LayoutInflater;
 import android.view.MenuItem;
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewGroup;
-import android.view.ViewRootImpl;
+import android.view.WindowManager;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.animation.AnimationUtils;
 import android.widget.AdapterView;
@@ -91,6 +92,13 @@
         public void onRecentsPanelVisibilityChanged(boolean visible);
     }
 
+    public static interface RecentsScrollView {
+        public int numItemsInOneScreenful();
+        public void setAdapter(TaskDescriptionAdapter adapter);
+        public void setCallback(RecentsCallback callback);
+        public void setMinSwipeAlpha(float minAlpha);
+    }
+
     private final class OnLongClickDelegate implements View.OnLongClickListener {
         View mOtherView;
         OnLongClickDelegate(View other) {
@@ -195,16 +203,11 @@
     }
 
     public int numItemsInOneScreenful() {
-        if (mRecentsContainer instanceof RecentsHorizontalScrollView){
-            RecentsHorizontalScrollView scrollView
-                    = (RecentsHorizontalScrollView) mRecentsContainer;
+        if (mRecentsContainer instanceof RecentsScrollView){
+            RecentsScrollView scrollView
+                    = (RecentsScrollView) mRecentsContainer;
             return scrollView.numItemsInOneScreenful();
-        } else if (mRecentsContainer instanceof RecentsVerticalScrollView){
-            RecentsVerticalScrollView scrollView
-                    = (RecentsVerticalScrollView) mRecentsContainer;
-            return scrollView.numItemsInOneScreenful();
-        }
-        else {
+        }  else {
             throw new IllegalArgumentException("missing Recents[Horizontal]ScrollView");
         }
     }
@@ -325,18 +328,6 @@
         }
     }
 
-    public void handleShowBackground(boolean show) {
-        if (show) {
-            mRecentsScrim.setBackgroundResource(R.drawable.status_bar_recents_background_solid);
-        } else {
-            mRecentsScrim.setBackgroundDrawable(null);
-        }
-    }
-
-    public boolean isRecentsVisible() {
-        return getVisibility() == VISIBLE;
-    }
-
     public void onAnimationCancel(Animator animation) {
     }
 
@@ -438,18 +429,12 @@
         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
-                    = (RecentsHorizontalScrollView) mRecentsContainer;
+        if (mRecentsContainer instanceof RecentsScrollView){
+            RecentsScrollView scrollView
+                    = (RecentsScrollView) mRecentsContainer;
             scrollView.setAdapter(mListAdapter);
             scrollView.setCallback(this);
-        } else if (mRecentsContainer instanceof RecentsVerticalScrollView){
-            RecentsVerticalScrollView scrollView
-                    = (RecentsVerticalScrollView) mRecentsContainer;
-            scrollView.setAdapter(mListAdapter);
-            scrollView.setCallback(this);
-        }
-        else {
+        } else {
             throw new IllegalArgumentException("missing Recents[Horizontal]ScrollView");
         }
 
@@ -457,9 +442,15 @@
         mRecentsNoApps = findViewById(R.id.recents_no_apps);
         mChoreo = new Choreographer(this, mRecentsScrim, mRecentsContainer, mRecentsNoApps, this);
 
-        // In order to save space, we make the background texture repeat in the Y direction
-        if (mRecentsScrim != null && mRecentsScrim.getBackground() instanceof BitmapDrawable) {
-            ((BitmapDrawable) mRecentsScrim.getBackground()).setTileModeY(TileMode.REPEAT);
+        if (mRecentsScrim != null) {
+            Display d = ((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE))
+                .getDefaultDisplay();
+            if (!ActivityManager.isHighEndGfx(d)) {
+                mRecentsScrim.setBackgroundDrawable(null);
+            } else if (mRecentsScrim.getBackground() instanceof BitmapDrawable) {
+                // In order to save space, we make the background texture repeat in the Y direction
+                ((BitmapDrawable) mRecentsScrim.getBackground()).setTileModeY(TileMode.REPEAT);
+            }
         }
 
         mPreloadTasksRunnable = new Runnable() {
@@ -472,27 +463,20 @@
         };
     }
 
+    public void setMinSwipeAlpha(float minAlpha) {
+        if (mRecentsContainer instanceof RecentsScrollView){
+            RecentsScrollView scrollView
+                = (RecentsScrollView) mRecentsContainer;
+            scrollView.setMinSwipeAlpha(minAlpha);
+        }
+    }
+
     private void createCustomAnimations(LayoutTransition transitioner) {
         transitioner.setDuration(200);
         transitioner.setStartDelay(LayoutTransition.CHANGE_DISAPPEARING, 0);
         transitioner.setAnimator(LayoutTransition.DISAPPEARING, null);
     }
 
-    @Override
-    protected void onVisibilityChanged(View changedView, int visibility) {
-        super.onVisibilityChanged(changedView, visibility);
-        if (DEBUG) Log.v(TAG, "onVisibilityChanged(" + changedView + ", " + visibility + ")");
-
-        if (mRecentsContainer instanceof RecentsHorizontalScrollView) {
-            ((RecentsHorizontalScrollView) mRecentsContainer).onRecentsVisibilityChanged();
-        } else if (mRecentsContainer instanceof RecentsVerticalScrollView) {
-            ((RecentsVerticalScrollView) mRecentsContainer).onRecentsVisibilityChanged();
-        } else {
-            throw new IllegalArgumentException("missing Recents[Horizontal]ScrollView");
-        }
-    }
-
-
     private void updateIcon(ViewHolder h, Drawable icon, boolean show, boolean anim) {
         if (icon != null) {
             h.iconView.setImageDrawable(icon);
@@ -543,8 +527,7 @@
         synchronized (td) {
             if (mRecentsContainer != null) {
                 ViewGroup container = mRecentsContainer;
-                if (container instanceof HorizontalScrollView
-                        || container instanceof ScrollView) {
+                if (container instanceof RecentsScrollView) {
                     container = (ViewGroup) container.findViewById(
                             R.id.recents_linear_layout);
                 }
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsScrollViewPerformanceHelper.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsScrollViewPerformanceHelper.java
index 813099a..5529d0c 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsScrollViewPerformanceHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsScrollViewPerformanceHelper.java
@@ -78,39 +78,13 @@
             mScrollView.setVerticalFadingEdgeEnabled(false);
             mScrollView.setHorizontalFadingEdgeEnabled(false);
         }
-        if (mSoftwareRendered && OPTIMIZE_SW_RENDERED_RECENTS) {
-            mCallback = callback;
-            mLinearLayout = layout;
-            mAttachedToWindow = true;
-            mBackgroundDrawable = mContext.getResources()
-                .getDrawable(R.drawable.status_bar_recents_background_solid).getConstantState();
-            updateShowBackground();
-        }
-
     }
 
     public void addViewCallback(View newLinearLayoutChild) {
         if (mSoftwareRendered && OPTIMIZE_SW_RENDERED_RECENTS) {
             final View view = newLinearLayoutChild;
-            if (mShowBackground) {
-                view.setBackgroundDrawable(mBackgroundDrawable.newDrawable());
-                view.setDrawingCacheEnabled(true);
-                view.buildDrawingCache();
-            } else {
-                view.setBackgroundDrawable(null);
-                view.setDrawingCacheEnabled(false);
-                view.destroyDrawingCache();
-            }
-        }
-    }
-
-    public void onLayoutCallback() {
-        if (mSoftwareRendered && OPTIMIZE_SW_RENDERED_RECENTS) {
-            mScrollView.post(new Runnable() {
-                public void run() {
-                    updateShowBackground();
-                }
-            });
+            view.setDrawingCacheEnabled(true);
+            view.buildDrawingCache();
         }
     }
 
@@ -118,37 +92,6 @@
             int left, int right, int top, int bottom, int scrollX, int scrollY,
             float topFadingEdgeStrength, float bottomFadingEdgeStrength,
             float leftFadingEdgeStrength, float rightFadingEdgeStrength) {
-        if (mSoftwareRendered && OPTIMIZE_SW_RENDERED_RECENTS) {
-            if (mIsVertical) {
-                if (scrollY < 0) {
-                    Drawable d = mBackgroundDrawable.newDrawable().getCurrent();
-                    d.setBounds(0, scrollY, mScrollView.getWidth(), 0);
-                    d.draw(canvas);
-                } else {
-                    final int childHeight = mLinearLayout.getHeight();
-                    if (scrollY + mScrollView.getHeight() > childHeight) {
-                        Drawable d = mBackgroundDrawable.newDrawable().getCurrent();
-                        d.setBounds(0, childHeight, mScrollView.getWidth(),
-                                scrollY + mScrollView.getHeight());
-                        d.draw(canvas);
-                    }
-                }
-            } else {
-                if (scrollX < 0) {
-                    Drawable d = mBackgroundDrawable.newDrawable().getCurrent();
-                    d.setBounds(scrollX, 0, 0, mScrollView.getHeight());
-                    d.draw(canvas);
-                } else {
-                    final int childWidth = mLinearLayout.getWidth();
-                    if (scrollX + mScrollView.getWidth() > childWidth) {
-                        Drawable d = mBackgroundDrawable.newDrawable().getCurrent();
-                        d.setBounds(childWidth, 0,
-                                scrollX + mScrollView.getWidth(), mScrollView.getHeight());
-                        d.draw(canvas);
-                    }
-                }
-            }
-        }
 
         if ((mSoftwareRendered && OPTIMIZE_SW_RENDERED_RECENTS)
                 || USE_DARK_FADE_IN_HW_ACCELERATED_MODE) {
@@ -241,64 +184,4 @@
         return mFadingEdgeLength;
     }
 
-    public void setLayoutTransitionCallback(LayoutTransition transition) {
-        if (mSoftwareRendered && OPTIMIZE_SW_RENDERED_RECENTS) {
-            if (transition != null) {
-                transition.addTransitionListener(new LayoutTransition.TransitionListener() {
-                    @Override
-                    public void startTransition(LayoutTransition transition,
-                            ViewGroup container, View view, int transitionType) {
-                        updateShowBackground();
-                    }
-
-                    @Override
-                    public void endTransition(LayoutTransition transition,
-                            ViewGroup container, View view, int transitionType) {
-                        updateShowBackground();
-                    }
-                });
-            }
-        }
-    }
-
-    // Turn on/off drawing the background in our ancestor, and turn on/off drawing
-    // in the items in LinearLayout contained by this scrollview.
-    // Moving the background drawing to our children, and turning on a drawing cache
-    // for each of them, gives us a ~20fps gain when Recents is rendered in software
-    public void updateShowBackground() {
-        if (!mAttachedToWindow) {
-            // We haven't been initialized yet-- we'll get called again when we are
-            return;
-        }
-        if (mSoftwareRendered && OPTIMIZE_SW_RENDERED_RECENTS) {
-            LayoutTransition transition = mLinearLayout.getLayoutTransition();
-            int linearLayoutSize =
-                mIsVertical ? mLinearLayout.getHeight() : mLinearLayout.getWidth();
-            int scrollViewSize =
-                mIsVertical ? mScrollView.getHeight() : mScrollView.getWidth();
-            boolean show = !mScrollView.isHardwareAccelerated() &&
-                (linearLayoutSize > scrollViewSize) &&
-                !(transition != null && transition.isRunning()) &&
-                mCallback.isRecentsVisible();
-
-            if (!mFirstTime && show == mShowBackground) return;
-            mShowBackground = show;
-            mFirstTime = false;
-
-            mCallback.handleShowBackground(!show);
-            for (int i = 0; i < mLinearLayout.getChildCount(); i++) {
-                View v = mLinearLayout.getChildAt(i);
-                if (show) {
-                    v.setBackgroundDrawable(mBackgroundDrawable.newDrawable());
-                    v.setDrawingCacheEnabled(true);
-                    v.buildDrawingCache();
-                } else {
-                    v.setDrawingCacheEnabled(false);
-                    v.destroyDrawingCache();
-                    v.setBackgroundDrawable(null);
-                }
-            }
-        }
-    }
-
 }
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java
index 19fce37..f4e516c 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java
@@ -43,7 +43,8 @@
 
 import java.util.ArrayList;
 
-public class RecentsVerticalScrollView extends ScrollView implements SwipeHelper.Callback {
+public class RecentsVerticalScrollView extends ScrollView
+        implements SwipeHelper.Callback, RecentsPanelView.RecentsScrollView {
     private static final String TAG = RecentsPanelView.TAG;
     private static final boolean DEBUG = RecentsPanelView.DEBUG;
     private LinearLayout mLinearLayout;
@@ -65,6 +66,10 @@
         mRecycledViews = new ArrayList<View>();
     }
 
+    public void setMinSwipeAlpha(float minAlpha) {
+        mSwipeHelper.setMinAlpha(minAlpha);
+    }
+
     private int scrollPositionOfMostRecent() {
         return mLinearLayout.getHeight() - getHeight();
     }
@@ -224,14 +229,6 @@
     }
 
     @Override
-    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
-        super.onLayout(changed, left, top, right, bottom);
-        if (mPerformanceHelper != null) {
-            mPerformanceHelper.onLayoutCallback();
-        }
-    }
-
-    @Override
     public void draw(Canvas canvas) {
         super.draw(canvas);
 
@@ -334,12 +331,6 @@
         });
     }
 
-    public void onRecentsVisibilityChanged() {
-        if (mPerformanceHelper != null) {
-            mPerformanceHelper.updateShowBackground();
-        }
-    }
-
     @Override
     protected void onVisibilityChanged(View changedView, int visibility) {
         super.onVisibilityChanged(changedView, visibility);
@@ -387,9 +378,6 @@
 
     @Override
     public void setLayoutTransition(LayoutTransition transition) {
-        if (mPerformanceHelper != null) {
-            mPerformanceHelper.setLayoutTransitionCallback(transition);
-        }
         // The layout transition applies to our embedded LinearLayout
         mLinearLayout.setLayoutTransition(transition);
     }
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 401553f..2e1f120 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -102,6 +102,8 @@
     public static final String ACTION_STATUSBAR_START
             = "com.android.internal.policy.statusbar.START";
 
+    private static final boolean ENABLE_INTRUDERS = false;
+
     static final int EXPANDED_LEAVE_ALONE = -10000;
     static final int EXPANDED_FULL_OPEN = -10001;
 
@@ -268,7 +270,7 @@
 
         addNavigationBar();
 
-        //addIntruderView();
+        if (ENABLE_INTRUDERS) addIntruderView();
 
         // Lastly, call to the icon policy to install/update all the icons.
         mIconPolicy = new PhoneStatusBarPolicy(mContext);
@@ -395,6 +397,9 @@
                 (opaque ? PixelFormat.OPAQUE : PixelFormat.TRANSLUCENT));
         if (ActivityManager.isHighEndGfx(mDisplay)) {
             lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
+        } else {
+            lp.flags |= WindowManager.LayoutParams.FLAG_DIM_BEHIND;
+            lp.dimAmount = 0.7f;
         }
         lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
         lp.setTitle("RecentsPanel");
@@ -427,6 +432,11 @@
         mRecentsPanel.setOnTouchListener(new TouchOutsideListener(MSG_CLOSE_RECENTS_PANEL,
                 mRecentsPanel));
         mRecentsPanel.setVisibility(View.GONE);
+
+        // Make .03 alpha the minimum so you always see the item a bit-- slightly below
+        // .03, the item disappears entirely (as if alpha = 0) and that discontinuity looks
+        // a bit jarring
+        mRecentsPanel.setMinSwipeAlpha(0.03f);
         WindowManager.LayoutParams lp = getRecentsLayoutParams(mRecentsPanel.getLayoutParams());
 
         WindowManagerImpl.getDefault().addView(mRecentsPanel, lp);
@@ -557,8 +567,9 @@
             }
         } catch (RemoteException ex) {
         }
-        if ((notification.score >= mIntruderInImmersiveMinScore) 
-                || (!immersive && (notification.score > mIntruderMinScore))) {
+        if (ENABLE_INTRUDERS && (
+                   (notification.score >= mIntruderInImmersiveMinScore)
+                || (!immersive && (notification.score > mIntruderMinScore)))) {
             Slog.d(TAG, "Presenting high-priority notification");
             // special new transient ticker mode
             // 1. Populate mIntruderAlertView
diff --git a/packages/VpnDialogs/res/layout/manage.xml b/packages/VpnDialogs/res/layout/manage.xml
index ec710ff..56332c3 100644
--- a/packages/VpnDialogs/res/layout/manage.xml
+++ b/packages/VpnDialogs/res/layout/manage.xml
@@ -32,12 +32,12 @@
         <TextView android:id="@+id/duration" style="@style/value"/>
     </TableRow>
 
-    <TableRow>
+    <TableRow android:id="@+id/data_transmitted_row" android:visibility="gone">
         <TextView android:text="@string/data_transmitted" style="@style/label"/>
         <TextView android:id="@+id/data_transmitted" style="@style/value"/>
     </TableRow>
 
-    <TableRow>
+    <TableRow android:id="@+id/data_received_row" android:visibility="gone">
         <TextView android:text="@string/data_received" style="@style/label"/>
         <TextView android:id="@+id/data_received" style="@style/value"/>
     </TableRow>
diff --git a/packages/VpnDialogs/res/values-af/strings.xml b/packages/VpnDialogs/res/values-af/strings.xml
index 6f9ac18..2c23fa3 100644
--- a/packages/VpnDialogs/res/values-af/strings.xml
+++ b/packages/VpnDialogs/res/values-af/strings.xml
@@ -26,6 +26,5 @@
     <string name="duration" msgid="3584782459928719435">"Tydsduur:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Gestuur:"</string>
     <string name="data_received" msgid="4062776929376067820">"Ontvang:"</string>
-    <string name="blank_value" msgid="6278484582661984635">"--"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> grepe/<xliff:g id="NUMBER_1">%2$s</xliff:g> pakkies"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-am/strings.xml b/packages/VpnDialogs/res/values-am/strings.xml
index c13c56b..7fc9897 100644
--- a/packages/VpnDialogs/res/values-am/strings.xml
+++ b/packages/VpnDialogs/res/values-am/strings.xml
@@ -26,6 +26,5 @@
     <string name="duration" msgid="3584782459928719435">"ጊዜ"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"ተልኳል ለ:"</string>
     <string name="data_received" msgid="4062776929376067820">"ተቀብሏል፡"</string>
-    <string name="blank_value" msgid="6278484582661984635">"--"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> ባይትስ / <xliff:g id="NUMBER_1">%2$s</xliff:g> ፓኬቶች"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-ar/strings.xml b/packages/VpnDialogs/res/values-ar/strings.xml
index 337b2ce..2380fa2 100644
--- a/packages/VpnDialogs/res/values-ar/strings.xml
+++ b/packages/VpnDialogs/res/values-ar/strings.xml
@@ -26,6 +26,5 @@
     <string name="duration" msgid="3584782459928719435">"المدة:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"مرسل:"</string>
     <string name="data_received" msgid="4062776929376067820">"تم الاستلام:"</string>
-    <string name="blank_value" msgid="6278484582661984635">"--"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> بايت / <xliff:g id="NUMBER_1">%2$s</xliff:g> من الحزم"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-be/strings.xml b/packages/VpnDialogs/res/values-be/strings.xml
index 45baff5..af43aef 100644
--- a/packages/VpnDialogs/res/values-be/strings.xml
+++ b/packages/VpnDialogs/res/values-be/strings.xml
@@ -26,6 +26,5 @@
     <string name="duration" msgid="3584782459928719435">"Працягласць:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Адпраўлена:"</string>
     <string name="data_received" msgid="4062776929376067820">"Атрымана:"</string>
-    <string name="blank_value" msgid="6278484582661984635">"-"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> байт / <xliff:g id="NUMBER_1">%2$s</xliff:g> пакеты"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-bg/strings.xml b/packages/VpnDialogs/res/values-bg/strings.xml
index 5d186a3..7ecfac7 100644
--- a/packages/VpnDialogs/res/values-bg/strings.xml
+++ b/packages/VpnDialogs/res/values-bg/strings.xml
@@ -26,6 +26,5 @@
     <string name="duration" msgid="3584782459928719435">"Продължителност:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Изпратено:"</string>
     <string name="data_received" msgid="4062776929376067820">"Получено:"</string>
-    <string name="blank_value" msgid="6278484582661984635">"–"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> байта/ <xliff:g id="NUMBER_1">%2$s</xliff:g> пакета"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-ca/strings.xml b/packages/VpnDialogs/res/values-ca/strings.xml
index 91236aa..e5332e0 100644
--- a/packages/VpnDialogs/res/values-ca/strings.xml
+++ b/packages/VpnDialogs/res/values-ca/strings.xml
@@ -26,6 +26,5 @@
     <string name="duration" msgid="3584782459928719435">"Durada:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Enviat:"</string>
     <string name="data_received" msgid="4062776929376067820">"Rebut:"</string>
-    <string name="blank_value" msgid="6278484582661984635">"--"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> bytes/<xliff:g id="NUMBER_1">%2$s</xliff:g> paquets"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-cs/strings.xml b/packages/VpnDialogs/res/values-cs/strings.xml
index ee737a1..28e861f 100644
--- a/packages/VpnDialogs/res/values-cs/strings.xml
+++ b/packages/VpnDialogs/res/values-cs/strings.xml
@@ -26,6 +26,5 @@
     <string name="duration" msgid="3584782459928719435">"Doba trvání:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Odesláno:"</string>
     <string name="data_received" msgid="4062776929376067820">"Přijato:"</string>
-    <string name="blank_value" msgid="6278484582661984635">"–"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> bajtů / <xliff:g id="NUMBER_1">%2$s</xliff:g> paketů"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-da/strings.xml b/packages/VpnDialogs/res/values-da/strings.xml
index 2a48a90..a226d0e 100644
--- a/packages/VpnDialogs/res/values-da/strings.xml
+++ b/packages/VpnDialogs/res/values-da/strings.xml
@@ -26,6 +26,5 @@
     <string name="duration" msgid="3584782459928719435">"Varighed:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Sendt:"</string>
     <string name="data_received" msgid="4062776929376067820">"Modtaget:"</string>
-    <string name="blank_value" msgid="6278484582661984635">"–"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> bytes / <xliff:g id="NUMBER_1">%2$s</xliff:g> pakker"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-de/strings.xml b/packages/VpnDialogs/res/values-de/strings.xml
index 0d2ee85..124a985 100644
--- a/packages/VpnDialogs/res/values-de/strings.xml
+++ b/packages/VpnDialogs/res/values-de/strings.xml
@@ -26,6 +26,5 @@
     <string name="duration" msgid="3584782459928719435">"Dauer:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Gesendet:"</string>
     <string name="data_received" msgid="4062776929376067820">"Empfangen:"</string>
-    <string name="blank_value" msgid="6278484582661984635">"-"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> Byte/<xliff:g id="NUMBER_1">%2$s</xliff:g> Pakete"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-el/strings.xml b/packages/VpnDialogs/res/values-el/strings.xml
index b82272a..5aefde4 100644
--- a/packages/VpnDialogs/res/values-el/strings.xml
+++ b/packages/VpnDialogs/res/values-el/strings.xml
@@ -26,6 +26,5 @@
     <string name="duration" msgid="3584782459928719435">"Διάρκεια:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Στάλθηκε:"</string>
     <string name="data_received" msgid="4062776929376067820">"Λήφθηκε:"</string>
-    <string name="blank_value" msgid="6278484582661984635">"--"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> byte / <xliff:g id="NUMBER_1">%2$s</xliff:g> πακέτα"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-en-rGB/strings.xml b/packages/VpnDialogs/res/values-en-rGB/strings.xml
index d7c411a..afc46d8 100644
--- a/packages/VpnDialogs/res/values-en-rGB/strings.xml
+++ b/packages/VpnDialogs/res/values-en-rGB/strings.xml
@@ -26,6 +26,5 @@
     <string name="duration" msgid="3584782459928719435">"Duration:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Sent:"</string>
     <string name="data_received" msgid="4062776929376067820">"Received:"</string>
-    <string name="blank_value" msgid="6278484582661984635">"-"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> bytes / <xliff:g id="NUMBER_1">%2$s</xliff:g> packets"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-es-rUS/strings.xml b/packages/VpnDialogs/res/values-es-rUS/strings.xml
index 58e72d1..4276065 100644
--- a/packages/VpnDialogs/res/values-es-rUS/strings.xml
+++ b/packages/VpnDialogs/res/values-es-rUS/strings.xml
@@ -26,6 +26,5 @@
     <string name="duration" msgid="3584782459928719435">"Duración:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Enviados:"</string>
     <string name="data_received" msgid="4062776929376067820">"Recibidos:"</string>
-    <string name="blank_value" msgid="6278484582661984635">"--"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> bytes / <xliff:g id="NUMBER_1">%2$s</xliff:g> paquetes"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-es/strings.xml b/packages/VpnDialogs/res/values-es/strings.xml
index 79ad80c..272042a 100644
--- a/packages/VpnDialogs/res/values-es/strings.xml
+++ b/packages/VpnDialogs/res/values-es/strings.xml
@@ -26,6 +26,5 @@
     <string name="duration" msgid="3584782459928719435">"Duración:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Enviado:"</string>
     <string name="data_received" msgid="4062776929376067820">"Recibido:"</string>
-    <string name="blank_value" msgid="6278484582661984635">"--"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> bytes / <xliff:g id="NUMBER_1">%2$s</xliff:g> paquetes"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-et/strings.xml b/packages/VpnDialogs/res/values-et/strings.xml
index 3a1ac5a..c016eb0 100644
--- a/packages/VpnDialogs/res/values-et/strings.xml
+++ b/packages/VpnDialogs/res/values-et/strings.xml
@@ -26,6 +26,5 @@
     <string name="duration" msgid="3584782459928719435">"Kestus:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Saadetud:"</string>
     <string name="data_received" msgid="4062776929376067820">"Vastu on võetud:"</string>
-    <string name="blank_value" msgid="6278484582661984635">"-"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> baiti / <xliff:g id="NUMBER_1">%2$s</xliff:g> paketti"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-fa/strings.xml b/packages/VpnDialogs/res/values-fa/strings.xml
index 9a76594..7bd5590 100644
--- a/packages/VpnDialogs/res/values-fa/strings.xml
+++ b/packages/VpnDialogs/res/values-fa/strings.xml
@@ -26,6 +26,5 @@
     <string name="duration" msgid="3584782459928719435">"مدت زمان:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"ارسال شده:"</string>
     <string name="data_received" msgid="4062776929376067820">"دریافتی:"</string>
-    <string name="blank_value" msgid="6278484582661984635">"--"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> بایت / <xliff:g id="NUMBER_1">%2$s</xliff:g> بسته"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-fi/strings.xml b/packages/VpnDialogs/res/values-fi/strings.xml
index c8d830c..2ca550d 100644
--- a/packages/VpnDialogs/res/values-fi/strings.xml
+++ b/packages/VpnDialogs/res/values-fi/strings.xml
@@ -26,6 +26,5 @@
     <string name="duration" msgid="3584782459928719435">"Kesto:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Lähetetty:"</string>
     <string name="data_received" msgid="4062776929376067820">"Vastaanotettu:"</string>
-    <string name="blank_value" msgid="6278484582661984635">"-"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> tavua / <xliff:g id="NUMBER_1">%2$s</xliff:g> pakettia"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-fr/strings.xml b/packages/VpnDialogs/res/values-fr/strings.xml
index e38c1a2..64334fd 100644
--- a/packages/VpnDialogs/res/values-fr/strings.xml
+++ b/packages/VpnDialogs/res/values-fr/strings.xml
@@ -26,6 +26,5 @@
     <string name="duration" msgid="3584782459928719435">"Durée :"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Envoyé :"</string>
     <string name="data_received" msgid="4062776929376067820">"Reçu :"</string>
-    <string name="blank_value" msgid="6278484582661984635">"–"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> octets / <xliff:g id="NUMBER_1">%2$s</xliff:g> paquets"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-hi/strings.xml b/packages/VpnDialogs/res/values-hi/strings.xml
index 7166877..e2cb51a 100644
--- a/packages/VpnDialogs/res/values-hi/strings.xml
+++ b/packages/VpnDialogs/res/values-hi/strings.xml
@@ -26,6 +26,5 @@
     <string name="duration" msgid="3584782459928719435">"अवधि:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"भेजे गए:"</string>
     <string name="data_received" msgid="4062776929376067820">"प्राप्त:"</string>
-    <string name="blank_value" msgid="6278484582661984635">"--"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> बाइट / <xliff:g id="NUMBER_1">%2$s</xliff:g> पैकेट"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-hr/strings.xml b/packages/VpnDialogs/res/values-hr/strings.xml
index cdbffbc..f825bef 100644
--- a/packages/VpnDialogs/res/values-hr/strings.xml
+++ b/packages/VpnDialogs/res/values-hr/strings.xml
@@ -26,6 +26,5 @@
     <string name="duration" msgid="3584782459928719435">"Trajanje:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Poslano:"</string>
     <string name="data_received" msgid="4062776929376067820">"Primljeno:"</string>
-    <string name="blank_value" msgid="6278484582661984635">"--"</string>
     <string name="data_value_format" msgid="2192466557826897580">"Bajtova: <xliff:g id="NUMBER_0">%1$s</xliff:g>/paketa: <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-hu/strings.xml b/packages/VpnDialogs/res/values-hu/strings.xml
index a268402..cb12f27 100644
--- a/packages/VpnDialogs/res/values-hu/strings.xml
+++ b/packages/VpnDialogs/res/values-hu/strings.xml
@@ -26,6 +26,5 @@
     <string name="duration" msgid="3584782459928719435">"Időtartam:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Elküldve:"</string>
     <string name="data_received" msgid="4062776929376067820">"Érkezett:"</string>
-    <string name="blank_value" msgid="6278484582661984635">"--"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> bájt/<xliff:g id="NUMBER_1">%2$s</xliff:g> adatcsomag"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-in/strings.xml b/packages/VpnDialogs/res/values-in/strings.xml
index 1721d68..c9710e5 100644
--- a/packages/VpnDialogs/res/values-in/strings.xml
+++ b/packages/VpnDialogs/res/values-in/strings.xml
@@ -26,6 +26,5 @@
     <string name="duration" msgid="3584782459928719435">"Durasi:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Terkirim:"</string>
     <string name="data_received" msgid="4062776929376067820">"Diterima:"</string>
-    <string name="blank_value" msgid="6278484582661984635">"--"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> byte / <xliff:g id="NUMBER_1">%2$s</xliff:g> paket"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-it/strings.xml b/packages/VpnDialogs/res/values-it/strings.xml
index 98e5cc9..224f083 100644
--- a/packages/VpnDialogs/res/values-it/strings.xml
+++ b/packages/VpnDialogs/res/values-it/strings.xml
@@ -26,6 +26,5 @@
     <string name="duration" msgid="3584782459928719435">"Durata:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Inviati:"</string>
     <string name="data_received" msgid="4062776929376067820">"Ricevuti:"</string>
-    <string name="blank_value" msgid="6278484582661984635">"--"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> byte/<xliff:g id="NUMBER_1">%2$s</xliff:g> pacchetti"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-iw/strings.xml b/packages/VpnDialogs/res/values-iw/strings.xml
index 4b8d125..bb845ee 100644
--- a/packages/VpnDialogs/res/values-iw/strings.xml
+++ b/packages/VpnDialogs/res/values-iw/strings.xml
@@ -26,6 +26,5 @@
     <string name="duration" msgid="3584782459928719435">"משך:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"נשלח:"</string>
     <string name="data_received" msgid="4062776929376067820">"התקבל:"</string>
-    <string name="blank_value" msgid="6278484582661984635">"--"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> בתים / <xliff:g id="NUMBER_1">%2$s</xliff:g> מנות"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-ja/strings.xml b/packages/VpnDialogs/res/values-ja/strings.xml
index 751162f..a88c388 100644
--- a/packages/VpnDialogs/res/values-ja/strings.xml
+++ b/packages/VpnDialogs/res/values-ja/strings.xml
@@ -26,6 +26,5 @@
     <string name="duration" msgid="3584782459928719435">"期間:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"送信:"</string>
     <string name="data_received" msgid="4062776929376067820">"受信:"</string>
-    <string name="blank_value" msgid="6278484582661984635">"--"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g>バイト/<xliff:g id="NUMBER_1">%2$s</xliff:g>パケット"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-ko/strings.xml b/packages/VpnDialogs/res/values-ko/strings.xml
index cfc4ffc..38a5e2e 100644
--- a/packages/VpnDialogs/res/values-ko/strings.xml
+++ b/packages/VpnDialogs/res/values-ko/strings.xml
@@ -26,6 +26,5 @@
     <string name="duration" msgid="3584782459928719435">"기간:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"보냄:"</string>
     <string name="data_received" msgid="4062776929376067820">"수신됨:"</string>
-    <string name="blank_value" msgid="6278484582661984635">"--"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g>바이트/<xliff:g id="NUMBER_1">%2$s</xliff:g>패킷"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-lt/strings.xml b/packages/VpnDialogs/res/values-lt/strings.xml
index e70c5e8..8ed3045 100644
--- a/packages/VpnDialogs/res/values-lt/strings.xml
+++ b/packages/VpnDialogs/res/values-lt/strings.xml
@@ -26,6 +26,5 @@
     <string name="duration" msgid="3584782459928719435">"Trukmė:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Išsiųsta"</string>
     <string name="data_received" msgid="4062776929376067820">"Gauta"</string>
-    <string name="blank_value" msgid="6278484582661984635">"--"</string>
     <string name="data_value_format" msgid="2192466557826897580">"Baitų: <xliff:g id="NUMBER_0">%1$s</xliff:g> baitų / paketų: <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-lv/strings.xml b/packages/VpnDialogs/res/values-lv/strings.xml
index 2e1a9f7c..2f41747 100644
--- a/packages/VpnDialogs/res/values-lv/strings.xml
+++ b/packages/VpnDialogs/res/values-lv/strings.xml
@@ -26,6 +26,5 @@
     <string name="duration" msgid="3584782459928719435">"Ilgums:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Nosūtīts:"</string>
     <string name="data_received" msgid="4062776929376067820">"Saņemts:"</string>
-    <string name="blank_value" msgid="6278484582661984635">"—"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> baiti/<xliff:g id="NUMBER_1">%2$s</xliff:g> paketes"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-ms/strings.xml b/packages/VpnDialogs/res/values-ms/strings.xml
index f17d851..417fbae 100644
--- a/packages/VpnDialogs/res/values-ms/strings.xml
+++ b/packages/VpnDialogs/res/values-ms/strings.xml
@@ -26,6 +26,5 @@
     <string name="duration" msgid="3584782459928719435">"Tempoh:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Dihantar:"</string>
     <string name="data_received" msgid="4062776929376067820">"Diterima:"</string>
-    <string name="blank_value" msgid="6278484582661984635">"--"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> bait / <xliff:g id="NUMBER_1">%2$s</xliff:g> bingkisan"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-nb/strings.xml b/packages/VpnDialogs/res/values-nb/strings.xml
index fbd9185..f716422 100644
--- a/packages/VpnDialogs/res/values-nb/strings.xml
+++ b/packages/VpnDialogs/res/values-nb/strings.xml
@@ -26,6 +26,5 @@
     <string name="duration" msgid="3584782459928719435">"Varighet:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Sendt:"</string>
     <string name="data_received" msgid="4062776929376067820">"Mottatt:"</string>
-    <string name="blank_value" msgid="6278484582661984635">"–"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> byte / <xliff:g id="NUMBER_1">%2$s</xliff:g> pakker"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-nl/strings.xml b/packages/VpnDialogs/res/values-nl/strings.xml
index 7f6e0b1..795071e 100644
--- a/packages/VpnDialogs/res/values-nl/strings.xml
+++ b/packages/VpnDialogs/res/values-nl/strings.xml
@@ -26,6 +26,5 @@
     <string name="duration" msgid="3584782459928719435">"Duur:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Verzonden:"</string>
     <string name="data_received" msgid="4062776929376067820">"Ontvangen:"</string>
-    <string name="blank_value" msgid="6278484582661984635">"--"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> bytes/<xliff:g id="NUMBER_1">%2$s</xliff:g> pakketten"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-pl/strings.xml b/packages/VpnDialogs/res/values-pl/strings.xml
index 80c5a7c..a918162 100644
--- a/packages/VpnDialogs/res/values-pl/strings.xml
+++ b/packages/VpnDialogs/res/values-pl/strings.xml
@@ -26,6 +26,5 @@
     <string name="duration" msgid="3584782459928719435">"Czas trwania:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Wysłano:"</string>
     <string name="data_received" msgid="4062776929376067820">"Odebrano:"</string>
-    <string name="blank_value" msgid="6278484582661984635">"–"</string>
     <string name="data_value_format" msgid="2192466557826897580">"Bajty: <xliff:g id="NUMBER_0">%1$s</xliff:g> / pakiety: <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-pt-rPT/strings.xml b/packages/VpnDialogs/res/values-pt-rPT/strings.xml
index e25ef66..007cd51 100644
--- a/packages/VpnDialogs/res/values-pt-rPT/strings.xml
+++ b/packages/VpnDialogs/res/values-pt-rPT/strings.xml
@@ -26,6 +26,5 @@
     <string name="duration" msgid="3584782459928719435">"Duração:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Enviados:"</string>
     <string name="data_received" msgid="4062776929376067820">"Recebidos:"</string>
-    <string name="blank_value" msgid="6278484582661984635">"-"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> bytes / <xliff:g id="NUMBER_1">%2$s</xliff:g> pacotes"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-pt/strings.xml b/packages/VpnDialogs/res/values-pt/strings.xml
index 8a16e87..07c8482 100644
--- a/packages/VpnDialogs/res/values-pt/strings.xml
+++ b/packages/VpnDialogs/res/values-pt/strings.xml
@@ -26,6 +26,5 @@
     <string name="duration" msgid="3584782459928719435">"Duração:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Enviado:"</string>
     <string name="data_received" msgid="4062776929376067820">"Recebido:"</string>
-    <string name="blank_value" msgid="6278484582661984635">"-"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> bytes/<xliff:g id="NUMBER_1">%2$s</xliff:g> pacotes"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-ro/strings.xml b/packages/VpnDialogs/res/values-ro/strings.xml
index 5b71cfa..fbc0d808 100644
--- a/packages/VpnDialogs/res/values-ro/strings.xml
+++ b/packages/VpnDialogs/res/values-ro/strings.xml
@@ -26,6 +26,5 @@
     <string name="duration" msgid="3584782459928719435">"Durată:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Trimise:"</string>
     <string name="data_received" msgid="4062776929376067820">"Primite:"</string>
-    <string name="blank_value" msgid="6278484582661984635">"-"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> (de) octeţi/<xliff:g id="NUMBER_1">%2$s</xliff:g> (de) pachete"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-ru/strings.xml b/packages/VpnDialogs/res/values-ru/strings.xml
index 411c51a..b65e9d3 100644
--- a/packages/VpnDialogs/res/values-ru/strings.xml
+++ b/packages/VpnDialogs/res/values-ru/strings.xml
@@ -26,6 +26,5 @@
     <string name="duration" msgid="3584782459928719435">"Продолжительность:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Отправлено:"</string>
     <string name="data_received" msgid="4062776929376067820">"Получено:"</string>
-    <string name="blank_value" msgid="6278484582661984635">"–"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> Б; пакетов: <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-sk/strings.xml b/packages/VpnDialogs/res/values-sk/strings.xml
index 733efd4..6321bc2 100644
--- a/packages/VpnDialogs/res/values-sk/strings.xml
+++ b/packages/VpnDialogs/res/values-sk/strings.xml
@@ -26,6 +26,5 @@
     <string name="duration" msgid="3584782459928719435">"Trvanie:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Odoslané:"</string>
     <string name="data_received" msgid="4062776929376067820">"Prijaté:"</string>
-    <string name="blank_value" msgid="6278484582661984635">"--"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> B/<xliff:g id="NUMBER_1">%2$s</xliff:g> paketov"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-sl/strings.xml b/packages/VpnDialogs/res/values-sl/strings.xml
index 92806fc..a93b08a 100644
--- a/packages/VpnDialogs/res/values-sl/strings.xml
+++ b/packages/VpnDialogs/res/values-sl/strings.xml
@@ -26,6 +26,5 @@
     <string name="duration" msgid="3584782459928719435">"Trajanje:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Poslano:"</string>
     <string name="data_received" msgid="4062776929376067820">"Prejeto:"</string>
-    <string name="blank_value" msgid="6278484582661984635">"-"</string>
     <string name="data_value_format" msgid="2192466557826897580">"Št. bajtov: <xliff:g id="NUMBER_0">%1$s</xliff:g>/št. paketov: <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-sr/strings.xml b/packages/VpnDialogs/res/values-sr/strings.xml
index 425ee89..10a25ef 100644
--- a/packages/VpnDialogs/res/values-sr/strings.xml
+++ b/packages/VpnDialogs/res/values-sr/strings.xml
@@ -26,6 +26,5 @@
     <string name="duration" msgid="3584782459928719435">"Трајање:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Послато:"</string>
     <string name="data_received" msgid="4062776929376067820">"Примљенo:"</string>
-    <string name="blank_value" msgid="6278484582661984635">"–"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> бајт(ов)а / <xliff:g id="NUMBER_1">%2$s</xliff:g> пакета"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-sv/strings.xml b/packages/VpnDialogs/res/values-sv/strings.xml
index 7cec26c..fdfc13f 100644
--- a/packages/VpnDialogs/res/values-sv/strings.xml
+++ b/packages/VpnDialogs/res/values-sv/strings.xml
@@ -26,6 +26,5 @@
     <string name="duration" msgid="3584782459928719435">"Längd:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Skickat:"</string>
     <string name="data_received" msgid="4062776929376067820">"Mottaget:"</string>
-    <string name="blank_value" msgid="6278484582661984635">"--"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> byte/<xliff:g id="NUMBER_1">%2$s</xliff:g> paket"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-sw/strings.xml b/packages/VpnDialogs/res/values-sw/strings.xml
index 4607728..f987aed 100644
--- a/packages/VpnDialogs/res/values-sw/strings.xml
+++ b/packages/VpnDialogs/res/values-sw/strings.xml
@@ -26,6 +26,5 @@
     <string name="duration" msgid="3584782459928719435">"Muda:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Zilizotumwa:"</string>
     <string name="data_received" msgid="4062776929376067820">"Imepokelewa:"</string>
-    <string name="blank_value" msgid="6278484582661984635">"--"</string>
     <string name="data_value_format" msgid="2192466557826897580">"baiti <xliff:g id="NUMBER_0">%1$s</xliff:g> / pakiti <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-th/strings.xml b/packages/VpnDialogs/res/values-th/strings.xml
index 2e9f6f9..0b4a31c 100644
--- a/packages/VpnDialogs/res/values-th/strings.xml
+++ b/packages/VpnDialogs/res/values-th/strings.xml
@@ -26,6 +26,5 @@
     <string name="duration" msgid="3584782459928719435">"ระยะเวลา:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"ส่งแล้ว:"</string>
     <string name="data_received" msgid="4062776929376067820">"รับแล้ว:"</string>
-    <string name="blank_value" msgid="6278484582661984635">"--"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> ไบต์/<xliff:g id="NUMBER_1">%2$s</xliff:g> แพ็คเก็ต"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-tl/strings.xml b/packages/VpnDialogs/res/values-tl/strings.xml
index 4826d8f..725a512 100644
--- a/packages/VpnDialogs/res/values-tl/strings.xml
+++ b/packages/VpnDialogs/res/values-tl/strings.xml
@@ -26,6 +26,5 @@
     <string name="duration" msgid="3584782459928719435">"Tagal:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Ipinadala:"</string>
     <string name="data_received" msgid="4062776929376067820">"Natanggap:"</string>
-    <string name="blank_value" msgid="6278484582661984635">"--"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> (na) byte / <xliff:g id="NUMBER_1">%2$s</xliff:g> (na) packet"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-tr/strings.xml b/packages/VpnDialogs/res/values-tr/strings.xml
index f4fd967..704a8cd 100644
--- a/packages/VpnDialogs/res/values-tr/strings.xml
+++ b/packages/VpnDialogs/res/values-tr/strings.xml
@@ -26,6 +26,5 @@
     <string name="duration" msgid="3584782459928719435">"Süre:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Gönderilen:"</string>
     <string name="data_received" msgid="4062776929376067820">"Alınan:"</string>
-    <string name="blank_value" msgid="6278484582661984635">"--"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> bayt / <xliff:g id="NUMBER_1">%2$s</xliff:g> paket"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-uk/strings.xml b/packages/VpnDialogs/res/values-uk/strings.xml
index a12bfea..b0db053 100644
--- a/packages/VpnDialogs/res/values-uk/strings.xml
+++ b/packages/VpnDialogs/res/values-uk/strings.xml
@@ -26,6 +26,5 @@
     <string name="duration" msgid="3584782459928719435">"Тривалість:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Надіслано:"</string>
     <string name="data_received" msgid="4062776929376067820">"Отримано:"</string>
-    <string name="blank_value" msgid="6278484582661984635">"–"</string>
     <string name="data_value_format" msgid="2192466557826897580">"Байтів: <xliff:g id="NUMBER_0">%1$s</xliff:g> / пакетів: <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-vi/strings.xml b/packages/VpnDialogs/res/values-vi/strings.xml
index eab3812..8cc8e71 100644
--- a/packages/VpnDialogs/res/values-vi/strings.xml
+++ b/packages/VpnDialogs/res/values-vi/strings.xml
@@ -26,6 +26,5 @@
     <string name="duration" msgid="3584782459928719435">"Thời lượng:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Đã gửi:"</string>
     <string name="data_received" msgid="4062776929376067820">"Đã nhận:"</string>
-    <string name="blank_value" msgid="6278484582661984635">"--"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> byte / <xliff:g id="NUMBER_1">%2$s</xliff:g> gói"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-zh-rCN/strings.xml b/packages/VpnDialogs/res/values-zh-rCN/strings.xml
index 24774eb..7fdb368 100644
--- a/packages/VpnDialogs/res/values-zh-rCN/strings.xml
+++ b/packages/VpnDialogs/res/values-zh-rCN/strings.xml
@@ -26,6 +26,5 @@
     <string name="duration" msgid="3584782459928719435">"时长:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"已发送:"</string>
     <string name="data_received" msgid="4062776929376067820">"已接收:"</string>
-    <string name="blank_value" msgid="6278484582661984635">"--"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> 字节/<xliff:g id="NUMBER_1">%2$s</xliff:g> 个数据包"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-zh-rTW/strings.xml b/packages/VpnDialogs/res/values-zh-rTW/strings.xml
index f7663c2..080330f 100644
--- a/packages/VpnDialogs/res/values-zh-rTW/strings.xml
+++ b/packages/VpnDialogs/res/values-zh-rTW/strings.xml
@@ -26,6 +26,5 @@
     <string name="duration" msgid="3584782459928719435">"持續時間:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"已傳送:"</string>
     <string name="data_received" msgid="4062776929376067820">"已接收:"</string>
-    <string name="blank_value" msgid="6278484582661984635">"--"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> 位元組 / <xliff:g id="NUMBER_1">%2$s</xliff:g> 個封包"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-zu/strings.xml b/packages/VpnDialogs/res/values-zu/strings.xml
index 67eeeb9..4594748 100644
--- a/packages/VpnDialogs/res/values-zu/strings.xml
+++ b/packages/VpnDialogs/res/values-zu/strings.xml
@@ -26,6 +26,5 @@
     <string name="duration" msgid="3584782459928719435">"Ubude besikhathi:"</string>
     <string name="data_transmitted" msgid="7988167672982199061">"Thunyelwe:"</string>
     <string name="data_received" msgid="4062776929376067820">"Okwamukelwe:"</string>
-    <string name="blank_value" msgid="6278484582661984635">"--"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> amaphakethe/ <xliff:g id="NUMBER_1">%2$s</xliff:g> amabhayithi"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values/strings.xml b/packages/VpnDialogs/res/values/strings.xml
index 1352e9b..3ff767a 100644
--- a/packages/VpnDialogs/res/values/strings.xml
+++ b/packages/VpnDialogs/res/values/strings.xml
@@ -48,8 +48,6 @@
     <!-- Label for the network usage of data received over VPN. [CHAR LIMIT=20] -->
     <string name="data_received">Received:</string>
 
-    <!-- Dummy string for a blank value. [CHAR LIMIT=40] -->
-    <string name="blank_value">--</string>
     <!-- Formatted string for the network usage over VPN. [CHAR LIMIT=40] -->
     <string name="data_value_format">
         <xliff:g id="number">%1$s</xliff:g> bytes /
diff --git a/packages/VpnDialogs/res/values/styles.xml b/packages/VpnDialogs/res/values/styles.xml
index e3469ec..0dda673 100644
--- a/packages/VpnDialogs/res/values/styles.xml
+++ b/packages/VpnDialogs/res/values/styles.xml
@@ -25,6 +25,5 @@
         <item name="android:gravity">center_vertical|left</item>
         <item name="android:textSize">18sp</item>
         <item name="android:textStyle">bold</item>
-        <item name="android:text">@string/blank_value</item>
     </style>
 </resources>
diff --git a/packages/VpnDialogs/src/com/android/vpndialogs/ManageDialog.java b/packages/VpnDialogs/src/com/android/vpndialogs/ManageDialog.java
index 2de0251..9999adb 100644
--- a/packages/VpnDialogs/src/com/android/vpndialogs/ManageDialog.java
+++ b/packages/VpnDialogs/src/com/android/vpndialogs/ManageDialog.java
@@ -50,6 +50,7 @@
     private TextView mDuration;
     private TextView mDataTransmitted;
     private TextView mDataReceived;
+    private boolean mDataRowsHidden;
 
     private Handler mHandler;
 
@@ -76,6 +77,7 @@
             mDuration = (TextView) view.findViewById(R.id.duration);
             mDataTransmitted = (TextView) view.findViewById(R.id.data_transmitted);
             mDataReceived = (TextView) view.findViewById(R.id.data_received);
+            mDataRowsHidden = true;
 
             if (mConfig.user.equals(VpnConfig.LEGACY_VPN)) {
                 mAlertParams.mIconId = android.R.drawable.ic_dialog_info;
@@ -140,8 +142,15 @@
                         seconds / 3600, seconds / 60 % 60, seconds % 60));
             }
 
-            String[] numbers = getStatistics();
+            String[] numbers = getNumbers();
             if (numbers != null) {
+                // First unhide the related data rows.
+                if (mDataRowsHidden) {
+                    findViewById(R.id.data_transmitted_row).setVisibility(View.VISIBLE);
+                    findViewById(R.id.data_received_row).setVisibility(View.VISIBLE);
+                    mDataRowsHidden = false;
+                }
+
                 // [1] and [2] are received data in bytes and packets.
                 mDataReceived.setText(getString(R.string.data_value_format,
                         numbers[1], numbers[2]));
@@ -155,7 +164,7 @@
         return true;
     }
 
-    private String[] getStatistics() {
+    private String[] getNumbers() {
         DataInputStream in = null;
         try {
             // See dev_seq_printf_stats() in net/core/dev.c.
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 8f35afb..1763674 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -39,6 +39,8 @@
 import android.graphics.PixelFormat;
 import android.graphics.Rect;
 import android.graphics.RectF;
+import android.media.AudioManager;
+import android.media.IAudioService;
 import android.os.BatteryManager;
 import android.os.Bundle;
 import android.os.Handler;
@@ -64,6 +66,7 @@
 import com.android.internal.telephony.ITelephony;
 import com.android.internal.widget.PointerLocationView;
 
+import android.speech.RecognizerIntent;
 import android.util.DisplayMetrics;
 import android.util.EventLog;
 import android.util.Log;
@@ -133,8 +136,6 @@
 import android.view.accessibility.AccessibilityEvent;
 import android.view.animation.Animation;
 import android.view.animation.AnimationUtils;
-import android.media.IAudioService;
-import android.media.AudioManager;
 
 import java.io.File;
 import java.io.FileDescriptor;
@@ -176,6 +177,7 @@
     static final int LONG_PRESS_HOME_NOTHING = 0;
     static final int LONG_PRESS_HOME_RECENT_DIALOG = 1;
     static final int LONG_PRESS_HOME_RECENT_SYSTEM_UI = 2;
+    static final int LONG_PRESS_HOME_VOICE_SEARCH = 3;
 
     // wallpaper is at the bottom, though the window manager may move it.
     static final int WALLPAPER_LAYER = 2;
@@ -710,6 +712,9 @@
                     mLongPressOnHomeBehavior > LONG_PRESS_HOME_RECENT_SYSTEM_UI) {
                 mLongPressOnHomeBehavior = LONG_PRESS_HOME_NOTHING;
             }
+            if (hasNavigationBar()) {
+                mLongPressOnHomeBehavior = LONG_PRESS_HOME_VOICE_SEARCH;
+            }
         }
 
         if (mLongPressOnHomeBehavior != LONG_PRESS_HOME_NOTHING) {
@@ -729,6 +734,18 @@
             } catch (RemoteException e) {
                 Slog.e(TAG, "RemoteException when showing recent apps", e);
             }
+        } else if (mLongPressOnHomeBehavior == LONG_PRESS_HOME_VOICE_SEARCH) {
+            Intent intent = new Intent(RecognizerIntent.ACTION_WEB_SEARCH);
+            try {
+                intent.setFlags(
+                    Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
+                mContext.startActivity(intent);
+            } catch (ActivityNotFoundException e) {
+                Log.e(TAG, "Unable to launch. tag=" + TAG + " intent=" + intent, e);
+            } catch (SecurityException e) {
+                Log.e(TAG, "PhoneWindowManager does not have the permission to launch " +
+                      "tag=" + TAG + " intent=" + intent, e);
+            }
         }
     }
 
diff --git a/services/audioflinger/Android.mk b/services/audioflinger/Android.mk
index 22fa752..86692e7 100644
--- a/services/audioflinger/Android.mk
+++ b/services/audioflinger/Android.mk
@@ -7,7 +7,6 @@
     AudioMixer.cpp.arm          \
     AudioResampler.cpp.arm      \
     AudioPolicyService.cpp      \
-    AudioBufferProvider.cpp     \
     ServiceUtilities.cpp
 #   AudioResamplerSinc.cpp.arm
 #   AudioResamplerCubic.cpp.arm
diff --git a/services/audioflinger/AudioBufferProvider.cpp b/services/audioflinger/AudioBufferProvider.cpp
deleted file mode 100644
index 678fd58..0000000
--- a/services/audioflinger/AudioBufferProvider.cpp
+++ /dev/null
@@ -1,28 +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.
- */
-
-#undef __STRICT_ANSI__
-#define __STDINT_LIMITS
-#define __STDC_LIMIT_MACROS
-#include <stdint.h>
-
-#include "AudioBufferProvider.h"
-
-namespace android {
-
-const int64_t AudioBufferProvider::kInvalidPTS = INT64_MAX;
-
-}; // namespace android
diff --git a/services/audioflinger/AudioBufferProvider.h b/services/audioflinger/AudioBufferProvider.h
index 62ad6bd..43e4de7 100644
--- a/services/audioflinger/AudioBufferProvider.h
+++ b/services/audioflinger/AudioBufferProvider.h
@@ -17,8 +17,6 @@
 #ifndef ANDROID_AUDIO_BUFFER_PROVIDER_H
 #define ANDROID_AUDIO_BUFFER_PROVIDER_H
 
-#include <stdint.h>
-#include <sys/types.h>
 #include <utils/Errors.h>
 
 namespace android {
@@ -29,6 +27,7 @@
 public:
 
     struct Buffer {
+        Buffer() : raw(NULL), frameCount(0) { }
         union {
             void*       raw;
             short*      i16;
@@ -40,12 +39,12 @@
     virtual ~AudioBufferProvider() {}
 
     // value representing an invalid presentation timestamp
-    static const int64_t kInvalidPTS;
+    static const int64_t kInvalidPTS = 0x7FFFFFFFFFFFFFFFLL;    // <stdint.h> is too painful
 
     // pts is the local time when the next sample yielded by getNextBuffer
     // will be rendered.
     // Pass kInvalidPTS if the PTS is unknown or not applicable.
-    virtual status_t getNextBuffer(Buffer* buffer, int64_t pts) = 0;
+    virtual status_t getNextBuffer(Buffer* buffer, int64_t pts = kInvalidPTS) = 0;
 
     virtual void releaseBuffer(Buffer* buffer) = 0;
 };
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 6256951..8f7b35c 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -232,7 +232,7 @@
             (NO_ERROR != dev->set_master_volume(dev, initialVolume))) {
             mMasterVolumeSupportLvl = MVS_NONE;
         }
-        mHardwareStatus = AUDIO_HW_INIT;
+        mHardwareStatus = AUDIO_HW_IDLE;
     }
 
     // Set the mode for each audio HAL, and try to set the initial volume (if
@@ -254,7 +254,7 @@
                 dev->set_master_volume(dev, initialVolume);
             }
 
-            mHardwareStatus = AUDIO_HW_INIT;
+            mHardwareStatus = AUDIO_HW_IDLE;
         }
     }
 
@@ -432,6 +432,7 @@
         audio_format_t format,
         uint32_t channelMask,
         int frameCount,
+        // FIXME dead, remove from IAudioFlinger
         uint32_t flags,
         const sp<IMemory>& sharedBuffer,
         audio_io_handle_t output,
@@ -822,8 +823,6 @@
 
 status_t AudioFlinger::setParameters(audio_io_handle_t ioHandle, const String8& keyValuePairs)
 {
-    status_t result;
-
     ALOGV("setParameters(): io %d, keyvalue %s, tid %d, calling pid %d",
             ioHandle, keyValuePairs.string(), gettid(), IPCThreadState::self()->getCallingPid());
     // check calling permissions
@@ -833,15 +832,17 @@
 
     // ioHandle == 0 means the parameters are global to the audio hardware interface
     if (ioHandle == 0) {
-        AutoMutex lock(mHardwareLock);
-        mHardwareStatus = AUDIO_SET_PARAMETER;
         status_t final_result = NO_ERROR;
+        {
+        AutoMutex lock(mHardwareLock);
+        mHardwareStatus = AUDIO_HW_SET_PARAMETER;
         for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
             audio_hw_device_t *dev = mAudioHwDevs[i];
-            result = dev->set_parameters(dev, keyValuePairs.string());
+            status_t result = dev->set_parameters(dev, keyValuePairs.string());
             final_result = result ?: final_result;
         }
         mHardwareStatus = AUDIO_HW_IDLE;
+        }
         // disable AEC and NS if the device is a BT SCO headset supporting those pre processings
         AudioParameter param = AudioParameter(keyValuePairs);
         String8 value;
@@ -904,8 +905,14 @@
         String8 out_s8;
 
         for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
+            char *s;
+            {
+            AutoMutex lock(mHardwareLock);
+            mHardwareStatus = AUDIO_HW_GET_PARAMETER;
             audio_hw_device_t *dev = mAudioHwDevs[i];
-            char *s = dev->get_parameters(dev, keys.string());
+            s = dev->get_parameters(dev, keys.string());
+            mHardwareStatus = AUDIO_HW_IDLE;
+            }
             out_s8 += String8(s ? s : "");
             free(s);
         }
@@ -967,7 +974,7 @@
     }
 
     AutoMutex lock(mHardwareLock);
-    mHardwareStatus = AUDIO_SET_VOICE_VOLUME;
+    mHardwareStatus = AUDIO_HW_SET_VOICE_VOLUME;
     ret = mPrimaryHardwareDev->set_voice_volume(mPrimaryHardwareDev, value);
     mHardwareStatus = AUDIO_HW_IDLE;
 
@@ -1022,12 +1029,7 @@
 {
     Mutex::Autolock _l(mLock);
 
-    ssize_t index = mNotificationClients.indexOfKey(pid);
-    if (index >= 0) {
-        sp <NotificationClient> client = mNotificationClients.valueFor(pid);
-        ALOGV("removeNotificationClient() %p, pid %d", client.get(), pid);
-        mNotificationClients.removeItem(pid);
-    }
+    mNotificationClients.removeItem(pid);
 
     ALOGV("%d died, releasing its sessions", pid);
     size_t num = mAudioSessionRefs.size();
@@ -1462,7 +1464,7 @@
         mMasterVolume(audioFlinger->masterVolumeSW_l()),
         mLastWriteTime(0), mNumWrites(0), mNumDelayedWrites(0), mInWrite(false)
 {
-    snprintf(mName, kNameLength, "AudioOut_%d", id);
+    snprintf(mName, kNameLength, "AudioOut_%X", id);
 
     readOutputParameters();
 
@@ -1932,12 +1934,71 @@
     delete mAudioMixer;
 }
 
+class CpuStats {
+public:
+    void sample();
+#ifdef DEBUG_CPU_USAGE
+private:
+    ThreadCpuUsage mCpu;
+#endif
+};
+
+void CpuStats::sample() {
+#ifdef DEBUG_CPU_USAGE
+    const CentralTendencyStatistics& stats = mCpu.statistics();
+    mCpu.sampleAndEnable();
+    unsigned n = stats.n();
+    // mCpu.elapsed() is expensive, so don't call it every loop
+    if ((n & 127) == 1) {
+        long long elapsed = mCpu.elapsed();
+        if (elapsed >= DEBUG_CPU_USAGE * 1000000000LL) {
+            double perLoop = elapsed / (double) n;
+            double perLoop100 = perLoop * 0.01;
+            double mean = stats.mean();
+            double stddev = stats.stddev();
+            double minimum = stats.minimum();
+            double maximum = stats.maximum();
+            mCpu.resetStatistics();
+            ALOGI("CPU usage over past %.1f secs (%u mixer loops at %.1f mean ms per loop):\n  us per mix loop: mean=%.0f stddev=%.0f min=%.0f max=%.0f\n  %% of wall: mean=%.1f stddev=%.1f min=%.1f max=%.1f",
+                    elapsed * .000000001, n, perLoop * .000001,
+                    mean * .001,
+                    stddev * .001,
+                    minimum * .001,
+                    maximum * .001,
+                    mean / perLoop100,
+                    stddev / perLoop100,
+                    minimum / perLoop100,
+                    maximum / perLoop100);
+        }
+    }
+#endif
+};
+
+void AudioFlinger::PlaybackThread::checkSilentMode_l()
+{
+    if (!mMasterMute) {
+        char value[PROPERTY_VALUE_MAX];
+        if (property_get("ro.audio.silent", value, "0") > 0) {
+            char *endptr;
+            unsigned long ul = strtoul(value, &endptr, 0);
+            if (*endptr == '\0' && ul != 0) {
+                ALOGD("Silence is golden");
+                // The setprop command will not allow a property to be changed after
+                // the first time it is set, so we don't have to worry about un-muting.
+                setMasterMute_l(true);
+            }
+        }
+    }
+}
+
 bool AudioFlinger::MixerThread::threadLoop()
 {
+    // DirectOutputThread has single trackToRemove instead of Vector
     Vector< sp<Track> > tracksToRemove;
-    mixer_state mixerStatus = MIXER_IDLE;
+    // DirectOutputThread has activeTrack here
     nsecs_t standbyTime = systemTime();
     size_t mixBufferSize = mFrameCount * mFrameSize;
+
     // FIXME: Relaxed timing because of a certain device that can't meet latency
     // Should be reduced to 2x after the vendor fixes the driver issue
     // increase threshold again due to low power audio mode. The way this warning threshold is
@@ -1945,78 +2006,58 @@
     nsecs_t maxPeriod = seconds(mFrameCount) / mSampleRate * 15;
     nsecs_t lastWarning = 0;
     bool longStandbyExit = false;
+
     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;
-    const CentralTendencyStatistics& stats = cpu.statistics();
-#endif
+    CpuStats cpuStats;
+
+    // DirectOutputThread has shorter standbyDelay
 
     acquireWakeLock();
 
     while (!exitPending())
     {
-#ifdef DEBUG_CPU_USAGE
-        cpu.sampleAndEnable();
-        unsigned n = stats.n();
-        // cpu.elapsed() is expensive, so don't call it every loop
-        if ((n & 127) == 1) {
-            long long elapsed = cpu.elapsed();
-            if (elapsed >= DEBUG_CPU_USAGE * 1000000000LL) {
-                double perLoop = elapsed / (double) n;
-                double perLoop100 = perLoop * 0.01;
-                double mean = stats.mean();
-                double stddev = stats.stddev();
-                double minimum = stats.minimum();
-                double maximum = stats.maximum();
-                cpu.resetStatistics();
-                ALOGI("CPU usage over past %.1f secs (%u mixer loops at %.1f mean ms per loop):\n  us per mix loop: mean=%.0f stddev=%.0f min=%.0f max=%.0f\n  %% of wall: mean=%.1f stddev=%.1f min=%.1f max=%.1f",
-                        elapsed * .000000001, n, perLoop * .000001,
-                        mean * .001,
-                        stddev * .001,
-                        minimum * .001,
-                        maximum * .001,
-                        mean / perLoop100,
-                        stddev / perLoop100,
-                        minimum / perLoop100,
-                        maximum / perLoop100);
-            }
-        }
-#endif
+        cpuStats.sample();
+
+        // DirectOutputThread has rampVolume, leftVol, rightVol
+
+        Vector< sp<EffectChain> > effectChains;
+
         processConfigEvents();
 
-        mixerStatus = MIXER_IDLE;
+        mixer_state mixerStatus = MIXER_IDLE;
         { // scope for mLock
 
             Mutex::Autolock _l(mLock);
 
             if (checkForNewParameters_l()) {
                 mixBufferSize = mFrameCount * mFrameSize;
+
                 // FIXME: Relaxed timing because of a certain device that can't meet latency
                 // Should be reduced to 2x after the vendor fixes the driver issue
                 // increase threshold again due to low power audio mode. The way this warning
                 // threshold is calculated and its usefulness should be reconsidered anyway.
                 maxPeriod = seconds(mFrameCount) / mSampleRate * 15;
+
                 activeSleepTime = activeSleepTimeUs();
                 idleSleepTime = idleSleepTimeUs();
+                // DirectOutputThread updates standbyDelay also
             }
 
-            const SortedVector< wp<Track> >& activeTracks = mActiveTracks;
-
             // put audio hardware into standby after short delay
-            if (CC_UNLIKELY((!activeTracks.size() && systemTime() > standbyTime) ||
-                        mSuspended)) {
+            if (CC_UNLIKELY((!mActiveTracks.size() && systemTime() > standbyTime) ||
+                        mSuspended > 0)) {
                 if (!mStandby) {
-                    ALOGV("Audio hardware entering standby, mixer %p, mSuspended %d", this, mSuspended);
+                    ALOGV("Audio hardware entering standby, mixer %p, suspend count %u", this, mSuspended);
                     mOutput->stream->common.standby(&mOutput->stream->common);
                     mStandby = true;
                     mBytesWritten = 0;
                 }
 
-                if (!activeTracks.size() && mConfigEvents.isEmpty()) {
+                if (!mActiveTracks.size() && mConfigEvents.isEmpty()) {
                     // we're about to wait, flush the binder command buffer
                     IPCThreadState::self()->flushCommands();
 
@@ -2024,20 +2065,13 @@
 
                     releaseWakeLock_l();
                     // wait until we have something to do...
-                    ALOGV("MixerThread %p TID %d going to sleep", this, gettid());
+                    ALOGV("Thread %p type %d TID %d going to sleep", this, mType, gettid());
                     mWaitWorkCV.wait(mLock);
-                    ALOGV("MixerThread %p TID %d waking up", this, gettid());
+                    ALOGV("Thread %p type %d TID %d waking up", this, mType, gettid());
                     acquireWakeLock_l();
 
                     mPrevMixerStatus = MIXER_IDLE;
-                    if (!mMasterMute) {
-                        char value[PROPERTY_VALUE_MAX];
-                        property_get("ro.audio.silent", value, "0");
-                        if (atoi(value)) {
-                            ALOGD("Silence is golden");
-                            setMasterMute_l(true);
-                        }
-                    }
+                    checkSilentMode_l();
 
                     standbyTime = systemTime() + mStandbyTimeInNsecs;
                     sleepTime = idleSleepTime;
@@ -2046,7 +2080,7 @@
                 }
             }
 
-            mixerStatus = prepareTracks_l(activeTracks, &tracksToRemove);
+            mixerStatus = prepareTracks_l(&tracksToRemove);
 
             // prevent any changes in effect chain list and in each effect chain
             // during mixing and effect process as the audio buffers could be deleted
@@ -2108,24 +2142,35 @@
             // TODO add standby time extension fct of effect tail
         }
 
-        if (mSuspended) {
+        if (mSuspended > 0) {
             sleepTime = suspendSleepTimeUs();
         }
-        // sleepTime == 0 means we must write to audio hardware
+
+        // only process effects if we're going to write
         if (sleepTime == 0) {
+
+            // DirectOutputThread adds applyVolume here
+
             for (size_t i = 0; i < effectChains.size(); i ++) {
                 effectChains[i]->process_l();
             }
-            // enable changes in effect chain
-            unlockEffectChains(effectChains);
+        }
+
+        // enable changes in effect chain
+        unlockEffectChains(effectChains);
+
+        // sleepTime == 0 means we must write to audio hardware
+        if (sleepTime == 0) {
+            // FIXME Only in MixerThread, and rewrite to reduce number of system calls
             mLastWriteTime = systemTime();
             mInWrite = true;
             mBytesWritten += mixBufferSize;
-
             int bytesWritten = (int)mOutput->stream->write(mOutput->stream, mMixBuffer, mixBufferSize);
             if (bytesWritten < 0) mBytesWritten -= mixBufferSize;
             mNumWrites++;
             mInWrite = false;
+
+            // Only in MixerThread: start of write blocked detection
             nsecs_t now = systemTime();
             nsecs_t delta = now - mLastWriteTime;
             if (!mStandby && delta > maxPeriod) {
@@ -2139,14 +2184,14 @@
                     longStandbyExit = true;
                 }
             }
+            // end of write blocked detection
+
             mStandby = false;
         } else {
-            // enable changes in effect chain
-            unlockEffectChains(effectChains);
             usleep(sleepTime);
         }
 
-        // finally let go of all our tracks, without the lock held
+        // finally let go of removed track(s), without the lock held
         // since we can't guarantee the destructors won't acquire that
         // same lock.
         tracksToRemove.clear();
@@ -2154,26 +2199,30 @@
         // Effect chains will be actually deleted here if they were removed from
         // mEffectChains list during mixing or effects processing
         effectChains.clear();
+
+        // FIXME Note that the above .clear() is no longer necessary since effectChains
+        // is now local to this block, but will keep it for now (at least until merge done).
     }
 
+    // put output stream into standby mode
     if (!mStandby) {
         mOutput->stream->common.standby(&mOutput->stream->common);
     }
 
     releaseWakeLock();
 
-    ALOGV("MixerThread %p exiting", this);
+    ALOGV("Thread %p type %d exiting", this, mType);
     return false;
 }
 
 // prepareTracks_l() must be called with ThreadBase::mLock held
 AudioFlinger::PlaybackThread::mixer_state AudioFlinger::MixerThread::prepareTracks_l(
-        const SortedVector< wp<Track> >& activeTracks, Vector< sp<Track> > *tracksToRemove)
+        Vector< sp<Track> > *tracksToRemove)
 {
 
     mixer_state mixerStatus = MIXER_IDLE;
     // find out which tracks need to be processed
-    size_t count = activeTracks.size();
+    size_t count = mActiveTracks.size();
     size_t mixedTracks = 0;
     size_t tracksWithEffect = 0;
 
@@ -2193,7 +2242,7 @@
     }
 
     for (size_t i=0 ; i<count ; i++) {
-        sp<Track> t = activeTracks[i].promote();
+        sp<Track> t = mActiveTracks[i].promote();
         if (t == 0) continue;
 
         // this const just means the local variable doesn't change
@@ -2680,14 +2729,20 @@
 
 bool AudioFlinger::DirectOutputThread::threadLoop()
 {
-    mixer_state mixerStatus = MIXER_IDLE;
+    // MixerThread has Vector instead of single trackToRemove
     sp<Track> trackToRemove;
-    sp<Track> activeTrack;
+
     nsecs_t standbyTime = systemTime();
-    size_t mixBufferSize = mFrameCount*mFrameSize;
+    size_t mixBufferSize = mFrameCount * mFrameSize;
+
+    // MixerThread has relaxed timing: maxPeriod, lastWarning, longStandbyExit
+
     uint32_t activeSleepTime = activeSleepTimeUs();
     uint32_t idleSleepTime = idleSleepTimeUs();
     uint32_t sleepTime = idleSleepTime;
+
+    // MixerThread has sleepTimeShift and cpuStats
+
     // use shorter standby delay as on normal output to release
     // hardware resources as soon as possible
     nsecs_t standbyDelay = microseconds(activeSleepTime*2);
@@ -2696,21 +2751,30 @@
 
     while (!exitPending())
     {
+        // MixerThread has cpuStats.sample()
+
         bool rampVolume;
         uint16_t leftVol;
         uint16_t rightVol;
+
         Vector< sp<EffectChain> > effectChains;
 
         processConfigEvents();
 
-        mixerStatus = MIXER_IDLE;
+        // MixerThread does not have activeTrack here
+        sp<Track> activeTrack;
 
+        mixer_state mixerStatus = MIXER_IDLE;
         { // scope for the mLock
 
             Mutex::Autolock _l(mLock);
 
             if (checkForNewParameters_l()) {
-                mixBufferSize = mFrameCount*mFrameSize;
+                mixBufferSize = mFrameCount * mFrameSize;
+
+                // different calculations here
+                standbyDelay = microseconds(activeSleepTime*2);
+
                 activeSleepTime = activeSleepTimeUs();
                 idleSleepTime = idleSleepTimeUs();
                 standbyDelay = microseconds(activeSleepTime*2);
@@ -2718,10 +2782,9 @@
 
             // put audio hardware into standby after short delay
             if (CC_UNLIKELY((!mActiveTracks.size() && systemTime() > standbyTime) ||
-                        mSuspended)) {
-                // wait until we have something to do...
+                        mSuspended > 0)) {
                 if (!mStandby) {
-                    ALOGV("Audio hardware entering standby, mixer %p", this);
+                    ALOGV("Audio hardware entering standby, mixer %p, suspend count %u", this, mSuspended);
                     mOutput->stream->common.standby(&mOutput->stream->common);
                     mStandby = true;
                     mBytesWritten = 0;
@@ -2734,26 +2797,27 @@
                     if (exitPending()) break;
 
                     releaseWakeLock_l();
-                    ALOGV("DirectOutputThread %p TID %d going to sleep", this, gettid());
+                    // wait until we have something to do...
+                    ALOGV("Thread %p type %d TID %d going to sleep", this, mType, gettid());
                     mWaitWorkCV.wait(mLock);
-                    ALOGV("DirectOutputThread %p TID %d waking up in active mode", this, gettid());
+                    ALOGV("Thread %p type %d TID %d waking up", this, mType, gettid());
                     acquireWakeLock_l();
 
-                    if (!mMasterMute) {
-                        char value[PROPERTY_VALUE_MAX];
-                        property_get("ro.audio.silent", value, "0");
-                        if (atoi(value)) {
-                            ALOGD("Silence is golden");
-                            setMasterMute_l(true);
-                        }
-                    }
+                    // MixerThread has "mPrevMixerStatus = MIXER_IDLE"
+                    checkSilentMode_l();
 
+                    // MixerThread has different standbyDelay
                     standbyTime = systemTime() + standbyDelay;
                     sleepTime = idleSleepTime;
+                    // MixerThread has "sleepTimeShift = 0"
                     continue;
                 }
             }
 
+            // MixerThread has "mixerStatus = prepareTracks_l(...)"
+
+            // equivalent to MixerThread's lockEffectChains_l, but without the lock
+            // FIXME - is it OK to omit the lock here?
             effectChains = mEffectChains;
 
             // find out which tracks need to be processed
@@ -2884,6 +2948,7 @@
             lockEffectChains_l(effectChains);
        }
 
+        // For DirectOutputThread, this test is equivalent to "activeTrack != 0"
         if (CC_LIKELY(mixerStatus == MIXER_TRACKS_READY)) {
             AudioBufferProvider::Buffer buffer;
             size_t frameCount = mFrameCount;
@@ -2891,8 +2956,7 @@
             // output audio to hardware
             while (frameCount) {
                 buffer.frameCount = frameCount;
-                activeTrack->getNextBuffer(&buffer,
-                                           AudioBufferProvider::kInvalidPTS);
+                activeTrack->getNextBuffer(&buffer);
                 if (CC_UNLIKELY(buffer.raw == NULL)) {
                     memset(curBuf, 0, frameCount * mFrameSize);
                     break;
@@ -2917,19 +2981,28 @@
             }
         }
 
-        if (mSuspended) {
+        if (mSuspended > 0) {
             sleepTime = suspendSleepTimeUs();
         }
-        // sleepTime == 0 means we must write to audio hardware
+
+        // only process effects if we're going to write
         if (sleepTime == 0) {
+
+            // MixerThread does not have applyVolume
             if (mixerStatus == MIXER_TRACKS_READY) {
                 applyVolume(leftVol, rightVol, rampVolume);
             }
+
             for (size_t i = 0; i < effectChains.size(); i ++) {
                 effectChains[i]->process_l();
             }
-            unlockEffectChains(effectChains);
+        }
 
+        // enable changes in effect chain
+        unlockEffectChains(effectChains);
+
+        // sleepTime == 0 means we must write to audio hardware
+        if (sleepTime == 0) {
             mLastWriteTime = systemTime();
             mInWrite = true;
             mBytesWritten += mixBufferSize;
@@ -2937,13 +3010,15 @@
             if (bytesWritten < 0) mBytesWritten -= mixBufferSize;
             mNumWrites++;
             mInWrite = false;
+
+            // MixerThread has write blocked detection here
+
             mStandby = false;
         } else {
-            unlockEffectChains(effectChains);
             usleep(sleepTime);
         }
 
-        // finally let go of removed track, without the lock held
+        // finally let go of removed track(s), without the lock held
         // since we can't guarantee the destructors won't acquire that
         // same lock.
         trackToRemove.clear();
@@ -2952,15 +3027,19 @@
         // Effect chains will be actually deleted here if they were removed from
         // mEffectChains list during mixing or effects processing
         effectChains.clear();
+
+        // FIXME Note that the above .clear() is no longer necessary since effectChains
+        // is now local to this block, but will keep it for now (at least until merge done).
     }
 
+    // put output stream into standby mode
     if (!mStandby) {
         mOutput->stream->common.standby(&mOutput->stream->common);
     }
 
     releaseWakeLock();
 
-    ALOGV("DirectOutputThread %p exiting", this);
+    ALOGV("Thread %p type %d exiting", this, mType);
     return false;
 }
 
@@ -3077,44 +3156,52 @@
 bool AudioFlinger::DuplicatingThread::threadLoop()
 {
     Vector< sp<Track> > tracksToRemove;
-    mixer_state mixerStatus = MIXER_IDLE;
     nsecs_t standbyTime = systemTime();
-    size_t mixBufferSize = mFrameCount*mFrameSize;
+    size_t mixBufferSize = mFrameCount * mFrameSize;
+
+    // Only in DuplicatingThread
     SortedVector< sp<OutputTrack> > outputTracks;
     uint32_t writeFrames = 0;
+
     uint32_t activeSleepTime = activeSleepTimeUs();
     uint32_t idleSleepTime = idleSleepTimeUs();
     uint32_t sleepTime = idleSleepTime;
-    Vector< sp<EffectChain> > effectChains;
 
     acquireWakeLock();
 
     while (!exitPending())
     {
+        // MixerThread has cpuStats.sample
+
+        Vector< sp<EffectChain> > effectChains;
+
         processConfigEvents();
 
-        mixerStatus = MIXER_IDLE;
+        mixer_state mixerStatus = MIXER_IDLE;
         { // scope for the mLock
 
             Mutex::Autolock _l(mLock);
 
             if (checkForNewParameters_l()) {
-                mixBufferSize = mFrameCount*mFrameSize;
+                mixBufferSize = mFrameCount * mFrameSize;
+
+                // Only in DuplicatingThread
                 updateWaitTime();
+
                 activeSleepTime = activeSleepTimeUs();
                 idleSleepTime = idleSleepTimeUs();
             }
 
-            const SortedVector< wp<Track> >& activeTracks = mActiveTracks;
-
+            // Only in DuplicatingThread
             for (size_t i = 0; i < mOutputTracks.size(); i++) {
                 outputTracks.add(mOutputTracks[i]);
             }
 
             // put audio hardware into standby after short delay
-            if (CC_UNLIKELY((!activeTracks.size() && systemTime() > standbyTime) ||
-                         mSuspended)) {
+            if (CC_UNLIKELY((!mActiveTracks.size() && systemTime() > standbyTime) ||
+                         mSuspended > 0)) {
                 if (!mStandby) {
+                    // DuplicatingThread implements standby by stopping all tracks
                     for (size_t i = 0; i < outputTracks.size(); i++) {
                         outputTracks[i]->stop();
                     }
@@ -3122,7 +3209,7 @@
                     mBytesWritten = 0;
                 }
 
-                if (!activeTracks.size() && mConfigEvents.isEmpty()) {
+                if (!mActiveTracks.size() && mConfigEvents.isEmpty()) {
                     // we're about to wait, flush the binder command buffer
                     IPCThreadState::self()->flushCommands();
                     outputTracks.clear();
@@ -3130,28 +3217,23 @@
                     if (exitPending()) break;
 
                     releaseWakeLock_l();
-                    ALOGV("DuplicatingThread %p TID %d going to sleep", this, gettid());
+                    // wait until we have something to do...
+                    ALOGV("Thread %p type %d TID %d going to sleep", this, mType, gettid());
                     mWaitWorkCV.wait(mLock);
-                    ALOGV("DuplicatingThread %p TID %d waking up", this, gettid());
+                    ALOGV("Thread %p type %d TID %d waking up", this, mType, gettid());
                     acquireWakeLock_l();
 
-                    mPrevMixerStatus = MIXER_IDLE;
-                    if (!mMasterMute) {
-                        char value[PROPERTY_VALUE_MAX];
-                        property_get("ro.audio.silent", value, "0");
-                        if (atoi(value)) {
-                            ALOGD("Silence is golden");
-                            setMasterMute_l(true);
-                        }
-                    }
+                    // MixerThread has "mPrevMixerStatus = MIXER_IDLE"
+                    checkSilentMode_l();
 
                     standbyTime = systemTime() + mStandbyTimeInNsecs;
                     sleepTime = idleSleepTime;
+                    // MixerThread has sleepTimeShift
                     continue;
                 }
             }
 
-            mixerStatus = prepareTracks_l(activeTracks, &tracksToRemove);
+            mixerStatus = prepareTracks_l(&tracksToRemove);
 
             // prevent any changes in effect chain list and in each effect chain
             // during mixing and effect process as the audio buffers could be deleted
@@ -3159,6 +3241,7 @@
             lockEffectChains_l(effectChains);
         }
 
+        // Duplicating Thread is completely different here
         if (CC_LIKELY(mixerStatus == MIXER_TRACKS_READY)) {
             // mix buffers...
             if (outputsReady(outputTracks)) {
@@ -3188,30 +3271,36 @@
             }
         }
 
-        if (mSuspended) {
+        if (mSuspended > 0) {
             sleepTime = suspendSleepTimeUs();
         }
-        // sleepTime == 0 means we must write to audio hardware
+
+        // only process effects if we're going to write
         if (sleepTime == 0) {
             for (size_t i = 0; i < effectChains.size(); i ++) {
                 effectChains[i]->process_l();
             }
-            // enable changes in effect chain
-            unlockEffectChains(effectChains);
+        }
 
+        // enable changes in effect chain
+        unlockEffectChains(effectChains);
+
+        // sleepTime == 0 means we must write to audio hardware
+        if (sleepTime == 0) {
             standbyTime = systemTime() + mStandbyTimeInNsecs;
             for (size_t i = 0; i < outputTracks.size(); i++) {
                 outputTracks[i]->write(mMixBuffer, writeFrames);
             }
             mStandby = false;
             mBytesWritten += mixBufferSize;
+
+            // MixerThread has write blocked detection here
+
         } else {
-            // enable changes in effect chain
-            unlockEffectChains(effectChains);
             usleep(sleepTime);
         }
 
-        // finally let go of all our tracks, without the lock held
+        // finally let go of removed track(s), without the lock held
         // since we can't guarantee the destructors won't acquire that
         // same lock.
         tracksToRemove.clear();
@@ -3220,15 +3309,23 @@
         // Effect chains will be actually deleted here if they were removed from
         // mEffectChains list during mixing or effects processing
         effectChains.clear();
+
+        // FIXME Note that the above .clear() is no longer necessary since effectChains
+        // is now local to this block, but will keep it for now (at least until merge done).
     }
 
+    // MixerThread and DirectOutpuThread have standby here,
+    // but for DuplicatingThread this is handled by the outputTracks
+
     releaseWakeLock();
 
+    ALOGV("Thread %p type %d exiting", this, mType);
     return false;
 }
 
 void AudioFlinger::DuplicatingThread::addOutputTrack(MixerThread *thread)
 {
+    Mutex::Autolock _l(mLock);
     // FIXME explain this formula
     int frameCount = (3 * mFrameCount * mSampleRate) / thread->sampleRate();
     OutputTrack *outputTrack = new OutputTrack(thread,
@@ -3274,7 +3371,7 @@
 }
 
 
-bool AudioFlinger::DuplicatingThread::outputsReady(SortedVector< sp<OutputTrack> > &outputTracks)
+bool AudioFlinger::DuplicatingThread::outputsReady(const SortedVector< sp<OutputTrack> > &outputTracks)
 {
     for (size_t i = 0; i < outputTracks.size(); i++) {
         sp <ThreadBase> thread = outputTracks[i]->thread().promote();
@@ -3306,7 +3403,6 @@
             audio_format_t format,
             uint32_t channelMask,
             int frameCount,
-            uint32_t flags,
             const sp<IMemory>& sharedBuffer,
             int sessionId)
     :   RefBase(),
@@ -3318,7 +3414,7 @@
         mFrameCount(0),
         mState(IDLE),
         mFormat(format),
-        mFlags(flags & ~SYSTEM_FLAGS_MASK),
+        mStepServerFailed(false),
         mSessionId(sessionId)
         // mChannelCount
         // mChannelMask
@@ -3398,11 +3494,14 @@
     }
 }
 
+// AudioBufferProvider interface
+// getNextBuffer() = 0;
+// This implementation of releaseBuffer() is used by Track and RecordTrack, but not TimedTrack
 void AudioFlinger::ThreadBase::TrackBase::releaseBuffer(AudioBufferProvider::Buffer* buffer)
 {
     buffer->raw = NULL;
     mFrameCount = buffer->frameCount;
-    step();
+    (void) step();      // ignore return value of step()
     buffer->frameCount = 0;
 }
 
@@ -3413,7 +3512,7 @@
     result = cblk->stepServer(mFrameCount);
     if (!result) {
         ALOGV("stepServer failed acquiring cblk mutex");
-        mFlags |= STEPSERVER_FAILED;
+        mStepServerFailed = true;
     }
     return result;
 }
@@ -3425,7 +3524,7 @@
     cblk->server = 0;
     cblk->userBase = 0;
     cblk->serverBase = 0;
-    mFlags &= (uint32_t)(~SYSTEM_FLAGS_MASK);
+    mStepServerFailed = false;
     ALOGV("TrackBase::reset");
 }
 
@@ -3465,7 +3564,7 @@
             int frameCount,
             const sp<IMemory>& sharedBuffer,
             int sessionId)
-    :   TrackBase(thread, client, sampleRate, format, channelMask, frameCount, 0, sharedBuffer, sessionId),
+    :   TrackBase(thread, client, sampleRate, format, channelMask, frameCount, sharedBuffer, sessionId),
     mMute(false), mSharedBuffer(sharedBuffer), mName(-1), mMainBuffer(NULL), mAuxBuffer(NULL),
     mAuxEffectId(0), mHasVolumeController(false)
 {
@@ -3548,6 +3647,7 @@
             (int)mAuxBuffer);
 }
 
+// AudioBufferProvider interface
 status_t AudioFlinger::PlaybackThread::Track::getNextBuffer(
     AudioBufferProvider::Buffer* buffer, int64_t pts)
 {
@@ -3556,10 +3656,10 @@
      uint32_t framesReq = buffer->frameCount;
 
      // Check if last stepServer failed, try to step now
-     if (mFlags & TrackBase::STEPSERVER_FAILED) {
+     if (mStepServerFailed) {
          if (!step())  goto getNextBuffer_exit;
          ALOGV("stepServer recovered");
-         mFlags &= ~TrackBase::STEPSERVER_FAILED;
+         mStepServerFailed = false;
      }
 
      framesReady = cblk->framesReady();
@@ -4096,6 +4196,7 @@
     mTimedAudioOutputOnTime = false;
 }
 
+// AudioBufferProvider interface
 void AudioFlinger::PlaybackThread::TimedTrack::releaseBuffer(
     AudioBufferProvider::Buffer* buffer) {
 
@@ -4155,10 +4256,9 @@
             audio_format_t format,
             uint32_t channelMask,
             int frameCount,
-            uint32_t flags,
             int sessionId)
     :   TrackBase(thread, client, sampleRate, format,
-                  channelMask, frameCount, flags, 0, sessionId),
+                  channelMask, frameCount, 0 /*sharedBuffer*/, sessionId),
         mOverflow(false)
 {
     if (mCblk != NULL) {
@@ -4181,6 +4281,7 @@
     }
 }
 
+// AudioBufferProvider interface
 status_t AudioFlinger::RecordThread::RecordTrack::getNextBuffer(AudioBufferProvider::Buffer* buffer, int64_t pts)
 {
     audio_track_cblk_t* cblk = this->cblk();
@@ -4188,10 +4289,10 @@
     uint32_t framesReq = buffer->frameCount;
 
      // Check if last stepServer failed, try to step now
-    if (mFlags & TrackBase::STEPSERVER_FAILED) {
+    if (mStepServerFailed) {
         if (!step()) goto getNextBuffer_exit;
         ALOGV("stepServer recovered");
-        mFlags &= ~TrackBase::STEPSERVER_FAILED;
+        mStepServerFailed = false;
     }
 
     framesAvail = cblk->framesAvailable_l();
@@ -4654,6 +4755,7 @@
         audio_format_t format,
         uint32_t channelMask,
         int frameCount,
+        // FIXME dead, remove from IAudioFlinger
         uint32_t flags,
         int *sessionId,
         status_t *status)
@@ -4698,7 +4800,6 @@
                                                 format,
                                                 channelMask,
                                                 frameCount,
-                                                flags,
                                                 lSessionId,
                                                 &lStatus);
     }
@@ -4769,7 +4870,7 @@
     // mBytesRead is only meaningful while active, and so is cleared in start()
     // (but might be better to also clear here for dump?)
 {
-    snprintf(mName, kNameLength, "AudioIn_%d", id);
+    snprintf(mName, kNameLength, "AudioIn_%X", id);
 
     readInputParameters();
 }
@@ -4868,8 +4969,7 @@
             }
 
             buffer.frameCount = mFrameCount;
-            if (CC_LIKELY(mActiveTrack->getNextBuffer(
-                    &buffer, AudioBufferProvider::kInvalidPTS) == NO_ERROR)) {
+            if (CC_LIKELY(mActiveTrack->getNextBuffer(&buffer) == NO_ERROR)) {
                 size_t framesOut = buffer.frameCount;
                 if (mResampler == NULL) {
                     // no resampling
@@ -4992,7 +5092,6 @@
         audio_format_t format,
         int channelMask,
         int frameCount,
-        uint32_t flags,
         int sessionId,
         status_t *status)
 {
@@ -5009,7 +5108,7 @@
         Mutex::Autolock _l(mLock);
 
         track = new RecordTrack(this, client, sampleRate,
-                      format, channelMask, frameCount, flags, sessionId);
+                      format, channelMask, frameCount, sessionId);
 
         if (track->getCblk() == 0) {
             lStatus = NO_MEMORY;
@@ -5147,6 +5246,7 @@
     return NO_ERROR;
 }
 
+// AudioBufferProvider interface
 status_t AudioFlinger::RecordThread::getNextBuffer(AudioBufferProvider::Buffer* buffer, int64_t pts)
 {
     size_t framesReq = buffer->frameCount;
@@ -5185,6 +5285,7 @@
     return NO_ERROR;
 }
 
+// AudioBufferProvider interface
 void AudioFlinger::RecordThread::releaseBuffer(AudioBufferProvider::Buffer* buffer)
 {
     mRsmpInIndex += buffer->frameCount;
@@ -5429,7 +5530,6 @@
 {
     status_t status;
     PlaybackThread *thread = NULL;
-    mHardwareStatus = AUDIO_HW_OUTPUT_OPEN;
     uint32_t samplingRate = pSamplingRate ? *pSamplingRate : 0;
     audio_format_t format = pFormat ? *pFormat : AUDIO_FORMAT_DEFAULT;
     uint32_t channels = pChannels ? *pChannels : 0;
@@ -5454,8 +5554,10 @@
     if (outHwDev == NULL)
         return 0;
 
+    mHardwareStatus = AUDIO_HW_OUTPUT_OPEN;
     status = outHwDev->open_output_stream(outHwDev, *pDevices, &format,
                                           &channels, &samplingRate, &outStream);
+    mHardwareStatus = AUDIO_HW_IDLE;
     ALOGV("openOutput() openOutputStream returned output %p, SamplingRate %d, Format %d, Channels %x, status %d",
             outStream,
             samplingRate,
@@ -5463,7 +5565,6 @@
             channels,
             status);
 
-    mHardwareStatus = AUDIO_HW_IDLE;
     if (outStream != NULL) {
         AudioStreamOut *output = new AudioStreamOut(outHwDev, outStream);
         audio_io_handle_t id = nextUniqueId();
@@ -5855,7 +5956,7 @@
     return android_atomic_inc(&mNextUniqueId);
 }
 
-AudioFlinger::PlaybackThread *AudioFlinger::primaryPlaybackThread_l()
+AudioFlinger::PlaybackThread *AudioFlinger::primaryPlaybackThread_l() const
 {
     for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
         PlaybackThread *thread = mPlaybackThreads.valueAt(i).get();
@@ -5867,7 +5968,7 @@
     return NULL;
 }
 
-uint32_t AudioFlinger::primaryOutputDevice_l()
+uint32_t AudioFlinger::primaryOutputDevice_l() const
 {
     PlaybackThread *thread = primaryPlaybackThread_l();
 
@@ -6362,7 +6463,7 @@
 }
 
 void AudioFlinger::ThreadBase::unlockEffectChains(
-        Vector<sp <AudioFlinger::EffectChain> >& effectChains)
+        const Vector<sp <AudioFlinger::EffectChain> >& effectChains)
 {
     for (size_t i = 0; i < effectChains.size(); i++) {
         effectChains[i]->unlock();
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 1a52de5..bdaf97c 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -312,19 +312,12 @@
                 PAUSED
             };
 
-            enum track_flags {
-                STEPSERVER_FAILED = 0x01, //  StepServer could not acquire cblk->lock mutex
-                SYSTEM_FLAGS_MASK = 0x0000ffffUL,
-                // The upper 16 bits are used for track-specific flags.
-            };
-
                                 TrackBase(ThreadBase *thread,
                                         const sp<Client>& client,
                                         uint32_t sampleRate,
                                         audio_format_t format,
                                         uint32_t channelMask,
                                         int frameCount,
-                                        uint32_t flags,
                                         const sp<IMemory>& sharedBuffer,
                                         int sessionId);
             virtual             ~TrackBase();
@@ -346,9 +339,8 @@
                                 TrackBase(const TrackBase&);
                                 TrackBase& operator = (const TrackBase&);
 
-            virtual status_t getNextBuffer(
-                AudioBufferProvider::Buffer* buffer,
-                int64_t pts) = 0;
+            // AudioBufferProvider interface
+            virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer, int64_t pts) = 0;
             virtual void releaseBuffer(AudioBufferProvider::Buffer* buffer);
 
             audio_format_t format() const {
@@ -384,7 +376,7 @@
             // we don't really need a lock for these
             track_state         mState;
             const audio_format_t mFormat;
-            uint32_t            mFlags;
+            bool                mStepServerFailed;
             const int           mSessionId;
             uint8_t             mChannelCount;
             uint32_t            mChannelMask;
@@ -431,8 +423,8 @@
                     void        sendConfigEvent_l(int event, int param = 0);
                     void        processConfigEvents();
                     audio_io_handle_t id() const { return mId;}
-                    bool        standby() { return mStandby; }
-                    uint32_t    device() { return mDevice; }
+                    bool        standby() const { return mStandby; }
+                    uint32_t    device() const { return mDevice; }
         virtual     audio_stream_t* stream() = 0;
 
                     sp<EffectHandle> createEffect_l(
@@ -463,12 +455,13 @@
         virtual     status_t addEffectChain_l(const sp<EffectChain>& chain) = 0;
                     // remove an effect chain from the chain list (mEffectChains)
         virtual     size_t removeEffectChain_l(const sp<EffectChain>& chain) = 0;
-                    // lock mall effect chains Mutexes. Must be called before releasing the
+                    // lock all effect chains Mutexes. Must be called before releasing the
                     // ThreadBase mutex before processing the mixer and effects. This guarantees the
                     // integrity of the chains during the process.
+                    // Also sets the parameter 'effectChains' to current value of mEffectChains.
                     void lockEffectChains_l(Vector<sp <EffectChain> >& effectChains);
                     // unlock effect chains after process
-                    void unlockEffectChains(Vector<sp <EffectChain> >& effectChains);
+                    void unlockEffectChains(const Vector<sp<EffectChain> >& effectChains);
                     // set audio mode to all effect chains
                     void setMode(audio_mode_t mode);
                     // get effect module with corresponding ID on specified audio session
@@ -556,7 +549,7 @@
                     Vector< sp<EffectChain> > mEffectChains;
                     uint32_t                mDevice;    // output device for PlaybackThread
                                                         // input + output devices for RecordThread
-                    static const int        kNameLength = 32;
+                    static const int        kNameLength = 16;   // prctl(PR_SET_NAME) limit
                     char                    mName[kNameLength];
                     sp<IPowerManager>       mPowerManager;
                     sp<IBinder>             mWakeLockToken;
@@ -583,9 +576,11 @@
     public:
 
         enum mixer_state {
-            MIXER_IDLE,
-            MIXER_TRACKS_ENABLED,
-            MIXER_TRACKS_READY
+            MIXER_IDLE,             // no active tracks
+            MIXER_TRACKS_ENABLED,   // at least one active track, but no track has any data ready
+            MIXER_TRACKS_READY      // at least one active track, and at least one track has data
+            // standby mode does not have an enum value
+            // suspend by audio policy manager is orthogonal to mixer state
         };
 
         // playback track
@@ -634,9 +629,10 @@
                                 Track(const Track&);
                                 Track& operator = (const Track&);
 
-            virtual status_t getNextBuffer(
-                AudioBufferProvider::Buffer* buffer,
-                int64_t pts);
+            // AudioBufferProvider interface
+            virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer, int64_t pts = kInvalidPTS);
+            // releaseBuffer() not overridden
+
             virtual uint32_t framesReady() const;
 
             bool isMuted() const { return mMute; }
@@ -703,9 +699,10 @@
 
             virtual uint32_t framesReady() const;
 
-            virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer,
-                                           int64_t pts);
+            // AudioBufferProvider interface
+            virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer, int64_t pts);
             virtual void releaseBuffer(AudioBufferProvider::Buffer* buffer);
+
             void timedYieldSamples(AudioBufferProvider::Buffer* buffer);
             void timedYieldSilence(uint32_t numFrames,
                                    AudioBufferProvider::Buffer* buffer);
@@ -827,8 +824,8 @@
                     virtual audio_stream_t* stream();
 
                     void        suspend() { mSuspended++; }
-                    void        restore() { if (mSuspended) mSuspended--; }
-                    bool        isSuspended() const { return (mSuspended != 0); }
+                    void        restore() { if (mSuspended > 0) mSuspended--; }
+                    bool        isSuspended() const { return (mSuspended > 0); }
         virtual     String8     getParameters(const String8& keys);
         virtual     void        audioConfigChanged_l(int event, int param = 0);
         virtual     status_t    getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames);
@@ -849,7 +846,7 @@
 
     protected:
         int16_t*                        mMixBuffer;
-        int                             mSuspended;
+        uint32_t                        mSuspended;     // suspend count, > 0 means suspended
         int                             mBytesWritten;
     private:
         // mMasterMute is in both PlaybackThread and in AudioFlinger.  When a
@@ -866,6 +863,9 @@
         virtual uint32_t        idleSleepTimeUs() = 0;
         virtual uint32_t        suspendSleepTimeUs() = 0;
 
+        // Code snippets that are temporarily lifted up out of threadLoop() until the merge
+                    void        checkSilentMode_l();
+
     private:
 
         friend class AudioFlinger;
@@ -916,8 +916,11 @@
         virtual     status_t    dumpInternals(int fd, const Vector<String16>& args);
 
     protected:
-                    mixer_state prepareTracks_l(const SortedVector< wp<Track> >& activeTracks,
-                                                Vector< sp<Track> > *tracksToRemove);
+                    // prepareTracks_l reads and writes mActiveTracks, and also returns the
+                    // pending set of tracks to remove via Vector 'tracksToRemove'.  The caller is
+                    // responsible for clearing or destroying this Vector later on, when it
+                    // is safe to do so. That will drop the final ref count and destroy the tracks.
+                    mixer_state prepareTracks_l(Vector< sp<Track> > *tracksToRemove);
         virtual     int         getTrackName_l();
         virtual     void        deleteTrackName_l(int name);
         virtual     uint32_t    idleSleepTimeUs();
@@ -972,7 +975,7 @@
         virtual     uint32_t    activeSleepTimeUs();
 
     private:
-                    bool        outputsReady(SortedVector< sp<OutputTrack> > &outputTracks);
+                    bool        outputsReady(const SortedVector<sp<OutputTrack> > &outputTracks);
                     void        updateWaitTime();
 
         SortedVector < sp<OutputTrack> >  mOutputTracks;
@@ -997,8 +1000,9 @@
                                      PlaybackThread *srcThread,
                                      PlaybackThread *dstThread,
                                      bool reRegister);
-              PlaybackThread *primaryPlaybackThread_l();
-              uint32_t primaryOutputDevice_l();
+              // return thread associated with primary hardware device, or NULL
+              PlaybackThread *primaryPlaybackThread_l() const;
+              uint32_t primaryOutputDevice_l() const;
 
     friend class AudioBuffer;
 
@@ -1048,7 +1052,6 @@
                                         audio_format_t format,
                                         uint32_t channelMask,
                                         int frameCount,
-                                        uint32_t flags,
                                         int sessionId);
             virtual             ~RecordTrack();
 
@@ -1067,9 +1070,9 @@
                                 RecordTrack(const RecordTrack&);
                                 RecordTrack& operator = (const RecordTrack&);
 
-            virtual status_t getNextBuffer(
-                AudioBufferProvider::Buffer* buffer,
-                int64_t pts);
+            // AudioBufferProvider interface
+            virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer, int64_t pts = kInvalidPTS);
+            // releaseBuffer() not overridden
 
             bool                mOverflow;
         };
@@ -1094,7 +1097,6 @@
                         audio_format_t format,
                         int channelMask,
                         int frameCount,
-                        uint32_t flags,
                         int sessionId,
                         status_t *status);
 
@@ -1106,9 +1108,10 @@
                 AudioStreamIn* clearInput();
                 virtual audio_stream_t* stream();
 
-        virtual status_t    getNextBuffer(AudioBufferProvider::Buffer* buffer,
-                                          int64_t pts);
+        // AudioBufferProvider interface
+        virtual status_t    getNextBuffer(AudioBufferProvider::Buffer* buffer, int64_t pts);
         virtual void        releaseBuffer(AudioBufferProvider::Buffer* buffer);
+
         virtual bool        checkForNewParameters_l();
         virtual String8     getParameters(const String8& keys);
         virtual void        audioConfigChanged_l(int event, int param = 0);
@@ -1537,25 +1540,27 @@
                 audio_hw_device_t*                  mPrimaryHardwareDev; // mAudioHwDevs[0] or NULL
                 Vector<audio_hw_device_t*>          mAudioHwDevs;
 
+    // for dump, indicates which hardware operation is currently in progress (but not stream ops)
     enum hardware_call_state {
-        AUDIO_HW_IDLE = 0,
-        AUDIO_HW_INIT,
-        AUDIO_HW_OUTPUT_OPEN,
-        AUDIO_HW_OUTPUT_CLOSE,
-        AUDIO_HW_INPUT_OPEN,
-        AUDIO_HW_INPUT_CLOSE,
-        AUDIO_HW_STANDBY,
-        AUDIO_HW_SET_MASTER_VOLUME,
-        AUDIO_HW_GET_ROUTING,
-        AUDIO_HW_SET_ROUTING,
-        AUDIO_HW_GET_MODE,
-        AUDIO_HW_SET_MODE,
-        AUDIO_HW_GET_MIC_MUTE,
-        AUDIO_HW_SET_MIC_MUTE,
-        AUDIO_SET_VOICE_VOLUME,
-        AUDIO_SET_PARAMETER,
-        AUDIO_HW_GET_INPUT_BUFFER_SIZE,
-        AUDIO_HW_GET_MASTER_VOLUME,
+        AUDIO_HW_IDLE = 0,              // no operation in progress
+        AUDIO_HW_INIT,                  // init_check
+        AUDIO_HW_OUTPUT_OPEN,           // open_output_stream
+        AUDIO_HW_OUTPUT_CLOSE,          // unused
+        AUDIO_HW_INPUT_OPEN,            // unused
+        AUDIO_HW_INPUT_CLOSE,           // unused
+        AUDIO_HW_STANDBY,               // unused
+        AUDIO_HW_SET_MASTER_VOLUME,     // set_master_volume
+        AUDIO_HW_GET_ROUTING,           // unused
+        AUDIO_HW_SET_ROUTING,           // unused
+        AUDIO_HW_GET_MODE,              // unused
+        AUDIO_HW_SET_MODE,              // set_mode
+        AUDIO_HW_GET_MIC_MUTE,          // get_mic_mute
+        AUDIO_HW_SET_MIC_MUTE,          // set_mic_mute
+        AUDIO_HW_SET_VOICE_VOLUME,      // set_voice_volume
+        AUDIO_HW_SET_PARAMETER,         // set_parameters
+        AUDIO_HW_GET_INPUT_BUFFER_SIZE, // get_input_buffer_size
+        AUDIO_HW_GET_MASTER_VOLUME,     // get_master_volume
+        AUDIO_HW_GET_PARAMETER,         // get_parameters
     };
 
     mutable     hardware_call_state                 mHardwareStatus;    // for dump only
diff --git a/services/audioflinger/AudioMixer.cpp b/services/audioflinger/AudioMixer.cpp
index 020d62a..2cec525 100644
--- a/services/audioflinger/AudioMixer.cpp
+++ b/services/audioflinger/AudioMixer.cpp
@@ -332,11 +332,11 @@
     return 0;
 }
 
-void AudioMixer::setBufferProvider(int name, AudioBufferProvider* buffer)
+void AudioMixer::setBufferProvider(int name, AudioBufferProvider* bufferProvider)
 {
     name -= TRACK0;
     assert(uint32_t(name) < MAX_NUM_TRACKS);
-    mState.tracks[name].bufferProvider = buffer;
+    mState.tracks[name].bufferProvider = bufferProvider;
 }
 
 
diff --git a/services/audioflinger/AudioPolicyService.cpp b/services/audioflinger/AudioPolicyService.cpp
index 987b039..753b1d2 100644
--- a/services/audioflinger/AudioPolicyService.cpp
+++ b/services/audioflinger/AudioPolicyService.cpp
@@ -69,7 +69,7 @@
     // start tone playback thread
     mTonePlaybackThread = new AudioCommandThread(String8(""));
     // start audio commands thread
-    mAudioCommandThread = new AudioCommandThread(String8("ApmCommandThread"));
+    mAudioCommandThread = new AudioCommandThread(String8("ApmCommand"));
 
     /* instantiate the audio policy manager */
     rc = hw_get_module(AUDIO_POLICY_HARDWARE_MODULE_ID, &module);
@@ -638,7 +638,7 @@
     if (mName != "") {
         run(mName.string(), ANDROID_PRIORITY_AUDIO);
     } else {
-        run("AudioCommandThread", ANDROID_PRIORITY_AUDIO);
+        run("AudioCommand", ANDROID_PRIORITY_AUDIO);
     }
 }
 
diff --git a/services/camera/libcameraservice/CameraHardwareInterface.h b/services/camera/libcameraservice/CameraHardwareInterface.h
index 2ac69f7..87a0802 100644
--- a/services/camera/libcameraservice/CameraHardwareInterface.h
+++ b/services/camera/libcameraservice/CameraHardwareInterface.h
@@ -21,8 +21,6 @@
 #include <binder/MemoryBase.h>
 #include <binder/MemoryHeapBase.h>
 #include <utils/RefBase.h>
-#include <surfaceflinger/ISurface.h>
-#include <ui/android_native_buffer.h>
 #include <ui/GraphicBuffer.h>
 #include <camera/Camera.h>
 #include <camera/CameraParameters.h>
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 06fc708..adf1d49 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -29,10 +29,10 @@
 #include <cutils/atomic.h>
 #include <cutils/properties.h>
 #include <gui/SurfaceTextureClient.h>
+#include <gui/Surface.h>
 #include <hardware/hardware.h>
 #include <media/AudioSystem.h>
 #include <media/mediaplayer.h>
-#include <surfaceflinger/ISurface.h>
 #include <utils/Errors.h>
 #include <utils/Log.h>
 #include <utils/String16.h>
diff --git a/services/camera/tests/CameraServiceTest/CameraServiceTest.cpp b/services/camera/tests/CameraServiceTest/CameraServiceTest.cpp
index 1055538..e417b79 100644
--- a/services/camera/tests/CameraServiceTest/CameraServiceTest.cpp
+++ b/services/camera/tests/CameraServiceTest/CameraServiceTest.cpp
@@ -22,7 +22,6 @@
 #include <sys/types.h>
 #include <sys/wait.h>
 #include <unistd.h>
-#include <surfaceflinger/ISurface.h>
 #include <camera/Camera.h>
 #include <camera/CameraParameters.h>
 #include <ui/GraphicBuffer.h>
diff --git a/services/input/SpriteController.h b/services/input/SpriteController.h
index 50ae8a5..75e4843 100644
--- a/services/input/SpriteController.h
+++ b/services/input/SpriteController.h
@@ -20,9 +20,7 @@
 #include <utils/RefBase.h>
 #include <utils/Looper.h>
 
-#include <surfaceflinger/Surface.h>
-#include <surfaceflinger/SurfaceComposerClient.h>
-#include <surfaceflinger/ISurfaceComposer.h>
+#include <gui/SurfaceComposerClient.h>
 
 #include <SkBitmap.h>
 
diff --git a/services/java/com/android/server/BootReceiver.java b/services/java/com/android/server/BootReceiver.java
index 6665614..da65438 100644
--- a/services/java/com/android/server/BootReceiver.java
+++ b/services/java/com/android/server/BootReceiver.java
@@ -39,8 +39,10 @@
 public class BootReceiver extends BroadcastReceiver {
     private static final String TAG = "BootReceiver";
 
-    // Maximum size of a logged event (files get truncated if they're longer)
-    private static final int LOG_SIZE = 65536;
+    // Maximum size of a logged event (files get truncated if they're longer).
+    // Give userdebug builds a larger max to capture extra debug, esp. for last_kmsg.
+    private static final int LOG_SIZE =
+        SystemProperties.getInt("ro.debuggable", 0) == 1 ? 98304 : 65536;
 
     private static final File TOMBSTONE_DIR = new File("/data/tombstones");
 
diff --git a/services/java/com/android/server/InputMethodManagerService.java b/services/java/com/android/server/InputMethodManagerService.java
index 86669f8..c705646 100644
--- a/services/java/com/android/server/InputMethodManagerService.java
+++ b/services/java/com/android/server/InputMethodManagerService.java
@@ -786,7 +786,7 @@
         return flags;
     }
 
-    InputBindResult attachNewInputLocked(boolean initial, boolean needResult) {
+    InputBindResult attachNewInputLocked(boolean initial) {
         if (!mBoundToMethod) {
             executeOrSendMessage(mCurMethod, mCaller.obtainMessageOO(
                     MSG_BIND_INPUT, mCurMethod, mCurClient.binding));
@@ -804,14 +804,11 @@
             if (DEBUG) Slog.v(TAG, "Attach new input asks to show input");
             showCurrentInputLocked(getAppShowFlags(), null);
         }
-        return needResult
-                ? new InputBindResult(session.session, mCurId, mCurSeq)
-                : null;
+        return new InputBindResult(session.session, mCurId, mCurSeq);
     }
 
     InputBindResult startInputLocked(IInputMethodClient client,
-            IInputContext inputContext, EditorInfo attribute,
-            boolean initial, boolean needResult) {
+            IInputContext inputContext, EditorInfo attribute, int controlFlags) {
         // If no method is currently selected, do nothing.
         if (mCurMethodId == null) {
             return mNoBinding;
@@ -837,6 +834,16 @@
         } catch (RemoteException e) {
         }
 
+        return startInputUncheckedLocked(cs, inputContext, attribute, controlFlags);
+    }
+
+    InputBindResult startInputUncheckedLocked(ClientState cs,
+            IInputContext inputContext, EditorInfo attribute, int controlFlags) {
+        // If no method is currently selected, do nothing.
+        if (mCurMethodId == null) {
+            return mNoBinding;
+        }
+
         if (mCurClient != cs) {
             // If the client is changing, we need to switch over to the new
             // one.
@@ -867,7 +874,8 @@
             if (cs.curSession != null) {
                 // Fast case: if we are already connected to the input method,
                 // then just return it.
-                return attachNewInputLocked(initial, needResult);
+                return attachNewInputLocked(
+                        (controlFlags&InputMethodManager.CONTROL_START_INITIAL) != 0);
             }
             if (mHaveConnection) {
                 if (mCurMethod != null) {
@@ -948,13 +956,11 @@
 
     @Override
     public InputBindResult startInput(IInputMethodClient client,
-            IInputContext inputContext, EditorInfo attribute,
-            boolean initial, boolean needResult) {
+            IInputContext inputContext, EditorInfo attribute, int controlFlags) {
         synchronized (mMethodMap) {
             final long ident = Binder.clearCallingIdentity();
             try {
-                return startInputLocked(client, inputContext, attribute,
-                        initial, needResult);
+                return startInputLocked(client, inputContext, attribute, controlFlags);
             } finally {
                 Binder.restoreCallingIdentity(ident);
             }
@@ -997,7 +1003,7 @@
                     mCurClient.curSession = new SessionState(mCurClient,
                             method, session);
                     mCurClient.sessionRequested = false;
-                    InputBindResult res = attachNewInputLocked(true, true);
+                    InputBindResult res = attachNewInputLocked(true);
                     if (res.method != null) {
                         executeOrSendMessage(mCurClient.client, mCaller.obtainMessageOO(
                                 MSG_BIND_METHOD, mCurClient.client, res));
@@ -1482,36 +1488,45 @@
     }
 
     @Override
-    public void windowGainedFocus(IInputMethodClient client, IBinder windowToken,
-            boolean viewHasFocus, boolean isTextEditor, int softInputMode,
-            boolean first, int windowFlags) {
+    public InputBindResult windowGainedFocus(IInputMethodClient client, IBinder windowToken,
+            int controlFlags, int softInputMode, int windowFlags,
+            EditorInfo attribute, IInputContext inputContext) {
+        InputBindResult res = null;
         long ident = Binder.clearCallingIdentity();
         try {
             synchronized (mMethodMap) {
                 if (DEBUG) Slog.v(TAG, "windowGainedFocus: " + client.asBinder()
-                        + " viewHasFocus=" + viewHasFocus
-                        + " isTextEditor=" + isTextEditor
+                        + " controlFlags=#" + Integer.toHexString(controlFlags)
                         + " softInputMode=#" + Integer.toHexString(softInputMode)
-                        + " first=" + first + " flags=#"
-                        + Integer.toHexString(windowFlags));
+                        + " windowFlags=#" + Integer.toHexString(windowFlags));
 
-                if (mCurClient == null || client == null
-                        || mCurClient.client.asBinder() != client.asBinder()) {
-                    try {
-                        // We need to check if this is the current client with
-                        // focus in the window manager, to allow this call to
-                        // be made before input is started in it.
-                        if (!mIWindowManager.inputMethodClientHasFocus(client)) {
-                            Slog.w(TAG, "Client not active, ignoring focus gain of: " + client);
-                            return;
-                        }
-                    } catch (RemoteException e) {
+                ClientState cs = mClients.get(client.asBinder());
+                if (cs == null) {
+                    throw new IllegalArgumentException("unknown client "
+                            + client.asBinder());
+                }
+
+                try {
+                    if (!mIWindowManager.inputMethodClientHasFocus(cs.client)) {
+                        // Check with the window manager to make sure this client actually
+                        // has a window with focus.  If not, reject.  This is thread safe
+                        // because if the focus changes some time before or after, the
+                        // next client receiving focus that has any interest in input will
+                        // be calling through here after that change happens.
+                        Slog.w(TAG, "Focus gain on non-focused client " + cs.client
+                                + " (uid=" + cs.uid + " pid=" + cs.pid + ")");
+                        return null;
                     }
+                } catch (RemoteException e) {
                 }
 
                 if (mCurFocusedWindow == windowToken) {
                     Slog.w(TAG, "Window already focused, ignoring focus gain of: " + client);
-                    return;
+                    if (attribute != null) {
+                        return startInputUncheckedLocked(cs, inputContext, attribute,
+                                controlFlags);
+                    }
+                    return null;
                 }
                 mCurFocusedWindow = windowToken;
 
@@ -1527,6 +1542,14 @@
                                 == WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE
                         || mRes.getConfiguration().isLayoutSizeAtLeast(
                                 Configuration.SCREENLAYOUT_SIZE_LARGE);
+                final boolean isTextEditor =
+                        (controlFlags&InputMethodManager.CONTROL_WINDOW_IS_TEXT_EDITOR) != 0;
+
+                // We want to start input before showing the IME, but after closing
+                // it.  We want to do this after closing it to help the IME disappear
+                // more quickly (not get stuck behind it initializing itself for the
+                // new focused input, even if its window wants to hide the IME).
+                boolean didStart = false;
                         
                 switch (softInputMode&WindowManager.LayoutParams.SOFT_INPUT_MASK_STATE) {
                     case WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED:
@@ -1542,12 +1565,17 @@
                                 WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION) != 0) {
                             // There is a focus view, and we are navigating forward
                             // into the window, so show the input window for the user.
-                            // We only do this automatically if the window an resize
-                            // to accomodate the IME (so what the user sees will give
+                            // We only do this automatically if the window can resize
+                            // to accommodate the IME (so what the user sees will give
                             // them good context without input information being obscured
                             // by the IME) or if running on a large screen where there
                             // is more room for the target window + IME.
                             if (DEBUG) Slog.v(TAG, "Unspecified window will show input");
+                            if (attribute != null) {
+                                res = startInputUncheckedLocked(cs, inputContext, attribute,
+                                        controlFlags);
+                                didStart = true;
+                            }
                             showCurrentInputLocked(InputMethodManager.SHOW_IMPLICIT, null);
                         }
                         break;
@@ -1569,18 +1597,35 @@
                         if ((softInputMode &
                                 WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION) != 0) {
                             if (DEBUG) Slog.v(TAG, "Window asks to show input going forward");
+                            if (attribute != null) {
+                                res = startInputUncheckedLocked(cs, inputContext, attribute,
+                                        controlFlags);
+                                didStart = true;
+                            }
                             showCurrentInputLocked(InputMethodManager.SHOW_IMPLICIT, null);
                         }
                         break;
                     case WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE:
                         if (DEBUG) Slog.v(TAG, "Window asks to always show input");
+                        if (attribute != null) {
+                            res = startInputUncheckedLocked(cs, inputContext, attribute,
+                                    controlFlags);
+                            didStart = true;
+                        }
                         showCurrentInputLocked(InputMethodManager.SHOW_IMPLICIT, null);
                         break;
                 }
+
+                if (!didStart && attribute != null) {
+                    res = startInputUncheckedLocked(cs, inputContext, attribute,
+                            controlFlags);
+                }
             }
         } finally {
             Binder.restoreCallingIdentity(ident);
         }
+
+        return res;
     }
 
     @Override
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index c9b5997..423dad6 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -402,6 +402,14 @@
                 reportWtf("starting ThrottleService", e);
             }
 
+            try {
+                Slog.i(TAG, "UpdateLock Service");
+                ServiceManager.addService(Context.UPDATE_LOCK_SERVICE,
+                        new UpdateLockService(context));
+            } catch (Throwable e) {
+                reportWtf("starting UpdateLockService", e);
+            }
+
             if (!"0".equals(SystemProperties.get("system_init.startmountservice"))) {
                 try {
                     /*
diff --git a/services/java/com/android/server/TextServicesManagerService.java b/services/java/com/android/server/TextServicesManagerService.java
index 8384ebc..106bb3e 100644
--- a/services/java/com/android/server/TextServicesManagerService.java
+++ b/services/java/com/android/server/TextServicesManagerService.java
@@ -52,6 +52,7 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.concurrent.CopyOnWriteArrayList;
 
 public class TextServicesManagerService extends ITextServicesManager.Stub {
     private static final String TAG = TextServicesManagerService.class.getSimpleName();
@@ -582,8 +583,8 @@
     private class SpellCheckerBindGroup {
         private final String TAG = SpellCheckerBindGroup.class.getSimpleName();
         private final InternalServiceConnection mInternalConnection;
-        private final ArrayList<InternalDeathRecipient> mListeners =
-                new ArrayList<InternalDeathRecipient>();
+        private final CopyOnWriteArrayList<InternalDeathRecipient> mListeners =
+                new CopyOnWriteArrayList<InternalDeathRecipient>();
         public boolean mBound;
         public ISpellCheckerService mSpellChecker;
         public boolean mConnected;
@@ -601,19 +602,24 @@
             if (DBG) {
                 Slog.d(TAG, "onServiceConnected");
             }
-            synchronized(mSpellCheckerMap) {
-                for (InternalDeathRecipient listener : mListeners) {
-                    try {
-                        final ISpellCheckerSession session = spellChecker.getISpellCheckerSession(
-                                listener.mScLocale, listener.mScListener, listener.mBundle);
-                        listener.mTsListener.onServiceConnected(session);
-                    } catch (RemoteException e) {
-                        Slog.e(TAG, "Exception in getting the spell checker session."
-                                + "Reconnect to the spellchecker. ", e);
-                        removeAll();
-                        return;
+
+            for (InternalDeathRecipient listener : mListeners) {
+                try {
+                    final ISpellCheckerSession session = spellChecker.getISpellCheckerSession(
+                            listener.mScLocale, listener.mScListener, listener.mBundle);
+                    synchronized(mSpellCheckerMap) {
+                        if (mListeners.contains(listener)) {
+                            listener.mTsListener.onServiceConnected(session);
+                        }
                     }
+                } catch (RemoteException e) {
+                    Slog.e(TAG, "Exception in getting the spell checker session."
+                            + "Reconnect to the spellchecker. ", e);
+                    removeAll();
+                    return;
                 }
+            }
+            synchronized(mSpellCheckerMap) {
                 mSpellChecker = spellChecker;
                 mConnected = true;
             }
diff --git a/services/java/com/android/server/UpdateLockService.java b/services/java/com/android/server/UpdateLockService.java
new file mode 100644
index 0000000..5df1928
--- /dev/null
+++ b/services/java/com/android/server/UpdateLockService.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.os.Binder;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.IUpdateLock;
+import android.os.RemoteException;
+import android.os.SystemClock;
+import android.os.TokenWatcher;
+import android.os.UpdateLock;
+import android.util.Slog;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+
+public class UpdateLockService extends IUpdateLock.Stub {
+    static final boolean DEBUG = false;
+    static final String TAG = "UpdateLockService";
+
+    // signatureOrSystem required to use update locks
+    static final String PERMISSION = "android.permission.UPDATE_LOCK";
+
+    Context mContext;
+    LockWatcher mLocks;
+
+    class LockWatcher extends TokenWatcher {
+        LockWatcher(Handler h, String tag) {
+            super(h, tag);
+        }
+
+        public void acquired() {
+            if (DEBUG) {
+                Slog.d(TAG, "first acquire; broadcasting convenient=false");
+            }
+            sendLockChangedBroadcast(false);
+        }
+        public void released() {
+            if (DEBUG) {
+                Slog.d(TAG, "last release; broadcasting convenient=true");
+            }
+            sendLockChangedBroadcast(true);
+        }
+    }
+
+    UpdateLockService(Context context) {
+        mContext = context;
+        mLocks = new LockWatcher(new Handler(), "UpdateLocks");
+
+        // Consider just-booting to be a reasonable time to allow
+        // interruptions for update installation etc.
+        sendLockChangedBroadcast(true);
+    }
+
+    void sendLockChangedBroadcast(boolean state) {
+        // Safe early during boot because this broadcast only goes to registered receivers.
+        long oldIdent = Binder.clearCallingIdentity();
+        try {
+            Intent intent = new Intent(UpdateLock.UPDATE_LOCK_CHANGED)
+                    .putExtra(UpdateLock.NOW_IS_CONVENIENT, state)
+                    .putExtra(UpdateLock.TIMESTAMP, System.currentTimeMillis())
+                    .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
+            mContext.sendStickyBroadcast(intent);
+        } finally {
+            Binder.restoreCallingIdentity(oldIdent);
+        }
+    }
+
+    @Override
+    public void acquireUpdateLock(IBinder token, String tag) throws RemoteException {
+        if (DEBUG) {
+            Slog.d(TAG, "acquire(" + token + ") by " + makeTag(tag));
+        }
+
+        mContext.enforceCallingOrSelfPermission(PERMISSION, "acquireUpdateLock");
+        mLocks.acquire(token, makeTag(tag));
+    }
+
+    @Override
+    public void releaseUpdateLock(IBinder token) throws RemoteException {
+        if (DEBUG) {
+            Slog.d(TAG, "release(" + token + ')');
+        }
+
+        mContext.enforceCallingOrSelfPermission(PERMISSION, "releaseUpdateLock");
+        mLocks.release(token);
+    };
+
+    private String makeTag(String tag) {
+        return "{tag=" + tag
+                + " uid=" + Binder.getCallingUid()
+                + " pid=" + Binder.getCallingPid() + '}';
+    }
+
+    @Override
+    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
+                != PackageManager.PERMISSION_GRANTED) {
+            pw.println("Permission Denial: can't dump update lock service from from pid="
+                    + Binder.getCallingPid()
+                    + ", uid=" + Binder.getCallingUid());
+            return;
+        }
+
+        mLocks.dump(pw);
+    }
+}
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 8a5e7fc..3ac446c 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -2792,14 +2792,7 @@
                                 r.task.taskId, r.shortComponentName,
                                 "proc died without state saved");
                     }
-                    r.makeFinishing();
-                    mMainStack.mHistory.remove(i);
-                    r.takeFromHistory();
-                    mWindowManager.removeAppToken(r.appToken);
-                    if (VALIDATE_TOKENS) {
-                        mMainStack.validateAppTokensLocked();
-                    }
-                    r.removeUriPermissionsLocked();
+                    mMainStack.removeActivityFromHistoryLocked(r);
 
                 } else {
                     // We have the current state for this activity, so
diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java
index 7b8bc26..f9641eb 100644
--- a/services/java/com/android/server/am/ActivityStack.java
+++ b/services/java/com/android/server/am/ActivityStack.java
@@ -3414,6 +3414,33 @@
         return true;
     }
 
+    final void finishActivityResultsLocked(ActivityRecord r, int resultCode, Intent resultData) {
+        // send the result
+        ActivityRecord resultTo = r.resultTo;
+        if (resultTo != null) {
+            if (DEBUG_RESULTS) Slog.v(TAG, "Adding result to " + resultTo
+                    + " who=" + r.resultWho + " req=" + r.requestCode
+                    + " res=" + resultCode + " data=" + resultData);
+            if (r.info.applicationInfo.uid > 0) {
+                mService.grantUriPermissionFromIntentLocked(r.info.applicationInfo.uid,
+                        resultTo.packageName, resultData,
+                        resultTo.getUriPermissionsLocked());
+            }
+            resultTo.addResultLocked(r, r.resultWho, r.requestCode, resultCode,
+                                     resultData);
+            r.resultTo = null;
+        }
+        else if (DEBUG_RESULTS) Slog.v(TAG, "No result destination from " + r);
+
+        // Make sure this HistoryRecord is not holding on to other resources,
+        // because clients have remote IPC references to this object so we
+        // can't assume that will go away and want to avoid circular IPC refs.
+        r.results = null;
+        r.pendingResults = null;
+        r.newIntents = null;
+        r.icicle = null;
+    }
+
     /**
      * @return Returns true if this activity has been removed from the history
      * list, or false if it is still in the list and will be removed later.
@@ -3452,30 +3479,7 @@
             }
         }
 
-        // send the result
-        ActivityRecord resultTo = r.resultTo;
-        if (resultTo != null) {
-            if (DEBUG_RESULTS) Slog.v(TAG, "Adding result to " + resultTo
-                    + " who=" + r.resultWho + " req=" + r.requestCode
-                    + " res=" + resultCode + " data=" + resultData);
-            if (r.info.applicationInfo.uid > 0) {
-                mService.grantUriPermissionFromIntentLocked(r.info.applicationInfo.uid,
-                        resultTo.packageName, resultData, 
-                        resultTo.getUriPermissionsLocked());
-            }
-            resultTo.addResultLocked(r, r.resultWho, r.requestCode, resultCode,
-                                     resultData);
-            r.resultTo = null;
-        }
-        else if (DEBUG_RESULTS) Slog.v(TAG, "No result destination from " + r);
-
-        // Make sure this HistoryRecord is not holding on to other resources,
-        // because clients have remote IPC references to this object so we
-        // can't assume that will go away and want to avoid circular IPC refs.
-        r.results = null;
-        r.pendingResults = null;
-        r.newIntents = null;
-        r.icicle = null;
+        finishActivityResultsLocked(r, resultCode, resultData);
         
         if (mService.mPendingThumbnails.size() > 0) {
             // There are clients waiting to receive thumbnails so, in case
@@ -3638,8 +3642,9 @@
         mHandler.removeMessages(DESTROY_TIMEOUT_MSG, r);
     }
 
-    private final void removeActivityFromHistoryLocked(ActivityRecord r) {
+    final void removeActivityFromHistoryLocked(ActivityRecord r) {
         if (r.state != ActivityState.DESTROYED) {
+            finishActivityResultsLocked(r, Activity.RESULT_CANCELED, null);
             r.makeFinishing();
             if (DEBUG_ADD_REMOVE) {
                 RuntimeException here = new RuntimeException("here");
diff --git a/services/java/com/android/server/location/GpsLocationProvider.java b/services/java/com/android/server/location/GpsLocationProvider.java
index 0ce5499..65b9627 100755
--- a/services/java/com/android/server/location/GpsLocationProvider.java
+++ b/services/java/com/android/server/location/GpsLocationProvider.java
@@ -1082,6 +1082,7 @@
             } else {
                 mLocation.removeAccuracy();
             }
+            mLocation.setExtras(mLocationExtras);
 
             try {
                 mLocationManager.reportLocation(mLocation, false);
diff --git a/services/java/com/android/server/net/NetworkStatsRecorder.java b/services/java/com/android/server/net/NetworkStatsRecorder.java
index 240cc1c..290bd2c 100644
--- a/services/java/com/android/server/net/NetworkStatsRecorder.java
+++ b/services/java/com/android/server/net/NetworkStatsRecorder.java
@@ -50,7 +50,7 @@
  */
 public class NetworkStatsRecorder {
     private static final String TAG = "NetworkStatsRecorder";
-    private static final boolean LOGD = true;
+    private static final boolean LOGD = false;
     private static final boolean LOGV = false;
 
     private final FileRotator mRotator;
diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java
index 7169015..e471a3f 100644
--- a/services/java/com/android/server/pm/PackageManagerService.java
+++ b/services/java/com/android/server/pm/PackageManagerService.java
@@ -1127,7 +1127,10 @@
                     + "; regranting permissions for internal storage");
             mSettings.mInternalSdkPlatform = mSdkVersion;
             
-            updatePermissionsLPw(null, null, true, regrantPermissions, regrantPermissions);
+            updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL
+                    | (regrantPermissions
+                            ? (UPDATE_PERMISSIONS_REPLACE_PKG|UPDATE_PERMISSIONS_REPLACE_ALL)
+                            : 0));
 
             // can downgrade to reader
             mSettings.writeLPr();
@@ -1473,7 +1476,7 @@
     PackageInfo generatePackageInfo(PackageParser.Package p, int flags) {
         if ((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) {
             // The package has been uninstalled but has retained data and resources.
-            return PackageParser.generatePackageInfo(p, null, flags, 0, 0);
+            return PackageParser.generatePackageInfo(p, null, flags, 0, 0, null);
         }
         final PackageSetting ps = (PackageSetting)p.mExtras;
         if (ps == null) {
@@ -1481,7 +1484,7 @@
         }
         final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps;
         return PackageParser.generatePackageInfo(p, gp.gids, flags,
-                ps.firstInstallTime, ps.lastUpdateTime);
+                ps.firstInstallTime, ps.lastUpdateTime, gp.grantedPermissions);
     }
 
     public PackageInfo getPackageInfo(String packageName, int flags) {
@@ -1934,6 +1937,7 @@
         BasePermission bp = mSettings.mPermissions.get(info.name);
         boolean added = bp == null;
         boolean changed = true;
+        int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel);
         if (added) {
             bp = new BasePermission(info.name, tree.sourcePackage,
                     BasePermission.TYPE_DYNAMIC);
@@ -1942,16 +1946,17 @@
                     "Not allowed to modify non-dynamic permission "
                     + info.name);
         } else {
-            if (bp.protectionLevel == info.protectionLevel
+            if (bp.protectionLevel == fixedLevel
                     && bp.perm.owner.equals(tree.perm.owner)
                     && bp.uid == tree.uid
                     && comparePermissionInfos(bp.perm.info, info)) {
                 changed = false;
             }
         }
-        bp.protectionLevel = info.protectionLevel;
-        bp.perm = new PackageParser.Permission(tree.perm.owner,
-                new PermissionInfo(info));
+        bp.protectionLevel = fixedLevel;
+        info = new PermissionInfo(info);
+        info.protectionLevel = fixedLevel;
+        bp.perm = new PackageParser.Permission(tree.perm.owner, info);
         bp.perm.info.packageName = tree.perm.info.packageName;
         bp.uid = tree.uid;
         if (added) {
@@ -1995,6 +2000,77 @@
         }
     }
 
+    public void grantPermission(String packageName, String permissionName) {
+        mContext.enforceCallingOrSelfPermission(
+                android.Manifest.permission.GRANT_REVOKE_PERMISSIONS, null);
+        synchronized (mPackages) {
+            final PackageParser.Package pkg = mPackages.get(packageName);
+            if (pkg == null) {
+                throw new IllegalArgumentException("Unknown package: " + packageName);
+            }
+            final BasePermission bp = mSettings.mPermissions.get(permissionName);
+            if (bp == null) {
+                throw new IllegalArgumentException("Unknown permission: " + packageName);
+            }
+            if (!pkg.requestedPermissions.contains(permissionName)) {
+                throw new SecurityException("Package " + packageName
+                        + " has not requested permission " + permissionName);
+            }
+            if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) == 0) {
+                throw new SecurityException("Permission " + permissionName
+                        + " is not a development permission");
+            }
+            final PackageSetting ps = (PackageSetting) pkg.mExtras;
+            if (ps == null) {
+                return;
+            }
+            final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps;
+            if (gp.grantedPermissions.add(permissionName)) {
+                if (ps.haveGids) {
+                    gp.gids = appendInts(gp.gids, bp.gids);
+                }
+                mSettings.writeLPr();
+            }
+        }
+    }
+
+    public void revokePermission(String packageName, String permissionName) {
+        synchronized (mPackages) {
+            final PackageParser.Package pkg = mPackages.get(packageName);
+            if (pkg == null) {
+                throw new IllegalArgumentException("Unknown package: " + packageName);
+            }
+            if (pkg.applicationInfo.uid != Binder.getCallingUid()) {
+                mContext.enforceCallingOrSelfPermission(
+                        android.Manifest.permission.GRANT_REVOKE_PERMISSIONS, null);
+            }
+            final BasePermission bp = mSettings.mPermissions.get(permissionName);
+            if (bp == null) {
+                throw new IllegalArgumentException("Unknown permission: " + packageName);
+            }
+            if (!pkg.requestedPermissions.contains(permissionName)) {
+                throw new SecurityException("Package " + packageName
+                        + " has not requested permission " + permissionName);
+            }
+            if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) == 0) {
+                throw new SecurityException("Permission " + permissionName
+                        + " is not a development permission");
+            }
+            final PackageSetting ps = (PackageSetting) pkg.mExtras;
+            if (ps == null) {
+                return;
+            }
+            final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps;
+            if (gp.grantedPermissions.remove(permissionName)) {
+                gp.grantedPermissions.remove(permissionName);
+                if (ps.haveGids) {
+                    gp.gids = removeInts(gp.gids, bp.gids);
+                }
+                mSettings.writeLPr();
+            }
+        }
+    }
+
     public boolean isProtectedBroadcast(String actionName) {
         synchronized (mPackages) {
             return mProtectedBroadcasts.contains(actionName);
@@ -4117,10 +4193,13 @@
         }
         return false;
     }
-    
+
+    static final int UPDATE_PERMISSIONS_ALL = 1<<0;
+    static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1;
+    static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2;
+
     private void updatePermissionsLPw(String changingPkg,
-            PackageParser.Package pkgInfo, boolean grantPermissions,
-            boolean replace, boolean replaceAll) {
+            PackageParser.Package pkgInfo, int flags) {
         // Make sure there are no dangling permission trees.
         Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator();
         while (it.hasNext()) {
@@ -4138,7 +4217,7 @@
                 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
                     Slog.i(TAG, "Removing old permission tree: " + bp.name
                             + " from package " + bp.sourcePackage);
-                    grantPermissions = true;
+                    flags |= UPDATE_PERMISSIONS_ALL;
                     it.remove();
                 }
             }
@@ -4178,7 +4257,7 @@
                 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
                     Slog.i(TAG, "Removing old permission: " + bp.name
                             + " from package " + bp.sourcePackage);
-                    grantPermissions = true;
+                    flags |= UPDATE_PERMISSIONS_ALL;
                     it.remove();
                 }
             }
@@ -4186,16 +4265,16 @@
 
         // Now update the permissions for all packages, in particular
         // replace the granted permissions of the system packages.
-        if (grantPermissions) {
+        if ((flags&UPDATE_PERMISSIONS_ALL) != 0) {
             for (PackageParser.Package pkg : mPackages.values()) {
                 if (pkg != pkgInfo) {
-                    grantPermissionsLPw(pkg, replaceAll);
+                    grantPermissionsLPw(pkg, (flags&UPDATE_PERMISSIONS_REPLACE_ALL) != 0);
                 }
             }
         }
         
         if (pkgInfo != null) {
-            grantPermissionsLPw(pkgInfo, replace);
+            grantPermissionsLPw(pkgInfo, (flags&UPDATE_PERMISSIONS_REPLACE_PKG) != 0);
         }
     }
 
@@ -4205,11 +4284,13 @@
             return;
         }
         final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps;
+        HashSet<String> origPermissions = gp.grantedPermissions;
         boolean changedPermission = false;
 
         if (replace) {
             ps.permissionsFixed = false;
             if (gp == ps) {
+                origPermissions = new HashSet<String>(gp.grantedPermissions);
                 gp.grantedPermissions.clear();
                 gp.gids = mGlobalGids;
             }
@@ -4222,6 +4303,7 @@
         final int N = pkg.requestedPermissions.size();
         for (int i=0; i<N; i++) {
             final String name = pkg.requestedPermissions.get(i);
+            //final boolean required = pkg.requestedPermssionsRequired.get(i);
             final BasePermission bp = mSettings.mPermissions.get(name);
             if (DEBUG_INSTALL) {
                 if (gp != ps) {
@@ -4232,23 +4314,23 @@
                 final String perm = bp.name;
                 boolean allowed;
                 boolean allowedSig = false;
-                if (bp.protectionLevel == PermissionInfo.PROTECTION_NORMAL
-                        || bp.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS) {
+                final int level = bp.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE;
+                if (level == PermissionInfo.PROTECTION_NORMAL
+                        || level == PermissionInfo.PROTECTION_DANGEROUS) {
                     allowed = true;
                 } else if (bp.packageSetting == null) {
                     // This permission is invalid; skip it.
                     allowed = false;
-                } else if (bp.protectionLevel == PermissionInfo.PROTECTION_SIGNATURE
-                        || bp.protectionLevel == PermissionInfo.PROTECTION_SIGNATURE_OR_SYSTEM) {
+                } else if (level == PermissionInfo.PROTECTION_SIGNATURE) {
                     allowed = (compareSignatures(
                             bp.packageSetting.signatures.mSignatures, pkg.mSignatures)
                                     == PackageManager.SIGNATURE_MATCH)
                             || (compareSignatures(mPlatformPackage.mSignatures, pkg.mSignatures)
                                     == PackageManager.SIGNATURE_MATCH);
-                    if (!allowed && bp.protectionLevel
-                            == PermissionInfo.PROTECTION_SIGNATURE_OR_SYSTEM) {
+                    if (!allowed && (bp.protectionLevel
+                            & PermissionInfo.PROTECTION_FLAG_SYSTEM) != 0) {
                         if (isSystemApp(pkg)) {
-                            // For updated system applications, the signatureOrSystem permission
+                            // For updated system applications, a system permission
                             // is granted only if it had been defined by the original application.
                             if (isUpdatedSystemApp(pkg)) {
                                 final PackageSetting sysPs = mSettings
@@ -4265,6 +4347,16 @@
                             }
                         }
                     }
+                    if (!allowed && (bp.protectionLevel
+                            & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) {
+                        // For development permissions, a development permission
+                        // is granted only if it was already granted.
+                        if (origPermissions.contains(perm)) {
+                            allowed = true;
+                        } else {
+                            allowed = false;
+                        }
+                    }
                     if (allowed) {
                         allowedSig = true;
                     }
@@ -4883,7 +4975,7 @@
                             // writer
                             synchronized (mPackages) {
                                 updatePermissionsLPw(p.packageName, p,
-                                        p.permissions.size() > 0, false, false);
+                                        p.permissions.size() > 0 ? UPDATE_PERMISSIONS_ALL : 0);
                             }
                             addedPackage = p.applicationInfo.packageName;
                             addedUid = p.applicationInfo.uid;
@@ -6447,7 +6539,7 @@
                 // writer
                 synchronized (mPackages) {
                     updatePermissionsLPw(deletedPackage.packageName, deletedPackage,
-                            true, false, false);
+                            UPDATE_PERMISSIONS_ALL);
                     // can downgrade to reader
                     mSettings.writeLPr();
                 }
@@ -6591,7 +6683,8 @@
         }
         synchronized (mPackages) {
             updatePermissionsLPw(newPackage.packageName, newPackage,
-                    newPackage.permissions.size() > 0, true, false);
+                    UPDATE_PERMISSIONS_REPLACE_PKG | (newPackage.permissions.size() > 0
+                            ? UPDATE_PERMISSIONS_ALL : 0));
             res.name = pkgName;
             res.uid = newPackage.applicationInfo.uid;
             res.pkg = newPackage;
@@ -7019,7 +7112,7 @@
                         outInfo.removedUid = mSettings.removePackageLPw(packageName);
                     }
                     if (deletedPs != null) {
-                        updatePermissionsLPw(deletedPs.name, null, false, false, false);
+                        updatePermissionsLPw(deletedPs.name, null, 0);
                         if (deletedPs.sharedUser != null) {
                             // remove permissions associated with package
                             mSettings.updateSharedUserPermsLPw(deletedPs, mGlobalGids);
@@ -7102,7 +7195,8 @@
         }
         // writer
         synchronized (mPackages) {
-            updatePermissionsLPw(newPkg.packageName, newPkg, true, true, false);
+            updatePermissionsLPw(newPkg.packageName, newPkg,
+                    UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG);
             // can downgrade to reader here
             if (writeSettings) {
                 mSettings.writeLPr();
@@ -8320,7 +8414,10 @@
 
             // Make sure group IDs have been assigned, and any permission
             // changes in other apps are accounted for
-            updatePermissionsLPw(null, null, true, regrantPermissions, regrantPermissions);
+            updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL
+                    | (regrantPermissions
+                            ? (UPDATE_PERMISSIONS_REPLACE_PKG|UPDATE_PERMISSIONS_REPLACE_ALL)
+                            : 0));
             // can downgrade to reader
             // Persist settings
             mSettings.writeLPr();
diff --git a/services/java/com/android/server/pm/Settings.java b/services/java/com/android/server/pm/Settings.java
index ebf954bf..5da6ac9 100644
--- a/services/java/com/android/server/pm/Settings.java
+++ b/services/java/com/android/server/pm/Settings.java
@@ -1398,6 +1398,7 @@
                             dynamic ? BasePermission.TYPE_DYNAMIC : BasePermission.TYPE_NORMAL);
                     bp.protectionLevel = readInt(parser, null, "protection",
                             PermissionInfo.PROTECTION_NORMAL);
+                    bp.protectionLevel = PermissionInfo.fixProtectionLevel(bp.protectionLevel);
                     if (dynamic) {
                         PermissionInfo pi = new PermissionInfo();
                         pi.packageName = sourcePackage.intern();
@@ -2244,7 +2245,8 @@
             pw.print("    uid="); pw.print(p.uid);
                     pw.print(" gids="); pw.print(PackageManagerService.arrayToString(p.gids));
                     pw.print(" type="); pw.print(p.type);
-                    pw.print(" prot="); pw.println(p.protectionLevel);
+                    pw.print(" prot=");
+                    pw.println(PermissionInfo.protectionToString(p.protectionLevel));
             if (p.packageSetting != null) {
                 pw.print("    packageSetting="); pw.println(p.packageSetting);
             }
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 21cb3e8..008793c 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -7685,8 +7685,6 @@
                     }
                 }
 
-                final boolean wasAnimating = w.mAnimating;
-
                 // If the window has moved due to its containing
                 // content frame changing, then we'd like to animate
                 // it.  The checks here are ordered by what is least
@@ -7705,8 +7703,13 @@
                     w.mAnimDh = innerDh;
                 }
 
-                // Execute animation.
-                final boolean nowAnimating = w.isAnimating();
+                final boolean wasAnimating = w.mWasAnimating;
+                final boolean nowAnimating = w.mLocalAnimating;
+
+                if (DEBUG_WALLPAPER) {
+                    Slog.v(TAG, w + ": wasAnimating=" + wasAnimating +
+                            ", nowAnimating=" + nowAnimating);
+                }
 
                 // If this window is animating, make a note that we have
                 // an animating window and take care of a request to run
diff --git a/services/java/com/android/server/wm/WindowState.java b/services/java/com/android/server/wm/WindowState.java
index d7a7cb0..eeecad1 100644
--- a/services/java/com/android/server/wm/WindowState.java
+++ b/services/java/com/android/server/wm/WindowState.java
@@ -91,6 +91,7 @@
     boolean mAttachedHidden;    // is our parent window hidden?
     boolean mLastHidden;        // was this window last hidden?
     boolean mWallpaperVisible;  // for wallpaper, what was last vis report?
+    boolean mWasAnimating;      // Were we animating going into the most recent animation step?
 
     /**
      * The window size that was requested by the application.  These are in
@@ -979,6 +980,9 @@
     // This must be called while inside a transaction.  Returns true if
     // there is more animation to run.
     boolean stepAnimationLocked(long currentTime) {
+        // Save the animation state as it was before this step so WindowManagerService can tell if
+        // we just started or just stopped animating by comparing mWasAnimating with isAnimating().
+        mWasAnimating = mAnimating;
         if (!mService.mDisplayFrozen && mService.mPolicy.isScreenOnFully()) {
             // We will run animations as long as the display isn't frozen.
 
diff --git a/services/jni/com_android_server_PowerManagerService.cpp b/services/jni/com_android_server_PowerManagerService.cpp
index d2b3118..ce80c1f 100644
--- a/services/jni/com_android_server_PowerManagerService.cpp
+++ b/services/jni/com_android_server_PowerManagerService.cpp
@@ -25,8 +25,7 @@
 
 #include <android_runtime/AndroidRuntime.h>
 #include <utils/Timers.h>
-#include <surfaceflinger/ISurfaceComposer.h>
-#include <surfaceflinger/SurfaceComposerClient.h>
+#include <gui/ISurfaceComposer.h>
 
 #include <private/gui/ComposerService.h>
 
diff --git a/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp b/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp
index 986aec5..9baae80 100644
--- a/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp
+++ b/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp
@@ -26,14 +26,11 @@
 
 #include <ui/PixelFormat.h>
 #include <ui/FramebufferNativeWindow.h>
-#include <ui/EGLUtils.h>
 
 #include <GLES/gl.h>
 #include <EGL/egl.h>
 #include <EGL/eglext.h>
 
-#include <pixelflinger/pixelflinger.h>
-
 #include "DisplayHardware/DisplayHardware.h"
 
 #include <hardware/gralloc.h>
@@ -60,6 +57,29 @@
 static __attribute__((noinline))
 void checkEGLErrors(const char* token)
 {
+    struct EGLUtils {
+        static const char *strerror(EGLint err) {
+            switch (err){
+                case EGL_SUCCESS:           return "EGL_SUCCESS";
+                case EGL_NOT_INITIALIZED:   return "EGL_NOT_INITIALIZED";
+                case EGL_BAD_ACCESS:        return "EGL_BAD_ACCESS";
+                case EGL_BAD_ALLOC:         return "EGL_BAD_ALLOC";
+                case EGL_BAD_ATTRIBUTE:     return "EGL_BAD_ATTRIBUTE";
+                case EGL_BAD_CONFIG:        return "EGL_BAD_CONFIG";
+                case EGL_BAD_CONTEXT:       return "EGL_BAD_CONTEXT";
+                case EGL_BAD_CURRENT_SURFACE: return "EGL_BAD_CURRENT_SURFACE";
+                case EGL_BAD_DISPLAY:       return "EGL_BAD_DISPLAY";
+                case EGL_BAD_MATCH:         return "EGL_BAD_MATCH";
+                case EGL_BAD_NATIVE_PIXMAP: return "EGL_BAD_NATIVE_PIXMAP";
+                case EGL_BAD_NATIVE_WINDOW: return "EGL_BAD_NATIVE_WINDOW";
+                case EGL_BAD_PARAMETER:     return "EGL_BAD_PARAMETER";
+                case EGL_BAD_SURFACE:       return "EGL_BAD_SURFACE";
+                case EGL_CONTEXT_LOST:      return "EGL_CONTEXT_LOST";
+                default: return "UNKNOWN";
+            }
+        }
+    };
+
     EGLint error = eglGetError();
     if (error && error != EGL_SUCCESS) {
         ALOGE("%s: EGL error 0x%04x (%s)",
diff --git a/services/surfaceflinger/DisplayHardware/DisplayHardware.h b/services/surfaceflinger/DisplayHardware/DisplayHardware.h
index 02be4dc..0a828b3 100644
--- a/services/surfaceflinger/DisplayHardware/DisplayHardware.h
+++ b/services/surfaceflinger/DisplayHardware/DisplayHardware.h
@@ -27,8 +27,6 @@
 #include <EGL/egl.h>
 #include <EGL/eglext.h>
 
-#include <pixelflinger/pixelflinger.h>
-
 #include "GLExtensions.h"
 
 #include "DisplayHardware/DisplayHardwareBase.h"
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 4ee6953..df7fe5c 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -14,9 +14,12 @@
  * limitations under the License.
  */
 
+#define ATRACE_TAG ATRACE_TAG_GRAPHICS
+
 #include <stdlib.h>
 #include <stdint.h>
 #include <sys/types.h>
+#include <math.h>
 
 #include <cutils/compiler.h>
 #include <cutils/native_handle.h>
@@ -25,11 +28,12 @@
 #include <utils/Errors.h>
 #include <utils/Log.h>
 #include <utils/StopWatch.h>
+#include <utils/Trace.h>
 
 #include <ui/GraphicBuffer.h>
 #include <ui/PixelFormat.h>
 
-#include <surfaceflinger/Surface.h>
+#include <gui/Surface.h>
 
 #include "clz.h"
 #include "DisplayHardware/DisplayHardware.h"
@@ -38,7 +42,6 @@
 #include "Layer.h"
 #include "SurfaceFlinger.h"
 #include "SurfaceTextureLayer.h"
-#include <math.h>
 
 #define DEBUG_RESIZE    0
 
@@ -160,7 +163,10 @@
     // this surfaces pixel format
     PixelFormatInfo info;
     status_t err = getPixelFormatInfo(format, &info);
-    if (err) return err;
+    if (err) {
+        ALOGE("unsupported pixelformat %d", format);
+        return err;
+    }
 
     // the display's pixel format
     const DisplayHardware& hw(graphicPlane(0).displayHardware());
@@ -170,6 +176,7 @@
     // never allow a surface larger than what our underlying GL implementation
     // can handle.
     if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
+        ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h));
         return BAD_VALUE;
     }
 
@@ -263,6 +270,8 @@
 
 void Layer::onDraw(const Region& clip) const
 {
+    ATRACE_CALL();
+
     if (CC_UNLIKELY(mActiveBuffer == 0)) {
         // the texture has not been created yet, this Layer has
         // in fact never been drawn into. This happens frequently with
@@ -361,6 +370,8 @@
 
 uint32_t Layer::doTransaction(uint32_t flags)
 {
+    ATRACE_CALL();
+
     const Layer::State& front(drawingState());
     const Layer::State& temp(currentState());
 
@@ -414,6 +425,8 @@
 
 void Layer::lockPageFlip(bool& recomputeVisibleRegions)
 {
+    ATRACE_CALL();
+
     if (mQueuedFrames > 0) {
 
         // if we've already called updateTexImage() without going through
@@ -446,6 +459,12 @@
         mActiveBuffer = mSurfaceTexture->getCurrentBuffer();
         mFrameLatencyNeeded = true;
 
+        if (oldActiveBuffer == NULL && mActiveBuffer != NULL) {
+            // the first time we receive a buffer, we need to trigger a
+            // geometry invalidation.
+            mFlinger->invalidateHwcGeometry();
+        }
+
         const Rect crop(mSurfaceTexture->getCurrentCrop());
         const uint32_t transform(mSurfaceTexture->getCurrentTransform());
         const uint32_t scalingMode(mSurfaceTexture->getCurrentScalingMode());
@@ -536,6 +555,8 @@
 void Layer::unlockPageFlip(
         const Transform& planeTransform, Region& outDirtyRegion)
 {
+    ATRACE_CALL();
+
     Region postedRegion(mPostedDirtyRegion);
     if (!postedRegion.isEmpty()) {
         mPostedDirtyRegion.clear();
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 39bbb2b..8d508c2 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -22,10 +22,13 @@
 
 #include <gui/SurfaceTexture.h>
 
-#include <pixelflinger/pixelflinger.h>
+#include <utils/Timers.h>
+
 #include <ui/GraphicBuffer.h>
 #include <ui/PixelFormat.h>
 
+#include <gui/ISurfaceComposerClient.h>
+
 #include <EGL/egl.h>
 #include <EGL/eglext.h>
 #include <GLES/gl.h>
@@ -34,7 +37,6 @@
 #include "LayerBase.h"
 #include "SurfaceTextureLayer.h"
 #include "Transform.h"
-#include <utils/Timers.h>
 
 namespace android {
 
diff --git a/services/surfaceflinger/LayerBase.h b/services/surfaceflinger/LayerBase.h
index b8f7680..cd6efdd 100644
--- a/services/surfaceflinger/LayerBase.h
+++ b/services/surfaceflinger/LayerBase.h
@@ -28,10 +28,9 @@
 
 #include <ui/Region.h>
 
-#include <surfaceflinger/ISurfaceComposerClient.h>
-#include <private/surfaceflinger/LayerState.h>
+#include <gui/ISurfaceComposerClient.h>
 
-#include <pixelflinger/pixelflinger.h>
+#include <private/gui/LayerState.h>
 
 #include <hardware/hwcomposer.h>
 
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 9d821dc..42ed4fa 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -14,6 +14,8 @@
  * limitations under the License.
  */
 
+#define ATRACE_TAG ATRACE_TAG_GRAPHICS
+
 #include <stdlib.h>
 #include <stdio.h>
 #include <stdint.h>
@@ -39,18 +41,18 @@
 #include <utils/String8.h>
 #include <utils/String16.h>
 #include <utils/StopWatch.h>
+#include <utils/Trace.h>
 
 #include <ui/GraphicBufferAllocator.h>
 #include <ui/PixelFormat.h>
 
-#include <pixelflinger/pixelflinger.h>
 #include <GLES/gl.h>
 
 #include "clz.h"
+#include "DdmConnection.h"
 #include "DisplayEventConnection.h"
 #include "EventThread.h"
 #include "GLExtensions.h"
-#include "DdmConnection.h"
 #include "Layer.h"
 #include "LayerDim.h"
 #include "LayerScreenshot.h"
@@ -60,7 +62,7 @@
 #include "DisplayHardware/HWComposer.h"
 
 #include <private/android_filesystem_config.h>
-#include <private/surfaceflinger/SharedBufferStack.h>
+#include <private/gui/SharedBufferStack.h>
 
 #define EGL_VERSION_HW_ANDROID  0x3143
 
@@ -403,6 +405,7 @@
 
 void SurfaceFlinger::onMessageReceived(int32_t what)
 {
+    ATRACE_CALL();
     switch (what) {
         case MessageQueue::REFRESH: {
 //        case MessageQueue::INVALIDATE: {
@@ -738,6 +741,7 @@
 
 void SurfaceFlinger::handlePageFlip()
 {
+    ATRACE_CALL();
     const DisplayHardware& hw = graphicPlane(0).displayHardware();
     const Region screenRegion(hw.bounds());
 
@@ -1285,7 +1289,7 @@
         return surfaceHandle;
     }
 
-    //ALOGD("createSurface for pid %d (%d x %d)", pid, w, h);
+    //ALOGD("createSurface for (%d x %d), name=%s", w, h, name.string());
     sp<Layer> normalLayer;
     switch (flags & eFXSurfaceMask) {
         case eFXSurfaceNormal:
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index fcd9361..b507877 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -33,9 +33,9 @@
 #include <binder/IMemory.h>
 
 #include <ui/PixelFormat.h>
-#include <surfaceflinger/IGraphicBufferAlloc.h>
-#include <surfaceflinger/ISurfaceComposer.h>
-#include <surfaceflinger/ISurfaceComposerClient.h>
+#include <gui/IGraphicBufferAlloc.h>
+#include <gui/ISurfaceComposer.h>
+#include <gui/ISurfaceComposerClient.h>
 
 #include "Barrier.h"
 #include "Layer.h"
diff --git a/services/surfaceflinger/tests/Transaction_test.cpp b/services/surfaceflinger/tests/Transaction_test.cpp
index 396a3fd..84ae0d9 100644
--- a/services/surfaceflinger/tests/Transaction_test.cpp
+++ b/services/surfaceflinger/tests/Transaction_test.cpp
@@ -17,9 +17,12 @@
 #include <gtest/gtest.h>
 
 #include <binder/IMemory.h>
-#include <surfaceflinger/ISurfaceComposer.h>
-#include <surfaceflinger/Surface.h>
-#include <surfaceflinger/SurfaceComposerClient.h>
+
+#include <gui/ISurfaceComposer.h>
+#include <gui/Surface.h>
+#include <gui/SurfaceComposerClient.h>
+#include <private/gui/ComposerService.h>
+
 #include <utils/String8.h>
 
 namespace android {
diff --git a/services/surfaceflinger/tests/resize/resize.cpp b/services/surfaceflinger/tests/resize/resize.cpp
index 7f3f064..c143b3d 100644
--- a/services/surfaceflinger/tests/resize/resize.cpp
+++ b/services/surfaceflinger/tests/resize/resize.cpp
@@ -22,9 +22,8 @@
 #include <binder/ProcessState.h>
 #include <binder/IServiceManager.h>
 
-#include <surfaceflinger/Surface.h>
-#include <surfaceflinger/ISurface.h>
-#include <surfaceflinger/SurfaceComposerClient.h>
+#include <gui/Surface.h>
+#include <gui/SurfaceComposerClient.h>
 
 using namespace android;
 
diff --git a/services/surfaceflinger/tests/screencap/screencap.cpp b/services/surfaceflinger/tests/screencap/screencap.cpp
index 6cf1504..53566e0 100644
--- a/services/surfaceflinger/tests/screencap/screencap.cpp
+++ b/services/surfaceflinger/tests/screencap/screencap.cpp
@@ -21,7 +21,7 @@
 #include <binder/IServiceManager.h>
 
 #include <binder/IMemory.h>
-#include <surfaceflinger/ISurfaceComposer.h>
+#include <gui/ISurfaceComposer.h>
 
 #include <SkImageEncoder.h>
 #include <SkBitmap.h>
diff --git a/services/surfaceflinger/tests/surface/surface.cpp b/services/surfaceflinger/tests/surface/surface.cpp
index 9c15f9b..a8878f7 100644
--- a/services/surfaceflinger/tests/surface/surface.cpp
+++ b/services/surfaceflinger/tests/surface/surface.cpp
@@ -22,9 +22,8 @@
 #include <binder/ProcessState.h>
 #include <binder/IServiceManager.h>
 
-#include <surfaceflinger/Surface.h>
-#include <surfaceflinger/ISurface.h>
-#include <surfaceflinger/SurfaceComposerClient.h>
+#include <gui/Surface.h>
+#include <gui/SurfaceComposerClient.h>
 
 using namespace android;
 
diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java
index 32a6975..a9a5e90 100644
--- a/telephony/java/android/telephony/ServiceState.java
+++ b/telephony/java/android/telephony/ServiceState.java
@@ -64,44 +64,47 @@
 
     /**
      * Available radio technologies for GSM, UMTS and CDMA.
+     * Duplicates the constants from hardware/radio/include/ril.h
+     * This should only be used by agents working with the ril.  Others
+     * should use the equivalent TelephonyManager.NETWORK_TYPE_*
      */
     /** @hide */
-    public static final int RADIO_TECHNOLOGY_UNKNOWN = 0;
+    public static final int RIL_RADIO_TECHNOLOGY_UNKNOWN = 0;
     /** @hide */
-    public static final int RADIO_TECHNOLOGY_GPRS = 1;
+    public static final int RIL_RADIO_TECHNOLOGY_GPRS = 1;
     /** @hide */
-    public static final int RADIO_TECHNOLOGY_EDGE = 2;
+    public static final int RIL_RADIO_TECHNOLOGY_EDGE = 2;
     /** @hide */
-    public static final int RADIO_TECHNOLOGY_UMTS = 3;
+    public static final int RIL_RADIO_TECHNOLOGY_UMTS = 3;
     /** @hide */
-    public static final int RADIO_TECHNOLOGY_IS95A = 4;
+    public static final int RIL_RADIO_TECHNOLOGY_IS95A = 4;
     /** @hide */
-    public static final int RADIO_TECHNOLOGY_IS95B = 5;
+    public static final int RIL_RADIO_TECHNOLOGY_IS95B = 5;
     /** @hide */
-    public static final int RADIO_TECHNOLOGY_1xRTT = 6;
+    public static final int RIL_RADIO_TECHNOLOGY_1xRTT = 6;
     /** @hide */
-    public static final int RADIO_TECHNOLOGY_EVDO_0 = 7;
+    public static final int RIL_RADIO_TECHNOLOGY_EVDO_0 = 7;
     /** @hide */
-    public static final int RADIO_TECHNOLOGY_EVDO_A = 8;
+    public static final int RIL_RADIO_TECHNOLOGY_EVDO_A = 8;
     /** @hide */
-    public static final int RADIO_TECHNOLOGY_HSDPA = 9;
+    public static final int RIL_RADIO_TECHNOLOGY_HSDPA = 9;
     /** @hide */
-    public static final int RADIO_TECHNOLOGY_HSUPA = 10;
+    public static final int RIL_RADIO_TECHNOLOGY_HSUPA = 10;
     /** @hide */
-    public static final int RADIO_TECHNOLOGY_HSPA = 11;
+    public static final int RIL_RADIO_TECHNOLOGY_HSPA = 11;
     /** @hide */
-    public static final int RADIO_TECHNOLOGY_EVDO_B = 12;
+    public static final int RIL_RADIO_TECHNOLOGY_EVDO_B = 12;
     /** @hide */
-    public static final int RADIO_TECHNOLOGY_EHRPD = 13;
+    public static final int RIL_RADIO_TECHNOLOGY_EHRPD = 13;
     /** @hide */
-    public static final int RADIO_TECHNOLOGY_LTE = 14;
+    public static final int RIL_RADIO_TECHNOLOGY_LTE = 14;
     /** @hide */
-    public static final int RADIO_TECHNOLOGY_HSPAP = 15;
+    public static final int RIL_RADIO_TECHNOLOGY_HSPAP = 15;
     /**
      * GSM radio technology only supports voice. It does not support data.
      * @hide
      */
-    public static final int RADIO_TECHNOLOGY_GSM = 16;
+    public static final int RIL_RADIO_TECHNOLOGY_GSM = 16;
 
     /**
      * Available registration states for GSM, UMTS and CDMA.
@@ -400,59 +403,59 @@
      *
      * @hide
      */
-    public static String radioTechnologyToString(int rt) {
+    public static String rilRadioTechnologyToString(int rt) {
         String rtString;
 
         switch(rt) {
-            case 0:
+            case RIL_RADIO_TECHNOLOGY_UNKNOWN:
                 rtString = "Unknown";
                 break;
-            case 1:
+            case RIL_RADIO_TECHNOLOGY_GPRS:
                 rtString = "GPRS";
                 break;
-            case 2:
+            case RIL_RADIO_TECHNOLOGY_EDGE:
                 rtString = "EDGE";
                 break;
-            case 3:
+            case RIL_RADIO_TECHNOLOGY_UMTS:
                 rtString = "UMTS";
                 break;
-            case 4:
+            case RIL_RADIO_TECHNOLOGY_IS95A:
                 rtString = "CDMA-IS95A";
                 break;
-            case 5:
+            case RIL_RADIO_TECHNOLOGY_IS95B:
                 rtString = "CDMA-IS95B";
                 break;
-            case 6:
+            case RIL_RADIO_TECHNOLOGY_1xRTT:
                 rtString = "1xRTT";
                 break;
-            case 7:
+            case RIL_RADIO_TECHNOLOGY_EVDO_0:
                 rtString = "EvDo-rev.0";
                 break;
-            case 8:
+            case RIL_RADIO_TECHNOLOGY_EVDO_A:
                 rtString = "EvDo-rev.A";
                 break;
-            case 9:
+            case RIL_RADIO_TECHNOLOGY_HSDPA:
                 rtString = "HSDPA";
                 break;
-            case 10:
+            case RIL_RADIO_TECHNOLOGY_HSUPA:
                 rtString = "HSUPA";
                 break;
-            case 11:
+            case RIL_RADIO_TECHNOLOGY_HSPA:
                 rtString = "HSPA";
                 break;
-            case 12:
+            case RIL_RADIO_TECHNOLOGY_EVDO_B:
                 rtString = "EvDo-rev.B";
                 break;
-            case 13:
+            case RIL_RADIO_TECHNOLOGY_EHRPD:
                 rtString = "eHRPD";
                 break;
-            case 14:
+            case RIL_RADIO_TECHNOLOGY_LTE:
                 rtString = "LTE";
                 break;
-            case 15:
+            case RIL_RADIO_TECHNOLOGY_HSPAP:
                 rtString = "HSPAP";
                 break;
-            case 16:
+            case RIL_RADIO_TECHNOLOGY_GSM:
                 rtString = "GSM";
                 break;
             default:
@@ -460,12 +463,12 @@
                 Log.w(LOG_TAG, "Unexpected radioTechnology=" + rt);
                 break;
         }
-        return rtString + ":" + rt;
+        return rtString;
     }
 
     @Override
     public String toString() {
-        String radioTechnology = radioTechnologyToString(mRadioTechnology);
+        String radioTechnology = rilRadioTechnologyToString(mRadioTechnology);
 
         return (mState + " " + (mRoaming ? "roaming" : "home")
                 + " " + mOperatorAlphaLong
@@ -644,9 +647,50 @@
     }
 
     /** @hide */
-    public int getRadioTechnology() {
+    public int getRilRadioTechnology() {
         return this.mRadioTechnology;
     }
+    /** @hide */
+    public int getRadioTechnology() {
+        return getRilRadioTechnology();
+    }
+
+    /** @hide */
+    public int getNetworkType() {
+        switch(mRadioTechnology) {
+        case ServiceState.RIL_RADIO_TECHNOLOGY_GPRS:
+            return TelephonyManager.NETWORK_TYPE_GPRS;
+        case ServiceState.RIL_RADIO_TECHNOLOGY_EDGE:
+            return TelephonyManager.NETWORK_TYPE_EDGE;
+        case ServiceState.RIL_RADIO_TECHNOLOGY_UMTS:
+            return TelephonyManager.NETWORK_TYPE_UMTS;
+        case ServiceState.RIL_RADIO_TECHNOLOGY_HSDPA:
+            return TelephonyManager.NETWORK_TYPE_HSDPA;
+        case ServiceState.RIL_RADIO_TECHNOLOGY_HSUPA:
+            return TelephonyManager.NETWORK_TYPE_HSUPA;
+        case ServiceState.RIL_RADIO_TECHNOLOGY_HSPA:
+            return TelephonyManager.NETWORK_TYPE_HSPA;
+        case ServiceState.RIL_RADIO_TECHNOLOGY_IS95A:
+        case ServiceState.RIL_RADIO_TECHNOLOGY_IS95B:
+            return TelephonyManager.NETWORK_TYPE_CDMA;
+        case ServiceState.RIL_RADIO_TECHNOLOGY_1xRTT:
+            return TelephonyManager.NETWORK_TYPE_1xRTT;
+        case ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_0:
+            return TelephonyManager.NETWORK_TYPE_EVDO_0;
+        case ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_A:
+            return TelephonyManager.NETWORK_TYPE_EVDO_A;
+        case ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_B:
+            return TelephonyManager.NETWORK_TYPE_EVDO_B;
+        case ServiceState.RIL_RADIO_TECHNOLOGY_EHRPD:
+            return TelephonyManager.NETWORK_TYPE_EHRPD;
+        case ServiceState.RIL_RADIO_TECHNOLOGY_LTE:
+            return TelephonyManager.NETWORK_TYPE_LTE;
+        case ServiceState.RIL_RADIO_TECHNOLOGY_HSPAP:
+            return TelephonyManager.NETWORK_TYPE_HSPAP;
+        default:
+            return TelephonyManager.NETWORK_TYPE_UNKNOWN;
+        }
+    }
 
     /** @hide */
     public int getCssIndicator() {
@@ -665,25 +709,25 @@
 
     /** @hide */
     public static boolean isGsm(int radioTechnology) {
-        return radioTechnology == RADIO_TECHNOLOGY_GPRS
-                || radioTechnology == RADIO_TECHNOLOGY_EDGE
-                || radioTechnology == RADIO_TECHNOLOGY_UMTS
-                || radioTechnology == RADIO_TECHNOLOGY_HSDPA
-                || radioTechnology == RADIO_TECHNOLOGY_HSUPA
-                || radioTechnology == RADIO_TECHNOLOGY_HSPA
-                || radioTechnology == RADIO_TECHNOLOGY_LTE
-                || radioTechnology == RADIO_TECHNOLOGY_HSPAP
-                || radioTechnology == RADIO_TECHNOLOGY_GSM;
+        return radioTechnology == RIL_RADIO_TECHNOLOGY_GPRS
+                || radioTechnology == RIL_RADIO_TECHNOLOGY_EDGE
+                || radioTechnology == RIL_RADIO_TECHNOLOGY_UMTS
+                || radioTechnology == RIL_RADIO_TECHNOLOGY_HSDPA
+                || radioTechnology == RIL_RADIO_TECHNOLOGY_HSUPA
+                || radioTechnology == RIL_RADIO_TECHNOLOGY_HSPA
+                || radioTechnology == RIL_RADIO_TECHNOLOGY_LTE
+                || radioTechnology == RIL_RADIO_TECHNOLOGY_HSPAP
+                || radioTechnology == RIL_RADIO_TECHNOLOGY_GSM;
     }
 
     /** @hide */
     public static boolean isCdma(int radioTechnology) {
-        return radioTechnology == RADIO_TECHNOLOGY_IS95A
-                || radioTechnology == RADIO_TECHNOLOGY_IS95B
-                || radioTechnology == RADIO_TECHNOLOGY_1xRTT
-                || radioTechnology == RADIO_TECHNOLOGY_EVDO_0
-                || radioTechnology == RADIO_TECHNOLOGY_EVDO_A
-                || radioTechnology == RADIO_TECHNOLOGY_EVDO_B
-                || radioTechnology == RADIO_TECHNOLOGY_EHRPD;
+        return radioTechnology == RIL_RADIO_TECHNOLOGY_IS95A
+                || radioTechnology == RIL_RADIO_TECHNOLOGY_IS95B
+                || radioTechnology == RIL_RADIO_TECHNOLOGY_1xRTT
+                || radioTechnology == RIL_RADIO_TECHNOLOGY_EVDO_0
+                || radioTechnology == RIL_RADIO_TECHNOLOGY_EVDO_A
+                || radioTechnology == RIL_RADIO_TECHNOLOGY_EVDO_B
+                || radioTechnology == RIL_RADIO_TECHNOLOGY_EHRPD;
     }
 }
diff --git a/telephony/java/com/android/internal/telephony/DataConnection.java b/telephony/java/com/android/internal/telephony/DataConnection.java
index d0e304f..238afbe 100644
--- a/telephony/java/com/android/internal/telephony/DataConnection.java
+++ b/telephony/java/com/android/internal/telephony/DataConnection.java
@@ -355,14 +355,14 @@
         if (DBG) log("NotifyDisconnectCompleted DisconnectParams=" + dp);
     }
 
-    protected int getRadioTechnology(int defaultRadioTechnology) {
-        int radioTechnology;
+    protected int getRilRadioTechnology(int defaultRilRadioTechnology) {
+        int rilRadioTechnology;
         if (mRilVersion < 6) {
-            radioTechnology = defaultRadioTechnology;
+            rilRadioTechnology = defaultRilRadioTechnology;
         } else {
-            radioTechnology = phone.getServiceState().getRadioTechnology() + 2;
+            rilRadioTechnology = phone.getServiceState().getRilRadioTechnology() + 2;
         }
-        return radioTechnology;
+        return rilRadioTechnology;
     }
 
     /*
diff --git a/telephony/java/com/android/internal/telephony/DataConnectionTracker.java b/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
index 2b9fb91..fa90f1c 100644
--- a/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
@@ -40,6 +40,7 @@
 import android.provider.Settings;
 import android.provider.Settings.SettingNotFoundException;
 import android.telephony.ServiceState;
+import android.telephony.TelephonyManager;
 import android.text.TextUtils;
 import android.util.Log;
 
@@ -1167,15 +1168,14 @@
     }
 
     protected String getReryConfig(boolean forDefault) {
-        int rt = mPhone.getServiceState().getRadioTechnology();
+        int nt = mPhone.getServiceState().getNetworkType();
 
-        if ((rt == ServiceState.RADIO_TECHNOLOGY_IS95A) ||
-            (rt == ServiceState.RADIO_TECHNOLOGY_IS95B) ||
-            (rt == ServiceState.RADIO_TECHNOLOGY_1xRTT) ||
-            (rt == ServiceState.RADIO_TECHNOLOGY_EVDO_0) ||
-            (rt == ServiceState.RADIO_TECHNOLOGY_EVDO_A) ||
-            (rt == ServiceState.RADIO_TECHNOLOGY_EVDO_B) ||
-            (rt == ServiceState.RADIO_TECHNOLOGY_EHRPD)) {
+        if ((nt == TelephonyManager.NETWORK_TYPE_CDMA) ||
+            (nt == TelephonyManager.NETWORK_TYPE_1xRTT) ||
+            (nt == TelephonyManager.NETWORK_TYPE_EVDO_0) ||
+            (nt == TelephonyManager.NETWORK_TYPE_EVDO_A) ||
+            (nt == TelephonyManager.NETWORK_TYPE_EVDO_B) ||
+            (nt == TelephonyManager.NETWORK_TYPE_EHRPD)) {
             // CDMA variant
             return SystemProperties.get("ro.cdma.data_retry_config");
         } else {
diff --git a/telephony/java/com/android/internal/telephony/PhoneProxy.java b/telephony/java/com/android/internal/telephony/PhoneProxy.java
index 2931a02..1a8b3ca 100644
--- a/telephony/java/com/android/internal/telephony/PhoneProxy.java
+++ b/telephony/java/com/android/internal/telephony/PhoneProxy.java
@@ -149,7 +149,7 @@
                     logd("LTE ON CDMA property is set. Switch to CDMALTEPhone" +
                             " newVoiceRadioTech = " + newVoiceRadioTech +
                             " Active Phone = " + mActivePhone.getPhoneName());
-                    newVoiceRadioTech = ServiceState.RADIO_TECHNOLOGY_1xRTT;
+                    newVoiceRadioTech = ServiceState.RIL_RADIO_TECHNOLOGY_1xRTT;
                 }
             } else {
                 if ((ServiceState.isCdma(newVoiceRadioTech) &&
@@ -165,7 +165,7 @@
             }
         }
 
-        if (newVoiceRadioTech == ServiceState.RADIO_TECHNOLOGY_UNKNOWN) {
+        if (newVoiceRadioTech == ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN) {
             // We need some voice phone object to be active always, so never
             // delete the phone without anything to replace it with!
             logd("Ignoring voice radio technology changed message. newVoiceRadioTech = Unknown."
diff --git a/telephony/java/com/android/internal/telephony/ServiceStateTracker.java b/telephony/java/com/android/internal/telephony/ServiceStateTracker.java
index 9c80de7..fd39e04 100644
--- a/telephony/java/com/android/internal/telephony/ServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/ServiceStateTracker.java
@@ -54,10 +54,10 @@
     protected boolean mDesiredPowerState;
 
     /**
-     *  Values correspond to ServiceState.RADIO_TECHNOLOGY_ definitions.
+     *  Values correspond to ServiceState.RIL_RADIO_TECHNOLOGY_ definitions.
      */
-    protected int mRadioTechnology = 0;
-    protected int mNewRadioTechnology = 0;
+    protected int mRilRadioTechnology = 0;
+    protected int mNewRilRadioTechnology = 0;
 
     /**
      * By default, strength polling is enabled.  However, if we're
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java
index a93d94f..64d018e 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java
@@ -86,7 +86,7 @@
         Message msg = obtainMessage(EVENT_SETUP_DATA_CONNECTION_DONE, cp);
         msg.obj = cp;
         phone.mCM.setupDataCall(
-                Integer.toString(getRadioTechnology(RILConstants.SETUP_DATA_TECH_CDMA)),
+                Integer.toString(getRilRadioTechnology(RILConstants.SETUP_DATA_TECH_CDMA)),
                 Integer.toString(dataProfile),
                 null, null, null,
                 Integer.toString(RILConstants.SETUP_DATA_AUTH_PAP_CHAP),
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java
index 7da23d0..cad2e22 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java
@@ -185,19 +185,21 @@
 
     @Override
     protected void pollStateDone() {
-        // determine data NetworkType from both LET and CDMA SS
+        // determine data RadioTechnology from both LET and CDMA SS
         if (mLteSS.getState() == ServiceState.STATE_IN_SERVICE) {
             //in LTE service
-            newNetworkType = mLteSS.getRadioTechnology();
+            mNewRilRadioTechnology = mLteSS.getRilRadioTechnology();
             mNewDataConnectionState = mLteSS.getState();
-            newSS.setRadioTechnology(newNetworkType);
-            log("pollStateDone LTE/eHRPD STATE_IN_SERVICE newNetworkType = " + newNetworkType);
+            newSS.setRadioTechnology(mNewRilRadioTechnology);
+            log("pollStateDone LTE/eHRPD STATE_IN_SERVICE mNewRilRadioTechnology = " +
+                    mNewRilRadioTechnology);
         } else {
             // LTE out of service, get CDMA Service State
-            newNetworkType = newSS.getRadioTechnology();
-            mNewDataConnectionState = radioTechnologyToDataServiceState(newNetworkType);
-            log("pollStateDone CDMA STATE_IN_SERVICE newNetworkType = " + newNetworkType +
-                " mNewDataConnectionState = " + mNewDataConnectionState);
+            mNewRilRadioTechnology = newSS.getRilRadioTechnology();
+            mNewDataConnectionState = radioTechnologyToDataServiceState(mNewRilRadioTechnology);
+            log("pollStateDone CDMA STATE_IN_SERVICE mNewRilRadioTechnology = " +
+                    mNewRilRadioTechnology + " mNewDataConnectionState = " +
+                    mNewDataConnectionState);
         }
 
         // TODO: Add proper support for LTE Only, we should be looking at
@@ -239,7 +241,7 @@
         boolean hasCdmaDataConnectionChanged =
             mDataConnectionState != mNewDataConnectionState;
 
-        boolean hasNetworkTypeChanged = networkType != newNetworkType;
+        boolean hasRadioTechnologyChanged = mRilRadioTechnology != mNewRilRadioTechnology;
 
         boolean hasChanged = !newSS.equals(ss);
 
@@ -251,20 +253,20 @@
 
         boolean has4gHandoff =
                 mNewDataConnectionState == ServiceState.STATE_IN_SERVICE &&
-                (((networkType == ServiceState.RADIO_TECHNOLOGY_LTE) &&
-                  (newNetworkType == ServiceState.RADIO_TECHNOLOGY_EHRPD)) ||
-                 ((networkType == ServiceState.RADIO_TECHNOLOGY_EHRPD) &&
-                  (newNetworkType == ServiceState.RADIO_TECHNOLOGY_LTE)));
+                (((mRilRadioTechnology == ServiceState.RIL_RADIO_TECHNOLOGY_LTE) &&
+                  (mNewRilRadioTechnology == ServiceState.RIL_RADIO_TECHNOLOGY_EHRPD)) ||
+                 ((mRilRadioTechnology == ServiceState.RIL_RADIO_TECHNOLOGY_EHRPD) &&
+                  (mNewRilRadioTechnology == ServiceState.RIL_RADIO_TECHNOLOGY_LTE)));
 
         boolean hasMultiApnSupport =
-                (((newNetworkType == ServiceState.RADIO_TECHNOLOGY_LTE) ||
-                  (newNetworkType == ServiceState.RADIO_TECHNOLOGY_EHRPD)) &&
-                 ((networkType != ServiceState.RADIO_TECHNOLOGY_LTE) &&
-                  (networkType != ServiceState.RADIO_TECHNOLOGY_EHRPD)));
+                (((mNewRilRadioTechnology == ServiceState.RIL_RADIO_TECHNOLOGY_LTE) ||
+                  (mNewRilRadioTechnology == ServiceState.RIL_RADIO_TECHNOLOGY_EHRPD)) &&
+                 ((mRilRadioTechnology != ServiceState.RIL_RADIO_TECHNOLOGY_LTE) &&
+                  (mRilRadioTechnology != ServiceState.RIL_RADIO_TECHNOLOGY_EHRPD)));
 
         boolean hasLostMultiApnSupport =
-            ((newNetworkType >= ServiceState.RADIO_TECHNOLOGY_IS95A) &&
-             (newNetworkType <= ServiceState.RADIO_TECHNOLOGY_EVDO_A));
+            ((mNewRilRadioTechnology >= ServiceState.RIL_RADIO_TECHNOLOGY_IS95A) &&
+             (mNewRilRadioTechnology <= ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_A));
 
         if (DBG) {
             log("pollStateDone:"
@@ -273,7 +275,7 @@
                 + " hasCdmaDataConnectionAttached=" + hasCdmaDataConnectionAttached
                 + " hasCdmaDataConnectionDetached=" + hasCdmaDataConnectionDetached
                 + " hasCdmaDataConnectionChanged=" + hasCdmaDataConnectionChanged
-                + " hasNetworkTypeChanged = " + hasNetworkTypeChanged
+                + " hasRadioTechnologyChanged = " + hasRadioTechnologyChanged
                 + " hasChanged=" + hasChanged
                 + " hasRoamingOn=" + hasRoamingOn
                 + " hasRoamingOff=" + hasRoamingOff
@@ -316,13 +318,14 @@
         newCellLoc = tcl;
 
         mDataConnectionState = mNewDataConnectionState;
-        networkType = newNetworkType;
+        mRilRadioTechnology = mNewRilRadioTechnology;
+        mNewRilRadioTechnology = 0;
 
         newSS.setStateOutOfService(); // clean slate for next time
 
-        if (hasNetworkTypeChanged) {
+        if (hasRadioTechnologyChanged) {
             phone.setSystemProperty(TelephonyProperties.PROPERTY_DATA_NETWORK_TYPE,
-                    ServiceState.radioTechnologyToString(networkType));
+                    ServiceState.rilRadioTechnologyToString(mRilRadioTechnology));
         }
 
         if (hasRegistered) {
@@ -404,7 +407,7 @@
             mDetachedRegistrants.notifyRegistrants();
         }
 
-        if ((hasCdmaDataConnectionChanged || hasNetworkTypeChanged)) {
+        if ((hasCdmaDataConnectionChanged || hasRadioTechnologyChanged)) {
             phone.notifyDataConnection(null);
         }
 
@@ -446,7 +449,7 @@
             int evdoSnr = ((ints[offset + 4] > 0) && (ints[offset + 4] <= 8)) ? ints[offset + 4]
                     : -1;
 
-            if (networkType == ServiceState.RADIO_TECHNOLOGY_LTE) {
+            if (mRilRadioTechnology == ServiceState.RIL_RADIO_TECHNOLOGY_LTE) {
                 lteRssi = ints[offset+5];
                 lteRsrp = ints[offset+6];
                 lteRsrq = ints[offset+7];
@@ -454,7 +457,7 @@
                 lteCqi = ints[offset+9];
             }
 
-            if (networkType != ServiceState.RADIO_TECHNOLOGY_LTE) {
+            if (mRilRadioTechnology != ServiceState.RIL_RADIO_TECHNOLOGY_LTE) {
                 mSignalStrength = new SignalStrength(99, -1, cdmaDbm, cdmaEcio, evdoRssi, evdoEcio,
                         evdoSnr, false);
             } else {
@@ -476,7 +479,7 @@
         // Note: it needs to be confirmed which CDMA network types
         // can support voice and data calls concurrently.
         // For the time-being, the return value will be false.
-        return (networkType == ServiceState.RADIO_TECHNOLOGY_LTE);
+        return (mRilRadioTechnology == ServiceState.RIL_RADIO_TECHNOLOGY_LTE);
     }
 
     /**
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
index 5115d76..75f5d47 100755
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
@@ -86,12 +86,6 @@
     private int mNitzUpdateDiff = SystemProperties.getInt("ro.nitz_update_diff",
             NITZ_UPDATE_DIFF_DEFAULT);
 
-    /**
-     *  Values correspond to ServiceState.RADIO_TECHNOLOGY_ definitions.
-     */
-    protected int networkType = 0;
-    protected int newNetworkType = 0;
-
     private boolean mCdmaRoaming = false;
     private int mRoamingIndicator;
     private boolean mIsInPrl;
@@ -556,10 +550,10 @@
     /**
     * Determine data network type based on radio technology.
     */
-    protected void setCdmaTechnology(int radioTechnology){
-        mNewDataConnectionState = radioTechnologyToDataServiceState(radioTechnology);
-        newSS.setRadioTechnology(radioTechnology);
-        newNetworkType = radioTechnology;
+    protected void setCdmaTechnology(int radioTech){
+        mNewDataConnectionState = radioTechnologyToDataServiceState(radioTech);
+        newSS.setRadioTechnology(radioTech);
+        mNewRilRadioTechnology = radioTech;
     }
 
     /**
@@ -925,7 +919,7 @@
         boolean hasCdmaDataConnectionChanged =
                        mDataConnectionState != mNewDataConnectionState;
 
-        boolean hasNetworkTypeChanged = networkType != newNetworkType;
+        boolean hasRadioTechnologyChanged = mRilRadioTechnology != mNewRilRadioTechnology;
 
         boolean hasChanged = !newSS.equals(ss);
 
@@ -955,15 +949,15 @@
         newCellLoc = tcl;
 
         mDataConnectionState = mNewDataConnectionState;
-        networkType = newNetworkType;
+        mRilRadioTechnology = mNewRilRadioTechnology;
         // this new state has been applied - forget it until we get a new new state
-        newNetworkType = 0;
+        mNewRilRadioTechnology = 0;
 
         newSS.setStateOutOfService(); // clean slate for next time
 
-        if (hasNetworkTypeChanged) {
+        if (hasRadioTechnologyChanged) {
             phone.setSystemProperty(TelephonyProperties.PROPERTY_DATA_NETWORK_TYPE,
-                    ServiceState.radioTechnologyToString(networkType));
+                    ServiceState.rilRadioTechnologyToString(mRilRadioTechnology));
         }
 
         if (hasRegistered) {
@@ -1030,7 +1024,7 @@
             mDetachedRegistrants.notifyRegistrants();
         }
 
-        if (hasCdmaDataConnectionChanged || hasNetworkTypeChanged) {
+        if (hasCdmaDataConnectionChanged || hasRadioTechnologyChanged) {
             phone.notifyDataConnection(null);
         }
 
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmCallTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmCallTracker.java
index 425afe6..b4e0775 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmCallTracker.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmCallTracker.java
@@ -167,7 +167,7 @@
     /**
      * clirMode is one of the CLIR_ constants
      */
-    Connection
+    synchronized Connection
     dial (String dialString, int clirMode, UUSInfo uusInfo) throws CallStateException {
         // note that this triggers call state changed notif
         clearDisconnected();
@@ -406,7 +406,7 @@
         }
     }
 
-    protected void
+    protected synchronized void
     handlePollCalls(AsyncResult ar) {
         List polledCalls;
 
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java
index 1f28280..4956ef4 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java
@@ -100,7 +100,7 @@
         }
 
         phone.mCM.setupDataCall(
-                Integer.toString(getRadioTechnology(RILConstants.SETUP_DATA_TECH_GSM)),
+                Integer.toString(getRilRadioTechnology(RILConstants.SETUP_DATA_TECH_GSM)),
                 Integer.toString(mProfileId),
                 mApn.apn, mApn.user, mApn.password,
                 Integer.toString(authType),
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
index 66e9487..d1873eb 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
@@ -2318,7 +2318,7 @@
         }
 
         String operator = mPhone.mIccRecords.getOperatorNumeric();
-        int radioTech = mPhone.getServiceState().getRadioTechnology();
+        int networkType = mPhone.getServiceState().getNetworkType();
 
         if (requestedApnType.equals(Phone.APN_TYPE_DEFAULT)) {
             if (canSetPreferApn && mPreferredApn != null) {
@@ -2327,7 +2327,7 @@
                         + mPreferredApn.numeric + ":" + mPreferredApn);
                 }
                 if (mPreferredApn.numeric.equals(operator)) {
-                    if (mPreferredApn.bearer == 0 || mPreferredApn.bearer == radioTech) {
+                    if (mPreferredApn.bearer == 0 || mPreferredApn.bearer == networkType) {
                         apnList.add(mPreferredApn);
                         if (DBG) log("buildWaitingApns: X added preferred apnList=" + apnList);
                         return apnList;
@@ -2346,7 +2346,7 @@
         if (mAllApns != null) {
             for (ApnSetting apn : mAllApns) {
                 if (apn.canHandleType(requestedApnType)) {
-                    if (apn.bearer == 0 || apn.bearer == radioTech) {
+                    if (apn.bearer == 0 || apn.bearer == networkType) {
                         if (DBG) log("apn info : " +apn.toString());
                         apnList.add(apn);
                     }
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java
index 0ebeabe..a4fb1d8 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java
@@ -629,7 +629,7 @@
                     }
                     newGPRSState = regCodeToServiceState(regState);
                     mDataRoaming = regCodeIsRoaming(regState);
-                    mNewRadioTechnology = type;
+                    mNewRilRadioTechnology = type;
                     newSS.setRadioTechnology(type);
                 break;
 
@@ -746,8 +746,8 @@
                 " mNewMaxDataCalls=" + mNewMaxDataCalls +
                 " oldReasonDataDenied=" + mReasonDataDenied +
                 " mNewReasonDataDenied=" + mNewReasonDataDenied +
-                " oldType=" + ServiceState.radioTechnologyToString(mRadioTechnology) +
-                " newType=" + ServiceState.radioTechnologyToString(mNewRadioTechnology));
+                " oldType=" + ServiceState.rilRadioTechnologyToString(mRilRadioTechnology) +
+                " newType=" + ServiceState.rilRadioTechnologyToString(mNewRilRadioTechnology));
         }
 
         boolean hasRegistered =
@@ -766,7 +766,7 @@
                 gprsState == ServiceState.STATE_IN_SERVICE
                 && newGPRSState != ServiceState.STATE_IN_SERVICE;
 
-        boolean hasRadioTechnologyChanged = mRadioTechnology != mNewRadioTechnology;
+        boolean hasRadioTechnologyChanged = mRilRadioTechnology != mNewRilRadioTechnology;
 
         boolean hasChanged = !newSS.equals(ss);
 
@@ -800,11 +800,11 @@
             int cid = -1;
             GsmCellLocation loc = ((GsmCellLocation)phone.getCellLocation());
             if (loc != null) cid = loc.getCid();
-            EventLog.writeEvent(EventLogTags.GSM_RAT_SWITCHED, cid, mRadioTechnology,
-                    mNewRadioTechnology);
+            EventLog.writeEvent(EventLogTags.GSM_RAT_SWITCHED, cid, mRilRadioTechnology,
+                    mNewRilRadioTechnology);
             if (DBG) {
-                log("RAT switched " + ServiceState.radioTechnologyToString(mRadioTechnology) +
-                        " -> " + ServiceState.radioTechnologyToString(mNewRadioTechnology) +
+                log("RAT switched " + ServiceState.rilRadioTechnologyToString(mRilRadioTechnology) +
+                        " -> " + ServiceState.rilRadioTechnologyToString(mNewRilRadioTechnology) +
                         " at cell " + cid);
             }
         }
@@ -812,16 +812,16 @@
         gprsState = newGPRSState;
         mReasonDataDenied = mNewReasonDataDenied;
         mMaxDataCalls = mNewMaxDataCalls;
-        mRadioTechnology = mNewRadioTechnology;
+        mRilRadioTechnology = mNewRilRadioTechnology;
         // this new state has been applied - forget it until we get a new new state
-        mNewRadioTechnology = 0;
+        mNewRilRadioTechnology = 0;
 
 
         newSS.setStateOutOfService(); // clean slate for next time
 
         if (hasRadioTechnologyChanged) {
             phone.setSystemProperty(TelephonyProperties.PROPERTY_DATA_NETWORK_TYPE,
-                    ServiceState.radioTechnologyToString(mRadioTechnology));
+                    ServiceState.rilRadioTechnologyToString(mRilRadioTechnology));
         }
 
         if (hasRegistered) {
@@ -1246,7 +1246,7 @@
      * that could support voice and data simultaneously.
      */
     public boolean isConcurrentVoiceAndDataAllowed() {
-        return (mRadioTechnology >= ServiceState.RADIO_TECHNOLOGY_UMTS);
+        return (mRilRadioTechnology >= ServiceState.RIL_RADIO_TECHNOLOGY_UMTS);
     }
 
     /**
diff --git a/test-runner/src/android/test/mock/MockPackageManager.java b/test-runner/src/android/test/mock/MockPackageManager.java
index 58680ea..351c771 100644
--- a/test-runner/src/android/test/mock/MockPackageManager.java
+++ b/test-runner/src/android/test/mock/MockPackageManager.java
@@ -159,6 +159,18 @@
         throw new UnsupportedOperationException();
     }
 
+    /** @hide */
+    @Override
+    public void grantPermission(String packageName, String permissionName) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide */
+    @Override
+    public void revokePermission(String packageName, String permissionName) {
+        throw new UnsupportedOperationException();
+    }
+
     @Override
     public int checkSignatures(String pkg1, String pkg2) {
         throw new UnsupportedOperationException();
diff --git a/tests/HwAccelerationTest/AndroidManifest.xml b/tests/HwAccelerationTest/AndroidManifest.xml
index ed78daa3..b310d93 100644
--- a/tests/HwAccelerationTest/AndroidManifest.xml
+++ b/tests/HwAccelerationTest/AndroidManifest.xml
@@ -568,6 +568,15 @@
         </activity>
 
         <activity
+                android:name="TextOnPathActivity"
+                android:label="_TextOnPath">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+
+        <activity
                 android:name="PathsCacheActivity"
                 android:label="_PathsCache">
             <intent-filter>
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/TextOnPathActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/TextOnPathActivity.java
new file mode 100644
index 0000000..9849e3c
--- /dev/null
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/TextOnPathActivity.java
@@ -0,0 +1,153 @@
+/*
+ * 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.test.hwui;
+
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.Path;
+import android.graphics.PathMeasure;
+import android.os.Bundle;
+import android.view.View;
+
+@SuppressWarnings({"UnusedDeclaration"})
+public class TextOnPathActivity extends Activity {
+    private Path mPath;
+    private Path mStraightPath;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        mPath = makePath();
+        mStraightPath = makeStraightPath();
+
+        final TextOnPathView view = new TextOnPathView(this);
+        setContentView(view);
+    }
+
+    private Path makePath() {
+        Path path = new Path();
+        buildPath(path);
+        return path;
+    }
+
+    private void buildPath(Path path) {
+        path.moveTo(0.0f, 0.0f);
+        path.cubicTo(0.0f, 0.0f, 100.0f, 150.0f, 100.0f, 200.0f);
+        path.cubicTo(100.0f, 200.0f, 50.0f, 300.0f, -80.0f, 200.0f);
+        path.cubicTo(-80.0f, 200.0f, 100.0f, 200.0f, 200.0f, 0.0f);
+    }
+
+    private Path makeStraightPath() {
+        Path path = new Path();
+        buildStraightPath(path);
+        return path;
+    }
+
+    private void buildStraightPath(Path path) {
+        path.moveTo(0.0f, 0.0f);
+        path.lineTo(400.0f, 0.0f);
+    }
+
+    public class TextOnPathView extends View {
+        private static final String TEST_STRING = "Hello OpenGL renderer, text on path! ";
+
+        private final Paint mPaint;
+        private final Paint mPathPaint;
+        private final String mText;
+        private final PathMeasure mMeasure;
+        private final float mLength;
+        private final float[] mLines;
+        private final float[] mPos;
+        private final float[] mTan;
+
+        public TextOnPathView(Context c) {
+            super(c);
+
+            mPaint = new Paint();
+            mPaint.setAntiAlias(true);
+            mPaint.setColor(0xff000000);
+
+            mPathPaint = new Paint();
+            mPathPaint.setAntiAlias(true);
+            mPathPaint.setStyle(Paint.Style.STROKE);
+            mPathPaint.setColor(0xff000099);
+
+            StringBuilder builder = new StringBuilder(TEST_STRING.length() * 2);
+            for (int i = 0; i < 2; i++) {
+                builder.append(TEST_STRING);
+            }
+            mText = builder.toString();
+
+            mMeasure = new PathMeasure(mPath, false);
+            mLength = mMeasure.getLength();
+            
+            mLines = new float[100 * 4];
+            mPos = new float[2];
+            mTan = new float[2];
+        }
+
+        @Override
+        protected void onDraw(Canvas canvas) {
+            super.onDraw(canvas);
+
+            canvas.drawARGB(255, 255, 255, 255);
+
+            canvas.save();
+            canvas.translate(400.0f, 350.0f);
+            mPaint.setTextAlign(Paint.Align.LEFT);
+            canvas.drawTextOnPath(mText + mText, mPath, 0.0f, 0.0f, mPaint);
+            canvas.drawPath(mPath, mPathPaint);
+            
+            for (int i = 0; i < 100; i++) {
+                mMeasure.getPosTan(i * mLength / 100.0f, mPos, mTan);
+                mLines[i * 4    ] = mPos[0];
+                mLines[i * 4 + 1] = mPos[1];
+                mLines[i * 4 + 2] = mPos[0] + mTan[1] * 15;
+                mLines[i * 4 + 3] = mPos[1] - mTan[0] * 15;
+            }
+            canvas.drawLines(mLines, mPathPaint);
+            
+            canvas.translate(200.0f, 0.0f);
+            canvas.drawTextOnPath(mText + mText, mStraightPath, 0.0f, 0.0f, mPaint);
+            canvas.drawPath(mStraightPath, mPathPaint);
+
+            canvas.restore();
+
+            canvas.save();
+            canvas.translate(150.0f, 60.0f);
+            canvas.drawTextOnPath(mText, mPath, 0.0f, 10.0f, mPaint);
+            mMeasure.getPosTan(5.0f, mPos, mTan);
+            canvas.drawLine(mPos[0], mPos[1], mPos[0] + mTan[1] * 10, mPos[1] - mTan[0] * 10,
+                    mPathPaint);
+            canvas.drawPath(mPath, mPathPaint);
+
+            canvas.translate(250.0f, 0.0f);
+            mPaint.setTextAlign(Paint.Align.CENTER);
+            canvas.drawTextOnPath(mText, mPath, 0.0f, 0.0f, mPaint);
+            canvas.drawPath(mPath, mPathPaint);
+
+            canvas.translate(250.0f, 0.0f);
+            mPaint.setTextAlign(Paint.Align.RIGHT);
+            canvas.drawTextOnPath(mText, mPath, 0.0f, 0.0f, mPaint);
+            canvas.drawPath(mPath, mPathPaint);
+            canvas.restore();
+        }
+    }
+}
diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/RSTestCore.java b/tests/RenderScriptTests/tests/src/com/android/rs/test/RSTestCore.java
index 6f56223..22e1bff 100644
--- a/tests/RenderScriptTests/tests/src/com/android/rs/test/RSTestCore.java
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/RSTestCore.java
@@ -68,6 +68,7 @@
         unitTests.add(new UT_constant(this, mRes, mCtx));
         unitTests.add(new UT_vector(this, mRes, mCtx));
         unitTests.add(new UT_array_init(this, mRes, mCtx));
+        unitTests.add(new UT_convert(this, mRes, mCtx));
         unitTests.add(new UT_rsdebug(this, mRes, mCtx));
         unitTests.add(new UT_rstime(this, mRes, mCtx));
         unitTests.add(new UT_rstypes(this, mRes, mCtx));
diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_convert.java b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_convert.java
new file mode 100644
index 0000000..4fc6c55
--- /dev/null
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_convert.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.rs.test;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.renderscript.*;
+
+public class UT_convert extends UnitTest {
+    private Resources mRes;
+
+    protected UT_convert(RSTestCore rstc, Resources res, Context ctx) {
+        super(rstc, "Convert", ctx);
+        mRes = res;
+    }
+
+    public void run() {
+        RenderScript pRS = RenderScript.create(mCtx);
+        ScriptC_convert s = new ScriptC_convert(pRS, mRes, R.raw.convert);
+        pRS.setMessageHandler(mRsMessage);
+        s.invoke_convert_test();
+        pRS.finish();
+        waitForMessage();
+        pRS.destroy();
+    }
+}
diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/convert.rs b/tests/RenderScriptTests/tests/src/com/android/rs/test/convert.rs
new file mode 100644
index 0000000..e314f2b
--- /dev/null
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/convert.rs
@@ -0,0 +1,37 @@
+#include "shared.rsh"
+
+float4 f4 = { 2.0f, 4.0f, 6.0f, 8.0f };
+
+char4 i8_4 = { -1, -2, -3, 4 };
+
+static bool test_convert() {
+    bool failed = false;
+
+    f4 = convert_float4(i8_4);
+    _RS_ASSERT(f4.x == -1.0f);
+    _RS_ASSERT(f4.y == -2.0f);
+    _RS_ASSERT(f4.z == -3.0f);
+    _RS_ASSERT(f4.w == 4.0f);
+
+    if (failed) {
+        rsDebug("test_convert FAILED", 0);
+    }
+    else {
+        rsDebug("test_convert PASSED", 0);
+    }
+
+    return failed;
+}
+
+void convert_test() {
+    bool failed = false;
+    failed |= test_convert();
+
+    if (failed) {
+        rsSendToClientBlocking(RS_MSG_TEST_FAILED);
+    }
+    else {
+        rsSendToClientBlocking(RS_MSG_TEST_PASSED);
+    }
+}
+
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeConstants.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeConstants.java
index 112af1e..eb9e7f1da 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeConstants.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeConstants.java
@@ -39,6 +39,9 @@
     /** Namespace for the resource XML */
     public final static String NS_RESOURCES = "http://schemas.android.com/apk/res/android";
 
+    /** App auto namespace */
+    public final static String NS_APP_RES_AUTO = "http://schemas.android.com/apk/res-auto";
+
     public final static String R = "com.android.internal.R";
 
 
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
index cd085fc..58dc2d4 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
@@ -49,8 +49,8 @@
 import android.content.res.BridgeTypedArray;
 import android.content.res.Configuration;
 import android.content.res.Resources;
-import android.content.res.TypedArray;
 import android.content.res.Resources.Theme;
+import android.content.res.TypedArray;
 import android.database.DatabaseErrorHandler;
 import android.database.sqlite.SQLiteDatabase;
 import android.database.sqlite.SQLiteDatabase.CursorFactory;
@@ -78,8 +78,8 @@
 import java.util.HashMap;
 import java.util.IdentityHashMap;
 import java.util.Map;
-import java.util.TreeMap;
 import java.util.Map.Entry;
+import java.util.TreeMap;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicReference;
 
@@ -615,7 +615,8 @@
         }
 
         String namespace = BridgeConstants.NS_RESOURCES;
-        if (frameworkAttributes.get() == false) {
+        boolean useFrameworkNS = frameworkAttributes.get();
+        if (useFrameworkNS == false) {
             // need to use the application namespace
             namespace = mProjectCallback.getNamespace();
         }
@@ -628,6 +629,12 @@
                 String value = null;
                 if (set != null) {
                     value = set.getAttributeValue(namespace, name);
+
+                    // if this is an app attribute, and the first get fails, try with the
+                    // new res-auto namespace as well
+                    if (useFrameworkNS == false && value == null) {
+                        value = set.getAttributeValue(BridgeConstants.NS_APP_RES_AUTO, name);
+                    }
                 }
 
                 // if there's no direct value for this attribute in the XML, we look for default
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeIInputMethodManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeIInputMethodManager.java
index 6afdfbe..d6abbaa 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeIInputMethodManager.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeIInputMethodManager.java
@@ -184,8 +184,8 @@
     }
 
     @Override
-    public InputBindResult startInput(IInputMethodClient arg0, IInputContext arg1, EditorInfo arg2,
-            boolean arg3, boolean arg4) throws RemoteException {
+    public InputBindResult startInput(IInputMethodClient client, IInputContext inputContext,
+            EditorInfo attribute, int controlFlags) throws RemoteException {
         // TODO Auto-generated method stub
         return null;
     }
@@ -209,10 +209,11 @@
     }
 
     @Override
-    public void windowGainedFocus(IInputMethodClient arg0, IBinder arg1, boolean arg2,
-            boolean arg3, int arg4, boolean arg5, int arg6) throws RemoteException {
+    public InputBindResult windowGainedFocus(IInputMethodClient client, IBinder windowToken,
+            int controlFlags, int softInputMode, int windowFlags, EditorInfo attribute,
+            IInputContext inputContext) throws RemoteException {
         // TODO Auto-generated method stub
-
+        return null;
     }
 
     @Override