Merge "Fix return type mismatch in Region's JNI code."
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 2c7d16f..5634b43 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -154,7 +154,7 @@
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib/librtp_jni.so)
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/lib/librtp_jni.so)
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/symbols/system/lib/librtp_jni.so)
-
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/telephony/java/com/android/internal/telephony/SmsRawData.*)
 # ************************************************
 # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
 # ************************************************
diff --git a/api/current.txt b/api/current.txt
index 9cd44ed..e7d1d54 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -36,6 +36,8 @@
     field public static final java.lang.String CALL_PHONE = "android.permission.CALL_PHONE";
     field public static final java.lang.String CALL_PRIVILEGED = "android.permission.CALL_PRIVILEGED";
     field public static final java.lang.String CAMERA = "android.permission.CAMERA";
+    field public static final java.lang.String CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY = "android.permission.CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY";
+    field public static final java.lang.String CAN_REQUEST_TOUCH_EXPLORATION_MODE = "android.permission.CAN_REQUEST_TOUCH_EXPLORATION_MODE";
     field public static final java.lang.String CHANGE_COMPONENT_ENABLED_STATE = "android.permission.CHANGE_COMPONENT_ENABLED_STATE";
     field public static final java.lang.String CHANGE_CONFIGURATION = "android.permission.CHANGE_CONFIGURATION";
     field public static final java.lang.String CHANGE_NETWORK_STATE = "android.permission.CHANGE_NETWORK_STATE";
@@ -141,6 +143,7 @@
 
   public static final class Manifest.permission_group {
     ctor public Manifest.permission_group();
+    field public static final java.lang.String ACCESSIBILITY_FEATURES = "android.permission-group.ACCESSIBILITY_FEATURES";
     field public static final java.lang.String ACCOUNTS = "android.permission-group.ACCOUNTS";
     field public static final java.lang.String AFFECTS_BATTERY = "android.permission-group.AFFECTS_BATTERY";
     field public static final java.lang.String APP_INFO = "android.permission-group.APP_INFO";
@@ -725,6 +728,7 @@
     field public static final int minSdkVersion = 16843276; // 0x101020c
     field public static final int minWidth = 16843071; // 0x101013f
     field public static final int mipMap = 16843725; // 0x10103cd
+    field public static final int mirrorForRtl = 16843726; // 0x10103ce
     field public static final int mode = 16843134; // 0x101017e
     field public static final int moreIcon = 16843061; // 0x1010135
     field public static final int multiprocess = 16842771; // 0x1010013
@@ -2104,7 +2108,8 @@
     field public static final int FEEDBACK_SPOKEN = 1; // 0x1
     field public static final int FEEDBACK_VISUAL = 8; // 0x8
     field public static final int FLAG_INCLUDE_NOT_IMPORTANT_VIEWS = 2; // 0x2
-    field public static final int FLAG_REPORT_VIEW_IDS = 8; // 0x8
+    field public static final int FLAG_REPORT_VIEW_IDS = 16; // 0x10
+    field public static final int FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY = 8; // 0x8
     field public static final int FLAG_REQUEST_TOUCH_EXPLORATION_MODE = 4; // 0x4
     field public int eventTypes;
     field public int feedbackType;
@@ -24181,6 +24186,8 @@
     field public static final int KEYCODE_BACKSLASH = 73; // 0x49
     field public static final int KEYCODE_BOOKMARK = 174; // 0xae
     field public static final int KEYCODE_BREAK = 121; // 0x79
+    field public static final int KEYCODE_BRIGHTNESS_DOWN = 220; // 0xdc
+    field public static final int KEYCODE_BRIGHTNESS_UP = 221; // 0xdd
     field public static final int KEYCODE_BUTTON_1 = 188; // 0xbc
     field public static final int KEYCODE_BUTTON_10 = 197; // 0xc5
     field public static final int KEYCODE_BUTTON_11 = 198; // 0xc6
@@ -26348,21 +26355,28 @@
     method public void setVisibleToUser(boolean);
     method public void writeToParcel(android.os.Parcel, int);
     field public static final int ACTION_ACCESSIBILITY_FOCUS = 64; // 0x40
+    field public static final java.lang.String ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN = "ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN";
     field public static final java.lang.String ACTION_ARGUMENT_HTML_ELEMENT_STRING = "ACTION_ARGUMENT_HTML_ELEMENT_STRING";
     field public static final java.lang.String ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT = "ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT";
+    field public static final java.lang.String ACTION_ARGUMENT_SELECTION_END_INT = "ACTION_ARGUMENT_SELECTION_END_INT";
+    field public static final java.lang.String ACTION_ARGUMENT_SELECTION_START_INT = "ACTION_ARGUMENT_SELECTION_START_INT";
     field public static final int ACTION_CLEAR_ACCESSIBILITY_FOCUS = 128; // 0x80
     field public static final int ACTION_CLEAR_FOCUS = 2; // 0x2
     field public static final int ACTION_CLEAR_SELECTION = 8; // 0x8
     field public static final int ACTION_CLICK = 16; // 0x10
+    field public static final int ACTION_COPY = 16384; // 0x4000
+    field public static final int ACTION_CUT = 65536; // 0x10000
     field public static final int ACTION_FOCUS = 1; // 0x1
     field public static final int ACTION_LONG_CLICK = 32; // 0x20
     field public static final int ACTION_NEXT_AT_MOVEMENT_GRANULARITY = 256; // 0x100
     field public static final int ACTION_NEXT_HTML_ELEMENT = 1024; // 0x400
+    field public static final int ACTION_PASTE = 32768; // 0x8000
     field public static final int ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY = 512; // 0x200
     field public static final int ACTION_PREVIOUS_HTML_ELEMENT = 2048; // 0x800
     field public static final int ACTION_SCROLL_BACKWARD = 8192; // 0x2000
     field public static final int ACTION_SCROLL_FORWARD = 4096; // 0x1000
     field public static final int ACTION_SELECT = 4; // 0x4
+    field public static final int ACTION_SET_SELECTION = 131072; // 0x20000
     field public static final android.os.Parcelable.Creator CREATOR;
     field public static final int FOCUS_ACCESSIBILITY = 2; // 0x2
     field public static final int FOCUS_INPUT = 1; // 0x1
diff --git a/cmds/am/src/com/android/commands/am/Am.java b/cmds/am/src/com/android/commands/am/Am.java
index b5574cf..1c5f32e 100644
--- a/cmds/am/src/com/android/commands/am/Am.java
+++ b/cmds/am/src/com/android/commands/am/Am.java
@@ -488,11 +488,11 @@
             IActivityManager.WaitResult result = null;
             int res;
             if (mWaitOption) {
-                result = mAm.startActivityAndWait(null, intent, mimeType,
+                result = mAm.startActivityAndWait(null, null, intent, mimeType,
                             null, null, 0, mStartFlags, mProfileFile, fd, null, mUserId);
                 res = result.result;
             } else {
-                res = mAm.startActivityAsUser(null, intent, mimeType,
+                res = mAm.startActivityAsUser(null, null, intent, mimeType,
                         null, null, 0, mStartFlags, mProfileFile, fd, null, mUserId);
             }
             PrintStream out = mWaitOption ? System.out : System.err;
diff --git a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
index 2006bc7..d12a336 100644
--- a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
+++ b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
@@ -149,8 +149,38 @@
      * accessibility service that has this flag set. Hence, clearing this
      * flag does not guarantee that the device will not be in touch exploration
      * mode since there may be another enabled service that requested it.
+     * <p>
+     * For accessibility services targeting API version higher than
+     * {@link Build.VERSION_CODES#JELLY_BEAN_MR1} that want to set
+     * this flag have to request the
+     * {@link android.Manifest.permission#CAN_REQUEST_TOUCH_EXPLORATION_MODE}
+     * permission or the flag will be ignored.
+     * </p>
+     * <p>
+     * Services targeting API version equal to or lower than
+     * {@link Build.VERSION_CODES#JELLY_BEAN_MR1} will work normally, i.e.
+     * the first time they are run, if this flag is specified, a dialog is
+     * shown to the user to confirm enabling explore by touch.
+     * </p>
      */
-    public static final int FLAG_REQUEST_TOUCH_EXPLORATION_MODE= 0x0000004;
+    public static final int FLAG_REQUEST_TOUCH_EXPLORATION_MODE = 0x0000004;
+
+    /**
+     * This flag requests from the system to enable web accessibility enhancing
+     * extensions. Such extensions aim to provide improved accessibility support
+     * for content presented in a {@link android.webkit.WebView}. An example of such
+     * an extension is injecting JavaScript from Google. The system will enable
+     * enhanced web accessibility if there is at least one accessibility service
+     * that has this flag set. Hence, clearing this flag does not guarantee that the
+     * device will not have enhanced web accessibility enabled since there may be
+     * another enabled service that requested it.
+     * <p>
+     * Clients that want to set this flag have to request the
+     * {@link android.Manifest.permission#CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY}
+     * permission or the flag will be ignored.
+     * </p>
+     */
+    public static final int FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY = 0x00000008;
 
     /**
      * This flag requests that the {@link AccessibilityNodeInfo}s obtained
@@ -159,7 +189,7 @@
      * form "package:id/name", for example "foo.bar:id/my_list", and it is
      * useful for UI test automation. This flag is not set by default.
      */
-    public static final int FLAG_REPORT_VIEW_IDS = 0x00000008;
+    public static final int FLAG_REPORT_VIEW_IDS = 0x00000010;
 
     /**
      * The event types an {@link AccessibilityService} is interested in.
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 18ccd53..87c2d8c 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -3740,7 +3740,7 @@
             try {
                 intent.setAllowFds(false);
                 result = ActivityManagerNative.getDefault()
-                    .startActivity(mMainThread.getApplicationThread(),
+                    .startActivity(mMainThread.getApplicationThread(), getBasePackageName(),
                             intent, intent.resolveTypeIfNeeded(getContentResolver()),
                             mToken, mEmbeddedID, requestCode,
                             ActivityManager.START_FLAG_ONLY_IF_NEEDED, null, null,
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index d8e2239..c9930e9 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -116,6 +116,7 @@
             data.enforceInterface(IActivityManager.descriptor);
             IBinder b = data.readStrongBinder();
             IApplicationThread app = ApplicationThreadNative.asInterface(b);
+            String callingPackage = data.readString();
             Intent intent = Intent.CREATOR.createFromParcel(data);
             String resolvedType = data.readString();
             IBinder resultTo = data.readStrongBinder();
@@ -127,7 +128,7 @@
                     ? data.readFileDescriptor() : null;
             Bundle options = data.readInt() != 0
                     ? Bundle.CREATOR.createFromParcel(data) : null;
-            int result = startActivity(app, intent, resolvedType,
+            int result = startActivity(app, callingPackage, intent, resolvedType,
                     resultTo, resultWho, requestCode, startFlags,
                     profileFile, profileFd, options);
             reply.writeNoException();
@@ -140,6 +141,7 @@
             data.enforceInterface(IActivityManager.descriptor);
             IBinder b = data.readStrongBinder();
             IApplicationThread app = ApplicationThreadNative.asInterface(b);
+            String callingPackage = data.readString();
             Intent intent = Intent.CREATOR.createFromParcel(data);
             String resolvedType = data.readString();
             IBinder resultTo = data.readStrongBinder();
@@ -152,7 +154,7 @@
             Bundle options = data.readInt() != 0
                     ? Bundle.CREATOR.createFromParcel(data) : null;
             int userId = data.readInt();
-            int result = startActivityAsUser(app, intent, resolvedType,
+            int result = startActivityAsUser(app, callingPackage, intent, resolvedType,
                     resultTo, resultWho, requestCode, startFlags,
                     profileFile, profileFd, options, userId);
             reply.writeNoException();
@@ -165,6 +167,7 @@
             data.enforceInterface(IActivityManager.descriptor);
             IBinder b = data.readStrongBinder();
             IApplicationThread app = ApplicationThreadNative.asInterface(b);
+            String callingPackage = data.readString();
             Intent intent = Intent.CREATOR.createFromParcel(data);
             String resolvedType = data.readString();
             IBinder resultTo = data.readStrongBinder();
@@ -177,7 +180,7 @@
             Bundle options = data.readInt() != 0
                     ? Bundle.CREATOR.createFromParcel(data) : null;
             int userId = data.readInt();
-            WaitResult result = startActivityAndWait(app, intent, resolvedType,
+            WaitResult result = startActivityAndWait(app, callingPackage, intent, resolvedType,
                     resultTo, resultWho, requestCode, startFlags,
                     profileFile, profileFd, options, userId);
             reply.writeNoException();
@@ -190,6 +193,7 @@
             data.enforceInterface(IActivityManager.descriptor);
             IBinder b = data.readStrongBinder();
             IApplicationThread app = ApplicationThreadNative.asInterface(b);
+            String callingPackage = data.readString();
             Intent intent = Intent.CREATOR.createFromParcel(data);
             String resolvedType = data.readString();
             IBinder resultTo = data.readStrongBinder();
@@ -200,7 +204,7 @@
             Bundle options = data.readInt() != 0
                     ? Bundle.CREATOR.createFromParcel(data) : null;
             int userId = data.readInt();
-            int result = startActivityWithConfig(app, intent, resolvedType,
+            int result = startActivityWithConfig(app, callingPackage, intent, resolvedType,
                     resultTo, resultWho, requestCode, startFlags, config, options, userId);
             reply.writeNoException();
             reply.writeInt(result);
@@ -1526,13 +1530,14 @@
             data.enforceInterface(IActivityManager.descriptor);
             IBinder b = data.readStrongBinder();
             IApplicationThread app = ApplicationThreadNative.asInterface(b);
+            String callingPackage = data.readString();
             Intent[] intents = data.createTypedArray(Intent.CREATOR);
             String[] resolvedTypes = data.createStringArray();
             IBinder resultTo = data.readStrongBinder();
             Bundle options = data.readInt() != 0
                     ? Bundle.CREATOR.createFromParcel(data) : null;
             int userId = data.readInt();
-            int result = startActivities(app, intents, resolvedTypes, resultTo,
+            int result = startActivities(app, callingPackage, intents, resolvedTypes, resultTo,
                     options, userId);
             reply.writeNoException();
             reply.writeInt(result);
@@ -1784,6 +1789,15 @@
             return true;
         }
 
+        case GET_LAUNCHED_FROM_PACKAGE_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            IBinder token = data.readStrongBinder();
+            String res = getLaunchedFromPackage(token);
+            reply.writeNoException();
+            reply.writeString(res);
+            return true;
+        }
+
         case REGISTER_USER_SWITCH_OBSERVER_TRANSACTION: {
             data.enforceInterface(IActivityManager.descriptor);
             IUserSwitchObserver observer = IUserSwitchObserver.Stub.asInterface(
@@ -1873,7 +1887,7 @@
         return mRemote;
     }
 
-    public int startActivity(IApplicationThread caller, Intent intent,
+    public int startActivity(IApplicationThread caller, String callingPackage, Intent intent,
             String resolvedType, IBinder resultTo, String resultWho, int requestCode,
             int startFlags, String profileFile,
             ParcelFileDescriptor profileFd, Bundle options) throws RemoteException {
@@ -1881,6 +1895,7 @@
         Parcel reply = Parcel.obtain();
         data.writeInterfaceToken(IActivityManager.descriptor);
         data.writeStrongBinder(caller != null ? caller.asBinder() : null);
+        data.writeString(callingPackage);
         intent.writeToParcel(data, 0);
         data.writeString(resolvedType);
         data.writeStrongBinder(resultTo);
@@ -1908,7 +1923,7 @@
         return result;
     }
 
-    public int startActivityAsUser(IApplicationThread caller, Intent intent,
+    public int startActivityAsUser(IApplicationThread caller, String callingPackage, Intent intent,
             String resolvedType, IBinder resultTo, String resultWho, int requestCode,
             int startFlags, String profileFile,
             ParcelFileDescriptor profileFd, Bundle options, int userId) throws RemoteException {
@@ -1916,6 +1931,7 @@
         Parcel reply = Parcel.obtain();
         data.writeInterfaceToken(IActivityManager.descriptor);
         data.writeStrongBinder(caller != null ? caller.asBinder() : null);
+        data.writeString(callingPackage);
         intent.writeToParcel(data, 0);
         data.writeString(resolvedType);
         data.writeStrongBinder(resultTo);
@@ -1943,14 +1959,15 @@
         data.recycle();
         return result;
     }
-    public WaitResult startActivityAndWait(IApplicationThread caller, Intent intent,
-            String resolvedType, IBinder resultTo, String resultWho,
+    public WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
+            Intent intent, String resolvedType, IBinder resultTo, String resultWho,
             int requestCode, int startFlags, String profileFile,
             ParcelFileDescriptor profileFd, Bundle options, int userId) throws RemoteException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
         data.writeInterfaceToken(IActivityManager.descriptor);
         data.writeStrongBinder(caller != null ? caller.asBinder() : null);
+        data.writeString(callingPackage);
         intent.writeToParcel(data, 0);
         data.writeString(resolvedType);
         data.writeStrongBinder(resultTo);
@@ -1978,14 +1995,15 @@
         data.recycle();
         return result;
     }
-    public int startActivityWithConfig(IApplicationThread caller, Intent intent,
-            String resolvedType, IBinder resultTo, String resultWho,
+    public int startActivityWithConfig(IApplicationThread caller, String callingPackage,
+            Intent intent, String resolvedType, IBinder resultTo, String resultWho,
             int requestCode, int startFlags, Configuration config,
             Bundle options, int userId) throws RemoteException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
         data.writeInterfaceToken(IActivityManager.descriptor);
         data.writeStrongBinder(caller != null ? caller.asBinder() : null);
+        data.writeString(callingPackage);
         intent.writeToParcel(data, 0);
         data.writeString(resolvedType);
         data.writeStrongBinder(resultTo);
@@ -3771,13 +3789,14 @@
         return res;
     }
     
-    public int startActivities(IApplicationThread caller,
+    public int startActivities(IApplicationThread caller, String callingPackage,
             Intent[] intents, String[] resolvedTypes, IBinder resultTo,
             Bundle options, int userId) throws RemoteException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
         data.writeInterfaceToken(IActivityManager.descriptor);
         data.writeStrongBinder(caller != null ? caller.asBinder() : null);
+        data.writeString(callingPackage);
         data.writeTypedArray(intents, 0);
         data.writeStringArray(resolvedTypes);
         data.writeStrongBinder(resultTo);
@@ -4123,6 +4142,19 @@
         return result;
     }
 
+    public String getLaunchedFromPackage(IBinder activityToken) throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeStrongBinder(activityToken);
+        mRemote.transact(GET_LAUNCHED_FROM_PACKAGE_TRANSACTION, data, reply, 0);
+        reply.readException();
+        String result = reply.readString();
+        data.recycle();
+        reply.recycle();
+        return result;
+    }
+
     public void registerUserSwitchObserver(IUserSwitchObserver observer) throws RemoteException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index b1d0305..a81b6fe 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -16,6 +16,7 @@
 
 package android.app;
 
+import android.Manifest;
 import com.android.internal.app.IAppOpsService;
 
 import java.util.ArrayList;
@@ -47,35 +48,83 @@
     public static final int OP_READ_CALENDAR = 8;
     public static final int OP_WRITE_CALENDAR = 9;
     public static final int OP_WIFI_SCAN = 10;
+    public static final int OP_POST_NOTIFICATION = 11;
+    public static final int OP_NEIGHBORING_CELLS = 12;
+    public static final int OP_CALL_PHONE = 13;
+    /** @hide */
+    public static final int _NUM_OP = 14;
 
+    /**
+     * This maps each operation to the operation that serves as the
+     * switch to determine whether it is allowed.  Generally this is
+     * a 1:1 mapping, but for some things (like location) that have
+     * multiple low-level operations being tracked that should be
+     * presented to hte user as one switch then this can be used to
+     * make them all controlled by the same single operation.
+     */
+    private static int[] sOpToSwitch = new int[] {
+            OP_COARSE_LOCATION,
+            OP_COARSE_LOCATION,
+            OP_COARSE_LOCATION,
+            OP_VIBRATE,
+            OP_READ_CONTACTS,
+            OP_WRITE_CONTACTS,
+            OP_READ_CALL_LOG,
+            OP_WRITE_CALL_LOG,
+            OP_READ_CALENDAR,
+            OP_WRITE_CALENDAR,
+            OP_COARSE_LOCATION,
+            OP_POST_NOTIFICATION,
+            OP_COARSE_LOCATION,
+            OP_CALL_PHONE,
+    };
+
+    /**
+     * This provides a simple name for each operation to be used
+     * in debug output.
+     */
     private static String[] sOpNames = new String[] {
-        "COARSE_LOCATION",
-        "FINE_LOCATION",
-        "GPS",
-        "VIBRATE",
-        "READ_CONTACTS",
-        "WRITE_CONTACTS",
-        "READ_CALL_LOG",
-        "WRITE_CALL_LOG",
-        "READ_CALENDAR",
-        "WRITE_CALENDAR",
-        "WIFI_SCAN",
+            "COARSE_LOCATION",
+            "FINE_LOCATION",
+            "GPS",
+            "VIBRATE",
+            "READ_CONTACTS",
+            "WRITE_CONTACTS",
+            "READ_CALL_LOG",
+            "WRITE_CALL_LOG",
+            "READ_CALENDAR",
+            "WRITE_CALENDAR",
+            "WIFI_SCAN",
+            "POST_NOTIFICATION",
+            "NEIGHBORING_CELLS",
+            "CALL_PHONE",
     };
 
+    /**
+     * This optionally maps a permission to an operation.  If there
+     * is no permission associated with an operation, it is null.
+     */
     private static String[] sOpPerms = new String[] {
-        android.Manifest.permission.ACCESS_COARSE_LOCATION,
-        android.Manifest.permission.ACCESS_FINE_LOCATION,
-        android.Manifest.permission.ACCESS_FINE_LOCATION,
-        android.Manifest.permission.VIBRATE,
-        android.Manifest.permission.READ_CONTACTS,
-        android.Manifest.permission.WRITE_CONTACTS,
-        android.Manifest.permission.READ_CALL_LOG,
-        android.Manifest.permission.WRITE_CALL_LOG,
-        android.Manifest.permission.READ_CALENDAR,
-        android.Manifest.permission.WRITE_CALENDAR,
-        android.Manifest.permission.ACCESS_WIFI_STATE,
+            android.Manifest.permission.ACCESS_COARSE_LOCATION,
+            android.Manifest.permission.ACCESS_FINE_LOCATION,
+            null,
+            android.Manifest.permission.VIBRATE,
+            android.Manifest.permission.READ_CONTACTS,
+            android.Manifest.permission.WRITE_CONTACTS,
+            android.Manifest.permission.READ_CALL_LOG,
+            android.Manifest.permission.WRITE_CALL_LOG,
+            android.Manifest.permission.READ_CALENDAR,
+            android.Manifest.permission.WRITE_CALENDAR,
+            null, // no permission required for notifications
+            android.Manifest.permission.ACCESS_WIFI_STATE,
+            null, // neighboring cells shares the coarse location perm
+            android.Manifest.permission.CALL_PHONE,
     };
 
+    public static int opToSwitch(int op) {
+        return sOpToSwitch[op];
+    }
+
     public static String opToName(int op) {
         return op < sOpNames.length ? sOpNames[op] : ("Unknown(" + op + ")");
     }
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index e03d3fd..2cf9f59 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -963,7 +963,7 @@
     public void startActivityAsUser(Intent intent, Bundle options, UserHandle user) {
         try {
             ActivityManagerNative.getDefault().startActivityAsUser(
-                mMainThread.getApplicationThread(), intent,
+                mMainThread.getApplicationThread(), getBasePackageName(), intent,
                 intent.resolveTypeIfNeeded(getContentResolver()),
                 null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null, null, options,
                 user.getIdentifier());
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index 5a493294..e58ff62 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -51,19 +51,19 @@
  * {@hide}
  */
 public interface IActivityManager extends IInterface {
-    public int startActivity(IApplicationThread caller,
+    public int startActivity(IApplicationThread caller, String callingPackage,
             Intent intent, String resolvedType, IBinder resultTo, String resultWho,
             int requestCode, int flags, String profileFile,
             ParcelFileDescriptor profileFd, Bundle options) throws RemoteException;
-    public int startActivityAsUser(IApplicationThread caller,
+    public int startActivityAsUser(IApplicationThread caller, String callingPackage,
             Intent intent, String resolvedType, IBinder resultTo, String resultWho,
             int requestCode, int flags, String profileFile,
             ParcelFileDescriptor profileFd, Bundle options, int userId) throws RemoteException;
-    public WaitResult startActivityAndWait(IApplicationThread caller,
+    public WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
             Intent intent, String resolvedType, IBinder resultTo, String resultWho,
             int requestCode, int flags, String profileFile,
             ParcelFileDescriptor profileFd, Bundle options, int userId) throws RemoteException;
-    public int startActivityWithConfig(IApplicationThread caller,
+    public int startActivityWithConfig(IApplicationThread caller, String callingPackage,
             Intent intent, String resolvedType, IBinder resultTo, String resultWho,
             int requestCode, int startFlags, Configuration newConfig,
             Bundle options, int userId) throws RemoteException;
@@ -310,7 +310,7 @@
     public boolean dumpHeap(String process, int userId, boolean managed, String path,
         ParcelFileDescriptor fd) throws RemoteException;
 
-    public int startActivities(IApplicationThread caller,
+    public int startActivities(IApplicationThread caller, String callingPackage,
             Intent[] intents, String[] resolvedTypes, IBinder resultTo,
             Bundle options, int userId) throws RemoteException;
 
@@ -357,9 +357,10 @@
     public boolean navigateUpTo(IBinder token, Intent target, int resultCode, Intent resultData)
             throws RemoteException;
 
-    // This is not public because you need to be very careful in how you
+    // These are not public because you need to be very careful in how you
     // manage your activity to make sure it is always the uid you expect.
     public int getLaunchedFromUid(IBinder activityToken) throws RemoteException;
+    public String getLaunchedFromPackage(IBinder activityToken) throws RemoteException;
 
     public void registerUserSwitchObserver(IUserSwitchObserver observer) throws RemoteException;
     public void unregisterUserSwitchObserver(IUserSwitchObserver observer) throws RemoteException;
@@ -630,4 +631,5 @@
     int GET_INTENT_FOR_INTENT_SENDER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+160;
     int GET_TOP_ACTIVITY_EXTRAS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+161;
     int REPORT_TOP_ACTIVITY_EXTRAS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+162;
+    int GET_LAUNCHED_FROM_PACKAGE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+163;
 }
diff --git a/core/java/android/app/INotificationManager.aidl b/core/java/android/app/INotificationManager.aidl
index 62d4962..d400eba 100644
--- a/core/java/android/app/INotificationManager.aidl
+++ b/core/java/android/app/INotificationManager.aidl
@@ -28,11 +28,11 @@
 
     void enqueueToast(String pkg, ITransientNotification callback, int duration);
     void cancelToast(String pkg, ITransientNotification callback);
-    void enqueueNotificationWithTag(String pkg, String tag, int id,
+    void enqueueNotificationWithTag(String pkg, String basePkg, String tag, int id,
             in Notification notification, inout int[] idReceived, int userId);
     void cancelNotificationWithTag(String pkg, String tag, int id, int userId);
 
-    void setNotificationsEnabledForPackage(String pkg, boolean enabled);
-    boolean areNotificationsEnabledForPackage(String pkg);
+    void setNotificationsEnabledForPackage(String pkg, int uid, boolean enabled);
+    boolean areNotificationsEnabledForPackage(String pkg, int uid);
 }
 
diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java
index a2eeddd..e7bf305 100644
--- a/core/java/android/app/Instrumentation.java
+++ b/core/java/android/app/Instrumentation.java
@@ -1413,7 +1413,7 @@
             intent.setAllowFds(false);
             intent.migrateExtraStreamToClipData();
             int result = ActivityManagerNative.getDefault()
-                .startActivity(whoThread, intent,
+                .startActivity(whoThread, who.getBasePackageName(), intent,
                         intent.resolveTypeIfNeeded(who.getContentResolver()),
                         token, target != null ? target.mEmbeddedID : null,
                         requestCode, 0, null, null, options);
@@ -1471,15 +1471,16 @@
                 resolvedTypes[i] = intents[i].resolveTypeIfNeeded(who.getContentResolver());
             }
             int result = ActivityManagerNative.getDefault()
-                .startActivities(whoThread, intents, resolvedTypes, token, options,
-                        userId);
+                .startActivities(whoThread, who.getBasePackageName(), intents, resolvedTypes,
+                        token, options, userId);
             checkStartActivityResult(result, intents[0]);
         } catch (RemoteException e) {
         }
     }
 
     /**
-     * Like {@link #execStartActivity(Context, IBinder, IBinder, Activity, Intent, int)},
+     * Like {@link #execStartActivity(android.content.Context, android.os.IBinder,
+     * android.os.IBinder, Fragment, android.content.Intent, int, android.os.Bundle)},
      * but for calls from a {#link Fragment}.
      * 
      * @param who The Context from which the activity is being started.
@@ -1528,7 +1529,7 @@
             intent.setAllowFds(false);
             intent.migrateExtraStreamToClipData();
             int result = ActivityManagerNative.getDefault()
-                .startActivity(whoThread, intent,
+                .startActivity(whoThread, who.getBasePackageName(), intent,
                         intent.resolveTypeIfNeeded(who.getContentResolver()),
                         token, target != null ? target.mWho : null,
                         requestCode, 0, null, null, options);
@@ -1588,7 +1589,7 @@
             intent.setAllowFds(false);
             intent.migrateExtraStreamToClipData();
             int result = ActivityManagerNative.getDefault()
-                .startActivityAsUser(whoThread, intent,
+                .startActivityAsUser(whoThread, who.getBasePackageName(), intent,
                         intent.resolveTypeIfNeeded(who.getContentResolver()),
                         token, target != null ? target.mEmbeddedID : null,
                         requestCode, 0, null, null, options, user.getIdentifier());
diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java
index 0acad75..5e69128 100644
--- a/core/java/android/app/NotificationManager.java
+++ b/core/java/android/app/NotificationManager.java
@@ -129,8 +129,8 @@
         }
         if (localLOGV) Log.v(TAG, pkg + ": notify(" + id + ", " + notification + ")");
         try {
-            service.enqueueNotificationWithTag(pkg, tag, id, notification, idOut,
-                    UserHandle.myUserId());
+            service.enqueueNotificationWithTag(pkg, mContext.getBasePackageName(), tag, id,
+                    notification, idOut, UserHandle.myUserId());
             if (id != idOut[0]) {
                 Log.w(TAG, "notify: id corrupted: sent " + id + ", got back " + idOut[0]);
             }
@@ -151,8 +151,8 @@
         }
         if (localLOGV) Log.v(TAG, pkg + ": notify(" + id + ", " + notification + ")");
         try {
-            service.enqueueNotificationWithTag(pkg, tag, id, notification, idOut,
-                    user.getIdentifier());
+            service.enqueueNotificationWithTag(pkg, mContext.getBasePackageName(), tag, id,
+                    notification, idOut, user.getIdentifier());
             if (id != idOut[0]) {
                 Log.w(TAG, "notify: id corrupted: sent " + id + ", got back " + idOut[0]);
             }
diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java
index 4b977ab..e66efd5 100644
--- a/core/java/android/content/ContentProvider.java
+++ b/core/java/android/content/ContentProvider.java
@@ -191,11 +191,8 @@
                 String selection, String[] selectionArgs, String sortOrder,
                 ICancellationSignal cancellationSignal) {
             if (enforceReadPermission(callingPkg, uri) != AppOpsManager.MODE_ALLOWED) {
-                // The read is not allowed...  to fake it out, we replace the given
-                // selection statement with a dummy one that will always be false.
-                // This way we will get a cursor back that has the correct structure
-                // but contains no rows.
-                selection = "'A' = 'B'";
+                return rejectQuery(uri, projection, selection, selectionArgs, sortOrder,
+                        CancellationSignal.fromTransport(cancellationSignal));
             }
             return ContentProvider.this.query(uri, projection, selection, selectionArgs, sortOrder,
                     CancellationSignal.fromTransport(cancellationSignal));
@@ -209,12 +206,7 @@
         @Override
         public Uri insert(String callingPkg, Uri uri, ContentValues initialValues) {
             if (enforceWritePermission(callingPkg, uri) != AppOpsManager.MODE_ALLOWED) {
-                // If not allowed, we need to return some reasonable URI.  Maybe the
-                // content provider should be responsible for this, but for now we
-                // will just return the base URI with a dummy '0' tagged on to it.
-                // You shouldn't be able to read if you can't write, anyway, so it
-                // shouldn't matter much what is returned.
-                return uri.buildUpon().appendPath("0").build();
+                return rejectInsert(uri, initialValues);
             }
             return ContentProvider.this.insert(uri, initialValues);
         }
@@ -592,6 +584,31 @@
     }
 
     /**
+     * @hide
+     * Implementation when a caller has performed a query on the content
+     * provider, but that call has been rejected for the operation given
+     * to {@link #setAppOps(int, int)}.  The default implementation
+     * rewrites the <var>selection</var> argument to include a condition
+     * that is never true (so will always result in an empty cursor)
+     * and calls through to {@link #query(android.net.Uri, String[], String, String[],
+     * String, android.os.CancellationSignal)} with that.
+     */
+    public Cursor rejectQuery(Uri uri, String[] projection,
+            String selection, String[] selectionArgs, String sortOrder,
+            CancellationSignal cancellationSignal) {
+        // The read is not allowed...  to fake it out, we replace the given
+        // selection statement with a dummy one that will always be false.
+        // This way we will get a cursor back that has the correct structure
+        // but contains no rows.
+        if (selection == null) {
+            selection = "'A' = 'B'";
+        } else {
+            selection = "'A' = 'B' AND (" + selection + ")";
+        }
+        return query(uri, projection, selection, selectionArgs, sortOrder, cancellationSignal);
+    }
+
+    /**
      * Implement this to handle query requests from clients.
      * This method can be called from multiple threads, as described in
      * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
@@ -739,6 +756,23 @@
     public abstract String getType(Uri uri);
 
     /**
+     * @hide
+     * Implementation when a caller has performed an insert on the content
+     * provider, but that call has been rejected for the operation given
+     * to {@link #setAppOps(int, int)}.  The default implementation simply
+     * returns a dummy URI that is the base URI with a 0 path element
+     * appended.
+     */
+    public Uri rejectInsert(Uri uri, ContentValues values) {
+        // If not allowed, we need to return some reasonable URI.  Maybe the
+        // content provider should be responsible for this, but for now we
+        // will just return the base URI with a dummy '0' tagged on to it.
+        // You shouldn't be able to read if you can't write, anyway, so it
+        // shouldn't matter much what is returned.
+        return uri.buildUpon().appendPath("0").build();
+    }
+
+    /**
      * Implement this to handle requests to insert a new row.
      * As a courtesy, call {@link ContentResolver#notifyChange(android.net.Uri ,android.database.ContentObserver) notifyChange()}
      * after inserting.
diff --git a/core/java/android/hardware/input/InputManager.java b/core/java/android/hardware/input/InputManager.java
index 262d87d..761faaf 100644
--- a/core/java/android/hardware/input/InputManager.java
+++ b/core/java/android/hardware/input/InputManager.java
@@ -212,8 +212,10 @@
                 } catch (RemoteException ex) {
                     throw new RuntimeException("Could not get input device information.", ex);
                 }
+                if (inputDevice != null) {
+                    mInputDevices.setValueAt(index, inputDevice);
+                }
             }
-            mInputDevices.setValueAt(index, inputDevice);
             return inputDevice;
         }
     }
@@ -241,6 +243,8 @@
                         inputDevice = mIm.getInputDevice(id);
                     } catch (RemoteException ex) {
                         // Ignore the problem for the purposes of this method.
+                    }
+                    if (inputDevice == null) {
                         continue;
                     }
                     mInputDevices.setValueAt(i, inputDevice);
@@ -809,6 +813,22 @@
             }
         }
 
+        /**
+         * @hide
+         */
+        @Override
+        public void vibrate(int owningUid, String owningPackage, long milliseconds) {
+            vibrate(milliseconds);
+        }
+
+        /**
+         * @hide
+         */
+        @Override
+        public void vibrate(int owningUid, String owningPackage, long[] pattern, int repeat) {
+            vibrate(pattern, repeat);
+        }
+
         @Override
         public void cancel() {
             try {
diff --git a/core/java/android/hardware/usb/IUsbManager.aidl b/core/java/android/hardware/usb/IUsbManager.aidl
index 8286686..9bc967f 100644
--- a/core/java/android/hardware/usb/IUsbManager.aidl
+++ b/core/java/android/hardware/usb/IUsbManager.aidl
@@ -95,4 +95,7 @@
 
     /* Deny USB debugging from the attached host */
     void denyUsbDebugging();
+
+    /* Clear public keys installed for secure USB debugging */
+    void clearUsbDebuggingKeys();
 }
diff --git a/core/java/android/os/IVibratorService.aidl b/core/java/android/os/IVibratorService.aidl
index 15cedf9..456ffb1 100644
--- a/core/java/android/os/IVibratorService.aidl
+++ b/core/java/android/os/IVibratorService.aidl
@@ -20,8 +20,8 @@
 interface IVibratorService
 {
     boolean hasVibrator();
-    void vibrate(String packageName, long milliseconds, IBinder token);
-    void vibratePattern(String packageName, in long[] pattern, int repeat, IBinder token);
+    void vibrate(int uid, String packageName, long milliseconds, IBinder token);
+    void vibratePattern(int uid, String packageName, in long[] pattern, int repeat, IBinder token);
     void cancelVibrate(IBinder token);
 }
 
diff --git a/core/java/android/os/NullVibrator.java b/core/java/android/os/NullVibrator.java
index 8de4e06..ac6027f 100644
--- a/core/java/android/os/NullVibrator.java
+++ b/core/java/android/os/NullVibrator.java
@@ -49,6 +49,22 @@
         }
     }
 
+    /**
+     * @hide
+     */
+    @Override
+    public void vibrate(int owningUid, String owningPackage, long milliseconds) {
+        vibrate(milliseconds);
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public void vibrate(int owningUid, String owningPackage, long[] pattern, int repeat) {
+        vibrate(pattern, repeat);
+    }
+
     @Override
     public void cancel() {
     }
diff --git a/core/java/android/os/SystemVibrator.java b/core/java/android/os/SystemVibrator.java
index 08eba4f..e66fb285 100644
--- a/core/java/android/os/SystemVibrator.java
+++ b/core/java/android/os/SystemVibrator.java
@@ -16,6 +16,7 @@
 
 package android.os;
 
+import android.app.ActivityThread;
 import android.content.Context;
 import android.util.Log;
 
@@ -32,7 +33,7 @@
     private final Binder mToken = new Binder();
 
     public SystemVibrator() {
-        mPackageName = null;
+        mPackageName = ActivityThread.currentPackageName();
         mService = IVibratorService.Stub.asInterface(
                 ServiceManager.getService("vibrator"));
     }
@@ -58,19 +59,35 @@
 
     @Override
     public void vibrate(long milliseconds) {
+        vibrate(Process.myUid(), mPackageName, milliseconds);
+    }
+
+    @Override
+    public void vibrate(long[] pattern, int repeat) {
+        vibrate(Process.myUid(), mPackageName, pattern, repeat);
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public void vibrate(int owningUid, String owningPackage, long milliseconds) {
         if (mService == null) {
             Log.w(TAG, "Failed to vibrate; no vibrator service.");
             return;
         }
         try {
-            mService.vibrate(mPackageName, milliseconds, mToken);
+            mService.vibrate(owningUid, owningPackage, milliseconds, mToken);
         } catch (RemoteException e) {
             Log.w(TAG, "Failed to vibrate.", e);
         }
     }
 
+    /**
+     * @hide
+     */
     @Override
-    public void vibrate(long[] pattern, int repeat) {
+    public void vibrate(int owningUid, String owningPackage, long[] pattern, int repeat) {
         if (mService == null) {
             Log.w(TAG, "Failed to vibrate; no vibrator service.");
             return;
@@ -80,7 +97,7 @@
         // anyway
         if (repeat < pattern.length) {
             try {
-                mService.vibratePattern(mPackageName, pattern, repeat, mToken);
+                mService.vibratePattern(owningUid, owningPackage, pattern, repeat, mToken);
             } catch (RemoteException e) {
                 Log.w(TAG, "Failed to vibrate.", e);
             }
diff --git a/core/java/android/os/Vibrator.java b/core/java/android/os/Vibrator.java
index b67be4b..6650fca 100644
--- a/core/java/android/os/Vibrator.java
+++ b/core/java/android/os/Vibrator.java
@@ -73,6 +73,20 @@
     public abstract void vibrate(long[] pattern, int repeat);
 
     /**
+     * @hide
+     * Like {@link #vibrate(long)}, but allowing the caller to specify that
+     * the vibration is owned by someone else.
+     */
+    public abstract void vibrate(int owningUid, String owningPackage, long milliseconds);
+
+    /**
+     * @hide
+     * Like {@link #vibrate(long[], int)}, but allowing the caller to specify that
+     * the vibration is owned by someone else.
+     */
+    public abstract void vibrate(int owningUid, String owningPackage, long[] pattern, int repeat);
+
+    /**
      * Turn the vibrator off.
      * <p>This method requires the caller to hold the permission
      * {@link android.Manifest.permission#VIBRATE}.
diff --git a/core/java/android/view/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java
index e0cf3b2..8051923 100644
--- a/core/java/android/view/GLES20Canvas.java
+++ b/core/java/android/view/GLES20Canvas.java
@@ -144,6 +144,14 @@
         }
     }
 
+    @Override
+    public void setName(String name) {
+        super.setName(name);
+        nSetName(mRenderer, name);
+    }
+
+    private static native void nSetName(int renderer, String name);
+
     ///////////////////////////////////////////////////////////////////////////
     // Hardware layers
     ///////////////////////////////////////////////////////////////////////////
diff --git a/core/java/android/view/GLES20RecordingCanvas.java b/core/java/android/view/GLES20RecordingCanvas.java
index 168ae81..7da2451 100644
--- a/core/java/android/view/GLES20RecordingCanvas.java
+++ b/core/java/android/view/GLES20RecordingCanvas.java
@@ -43,7 +43,7 @@
     private GLES20DisplayList mDisplayList;
 
     private GLES20RecordingCanvas() {
-        super(true /*record*/, true /*translucent*/);
+        super(true, true);
     }
 
     static GLES20RecordingCanvas obtain(GLES20DisplayList displayList) {
diff --git a/core/java/android/view/HardwareCanvas.java b/core/java/android/view/HardwareCanvas.java
index eeae3ed..3d19260 100644
--- a/core/java/android/view/HardwareCanvas.java
+++ b/core/java/android/view/HardwareCanvas.java
@@ -27,6 +27,8 @@
  * @hide 
  */
 public abstract class HardwareCanvas extends Canvas {
+    private String mName;
+
     @Override
     public boolean isHardwareAccelerated() {
         return true;
@@ -36,7 +38,30 @@
     public void setBitmap(Bitmap bitmap) {
         throw new UnsupportedOperationException();
     }
-    
+
+    /**
+     * Specifies the name of this canvas. Naming the canvas is entirely
+     * optional but can be useful for debugging purposes.
+     *
+     * @param name The name of the canvas, can be null
+     *
+     * @see #getName()
+     */
+    public void setName(String name) {
+        mName = name;
+    }
+
+    /**
+     * Returns the name of this canvas.
+     *
+     * @return The name of the canvas or null
+     *
+     * @see #setName(String)
+     */
+    public String getName() {
+        return mName;
+    }
+
     /**
      * Invoked before any drawing operation is performed in this canvas.
      * 
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java
index 2b4260d..e0d48a4 100644
--- a/core/java/android/view/HardwareRenderer.java
+++ b/core/java/android/view/HardwareRenderer.java
@@ -543,6 +543,13 @@
     }
 
     /**
+     * Optional, sets the name of the renderer. Useful for debugging purposes.
+     *
+     * @param name The name of this renderer, can be null
+     */
+    abstract void setName(String name);
+
+    /**
      * Creates a hardware renderer using OpenGL.
      * 
      * @param glVersion The version of OpenGL to use (1 for OpenGL 1, 11 for OpenGL 1.1, etc.)
@@ -756,6 +763,8 @@
         GL mGl;
         HardwareCanvas mCanvas;
 
+        String mName;
+
         long mFrameCount;
         Paint mDebugPaint;
 
@@ -963,6 +972,7 @@
                     } else {
                         if (mCanvas == null) {
                             mCanvas = createCanvas();
+                            mCanvas.setName(mName);
                         }
                         if (mCanvas != null) {
                             setEnabled(true);
@@ -1277,6 +1287,11 @@
             return mCanvas;
         }
 
+        @Override
+        void setName(String name) {
+            mName = name;
+        }
+
         boolean canDraw() {
             return mGl != null && mCanvas != null;
         }        
@@ -1868,7 +1883,7 @@
                 mDebugDataProvider.setupGraphPaint(mProfilePaint, i);
                 switch (graphType) {
                     case GraphDataProvider.GRAPH_TYPE_BARS:
-                        mGlCanvas.drawRects(mProfileShapes[i], count, mProfilePaint);
+                        mGlCanvas.drawRects(mProfileShapes[i], count * 4, mProfilePaint);
                         break;
                     case GraphDataProvider.GRAPH_TYPE_LINES:
                         mGlCanvas.drawLines(mProfileShapes[i], 0, count * 4, mProfilePaint);
diff --git a/core/java/android/view/KeyEvent.java b/core/java/android/view/KeyEvent.java
index af818fa..bb533bf 100644
--- a/core/java/android/view/KeyEvent.java
+++ b/core/java/android/view/KeyEvent.java
@@ -623,8 +623,14 @@
     /** Key code constant: Assist key.
      * Launches the global assist activity.  Not delivered to applications. */
     public static final int KEYCODE_ASSIST          = 219;
+    /** Key code constant: Brightness Down key.
+     * Adjusts the screen brightness down. */
+    public static final int KEYCODE_BRIGHTNESS_DOWN = 220;
+    /** Key code constant: Brightness Up key.
+     * Adjusts the screen brightness up. */
+    public static final int KEYCODE_BRIGHTNESS_UP   = 221;
 
-    private static final int LAST_KEYCODE           = KEYCODE_ASSIST;
+    private static final int LAST_KEYCODE           = KEYCODE_BRIGHTNESS_UP;
 
     // NOTE: If you add a new keycode here you must also add it to:
     //  isSystem()
@@ -866,6 +872,8 @@
         names.append(KEYCODE_RO, "KEYCODE_RO");
         names.append(KEYCODE_KANA, "KEYCODE_KANA");
         names.append(KEYCODE_ASSIST, "KEYCODE_ASSIST");
+        names.append(KEYCODE_BRIGHTNESS_DOWN, "KEYCODE_BRIGHTNESS_DOWN");
+        names.append(KEYCODE_BRIGHTNESS_UP, "KEYCODE_BRIGHTNESS_UP");
     };
 
     // Symbolic names of all metakeys in bit order from least significant to most significant.
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index b9babdc..11c80c26 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -1562,9 +1562,6 @@
      */
     int mAccessibilityViewId = NO_ID;
 
-    /**
-     * @hide
-     */
     private int mAccessibilityCursorPosition = ACCESSIBILITY_CURSOR_POSITION_UNDEFINED;
 
     /**
@@ -2516,8 +2513,10 @@
 
     /**
      * The undefined cursor position.
+     *
+     * @hide
      */
-    private static final int ACCESSIBILITY_CURSOR_POSITION_UNDEFINED = -1;
+    public static final int ACCESSIBILITY_CURSOR_POSITION_UNDEFINED = -1;
 
     /**
      * Indicates that the screen has changed state and is now off.
@@ -7009,21 +7008,25 @@
                 if (arguments != null) {
                     final int granularity = arguments.getInt(
                             AccessibilityNodeInfo.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT);
-                    return nextAtGranularity(granularity);
+                    final boolean extendSelection = arguments.getBoolean(
+                            AccessibilityNodeInfo.ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN);
+                    return nextAtGranularity(granularity, extendSelection);
                 }
             } break;
             case AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY: {
                 if (arguments != null) {
                     final int granularity = arguments.getInt(
                             AccessibilityNodeInfo.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT);
-                    return previousAtGranularity(granularity);
+                    final boolean extendSelection = arguments.getBoolean(
+                            AccessibilityNodeInfo.ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN);
+                    return previousAtGranularity(granularity, extendSelection);
                 }
             } break;
         }
         return false;
     }
 
-    private boolean nextAtGranularity(int granularity) {
+    private boolean nextAtGranularity(int granularity, boolean extendSelection) {
         CharSequence text = getIterableTextForAccessibility();
         if (text == null || text.length() == 0) {
             return false;
@@ -7032,21 +7035,32 @@
         if (iterator == null) {
             return false;
         }
-        final int current = getAccessibilityCursorPosition();
+        int current = getAccessibilitySelectionEnd();
+        if (current == ACCESSIBILITY_CURSOR_POSITION_UNDEFINED) {
+            current = 0;
+        }
         final int[] range = iterator.following(current);
         if (range == null) {
             return false;
         }
         final int start = range[0];
         final int end = range[1];
-        setAccessibilityCursorPosition(end);
+        if (extendSelection && isAccessibilitySelectionExtendable()) {
+            int selectionStart = getAccessibilitySelectionStart();
+            if (selectionStart == ACCESSIBILITY_CURSOR_POSITION_UNDEFINED) {
+                selectionStart = start;
+            }
+            setAccessibilitySelection(selectionStart, end);
+        } else {
+            setAccessibilitySelection(end, end);
+        }
         sendViewTextTraversedAtGranularityEvent(
                 AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY,
                 granularity, start, end);
         return true;
     }
 
-    private boolean previousAtGranularity(int granularity) {
+    private boolean previousAtGranularity(int granularity, boolean extendSelection) {
         CharSequence text = getIterableTextForAccessibility();
         if (text == null || text.length() == 0) {
             return false;
@@ -7055,15 +7069,9 @@
         if (iterator == null) {
             return false;
         }
-        int current = getAccessibilityCursorPosition();
+        int current = getAccessibilitySelectionStart();
         if (current == ACCESSIBILITY_CURSOR_POSITION_UNDEFINED) {
             current = text.length();
-            setAccessibilityCursorPosition(current);
-        } else if (granularity == AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER) {
-            // When traversing by character we always put the cursor after the character
-            // to ease edit and have to compensate before asking the for previous segment.
-            current--;
-            setAccessibilityCursorPosition(current);
         }
         final int[] range = iterator.preceding(current);
         if (range == null) {
@@ -7071,11 +7079,14 @@
         }
         final int start = range[0];
         final int end = range[1];
-        // Always put the cursor after the character to ease edit.
-        if (granularity == AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER) {
-            setAccessibilityCursorPosition(end);
+        if (extendSelection && isAccessibilitySelectionExtendable()) {
+            int selectionEnd = getAccessibilitySelectionEnd();
+            if (selectionEnd == ACCESSIBILITY_CURSOR_POSITION_UNDEFINED) {
+                selectionEnd = end;
+            }
+            setAccessibilitySelection(start, selectionEnd);
         } else {
-            setAccessibilityCursorPosition(start);
+            setAccessibilitySelection(start, start);
         }
         sendViewTextTraversedAtGranularityEvent(
                 AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY,
@@ -7095,17 +7106,39 @@
     }
 
     /**
+     * Gets whether accessibility selection can be extended.
+     *
+     * @return If selection is extensible.
+     *
      * @hide
      */
-    public int getAccessibilityCursorPosition() {
+    public boolean isAccessibilitySelectionExtendable() {
+        return false;
+    }
+
+    /**
+     * @hide
+     */
+    public int getAccessibilitySelectionStart() {
         return mAccessibilityCursorPosition;
     }
 
     /**
      * @hide
      */
-    public void setAccessibilityCursorPosition(int position) {
-        mAccessibilityCursorPosition = position;
+    public int getAccessibilitySelectionEnd() {
+        return getAccessibilitySelectionStart();
+    }
+
+    /**
+     * @hide
+     */
+    public void setAccessibilitySelection(int start, int end) {
+        if (start >= 0 && start == end && end <= getIterableTextForAccessibility().length()) {
+            mAccessibilityCursorPosition = start;
+        } else {
+            mAccessibilityCursorPosition = ACCESSIBILITY_CURSOR_POSITION_UNDEFINED;
+        }
     }
 
     private void sendViewTextTraversedAtGranularityEvent(int action, int granularity,
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index ba9eb89..c3321ea 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -739,6 +739,7 @@
 
                 final boolean translucent = attrs.format != PixelFormat.OPAQUE;
                 mAttachInfo.mHardwareRenderer = HardwareRenderer.createGlRenderer(2, translucent);
+                mAttachInfo.mHardwareRenderer.setName(attrs.getTitle().toString());
                 mAttachInfo.mHardwareAccelerated = mAttachInfo.mHardwareAccelerationRequested
                         = mAttachInfo.mHardwareRenderer != null;
 
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index 02be4db..bd28abc 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -135,6 +135,16 @@
      */
     public interface WindowState {
         /**
+         * Return the uid of the app that owns this window.
+         */
+        int getOwningUid();
+
+        /**
+         * Return the package name of the app that owns this window.
+         */
+        String getOwningPackage();
+
+        /**
          * Perform standard frame computation.  The result can be obtained with
          * getFrame() if so desired.  Must be called with the window manager
          * lock held.
diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
index 6d0a237..4e7ff08 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
@@ -131,16 +131,22 @@
      * at a given movement granularity. For example, move to the next character,
      * word, etc.
      * <p>
-     * <strong>Arguments:</strong> {@link #ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT}<br>
-     * <strong>Example:</strong>
+     * <strong>Arguments:</strong> {@link #ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT}<,
+     * {@link #ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN}<br>
+     * <strong>Example:</strong> Move to the previous character and do not extend selection.
      * <code><pre><p>
      *   Bundle arguments = new Bundle();
      *   arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT,
      *           AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER);
+     *   arguments.putBoolean(AccessibilityNodeInfo.ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN,
+     *           false);
      *   info.performAction(AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY, arguments);
      * </code></pre></p>
      * </p>
      *
+     * @see #ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT
+     * @see #ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN
+     *
      * @see #setMovementGranularities(int)
      * @see #getMovementGranularities()
      *
@@ -157,17 +163,23 @@
      * at a given movement granularity. For example, move to the next character,
      * word, etc.
      * <p>
-     * <strong>Arguments:</strong> {@link #ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT}<br>
-     * <strong>Example:</strong>
+     * <strong>Arguments:</strong> {@link #ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT}<,
+     * {@link #ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN}<br>
+     * <strong>Example:</strong> Move to the next character and do not extend selection.
      * <code><pre><p>
      *   Bundle arguments = new Bundle();
      *   arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT,
      *           AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER);
+     *   arguments.putBoolean(AccessibilityNodeInfo.ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN,
+     *           false);
      *   info.performAction(AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY,
      *           arguments);
      * </code></pre></p>
      * </p>
      *
+     * @see #ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT
+     * @see #ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN
+     *
      * @see #setMovementGranularities(int)
      * @see #getMovementGranularities()
      *
@@ -220,15 +232,53 @@
     public static final int ACTION_SCROLL_BACKWARD = 0x00002000;
 
     /**
+     * Action to copy the current selection to the clipboard.
+     */
+    public static final int ACTION_COPY = 0x00004000;
+
+    /**
+     * Action to paste the current clipboard content.
+     */
+    public static final int ACTION_PASTE = 0x00008000;
+
+    /**
+     * Action to cut the current selection and place it to the clipboard.
+     */
+    public static final int ACTION_CUT = 0x00010000;
+
+    /**
+     * Action to set the selection. Performing this action with no arguments
+     * clears the selection.
+     * <p>
+     * <strong>Arguments:</strong> {@link #ACTION_ARGUMENT_SELECTION_START_INT},
+     * {@link #ACTION_ARGUMENT_SELECTION_END_INT}<br>
+     * <strong>Example:</strong>
+     * <code><pre><p>
+     *   Bundle arguments = new Bundle();
+     *   arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_START_INT, 1);
+     *   arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_END_INT, 2);
+     *   info.performAction(AccessibilityNodeInfo.ACTION_SET_SELECTION, arguments);
+     * </code></pre></p>
+     * </p>
+     *
+     * @see #ACTION_ARGUMENT_SELECTION_START_INT
+     * @see #ACTION_ARGUMENT_SELECTION_END_INT
+     */
+    public static final int ACTION_SET_SELECTION = 0x00020000;
+
+    /**
      * Argument for which movement granularity to be used when traversing the node text.
      * <p>
      * <strong>Type:</strong> int<br>
      * <strong>Actions:</strong> {@link #ACTION_NEXT_AT_MOVEMENT_GRANULARITY},
      * {@link #ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY}
      * </p>
+     *
+     * @see #ACTION_NEXT_AT_MOVEMENT_GRANULARITY
+     * @see #ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
      */
     public static final String ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT =
-        "ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT";
+            "ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT";
 
     /**
      * Argument for which HTML element to get moving to the next/previous HTML element.
@@ -237,9 +287,51 @@
      * <strong>Actions:</strong> {@link #ACTION_NEXT_HTML_ELEMENT},
      *         {@link #ACTION_PREVIOUS_HTML_ELEMENT}
      * </p>
+     *
+     * @see #ACTION_NEXT_HTML_ELEMENT
+     * @see #ACTION_PREVIOUS_HTML_ELEMENT
      */
     public static final String ACTION_ARGUMENT_HTML_ELEMENT_STRING =
-        "ACTION_ARGUMENT_HTML_ELEMENT_STRING";
+            "ACTION_ARGUMENT_HTML_ELEMENT_STRING";
+
+    /**
+     * Argument for whether when moving at granularity to extend the selection
+     * or to move it otherwise.
+     * <p>
+     * <strong>Type:</strong> boolean<br>
+     * <strong>Actions:</strong> {@link #ACTION_NEXT_AT_MOVEMENT_GRANULARITY},
+     * {@link #ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY}
+     * </p>
+     *
+     * @see #ACTION_NEXT_AT_MOVEMENT_GRANULARITY
+     * @see #ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
+     */
+    public static final String ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN =
+            "ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN";
+
+    /**
+     * Argument for specifying the selection start.
+     * <p>
+     * <strong>Type:</strong> int<br>
+     * <strong>Actions:</strong> {@link #ACTION_SET_SELECTION}
+     * </p>
+     *
+     * @see #ACTION_SET_SELECTION
+     */
+    public static final String ACTION_ARGUMENT_SELECTION_START_INT =
+            "ACTION_ARGUMENT_SELECTION_START_INT";
+
+    /**
+     * Argument for specifying the selection end.
+     * <p>
+     * <strong>Type:</strong> int<br>
+     * <strong>Actions:</strong> {@link #ACTION_SET_SELECTION}
+     * </p>
+     *
+     * @see #ACTION_SET_SELECTION
+     */
+    public static final String ACTION_ARGUMENT_SELECTION_END_INT =
+            "ACTION_ARGUMENT_SELECTION_END_INT";
 
     /**
      * The input focus.
@@ -1822,8 +1914,16 @@
                 return "ACTION_SCROLL_FORWARD";
             case ACTION_SCROLL_BACKWARD:
                 return "ACTION_SCROLL_BACKWARD";
+            case ACTION_CUT:
+                return "ACTION_CUT";
+            case ACTION_COPY:
+                return "ACTION_COPY";
+            case ACTION_PASTE:
+                return "ACTION_PASTE";
+            case ACTION_SET_SELECTION:
+                return "ACTION_SET_SELECTION";
             default:
-                throw new IllegalArgumentException("Unknown action: " + action);
+                return"ACTION_UNKNOWN";
         }
     }
 
diff --git a/core/java/android/widget/AbsSeekBar.java b/core/java/android/widget/AbsSeekBar.java
index 3b5e75b..7674837 100644
--- a/core/java/android/widget/AbsSeekBar.java
+++ b/core/java/android/widget/AbsSeekBar.java
@@ -305,7 +305,7 @@
         }
         
         // Canvas will be translated, so 0,0 is where we start drawing
-        final int left = isLayoutRtl() ? available - thumbPos : thumbPos;
+        final int left = (isLayoutRtl() && mMirrorForRtl) ? available - thumbPos : thumbPos;
         thumb.setBounds(left, topBound, left + thumbWidth, bottomBound);
     }
 
@@ -426,7 +426,7 @@
         int x = (int)event.getX();
         float scale;
         float progress = 0;
-        if (isLayoutRtl()) {
+        if (isLayoutRtl() && mMirrorForRtl) {
             if (x > width - mPaddingRight) {
                 scale = 0.0f;
             } else if (x < mPaddingLeft) {
diff --git a/core/java/android/widget/ImageView.java b/core/java/android/widget/ImageView.java
index 8c710ce..1bbf4eb 100644
--- a/core/java/android/widget/ImageView.java
+++ b/core/java/android/widget/ImageView.java
@@ -562,13 +562,14 @@
 
     /** Return the view's optional matrix. This is applied to the
         view's drawable when it is drawn. If there is not matrix,
-        this method will return null.
-        Do not change this matrix in place. If you want a different matrix
-        applied to the drawable, be sure to call setImageMatrix().
+        this method will return an identity matrix.
+        Do not change this matrix in place but make a copy.
+        If you want a different matrix applied to the drawable,
+        be sure to call setImageMatrix().
     */
     public Matrix getImageMatrix() {
         if (mDrawMatrix == null) {
-            return Matrix.IDENTITY_MATRIX;
+            return new Matrix(Matrix.IDENTITY_MATRIX);
         }
         return mDrawMatrix;
     }
diff --git a/core/java/android/widget/ProgressBar.java b/core/java/android/widget/ProgressBar.java
index f2d2c65..d816200 100644
--- a/core/java/android/widget/ProgressBar.java
+++ b/core/java/android/widget/ProgressBar.java
@@ -223,6 +223,8 @@
     private boolean mAttached;
     private boolean mRefreshIsPosted;
 
+    boolean mMirrorForRtl = false;
+
     private final ArrayList<RefreshData> mRefreshData = new ArrayList<RefreshData>();
 
     private AccessibilityEventSender mAccessibilityEventSender;
@@ -302,6 +304,8 @@
         setIndeterminate(mOnlyIndeterminate || a.getBoolean(
                 R.styleable.ProgressBar_indeterminate, mIndeterminate));
 
+        mMirrorForRtl = a.getBoolean(R.styleable.ProgressBar_mirrorForRtl, mMirrorForRtl);
+
         a.recycle();
     }
 
@@ -1004,7 +1008,7 @@
                     }
                 }
             }
-            if (isLayoutRtl()) {
+            if (isLayoutRtl() && mMirrorForRtl) {
                 int tempLeft = left;
                 left = w - right;
                 right = w - tempLeft;
@@ -1026,7 +1030,7 @@
             // Translate canvas so a indeterminate circular progress bar with padding
             // rotates properly in its animation
             canvas.save();
-            if(isLayoutRtl()) {
+            if(isLayoutRtl() && mMirrorForRtl) {
                 canvas.translate(getWidth() - mPaddingRight, mPaddingTop);
                 canvas.scale(-1.0f, 1.0f);
             } else {
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index f8db622..2f02780 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -7985,6 +7985,80 @@
                     | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH
                     | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE);
         }
+        if (isFocused()) {
+            if (canSelectText()) {
+                info.addAction(AccessibilityNodeInfo.ACTION_SET_SELECTION);
+            }
+            if (canCopy()) {
+                info.addAction(AccessibilityNodeInfo.ACTION_COPY);
+            }
+            if (canPaste()) {
+                info.addAction(AccessibilityNodeInfo.ACTION_PASTE);
+            }
+            if (canCut()) {
+                info.addAction(AccessibilityNodeInfo.ACTION_CUT);
+            }
+        }
+    }
+
+    @Override
+    public boolean performAccessibilityAction(int action, Bundle arguments) {
+        switch (action) {
+            case AccessibilityNodeInfo.ACTION_COPY: {
+                if (isFocused() && canCopy()) {
+                    if (onTextContextMenuItem(ID_COPY)) {
+                        notifyAccessibilityStateChanged();
+                        return true;
+                    }
+                }
+            } return false;
+            case AccessibilityNodeInfo.ACTION_PASTE: {
+                if (isFocused() && canPaste()) {
+                    if (onTextContextMenuItem(ID_PASTE)) {
+                        notifyAccessibilityStateChanged();
+                        return true;
+                    }
+                }
+            } return false;
+            case AccessibilityNodeInfo.ACTION_CUT: {
+                if (isFocused() && canCut()) {
+                    if (onTextContextMenuItem(ID_CUT)) {
+                        notifyAccessibilityStateChanged();
+                        return true;
+                    }
+                }
+            } return false;
+            case AccessibilityNodeInfo.ACTION_SET_SELECTION: {
+                if (isFocused() && canSelectText()) {
+                    final int start = (arguments != null) ? arguments.getInt(
+                            AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_START_INT, -1) : -1;
+                    final int end = (arguments != null) ? arguments.getInt(
+                            AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_END_INT, -1) : -1;
+                    CharSequence text = getIterableTextForAccessibility();
+                    if (text == null) {
+                        return false;
+                    }
+                    // No arguments clears the selection.
+                    if (start == end && end == -1) {
+                        Selection.removeSelection((Spannable) text);
+                        notifyAccessibilityStateChanged();
+                        return true;
+                    }
+                    if (start >= 0 && start <= end && end <= text.length()) {
+                        Selection.setSelection((Spannable) text, start, end);
+                        // Make sure selection mode is engaged.
+                        if (mEditor != null) {
+                            mEditor.startSelectionActionMode();
+                        }
+                        notifyAccessibilityStateChanged();
+                        return true;
+                    }
+                }
+            } return false;
+            default: {
+                return super.performAccessibilityAction(action, arguments);
+            }
+        }
     }
 
     @Override
@@ -8554,32 +8628,51 @@
      * @hide
      */
     @Override
-    public int getAccessibilityCursorPosition() {
+    public int getAccessibilitySelectionStart() {
         if (TextUtils.isEmpty(getContentDescription())) {
-            final int selectionEnd = getSelectionEnd();
-            if (selectionEnd >= 0) {
-                return selectionEnd;
+            final int selectionStart = getSelectionStart();
+            if (selectionStart >= 0) {
+                return selectionStart;
             }
         }
-        return super.getAccessibilityCursorPosition();
+        return ACCESSIBILITY_CURSOR_POSITION_UNDEFINED;
+    }
+
+    /**
+     * @hide
+     */
+    public boolean isAccessibilitySelectionExtendable() {
+        return true;
     }
 
     /**
      * @hide
      */
     @Override
-    public void setAccessibilityCursorPosition(int index) {
-        if (getAccessibilityCursorPosition() == index) {
+    public int getAccessibilitySelectionEnd() {
+        if (TextUtils.isEmpty(getContentDescription())) {
+            final int selectionEnd = getSelectionEnd();
+            if (selectionEnd >= 0) {
+                return selectionEnd;
+            }
+        }
+        return ACCESSIBILITY_CURSOR_POSITION_UNDEFINED;
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public void setAccessibilitySelection(int start, int end) {
+        if (getAccessibilitySelectionStart() == start
+                && getAccessibilitySelectionEnd() == end) {
             return;
         }
-        if (TextUtils.isEmpty(getContentDescription())) {
-            if (index >= 0 && index <= mText.length()) {
-                Selection.setSelection((Spannable) mText, index);
-            } else {
-                Selection.removeSelection((Spannable) mText);
-            }
+        CharSequence text = getIterableTextForAccessibility();
+        if (start >= 0 && start <= end && end <= text.length()) {
+            Selection.setSelection((Spannable) text, start, end);
         } else {
-            super.setAccessibilityCursorPosition(index);
+            Selection.removeSelection((Spannable) text);
         }
     }
 
diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java
index d24513a3..fd7e3b0 100644
--- a/core/java/com/android/internal/os/ZygoteConnection.java
+++ b/core/java/com/android/internal/os/ZygoteConnection.java
@@ -76,18 +76,6 @@
     private final String peerSecurityContext;
 
     /**
-     * A long-lived reference to the original command socket used to launch
-     * this peer. If "peer wait" mode is specified, the process that requested
-     * the new VM instance intends to track the lifetime of the spawned instance
-     * via the command socket. In this case, the command socket is closed
-     * in the Zygote and placed here in the spawned instance so that it will
-     * not be collected and finalized. This field remains null at all times
-     * in the original Zygote process, and in all spawned processes where
-     * "peer-wait" mode was not requested.
-     */
-    private static LocalSocket sPeerWaitSocket = null;
-
-    /**
      * Constructs instance from connected socket.
      *
      * @param socket non-null; connected socket
@@ -298,11 +286,6 @@
      *   <li> --rlimit=r,c,m<i>tuple of values for setrlimit() call.
      *    <code>r</code> is the resource, <code>c</code> and <code>m</code>
      *    are the settings for current and max value.</i>
-     *   <li> --peer-wait indicates that the command socket should
-     * be inherited by (and set to close-on-exec in) the spawned process
-     * and used to track the lifetime of that process. The spawning process
-     * then exits. Without this flag, it is retained by the spawning process
-     * (and closed in the child) in expectation of a new spawn request.
      *   <li> --classpath=<i>colon-separated classpath</i> indicates
      * that the specified class (which must b first non-flag argument) should
      * be loaded from jar files in the specified classpath. Incompatible with
@@ -330,9 +313,6 @@
         /** from --setgroups */
         int[] gids;
 
-        /** from --peer-wait */
-        boolean peerWait;
-
         /**
          * From --enable-debugger, --enable-checkjni, --enable-assert,
          * --enable-safemode, and --enable-jni-logging.
@@ -437,8 +417,6 @@
                     debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
                 } else if (arg.equals("--enable-assert")) {
                     debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
-                } else if (arg.equals("--peer-wait")) {
-                    peerWait = true;
                 } else if (arg.equals("--runtime-init")) {
                     runtimeInit = true;
                 } else if (arg.startsWith("--seinfo=")) {
@@ -897,23 +875,8 @@
             FileDescriptor[] descriptors, FileDescriptor pipeFd, PrintStream newStderr)
             throws ZygoteInit.MethodAndArgsCaller {
 
-        /*
-         * Close the socket, unless we're in "peer wait" mode, in which
-         * case it's used to track the liveness of this process.
-         */
-
-        if (parsedArgs.peerWait) {
-            try {
-                ZygoteInit.setCloseOnExec(mSocket.getFileDescriptor(), true);
-                sPeerWaitSocket = mSocket;
-            } catch (IOException ex) {
-                Log.e(TAG, "Zygote Child: error setting peer wait "
-                        + "socket to be close-on-exec", ex);
-            }
-        } else {
-            closeSocket();
-            ZygoteInit.closeServerSocket();
-        }
+        closeSocket();
+        ZygoteInit.closeServerSocket();
 
         if (descriptors != null) {
             try {
@@ -1044,18 +1007,6 @@
             return true;
         }
 
-        /*
-         * If the peer wants to use the socket to wait on the
-         * newly spawned process, then we're all done.
-         */
-        if (parsedArgs.peerWait) {
-            try {
-                mSocket.close();
-            } catch (IOException ex) {
-                Log.e(TAG, "Zygote: error closing sockets", ex);
-            }
-            return true;
-        }
         return false;
     }
 
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index 9e43749..7eddc9c 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -19,10 +19,8 @@
 import static libcore.io.OsConstants.S_IRWXG;
 import static libcore.io.OsConstants.S_IRWXO;
 
-import android.content.pm.ActivityInfo;
 import android.content.res.Resources;
 import android.content.res.TypedArray;
-import android.graphics.drawable.Drawable;
 import android.net.LocalServerSocket;
 import android.os.Debug;
 import android.os.Process;
@@ -88,12 +86,6 @@
     static final int GC_LOOP_COUNT = 10;
 
     /**
-     * If true, zygote forks for each peer. If false, a select loop is used
-     * inside a single process. The latter is preferred.
-     */
-    private static final boolean ZYGOTE_FORK_MODE = false;
-
-    /**
      * The name of a resource file that contains classes to preload.
      */
     private static final String PRELOADED_CLASSES = "preloaded-classes";
@@ -549,11 +541,7 @@
 
             Log.i(TAG, "Accepting command socket connections");
 
-            if (ZYGOTE_FORK_MODE) {
-                runForkMode();
-            } else {
-                runSelectLoopMode();
-            }
+            runSelectLoop();
 
             closeServerSocket();
         } catch (MethodAndArgsCaller caller) {
@@ -566,44 +554,6 @@
     }
 
     /**
-     * Runs the zygote in accept-and-fork mode. In this mode, each peer
-     * gets its own zygote spawner process. This code is retained for
-     * reference only.
-     *
-     * @throws MethodAndArgsCaller in a child process when a main() should
-     * be executed.
-     */
-    private static void runForkMode() throws MethodAndArgsCaller {
-        while (true) {
-            ZygoteConnection peer = acceptCommandPeer();
-
-            int pid;
-
-            pid = Zygote.fork();
-
-            if (pid == 0) {
-                // The child process should handle the peer requests
-
-                // The child does not accept any more connections
-                try {
-                    sServerSocket.close();
-                } catch (IOException ex) {
-                    Log.e(TAG, "Zygote Child: error closing sockets", ex);
-                } finally {
-                    sServerSocket = null;
-                }
-
-                peer.run();
-                break;
-            } else if (pid > 0) {
-                peer.closeSocket();
-            } else {
-                throw new RuntimeException("Error invoking fork()");
-            }
-        }
-    }
-
-    /**
      * Runs the zygote process's select loop. Accepts new connections as
      * they happen, and reads commands from connections one spawn-request's
      * worth at a time.
@@ -611,9 +561,9 @@
      * @throws MethodAndArgsCaller in a child process when a main() should
      * be executed.
      */
-    private static void runSelectLoopMode() throws MethodAndArgsCaller {
-        ArrayList<FileDescriptor> fds = new ArrayList();
-        ArrayList<ZygoteConnection> peers = new ArrayList();
+    private static void runSelectLoop() throws MethodAndArgsCaller {
+        ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>();
+        ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();
         FileDescriptor[] fdArray = new FileDescriptor[4];
 
         fds.add(sServerSocket.getFileDescriptor());
@@ -734,17 +684,6 @@
             throws IOException;
 
     /**
-     * Sets the permitted and effective capability sets of this process.
-     *
-     * @param permittedCapabilities permitted set
-     * @param effectiveCapabilities effective set
-     * @throws IOException on error
-     */
-    static native void setCapabilities(
-            long permittedCapabilities,
-            long effectiveCapabilities) throws IOException;
-
-    /**
      * Invokes select() on the provider array of file descriptors (selecting
      * for readability only). Array elements of null are ignored.
      *
diff --git a/core/java/com/android/internal/util/FastXmlSerializer.java b/core/java/com/android/internal/util/FastXmlSerializer.java
index 99eea15..7a04080 100644
--- a/core/java/com/android/internal/util/FastXmlSerializer.java
+++ b/core/java/com/android/internal/util/FastXmlSerializer.java
@@ -390,7 +390,7 @@
         }
         escapeAndAppendString(text);
         if (mIndent) {
-            mLineStart = text.charAt(text.length()-1) == '\n';
+            mLineStart = text.length() > 0 && (text.charAt(text.length()-1) == '\n');
         }
         return this;
     }
diff --git a/core/java/com/android/internal/util/IndentingPrintWriter.java b/core/java/com/android/internal/util/IndentingPrintWriter.java
index dd5918b..d01a817 100644
--- a/core/java/com/android/internal/util/IndentingPrintWriter.java
+++ b/core/java/com/android/internal/util/IndentingPrintWriter.java
@@ -21,29 +21,47 @@
 
 /**
  * Lightweight wrapper around {@link PrintWriter} that automatically indents
- * newlines based on internal state. Delays writing indent until first actual
- * write on a newline, enabling indent modification after newline.
+ * newlines based on internal state. It also automatically wraps long lines
+ * based on given line length.
+ * <p>
+ * Delays writing indent until first actual write on a newline, enabling indent
+ * modification after newline.
  */
 public class IndentingPrintWriter extends PrintWriter {
-    private final String mIndent;
+    private final String mSingleIndent;
+    private final int mWrapLength;
 
-    private StringBuilder mBuilder = new StringBuilder();
-    private char[] mCurrent;
+    /** Mutable version of current indent */
+    private StringBuilder mIndentBuilder = new StringBuilder();
+    /** Cache of current {@link #mIndentBuilder} value */
+    private char[] mCurrentIndent;
+    /** Length of current line being built, excluding any indent */
+    private int mCurrentLength;
+
+    /**
+     * Flag indicating if we're currently sitting on an empty line, and that
+     * next write should be prefixed with the current indent.
+     */
     private boolean mEmptyLine = true;
 
-    public IndentingPrintWriter(Writer writer, String indent) {
+    public IndentingPrintWriter(Writer writer, String singleIndent) {
+        this(writer, singleIndent, -1);
+    }
+
+    public IndentingPrintWriter(Writer writer, String singleIndent, int wrapLength) {
         super(writer);
-        mIndent = indent;
+        mSingleIndent = singleIndent;
+        mWrapLength = wrapLength;
     }
 
     public void increaseIndent() {
-        mBuilder.append(mIndent);
-        mCurrent = null;
+        mIndentBuilder.append(mSingleIndent);
+        mCurrentIndent = null;
     }
 
     public void decreaseIndent() {
-        mBuilder.delete(0, mIndent.length());
-        mCurrent = null;
+        mIndentBuilder.delete(0, mSingleIndent.length());
+        mCurrentIndent = null;
     }
 
     public void printPair(String key, Object value) {
@@ -52,33 +70,56 @@
 
     @Override
     public void write(char[] buf, int offset, int count) {
+        final int indentLength = mIndentBuilder.length();
         final int bufferEnd = offset + count;
         int lineStart = offset;
         int lineEnd = offset;
+
+        // March through incoming buffer looking for newlines
         while (lineEnd < bufferEnd) {
             char ch = buf[lineEnd++];
+            mCurrentLength++;
             if (ch == '\n') {
-                writeIndent();
+                maybeWriteIndent();
                 super.write(buf, lineStart, lineEnd - lineStart);
                 lineStart = lineEnd;
                 mEmptyLine = true;
+                mCurrentLength = 0;
+            }
+
+            // Wrap if we've pushed beyond line length
+            if (mWrapLength > 0 && mCurrentLength >= mWrapLength - indentLength) {
+                if (!mEmptyLine) {
+                    // Give ourselves a fresh line to work with
+                    super.write('\n');
+                    mEmptyLine = true;
+                    mCurrentLength = lineEnd - lineStart;
+                } else {
+                    // We need more than a dedicated line, slice it hard
+                    maybeWriteIndent();
+                    super.write(buf, lineStart, lineEnd - lineStart);
+                    super.write('\n');
+                    mEmptyLine = true;
+                    lineStart = lineEnd;
+                    mCurrentLength = 0;
+                }
             }
         }
 
         if (lineStart != lineEnd) {
-            writeIndent();
+            maybeWriteIndent();
             super.write(buf, lineStart, lineEnd - lineStart);
         }
     }
 
-    private void writeIndent() {
+    private void maybeWriteIndent() {
         if (mEmptyLine) {
             mEmptyLine = false;
-            if (mBuilder.length() != 0) {
-                if (mCurrent == null) {
-                    mCurrent = mBuilder.toString().toCharArray();
+            if (mIndentBuilder.length() != 0) {
+                if (mCurrentIndent == null) {
+                    mCurrentIndent = mIndentBuilder.toString().toCharArray();
                 }
-                super.write(mCurrent, 0, mCurrent.length);
+                super.write(mCurrentIndent, 0, mCurrentIndent.length);
             }
         }
     }
diff --git a/core/java/com/android/internal/util/ProcFileReader.java b/core/java/com/android/internal/util/ProcFileReader.java
index 72e1f0f..81571fe 100644
--- a/core/java/com/android/internal/util/ProcFileReader.java
+++ b/core/java/com/android/internal/util/ProcFileReader.java
@@ -19,6 +19,7 @@
 import java.io.Closeable;
 import java.io.IOException;
 import java.io.InputStream;
+import java.net.ProtocolException;
 import java.nio.charset.Charsets;
 
 /**
@@ -82,12 +83,15 @@
     }
 
     /**
-     * Find buffer index of next token delimiter, usually space or newline. Will
-     * fill buffer as needed.
+     * Find buffer index of next token delimiter, usually space or newline.
+     * Fills buffer as needed.
+     *
+     * @return Index of next delimeter, otherwise -1 if no tokens remain on
+     *         current line.
      */
     private int nextTokenIndex() throws IOException {
         if (mLineFinished) {
-            throw new IOException("no tokens remaining on current line");
+            return -1;
         }
 
         int i = 0;
@@ -105,7 +109,7 @@
             }
         } while (fillBuf() > 0);
 
-        throw new IOException("end of stream while looking for token boundary");
+        throw new ProtocolException("End of stream while looking for token boundary");
     }
 
     /**
@@ -136,7 +140,7 @@
             }
         } while (fillBuf() > 0);
 
-        throw new IOException("end of stream while looking for line boundary");
+        throw new ProtocolException("End of stream while looking for line boundary");
     }
 
     /**
@@ -144,9 +148,11 @@
      */
     public String nextString() throws IOException {
         final int tokenIndex = nextTokenIndex();
-        final String s = new String(mBuffer, 0, tokenIndex, Charsets.US_ASCII);
-        consumeBuf(tokenIndex + 1);
-        return s;
+        if (tokenIndex == -1) {
+            throw new ProtocolException("Missing required string");
+        } else {
+            return parseAndConsumeString(tokenIndex);
+        }
     }
 
     /**
@@ -154,6 +160,33 @@
      */
     public long nextLong() throws IOException {
         final int tokenIndex = nextTokenIndex();
+        if (tokenIndex == -1) {
+            throw new ProtocolException("Missing required long");
+        } else {
+            return parseAndConsumeLong(tokenIndex);
+        }
+    }
+
+    /**
+     * Parse and return next token as base-10 encoded {@code long}, or return
+     * the given default value if no remaining tokens on current line.
+     */
+    public long nextOptionalLong(long def) throws IOException {
+        final int tokenIndex = nextTokenIndex();
+        if (tokenIndex == -1) {
+            return def;
+        } else {
+            return parseAndConsumeLong(tokenIndex);
+        }
+    }
+
+    private String parseAndConsumeString(int tokenIndex) throws IOException {
+        final String s = new String(mBuffer, 0, tokenIndex, Charsets.US_ASCII);
+        consumeBuf(tokenIndex + 1);
+        return s;
+    }
+
+    private long parseAndConsumeLong(int tokenIndex) throws IOException {
         final boolean negative = mBuffer[0] == '-';
 
         // TODO: refactor into something like IntegralToString
@@ -193,6 +226,7 @@
         return (int) value;
     }
 
+    @Override
     public void close() throws IOException {
         mStream.close();
     }
diff --git a/core/java/com/android/internal/util/StateMachine.java b/core/java/com/android/internal/util/StateMachine.java
index 1e5a97a..6641f2c 100644
--- a/core/java/com/android/internal/util/StateMachine.java
+++ b/core/java/com/android/internal/util/StateMachine.java
@@ -27,6 +27,7 @@
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.Calendar;
+import java.util.Collection;
 import java.util.HashMap;
 import java.util.Vector;
 
@@ -81,8 +82,8 @@
  * machine will cause <code>haltedProcessMessage</code> to be invoked.</p>
  *
  * <p>If it is desirable to completely stop the state machine call <code>quit</code> or
- * <code>abort</code>. These will call <code>exit</code> of the current state and its parents, call
- * <code>onQuiting</code> and then exit Thread/Loopers.</p>
+ * <code>quitNow</code>. These will call <code>exit</code> of the current state and its parents,
+ * call <code>onQuiting</code> and then exit Thread/Loopers.</p>
  *
  * <p>In addition to <code>processMessage</code> each <code>State</code> has
  * an <code>enter</code> method and <code>exit</exit> method which may be overridden.</p>
@@ -444,12 +445,13 @@
      * {@hide}
      */
     public static class LogRec {
+        private StateMachine mSm;
         private long mTime;
         private int mWhat;
         private String mInfo;
-        private State mState;
-        private State mOrgState;
-        private State mTransitionToState;
+        private IState mState;
+        private IState mOrgState;
+        private IState mDstState;
 
         /**
          * Constructor
@@ -461,26 +463,26 @@
          * @param transToState is the state that was transitioned to after the message was
          * processed.
          */
-        LogRec(Message msg, String info, State state, State orgState, State transToState) {
-            update(msg, info, state, orgState, transToState);
+        LogRec(StateMachine sm, Message msg, String info, IState state, IState orgState,
+                IState transToState) {
+            update(sm, msg, info, state, orgState, transToState);
         }
 
         /**
          * Update the information in the record.
          * @param state that handled the message
-         * @param orgState is the first state the received the message but
-         * did not processes the message.
-         * @param transToState is the state that was transitioned to after the message was
-         * processed.
+         * @param orgState is the first state the received the message
+         * @param dstState is the state that was the transition target when logging
          */
-        public void update(Message msg, String info, State state, State orgState,
-                State transToState) {
+        public void update(StateMachine sm, Message msg, String info, IState state, IState orgState,
+                IState dstState) {
+            mSm = sm;
             mTime = System.currentTimeMillis();
             mWhat = (msg != null) ? msg.what : 0;
             mInfo = info;
             mState = state;
             mOrgState = orgState;
-            mTransitionToState = transToState;
+            mDstState = dstState;
         }
 
         /**
@@ -507,21 +509,27 @@
         /**
          * @return the state that handled this message
          */
-        public State getState() {
+        public IState getState() {
             return mState;
         }
 
         /**
+         * @return the state destination state if a transition is occurring or null if none.
+         */
+        public IState getDestState() {
+            return mDstState;
+        }
+
+
+        /**
          * @return the original state that received the message.
          */
-        public State getOriginalState() {
+        public IState getOriginalState() {
             return mOrgState;
         }
 
-        /**
-         * @return as string
-         */
-        public String toString(StateMachine sm) {
+        @Override
+        public String toString() {
             StringBuilder sb = new StringBuilder();
             sb.append("time=");
             Calendar c = Calendar.getInstance();
@@ -532,9 +540,9 @@
             sb.append(" org=");
             sb.append(mOrgState == null ? "<null>" : mOrgState.getName());
             sb.append(" dest=");
-            sb.append(mTransitionToState == null ? "<null>" : mTransitionToState.getName());
+            sb.append(mDstState == null ? "<null>" : mDstState.getName());
             sb.append(" what=");
-            String what = sm.getWhatToString(mWhat);
+            String what = mSm != null ? mSm.getWhatToString(mWhat) : "";
             if (TextUtils.isEmpty(what)) {
                 sb.append(mWhat);
                 sb.append("(0x");
@@ -647,18 +655,19 @@
          * processed.
          *
          */
-        synchronized void add(Message msg, String messageInfo, State state, State orgState,
-                State transToState) {
+        synchronized void add(StateMachine sm, Message msg, String messageInfo, IState state,
+                IState orgState,
+                IState transToState) {
             mCount += 1;
             if (mLogRecVector.size() < mMaxSize) {
-                mLogRecVector.add(new LogRec(msg, messageInfo, state, orgState, transToState));
+                mLogRecVector.add(new LogRec(sm, msg, messageInfo, state, orgState, transToState));
             } else {
                 LogRec pmi = mLogRecVector.get(mOldestIndex);
                 mOldestIndex += 1;
                 if (mOldestIndex >= mMaxSize) {
                     mOldestIndex = 0;
                 }
-                pmi.update(msg, messageInfo, state, orgState, transToState);
+                pmi.update(sm, msg, messageInfo, state, orgState, transToState);
             }
         }
     }
@@ -788,55 +797,79 @@
                 throw new RuntimeException("StateMachine.handleMessage: " +
                             "The start method not called, received msg: " + msg);
             }
-            performTransitions(msgProcessedState);
+            performTransitions(msgProcessedState, msg);
 
-            if (mDbg) mSm.log("handleMessage: X");
+            // We need to check if mSm == null here as we could be quitting.
+            if (mDbg && mSm != null) mSm.log("handleMessage: X");
         }
 
         /**
          * Do any transitions
          * @param msgProcessedState is the state that processed the message
          */
-        private void performTransitions(State msgProcessedState) {
+        private void performTransitions(State msgProcessedState, Message msg) {
             /**
              * If transitionTo has been called, exit and then enter
              * the appropriate states. We loop on this to allow
              * enter and exit methods to use transitionTo.
              */
-            State destState = null;
             State orgState = mStateStack[mStateStackTopIndex].state;
 
-            /** Record whether message needs to be logged before transitions */
-            boolean recordLogMsg = mSm.recordLogRec(mMsg);
+            /**
+             * Record whether message needs to be logged before we transition and
+             * and we won't log special messages SM_INIT_CMD or SM_QUIT_CMD which
+             * always set msg.obj to the handler.
+             */
+            boolean recordLogMsg = mSm.recordLogRec(mMsg) && (msg.obj == mSmHandlerObj);
 
-            while (mDestState != null) {
-                if (mDbg) mSm.log("handleMessage: new destination call exit");
+            if (mLogRecords.logOnlyTransitions()) {
+                /** Record only if there is a transition */
+                if (mDestState != null) {
+                    mLogRecords.add(mSm, mMsg, mSm.getLogRecString(mMsg), msgProcessedState,
+                            orgState, mDestState);
+                }
+            } else if (recordLogMsg) {
+                /** Record message */
+               mLogRecords.add(mSm, mMsg, mSm.getLogRecString(mMsg), msgProcessedState,
+                        orgState, mDestState);
+            }
 
+            State destState = mDestState;
+            if (destState != null) {
                 /**
-                 * Save mDestState locally and set to null
-                 * to know if enter/exit use transitionTo.
+                 * Process the transitions including transitions in the enter/exit methods
                  */
-                destState = mDestState;
+                while (true) {
+                    if (mDbg) mSm.log("handleMessage: new destination call exit/enter");
+
+                    /**
+                     * Determine the states to exit and enter and return the
+                     * common ancestor state of the enter/exit states. Then
+                     * invoke the exit methods then the enter methods.
+                     */
+                    StateInfo commonStateInfo = setupTempStateStackWithStatesToEnter(destState);
+                    invokeExitMethods(commonStateInfo);
+                    int stateStackEnteringIndex = moveTempStateStackToStateStack();
+                    invokeEnterMethods(stateStackEnteringIndex);
+
+
+                    /**
+                     * Since we have transitioned to a new state we need to have
+                     * any deferred messages moved to the front of the message queue
+                     * so they will be processed before any other messages in the
+                     * message queue.
+                     */
+                    moveDeferredMessageAtFrontOfQueue();
+
+                    if (destState != mDestState) {
+                        // A new mDestState so continue looping
+                        destState = mDestState;
+                    } else {
+                        // No change in mDestState so we're done
+                        break;
+                    }
+                }
                 mDestState = null;
-
-                /**
-                 * Determine the states to exit and enter and return the
-                 * common ancestor state of the enter/exit states. Then
-                 * invoke the exit methods then the enter methods.
-                 */
-                StateInfo commonStateInfo = setupTempStateStackWithStatesToEnter(destState);
-                invokeExitMethods(commonStateInfo);
-                int stateStackEnteringIndex = moveTempStateStackToStateStack();
-                invokeEnterMethods(stateStackEnteringIndex);
-
-
-                /**
-                 * Since we have transitioned to a new state we need to have
-                 * any deferred messages moved to the front of the message queue
-                 * so they will be processed before any other messages in the
-                 * message queue.
-                 */
-                moveDeferredMessageAtFrontOfQueue();
             }
 
             /**
@@ -859,21 +892,6 @@
                     mSm.onHalting();
                 }
             }
-
-            // Log only if state machine has not quit
-            if (mSm != null) {
-                if (mLogRecords.logOnlyTransitions()) {
-                    /** Record only if there is a transition */
-                    if (destState != null) {
-                        mLogRecords.add(mMsg, mSm.getLogRecString(mMsg), msgProcessedState,
-                                orgState, destState);
-                    }
-                } else if (recordLogMsg) {
-                    /** Record message */
-                    mLogRecords.add(mMsg, mSm.getLogRecString(mMsg), msgProcessedState,
-                            orgState, destState);
-                }
-            }
         }
 
         /**
@@ -1255,20 +1273,6 @@
     }
 
     /**
-     * @return current message
-     */
-    protected final Message getCurrentMessage() {
-        return mSmHandler.getCurrentMessage();
-    }
-
-    /**
-     * @return current state
-     */
-    protected final IState getCurrentState() {
-        return mSmHandler.getCurrentState();
-    }
-
-    /**
      * Add a new state to the state machine, parent will be null
      * @param state to add
      */
@@ -1287,6 +1291,26 @@
     }
 
     /**
+     * @return current message
+     */
+    protected final Message getCurrentMessage() {
+        // mSmHandler can be null if the state machine has quit.
+        SmHandler smh = mSmHandler;
+        if (smh == null) return null;
+        return smh.getCurrentMessage();
+    }
+
+    /**
+     * @return current state
+     */
+    protected final IState getCurrentState() {
+        // mSmHandler can be null if the state machine has quit.
+        SmHandler smh = mSmHandler;
+        if (smh == null) return null;
+        return smh.getCurrentState();
+    }
+
+    /**
      * transition to destination state. Upon returning
      * from processMessage the current state's exit will
      * be executed and upon the next message arriving
@@ -1390,21 +1414,44 @@
      * @return number of log records
      */
     public final int getLogRecSize() {
-        return mSmHandler.mLogRecords.size();
+        // mSmHandler can be null if the state machine has quit.
+        SmHandler smh = mSmHandler;
+        if (smh == null) return 0;
+        return smh.mLogRecords.size();
     }
 
     /**
      * @return the total number of records processed
      */
     public final int getLogRecCount() {
-        return mSmHandler.mLogRecords.count();
+        // mSmHandler can be null if the state machine has quit.
+        SmHandler smh = mSmHandler;
+        if (smh == null) return 0;
+        return smh.mLogRecords.count();
     }
 
     /**
-     * @return a log record
+     * @return a log record, or null if index is out of range
      */
     public final LogRec getLogRec(int index) {
-        return mSmHandler.mLogRecords.get(index);
+        // mSmHandler can be null if the state machine has quit.
+        SmHandler smh = mSmHandler;
+        if (smh == null) return null;
+        return smh.mLogRecords.get(index);
+    }
+
+    /**
+     * @return a copy of LogRecs as a collection
+     */
+    public final Collection<LogRec> copyLogRecs() {
+        Vector<LogRec> vlr = new Vector<LogRec>();
+        SmHandler smh = mSmHandler;
+        if (smh != null) {
+            for (LogRec lr : smh.mLogRecords.mLogRecVector) {
+                vlr.add(lr);
+            }
+        }
+        return vlr;
     }
 
     /**
@@ -1413,17 +1460,11 @@
      * @param string
      */
     protected void addLogRec(String string) {
-        mSmHandler.mLogRecords.add(null, string, null, null, null);
-    }
-
-    /**
-     * Add the string and state to LogRecords
-     *
-     * @param string
-     * @param state current state
-     */
-    protected void addLogRec(String string, State state) {
-        mSmHandler.mLogRecords.add(null, string, state, null, null);
+        // mSmHandler can be null if the state machine has quit.
+        SmHandler smh = mSmHandler;
+        if (smh == null) return;
+        smh.mLogRecords.add(this, smh.getCurrentMessage(), string, smh.getCurrentState(),
+                smh.mStateStack[smh.mStateStackTopIndex].state, smh.mDestState);
     }
 
     /**
@@ -1452,168 +1493,217 @@
     }
 
     /**
-     * @return Handler
+     * @return Handler, maybe null if state machine has quit.
      */
     public final Handler getHandler() {
         return mSmHandler;
     }
 
     /**
-     * Get a message and set Message.target = this.
+     * Get a message and set Message.target state machine handler.
      *
-     * @return message or null if SM has quit
+     * Note: The handler can be null if the state machine has quit,
+     * which means target will be null and may cause a AndroidRuntimeException
+     * in MessageQueue#enqueMessage if sent directly or if sent using
+     * StateMachine#sendMessage the message will just be ignored.
+     *
+     * @return  A Message object from the global pool
      */
     public final Message obtainMessage()
     {
-        if (mSmHandler == null) return null;
-
         return Message.obtain(mSmHandler);
     }
 
     /**
-     * Get a message and set Message.target = this and what
+     * Get a message and set Message.target state machine handler, what.
+     *
+     * Note: The handler can be null if the state machine has quit,
+     * which means target will be null and may cause a AndroidRuntimeException
+     * in MessageQueue#enqueMessage if sent directly or if sent using
+     * StateMachine#sendMessage the message will just be ignored.
      *
      * @param what is the assigned to Message.what.
-     * @return message or null if SM has quit
+     * @return  A Message object from the global pool
      */
     public final Message obtainMessage(int what) {
-        if (mSmHandler == null) return null;
-
         return Message.obtain(mSmHandler, what);
     }
 
     /**
-     * Get a message and set Message.target = this,
+     * Get a message and set Message.target state machine handler,
      * what and obj.
      *
+     * Note: The handler can be null if the state machine has quit,
+     * which means target will be null and may cause a AndroidRuntimeException
+     * in MessageQueue#enqueMessage if sent directly or if sent using
+     * StateMachine#sendMessage the message will just be ignored.
+     *
      * @param what is the assigned to Message.what.
      * @param obj is assigned to Message.obj.
-     * @return message or null if SM has quit
+     * @return  A Message object from the global pool
      */
     public final Message obtainMessage(int what, Object obj)
     {
-        if (mSmHandler == null) return null;
-
         return Message.obtain(mSmHandler, what, obj);
     }
 
     /**
-     * Get a message and set Message.target = this,
+     * Get a message and set Message.target state machine handler,
      * what, arg1 and arg2
      *
+     * Note: The handler can be null if the state machine has quit,
+     * which means target will be null and may cause a AndroidRuntimeException
+     * in MessageQueue#enqueMessage if sent directly or if sent using
+     * StateMachine#sendMessage the message will just be ignored.
+     *
      * @param what  is assigned to Message.what
      * @param arg1  is assigned to Message.arg1
      * @param arg2  is assigned to Message.arg2
-     * @return  A Message object from the global pool or null if
-     *          SM has quit
+     * @return  A Message object from the global pool
      */
     public final Message obtainMessage(int what, int arg1, int arg2)
     {
-        if (mSmHandler == null) return null;
-
         return Message.obtain(mSmHandler, what, arg1, arg2);
     }
 
     /**
-     * Get a message and set Message.target = this,
+     * Get a message and set Message.target state machine handler,
      * what, arg1, arg2 and obj
      *
+     * Note: The handler can be null if the state machine has quit,
+     * which means target will be null and may cause a AndroidRuntimeException
+     * in MessageQueue#enqueMessage if sent directly or if sent using
+     * StateMachine#sendMessage the message will just be ignored.
+     *
      * @param what  is assigned to Message.what
      * @param arg1  is assigned to Message.arg1
      * @param arg2  is assigned to Message.arg2
      * @param obj is assigned to Message.obj
-     * @return  A Message object from the global pool or null if
-     *          SM has quit
+     * @return  A Message object from the global pool
      */
     public final Message obtainMessage(int what, int arg1, int arg2, Object obj)
     {
-        if (mSmHandler == null) return null;
-
         return Message.obtain(mSmHandler, what, arg1, arg2, obj);
     }
 
     /**
      * Enqueue a message to this state machine.
+     *
+     * Message is ignored if state machine has quit.
      */
     public final void sendMessage(int what) {
         // mSmHandler can be null if the state machine has quit.
-        if (mSmHandler == null) return;
+        SmHandler smh = mSmHandler;
+        if (smh == null) return;
 
-        mSmHandler.sendMessage(obtainMessage(what));
+        smh.sendMessage(obtainMessage(what));
     }
 
     /**
      * Enqueue a message to this state machine.
+     *
+     * Message is ignored if state machine has quit.
      */
     public final void sendMessage(int what, Object obj) {
         // mSmHandler can be null if the state machine has quit.
-        if (mSmHandler == null) return;
+        SmHandler smh = mSmHandler;
+        if (smh == null) return;
 
-        mSmHandler.sendMessage(obtainMessage(what,obj));
+        smh.sendMessage(obtainMessage(what,obj));
     }
 
     /**
      * Enqueue a message to this state machine.
+     *
+     * Message is ignored if state machine has quit.
      */
     public final void sendMessage(Message msg) {
         // mSmHandler can be null if the state machine has quit.
-        if (mSmHandler == null) return;
+        SmHandler smh = mSmHandler;
+        if (smh == null) return;
 
-        mSmHandler.sendMessage(msg);
+        smh.sendMessage(msg);
     }
 
     /**
      * Enqueue a message to this state machine after a delay.
+     *
+     * Message is ignored if state machine has quit.
      */
     public final void sendMessageDelayed(int what, long delayMillis) {
         // mSmHandler can be null if the state machine has quit.
-        if (mSmHandler == null) return;
+        SmHandler smh = mSmHandler;
+        if (smh == null) return;
 
-        mSmHandler.sendMessageDelayed(obtainMessage(what), delayMillis);
+        smh.sendMessageDelayed(obtainMessage(what), delayMillis);
     }
 
     /**
      * Enqueue a message to this state machine after a delay.
+     *
+     * Message is ignored if state machine has quit.
      */
     public final void sendMessageDelayed(int what, Object obj, long delayMillis) {
         // mSmHandler can be null if the state machine has quit.
-        if (mSmHandler == null) return;
+        SmHandler smh = mSmHandler;
+        if (smh == null) return;
 
-        mSmHandler.sendMessageDelayed(obtainMessage(what, obj), delayMillis);
+        smh.sendMessageDelayed(obtainMessage(what, obj), delayMillis);
     }
 
     /**
      * Enqueue a message to this state machine after a delay.
+     *
+     * Message is ignored if state machine has quit.
      */
     public final void sendMessageDelayed(Message msg, long delayMillis) {
         // mSmHandler can be null if the state machine has quit.
-        if (mSmHandler == null) return;
+        SmHandler smh = mSmHandler;
+        if (smh == null) return;
 
-        mSmHandler.sendMessageDelayed(msg, delayMillis);
+        smh.sendMessageDelayed(msg, delayMillis);
     }
 
     /**
      * Enqueue a message to the front of the queue for this state machine.
      * Protected, may only be called by instances of StateMachine.
+     *
+     * Message is ignored if state machine has quit.
      */
     protected final void sendMessageAtFrontOfQueue(int what, Object obj) {
-        mSmHandler.sendMessageAtFrontOfQueue(obtainMessage(what, obj));
+        // mSmHandler can be null if the state machine has quit.
+        SmHandler smh = mSmHandler;
+        if (smh == null) return;
+
+        smh.sendMessageAtFrontOfQueue(obtainMessage(what, obj));
     }
 
     /**
      * Enqueue a message to the front of the queue for this state machine.
      * Protected, may only be called by instances of StateMachine.
+     *
+     * Message is ignored if state machine has quit.
      */
     protected final void sendMessageAtFrontOfQueue(int what) {
-        mSmHandler.sendMessageAtFrontOfQueue(obtainMessage(what));
+        // mSmHandler can be null if the state machine has quit.
+        SmHandler smh = mSmHandler;
+        if (smh == null) return;
+
+        smh.sendMessageAtFrontOfQueue(obtainMessage(what));
     }
 
     /**
      * Enqueue a message to the front of the queue for this state machine.
      * Protected, may only be called by instances of StateMachine.
+     *
+     * Message is ignored if state machine has quit.
      */
     protected final void sendMessageAtFrontOfQueue(Message msg) {
-        mSmHandler.sendMessageAtFrontOfQueue(msg);
+        // mSmHandler can be null if the state machine has quit.
+        SmHandler smh = mSmHandler;
+        if (smh == null) return;
+
+        smh.sendMessageAtFrontOfQueue(msg);
     }
 
     /**
@@ -1621,7 +1711,23 @@
      * Protected, may only be called by instances of StateMachine.
      */
     protected final void removeMessages(int what) {
-        mSmHandler.removeMessages(what);
+        // mSmHandler can be null if the state machine has quit.
+        SmHandler smh = mSmHandler;
+        if (smh == null) return;
+
+        smh.removeMessages(what);
+    }
+
+    /**
+     * Validate that the message was sent by
+     * {@link StateMachine#quit} or {@link StateMachine#quitNow}.
+     * */
+    protected final boolean isQuit(Message msg) {
+        // mSmHandler can be null if the state machine has quit.
+        SmHandler smh = mSmHandler;
+        if (smh == null) return msg.what == SM_QUIT_CMD;
+
+        return smh.isQuit(msg);
     }
 
     /**
@@ -1629,9 +1735,10 @@
      */
     protected final void quit() {
         // mSmHandler can be null if the state machine is already stopped.
-        if (mSmHandler == null) return;
+        SmHandler smh = mSmHandler;
+        if (smh == null) return;
 
-        mSmHandler.quit();
+        smh.quit();
     }
 
     /**
@@ -1639,9 +1746,10 @@
      */
     protected final void quitNow() {
         // mSmHandler can be null if the state machine is already stopped.
-        if (mSmHandler == null) return;
+        SmHandler smh = mSmHandler;
+        if (smh == null) return;
 
-        mSmHandler.quitNow();
+        smh.quitNow();
     }
 
     /**
@@ -1649,9 +1757,10 @@
      */
     public boolean isDbg() {
         // mSmHandler can be null if the state machine has quit.
-        if (mSmHandler == null) return false;
+        SmHandler smh = mSmHandler;
+        if (smh == null) return false;
 
-        return mSmHandler.isDbg();
+        return smh.isDbg();
     }
 
     /**
@@ -1661,9 +1770,10 @@
      */
     public void setDbg(boolean dbg) {
         // mSmHandler can be null if the state machine has quit.
-        if (mSmHandler == null) return;
+        SmHandler smh = mSmHandler;
+        if (smh == null) return;
 
-        mSmHandler.setDbg(dbg);
+        smh.setDbg(dbg);
     }
 
     /**
@@ -1671,10 +1781,11 @@
      */
     public void start() {
         // mSmHandler can be null if the state machine has quit.
-        if (mSmHandler == null) return;
+        SmHandler smh = mSmHandler;
+        if (smh == null) return;
 
         /** Send the complete construction message */
-        mSmHandler.completeConstruction();
+        smh.completeConstruction();
     }
 
     /**
@@ -1688,7 +1799,7 @@
         pw.println(getName() + ":");
         pw.println(" total records=" + getLogRecCount());
         for (int i=0; i < getLogRecSize(); i++) {
-            pw.printf(" rec[%d]: %s\n", i, getLogRec(i).toString(this));
+            pw.printf(" rec[%d]: %s\n", i, getLogRec(i).toString());
             pw.flush();
         }
         pw.println("curState=" + getCurrentState().getName());
diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp
index de14826..33ed0b9 100644
--- a/core/jni/android_view_GLES20Canvas.cpp
+++ b/core/jni/android_view_GLES20Canvas.cpp
@@ -156,6 +156,17 @@
     return Stencil::getStencilSize();
 }
 
+static void android_view_GLES20Canvas_setName(JNIEnv* env,
+        jobject clazz, OpenGLRenderer* renderer, jstring name) {
+    if (name != NULL) {
+        const char* textArray = env->GetStringUTFChars(name, NULL);
+        renderer->setName(textArray);
+        env->ReleaseStringUTFChars(name, textArray);
+    } else {
+        renderer->setName(NULL);
+    }
+}
+
 // ----------------------------------------------------------------------------
 // Functor
 // ----------------------------------------------------------------------------
@@ -479,7 +490,7 @@
             rects.push(r.fTop);
             rects.push(r.fRight);
             rects.push(r.fBottom);
-            count++;
+            count += 4;
             it.next();
         }
         renderer->drawRects(rects.array(), count, paint);
@@ -949,6 +960,8 @@
     { "nPrepare",           "(IZ)I",           (void*) android_view_GLES20Canvas_prepare },
     { "nPrepareDirty",      "(IIIIIZ)I",       (void*) android_view_GLES20Canvas_prepareDirty },
     { "nFinish",            "(I)V",            (void*) android_view_GLES20Canvas_finish },
+    { "nSetName",           "(ILjava/lang/String;)V",
+            (void*) android_view_GLES20Canvas_setName },
 
     { "nGetStencilSize",    "()I",             (void*) android_view_GLES20Canvas_getStencilSize },
 
diff --git a/core/jni/com_android_internal_os_ZygoteInit.cpp b/core/jni/com_android_internal_os_ZygoteInit.cpp
index 7e5dede..bc8c4a7 100644
--- a/core/jni/com_android_internal_os_ZygoteInit.cpp
+++ b/core/jni/com_android_internal_os_ZygoteInit.cpp
@@ -163,32 +163,6 @@
     }
 }
 
-static void com_android_internal_os_ZygoteInit_setCapabilities (JNIEnv *env,
-    jobject clazz, jlong permitted, jlong effective)
-{
-    struct __user_cap_header_struct capheader;
-    struct __user_cap_data_struct capdata;
-    int err;
-
-    memset (&capheader, 0, sizeof(capheader));
-    memset (&capdata, 0, sizeof(capdata));
-
-    capheader.version = _LINUX_CAPABILITY_VERSION;
-    capheader.pid = 0;
-
-    // As of this writing, capdata is __u32, but that's expected
-    // to change...
-    capdata.effective = effective;
-    capdata.permitted = permitted;
-
-    err = capset (&capheader, &capdata);
-
-    if (err < 0) {
-        jniThrowIOException(env, errno);
-        return;
-    }
-}
-
 static jlong com_android_internal_os_ZygoteInit_capgetPermitted (JNIEnv *env,
     jobject clazz, jint pid)
 {
@@ -304,8 +278,6 @@
             (void *) com_android_internal_os_ZygoteInit_reopenStdio},
     { "setCloseOnExec", "(Ljava/io/FileDescriptor;Z)V",
         (void *)  com_android_internal_os_ZygoteInit_setCloseOnExec},
-    { "setCapabilities", "(JJ)V",
-        (void *) com_android_internal_os_ZygoteInit_setCapabilities },
     { "capgetPermitted", "(I)J",
         (void *) com_android_internal_os_ZygoteInit_capgetPermitted },
     { "selectReadable", "([Ljava/io/FileDescriptor;)I",
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 558080c..e5aca48 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -532,6 +532,31 @@
         android:label="@string/permlab_addVoicemail"
         android:description="@string/permdesc_addVoicemail" />
 
+    <!-- =============================================== -->
+    <!-- Permissions for enabling accessibility features -->
+    <!-- =============================================== -->
+
+    <!-- Used for permissions that allow requesting certain accessibility features. -->
+    <permission-group android:name="android.permission-group.ACCESSIBILITY_FEATURES"
+        android:label="@string/permgrouplab_accessibilityFeatures"
+        android:icon="@drawable/perm_group_accessibility_features"
+        android:description="@string/permgroupdesc_accessibilityFeatures"
+        android:priority="380" />
+
+    <!-- Allows an accessibility service to request touch exploration mode. -->
+    <permission android:name="android.permission.CAN_REQUEST_TOUCH_EXPLORATION_MODE"
+        android:permissionGroup="android.permission-group.ACCESSIBILITY_FEATURES"
+        android:label="@string/permlab_canRequestTouchExplorationMode"
+        android:description="@string/permdesc_canRequestTouchExplorationMode"
+        android:protectionLevel="dangerous" />
+
+    <!-- Allows an accessibility service to request enhanced web accessibility. -->
+    <permission android:name="android.permission.CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY"
+        android:permissionGroup="android.permission-group.ACCESSIBILITY_FEATURES"
+        android:label="@string/permlab_canRequestEnahncedWebAccessibility"
+        android:description="@string/permdesc_canRequestEnahncedWebAccessibility"
+        android:protectionLevel="dangerous" />
+
     <!-- ======================================= -->
     <!-- Permissions for accessing location info -->
     <!-- ======================================= -->
@@ -1730,7 +1755,7 @@
         android:description="@string/permdesc_bindInputMethod"
         android:protectionLevel="signature" />
 
-        <!-- Must be required by an {@link android.accessibilityservice.AccessibilityService},
+    <!-- Must be required by an {@link android.accessibilityservice.AccessibilityService},
          to ensure that only the system can bind to it. -->
     <permission android:name="android.permission.BIND_ACCESSIBILITY_SERVICE"
         android:label="@string/permlab_bindAccessibilityService"
@@ -2265,6 +2290,12 @@
             </intent-filter>
         </receiver>
 
+        <receiver android:name="com.android.server.updates.TZInfoInstallReceiver" >
+            <intent-filter>
+                <action android:name="android.intent.action.UPDATE_TZINFO" />
+            </intent-filter>
+        </receiver>
+
         <receiver android:name="com.android.server.MasterClearReceiver"
             android:permission="android.permission.MASTER_CLEAR"
             android:priority="100" >
diff --git a/core/res/res/drawable-hdpi/perm_group_accessibility_features.png b/core/res/res/drawable-hdpi/perm_group_accessibility_features.png
new file mode 100755
index 0000000..849c19c
--- /dev/null
+++ b/core/res/res/drawable-hdpi/perm_group_accessibility_features.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/perm_group_accessibility_features.png b/core/res/res/drawable-mdpi/perm_group_accessibility_features.png
new file mode 100755
index 0000000..ba86d3d
--- /dev/null
+++ b/core/res/res/drawable-mdpi/perm_group_accessibility_features.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/perm_group_accessibility_features.png b/core/res/res/drawable-xhdpi/perm_group_accessibility_features.png
new file mode 100644
index 0000000..2fec7a3
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/perm_group_accessibility_features.png
Binary files differ
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 0639da8..86554f5 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -225,6 +225,10 @@
     <string name="permgrouplab_storage" msgid="1971118770546336966">"Stoor"</string>
     <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"Gebruik die USB-berging."</string>
     <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"Lees die SD-kaart."</string>
+    <!-- no translation found for permgrouplab_accessibilityFeatures (7919025602283593907) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_accessibilityFeatures (4205196881678144335) -->
+    <skip />
     <string name="permlab_statusBar" msgid="7417192629601890791">"deaktiveer of verander statusbalk"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Laat die program toe om die statusbalk te deaktiveer en stelselikone by te voeg of te verwyder."</string>
     <string name="permlab_statusBarService" msgid="7247281911387931485">"statusbalk"</string>
@@ -344,6 +348,14 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Dit laat die houer toe om aan die topvlak-koppelvlak van \'n invoermetode te bind. Dit moet nooit vir normale programme nodig wees nie."</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"verbind aan \'n toeganklikheidsdiens"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Dit laat die houer toe om aan die top-koppelvlak van \'n toeganklikheidsdiens te verbind. Behoort nooit vir gewone programme nodig te wees nie."</string>
+    <!-- no translation found for permlab_canRequestTouchExplorationMode (6094034289937541846) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestTouchExplorationMode (940314268922270663) -->
+    <skip />
+    <!-- no translation found for permlab_canRequestEnahncedWebAccessibility (1905232971331801453) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestEnahncedWebAccessibility (4500520989321729676) -->
+    <skip />
     <string name="permlab_bindTextService" msgid="7358378401915287938">"bind aan \'n teksdiens"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"Dit laat die houer toe om aan die topvlak-koppelvlak van \'n teksdiens (bv SpellCheckerService) te bind. Dit moet nooit vir normale programme nodig wees nie."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"bind aan \'n VPN-diens"</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index f0ad4bf..0e23085 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -225,6 +225,10 @@
     <string name="permgrouplab_storage" msgid="1971118770546336966">"ማከማቻ"</string>
     <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"የUSB ማከማቻ ድረስ።"</string>
     <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"SD ካርድ ድረስ"</string>
+    <!-- no translation found for permgrouplab_accessibilityFeatures (7919025602283593907) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_accessibilityFeatures (4205196881678144335) -->
+    <skip />
     <string name="permlab_statusBar" msgid="7417192629601890791">"የሁኔቴ አሞሌ አቦዝን ወይም ቀይር"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"የስርዓት አዶዎችን ወደ ሁኔታ አሞሌ ላለማስቻል ወይም ለማከል እና ለማስወገድ ለመተግበሪያው ይፈቅዳሉ፡፡"</string>
     <string name="permlab_statusBarService" msgid="7247281911387931485">"ኹናቴ አሞሌ"</string>
@@ -299,10 +303,8 @@
     <string name="permdesc_shutdown" msgid="7046500838746291775">"የእንቅስቃሴውን አደራጅ ወደ ዝጋ ሁነታ አስቀምጥ።ሙሉ ለሙሉ ዝጋ አያከናውንም።"</string>
     <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"የትግበራ መቀያየርን ተከላከል"</string>
     <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"ተጠቃሚው ከሌላ መተግበሪያ ከመቀየር ይከላከላል።"</string>
-    <!-- no translation found for permlab_getTopActivityInfo (2537922311411546016) -->
-    <skip />
-    <!-- no translation found for permdesc_getTopActivityInfo (2512448855496067131) -->
-    <skip />
+    <string name="permlab_getTopActivityInfo" msgid="2537922311411546016">"የአሁኑ የመተግበሪያ መረጃ ያግኙ"</string>
+    <string name="permdesc_getTopActivityInfo" msgid="2512448855496067131">"ያዢው በማያ ገጹ ፊት ላይ ስላለው የአሁኑ መተግበሪያ የግል መረጃ እንዲያመጣ ያስችለዋል።"</string>
     <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"ሁሉንም መተግበሪያ ማስነሻ አሳይ እና ተቆጣጠር"</string>
     <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"እንቅስቃሴዎችን ስርዓቱ እንዴት እንደሚያስጀምር ለመከታተል እና ለመቆጣጠር ለመተግበሪያው ይፈቅዳሉ፡፡ ተንኮል አዘል መተግበሪያዎች የስርዓቱን ክብረ ገመና ሙሉለሙሉ ሊያጋልጡ ይችላሉ፡፡ ይህ ፍቃድ የሚያስፈልገው ለግንባታ ብቻ ነው፤ ለመደበኛ አጠቃቀም ፈጽሞ አይደለም፡፡"</string>
     <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"አካታች የተወገደለት ስርጭት ላክ"</string>
@@ -346,6 +348,14 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"ያዡ ግቤት ስልቱን ወደ ከፍተኛ-ደረጃ በይነገጽ ለመጠረዝ ይፈቅዳሉ። ለመደበኛ ትግበራዎች በፍፁም አያስፈልግም።"</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"ከአንድ የተደራሽነት አገልግሎት ጋር እሰር"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"ያዢው ወደ የአንድ ተደራሽነት አገልግሎት ከፍተኛ-ደረጃ በይነገጽ እንዲያስር ይፈቅድለታል። ለመደበኛ መተግበሪያዎች መቼም ቢሆን ሊያስፈልግ አይገባም።"</string>
+    <!-- no translation found for permlab_canRequestTouchExplorationMode (6094034289937541846) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestTouchExplorationMode (940314268922270663) -->
+    <skip />
+    <!-- no translation found for permlab_canRequestEnahncedWebAccessibility (1905232971331801453) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestEnahncedWebAccessibility (4500520989321729676) -->
+    <skip />
     <string name="permlab_bindTextService" msgid="7358378401915287938">"ለፅሁፍ አገልግሎት አሰረ"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"ያዡ ግቤት ለከፍተኛ-ደረጃ የፅሁፍ አገልግሎት ገፅታ ለመጠረዝ ይፈቅዳል። ለመደበኛ ትግበራዎች በፍፁም አያስፈልግም።"</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"ለVPN አገልግሎት ተገዛ"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index c2f5a35..32e6d5d 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -225,6 +225,10 @@
     <string name="permgrouplab_storage" msgid="1971118770546336966">"التخزين"</string>
     <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"الدخول إلى وحدة تخزين USB."</string>
     <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"الدخول إلى بطاقة SD."</string>
+    <!-- no translation found for permgrouplab_accessibilityFeatures (7919025602283593907) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_accessibilityFeatures (4205196881678144335) -->
+    <skip />
     <string name="permlab_statusBar" msgid="7417192629601890791">"تعطيل شريط الحالة أو تعديله"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"للسماح للتطبيق بتعطيل شريط الحالة أو إضافة رموز نظام وإزالتها."</string>
     <string name="permlab_statusBarService" msgid="7247281911387931485">"شريط الحالة"</string>
@@ -344,6 +348,14 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"للسماح للمالك بالالتزام بواجهة المستوى العلوي لأسلوب الإدخال. لن تكون هناك حاجة إليه مطلقًا مع التطبيقات العادية."</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"الالتزام بخدمة إمكانية الدخول"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"للسماح للمالك بالالتزام بواجهة المستوى العلوي لخدمة إمكانية الدخول. لن تكون هناك حاجة إليه مطلقًا مع التطبيقات العادية."</string>
+    <!-- no translation found for permlab_canRequestTouchExplorationMode (6094034289937541846) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestTouchExplorationMode (940314268922270663) -->
+    <skip />
+    <!-- no translation found for permlab_canRequestEnahncedWebAccessibility (1905232971331801453) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestEnahncedWebAccessibility (4500520989321729676) -->
+    <skip />
     <string name="permlab_bindTextService" msgid="7358378401915287938">"الالتزام بخدمة إدخال النصوص"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"للسماح للمالك بالالتزام بواجهة المستوى العلوي لخدمة إدخال النصوص (على سبيل المثال، SpellCheckerService). لن تكون هناك حاجة إليه مطلقًا مع التطبيقات العادية."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"الالتزام بخدمة VPN"</string>
@@ -783,7 +795,7 @@
     <string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"زر الإيقاف المؤقت"</string>
     <string name="lockscreen_transport_play_description" msgid="5888422938351019426">"زر التشغيل"</string>
     <string name="lockscreen_transport_stop_description" msgid="4562318378766987601">"زر الإيقاف"</string>
-    <string name="emergency_calls_only" msgid="6733978304386365407">"مكالمات الطوارئ فقط"</string>
+    <string name="emergency_calls_only" msgid="6733978304386365407">"مكالمات طوارئ فقط"</string>
     <string name="lockscreen_network_locked_message" msgid="143389224986028501">"الشبكة مؤمّنة"</string>
     <string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"بطاقة SIM مؤمّنة بكود PUK."</string>
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"راجع دليل المستخدم أو اتصل بخدمة العملاء."</string>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index 0f1fda4..0d95884 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -225,6 +225,10 @@
     <string name="permgrouplab_storage" msgid="1971118770546336966">"Сховішча"</string>
     <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"Атрымаць доступ да USB-назапашвальнiка."</string>
     <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"Доступ да SD-карты."</string>
+    <!-- no translation found for permgrouplab_accessibilityFeatures (7919025602283593907) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_accessibilityFeatures (4205196881678144335) -->
+    <skip />
     <string name="permlab_statusBar" msgid="7417192629601890791">"адключаць ці змяняць радок стану"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Дазваляе прыкладанням адключаць радок стану або дадаваць і выдаляць сістэмныя значкі."</string>
     <string name="permlab_statusBarService" msgid="7247281911387931485">"радок стану"</string>
@@ -299,10 +303,8 @@
     <string name="permdesc_shutdown" msgid="7046500838746291775">"Спыняе дзейнасць менеджэра. Не выконвае поўнае адключэнне."</string>
     <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"прадухіляць пераключэнне прыкладанняў"</string>
     <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"Не дазваляе карыстальніку пераходзіць да іншага прыкладання."</string>
-    <!-- no translation found for permlab_getTopActivityInfo (2537922311411546016) -->
-    <skip />
-    <!-- no translation found for permdesc_getTopActivityInfo (2512448855496067131) -->
-    <skip />
+    <string name="permlab_getTopActivityInfo" msgid="2537922311411546016">"атрымаць бягучую інфармацыю прыкладання"</string>
+    <string name="permdesc_getTopActivityInfo" msgid="2512448855496067131">"Дазваляе ўладальніку атрымлiваць асабістую інфармацыю аб бягучым прыкладаннi на пярэднім плане экрана."</string>
     <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"адсочваць і кантраляваць запуск усіх прыкладанняў"</string>
     <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"Дазваляе прыкладанню сачыць і кантраляваць, як сістэма запускае працэсы. Шкоднасныя прыкладанні могуць цалкам парушыць працу сістэмы. Гэты дазвол патрэбны толькі для распрацоўкі, ніколі для звычайнага выкарыстання."</string>
     <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"трансляваць паведамленні аб выдаленні пакетаў"</string>
@@ -346,6 +348,14 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Дазваляе ўладальніку прывязвацца да інтэрфейсу верхняга ўзроўню метада ўводу. Не патрабуецца для звычайных прыкладанняў."</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"прывязацца да службы доступу"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Дазваляе ўладальніку прывязвацца да інтэрфейсу верхняга ўзроўню службы доступу. Не патрабуецца для звычайных прыкладанняў."</string>
+    <!-- no translation found for permlab_canRequestTouchExplorationMode (6094034289937541846) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestTouchExplorationMode (940314268922270663) -->
+    <skip />
+    <!-- no translation found for permlab_canRequestEnahncedWebAccessibility (1905232971331801453) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestEnahncedWebAccessibility (4500520989321729676) -->
+    <skip />
     <string name="permlab_bindTextService" msgid="7358378401915287938">"звязаць з тэкставай службай"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"Дазваляе ўладальніку прывязвацца да інтэрфейсу верхняга ўзроўню тэкставай паслугі (напрыклад, SpellCheckerService). Ніколі не патрабуецца для звычайных прыкладанняў."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"звязвацца з VPN сэрвісам"</string>
@@ -1458,7 +1468,7 @@
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Вы няправільна ўвялі графічны ключ разблакiроўкi пэўную колькасць разоў: <xliff:g id="NUMBER_0">%d</xliff:g>. Пасля яшчэ некалькiх няўдалых спроб (<xliff:g id="NUMBER_1">%d</xliff:g>) вам будзе прапанавана разблакiраваць тэлефон, увайшоўшы ў Google."\n\n" Паўтарыце спробу праз <xliff:g id="NUMBER_2">%d</xliff:g> с."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Вы няправільна ўвялі графічны ключ разблакiроўкi пэўную колькасць разоў: <xliff:g id="NUMBER_0">%d</xliff:g>. Пасля яшчэ некалькiх няўдалых спроб (<xliff:g id="NUMBER_1">%d</xliff:g>) вам будзе прапанавана разблакiраваць тэлефон, увайшоўшы ў Google."\n\n" Паўтарыце спробу праз <xliff:g id="NUMBER_2">%d</xliff:g> с."</string>
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
-    <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Выдаліць"</string>
+    <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Выдалiць"</string>
     <string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"Павялiчыць гук больш за рэкамендаваны ўзровень?"\n"Доўгае слуханне музыкi на вялiкай гучнасцi можа пашкодзiць ваш слых."</string>
     <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Утрымлiвайце два пальцы, каб уключыць доступ."</string>
     <string name="accessibility_enabled" msgid="1381972048564547685">"Даступнасць уключана."</string>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 54b6198..0e8fa7f 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -225,6 +225,10 @@
     <string name="permgrouplab_storage" msgid="1971118770546336966">"Съхранение"</string>
     <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"Достъп до USB хранилището."</string>
     <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"Достъп до SD картата."</string>
+    <!-- no translation found for permgrouplab_accessibilityFeatures (7919025602283593907) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_accessibilityFeatures (4205196881678144335) -->
+    <skip />
     <string name="permlab_statusBar" msgid="7417192629601890791">"деактивиране или промяна на лентата на състоянието"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Разрешава на приложението да деактивира лентата на състоянието или да добавя и премахва системни икони."</string>
     <string name="permlab_statusBarService" msgid="7247281911387931485">"лента на състоянието"</string>
@@ -299,10 +303,8 @@
     <string name="permdesc_shutdown" msgid="7046500838746291775">"Изключва диспечера на дейностите. Не извършва пълно изключване."</string>
     <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"предотвратяване на превключването между приложения"</string>
     <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"Не позволява на потребителя да превключва към друго приложение."</string>
-    <!-- no translation found for permlab_getTopActivityInfo (2537922311411546016) -->
-    <skip />
-    <!-- no translation found for permdesc_getTopActivityInfo (2512448855496067131) -->
-    <skip />
+    <string name="permlab_getTopActivityInfo" msgid="2537922311411546016">"извличане на информация за текущото приложение"</string>
+    <string name="permdesc_getTopActivityInfo" msgid="2512448855496067131">"Разрешава на собственика да извлича частна информация за текущото приложение на преден план на екрана."</string>
     <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"наблюдение и контрол на стартирането на всички приложения"</string>
     <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"Разрешава на приложението да наблюдава и контролира как системата стартира дейности. Злонамерените приложения могат изцяло да компрометират системата. Това разрешение е нужно само за програмиране, никога за нормална употреба."</string>
     <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"изпращане на излъчване при премахнат пакет"</string>
@@ -346,6 +348,14 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Разрешава на притежателя да се обвърже с интерфейса от най-високото ниво на метод на въвеждане. Нормалните приложения би трябвало никога да не се нуждаят от това."</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"обвързване с услуга за достъпност"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Разрешава на притежателя да се обвърже с интерфейса от най-високото ниво на услуга за достъпност. Нормалните приложения би трябвало никога да не се нуждаят от това."</string>
+    <!-- no translation found for permlab_canRequestTouchExplorationMode (6094034289937541846) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestTouchExplorationMode (940314268922270663) -->
+    <skip />
+    <!-- no translation found for permlab_canRequestEnahncedWebAccessibility (1905232971331801453) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestEnahncedWebAccessibility (4500520989321729676) -->
+    <skip />
     <string name="permlab_bindTextService" msgid="7358378401915287938">"обвързване с текстова услуга"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"Разрешава на притежателя да се обвърже с интерфейса от най-високото ниво на текстова услуга (напр. SpellCheckerService). Нормалните приложения би трябвало никога да не се нуждаят от това."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"обвързване с услуга за VPN"</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 5acb723..b952bd1 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -225,6 +225,10 @@
     <string name="permgrouplab_storage" msgid="1971118770546336966">"Emmagatzematge"</string>
     <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"Accedeix a l\'emmag. USB."</string>
     <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"Accedeix a la targeta SD."</string>
+    <!-- no translation found for permgrouplab_accessibilityFeatures (7919025602283593907) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_accessibilityFeatures (4205196881678144335) -->
+    <skip />
     <string name="permlab_statusBar" msgid="7417192629601890791">"desactivar o modificar la barra d\'estat"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Permet que l\'aplicació desactivi la barra d\'estat o afegeixi i elimini icones del sistema."</string>
     <string name="permlab_statusBarService" msgid="7247281911387931485">"barra d\'estat"</string>
@@ -299,10 +303,8 @@
     <string name="permdesc_shutdown" msgid="7046500838746291775">"Posa el gestor d\'activitats en estat d\'apagada. No fa una apagada completa."</string>
     <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"impedir els canvis d\'aplicació"</string>
     <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"Impedeix que l\'usuari canviï a una altra aplicació."</string>
-    <!-- no translation found for permlab_getTopActivityInfo (2537922311411546016) -->
-    <skip />
-    <!-- no translation found for permdesc_getTopActivityInfo (2512448855496067131) -->
-    <skip />
+    <string name="permlab_getTopActivityInfo" msgid="2537922311411546016">"obtenció d\'informació de l\'aplicació actual"</string>
+    <string name="permdesc_getTopActivityInfo" msgid="2512448855496067131">"Permet que el titular recuperi informació privada sobre l\'aplicació actual al primer pla de la pantalla."</string>
     <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"supervisa i controla tots els inicis d\'aplicacions"</string>
     <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"Permet que l\'aplicació supervisi i controli com el sistema inicia activitats. Les aplicacions malicioses poden comprometre totalment el sistema. Aquest permís només és necessari per al desenvolupament, mai per a l\'ús normal."</string>
     <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"enviar difusió d\'eliminació de paquet"</string>
@@ -346,6 +348,14 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Permet que el titular vinculi a la interfície de nivell superior d\'un mètode d\'entrada. No s\'hauria de necessitar mai per a les aplicacions normals."</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"vincular amb un servei d\'accessibilitat"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Permet vincular amb la interfície de nivell superior d\'un servei d\'accessibilitat. Les aplicacions normals no haurien de necessitar-ho."</string>
+    <!-- no translation found for permlab_canRequestTouchExplorationMode (6094034289937541846) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestTouchExplorationMode (940314268922270663) -->
+    <skip />
+    <!-- no translation found for permlab_canRequestEnahncedWebAccessibility (1905232971331801453) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestEnahncedWebAccessibility (4500520989321729676) -->
+    <skip />
     <string name="permlab_bindTextService" msgid="7358378401915287938">"vincula a un servei de text"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"Permet al titular vincular amb la interfície de nivell superior d\'un servei de text (per exemple, SpellCheckerService). Les aplicacions normals mai no ho haurien de necessitar."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"vincula a un servei de VPN"</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index f10a217..16d6490 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -225,6 +225,10 @@
     <string name="permgrouplab_storage" msgid="1971118770546336966">"Úložiště"</string>
     <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"Přístup do úložiště USB."</string>
     <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"Přístup ke kartě SD."</string>
+    <!-- no translation found for permgrouplab_accessibilityFeatures (7919025602283593907) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_accessibilityFeatures (4205196881678144335) -->
+    <skip />
     <string name="permlab_statusBar" msgid="7417192629601890791">"zakázání či změny stavového řádku"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Umožňuje aplikaci zakázat stavový řádek nebo přidat či odebrat systémové ikony."</string>
     <string name="permlab_statusBarService" msgid="7247281911387931485">"stavový řádek"</string>
@@ -299,10 +303,8 @@
     <string name="permdesc_shutdown" msgid="7046500838746291775">"Uvede správce činností do vypnutého stavu. Nedojde však k úplnému vypnutí."</string>
     <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"zabránění přepínání aplikací"</string>
     <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"Zabrání uživateli přepnout na jinou aplikaci."</string>
-    <!-- no translation found for permlab_getTopActivityInfo (2537922311411546016) -->
-    <skip />
-    <!-- no translation found for permdesc_getTopActivityInfo (2512448855496067131) -->
-    <skip />
+    <string name="permlab_getTopActivityInfo" msgid="2537922311411546016">"získat informace o aktuální aplikaci"</string>
+    <string name="permdesc_getTopActivityInfo" msgid="2512448855496067131">"Umožňuje držiteli získat soukromé informace o aktuální aplikaci na popředí obrazovky."</string>
     <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"sledování a řízení spouštění všech aplikací"</string>
     <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"Umožňuje aplikaci sledovat a řídit spouštění činností systémem. Škodlivé aplikace mohou systém zcela ovládnout. Toto oprávnění je požadováno pouze pro účely vývoje, nikdy pro běžné použití."</string>
     <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"odeslání vysílání o odstranění balíčku"</string>
@@ -346,6 +348,14 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Umožňuje držiteli vázat se na nejvyšší úroveň rozhraní pro zadávání dat. Běžné aplikace by toto oprávnění neměly nikdy požadovat."</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"navázat se na službu usnadnění přístupu"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Umožňuje držiteli navázat se na nejvyšší úroveň rozhraní služby usnadnění přístupu. Běžné aplikace by toto oprávnění neměly nikdy požadovat."</string>
+    <!-- no translation found for permlab_canRequestTouchExplorationMode (6094034289937541846) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestTouchExplorationMode (940314268922270663) -->
+    <skip />
+    <!-- no translation found for permlab_canRequestEnahncedWebAccessibility (1905232971331801453) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestEnahncedWebAccessibility (4500520989321729676) -->
+    <skip />
     <string name="permlab_bindTextService" msgid="7358378401915287938">"navázat se na textovou službu"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"Umožňuje držiteli připojit se k nejvyšší úrovni rozhraní textové služby (např. SpellCheckerService). Běžné aplikace by toto oprávnění neměly nikdy požadovat."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"navázat se na službu VPN"</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index eec3dd4..c8ef522 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -225,6 +225,10 @@
     <string name="permgrouplab_storage" msgid="1971118770546336966">"Lagring"</string>
     <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"Få adgang til USB-lager."</string>
     <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"Få adgang til SD-kortet."</string>
+    <!-- no translation found for permgrouplab_accessibilityFeatures (7919025602283593907) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_accessibilityFeatures (4205196881678144335) -->
+    <skip />
     <string name="permlab_statusBar" msgid="7417192629601890791">"deaktiver eller rediger statuslinje"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Tillader, at appen kan deaktivere statusbjælken eller tilføje og fjerne systemikoner."</string>
     <string name="permlab_statusBarService" msgid="7247281911387931485">"statusbjælke"</string>
@@ -299,10 +303,8 @@
     <string name="permdesc_shutdown" msgid="7046500838746291775">"Sætter aktivitetsadministratoren i lukningstilstand. Lukker ikke helt ned."</string>
     <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"undgå programskift"</string>
     <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"Forhindrer brugeren i at skifte til en anden app."</string>
-    <!-- no translation found for permlab_getTopActivityInfo (2537922311411546016) -->
-    <skip />
-    <!-- no translation found for permdesc_getTopActivityInfo (2512448855496067131) -->
-    <skip />
+    <string name="permlab_getTopActivityInfo" msgid="2537922311411546016">"få aktuelle app-oplysninger"</string>
+    <string name="permdesc_getTopActivityInfo" msgid="2512448855496067131">"Tillader, at brugeren henter private oplysninger om den aktuelle applikation i forgrunden på ​​skærmen."</string>
     <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"overvåge og kontrollere åbning af alle apps"</string>
     <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"Tillader, at appen kan overvåge og kontrollere, hvordan systemet starter aktiviteter. Ondsindede apps kan fuldstændig kompromittere systemet. Denne tilladelse er kun nødvendig til udvikling, aldrig til normal brug."</string>
     <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"send udsendelse om fjernet pakke"</string>
@@ -346,6 +348,14 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Tillader, at brugeren kan forpligter sig til en inputmetodes grænseflade på øverste niveau. Bør aldrig være nødvendigt til almindelige apps."</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"bind dig til en tilgængelighedstjeneste"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Tillader, at brugeren binder sig til en grænseflade for en tilgængelighedstjeneste på øverste niveau. Bør aldrig være nødvendigt til almindelige apps."</string>
+    <!-- no translation found for permlab_canRequestTouchExplorationMode (6094034289937541846) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestTouchExplorationMode (940314268922270663) -->
+    <skip />
+    <!-- no translation found for permlab_canRequestEnahncedWebAccessibility (1905232971331801453) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestEnahncedWebAccessibility (4500520989321729676) -->
+    <skip />
     <string name="permlab_bindTextService" msgid="7358378401915287938">"forpligte sig til en sms-tjeneste"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"Tillader, at ejeren kan binde en teksttjenestes grænseflade (f. eks. SpellCheckerService) på øverste niveau. Dette bør aldrig være nødvendigt til normale apps."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"bind til en VPN-tjeneste"</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index d5a67f0..a51e459 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -225,6 +225,10 @@
     <string name="permgrouplab_storage" msgid="1971118770546336966">"Speicher"</string>
     <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"Zugriff auf USB-Speicher"</string>
     <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"Zugriff auf SD-Karte"</string>
+    <!-- no translation found for permgrouplab_accessibilityFeatures (7919025602283593907) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_accessibilityFeatures (4205196881678144335) -->
+    <skip />
     <string name="permlab_statusBar" msgid="7417192629601890791">"Statusleiste deaktivieren oder ändern"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Ermöglicht der App, die Statusleiste zu deaktivieren oder Systemsymbole hinzuzufügen oder zu entfernen"</string>
     <string name="permlab_statusBarService" msgid="7247281911387931485">"Statusleiste"</string>
@@ -299,10 +303,8 @@
     <string name="permdesc_shutdown" msgid="7046500838746291775">"Versetzt den Aktivitätsmanager in einen heruntergefahrenen Zustand. Führt kein vollständiges Herunterfahren aus."</string>
     <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"App-Wechsel verhindern"</string>
     <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"Hindert den Nutzer daran, zu einer anderen App zu wechseln"</string>
-    <!-- no translation found for permlab_getTopActivityInfo (2537922311411546016) -->
-    <skip />
-    <!-- no translation found for permdesc_getTopActivityInfo (2512448855496067131) -->
-    <skip />
+    <string name="permlab_getTopActivityInfo" msgid="2537922311411546016">"Informationen zur aktuellen App abrufen"</string>
+    <string name="permdesc_getTopActivityInfo" msgid="2512448855496067131">"Ermöglicht es dem Inhaber, private Informationen zur aktuellen App im Vordergrund des Bildschirms abzurufen"</string>
     <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"Start von Apps überwachen und steuern"</string>
     <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"Ermöglicht der App, den Start von Systemaktivitäten zu überwachen und zu steuern. Schädliche Apps können so das gesamte System beeinträchtigen. Diese Berechtigung wird nur zu Entwicklungszwecken und nie für die normale Nutzung benötigt."</string>
     <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"Broadcast ohne Paket senden"</string>
@@ -346,6 +348,14 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Ermöglicht dem Halter, sich an die Oberfläche einer Eingabemethode auf oberster Ebene zu binden. Sollte nie für normale Apps benötigt werden."</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"An eine Bedienungshilfe binden"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Ermöglicht dem Halter, sich an die Oberfläche einer Bedienungshilfe auf oberster Ebene zu binden. Sollte nie für normale Apps benötigt werden."</string>
+    <!-- no translation found for permlab_canRequestTouchExplorationMode (6094034289937541846) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestTouchExplorationMode (940314268922270663) -->
+    <skip />
+    <!-- no translation found for permlab_canRequestEnahncedWebAccessibility (1905232971331801453) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestEnahncedWebAccessibility (4500520989321729676) -->
+    <skip />
     <string name="permlab_bindTextService" msgid="7358378401915287938">"An einen Textdienst binden"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"Ermöglicht dem Halter, sich an die Oberfläche eines Textdienstes auf oberster Ebene zu binden, z. B. eines Rechtschreibprüfungsdienstes. Sollte nie für normale Apps benötigt werden."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"An einen VPN-Dienst binden"</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index cf42a41..0ef5064 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -225,6 +225,10 @@
     <string name="permgrouplab_storage" msgid="1971118770546336966">"Αποθηκευτικός χώρος"</string>
     <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"Πρόσβαση στον χώρο αποθ. USB."</string>
     <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"Πρόσβαση στην κάρτα SD."</string>
+    <!-- no translation found for permgrouplab_accessibilityFeatures (7919025602283593907) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_accessibilityFeatures (4205196881678144335) -->
+    <skip />
     <string name="permlab_statusBar" msgid="7417192629601890791">"απενεργοποίηση ή τροποποίηση γραμμής κατάστασης"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Επιτρέπει στην εφαρμογή να απενεργοποιεί τη γραμμή κατάστασης ή να προσθέτει και να αφαιρεί εικονίδια συστήματος."</string>
     <string name="permlab_statusBarService" msgid="7247281911387931485">"γραμμή κατάστασης"</string>
@@ -299,10 +303,8 @@
     <string name="permdesc_shutdown" msgid="7046500838746291775">"Θέτει το πρόγραμμα διαχείρισης δραστηριοτήτων σε κατάσταση τερματισμού λειτουργιών. Δεν εκτελεί πλήρη τερματισμό λειτουργιών."</string>
     <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"αποτροπή εναλλαγών εφαρμογών"</string>
     <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"Δεν επιτρέπει στο χρήστη να μεταβεί σε άλλη εφαρμογή."</string>
-    <!-- no translation found for permlab_getTopActivityInfo (2537922311411546016) -->
-    <skip />
-    <!-- no translation found for permdesc_getTopActivityInfo (2512448855496067131) -->
-    <skip />
+    <string name="permlab_getTopActivityInfo" msgid="2537922311411546016">"λήψη πληροφοριών σχετικά με την τρέχουσα εφαρμογή"</string>
+    <string name="permdesc_getTopActivityInfo" msgid="2512448855496067131">"Δίνει στον κάτοχο τη δυνατότητα ανάκτησης απόρρητων πληροφοριών σχετικά με την τρέχουσα εφαρμογή στο προσκήνιο της οθόνης."</string>
     <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"παρακολούθηση και έλεγχος όλων των εκκινήσεων εφαρμογών"</string>
     <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"Επιτρέπει στην εφαρμογή να παρακολουθεί και να ελέγχει τον τρόπο με τον οποίο το σύστημα εκκινεί δραστηριότητες. Τυχόν κακόβουλες εφαρμογές ενδέχεται να θέσουν σε κίνδυνο το σύστημα. Αυτή η άδεια είναι απαραίτητη μόνο για σκοπούς ανάπτυξης και ποτέ για συνήθη χρήση."</string>
     <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"αποστολή εκπομπής χωρίς πακέτο"</string>
@@ -346,6 +348,14 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Επιτρέπει στον κάτοχο τη δέσμευση στη διεπαφή ανωτάτου επιπέδου μιας μεθόδου εισόδου. Δεν απαιτείται για συνήθεις εφαρμογές."</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"δέσμευση σε υπηρεσία προσβασιμότητας"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Επιτρέπει στον κάτοχο τη δέσμευση στη διεπαφή ανώτατου επιπέδου μιας υπηρεσίας προσβασιμότητας. Δεν απαιτείται σε κανονικές εφαρμογές."</string>
+    <!-- no translation found for permlab_canRequestTouchExplorationMode (6094034289937541846) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestTouchExplorationMode (940314268922270663) -->
+    <skip />
+    <!-- no translation found for permlab_canRequestEnahncedWebAccessibility (1905232971331801453) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestEnahncedWebAccessibility (4500520989321729676) -->
+    <skip />
     <string name="permlab_bindTextService" msgid="7358378401915287938">"δέσμευση σε υπηρεσία ανταλλαγής μηνυμάτων"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"Επιτρέπει στον κάτοχο τη σύνδεση με τη διεπαφή ανωτέρου επιπέδου μιας υπηρεσίας ανταλλαγής μηνυμάτων (π.χ. SpellCheckerService). Δεν είναι απαραίτητο για κανονικές εφαρμογές."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"δέσμευση σε υπηρεσία VPN"</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index 73ee358..d8aa0b4 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -225,6 +225,10 @@
     <string name="permgrouplab_storage" msgid="1971118770546336966">"Storage"</string>
     <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"Access the USB storage."</string>
     <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"Access the SD card."</string>
+    <!-- no translation found for permgrouplab_accessibilityFeatures (7919025602283593907) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_accessibilityFeatures (4205196881678144335) -->
+    <skip />
     <string name="permlab_statusBar" msgid="7417192629601890791">"disable or modify status bar"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Allows the app to disable the status bar or add and remove system icons."</string>
     <string name="permlab_statusBarService" msgid="7247281911387931485">"status bar"</string>
@@ -299,10 +303,8 @@
     <string name="permdesc_shutdown" msgid="7046500838746291775">"Puts the activity manager into a shut-down state. Does not perform a complete shut down."</string>
     <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"prevent app switches"</string>
     <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"Prevents the user from switching to another app."</string>
-    <!-- no translation found for permlab_getTopActivityInfo (2537922311411546016) -->
-    <skip />
-    <!-- no translation found for permdesc_getTopActivityInfo (2512448855496067131) -->
-    <skip />
+    <string name="permlab_getTopActivityInfo" msgid="2537922311411546016">"get current app info"</string>
+    <string name="permdesc_getTopActivityInfo" msgid="2512448855496067131">"Allows the holder to retrieve private information about the current application in the foreground of the screen."</string>
     <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"monitor and control all app launching"</string>
     <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"Allows the app to monitor and control how the system launches activities. Malicious apps may completely compromise the system. This permission is only needed for development, never for normal use."</string>
     <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"send package removed broadcast"</string>
@@ -346,6 +348,14 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Allows the holder to bind to the top-level interface of an input method. Should never be needed for normal apps."</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"bind to an accessibility service"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Allows the holder to bind to the top-level interface of an accessibility service. Should never be needed for normal apps."</string>
+    <!-- no translation found for permlab_canRequestTouchExplorationMode (6094034289937541846) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestTouchExplorationMode (940314268922270663) -->
+    <skip />
+    <!-- no translation found for permlab_canRequestEnahncedWebAccessibility (1905232971331801453) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestEnahncedWebAccessibility (4500520989321729676) -->
+    <skip />
     <string name="permlab_bindTextService" msgid="7358378401915287938">"bind to a text service"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"Allows the holder to bind to the top-level interface of a text service (e.g. SpellCheckerService). Should never be needed for normal applications."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"bind to a VPN service"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 6bb8e44..a05fbb9 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -225,6 +225,10 @@
     <string name="permgrouplab_storage" msgid="1971118770546336966">"Espacio de almacenamiento"</string>
     <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"Acceder al almacenamiento USB."</string>
     <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"Acceder a la tarjeta SD."</string>
+    <!-- no translation found for permgrouplab_accessibilityFeatures (7919025602283593907) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_accessibilityFeatures (4205196881678144335) -->
+    <skip />
     <string name="permlab_statusBar" msgid="7417192629601890791">"desactivar o modificar la barra de estado"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Permite que la aplicación inhabilite la barra de estado o que agregue y elimine íconos del sistema."</string>
     <string name="permlab_statusBarService" msgid="7247281911387931485">"barra de estado"</string>
@@ -299,10 +303,8 @@
     <string name="permdesc_shutdown" msgid="7046500838746291775">"Pone al administrador de la actividad en estado de cierre. No realiza un cierre completo."</string>
     <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"impedir conmutadores de aplicación"</string>
     <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"Evita que el usuario cambie a otra aplicación."</string>
-    <!-- no translation found for permlab_getTopActivityInfo (2537922311411546016) -->
-    <skip />
-    <!-- no translation found for permdesc_getTopActivityInfo (2512448855496067131) -->
-    <skip />
+    <string name="permlab_getTopActivityInfo" msgid="2537922311411546016">"obtener información de aplicación actual"</string>
+    <string name="permdesc_getTopActivityInfo" msgid="2512448855496067131">"Permite que el titular recupere información privada sobre la aplicación actual en el primer plano de la pantalla."</string>
     <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"supervisar y controlar la ejecución de todas las aplicaciones"</string>
     <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"Permite que la aplicación supervise y controle la manera en la que el sistema inicia actividades. Las aplicaciones maliciosas pueden comprometer el sistema por completo. Este permiso es necesario solo para el desarrollo, nunca para el uso habitual."</string>
     <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"enviar emisión de paquete eliminado"</string>
@@ -346,6 +348,14 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Permite al propietario vincularse a la interfaz de nivel superior de un método de entrada. Las aplicaciones normales no deberían necesitar este permiso."</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"vincular a un servicio de accesibilidad"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Permite al propietario vincularse a la interfaz de nivel superior de un servicio de accesibilidad. Las aplicaciones normales no deberían necesitar este permiso."</string>
+    <!-- no translation found for permlab_canRequestTouchExplorationMode (6094034289937541846) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestTouchExplorationMode (940314268922270663) -->
+    <skip />
+    <!-- no translation found for permlab_canRequestEnahncedWebAccessibility (1905232971331801453) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestEnahncedWebAccessibility (4500520989321729676) -->
+    <skip />
     <string name="permlab_bindTextService" msgid="7358378401915287938">"vincular a un servicio de texto"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"Permite al titular vincularse a la interfaz de nivel superior de un servicio de texto (p. ej., SpellCheckerService). Las aplicaciones normales no deberían necesitar este permiso."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"vincular con un servicio de VPN"</string>
@@ -897,7 +907,7 @@
     <string name="permlab_updateLock" msgid="3527558366616680889">"no realizar actualizaciones automáticas"</string>
     <string name="permdesc_updateLock" msgid="1655625832166778492">"Permite a su propietario ofrecer información al sistema acerca de cuándo sería adecuado reiniciar el sistema de forma no interactiva y actualizar el dispositivo."</string>
     <string name="save_password_message" msgid="767344687139195790">"¿Quieres recordar esta contraseña en el navegador?"</string>
-    <string name="save_password_notnow" msgid="6389675316706699758">"Ahora no."</string>
+    <string name="save_password_notnow" msgid="6389675316706699758">"Ahora no"</string>
     <string name="save_password_remember" msgid="6491879678996749466">"Recuerda"</string>
     <string name="save_password_never" msgid="8274330296785855105">"Nunca"</string>
     <string name="open_permission_deny" msgid="7374036708316629800">"No tienes permiso para abrir esta página."</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index fbbcf89..d7deef4 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -225,6 +225,10 @@
     <string name="permgrouplab_storage" msgid="1971118770546336966">"Almacenamiento"</string>
     <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"Acceso a almacenamiento USB"</string>
     <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"Acceder a la tarjeta SD"</string>
+    <!-- no translation found for permgrouplab_accessibilityFeatures (7919025602283593907) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_accessibilityFeatures (4205196881678144335) -->
+    <skip />
     <string name="permlab_statusBar" msgid="7417192629601890791">"inhabilitar o modificar la barra de estado"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Permite que la aplicación inhabilite la barra de estado o añada y elimine iconos del sistema."</string>
     <string name="permlab_statusBarService" msgid="7247281911387931485">"barra de estado"</string>
@@ -299,10 +303,8 @@
     <string name="permdesc_shutdown" msgid="7046500838746291775">"Pone el administrador de actividades en estado de cierre. No realiza un cierre completo."</string>
     <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"evitar cambios de aplicación"</string>
     <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"Evita que el usuario cambie a otra aplicación."</string>
-    <!-- no translation found for permlab_getTopActivityInfo (2537922311411546016) -->
-    <skip />
-    <!-- no translation found for permdesc_getTopActivityInfo (2512448855496067131) -->
-    <skip />
+    <string name="permlab_getTopActivityInfo" msgid="2537922311411546016">"obtener información de la aplicación actual"</string>
+    <string name="permdesc_getTopActivityInfo" msgid="2512448855496067131">"Permite que el titular recupere información privada sobre la aplicación actual en el primer plano de la pantalla."</string>
     <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"supervisar y controlar la ejecución de todas las aplicaciones"</string>
     <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"Permite que la aplicación supervise y controle la ejecución de las actividades del sistema. Las aplicaciones malintencionadas pueden vulnerar la seguridad del sistema. Este permiso es necesario únicamente para tareas de desarrollo, nunca para el uso habitual."</string>
     <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"enviar emisión eliminada de paquete"</string>
@@ -346,6 +348,14 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Permite que se enlace con la interfaz de nivel superior de un método de entrada de texto. Las aplicaciones normales no deberían necesitar este permiso."</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"enlazar con un servicio de accesibilidad"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Permite enlazar con la interfaz de nivel superior de un servicio de accesibilidad. Las aplicaciones normales no deberían necesitar este permiso."</string>
+    <!-- no translation found for permlab_canRequestTouchExplorationMode (6094034289937541846) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestTouchExplorationMode (940314268922270663) -->
+    <skip />
+    <!-- no translation found for permlab_canRequestEnahncedWebAccessibility (1905232971331801453) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestEnahncedWebAccessibility (4500520989321729676) -->
+    <skip />
     <string name="permlab_bindTextService" msgid="7358378401915287938">"enlazar con un servicio de texto"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"Permite enlazar con la interfaz de nivel superior de un servicio de texto (por ejemplo, SpellCheckerService). Las aplicaciones normales no deberían necesitar este permiso."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"enlazar con un servicio VPN"</string>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index 00b5c2d..1e18a8e 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -225,6 +225,10 @@
     <string name="permgrouplab_storage" msgid="1971118770546336966">"Mäluruum"</string>
     <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"Juurdepääs USB-mäluseadmele."</string>
     <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"Juurdepääs SD-kaardile."</string>
+    <!-- no translation found for permgrouplab_accessibilityFeatures (7919025602283593907) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_accessibilityFeatures (4205196881678144335) -->
+    <skip />
     <string name="permlab_statusBar" msgid="7417192629601890791">"keela või muuda olekuriba"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Võimaldab rakendusel keelata olekuriba või lisada ja eemaldada süsteemiikoone."</string>
     <string name="permlab_statusBarService" msgid="7247281911387931485">"olekuriba"</string>
@@ -299,10 +303,8 @@
     <string name="permdesc_shutdown" msgid="7046500838746291775">"Lülitab tegevushalduri väljalülitusolekusse. Ei lülita lõplikult välja."</string>
     <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"väldi rakenduste ümberlülitamist"</string>
     <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"Takistab kasutaja lülitumist teisele rakendusele."</string>
-    <!-- no translation found for permlab_getTopActivityInfo (2537922311411546016) -->
-    <skip />
-    <!-- no translation found for permdesc_getTopActivityInfo (2512448855496067131) -->
-    <skip />
+    <string name="permlab_getTopActivityInfo" msgid="2537922311411546016">"aktiivse rakenduse teabe hankimine"</string>
+    <string name="permdesc_getTopActivityInfo" msgid="2512448855496067131">"Lubab õiguste saajal hankida privaatset teavet ekraanil esiplaanil oleva aktiivse rakenduse kohta."</string>
     <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"Kõigi rakenduste käivitumise jälgimine ja juhtimine"</string>
     <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"Võimaldab rakendusel jälgida ja juhtida, kuidas süsteem tegevusi käivitab. Pahatahtlikud rakendused võivad süsteemi täielikult rikkuda. Seda õigust on vaja ainult arenduseks, mitte tavakasutuse korral."</string>
     <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"saada paketist eemaldatud saade"</string>
@@ -346,6 +348,14 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Lubab omanikul siduda sisestusmeetodi ülataseme liidesega. Tavarakenduste puhul ei peaks seda kunagi vaja minema."</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"sidumine juurdepääsuteenusega"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Lubab omanikul luua sideme juurdepääsuteenuse ülataseme liidesega. Tavarakenduste puhul ei tohiks seda kunagi vaja minna."</string>
+    <!-- no translation found for permlab_canRequestTouchExplorationMode (6094034289937541846) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestTouchExplorationMode (940314268922270663) -->
+    <skip />
+    <!-- no translation found for permlab_canRequestEnahncedWebAccessibility (1905232971331801453) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestEnahncedWebAccessibility (4500520989321729676) -->
+    <skip />
     <string name="permlab_bindTextService" msgid="7358378401915287938">"tekstiteenusega sidumine"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"Võimaldab omanikul siduda tekstiteenuse (nt SpellCheckerService) ülataseme liidesega. Tavarakenduste puhul ei peaks seda kunagi vaja minema."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"seo VPN-teenusega"</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 3cbd496..ba37b34 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -225,6 +225,10 @@
     <string name="permgrouplab_storage" msgid="1971118770546336966">"حافظه"</string>
     <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"به حافظهٔ USB دسترسی پیدا کنید."</string>
     <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"به کارت SD دسترسی داشته باشید."</string>
+    <!-- no translation found for permgrouplab_accessibilityFeatures (7919025602283593907) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_accessibilityFeatures (4205196881678144335) -->
+    <skip />
     <string name="permlab_statusBar" msgid="7417192629601890791">"غیرفعال کردن یا تغییر نوار وضعیت"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"به برنامه اجازه می‎دهد تا نوار وضعیت را غیرفعال کند یا نمادهای سیستم را اضافه یا حذف کند."</string>
     <string name="permlab_statusBarService" msgid="7247281911387931485">"نوار وضعیت"</string>
@@ -344,6 +348,14 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"به دارنده این دستگاه اجازه می‎دهد تا به رابط سطح بالای یک روش ورودی متصل شود. این ویژگی هیچگاه برای برنامه‎های معمولی ضروری نمی‎باشد."</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"اتصال به سرویس دسترسی"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"به دارنده اجازه می‌دهد که به رابط سطح بالای سرویس دسترسی متصل شود. هرگز برای برنامه‌های معمولی مورد نیاز نیست."</string>
+    <!-- no translation found for permlab_canRequestTouchExplorationMode (6094034289937541846) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestTouchExplorationMode (940314268922270663) -->
+    <skip />
+    <!-- no translation found for permlab_canRequestEnahncedWebAccessibility (1905232971331801453) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestEnahncedWebAccessibility (4500520989321729676) -->
+    <skip />
     <string name="permlab_bindTextService" msgid="7358378401915287938">"اتصال به یک سرویس متنی"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"به دارنده اجازه می‌دهد خود را به یک رابط سطح بالای خدمات متنی مرتبط کند (برای مثال SpellCheckerService). هرگز برای برنامه‌های عادی لازم نیست."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"اتصال به یک سرویس VPN"</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index c4dfd6c..a65e158 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -225,6 +225,10 @@
     <string name="permgrouplab_storage" msgid="1971118770546336966">"Tallennustila"</string>
     <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"Käytä USB-tallennustilaa."</string>
     <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"Käytä SD-korttia."</string>
+    <!-- no translation found for permgrouplab_accessibilityFeatures (7919025602283593907) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_accessibilityFeatures (4205196881678144335) -->
+    <skip />
     <string name="permlab_statusBar" msgid="7417192629601890791">"poista tilapalkki käytöstä tai muokkaa tilapalkkia"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Antaa sovelluksen poistaa tilapalkin käytöstä ja lisätä tai poistaa järjestelmäkuvakkeita."</string>
     <string name="permlab_statusBarService" msgid="7247281911387931485">"tilapalkki"</string>
@@ -299,10 +303,8 @@
     <string name="permdesc_shutdown" msgid="7046500838746291775">"Asettaa toimintojen hallinnan sulkeutumistilaan. Ei sulje puhelinta kokonaan."</string>
     <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"estä sovellusten vaihto"</string>
     <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"Estää käyttäjää siirtymästä toiseen sovellukseen."</string>
-    <!-- no translation found for permlab_getTopActivityInfo (2537922311411546016) -->
-    <skip />
-    <!-- no translation found for permdesc_getTopActivityInfo (2512448855496067131) -->
-    <skip />
+    <string name="permlab_getTopActivityInfo" msgid="2537922311411546016">"hae nykyisen sovelluksen tiedot"</string>
+    <string name="permdesc_getTopActivityInfo" msgid="2512448855496067131">"Antaa sovellukselle luvan noutaa nykyistä sovellusta koskevia yksityisiä tietoja ruudun etualalla."</string>
     <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"kaikkien sovellusten käynnistämisen valvonta ja hallinta"</string>
     <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"Antaa sovelluksen valvoa ja hallita sitä, miten laite käynnistää toimintoja. Haitalliset sovellukset voivat vaarantaa laitteen käytön. Tätä oikeutta tarvitaan vain kehityskäyttöön eikä koskaan tavalliseen käyttöön."</string>
     <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"lähetä paketeista poistettuja lähetyksiä"</string>
@@ -346,6 +348,14 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Antaa sovelluksen sitoutua syötetavan ylätason käyttöliittymään. Ei tavallisten sovellusten käyttöön."</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"sitoudu esteettömyyspalveluun"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Antaa sovelluksen sitoutua esteettömyyspalvelun ylemmän tason käyttöliittymään. Ei tavallisten sovelluksien käyttöön."</string>
+    <!-- no translation found for permlab_canRequestTouchExplorationMode (6094034289937541846) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestTouchExplorationMode (940314268922270663) -->
+    <skip />
+    <!-- no translation found for permlab_canRequestEnahncedWebAccessibility (1905232971331801453) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestEnahncedWebAccessibility (4500520989321729676) -->
+    <skip />
     <string name="permlab_bindTextService" msgid="7358378401915287938">"tekstipalveluun sitoutuminen"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"Antaa sovelluksen sitoutua tekstipalvelun (kuten SpellCheckerServicen) ylätason liittymään. Ei tavallisten sovellusten käyttöön."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"sitoudu VPN-palveluun"</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index ea1ef50..6a9354b 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -225,6 +225,10 @@
     <string name="permgrouplab_storage" msgid="1971118770546336966">"Stockage"</string>
     <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"Accéder à la  mémoire de stockage USB"</string>
     <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"Accéder à la carte SD"</string>
+    <!-- no translation found for permgrouplab_accessibilityFeatures (7919025602283593907) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_accessibilityFeatures (4205196881678144335) -->
+    <skip />
     <string name="permlab_statusBar" msgid="7417192629601890791">"Désactivation ou modification de la barre d\'état"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Permet à l\'application de désactiver la barre d\'état, ou d\'ajouter et de supprimer des icônes système."</string>
     <string name="permlab_statusBarService" msgid="7247281911387931485">"barre d\'état"</string>
@@ -299,10 +303,8 @@
     <string name="permdesc_shutdown" msgid="7046500838746291775">"Place le gestionnaire d\'activités en état d\'arrêt. N\'effectue pas un arrêt complet."</string>
     <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"empêcher les changements d\'applications"</string>
     <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"Empêche l\'utilisateur de changer d\'application."</string>
-    <!-- no translation found for permlab_getTopActivityInfo (2537922311411546016) -->
-    <skip />
-    <!-- no translation found for permdesc_getTopActivityInfo (2512448855496067131) -->
-    <skip />
+    <string name="permlab_getTopActivityInfo" msgid="2537922311411546016">"Récupérer des informations sur l\'application actuelle"</string>
+    <string name="permdesc_getTopActivityInfo" msgid="2512448855496067131">"Permet à l\'application autorisée de récupérer des informations confidentielles à propos de l\'application exécutée au premier plan sur l\'écran."</string>
     <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"suivre et contrôler le lancement de toutes les applications"</string>
     <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"Permet à l\'application de surveiller et de contrôler la façon dont le système lance les activités. Des applications malveillantes peuvent exploiter cette fonctionnalité pour totalement compromettre le système. Cette autorisation est uniquement destinée aux développeurs. Elle ne doit jamais être activée dans le cadre d\'une utilisation standard."</string>
     <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"Envoyer une diffusion sans paquet"</string>
@@ -346,6 +348,14 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Permet à l\'application autorisée de s\'associer à l\'interface de plus haut niveau d\'un mode de saisie. Les applications standards ne doivent jamais avoir recours à cette fonctionnalité."</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"associer à un service d\'accessibilité"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Permet à l\'application autorisée de s\'associer à l\'interface de plus haut niveau d\'un service d\'accessibilité. Les applications standards ne doivent jamais avoir recours à cette fonctionnalité."</string>
+    <!-- no translation found for permlab_canRequestTouchExplorationMode (6094034289937541846) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestTouchExplorationMode (940314268922270663) -->
+    <skip />
+    <!-- no translation found for permlab_canRequestEnahncedWebAccessibility (1905232971331801453) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestEnahncedWebAccessibility (4500520989321729676) -->
+    <skip />
     <string name="permlab_bindTextService" msgid="7358378401915287938">"associer à un service de texte"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"Permet à l\'application de s\'associer à l\'interface de haut niveau d\'un service de texte (par exemple, SpellCheckerService). Les applications standards ne doivent jamais avoir recours à cette fonctionnalité."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"associer à un service VPN"</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index c3ef672..72b881c 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -225,6 +225,10 @@
     <string name="permgrouplab_storage" msgid="1971118770546336966">"संग्रहण"</string>
     <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"USB संग्रहण में पहुंचें."</string>
     <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"SD कार्ड में पहुंचें."</string>
+    <!-- no translation found for permgrouplab_accessibilityFeatures (7919025602283593907) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_accessibilityFeatures (4205196881678144335) -->
+    <skip />
     <string name="permlab_statusBar" msgid="7417192629601890791">"स्‍थिति बार अक्षम या बदलें"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"एप्लिकेशन को स्थिति बार अक्षम करने या सिस्‍टम आइकन को जोड़ने या निकालने देता है."</string>
     <string name="permlab_statusBarService" msgid="7247281911387931485">"स्‍थिति बार"</string>
@@ -299,10 +303,8 @@
     <string name="permdesc_shutdown" msgid="7046500838746291775">"गतिविधि प्रबंधक को शटडाउन स्‍थिति में रखता है. पूर्ण शटडाउन निष्‍पादित नहीं करता है."</string>
     <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"एप्‍लिकेशन स्‍विच करने से रोकता है"</string>
     <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"उपयोगकर्ता को दूसरे एप्‍लिकेशन पर स्‍विच करने से रोकता है."</string>
-    <!-- no translation found for permlab_getTopActivityInfo (2537922311411546016) -->
-    <skip />
-    <!-- no translation found for permdesc_getTopActivityInfo (2512448855496067131) -->
-    <skip />
+    <string name="permlab_getTopActivityInfo" msgid="2537922311411546016">"वर्तमान एप्लिकेशन की जानकारी प्राप्त करें"</string>
+    <string name="permdesc_getTopActivityInfo" msgid="2512448855496067131">"धारक को स्क्रीन के अग्रभाग में स्थित वर्तमान एप्लिकेशन के बारे में निजी जानकारी प्राप्त करने देती है."</string>
     <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"सभी एप्‍लिकेशन की लॉन्‍चिंग की निगरानी करें और उसे नियंत्रित करें"</string>
     <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"एप्लिकेशन को यह निगरानी और नियंत्रित करने देता है कि सिस्टम कैसे गतिविधियां लॉन्च करता है. दुर्भावनापूर्ण एप्लिकेशन सिस्टम को पूरी तरह से जोखिम में डाल सकते हैं. इस अनुमति की आवश्यकता केवल विकास के लिए है, सामान्य उपयोग के लिए कभी नहीं."</string>
     <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"पैकेज निकाले गए प्रसारण भेजें"</string>
@@ -346,6 +348,14 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"धारक को किसी इनपुट विधि के शीर्ष-स्‍तर इंटरफ़ेस से आबद्ध होने देता है. सामान्‍य एप्‍लिकेशन के लिए कभी भी आवश्‍यक नहीं होना चाहिए."</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"पहुंच-योग्‍यता सेवा से आबद्ध करें"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"धारक को किसी पहुंच-योग्यता सेवा के शीर्ष-स्‍तर इंटरफ़ेस से आबद्ध होने देता है. सामान्‍य एप्‍लिकेशन के लिए कभी भी आवश्‍यक नहीं होना चाहिए."</string>
+    <!-- no translation found for permlab_canRequestTouchExplorationMode (6094034289937541846) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestTouchExplorationMode (940314268922270663) -->
+    <skip />
+    <!-- no translation found for permlab_canRequestEnahncedWebAccessibility (1905232971331801453) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestEnahncedWebAccessibility (4500520989321729676) -->
+    <skip />
     <string name="permlab_bindTextService" msgid="7358378401915287938">"किसी पाठ सेवा पर बने रहें"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"धारक को किसी पाठ सेवा (उदा. SpellCheckerService) के शीर्ष-स्‍तर इंटरफ़ेस पर आबद्ध होने देता है. सामान्‍य एप्‍लिकेशन के लिए कभी भी आवश्‍यक नहीं होना चाहिए."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"किसी VPN सेवा से आबद्ध करें"</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 72aad27..19c0c9a 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -225,6 +225,10 @@
     <string name="permgrouplab_storage" msgid="1971118770546336966">"Prostor za pohranu"</string>
     <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"Pristupi memoriji USB."</string>
     <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"Pristup SD kartici."</string>
+    <!-- no translation found for permgrouplab_accessibilityFeatures (7919025602283593907) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_accessibilityFeatures (4205196881678144335) -->
+    <skip />
     <string name="permlab_statusBar" msgid="7417192629601890791">"onemogućavanje ili izmjena trake statusa"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Aplikaciji omogućuje onemogućavanje trake statusa ili dodavanje i uklanjanje sistemskih ikona."</string>
     <string name="permlab_statusBarService" msgid="7247281911387931485">"traka statusa"</string>
@@ -299,10 +303,8 @@
     <string name="permdesc_shutdown" msgid="7046500838746291775">"Postavlja upravitelja za aktivnost u stanje mirovanja. Ne isključuje ga u potpunosti."</string>
     <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"sprečavanje promjene aplikacije"</string>
     <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"Sprječava korisnika u prebacivanju na drugu aplikaciju."</string>
-    <!-- no translation found for permlab_getTopActivityInfo (2537922311411546016) -->
-    <skip />
-    <!-- no translation found for permdesc_getTopActivityInfo (2512448855496067131) -->
-    <skip />
+    <string name="permlab_getTopActivityInfo" msgid="2537922311411546016">"dohvaćanje informacija o trenutačnoj aplikaciji"</string>
+    <string name="permdesc_getTopActivityInfo" msgid="2512448855496067131">"Omogućuje nositelju dohvaćanje privatnih informacija o trenutačnoj aplikaciji u prednjem planu na zaslonu."</string>
     <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"praćenje i nadzor svih pokretanja aplikacija"</string>
     <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"Omogućuje aplikaciji nadzor i upravljanje načinom na koji sustav pokreće aktivnosti. Zlonamjerne aplikacije mogu posve ugroziti sustav. Ta je dozvola potrebna samo za razvoj, nikada za uobičajenu upotrebu."</string>
     <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"slanje paketno uklonjenog prijenosa"</string>
@@ -346,6 +348,14 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Nositelju omogućuje povezivanje sučelja najviše razine načina unosa. Ne bi smjelo biti potrebno za normalne aplikacije."</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"vezivanje uz uslugu dostupnosti"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Nositelju omogućuje vezanje uz sučelje najviše razine usluge dostupnosti. Ne bi smjelo biti potrebno za normalne aplikacije."</string>
+    <!-- no translation found for permlab_canRequestTouchExplorationMode (6094034289937541846) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestTouchExplorationMode (940314268922270663) -->
+    <skip />
+    <!-- no translation found for permlab_canRequestEnahncedWebAccessibility (1905232971331801453) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestEnahncedWebAccessibility (4500520989321729676) -->
+    <skip />
     <string name="permlab_bindTextService" msgid="7358378401915287938">"vezanje na tekstualnu uslugu"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"Omogućuje korisniku povezivanje s najvišom razinom sučelja tekstualne usluge (npr. SpellCheckerService). Ne bi smjelo biti potrebno za normalne aplikacije."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"vezanje na VPN uslugu"</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 6dd4f8f..4e10901 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -225,6 +225,10 @@
     <string name="permgrouplab_storage" msgid="1971118770546336966">"Tárhely"</string>
     <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"Az USB-tár elérése."</string>
     <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"Az SD-kártya elérése."</string>
+    <!-- no translation found for permgrouplab_accessibilityFeatures (7919025602283593907) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_accessibilityFeatures (4205196881678144335) -->
+    <skip />
     <string name="permlab_statusBar" msgid="7417192629601890791">"állapotsor kikapcsolása vagy módosítása"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Lehetővé teszi az alkalmazás számára az állapotsor kikapcsolását, illetve rendszerikonok hozzáadását és eltávolítását."</string>
     <string name="permlab_statusBarService" msgid="7247281911387931485">"állapotsor"</string>
@@ -299,10 +303,8 @@
     <string name="permdesc_shutdown" msgid="7046500838746291775">"Leállítás állapotba helyezi a tevékenységkezelőt. Nem hajtja végre a teljes leállítást."</string>
     <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"alkalmazásváltás megakadályozása"</string>
     <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"Megakadályozza, hogy a felhasználó átváltson egy másik alkalmazásra."</string>
-    <!-- no translation found for permlab_getTopActivityInfo (2537922311411546016) -->
-    <skip />
-    <!-- no translation found for permdesc_getTopActivityInfo (2512448855496067131) -->
-    <skip />
+    <string name="permlab_getTopActivityInfo" msgid="2537922311411546016">"az alkalmazás aktuális információinak lekérése"</string>
+    <string name="permdesc_getTopActivityInfo" msgid="2512448855496067131">"Lehetővé teszi, hogy a felhasználó privát adatokat kérjen le az aktuális alkalmazásról a képernyő előterében."</string>
     <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"alkalmazásindítások nyomon követése és vezérlése"</string>
     <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"Lehetővé teszi az alkalmazás számára, hogy figyelje és vezérelje, hogy a rendszer hogyan indít el tevékenységeket. A rosszindulatú alkalmazások teljesen tönkretehetik a rendszert. Ez az engedély csak fejlesztéshez szükséges, normál használathoz sosem."</string>
     <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"eltávolított csomagú üzenetek küldése"</string>
@@ -346,6 +348,14 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Lehetővé teszi, hogy a tulajdonos kötelezővé tegye egy beviteli mód legfelső szintű felületét. A normál alkalmazásoknak erre soha nincs szüksége."</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"csatlakozás egy kisegítő szolgáltatáshoz"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Lehetővé teszi a használó számára, hogy csatlakozzon egy kisegítő szolgáltatás legfelső szintű kezelőfelületéhez. A normál alkalmazásoknak erre soha nincs szükségük."</string>
+    <!-- no translation found for permlab_canRequestTouchExplorationMode (6094034289937541846) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestTouchExplorationMode (940314268922270663) -->
+    <skip />
+    <!-- no translation found for permlab_canRequestEnahncedWebAccessibility (1905232971331801453) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestEnahncedWebAccessibility (4500520989321729676) -->
+    <skip />
     <string name="permlab_bindTextService" msgid="7358378401915287938">"csatlakozás szövegszolgáltatáshoz"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"Lehetővé teszi, hogy a tulajdonos egy szöveges szolgáltatás felső szintjéhez kapcsolódjon (pl. SpellCheckerService). A normál alkalmazásoknak erre soha nincs szüksége."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"csatlakozás egy VPN-szolgáltatáshoz"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 8d3c139..e9a4226 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -225,6 +225,10 @@
     <string name="permgrouplab_storage" msgid="1971118770546336966">"Penyimpanan"</string>
     <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"Akses penyimpanan USB."</string>
     <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"Akses kartu SD."</string>
+    <!-- no translation found for permgrouplab_accessibilityFeatures (7919025602283593907) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_accessibilityFeatures (4205196881678144335) -->
+    <skip />
     <string name="permlab_statusBar" msgid="7417192629601890791">"nonaktifkan atau ubah bilah status"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Mengizinkan apl menonaktifkan bilah status atau menambah dan menghapus ikon sistem."</string>
     <string name="permlab_statusBarService" msgid="7247281911387931485">"bilah status"</string>
@@ -299,10 +303,8 @@
     <string name="permdesc_shutdown" msgid="7046500838746291775">"Letakkan pengelola aktivitas dalam kondisi mati. Tidak melakukan penonaktifan penuh."</string>
     <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"cegah pergantian aplikasi"</string>
     <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"Mencegah pengguna beralih ke apl lain."</string>
-    <!-- no translation found for permlab_getTopActivityInfo (2537922311411546016) -->
-    <skip />
-    <!-- no translation found for permdesc_getTopActivityInfo (2512448855496067131) -->
-    <skip />
+    <string name="permlab_getTopActivityInfo" msgid="2537922311411546016">"dapatkan info tentang aplikasi yang aktif"</string>
+    <string name="permdesc_getTopActivityInfo" msgid="2512448855496067131">"Memungkinkan pemegang mengambil informasi pribadi tentang aplikasi yang aktif di latar depan layar."</string>
     <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"memantau dan mengontrol semua peluncuran apl"</string>
     <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"Mengizinkan apl memantau dan mengontrol cara sistem meluncurkan kegiatan. Apl berbahaya dapat meretas sistem sepenuhnya. Izin ini hanya diperlukan untuk pengembangan, tidak pernah diperlukan untuk penggunaan normal."</string>
     <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"kirim siaran paket dihapus"</string>
@@ -346,6 +348,14 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Mengizinkan pemegang mengikat antarmuka tingkat tinggi dari suatu metode masukan. Tidak pernah diperlukan oleh apl normal."</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"mengikat ke layanan aksesibilitas"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Mengizinkan pemegang untuk mengikat antarmuka tingkat tinggi dari suatu layanan. Tidak pernah diperlukan oleh aplikasi normal."</string>
+    <!-- no translation found for permlab_canRequestTouchExplorationMode (6094034289937541846) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestTouchExplorationMode (940314268922270663) -->
+    <skip />
+    <!-- no translation found for permlab_canRequestEnahncedWebAccessibility (1905232971331801453) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestEnahncedWebAccessibility (4500520989321729676) -->
+    <skip />
     <string name="permlab_bindTextService" msgid="7358378401915287938">"mengikat ke layanan SMS"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"Mengizinkan pemegang mengikat antarmuka tingkat tinggi dari suatu layanan teks (mis. SpellCheckerService). Tidak pernah diperlukan oleh apl normal."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"mengikat ke layanan VPN"</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 7fc8b73..b1c9625 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -225,6 +225,10 @@
     <string name="permgrouplab_storage" msgid="1971118770546336966">"Archiviazione"</string>
     <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"Accesso all\'archivio USB."</string>
     <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"Accesso alla scheda SD."</string>
+    <!-- no translation found for permgrouplab_accessibilityFeatures (7919025602283593907) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_accessibilityFeatures (4205196881678144335) -->
+    <skip />
     <string name="permlab_statusBar" msgid="7417192629601890791">"disattivare o modificare la barra di stato"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Consente all\'applicazione di disattivare la barra di stato o di aggiungere e rimuovere icone di sistema."</string>
     <string name="permlab_statusBarService" msgid="7247281911387931485">"barra di stato"</string>
@@ -299,10 +303,8 @@
     <string name="permdesc_shutdown" msgid="7046500838746291775">"Mette il gestore delle attività in uno stato di chiusura. Non esegue una chiusura completa."</string>
     <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"impedire commutazione applicazione"</string>
     <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"Impedisce all\'utente di passare a un\'altra applicazione."</string>
-    <!-- no translation found for permlab_getTopActivityInfo (2537922311411546016) -->
-    <skip />
-    <!-- no translation found for permdesc_getTopActivityInfo (2512448855496067131) -->
-    <skip />
+    <string name="permlab_getTopActivityInfo" msgid="2537922311411546016">"recupero di informazioni sull\'app corrente"</string>
+    <string name="permdesc_getTopActivityInfo" msgid="2512448855496067131">"Consente al titolare di recuperare le informazioni private sull\'app correntemente in primo piano sullo schermo."</string>
     <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"monitoraggio e controllo avvio di tutte le applicazioni"</string>
     <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"Consente all\'applicazione di monitorare e controllare l\'avvio delle attività da parte del sistema. Le applicazioni dannose potrebbero compromettere completamente il sistema. Questa autorizzazione è necessaria solo per lo sviluppo, mai per l\'utilizzo normale."</string>
     <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"invio broadcast rimossi dal pacchetto"</string>
@@ -346,6 +348,14 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Consente l\'associazione di un metodo di inserimento all\'interfaccia principale. Non dovrebbe mai essere necessaria per le normali applicazioni."</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"collegamento a un servizio di accessibilità"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Consente al titolare di collegarsi all\'interfaccia di primo livello di un servizio di accessibilità. Non dovrebbe essere mai necessaria per le normali applicazioni."</string>
+    <!-- no translation found for permlab_canRequestTouchExplorationMode (6094034289937541846) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestTouchExplorationMode (940314268922270663) -->
+    <skip />
+    <!-- no translation found for permlab_canRequestEnahncedWebAccessibility (1905232971331801453) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestEnahncedWebAccessibility (4500520989321729676) -->
+    <skip />
     <string name="permlab_bindTextService" msgid="7358378401915287938">"associazione a un servizio di testo"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"Consente al titolare di collegarsi all\'interfaccia di primo livello di un servizio di testo (ad esempio SpellCheckerService). Non dovrebbe essere mai necessaria per le normali applicazioni."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"associazione a un servizio VPN"</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index fff9c52..c7140c6 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -225,6 +225,10 @@
     <string name="permgrouplab_storage" msgid="1971118770546336966">"אחסון"</string>
     <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"גישה לאמצעי אחסון מסוג USB."</string>
     <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"גש לכרטיס SD."</string>
+    <!-- no translation found for permgrouplab_accessibilityFeatures (7919025602283593907) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_accessibilityFeatures (4205196881678144335) -->
+    <skip />
     <string name="permlab_statusBar" msgid="7417192629601890791">"השבת או שנה את שורת המצב"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"מאפשר ליישום להשבית את שורת המצב או להוסיף ולהסיר סמלי מערכת."</string>
     <string name="permlab_statusBarService" msgid="7247281911387931485">"שורת מצב"</string>
@@ -344,6 +348,14 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"מאפשר למשתמש לבצע איגוד לממשק ברמה עליונה של שיטת קלט. הרשאה זו לעולם אינה נחוצה ליישומים רגילים."</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"הכפפה לשירות נגישות"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"מתיר לבעלים להכפיף לממשק ברמה העליונה של שירות זמינות. הרשאה זו אף פעם אינה אמורה להיות נחוצה ליישומים רגילים."</string>
+    <!-- no translation found for permlab_canRequestTouchExplorationMode (6094034289937541846) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestTouchExplorationMode (940314268922270663) -->
+    <skip />
+    <!-- no translation found for permlab_canRequestEnahncedWebAccessibility (1905232971331801453) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestEnahncedWebAccessibility (4500520989321729676) -->
+    <skip />
     <string name="permlab_bindTextService" msgid="7358378401915287938">"הכפפה לשירות טקסט"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"מאפשר למשתמש ליצור איגוד לממשק הרמה העליונה של שירות טקסט (למשל, SpellCheckerService). הרשאה זו לעולם אינה נחוצה ליישומים רגילים."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"אגד לשירות VPN"</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 0afcbf7..9695e36 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -225,6 +225,10 @@
     <string name="permgrouplab_storage" msgid="1971118770546336966">"ストレージ"</string>
     <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"USBストレージへのアクセス"</string>
     <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"SDカードにアクセスします。"</string>
+    <!-- no translation found for permgrouplab_accessibilityFeatures (7919025602283593907) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_accessibilityFeatures (4205196881678144335) -->
+    <skip />
     <string name="permlab_statusBar" msgid="7417192629601890791">"ステータスバーの無効化や変更"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"ステータスバーの無効化、システムアイコンの追加や削除をアプリに許可します。"</string>
     <string name="permlab_statusBarService" msgid="7247281911387931485">"ステータスバーへの表示"</string>
@@ -299,10 +303,8 @@
     <string name="permdesc_shutdown" msgid="7046500838746291775">"アクティビティマネージャをシャットダウン状態にします。完全なシャットダウンは実行しません。"</string>
     <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"アプリケーションの切り替えを禁止する"</string>
     <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"ユーザーが別のアプリに切り替えられないようにします。"</string>
-    <!-- no translation found for permlab_getTopActivityInfo (2537922311411546016) -->
-    <skip />
-    <!-- no translation found for permdesc_getTopActivityInfo (2512448855496067131) -->
-    <skip />
+    <string name="permlab_getTopActivityInfo" msgid="2537922311411546016">"現在のアプリ情報の取得"</string>
+    <string name="permdesc_getTopActivityInfo" msgid="2512448855496067131">"画面のフォアグラウンドで現在のアプリに関する非公開情報を取得することを所有者に許可します。"</string>
     <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"すべてのアプリ起動の監視と制御"</string>
     <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"システムによるアクティビティ起動方法を監視し制御することをアプリに許可します。この許可を悪意のあるアプリに利用されると、システム全体のセキュリティが侵害される恐れがあります。この許可は開発時にのみ必要で、通常の使用では不要です。"</string>
     <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"パッケージ削除ブロードキャストの送信"</string>
@@ -346,6 +348,14 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"入力方法のトップレベルインターフェースにバインドすることを所有者に許可します。通常のアプリでは不要です。"</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"ユーザー補助サービスにバインド"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"ユーザー補助サービスのトップレベルインターフェースにバインドすることを所有者に許可します。通常のアプリでは不要です。"</string>
+    <!-- no translation found for permlab_canRequestTouchExplorationMode (6094034289937541846) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestTouchExplorationMode (940314268922270663) -->
+    <skip />
+    <!-- no translation found for permlab_canRequestEnahncedWebAccessibility (1905232971331801453) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestEnahncedWebAccessibility (4500520989321729676) -->
+    <skip />
     <string name="permlab_bindTextService" msgid="7358378401915287938">"テキストサービスにバインド"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"テキストサービス(SpellCheckerServiceなど)のトップレベルインターフェースにバインドすることを所有者に許可します。通常のアプリでは不要です。"</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"VPNサービスにバインド"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 85b35a7..9ee6559 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -225,6 +225,10 @@
     <string name="permgrouplab_storage" msgid="1971118770546336966">"저장"</string>
     <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"USB 저장소에 액세스합니다."</string>
     <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"SD 카드에 액세스합니다."</string>
+    <!-- no translation found for permgrouplab_accessibilityFeatures (7919025602283593907) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_accessibilityFeatures (4205196881678144335) -->
+    <skip />
     <string name="permlab_statusBar" msgid="7417192629601890791">"상태 표시줄 사용 중지 또는 수정"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"앱이 상태 표시줄을 사용중지하거나 시스템 아이콘을 추가 및 제거할 수 있도록 허용합니다."</string>
     <string name="permlab_statusBarService" msgid="7247281911387931485">"상태 표시줄"</string>
@@ -299,10 +303,8 @@
     <string name="permdesc_shutdown" msgid="7046500838746291775">"작업 관리자를 종료 상태로 설정합니다. 전체 종료를 수행하지는 않습니다."</string>
     <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"애플리케이션 전환 방지"</string>
     <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"사용자가 다른 앱으로 전환하지 못하게 합니다."</string>
-    <!-- no translation found for permlab_getTopActivityInfo (2537922311411546016) -->
-    <skip />
-    <!-- no translation found for permdesc_getTopActivityInfo (2512448855496067131) -->
-    <skip />
+    <string name="permlab_getTopActivityInfo" msgid="2537922311411546016">"현재 앱 정보 얻기"</string>
+    <string name="permdesc_getTopActivityInfo" msgid="2512448855496067131">"권한을 가진 프로그램이 화면의 포그라운드에서 현재 애플리케이션에 대한 비공개 정보를 검색하도록 허용합니다."</string>
     <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"실행 중인 모든 앱 모니터링 및 제어"</string>
     <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"앱이 시스템에서 활동이 시작되는 방식을 모니터링하고 관리할 수 있도록 허용합니다. 이 경우 악성 앱이 이 기능을 이용하여 시스템을 완전히 손상시킬 수 있습니다. 이 권한은 개발 과정에만 필요하며 일반 사용 시에는 필요하지 않습니다."</string>
     <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"패키지 제거 브로드캐스트 보내기"</string>
@@ -346,6 +348,14 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"권한을 가진 프로그램이 입력 방법에 대한 최상위 인터페이스를 사용하도록 허용합니다. 일반 앱에는 필요하지 않습니다."</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"접근성 서비스와 연결"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"권한을 가진 프로그램이 접근성 서비스에 대한 최상위 인터페이스를 사용하도록 허용합니다. 일반 앱에는 필요하지 않습니다."</string>
+    <!-- no translation found for permlab_canRequestTouchExplorationMode (6094034289937541846) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestTouchExplorationMode (940314268922270663) -->
+    <skip />
+    <!-- no translation found for permlab_canRequestEnahncedWebAccessibility (1905232971331801453) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestEnahncedWebAccessibility (4500520989321729676) -->
+    <skip />
     <string name="permlab_bindTextService" msgid="7358378401915287938">"텍스트 서비스 연결"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"권한을 가진 프로그램이 텍스트 서비스(예: SpellCheckerService)에 대한 최상위 인터페이스를 사용하도록 허용합니다. 일반 앱에는 필요하지 않습니다."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"VPN 서비스와 연결"</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 86262e9..de79c33 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -225,6 +225,10 @@
     <string name="permgrouplab_storage" msgid="1971118770546336966">"Saugykla"</string>
     <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"Pasiekti USB atmintinę."</string>
     <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"Pasiekite SD kortelę."</string>
+    <!-- no translation found for permgrouplab_accessibilityFeatures (7919025602283593907) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_accessibilityFeatures (4205196881678144335) -->
+    <skip />
     <string name="permlab_statusBar" msgid="7417192629601890791">"išjungti ar keisti būsenos juostą"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Leidžiama programai neleisti būsenos juostos arba pridėti ir pašalinti sistemos piktogramas."</string>
     <string name="permlab_statusBarService" msgid="7247281911387931485">"būsenos juosta"</string>
@@ -299,10 +303,8 @@
     <string name="permdesc_shutdown" msgid="7046500838746291775">"Veiklos tvarkyklę perjungia į išsijungimo būseną. Neišjungia visiškai."</string>
     <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"neleisti perjungti programų"</string>
     <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"Neleidžiama naudotojui perjungti į kitą programą."</string>
-    <!-- no translation found for permlab_getTopActivityInfo (2537922311411546016) -->
-    <skip />
-    <!-- no translation found for permdesc_getTopActivityInfo (2512448855496067131) -->
-    <skip />
+    <string name="permlab_getTopActivityInfo" msgid="2537922311411546016">"gauti esamos programos informaciją"</string>
+    <string name="permdesc_getTopActivityInfo" msgid="2512448855496067131">"Savininkui leidžiama gauti privačią esamos pirmaeilės ekrano programos informaciją."</string>
     <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"stebėti ir valdyti visų programų paleidimą"</string>
     <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"Leidžiama programai stebėti ir valdyti, kaip sistema paleidžia veiklą. Kenkėjiškos programos gali visiškai pažeisti sistemą. Šis leidimas reikalingas tik kuriant ir jo niekada nereikia naudojant įprastai."</string>
     <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"siųsti pašalinto paketo perdavimą"</string>
@@ -346,6 +348,14 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Leidžiama savininką susaistyti su įvesties metodo aukščiausio lygio sąsaja. Įprastoms programoms to neturėtų prireikti."</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"susisaistyti su pasiekiamumo paslauga"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Savininkui leidžiama susisaistyti su aukščiausio lygio pasiekiamumo paslaugos sąsaja. Įprastoms programoms to neturėtų prireikti."</string>
+    <!-- no translation found for permlab_canRequestTouchExplorationMode (6094034289937541846) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestTouchExplorationMode (940314268922270663) -->
+    <skip />
+    <!-- no translation found for permlab_canRequestEnahncedWebAccessibility (1905232971331801453) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestEnahncedWebAccessibility (4500520989321729676) -->
+    <skip />
     <string name="permlab_bindTextService" msgid="7358378401915287938">"priskirti teksto paslaugą"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"Leidžiama savininkui priskirti aukščiausio lygio teksto paslaugos (pvz., „SpellCheckerService“) sąsają. Įprastoms programoms to neturėtų prireikti."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"susaistyti su VPN paslauga"</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index cd28e58..1e3722b 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -225,6 +225,10 @@
     <string name="permgrouplab_storage" msgid="1971118770546336966">"Krātuve"</string>
     <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"Piekļūst USB krātuvei."</string>
     <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"Piekļūstiet SD kartei."</string>
+    <!-- no translation found for permgrouplab_accessibilityFeatures (7919025602283593907) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_accessibilityFeatures (4205196881678144335) -->
+    <skip />
     <string name="permlab_statusBar" msgid="7417192629601890791">"atspējot vai pārveidot statusa joslu"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Ļauj lietotnei atspējot statusa joslu vai pievienot un noņemt sistēmas ikonas."</string>
     <string name="permlab_statusBarService" msgid="7247281911387931485">"statusa josla"</string>
@@ -299,10 +303,8 @@
     <string name="permdesc_shutdown" msgid="7046500838746291775">"Liek darbību pārvaldniekam pāriet izslēgšanas stāvoklī. Neveic pilnīgu izslēgšanu."</string>
     <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"novērst lietojumprogrammu pārslēgšanu"</string>
     <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"Novērš lietotāja pārslēgšanos uz citu lietotni."</string>
-    <!-- no translation found for permlab_getTopActivityInfo (2537922311411546016) -->
-    <skip />
-    <!-- no translation found for permdesc_getTopActivityInfo (2512448855496067131) -->
-    <skip />
+    <string name="permlab_getTopActivityInfo" msgid="2537922311411546016">"pašreizējās lietotnes informācijas iegūšana"</string>
+    <string name="permdesc_getTopActivityInfo" msgid="2512448855496067131">"Ļauj īpašniekam izgūt privātu informāciju par pašreizējo lietojumprogrammu ekrāna priekšplānā."</string>
     <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"pārraudzīt un kontrolēt visu lietotņu atvēršanu"</string>
     <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"Ļauj lietotnei pārraudzīt un kontrolēt, kā sistēmā tiek palaistas darbības. Ļaunprātīgas lietotnes var pilnībā uzlauzt sistēmu. Šī atļauja ir nepieciešama tikai izstrādei, taču ne parastai lietošanai."</string>
     <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"sūtīt apraidi par pakotnes noņemšanu"</string>
@@ -346,6 +348,14 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Ļauj īpašniekam izveidot saiti ar ievades metodes augstākā līmeņa saskarni. Parastajām lietotnēm tas nekad nav nepieciešams."</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"saistīt ar pieejamības pakalpojumu"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Ļauj īpašniekam izveidot saiti ar pieejamības pakalpojuma augšējā līmeņa saskarni. Parastajām lietotnēm šī atļauja nav nepieciešama."</string>
+    <!-- no translation found for permlab_canRequestTouchExplorationMode (6094034289937541846) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestTouchExplorationMode (940314268922270663) -->
+    <skip />
+    <!-- no translation found for permlab_canRequestEnahncedWebAccessibility (1905232971331801453) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestEnahncedWebAccessibility (4500520989321729676) -->
+    <skip />
     <string name="permlab_bindTextService" msgid="7358378401915287938">"saistīt ar īsziņu pakalpojumu"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"Ļauj īpašniekam veikt saistīšanu ar īsziņu pakalpojuma augstākā līmeņa saskarni (piem., SpellCheckerService). Parastajām lietotnēm tas nekad nav nepieciešams."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"saistīt ar VPN pakalpojumu"</string>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index 0ab4384..049aa9b 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -225,6 +225,10 @@
     <string name="permgrouplab_storage" msgid="1971118770546336966">"Storan"</string>
     <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"Akses storan USB."</string>
     <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"Akses kad SD."</string>
+    <!-- no translation found for permgrouplab_accessibilityFeatures (7919025602283593907) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_accessibilityFeatures (4205196881678144335) -->
+    <skip />
     <string name="permlab_statusBar" msgid="7417192629601890791">"lumpuhkan atau ubah suai bar status"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Membenarkan apl melumpuhkan bar status atau menambah dan mengalih keluar ikon sistem."</string>
     <string name="permlab_statusBarService" msgid="7247281911387931485">"bar status"</string>
@@ -299,7 +303,7 @@
     <string name="permdesc_shutdown" msgid="7046500838746291775">"Meletakkan pengurus aktiviti dalam keadaan tutup. Tidak melaksanakan penutupan lengkap."</string>
     <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"halang pertukaran apl"</string>
     <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"Menghalang pengguna daripada bertukar kepada apl lain."</string>
-    <string name="permlab_getTopActivityInfo" msgid="2537922311411546016">"dapatkan maklumat apl. semasa"</string>
+    <string name="permlab_getTopActivityInfo" msgid="2537922311411546016">"dapatkan maklumat apl semasa"</string>
     <string name="permdesc_getTopActivityInfo" msgid="2512448855496067131">"Membenarkan pemegang mendapatkan maklumat peribadi tentang permohonan semasa di latar hadapan skrin"</string>
     <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"pantau dan kawal semua pelancaran apl"</string>
     <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"Membenarkan apl untuk memantau dan mengawal cara sistem melancarkan aktiviti. Apl hasad boleh menjejaskan sistem sepenuhnya. Kebenaran ini hanya diperlukan untuk pembangunan, tidak sekali-kali untuk penggunaan biasa."</string>
@@ -344,6 +348,14 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Membenarkan pemegang terikat dengan antara muka peringkat tertinggi bagi kaedah input itu. Tidak sekali-kali diperlukan untuk apl biasa."</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"terikat kepada perkhidmatan yang boleh diakses"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Membenarkan pemegang terikat dengan antara muka peringkat tertinggi bagi perkhidmatan yang boleh diakses. Tidak sekali-kali diperlukan untuk apl biasa."</string>
+    <!-- no translation found for permlab_canRequestTouchExplorationMode (6094034289937541846) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestTouchExplorationMode (940314268922270663) -->
+    <skip />
+    <!-- no translation found for permlab_canRequestEnahncedWebAccessibility (1905232971331801453) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestEnahncedWebAccessibility (4500520989321729676) -->
+    <skip />
     <string name="permlab_bindTextService" msgid="7358378401915287938">"terikat kepada perkhidmatan teks"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"Membenarkan pemegang mengikat kepada antara muka peringkat atasan perkhidmatan teks(mis. PerkhidmatanPenyemakEjaan). Tidak seharusnya diperlukan untuk apl biasa."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"terikat kepada perkhidmatan VPN"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 0969c34..d568069 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -225,6 +225,10 @@
     <string name="permgrouplab_storage" msgid="1971118770546336966">"Lagring"</string>
     <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"Tilgang til USB-lagring."</string>
     <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"Tilgang til minnekortet."</string>
+    <!-- no translation found for permgrouplab_accessibilityFeatures (7919025602283593907) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_accessibilityFeatures (4205196881678144335) -->
+    <skip />
     <string name="permlab_statusBar" msgid="7417192629601890791">"deaktivere eller endre statusfeltet"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Lar appen deaktivere statusfeltet eller legge til og fjerne systemikoner."</string>
     <string name="permlab_statusBarService" msgid="7247281911387931485">"statusrad"</string>
@@ -299,10 +303,8 @@
     <string name="permdesc_shutdown" msgid="7046500838746291775">"Lar applikasjonen sette aktivitetshåndtereren i avslutningstilstand. Slår ikke systemet helt av."</string>
     <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"forhindre applikasjonsbytte"</string>
     <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"Hindrer brukeren i å bytte til en annen app."</string>
-    <!-- no translation found for permlab_getTopActivityInfo (2537922311411546016) -->
-    <skip />
-    <!-- no translation found for permdesc_getTopActivityInfo (2512448855496067131) -->
-    <skip />
+    <string name="permlab_getTopActivityInfo" msgid="2537922311411546016">"få informasjon om appen"</string>
+    <string name="permdesc_getTopActivityInfo" msgid="2512448855496067131">"Tillater brukeren å få tilgang til privat informasjon om den aktuelle appen i forgrunnen på skjermen."</string>
     <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"avervåke og kontrollere all oppstart av apper"</string>
     <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"Lar appen overvåke og kontrollere hvordan systemet starter opp aktiviteter. Ondsinnede apper kan utsette hele systemet for sikkerhetsbrudd. Denne tillatelsen er bare nødvendig for utviklere, aldri for vanlig bruk."</string>
     <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"kringkaste melding om fjernet pakke"</string>
@@ -346,6 +348,14 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Lar innehaveren binde det øverste nivået av grensesnittet til en inndatametode. Skal aldri være nødvendig for normale apper."</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"binde seg til en tilgjengelighetstjeneste"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Gir innehaveren tillatelse til å bindes til det øverste nivået av grensesnittet for en tilgjengelighetstjeneste. Skal aldri være nødvendig for vanlige apper."</string>
+    <!-- no translation found for permlab_canRequestTouchExplorationMode (6094034289937541846) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestTouchExplorationMode (940314268922270663) -->
+    <skip />
+    <!-- no translation found for permlab_canRequestEnahncedWebAccessibility (1905232971331801453) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestEnahncedWebAccessibility (4500520989321729676) -->
+    <skip />
     <string name="permlab_bindTextService" msgid="7358378401915287938">"binde til en teksttjeneste"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"Lar innehaveren binde seg til øverste grensesnittnivå for en teksttjeneste (f.eks. SpellCheckerService). Skal aldri være nødvendig for vanlige apper."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"binde deg til en VPN-tjeneste"</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index f82e5dc..a914e21 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -225,6 +225,10 @@
     <string name="permgrouplab_storage" msgid="1971118770546336966">"Opslagruimte"</string>
     <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"Toegang krijgen tot USB-opslag."</string>
     <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"Toegang tot de SD-kaart."</string>
+    <!-- no translation found for permgrouplab_accessibilityFeatures (7919025602283593907) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_accessibilityFeatures (4205196881678144335) -->
+    <skip />
     <string name="permlab_statusBar" msgid="7417192629601890791">"statusbalk uitschakelen of wijzigen"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Hiermee kan de app de statusbalk uitschakelen of systeempictogrammen toevoegen en verwijderen."</string>
     <string name="permlab_statusBarService" msgid="7247281911387931485">"statusbalk"</string>
@@ -299,10 +303,8 @@
     <string name="permdesc_shutdown" msgid="7046500838746291775">"Hiermee wordt activiteitenbeheer uitgeschakeld. Er wordt geen volledige uitschakeling uitgevoerd."</string>
     <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"schakelen tussen apps voorkomen"</string>
     <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"Hiermee wordt voorkomen dat de gebruiker overschakelt naar een andere app."</string>
-    <!-- no translation found for permlab_getTopActivityInfo (2537922311411546016) -->
-    <skip />
-    <!-- no translation found for permdesc_getTopActivityInfo (2512448855496067131) -->
-    <skip />
+    <string name="permlab_getTopActivityInfo" msgid="2537922311411546016">"huidige appgegevens ophalen"</string>
+    <string name="permdesc_getTopActivityInfo" msgid="2512448855496067131">"De houder kan hiermee persoonlijke gegevens ophalen over de applicatie die momenteel op de voorgrond wordt weergegeven."</string>
     <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"alle startende apps bijhouden en beheren"</string>
     <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"Hiermee kan de app de manier bijhouden en beheren waarop het systeem activiteiten start. Schadelijke apps kunnen het systeem volledig in gevaar brengen. Deze machtiging is alleen voor ontwikkeling vereist, nooit voor normaal gebruik."</string>
     <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"melding verzenden dat pakket is verwijderd"</string>
@@ -346,6 +348,14 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Hiermee kan de houder zich verbinden met de hoofdinterface van een invoermethode. Nooit vereist voor normale apps."</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"koppelen aan een toegankelijkheidsservice"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Hiermee wordt de houder toegestaan verbinding te maken met de hoofdinterface van een toegankelijkheidsservice. Nooit vereist voor normale apps."</string>
+    <!-- no translation found for permlab_canRequestTouchExplorationMode (6094034289937541846) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestTouchExplorationMode (940314268922270663) -->
+    <skip />
+    <!-- no translation found for permlab_canRequestEnahncedWebAccessibility (1905232971331801453) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestEnahncedWebAccessibility (4500520989321729676) -->
+    <skip />
     <string name="permlab_bindTextService" msgid="7358378401915287938">"koppelen aan een sms-service"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"Hiermee kan de gebruiker koppelen met de hoofdinterface van een tekstservice (zoals SpellCheckerService). Dit is niet nodig voor normale apps."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"koppelen aan een VPN-service"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 749a73e..81caee1 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -225,6 +225,10 @@
     <string name="permgrouplab_storage" msgid="1971118770546336966">"Pamięć"</string>
     <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"Dostęp do nośnika USB."</string>
     <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"Dostęp do karty SD."</string>
+    <!-- no translation found for permgrouplab_accessibilityFeatures (7919025602283593907) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_accessibilityFeatures (4205196881678144335) -->
+    <skip />
     <string name="permlab_statusBar" msgid="7417192629601890791">"wyłączanie lub zmienianie paska stanu"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Pozwala aplikacji na wyłączanie paska stanu oraz dodawanie i usuwanie ikon systemowych."</string>
     <string name="permlab_statusBarService" msgid="7247281911387931485">"pasek stanu"</string>
@@ -299,10 +303,8 @@
     <string name="permdesc_shutdown" msgid="7046500838746291775">"Przełącza menedżera aktywności w stan wyłączenia. Nie wykonuje pełnego wyłączenia."</string>
     <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"zapobieganie przełączaniu aplikacji"</string>
     <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"Uniemożliwia użytkownikowi przełączenie na inną aplikację."</string>
-    <!-- no translation found for permlab_getTopActivityInfo (2537922311411546016) -->
-    <skip />
-    <!-- no translation found for permdesc_getTopActivityInfo (2512448855496067131) -->
-    <skip />
+    <string name="permlab_getTopActivityInfo" msgid="2537922311411546016">"pobierz informacje o bieżącej aplikacji"</string>
+    <string name="permdesc_getTopActivityInfo" msgid="2512448855496067131">"Zezwala posiadaczowi na pobieranie prywatnych informacji o bieżącej aplikacji i wyświetlanie ich na pierwszym planie ekranu."</string>
     <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"monitorowanie i kontrolowanie wszystkich uruchamianych aplikacji"</string>
     <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"Pozwala aplikacji na monitorowanie i kontrolowanie sposobu uruchamiania działań przez system. Złośliwe aplikacje mogą całkowicie naruszyć zabezpieczenia systemu. To uprawnienie nigdy nie jest potrzebne podczas normalnego użytkowania, a jedynie podczas programowania."</string>
     <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"wysyłanie transmisji informującej o usuniętym pakiecie"</string>
@@ -346,6 +348,14 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Pozwala na powiązanie wybranego sposobu wprowadzania tekstu z interfejsem najwyższego poziomu. To uprawnienie nie powinno być nigdy wymagane przez zwykłe aplikacje."</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"tworzenie powiązania z usługą ułatwień dostępu"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Zezwala na tworzenie powiązania z interfejsem najwyższego poziomu usługi ułatwień dostępu. Nieprzeznaczone dla zwykłych aplikacji."</string>
+    <!-- no translation found for permlab_canRequestTouchExplorationMode (6094034289937541846) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestTouchExplorationMode (940314268922270663) -->
+    <skip />
+    <!-- no translation found for permlab_canRequestEnahncedWebAccessibility (1905232971331801453) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestEnahncedWebAccessibility (4500520989321729676) -->
+    <skip />
     <string name="permlab_bindTextService" msgid="7358378401915287938">"tworzenie powiązania z usługą tekstową"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"Pozwala na tworzenie powiązania z interfejsem najwyższego poziomu usługi tekstowej (np. SpellCheckerService). Nie powinno być nigdy potrzebne w przypadku zwykłych aplikacji."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"tworzenie powiązania z usługą VPN"</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 09a3d1f..6629fd1 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -225,6 +225,10 @@
     <string name="permgrouplab_storage" msgid="1971118770546336966">"Armazenamento"</string>
     <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"Aceder ao armazenamento USB."</string>
     <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"Aceder ao cartão SD."</string>
+    <!-- no translation found for permgrouplab_accessibilityFeatures (7919025602283593907) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_accessibilityFeatures (4205196881678144335) -->
+    <skip />
     <string name="permlab_statusBar" msgid="7417192629601890791">"desactivar ou modificar barra de estado"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Permite à aplicação desativar a barra de estado ou adicionar e remover ícones do sistema."</string>
     <string name="permlab_statusBarService" msgid="7247281911387931485">"barra de estado"</string>
@@ -299,10 +303,8 @@
     <string name="permdesc_shutdown" msgid="7046500838746291775">"Coloca o gestor de actividade num estado de encerramento. Não executa um encerramento completo."</string>
     <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"impedir trocas de aplicações"</string>
     <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"Impede que o utilizador mude para outra aplicação."</string>
-    <!-- no translation found for permlab_getTopActivityInfo (2537922311411546016) -->
-    <skip />
-    <!-- no translation found for permdesc_getTopActivityInfo (2512448855496067131) -->
-    <skip />
+    <string name="permlab_getTopActivityInfo" msgid="2537922311411546016">"obter informações da aplicação atual"</string>
+    <string name="permdesc_getTopActivityInfo" msgid="2512448855496067131">"Permite ao titular recuperar informações privadas acerca da aplicação atual no primeiro plano do ecrã."</string>
     <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"monitorizar e controlar a iniciação de todas as aplicações"</string>
     <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"Permite que uma aplicação monitorize e controle a forma como o sistema inicia atividades. As aplicações maliciosas podem comprometer totalmente o sistema. Esta autorização só é necessária para programação, nunca para utilização normal."</string>
     <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"enviar difusão de pacote removido"</string>
@@ -346,6 +348,14 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Permite ao titular vincular-se à interface de nível superior de um método de entrada. Nunca deve ser necessário para aplicações normais."</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"vincular a um serviço de acessibilidade"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Permite que o titular vincule a interface de nível superior de um serviço de acessibilidade. Nunca deverá ser necessário para aplicações normais."</string>
+    <!-- no translation found for permlab_canRequestTouchExplorationMode (6094034289937541846) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestTouchExplorationMode (940314268922270663) -->
+    <skip />
+    <!-- no translation found for permlab_canRequestEnahncedWebAccessibility (1905232971331801453) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestEnahncedWebAccessibility (4500520989321729676) -->
+    <skip />
     <string name="permlab_bindTextService" msgid="7358378401915287938">"vincular a um serviço de texto"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"Permite ao titular ligar-se à interface de nível superior de um serviço de texto (por exemplo SpellCheckerService). Nunca deverá ser necessário para aplicações normais."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"vincular a um serviço VPN"</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 3d5f68e..71ef30d 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -225,6 +225,10 @@
     <string name="permgrouplab_storage" msgid="1971118770546336966">"Armazenamento"</string>
     <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"Acessa o armazenamento USB."</string>
     <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"Acessar o cartão SD."</string>
+    <!-- no translation found for permgrouplab_accessibilityFeatures (7919025602283593907) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_accessibilityFeatures (4205196881678144335) -->
+    <skip />
     <string name="permlab_statusBar" msgid="7417192629601890791">"desativar ou modificar a barra de status"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Permite que o aplicativo desative a barra de status ou adicione e remova ícones do sistema."</string>
     <string name="permlab_statusBarService" msgid="7247281911387931485">"barra de status"</string>
@@ -299,10 +303,8 @@
     <string name="permdesc_shutdown" msgid="7046500838746291775">"Coloca o gerenciador de atividades em um estado de desligamento. Não executa o desligamento completo."</string>
     <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"evitar trocas de aplicativo"</string>
     <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"Impede que o usuário alterne para outro aplicativo."</string>
-    <!-- no translation found for permlab_getTopActivityInfo (2537922311411546016) -->
-    <skip />
-    <!-- no translation found for permdesc_getTopActivityInfo (2512448855496067131) -->
-    <skip />
+    <string name="permlab_getTopActivityInfo" msgid="2537922311411546016">"obter informações do aplicativo atual"</string>
+    <string name="permdesc_getTopActivityInfo" msgid="2512448855496067131">"Permite ao titular recuperar informações particulares sobre o aplicativo atual em primeiro plano na tela."</string>
     <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"monitorar e controlar todos os aplicativos que estão sendo iniciados"</string>
     <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"Permite que o aplicativo monitore e controle a forma como o sistema inicia atividades. Aplicativos maliciosos podem comprometer completamente o sistema. Esta permissão só é necessária para o desenvolvimento, nunca para o uso normal."</string>
     <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"enviar transmissão removida do pacote"</string>
@@ -346,6 +348,14 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Permite que o proprietário utilize a interface de nível superior de um método de entrada. Nunca deve ser necessário para aplicativos normais."</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"usar um serviço de acessibilidade"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Permite que o proprietário use a interface de nível superior de um serviço de acessibilidade. Nunca deve ser necessário para aplicativos comuns."</string>
+    <!-- no translation found for permlab_canRequestTouchExplorationMode (6094034289937541846) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestTouchExplorationMode (940314268922270663) -->
+    <skip />
+    <!-- no translation found for permlab_canRequestEnahncedWebAccessibility (1905232971331801453) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestEnahncedWebAccessibility (4500520989321729676) -->
+    <skip />
     <string name="permlab_bindTextService" msgid="7358378401915287938">"sujeitar-se a um serviço de texto"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"Permite que o proprietário utilize interface de nível superior de um serviço de texto (por exemplo, SpellCheckerService). Nunca deve ser necessário para aplicativos normais."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"se ligam a um serviço de VPN"</string>
diff --git a/core/res/res/values-rm/strings.xml b/core/res/res/values-rm/strings.xml
index 8ee8779..67e5576 100644
--- a/core/res/res/values-rm/strings.xml
+++ b/core/res/res/values-rm/strings.xml
@@ -310,6 +310,10 @@
     <!-- no translation found for permgroupdesc_storage (7442318502446874999) -->
     <skip />
     <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"Access a la carta SD."</string>
+    <!-- no translation found for permgrouplab_accessibilityFeatures (7919025602283593907) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_accessibilityFeatures (4205196881678144335) -->
+    <skip />
     <string name="permlab_statusBar" msgid="7417192629601890791">"deactivar u modifitgar la trav da status"</string>
     <!-- no translation found for permdesc_statusBar (8434669549504290975) -->
     <skip />
@@ -529,6 +533,14 @@
     <skip />
     <!-- no translation found for permdesc_bindAccessibilityService (7034615928609331368) -->
     <skip />
+    <!-- no translation found for permlab_canRequestTouchExplorationMode (6094034289937541846) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestTouchExplorationMode (940314268922270663) -->
+    <skip />
+    <!-- no translation found for permlab_canRequestEnahncedWebAccessibility (1905232971331801453) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestEnahncedWebAccessibility (4500520989321729676) -->
+    <skip />
     <!-- no translation found for permlab_bindTextService (7358378401915287938) -->
     <skip />
     <!-- no translation found for permdesc_bindTextService (8151968910973998670) -->
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index ecfef60..a2366d3 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -225,6 +225,10 @@
     <string name="permgrouplab_storage" msgid="1971118770546336966">"Stocare"</string>
     <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"Accesează stocarea USB."</string>
     <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"Accesează cardul SD."</string>
+    <!-- no translation found for permgrouplab_accessibilityFeatures (7919025602283593907) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_accessibilityFeatures (4205196881678144335) -->
+    <skip />
     <string name="permlab_statusBar" msgid="7417192629601890791">"dezactivare sau modificare bare de stare"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Permite aplicaţiei să dezactiveze bara de stare sau să adauge şi să elimine pictograme de sistem."</string>
     <string name="permlab_statusBarService" msgid="7247281911387931485">"bară de stare"</string>
@@ -299,10 +303,8 @@
     <string name="permdesc_shutdown" msgid="7046500838746291775">"Plasează Managerul de activităţi într-o stare de închidere. Nu efectuează o închidere completă."</string>
     <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"împiedicare comutare între aplicaţii"</string>
     <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"Împiedică trecerea utilizatorului la o altă aplicaţie."</string>
-    <!-- no translation found for permlab_getTopActivityInfo (2537922311411546016) -->
-    <skip />
-    <!-- no translation found for permdesc_getTopActivityInfo (2512448855496067131) -->
-    <skip />
+    <string name="permlab_getTopActivityInfo" msgid="2537922311411546016">"obținere informații despre aplicația curentă"</string>
+    <string name="permdesc_getTopActivityInfo" msgid="2512448855496067131">"Permite proprietarului să preia informațiile private despre aplicația curentă în prim-planul ecranului."</string>
     <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"monitorizare şi control asupra lansării tuturor aplicaţiilor"</string>
     <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"Permite aplicaţiei să monitorizeze şi să controleze modul în care sistemul lansează activităţi. Aplicaţiile rău intenţionate pot să compromită sistemul în întregime. Această permisiune este necesară doar pentru dezvoltare şi niciodată pentru utilizarea normală."</string>
     <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"trimitere mesaj difuzat privind extragerea din pachet"</string>
@@ -346,6 +348,14 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Permite proprietarului să se conecteze la interfaţa de nivel superior a unei metode de introducere. Nu ar trebui să fie niciodată necesară pentru aplicaţiile obişnuite."</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"conectare la un serviciu de accesibilitate"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Permite proprietarului să se conecteze la interfaţa de nivel superior a unui serviciu de accesibilitate. Nu ar trebui să fie niciodată necesară pentru aplicaţiile obişnuite."</string>
+    <!-- no translation found for permlab_canRequestTouchExplorationMode (6094034289937541846) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestTouchExplorationMode (940314268922270663) -->
+    <skip />
+    <!-- no translation found for permlab_canRequestEnahncedWebAccessibility (1905232971331801453) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestEnahncedWebAccessibility (4500520989321729676) -->
+    <skip />
     <string name="permlab_bindTextService" msgid="7358378401915287938">"conectare la un serviciu text"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"Permite proprietarului să se conecteze la o interfaţă de nivel superior a unui serviciu text (de ex., SpellCheckerService). Nu ar trebui să fie niciodată necesară pentru aplicaţiile obişnuite."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"conectare la un serviciu VPN"</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index f2908f4..692aa78 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -225,6 +225,10 @@
     <string name="permgrouplab_storage" msgid="1971118770546336966">"Память"</string>
     <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"Доступ к USB-накопителю."</string>
     <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"Доступ к SD-карте."</string>
+    <!-- no translation found for permgrouplab_accessibilityFeatures (7919025602283593907) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_accessibilityFeatures (4205196881678144335) -->
+    <skip />
     <string name="permlab_statusBar" msgid="7417192629601890791">"отключать или изменять строку состояния"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Приложение сможет отключать строку состояния, а также добавлять и удалять системные значки."</string>
     <string name="permlab_statusBarService" msgid="7247281911387931485">"строка состояния"</string>
@@ -299,10 +303,8 @@
     <string name="permdesc_shutdown" msgid="7046500838746291775">"Завершает работу диспетчера активности. Не выполняет полное завершение работы."</string>
     <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"запретить переключение приложений"</string>
     <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"Запрещает пользователям переключаться между приложениями."</string>
-    <!-- no translation found for permlab_getTopActivityInfo (2537922311411546016) -->
-    <skip />
-    <!-- no translation found for permdesc_getTopActivityInfo (2512448855496067131) -->
-    <skip />
+    <string name="permlab_getTopActivityInfo" msgid="2537922311411546016">"показывать информацию о текущем приложении"</string>
+    <string name="permdesc_getTopActivityInfo" msgid="2512448855496067131">"На экране будут отображаться сведения о текущем приложении."</string>
     <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"отслеживание и управление запуском всех приложений"</string>
     <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"Приложение сможет отслеживать запуск системных процессов и управлять им. Вредоносные программы смогут получить полный контроль над системой. Это разрешение необходимо только для разработки и не нужно в обычном режиме."</string>
     <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"отправлять рассылку об удалении пакета"</string>
@@ -346,6 +348,14 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Приложение сможет подключаться к базовому интерфейсу системы ввода. Это разрешение не используется обычными приложениями."</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"подключаться к службе спецвозможностей"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Приложение сможет подключаться к базовому интерфейсу службы специальных возможностей. Это разрешение не используется обычными приложениями."</string>
+    <!-- no translation found for permlab_canRequestTouchExplorationMode (6094034289937541846) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestTouchExplorationMode (940314268922270663) -->
+    <skip />
+    <!-- no translation found for permlab_canRequestEnahncedWebAccessibility (1905232971331801453) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestEnahncedWebAccessibility (4500520989321729676) -->
+    <skip />
     <string name="permlab_bindTextService" msgid="7358378401915287938">"привязка к службе текстовых сообщений"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"Позволяет подключаться к базовому интерфейсу службы текстовых сообщений (например, SpellCheckerService). Это разрешение не используется обычными приложениями."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"подключаться к VPN-службе"</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 9f6702b..355fe7f 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -225,6 +225,10 @@
     <string name="permgrouplab_storage" msgid="1971118770546336966">"Ukladací priestor"</string>
     <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"Prístup do ukl. priestoru USB."</string>
     <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"Prístup na kartu SD."</string>
+    <!-- no translation found for permgrouplab_accessibilityFeatures (7919025602283593907) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_accessibilityFeatures (4205196881678144335) -->
+    <skip />
     <string name="permlab_statusBar" msgid="7417192629601890791">"zakázanie alebo zmeny stavového riadka"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Umožňuje aplikácii vypnúť stavový riadok alebo pridať a odstrániť systémové ikony."</string>
     <string name="permlab_statusBarService" msgid="7247281911387931485">"stavový riadok"</string>
@@ -299,10 +303,8 @@
     <string name="permdesc_shutdown" msgid="7046500838746291775">"Uvedie správcu činností do vypnutého stavu. Úplné vypnutie však nenastane."</string>
     <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"zabrániť prepínaniu aplikácií"</string>
     <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"Zabráni používateľovi prepnúť na inú aplikáciu."</string>
-    <!-- no translation found for permlab_getTopActivityInfo (2537922311411546016) -->
-    <skip />
-    <!-- no translation found for permdesc_getTopActivityInfo (2512448855496067131) -->
-    <skip />
+    <string name="permlab_getTopActivityInfo" msgid="2537922311411546016">"získať informácie o aktuálnej aplikácii"</string>
+    <string name="permdesc_getTopActivityInfo" msgid="2512448855496067131">"Umožňuje držiteľovi povolenia načítať súkromné ​​informácie o aktuálnej aplikácii v popredí obrazovky."</string>
     <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"sledovať a ovládať všetky spustenia aplikácií"</string>
     <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"Umožňuje aplikácii sledovať a ovládať spúšťanie aktivít systémom. Škodlivé aplikácie môžu systém úplne ovládnuť. Toto povolenie je potrebné len na účely vývoja, nikdy nie na bežné používanie."</string>
     <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"odoslanie vysielania o odstránení balíčka"</string>
@@ -346,6 +348,14 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Umožňuje držiteľovi viazať sa na najvyššiu úroveň rozhrania metódy vstupu. Bežné aplikácie by toto nastavenie nemali nikdy potrebovať."</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"viazať na službu zjednodušeného ovládania"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Umožňuje držiteľovi viazať sa na najvyššiu úroveň rozhrania služby zjednodušeného ovládania. Bežné aplikácie by toto nastavenie nemali nikdy potrebovať."</string>
+    <!-- no translation found for permlab_canRequestTouchExplorationMode (6094034289937541846) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestTouchExplorationMode (940314268922270663) -->
+    <skip />
+    <!-- no translation found for permlab_canRequestEnahncedWebAccessibility (1905232971331801453) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestEnahncedWebAccessibility (4500520989321729676) -->
+    <skip />
     <string name="permlab_bindTextService" msgid="7358378401915287938">"väzba na textovú službu"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"Umožňuje držiteľovi viazať sa na najvyššiu úroveň rozhrania textovej služby (napr. SpellCheckerService). Bežné aplikácie by toto nastavenie nemali nikdy potrebovať."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"Zaviazať k službe VPN"</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 20e23ce..c407d2a 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -225,6 +225,10 @@
     <string name="permgrouplab_storage" msgid="1971118770546336966">"Prostor za shranjevanje"</string>
     <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"Dostop do pomnilnika USB."</string>
     <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"Dostop do kartice SD."</string>
+    <!-- no translation found for permgrouplab_accessibilityFeatures (7919025602283593907) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_accessibilityFeatures (4205196881678144335) -->
+    <skip />
     <string name="permlab_statusBar" msgid="7417192629601890791">"onemogočanje ali spreminjanje vrstice stanja"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Programom omogoča onemogočenje vrstice stanja ali dodajanje in odstranjevanje ikon sistema."</string>
     <string name="permlab_statusBarService" msgid="7247281911387931485">"vrstica stanja"</string>
@@ -299,10 +303,8 @@
     <string name="permdesc_shutdown" msgid="7046500838746291775">"Upravitelja dejavnosti preklopi v stanje za zaustavitev. Ne izvede celotne zaustavitve."</string>
     <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"preprečevanje preklopa programov"</string>
     <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"Uporabniku preprečuje preklop v drug program."</string>
-    <!-- no translation found for permlab_getTopActivityInfo (2537922311411546016) -->
-    <skip />
-    <!-- no translation found for permdesc_getTopActivityInfo (2512448855496067131) -->
-    <skip />
+    <string name="permlab_getTopActivityInfo" msgid="2537922311411546016">"pridobivanje podatkov o trenutni aplikaciji"</string>
+    <string name="permdesc_getTopActivityInfo" msgid="2512448855496067131">"Omogoča imetniku pridobivanje zasebnih podatkov o trenutni aplikaciji v ospredju zaslona."</string>
     <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"spremljanje in nadzor vseh zagonov programov"</string>
     <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"Programu omogoča spremljanje in nadziranje načina, kako sistem zažene dejavnosti. Zlonamerni programi lahko v celoti ogrozijo varnost sistema. To dovoljenje je potrebno samo za razvoj, vendar nikoli za običajno uporabo."</string>
     <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"pošiljanje oddaje brez paketa"</string>
@@ -346,6 +348,14 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Lastniku omogoča, da se poveže z vmesnikom načina vnosa najvišje ravni. Tega nikoli ni treba uporabiti za navadne programe."</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"povezovanje s storitvijo za ljudi s posebnimi potrebami"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Lastniku omogoča povezovanje z vmesnikom najvišje ravni storitve za ljudi s posebnimi potrebami. Tega nikoli ni treba uporabiti za navadne aplikacije."</string>
+    <!-- no translation found for permlab_canRequestTouchExplorationMode (6094034289937541846) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestTouchExplorationMode (940314268922270663) -->
+    <skip />
+    <!-- no translation found for permlab_canRequestEnahncedWebAccessibility (1905232971331801453) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestEnahncedWebAccessibility (4500520989321729676) -->
+    <skip />
     <string name="permlab_bindTextService" msgid="7358378401915287938">"poveži z besedilno storitvijo"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"Dovoljuje, da se lastnik poveže z vmesnikom besedilne storitve najvišje ravni (npr. SpellCheckerService). Tega nikoli ni treba uporabiti za navadne programe."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"povezava s storitvijo navideznega zasebnega omrežja"</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index b4f2096..42c17e0 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -225,6 +225,10 @@
     <string name="permgrouplab_storage" msgid="1971118770546336966">"Складиште"</string>
     <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"Приступите USB меморији."</string>
     <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"Приступ SD картици."</string>
+    <!-- no translation found for permgrouplab_accessibilityFeatures (7919025602283593907) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_accessibilityFeatures (4205196881678144335) -->
+    <skip />
     <string name="permlab_statusBar" msgid="7417192629601890791">"онемогућавање или измена статусне траке"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Дозвољава апликацији да онемогући статусну траку или да додаје и уклања системске иконе."</string>
     <string name="permlab_statusBarService" msgid="7247281911387931485">"статусна трака"</string>
@@ -299,10 +303,8 @@
     <string name="permdesc_shutdown" msgid="7046500838746291775">"Ставља менаџера активности у стање искључивања. Не искључује га у потпуности."</string>
     <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"спречавање пребацивања са једне апликације на другу"</string>
     <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"Спречава да корисник пређе на другу апликацију."</string>
-    <!-- no translation found for permlab_getTopActivityInfo (2537922311411546016) -->
-    <skip />
-    <!-- no translation found for permdesc_getTopActivityInfo (2512448855496067131) -->
-    <skip />
+    <string name="permlab_getTopActivityInfo" msgid="2537922311411546016">"преузимање информација о актуелној апликацији"</string>
+    <string name="permdesc_getTopActivityInfo" msgid="2512448855496067131">"Дозвољава власнику да преузима приватне информације о актуелној апликацији у првом плану екрана."</string>
     <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"надгледање и контрола покретања свих апликација"</string>
     <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"Дозвољава апликацији да прати начин на који систем покреће активности и да њиме управља. Злонамерне апликације могу у потпуности да угрозе систем. Ова дозвола је потребна само за програмирање, а никада за уобичајено коришћење."</string>
     <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"слање емитовања уклоњеног пакета"</string>
@@ -346,6 +348,14 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Омогућава да се власник обавеже на интерфејс методе уноса највишег нивоа. Уобичајене апликације никада не би требало да је користе."</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"повезивање са услугом приступачности"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Дозвољава власнику да се повеже са интерфејсом услуге приступачности највишег нивоа. Уобичајене апликације никада не би требало да је користе."</string>
+    <!-- no translation found for permlab_canRequestTouchExplorationMode (6094034289937541846) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestTouchExplorationMode (940314268922270663) -->
+    <skip />
+    <!-- no translation found for permlab_canRequestEnahncedWebAccessibility (1905232971331801453) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestEnahncedWebAccessibility (4500520989321729676) -->
+    <skip />
     <string name="permlab_bindTextService" msgid="7358378401915287938">"обавезивање на текстуалну услугу"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"Омогућава власнику да се обавеже на интерфејс текстуалне услуге највишег нивоа (нпр. SpellCheckerService). Обичне апликације никада не би требало да је користе."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"везивање за VPN услугу"</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index f858d54..535f8e5 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -225,6 +225,10 @@
     <string name="permgrouplab_storage" msgid="1971118770546336966">"Lagring"</string>
     <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"Få åtkomst till USB-enheten."</string>
     <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"Få åtkomst till SD-kortet."</string>
+    <!-- no translation found for permgrouplab_accessibilityFeatures (7919025602283593907) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_accessibilityFeatures (4205196881678144335) -->
+    <skip />
     <string name="permlab_statusBar" msgid="7417192629601890791">"inaktivera eller ändra statusfält"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Tillåter att appen inaktiverar statusfältet eller lägger till och tar bort systemikoner."</string>
     <string name="permlab_statusBarService" msgid="7247281911387931485">"statusfält"</string>
@@ -299,10 +303,8 @@
     <string name="permdesc_shutdown" msgid="7046500838746291775">"Sätter aktivitetshanteraren i avstängningsläge. Utför inte en fullständig avstängning."</string>
     <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"förhindrar programbyten"</string>
     <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"Hindrar användaren från att byta till en annan app."</string>
-    <!-- no translation found for permlab_getTopActivityInfo (2537922311411546016) -->
-    <skip />
-    <!-- no translation found for permdesc_getTopActivityInfo (2512448855496067131) -->
-    <skip />
+    <string name="permlab_getTopActivityInfo" msgid="2537922311411546016">"hämta information om aktuell app"</string>
+    <string name="permdesc_getTopActivityInfo" msgid="2512448855496067131">"Innehavaren tillåts att hämta privat information om den app som för tillfället är i förgrunden på skärmen."</string>
     <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"övervaka och styra alla appar som öppnas"</string>
     <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"Tillåter att appen övervakar och styr hur systemet startar aktiviteter. Skadliga appar kan kompromettera systemet helt. Den här behörigheten behövs bara för programmering, aldrig för vanlig användning."</string>
     <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"skicka meddelande om borttaget paket"</string>
@@ -346,6 +348,14 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Innehavaren tillåts att binda till den översta nivåns gränssnitt för en inmatningsmetod. Ska inte behövas för vanliga appar."</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"bind till en tillgänglighetstjänst"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Innehavaren tillåts att binda till den översta nivåns gränssnitt för en tillgänglighetstjänst. Ska inte behövas för vanliga appar."</string>
+    <!-- no translation found for permlab_canRequestTouchExplorationMode (6094034289937541846) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestTouchExplorationMode (940314268922270663) -->
+    <skip />
+    <!-- no translation found for permlab_canRequestEnahncedWebAccessibility (1905232971331801453) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestEnahncedWebAccessibility (4500520989321729676) -->
+    <skip />
     <string name="permlab_bindTextService" msgid="7358378401915287938">"bind till en texttjänst"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"Tillåter innehavaren att binda mot den högsta gränssnittsnivån i en texttjänst (t.ex. SpellCheckerService). Bör aldrig behövas för normala appar."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"bind till en VPN-tjänst"</string>
@@ -595,7 +605,7 @@
     <string name="permlab_sdcardRead" product="default" msgid="8235341515605559677">"testa åtkomst till skyddad lagringsenhet"</string>
     <string name="permdesc_sdcardRead" product="nosdcard" msgid="3642473292348132072">"Tillåter att appen testar behörighet till USB-enheter för användning på framtida enheter."</string>
     <string name="permdesc_sdcardRead" product="default" msgid="5914402684685848828">"Tillåter appen att testa behörighet till SD-kortet för användning på framtida enheter."</string>
-    <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"ändra eller ta bort innehållet"</string>
+    <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"ändra eller ta bort innehåll på USB-enheten"</string>
     <string name="permlab_sdcardWrite" product="default" msgid="8805693630050458763">"ändra eller ta bort innehåll på SD-kortet"</string>
     <string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"Gör att app skriver till USB."</string>
     <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Tillåter att appen skriver till SD-kortet."</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 4430ed5..71670c1 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -225,6 +225,10 @@
     <string name="permgrouplab_storage" msgid="1971118770546336966">"Hifadhi"</string>
     <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"Fikia hifadhi ya USB."</string>
     <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"Fikia kadi ya SD."</string>
+    <!-- no translation found for permgrouplab_accessibilityFeatures (7919025602283593907) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_accessibilityFeatures (4205196881678144335) -->
+    <skip />
     <string name="permlab_statusBar" msgid="7417192629601890791">"zima au rekebisha mwambaa hali"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Inaruhusu programu kulemaza upau wa hali au kuongeza na kutoa ikoni za mfumo."</string>
     <string name="permlab_statusBarService" msgid="7247281911387931485">"mwamba hali"</string>
@@ -299,10 +303,8 @@
     <string name="permdesc_shutdown" msgid="7046500838746291775">"Huweka kisimamia shughuli katika hali ya kuzima. Haiadhiri uzimaji kamili"</string>
     <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"zuia swichi za app"</string>
     <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"Huzuia mtumiaji dhidi ya kubadilisha na kwenda kwa programu nyingine."</string>
-    <!-- no translation found for permlab_getTopActivityInfo (2537922311411546016) -->
-    <skip />
-    <!-- no translation found for permdesc_getTopActivityInfo (2512448855496067131) -->
-    <skip />
+    <string name="permlab_getTopActivityInfo" msgid="2537922311411546016">"pata maelezo ya sasa kuhusu programu"</string>
+    <string name="permdesc_getTopActivityInfo" msgid="2512448855496067131">"Huruhusu mmiliki kurejesha maelezo ya faragha kuhusu programu ya sasa katika mandharimbele ya skrini."</string>
     <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"Fuatilia na kudhibiti uzinduzi wote wa programu"</string>
     <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"Inaruhusu programu kufuatilia na kudhibiti jinsi mfumo unazindua shughuli. Programu hasidi zinaweza kutia mfumo hatarini. Ruhusa inahitajika tu kwa usanidi, kamwe sio kwa matumizi ya kawaida."</string>
     <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"furushi lililotumwa limeondoa tangazo"</string>
@@ -346,6 +348,14 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Inaruhusu mmiliki kushurutisha kwenye kusano ya kiwango cha juu ya mbinu ya ingizo. Haipaswi kuhitajika kwa programu za kawaida."</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"funga kwa huduma ya ufikiaji"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Inamuruhusu mmiliki kufunga kipengee kinachojitokeza katika nyanja mbalimbali za kiwango cha juu cha huduma ya afikiaji. Hapaswi kuhitajika kwa programu za kawaida."</string>
+    <!-- no translation found for permlab_canRequestTouchExplorationMode (6094034289937541846) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestTouchExplorationMode (940314268922270663) -->
+    <skip />
+    <!-- no translation found for permlab_canRequestEnahncedWebAccessibility (1905232971331801453) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestEnahncedWebAccessibility (4500520989321729676) -->
+    <skip />
     <string name="permlab_bindTextService" msgid="7358378401915287938">"Imefungwa kwa huduma ya maandishi"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"Inaruhusu kishikiliaji kushurutisha kusano ya kiwango cha juu ya huduma ya matini(k.m.SpellCheckerService). Haipaswi kuhitajika kwa programu za kawaida."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"funga kwa huduma ya VPN"</string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 1cad285..0c56b90 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -225,6 +225,10 @@
     <string name="permgrouplab_storage" msgid="1971118770546336966">"พื้นที่เก็บข้อมูล"</string>
     <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"เข้าถึงที่เก็บข้อมูล USB"</string>
     <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"เข้าถึงการ์ด SD"</string>
+    <!-- no translation found for permgrouplab_accessibilityFeatures (7919025602283593907) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_accessibilityFeatures (4205196881678144335) -->
+    <skip />
     <string name="permlab_statusBar" msgid="7417192629601890791">"ปิดการใช้งานหรือแก้ไขแถบสถานะ"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"อนุญาตให้แอปพลิเคชันปิดใช้งานแถบสถานะหรือเพิ่มและนำไอคอนระบบออก"</string>
     <string name="permlab_statusBarService" msgid="7247281911387931485">"แถบสถานะ"</string>
@@ -299,10 +303,8 @@
     <string name="permdesc_shutdown" msgid="7046500838746291775">"กำหนดให้ตัวจัดการกิจกรรมอยู่ในสถานะปิดระบบ โดยไม่ได้ปิดระบบอย่างสมบูรณ์"</string>
     <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"ป้องกันการเปลี่ยนแอปพลิเคชัน"</string>
     <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"ป้องกันไม่ให้ผู้ใช้สลับไปใช้แอปพลิเคชันอื่น"</string>
-    <!-- no translation found for permlab_getTopActivityInfo (2537922311411546016) -->
-    <skip />
-    <!-- no translation found for permdesc_getTopActivityInfo (2512448855496067131) -->
-    <skip />
+    <string name="permlab_getTopActivityInfo" msgid="2537922311411546016">"รับข้อมูลแอปพลิเคชันปัจจุบัน"</string>
+    <string name="permdesc_getTopActivityInfo" msgid="2512448855496067131">"ช่วยให้เจ้าของสามารถดึงข้อมูลส่วนตัวเกี่ยวกับแอปพลิเคชันปัจจุบันในส่วนหน้าของหน้าจอ"</string>
     <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"ตรวจสอบและควบคุมแอปพลิเคชันทั้งหมดที่เปิดใช้งาน"</string>
     <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"อนุญาตให้แอปพลิเคชันตรวจสอบและควบคุมวิธีการที่ระบบเปิดกิจกรรมต่างๆ แอปพลิเคชันที่เป็นอันตรายอาจทำอันตรายแก่ระบบได้อย่างสิ้นเชิง การอนุญาตนี้จำเป็นสำหรับการพัฒนาเท่านั้น ไม่ใช้สำหรับแอปพลิเคชันทั่วไปโดยเด็ดขาด"</string>
     <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"ส่งการกระจายข้อมูลว่ามีการนำแพคเกจออก"</string>
@@ -346,6 +348,14 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"อนุญาตให้ผู้ใช้เชื่อมโยงกับส่วนติดต่อผู้ใช้ระดับสูงสุดของวิธีการป้อนข้อมูล ไม่ควรต้องใช้สำหรับแอปพลิเคชันทั่วไป"</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"เชื่อมโยงกับบริการการเข้าถึง"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"อนุญาตให้เจ้าของเชื่อมโยงกับส่วนติดต่อระดับบนสุดของบริการการเข้าถึง ซึ่งแอปพลิเคชันทั่วไปไม่จำเป็นต้องใช้"</string>
+    <!-- no translation found for permlab_canRequestTouchExplorationMode (6094034289937541846) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestTouchExplorationMode (940314268922270663) -->
+    <skip />
+    <!-- no translation found for permlab_canRequestEnahncedWebAccessibility (1905232971331801453) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestEnahncedWebAccessibility (4500520989321729676) -->
+    <skip />
     <string name="permlab_bindTextService" msgid="7358378401915287938">"เชื่อมโยงกับบริการข้อความ"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"อนุญาตให้ผู้ใช้เชื่อมโยงกับส่วนติดต่อผู้ใช้ระดับสูงสุดของบริการข้อความ (เช่น บริการเครื่องตรวจตัวสะกด) ไม่ควรต้องใช้สำหรับแอปพลิเคชันทั่วไป"</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"เชื่อมโยงกับบริการ VPN"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 6798be9..2479c0a 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -225,6 +225,10 @@
     <string name="permgrouplab_storage" msgid="1971118770546336966">"Imbakan"</string>
     <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"I-access ang imbakan na USB."</string>
     <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"I-access ang SD card."</string>
+    <!-- no translation found for permgrouplab_accessibilityFeatures (7919025602283593907) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_accessibilityFeatures (4205196881678144335) -->
+    <skip />
     <string name="permlab_statusBar" msgid="7417192629601890791">"huwag paganahin o baguhin ang status bar"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Pinapayagan ang app na huwag paganahin ang status bar o magdagdag at mag-alis ng mga icon ng system."</string>
     <string name="permlab_statusBarService" msgid="7247281911387931485">"status bar"</string>
@@ -299,10 +303,8 @@
     <string name="permdesc_shutdown" msgid="7046500838746291775">"Inilalagay ang tagapamahala ng aktibidad sa katayuan ng pag-shutdown. Hindi nagsasagawa ng kumpletong pag-shutdown."</string>
     <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"pigilan ang mga paglipat ng app"</string>
     <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"Pinipigilan ang mga user sa paglipat sa isa pang app."</string>
-    <!-- no translation found for permlab_getTopActivityInfo (2537922311411546016) -->
-    <skip />
-    <!-- no translation found for permdesc_getTopActivityInfo (2512448855496067131) -->
-    <skip />
+    <string name="permlab_getTopActivityInfo" msgid="2537922311411546016">"kunin ang impormasyon ng kasalukuyang app"</string>
+    <string name="permdesc_getTopActivityInfo" msgid="2512448855496067131">"Pinapayagan ang may-ari na bawiin ang pribadong impormasyon tungkol sa kasalukuyang application sa foreground ng screen."</string>
     <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"subaybayan at kontrolin ang lahat ng paglunsad ng app"</string>
     <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"Pinapayagan ang app na subaybayan at kontrolin kung paano naglulunsad ng mga aktibidad ang system. Maaaring ganap na ikompromiso ng nakakahamak na apps ang system. Kinakailangan lamang ang pahintulot na ito para sa pagpapabuti, hindi kailanman para sa normal na paggamit."</string>
     <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"magpadala ng package inalis ang broadcast"</string>
@@ -346,6 +348,14 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Pinapayagan ang may-hawak na sumailalim sa nangungunang interface ng pamamaraan ng pag-input. Hindi kailanman dapat na kailanganin para sa normal na apps."</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"sumailalim sa isang serbisyo sa accessibility"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Binibigyang-daan ang may-ari na sumailalim sa nasa nangungunang antas na interface ng isang serbisyo sa accessibility. Hindi dapat kailanman kailanganin para sa normal na apps."</string>
+    <!-- no translation found for permlab_canRequestTouchExplorationMode (6094034289937541846) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestTouchExplorationMode (940314268922270663) -->
+    <skip />
+    <!-- no translation found for permlab_canRequestEnahncedWebAccessibility (1905232971331801453) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestEnahncedWebAccessibility (4500520989321729676) -->
+    <skip />
     <string name="permlab_bindTextService" msgid="7358378401915287938">"sumailalim sa serbisyo ng teksto"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"Pinapayagan ang may-hawak na sumailalim sa nangungunang antas na interface (hal. SpellCheckerService). Hindi kailanman dapat na kailanganin para sa normal na apps."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"sumailalim sa isang serbisyo ng VPN"</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 015fe1b..78403a6 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -225,6 +225,10 @@
     <string name="permgrouplab_storage" msgid="1971118770546336966">"Depolama"</string>
     <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"USB belleğe erişin."</string>
     <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"SD karta erişin."</string>
+    <!-- no translation found for permgrouplab_accessibilityFeatures (7919025602283593907) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_accessibilityFeatures (4205196881678144335) -->
+    <skip />
     <string name="permlab_statusBar" msgid="7417192629601890791">"durum çubuğunu devre dışı bırak veya değiştir"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Uygulamaya, durum çubuğunu devre dışı bırakma ve sistem simgelerini ekleyip kaldırma izni verir."</string>
     <string name="permlab_statusBarService" msgid="7247281911387931485">"durum çubuğu"</string>
@@ -299,10 +303,8 @@
     <string name="permdesc_shutdown" msgid="7046500838746291775">"Eylem yöneticisini kapalı duruma getirir. Tam kapatma işlemi gerçekleştirmez."</string>
     <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"uygulama değişimlerini engelle"</string>
     <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"Kullanıcının başka bir uygulamaya geçiş yapmasını engeller."</string>
-    <!-- no translation found for permlab_getTopActivityInfo (2537922311411546016) -->
-    <skip />
-    <!-- no translation found for permdesc_getTopActivityInfo (2512448855496067131) -->
-    <skip />
+    <string name="permlab_getTopActivityInfo" msgid="2537922311411546016">"geçerli uygulama bilgilerini al"</string>
+    <string name="permdesc_getTopActivityInfo" msgid="2512448855496067131">"İzin sahibine, ekranın ön planındaki geçerli uygulama hakkında gizli bilgileri alma olanağı verir."</string>
     <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"tüm uygulama başlatma işlemlerini izle ve denetle"</string>
     <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"Uygulamaya, sistemin etkinlikleri nasıl başlattığını izleme ve denetleme izni verir. Kötü amaçlı uygulamalar sistemi tamamen tehlikeye atabilir. Bu izin normal kullanım için değildir, sadece geliştirme süreçlerinde kullanılır."</string>
     <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"paket ile kaldırılan yayını gönder"</string>
@@ -346,6 +348,14 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Cihazın sahibine, bir giriş yönteminin en üst düzey arayüzüne bağlanma izni verir. Normal uygulamalarda hiçbir zaman gerek duyulmaz."</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"erişilebilirlik hizmetine bağlan"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"İzin sahibine bir erişilebilirlik hizmetinin en üst düzey arayüzüne bağlanma izni verir. Normal uygulamalarda hiçbir zaman gerek duyulmaz."</string>
+    <!-- no translation found for permlab_canRequestTouchExplorationMode (6094034289937541846) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestTouchExplorationMode (940314268922270663) -->
+    <skip />
+    <!-- no translation found for permlab_canRequestEnahncedWebAccessibility (1905232971331801453) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestEnahncedWebAccessibility (4500520989321729676) -->
+    <skip />
     <string name="permlab_bindTextService" msgid="7358378401915287938">"kısa mesaj hizmetine bağla"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"Cihazın sahibine, bir metin hizmetinin (ör. SpellCheckerService) en üst düzey arayüzüne bağlanma izni verir. Normal uygulamalarda hiçbir zaman gerekmez."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"VPN hizmetine bağlan"</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 17f545c..d61af1d 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -225,6 +225,10 @@
     <string name="permgrouplab_storage" msgid="1971118770546336966">"Зберігання"</string>
     <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"Отрим. доступу до носія USB."</string>
     <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"Доступ до карти SD."</string>
+    <!-- no translation found for permgrouplab_accessibilityFeatures (7919025602283593907) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_accessibilityFeatures (4205196881678144335) -->
+    <skip />
     <string name="permlab_statusBar" msgid="7417192629601890791">"вимикати чи змін. рядок стану"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Дозволяє програмі вимикати рядок стану чи додавати та видаляти піктограми системи."</string>
     <string name="permlab_statusBarService" msgid="7247281911387931485">"рядок стану"</string>
@@ -299,10 +303,8 @@
     <string name="permdesc_shutdown" msgid="7046500838746291775">"Переводить диспетчер дій у стан завершення роботи. Не виконує повне завершення роботи."</string>
     <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"запобіг. зміні програм"</string>
     <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"Запобігати переходу користувача до іншої програми."</string>
-    <!-- no translation found for permlab_getTopActivityInfo (2537922311411546016) -->
-    <skip />
-    <!-- no translation found for permdesc_getTopActivityInfo (2512448855496067131) -->
-    <skip />
+    <string name="permlab_getTopActivityInfo" msgid="2537922311411546016">"отримати інформацію про поточну програму"</string>
+    <string name="permdesc_getTopActivityInfo" msgid="2512448855496067131">"Дозволяє власникові отримувати приватну інформацію про поточну програму на передньому плані екрана."</string>
     <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"відстежувати та контролювати запуски всіх програм"</string>
     <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"Дозволяє програмі відстежувати та контролювати, як саме система запускає дії. Шкідливі програми можуть отримати повний контроль над системою. Цей дозвіл потрібний лише для розробки, а не для звичайного користування."</string>
     <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"надсил. запис про видал. пакета"</string>
@@ -346,6 +348,14 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Дозволяє власнику прив’язуватися до інтерфейсу верхнього рівня методу введення. Ніколи не застосовується для звичайних програм."</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"прив’язуватися до служби доступності"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Дозволяє власникові прив’язуватися до інтерфейсу верхнього рівня служби доступності. Ніколи не застосовується для звичайних програм."</string>
+    <!-- no translation found for permlab_canRequestTouchExplorationMode (6094034289937541846) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestTouchExplorationMode (940314268922270663) -->
+    <skip />
+    <!-- no translation found for permlab_canRequestEnahncedWebAccessibility (1905232971331801453) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestEnahncedWebAccessibility (4500520989321729676) -->
+    <skip />
     <string name="permlab_bindTextService" msgid="7358378401915287938">"прив’язати до текстової служби"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"Дозволяє власникові прив’язуватися до інтерфейсу верхнього рівня текстової служби (напр. SpellCheckerService). Ніколи не застосовується для звичайних програм."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"прив’язуватися до служби VPN"</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index d26ee14..27b91af 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -225,6 +225,10 @@
     <string name="permgrouplab_storage" msgid="1971118770546336966">"Dung lượng"</string>
     <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"Truy cập bộ nhớ USB."</string>
     <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"Truy cập thẻ SD."</string>
+    <!-- no translation found for permgrouplab_accessibilityFeatures (7919025602283593907) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_accessibilityFeatures (4205196881678144335) -->
+    <skip />
     <string name="permlab_statusBar" msgid="7417192629601890791">"vô hiệu hóa hoặc sửa đổi thanh trạng thái"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Cho phép ứng dụng vô hiệu hóa thanh trạng thái hoặc thêm và xóa biểu tượng hệ thống."</string>
     <string name="permlab_statusBarService" msgid="7247281911387931485">"thanh trạng thái"</string>
@@ -299,10 +303,8 @@
     <string name="permdesc_shutdown" msgid="7046500838746291775">"Đặt trình quản lý hoạt động sang trạng thái tắt. Không thực hiện tắt hoàn toàn."</string>
     <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"ngăn chuyển đổi ứng dụng"</string>
     <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"Ngăn người dùng chuyển sang ứng dụng khác."</string>
-    <!-- no translation found for permlab_getTopActivityInfo (2537922311411546016) -->
-    <skip />
-    <!-- no translation found for permdesc_getTopActivityInfo (2512448855496067131) -->
-    <skip />
+    <string name="permlab_getTopActivityInfo" msgid="2537922311411546016">"truy cập thông tin ứng dụng hiện tại"</string>
+    <string name="permdesc_getTopActivityInfo" msgid="2512448855496067131">"Cho phép chủ sở hữu truy xuất thông tin cá nhân về ứng dụng hiện tại ở nền trước của màn hình."</string>
     <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"giám sát và kiểm soát tất cả hoạt động khởi chạy ứng dụng"</string>
     <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"Cho phép ứng dụng giám sát và kiểm soát cách hệ thống khởi chạy các hoạt động. Ứng dụng độc hại hoàn toàn có thể làm tổn hại hệ thống. Quyền này chỉ cần cho mục đích phát triển, không dành cho mục đích sử dụng thông thường."</string>
     <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"gửi truyền phát đã xóa của gói"</string>
@@ -346,6 +348,14 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Cho phép chủ sở hữu liên kết với giao diện cấp cao nhất của phương thức nhập. Không cần thiết cho các ứng dụng thông thường."</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"liên kết với dịch vụ truy cập"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Cho phép chủ sở hữu liên kết với giao diện cấp cao nhất của dịch vụ truy cập. Không cần thiết cho các ứng dụng thông thường."</string>
+    <!-- no translation found for permlab_canRequestTouchExplorationMode (6094034289937541846) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestTouchExplorationMode (940314268922270663) -->
+    <skip />
+    <!-- no translation found for permlab_canRequestEnahncedWebAccessibility (1905232971331801453) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestEnahncedWebAccessibility (4500520989321729676) -->
+    <skip />
     <string name="permlab_bindTextService" msgid="7358378401915287938">"liên kết với dịch vụ văn bản"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"Cho phép chủ sở hữu liên kết với giao diện cấp cao nhất của dịch vụ văn bản (ví dụ: SpellCheckerService). Không cần thiết cho các ứng dụng thông thường."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"liên kết với dịch vụ VPN"</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 87faf15..f80f677 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -225,6 +225,10 @@
     <string name="permgrouplab_storage" msgid="1971118770546336966">"存储"</string>
     <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"访问 USB 存储设备。"</string>
     <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"访问 SD 卡。"</string>
+    <!-- no translation found for permgrouplab_accessibilityFeatures (7919025602283593907) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_accessibilityFeatures (4205196881678144335) -->
+    <skip />
     <string name="permlab_statusBar" msgid="7417192629601890791">"停用或修改状态栏"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"允许应用停用状态栏或者增删系统图标。"</string>
     <string name="permlab_statusBarService" msgid="7247281911387931485">"状态栏"</string>
@@ -299,10 +303,8 @@
     <string name="permdesc_shutdown" msgid="7046500838746291775">"使活动管理器进入关闭状态。不执行彻底关机。"</string>
     <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"禁止切换应用"</string>
     <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"阻止用户切换到其他应用。"</string>
-    <!-- no translation found for permlab_getTopActivityInfo (2537922311411546016) -->
-    <skip />
-    <!-- no translation found for permdesc_getTopActivityInfo (2512448855496067131) -->
-    <skip />
+    <string name="permlab_getTopActivityInfo" msgid="2537922311411546016">"获取当前应用的信息"</string>
+    <string name="permdesc_getTopActivityInfo" msgid="2512448855496067131">"允许应用针对目前在屏幕前台运行的应用检索相关隐私信息。"</string>
     <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"监控所有应用的启动"</string>
     <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"允许应用监视和控制系统是如何启动活动的。恶意应用可能会完全破坏系统。此权限只有在进行开发时才需要,正常使用情况下绝不需要。"</string>
     <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"发送包删除的广播"</string>
@@ -346,6 +348,14 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"允许用户绑定至输入法的顶级接口。普通应用绝不需要此权限。"</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"绑定至辅助服务"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"允许应用绑定至辅助服务的顶级接口。普通应用绝不需要此权限。"</string>
+    <!-- no translation found for permlab_canRequestTouchExplorationMode (6094034289937541846) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestTouchExplorationMode (940314268922270663) -->
+    <skip />
+    <!-- no translation found for permlab_canRequestEnahncedWebAccessibility (1905232971331801453) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestEnahncedWebAccessibility (4500520989321729676) -->
+    <skip />
     <string name="permlab_bindTextService" msgid="7358378401915287938">"绑定至文字服务"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"允许用户绑定至文字服务(如 SpellCheckerService)的顶级接口。普通应用绝不需要此权限。"</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"绑定到 VPN 服务"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 6d1f3bd..a7e4b70 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -225,6 +225,10 @@
     <string name="permgrouplab_storage" msgid="1971118770546336966">"儲存"</string>
     <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"存取 USB 儲存裝置。"</string>
     <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"存取 SD 卡。"</string>
+    <!-- no translation found for permgrouplab_accessibilityFeatures (7919025602283593907) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_accessibilityFeatures (4205196881678144335) -->
+    <skip />
     <string name="permlab_statusBar" msgid="7417192629601890791">"停用或變更狀態列"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"允許應用程式停用狀態列,並可新增或移除系統圖示。"</string>
     <string name="permlab_statusBarService" msgid="7247281911387931485">"狀態列"</string>
@@ -299,10 +303,8 @@
     <string name="permdesc_shutdown" msgid="7046500838746291775">"讓活動管理員進入關機狀態,而不執行完整的關機程序。"</string>
     <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"防止切換應用程式"</string>
     <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"防止使用者切換到其他應用程式。"</string>
-    <!-- no translation found for permlab_getTopActivityInfo (2537922311411546016) -->
-    <skip />
-    <!-- no translation found for permdesc_getTopActivityInfo (2512448855496067131) -->
-    <skip />
+    <string name="permlab_getTopActivityInfo" msgid="2537922311411546016">"取得目前的應用程式資訊"</string>
+    <string name="permdesc_getTopActivityInfo" msgid="2512448855496067131">"允許應用程式針對目前在螢幕前景運作的應用程式擷取私人資訊。"</string>
     <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"監視及控制所有應用程式的啟動程序"</string>
     <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"允許應用程式監視和控制系統啟動活動的方式。請注意,惡意應用程式可能利用此功能破壞整個系統。這個權限只有開發人員才需要,一般使用者不需使用這個權限。"</string>
     <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"傳送程式已移除廣播"</string>
@@ -346,6 +348,14 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"允許應用程式繫結至輸入法的頂層介面 (一般應用程式不需使用)。"</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"繫結至協助工具服務"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"允許應用程式繫結至協助工具服務的頂層介面 (一般應用程式不需使用)。"</string>
+    <!-- no translation found for permlab_canRequestTouchExplorationMode (6094034289937541846) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestTouchExplorationMode (940314268922270663) -->
+    <skip />
+    <!-- no translation found for permlab_canRequestEnahncedWebAccessibility (1905232971331801453) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestEnahncedWebAccessibility (4500520989321729676) -->
+    <skip />
     <string name="permlab_bindTextService" msgid="7358378401915287938">"繫結至文字服務"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"允許應用程式繫結至文字服務 (例如 SpellCheckerService) 的頂層介面 (一般應用程式不需使用)。"</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"繫結至 VPN 服務"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index dafec7c..f4f1982 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -225,6 +225,10 @@
     <string name="permgrouplab_storage" msgid="1971118770546336966">"Isitoreji"</string>
     <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"Finyelela kwisitoreji se-USB."</string>
     <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"Finyelela ikhadi le-SD."</string>
+    <!-- no translation found for permgrouplab_accessibilityFeatures (7919025602283593907) -->
+    <skip />
+    <!-- no translation found for permgroupdesc_accessibilityFeatures (4205196881678144335) -->
+    <skip />
     <string name="permlab_statusBar" msgid="7417192629601890791">"khubaza noma guqula ibha yomumo"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Ivumela insiza ukuthi yenze umudwa ochaza ngesimo ukuthi ungasebenzi noma ukufaka noma ukukhipha izithonjana zohlelo."</string>
     <string name="permlab_statusBarService" msgid="7247281911387931485">"umudwa ochaza ngesimo"</string>
@@ -299,10 +303,8 @@
     <string name="permdesc_shutdown" msgid="7046500838746291775">"Ibeka imeneja yomsebenzi kwisimo sokuvala shaqa. Ayenzi ukuvala shaqa okuphelele."</string>
     <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"gwema ukushintsha kohlelo lokusebenza"</string>
     <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"Igwema umsebenzisi ukuthi ashintshele kolunye uhlelo lokusebenza."</string>
-    <!-- no translation found for permlab_getTopActivityInfo (2537922311411546016) -->
-    <skip />
-    <!-- no translation found for permdesc_getTopActivityInfo (2512448855496067131) -->
-    <skip />
+    <string name="permlab_getTopActivityInfo" msgid="2537922311411546016">"thola ulwazi lohlelo lokusebenza lwamanje"</string>
+    <string name="permdesc_getTopActivityInfo" msgid="2512448855496067131">"Ivumela umphathi ukuthi athole ulwazi oluyimfihlo mayelana nohlelo lokusebenza lwamanje ngaphambili kwesikrini."</string>
     <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"qapha futhi ulawule ukuqaliswa kwazo zonke izinsiza"</string>
     <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"Ivumela insiza ukuthi ihlole futhi ilawule ukuthi isistimu iziqalisa kanjani izehlakalo. Izinzisa ezinobungozi zingensa isistimu ibe sebungozini. Lemvume idingakalela intuthuku kuphela hhay ukusetshenziswa okwejwayelekile."</string>
     <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"thumela iphakheji yomsakazo okhishiwe"</string>
@@ -346,6 +348,14 @@
     <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Ivumela isimeli ukuhlanganisa uxhumano nomsebenzisi wezinga eliphezulu lendlela yokufaka. Ayisoze yadingeka kwizinhlelo ezivamile."</string>
     <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"hlanganisa kusevisi yokufinyeleleka"</string>
     <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Ivumela isibambi ukuhlanganisa uxhumo nomsebenzisi kwezinga eliphezulu lesevisi yesinqunjwana. Akusoze kwadingekela izinhlelo zokusebenza ezivamile."</string>
+    <!-- no translation found for permlab_canRequestTouchExplorationMode (6094034289937541846) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestTouchExplorationMode (940314268922270663) -->
+    <skip />
+    <!-- no translation found for permlab_canRequestEnahncedWebAccessibility (1905232971331801453) -->
+    <skip />
+    <!-- no translation found for permdesc_canRequestEnahncedWebAccessibility (4500520989321729676) -->
+    <skip />
     <string name="permlab_bindTextService" msgid="7358378401915287938">"bophezela kunsizakalo yombhalo"</string>
     <string name="permdesc_bindTextService" msgid="8151968910973998670">"Ivumela umbambi ukuhlanganisa uxhumano nomsebenzisi kwezinga eliphezulu lwesixhumi esibonakalayo sensizakalo yombhalo(isb. InsizakaloYokuhlolaUkubhala). Akusoze kwadingeka kwezinhlelo zokusebenza ezivamile."</string>
     <string name="permlab_bindVpnService" msgid="4708596021161473255">"hlanganisa kwinsizakalo ye-VPN"</string>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index dc921e6..0fb8a10 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -1542,6 +1542,8 @@
         <enum name="KEYCODE_RO" value="217" />
         <enum name="KEYCODE_KANA" value="218" />
         <enum name="KEYCODE_ASSIST" value="219" />
+        <enum name="KEYCODE_BRIGHTNESS_DOWN" value="220" />
+        <enum name="KEYCODE_BRIGHTNESS_UP" value="221" />
     </attr>
 
     <!-- ***************************************************************** -->
@@ -2510,6 +2512,8 @@
             <flag name="flagIncludeNotImportantViews" value="0x00000002" />
             <!-- Has flag {@link android.accessibilityservice.AccessibilityServiceInfo#FLAG_REQUEST_TOUCH_EXPLORATION_MODE} -->
             <flag name="flagRequestTouchExplorationMode" value="0x00000004" />
+            <!-- Has flag {@link android.accessibilityservice.AccessibilityServiceInfo#FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY} -->
+            <flag name="flagRequestEnhancedWebAccessibility" value="0x00000008" />
         </attr>
         <!-- Component name of an activity that allows the user to modify
              the settings for this service. This setting cannot be changed at runtime. -->
@@ -2960,6 +2964,9 @@
         <!-- Timeout between frames of animation in milliseconds
              {@deprecated Not used by the framework.} -->
         <attr name="animationResolution" format="integer" />
+        <!-- Defines if the associated drawables need to be mirrored when in RTL mode.
+             Default is false -->
+        <attr name="mirrorForRtl" format="boolean" />
     </declare-styleable>
 
     <declare-styleable name="SeekBar">
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 49b536d..0d80082 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2034,5 +2034,6 @@
   <eat-comment />
 
   <public type="attr" name="mipMap" id="0x010103cd" />
+  <public type="attr" name="mirrorForRtl" id="0x010103ce" />
 
 </resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 7f0fc0b..aae509e 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -535,6 +535,11 @@
     <!-- Description of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permgroupdesc_storage" product="default">Access the SD card.</string>
 
+    <!-- Title of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permgrouplab_accessibilityFeatures">Accessibility features</string>
+    <!-- Description of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permgroupdesc_accessibilityFeatures">Features that assistive technology can request.</string>
+
     <!--  Permissions -->
 
     <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
@@ -935,6 +940,20 @@
         interface of an accessibility service. Should never be needed for normal apps.</string>
 
     <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permlab_canRequestTouchExplorationMode">request explore by touch</string>
+    <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permdesc_canRequestTouchExplorationMode">Allows the hoder to request an
+        interaction mode in which touched items are spoken aloud and the UI can be explored
+        via gestures.</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_canRequestEnahncedWebAccessibility">request enhanced web accessibility</string>
+    <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permdesc_canRequestEnahncedWebAccessibility">Allows the hoder to request
+        enabling of web accessibility enhancements. For example, installing scripts to make
+        app content more accessible.</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_bindTextService">bind to a text service</string>
     <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permdesc_bindTextService">Allows the holder to bind to the top-level
@@ -2703,16 +2722,16 @@
          service to put the device into explore by touch mode, displayed as a dialog message when
          the user selects to enables the service. (tablet). [CHAR LIMIT=NONE] -->
     <string name="enable_explore_by_touch_warning_message" product="tablet">
-            <xliff:g id="accessibility_service_name">%1$s</xliff:g> wants to enable Explore by Touch.
-            When Explore by Touch is turned on, you can hear or see descriptions of what\'s under
-            your finger or perform gestures to interact with the tablet.</string>
+        <xliff:g id="accessibility_service_name">%1$s</xliff:g> wants to enable Explore by Touch.
+        When Explore by Touch is turned on, you can hear or see descriptions of what\'s under
+        your finger or perform gestures to interact with the tablet.</string>
     <!-- Summary for a warning message about the interaction model changes after allowing an accessibility
          service to put the device into explore by touch mode, displayed as a dialog message when
          the user selects to enables the service. (default). [CHAR LIMIT=NONE] -->
     <string name="enable_explore_by_touch_warning_message" product="default">
-            <xliff:g id="accessibility_service_name">%1$s</xliff:g> wants to enable Explore by Touch.
-            When Explore by Touch is turned on, you can hear or see descriptions of what\'s under
-            your finger or perform gestures to interact with the phone.</string>
+        <xliff:g id="accessibility_service_name">%1$s</xliff:g> wants to enable Explore by Touch.
+       When Explore by Touch is turned on, you can hear or see descriptions of what\'s under
+       your finger or perform gestures to interact with the phone.</string>
 
     <!-- String used to display the date. This is the string to say something happened 1 month ago. -->
     <string name="oneMonthDurationPast">1 month ago</string>
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index f489786..56c2235 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -370,6 +370,7 @@
         <item name="android:maxWidth">48dip</item>
         <item name="android:minHeight">48dip</item>
         <item name="android:maxHeight">48dip</item>
+        <item name="android:mirrorForRtl">false</item>
     </style>
 
     <style name="Widget.ProgressBar.Large">
@@ -410,6 +411,7 @@
         <item name="android:indeterminateDrawable">@android:drawable/progress_indeterminate_horizontal</item>
         <item name="android:minHeight">20dip</item>
         <item name="android:maxHeight">20dip</item>
+        <item name="android:mirrorForRtl">true</item>
     </style>
 
     <style name="Widget.SeekBar">
@@ -421,6 +423,7 @@
         <item name="android:thumb">@android:drawable/seek_thumb</item>
         <item name="android:thumbOffset">8dip</item>
         <item name="android:focusable">true</item>
+        <item name="android:mirrorForRtl">true</item>
     </style>
 
     <style name="Widget.RatingBar">
@@ -430,6 +433,7 @@
         <item name="android:minHeight">57dip</item>
         <item name="android:maxHeight">57dip</item>
         <item name="android:thumb">@null</item>
+        <item name="android:mirrorForRtl">true</item>
     </style>
 
     <style name="Widget.RatingBar.Indicator">
@@ -1745,6 +1749,7 @@
         <item name="android:focusable">true</item>
         <item name="android:paddingStart">16dip</item>
         <item name="android:paddingEnd">16dip</item>
+        <item name="android:mirrorForRtl">true</item>
     </style>
 
     <style name="Widget.Holo.RatingBar" parent="Widget.RatingBar">
diff --git a/core/tests/ConnectivityManagerTest/AndroidManifest.xml b/core/tests/ConnectivityManagerTest/AndroidManifest.xml
index 5db7ffc..2c34d47 100644
--- a/core/tests/ConnectivityManagerTest/AndroidManifest.xml
+++ b/core/tests/ConnectivityManagerTest/AndroidManifest.xml
@@ -17,7 +17,7 @@
 <!-- package name must be unique so suffix with "tests" so package loader doesn't ignore us -->
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
   package="com.android.connectivitymanagertest"
-  android:sharedUserId="com.android.uid.test">
+  android:sharedUserId="android.uid.system">
 
     <!-- We add an application tag here just so that we can indicate that
          this package needs to link against the android.test library,
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java
index 245f537..463e999 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java
@@ -60,13 +60,14 @@
 
     public static final String LOG_TAG = "ConnectivityManagerTestActivity";
     public static final int WAIT_FOR_SCAN_RESULT = 10 * 1000; //10 seconds
-    public static final int WIFI_SCAN_TIMEOUT = 50 * 1000;
-    public static final int SHORT_TIMEOUT = 5 * 1000;
-    public static final long LONG_TIMEOUT = 50 * 1000;
+    public static final int WIFI_SCAN_TIMEOUT = 50 * 1000; // 50 seconds
+    public static final int SHORT_TIMEOUT = 5 * 1000; // 5 seconds
+    public static final long LONG_TIMEOUT = 50 * 1000;  // 50 seconds
+    public static final long WIFI_CONNECTION_TIMEOUT = 5 * 60 * 1000; // 5 minutes
     // 2 minutes timer between wifi stop and start
-    public static final long  WIFI_STOP_START_INTERVAL = 2 * 60 * 1000;
+    public static final long  WIFI_STOP_START_INTERVAL = 2 * 60 * 1000; // 2 minutes
     // Set ping test timer to be 3 minutes
-    public static final long PING_TIMER = 3 * 60 *1000;
+    public static final long PING_TIMER = 3 * 60 *1000; // 3 minutes
     public static final int SUCCESS = 0;  // for Wifi tethering state change
     public static final int FAILURE = 1;
     public static final int INIT = -1;
@@ -573,7 +574,7 @@
         String ssid = config.SSID;
         config.SSID = convertToQuotedString(ssid);
 
-        //If Wifi is not enabled, enable it
+        // If Wifi is not enabled, enable it
         if (!mWifiManager.isWifiEnabled()) {
             log("Wifi is not enabled, enable it");
             mWifiManager.setWifiEnabled(true);
@@ -584,59 +585,16 @@
             }
         }
 
-        boolean foundApInScanResults = false;
-        for (int retry = 0; retry < 5; retry++) {
-            List<ScanResult> netList = mWifiManager.getScanResults();
-            if (netList != null) {
-                log("size of scan result list: " + netList.size());
-                for (int i = 0; i < netList.size(); i++) {
-                    ScanResult sr= netList.get(i);
-                    if (sr.SSID.equals(ssid)) {
-                        log("found " + ssid + " in the scan result list");
-                        log("retry: " + retry);
-                        foundApInScanResults = true;
-                        mWifiManager.connect(config,
-                                new WifiManager.ActionListener() {
-                                    public void onSuccess() {
-                                    }
-                                    public void onFailure(int reason) {
-                                        log("connect failure " + reason);
-                                    }
-                                });
-                        break;
-                   }
+        // Save network configuration and connect to network without scanning
+        mWifiManager.connect(config,
+            new WifiManager.ActionListener() {
+                public void onSuccess() {
                 }
-            }
-            if (foundApInScanResults) {
-                return true;
-            } else {
-                // Start an active scan
-                mWifiManager.startScanActive();
-                mScanResultIsAvailable = false;
-                long startTime = System.currentTimeMillis();
-                while (!mScanResultIsAvailable) {
-                    if ((System.currentTimeMillis() - startTime) > WIFI_SCAN_TIMEOUT) {
-                        log("wait for scan results timeout");
-                        return false;
-                    }
-                    // wait for the scan results to be available
-                    synchronized (this) {
-                        // wait for the scan result to be available
-                        try {
-                            this.wait(WAIT_FOR_SCAN_RESULT);
-                        } catch (InterruptedException e) {
-                            e.printStackTrace();
-                        }
-                        if ((mWifiManager.getScanResults() == null) ||
-                                (mWifiManager.getScanResults().size() <= 0)) {
-                            continue;
-                        }
-                        mScanResultIsAvailable = true;
-                    }
+                public void onFailure(int reason) {
+                    log("connect failure " + reason);
                 }
-            }
-        }
-        return false;
+            });
+        return true;
     }
 
     /*
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java
index 7928822..3111489 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java
@@ -126,7 +126,7 @@
         cmActivity.disableWifi();
 
         assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_WIFI,
-                State.DISCONNECTED, ConnectivityManagerTestActivity.LONG_TIMEOUT));
+                State.DISCONNECTED,  ConnectivityManagerTestActivity.LONG_TIMEOUT));
         assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_MOBILE,
                 State.CONNECTED, ConnectivityManagerTestActivity.LONG_TIMEOUT));
         // Wait for 10 seconds for broadcasts to be sent out
@@ -184,7 +184,7 @@
                 ConnectivityManagerTestActivity.LONG_TIMEOUT));
         log("wifi state is enabled");
         assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
-                ConnectivityManagerTestActivity.LONG_TIMEOUT));
+                ConnectivityManagerTestActivity.WIFI_CONNECTION_TIMEOUT));
         if (!mWifiOnlyFlag) {
             assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_MOBILE,
                     State.DISCONNECTED, ConnectivityManagerTestActivity.LONG_TIMEOUT));
@@ -217,7 +217,7 @@
         assertTrue(cmActivity.waitForWifiState(WifiManager.WIFI_STATE_ENABLED,
                 ConnectivityManagerTestActivity.LONG_TIMEOUT));
         assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
-                ConnectivityManagerTestActivity.LONG_TIMEOUT));
+                ConnectivityManagerTestActivity.WIFI_CONNECTION_TIMEOUT));
 
         sleep(ConnectivityManagerTestActivity.SHORT_TIMEOUT);
         // Disable Wifi
@@ -257,7 +257,7 @@
 
         // Wait for Wifi to be connected and mobile to be disconnected
         assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
-                ConnectivityManagerTestActivity.LONG_TIMEOUT));
+                ConnectivityManagerTestActivity.WIFI_CONNECTION_TIMEOUT));
         if (!mWifiOnlyFlag) {
             assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_MOBILE,
                     State.DISCONNECTED, ConnectivityManagerTestActivity.LONG_TIMEOUT));
@@ -279,10 +279,10 @@
 
         // connect to Wifi
         assertTrue("failed to connect to " + mTestAccessPoint,
-                   cmActivity.connectToWifi(mTestAccessPoint));
+                cmActivity.connectToWifi(mTestAccessPoint));
 
         assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
-            ConnectivityManagerTestActivity.LONG_TIMEOUT));
+                ConnectivityManagerTestActivity.WIFI_CONNECTION_TIMEOUT));
 
         // Wait for a few seconds to avoid the state that both Mobile and Wifi is connected
         sleep(ConnectivityManagerTestActivity.SHORT_TIMEOUT);
@@ -418,9 +418,9 @@
 
         // Connect to Wifi
         assertTrue("failed to connect to " + mTestAccessPoint,
-                   cmActivity.connectToWifi(mTestAccessPoint));
+                cmActivity.connectToWifi(mTestAccessPoint));
         assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
-                            ConnectivityManagerTestActivity.LONG_TIMEOUT));
+                ConnectivityManagerTestActivity.WIFI_CONNECTION_TIMEOUT));
 
         // validate state and broadcast
         if (!cmActivity.validateNetworkStates(ConnectivityManager.TYPE_WIFI)) {
@@ -454,7 +454,7 @@
                 cmActivity.connectToWifi(mTestAccessPoint));
 
         assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
-                ConnectivityManagerTestActivity.LONG_TIMEOUT));
+                ConnectivityManagerTestActivity.WIFI_CONNECTION_TIMEOUT));
 
         try {
             Thread.sleep(ConnectivityManagerTestActivity.SHORT_TIMEOUT);
@@ -484,7 +484,7 @@
         cmActivity.setAirplaneMode(getInstrumentation().getContext(), false);
 
         assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
-                            ConnectivityManagerTestActivity.LONG_TIMEOUT));
+                ConnectivityManagerTestActivity.WIFI_CONNECTION_TIMEOUT));
         if (!mWifiOnlyFlag) {
             assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_MOBILE,
                     State.DISCONNECTED, ConnectivityManagerTestActivity.LONG_TIMEOUT));
@@ -505,11 +505,11 @@
         assertNotNull("SSID is null", mTestAccessPoint);
         //Connect to mTestAccessPoint
         assertTrue("failed to connect to " + mTestAccessPoint,
-                   cmActivity.connectToWifi(mTestAccessPoint));
+                cmActivity.connectToWifi(mTestAccessPoint));
         assertTrue(cmActivity.waitForWifiState(WifiManager.WIFI_STATE_ENABLED,
                 ConnectivityManagerTestActivity.LONG_TIMEOUT));
         assertTrue(cmActivity.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
-                            ConnectivityManagerTestActivity.LONG_TIMEOUT));
+                ConnectivityManagerTestActivity.WIFI_CONNECTION_TIMEOUT));
         assertNotNull("Not associated with any AP",
                       cmActivity.mWifiManager.getConnectionInfo().getBSSID());
 
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/WifiConnectionTest.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/WifiConnectionTest.java
index 81075ef..de0298e 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/WifiConnectionTest.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/WifiConnectionTest.java
@@ -118,7 +118,7 @@
 
         // step 2: verify Wifi state and network state;
         assertTrue(mAct.waitForNetworkState(ConnectivityManager.TYPE_WIFI,
-                State.CONNECTED, 6 * ConnectivityManagerTestActivity.LONG_TIMEOUT));
+                State.CONNECTED, ConnectivityManagerTestActivity.WIFI_CONNECTION_TIMEOUT));
 
         // step 3: verify the current connected network is the given SSID
         assertNotNull("Wifi connection returns null", mAct.mWifiManager.getConnectionInfo());
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java
index 7bfb594..53876a5 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java
@@ -248,7 +248,7 @@
         assertTrue(mAct.waitForWifiState(WifiManager.WIFI_STATE_ENABLED,
                 ConnectivityManagerTestActivity.SHORT_TIMEOUT));
         assertTrue(mAct.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
-                ConnectivityManagerTestActivity.LONG_TIMEOUT));
+                ConnectivityManagerTestActivity.WIFI_CONNECTION_TIMEOUT));
         // Run ping test to verify the data connection
         assertTrue("Wi-Fi is connected, but no data connection.", mAct.pingTest(null));
 
@@ -302,7 +302,7 @@
                     ConnectivityManagerTestActivity.SHORT_TIMEOUT));
             assertTrue("Wait for Wi-Fi connection timeout after wake up",
                     mAct.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
-                    6 * ConnectivityManagerTestActivity.LONG_TIMEOUT));
+                    ConnectivityManagerTestActivity.WIFI_CONNECTION_TIMEOUT));
             long connectionTime = System.currentTimeMillis() - startTime;
             sum += connectionTime;
             log("average reconnection time is: " + sum/(i+1));
diff --git a/core/tests/coretests/src/com/android/internal/util/FastXmlSerializerTest.java b/core/tests/coretests/src/com/android/internal/util/FastXmlSerializerTest.java
new file mode 100644
index 0000000..be7116d
--- /dev/null
+++ b/core/tests/coretests/src/com/android/internal/util/FastXmlSerializerTest.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.util;
+
+import junit.framework.TestCase;
+
+import org.xmlpull.v1.XmlSerializer;
+
+import java.io.ByteArrayOutputStream;
+
+/**
+ * Tests for {@link FastXmlSerializer}
+ */
+public class FastXmlSerializerTest extends TestCase {
+    public void testEmptyText() throws Exception {
+        final ByteArrayOutputStream stream = new ByteArrayOutputStream();
+
+        final XmlSerializer out = new FastXmlSerializer();
+        out.setOutput(stream, "utf-8");
+        out.startDocument(null, true);
+        out.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
+
+        out.startTag(null, "string");
+        out.attribute(null, "name", "meow");
+        out.text("");
+        out.endTag(null, "string");
+
+        out.endDocument();
+
+        assertEquals("<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n"
+                + "<string name=\"meow\"></string>", stream.toString());
+    }
+}
diff --git a/core/tests/coretests/src/com/android/internal/util/IndentingPrintWriterTest.java b/core/tests/coretests/src/com/android/internal/util/IndentingPrintWriterTest.java
new file mode 100644
index 0000000..6773612
--- /dev/null
+++ b/core/tests/coretests/src/com/android/internal/util/IndentingPrintWriterTest.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.util;
+
+import junit.framework.TestCase;
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintWriter;
+
+/**
+ * Tests for {@link IndentingPrintWriter}.
+ */
+public class IndentingPrintWriterTest extends TestCase {
+
+    private ByteArrayOutputStream mStream;
+    private PrintWriter mWriter;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        mStream = new ByteArrayOutputStream();
+        mWriter = new PrintWriter(mStream);
+    }
+
+    public void testMultipleIndents() throws Exception {
+        final IndentingPrintWriter pw = new IndentingPrintWriter(mWriter, "  ");
+
+        pw.print("Hello");
+        pw.increaseIndent();
+        pw.println();
+        pw.print("World");
+        pw.increaseIndent();
+        pw.println();
+        pw.print("And");
+        pw.decreaseIndent();
+        pw.println();
+        pw.print("Goodbye");
+        pw.decreaseIndent();
+        pw.println();
+        pw.print("World");
+        pw.println();
+
+        pw.flush();
+        assertEquals("Hello\n  World\n    And\n  Goodbye\nWorld\n", mStream.toString());
+    }
+
+    public void testAdjustIndentAfterNewline() throws Exception {
+        final IndentingPrintWriter pw = new IndentingPrintWriter(mWriter, "  ");
+
+        pw.println("Hello");
+        pw.increaseIndent();
+        pw.println("World");
+
+        pw.flush();
+        assertEquals("Hello\n  World\n", mStream.toString());
+    }
+
+    public void testWrapping() throws Exception {
+        final IndentingPrintWriter pw = new IndentingPrintWriter(mWriter, "", 10);
+
+        pw.print("dog ");
+        pw.print("cat ");
+        pw.print("cow ");
+        pw.print("meow ");
+
+        pw.flush();
+        assertEquals("dog cat \ncow meow ", mStream.toString());
+    }
+
+    public void testWrappingIndented() throws Exception {
+        final IndentingPrintWriter pw = new IndentingPrintWriter(mWriter, "    ", 10);
+
+        pw.increaseIndent();
+        pw.print("dog ");
+        pw.print("meow ");
+        pw.print("a ");
+        pw.print("b ");
+        pw.print("cow ");
+
+        pw.flush();
+        assertEquals("    dog \n    meow \n    a b \n    cow ", mStream.toString());
+    }
+
+    public void testWrappingEmbeddedNewlines() throws Exception {
+        final IndentingPrintWriter pw = new IndentingPrintWriter(mWriter, "  ", 10);
+
+        pw.increaseIndent();
+        pw.print("Lorem ipsum \ndolor sit \namet, consectetur \nadipiscing elit.");
+
+        pw.flush();
+        assertEquals("  Lorem ip\n  sum \n  dolor si\n  t \n  amet, co\n"
+                + "  nsectetu\n  r \n  adipisci\n  ng elit.\n", mStream.toString());
+    }
+
+    public void testWrappingSingleGiant() throws Exception {
+        final IndentingPrintWriter pw = new IndentingPrintWriter(mWriter, "  ", 10);
+
+        pw.increaseIndent();
+        pw.print("Lorem ipsum dolor sit amet, consectetur adipiscing elit.");
+
+        pw.flush();
+        assertEquals("  Lorem ip\n  sum dolo\n  r sit am\n  et, cons\n"
+                + "  ectetur \n  adipisci\n  ng elit.\n", mStream.toString());
+    }
+
+    public void testWrappingPrefixedGiant() throws Exception {
+        final IndentingPrintWriter pw = new IndentingPrintWriter(mWriter, "  ", 10);
+
+        pw.increaseIndent();
+        pw.print("foo");
+        pw.print("Lorem ipsum dolor sit amet, consectetur adipiscing elit.");
+
+        pw.flush();
+        assertEquals("  foo\n  Lorem ip\n  sum dolo\n  r sit am\n  et, cons\n"
+                + "  ectetur \n  adipisci\n  ng elit.\n", mStream.toString());
+    }
+}
diff --git a/core/tests/coretests/src/com/android/internal/util/ProcFileReaderTest.java b/core/tests/coretests/src/com/android/internal/util/ProcFileReaderTest.java
index 386a78d..a81bb4b 100644
--- a/core/tests/coretests/src/com/android/internal/util/ProcFileReaderTest.java
+++ b/core/tests/coretests/src/com/android/internal/util/ProcFileReaderTest.java
@@ -134,7 +134,7 @@
             fail("somehow read a string value?");
         } catch (IOException e) {
             // expected
-            assertTrue(e.getMessage().contains("end of stream"));
+            assertTrue(e.getMessage().contains("End of stream"));
         }
     }
 
@@ -152,6 +152,20 @@
         }
     }
 
+    public void testOptionalLongs() throws Exception {
+        final ProcFileReader reader = buildReader("123 456\n789\n");
+
+        assertEquals(123L, reader.nextLong());
+        assertEquals(456L, reader.nextOptionalLong(-1L));
+        assertEquals(-1L, reader.nextOptionalLong(-1L));
+        assertEquals(-1L, reader.nextOptionalLong(-1L));
+        assertEquals(-1L, reader.nextOptionalLong(-1L));
+        reader.finishLine();
+
+        assertEquals(789L, reader.nextOptionalLong(-1L));
+        assertEquals(-1L, reader.nextOptionalLong(-1L));
+    }
+
     private static ProcFileReader buildReader(String string) throws IOException {
         return buildReader(string, 2048);
     }
diff --git a/core/tests/coretests/src/com/android/internal/util/StateMachineTest.java b/core/tests/coretests/src/com/android/internal/util/StateMachineTest.java
index 418bbd6..2a2c24e 100644
--- a/core/tests/coretests/src/com/android/internal/util/StateMachineTest.java
+++ b/core/tests/coretests/src/com/android/internal/util/StateMachineTest.java
@@ -16,6 +16,9 @@
 
 package com.android.internal.util;
 
+import java.util.Collection;
+import java.util.Iterator;
+
 import android.os.Debug;
 import android.os.HandlerThread;
 import android.os.Looper;
@@ -58,11 +61,28 @@
         }
     }
 
+    private void dumpLogRecs(StateMachine sm) {
+        int size = sm.getLogRecSize();
+        tlog("size=" + size + " count=" + sm.getLogRecCount());
+        for (int i = 0; i < size; i++) {
+            LogRec lr = sm.getLogRec(i);
+            tlog(lr.toString());
+        }
+    }
+
+    private void dumpLogRecs(Collection<LogRec> clr) {
+        int size = clr.size();
+        tlog("size=" + size);
+        for (LogRec lr : clr) {
+            tlog(lr.toString());
+        }
+    }
+
     /**
      * Tests {@link StateMachine#quit()}.
      */
     class StateMachineQuitTest extends StateMachine {
-        Object mWaitUntilTestDone = new Object();
+        Collection<LogRec> mLogRecs;
 
         StateMachineQuitTest(String name) {
             super(name);
@@ -78,39 +98,32 @@
 
         @Override
         public void onQuitting() {
-            Log.d(TAG, "onQuitting");
+            log("onQuitting");
             addLogRec(ON_QUITTING);
+            mLogRecs = mThisSm.copyLogRecs();
             synchronized (mThisSm) {
                 mThisSm.notifyAll();
             }
-
-            // Don't leave onQuitting before the test is done as everything is cleared
-            // including the log records.
-            synchronized (mWaitUntilTestDone) {
-                try {
-                    mWaitUntilTestDone.wait();
-                } catch(InterruptedException e) {
-                }
-            }
         }
 
         class S1 extends State {
+            @Override
             public void exit() {
-                Log.d(TAG, "S1.exit");
-                addLogRec(EXIT, mS1);
+                log("S1.exit");
+                addLogRec(EXIT);
             }
             @Override
             public boolean processMessage(Message message) {
                 switch(message.what) {
                     // Sleep and assume the other messages will be queued up.
                     case TEST_CMD_1: {
-                        Log.d(TAG, "TEST_CMD_1");
+                        log("TEST_CMD_1");
                         sleep(500);
                         quit();
                         break;
                     }
                     default: {
-                        Log.d(TAG, "default what=" + message.what);
+                        log("default what=" + message.what);
                         break;
                     }
                 }
@@ -128,7 +141,7 @@
 
         StateMachineQuitTest smQuitTest = new StateMachineQuitTest("smQuitTest");
         smQuitTest.start();
-        if (smQuitTest.isDbg()) Log.d(TAG, "testStateMachineQuit E");
+        if (smQuitTest.isDbg()) tlog("testStateMachineQuit E");
 
         synchronized (smQuitTest) {
 
@@ -141,38 +154,36 @@
                 // wait for the messages to be handled
                 smQuitTest.wait();
             } catch (InterruptedException e) {
-                Log.e(TAG, "testStateMachineQuit: exception while waiting " + e.getMessage());
+                tloge("testStateMachineQuit: exception while waiting " + e.getMessage());
             }
         }
 
-        assertEquals(8, smQuitTest.getLogRecCount());
+        dumpLogRecs(smQuitTest.mLogRecs);
+        assertEquals(8, smQuitTest.mLogRecs.size());
 
         LogRec lr;
-
-        for (int i = 0; i < 6; i++) {
-            lr = smQuitTest.getLogRec(i);
-            assertEquals(i+1, lr.getWhat());
+        Iterator<LogRec> itr = smQuitTest.mLogRecs.iterator();
+        for (int i = 1; i <= 6; i++) {
+            lr = itr.next();
+            assertEquals(i, lr.getWhat());
             assertEquals(smQuitTest.mS1, lr.getState());
             assertEquals(smQuitTest.mS1, lr.getOriginalState());
         }
-        lr = smQuitTest.getLogRec(6);
+        lr = itr.next();
         assertEquals(EXIT, lr.getInfo());
         assertEquals(smQuitTest.mS1, lr.getState());
 
-        lr = smQuitTest.getLogRec(7);
+        lr = itr.next();
         assertEquals(ON_QUITTING, lr.getInfo());
 
-        synchronized (smQuitTest.mWaitUntilTestDone) {
-            smQuitTest.mWaitUntilTestDone.notifyAll();
-        }
-        if (smQuitTest.isDbg()) Log.d(TAG, "testStateMachineQuit X");
+        if (smQuitTest.isDbg()) tlog("testStateMachineQuit X");
     }
 
     /**
      * Tests {@link StateMachine#quitNow()}
      */
     class StateMachineQuitNowTest extends StateMachine {
-        Object mWaitUntilTestDone = new Object();
+        public Collection<LogRec> mLogRecs = null;
 
         StateMachineQuitNowTest(String name) {
             super(name);
@@ -188,39 +199,34 @@
 
         @Override
         public void onQuitting() {
-            Log.d(TAG, "onQuitting");
+            log("onQuitting");
             addLogRec(ON_QUITTING);
+            // Get a copy of the log records since we're quitting and they will disappear
+            mLogRecs = mThisSm.copyLogRecs();
+
             synchronized (mThisSm) {
                 mThisSm.notifyAll();
             }
-
-            // Don't leave onQuitting before the test is done as everything is cleared
-            // including the log records.
-            synchronized (mWaitUntilTestDone) {
-                try {
-                    mWaitUntilTestDone.wait();
-                } catch(InterruptedException e) {
-                }
-            }
         }
 
         class S1 extends State {
+            @Override
             public void exit() {
-                Log.d(TAG, "S1.exit");
-                addLogRec(EXIT, mS1);
+                log("S1.exit");
+                addLogRec(EXIT);
             }
             @Override
             public boolean processMessage(Message message) {
                 switch(message.what) {
                     // Sleep and assume the other messages will be queued up.
                     case TEST_CMD_1: {
-                        Log.d(TAG, "TEST_CMD_1");
+                        log("TEST_CMD_1");
                         sleep(500);
                         quitNow();
                         break;
                     }
                     default: {
-                        Log.d(TAG, "default what=" + message.what);
+                        log("default what=" + message.what);
                         break;
                     }
                 }
@@ -238,11 +244,11 @@
 
         StateMachineQuitNowTest smQuitNowTest = new StateMachineQuitNowTest("smQuitNowTest");
         smQuitNowTest.start();
-        if (smQuitNowTest.isDbg()) Log.d(TAG, "testStateMachineQuitNow E");
+        if (smQuitNowTest.isDbg()) tlog("testStateMachineQuitNow E");
 
         synchronized (smQuitNowTest) {
 
-            // Send 6 messages but we'll QuitNow on the first so even though
+            // Send 6 message we'll QuitNow on the first even though
             // we send 6 only one will be processed.
             for (int i = 1; i <= 6; i++) {
                 smQuitNowTest.sendMessage(smQuitNowTest.obtainMessage(i));
@@ -252,31 +258,27 @@
                 // wait for the messages to be handled
                 smQuitNowTest.wait();
             } catch (InterruptedException e) {
-                Log.e(TAG, "testStateMachineQuitNow: exception while waiting " + e.getMessage());
+                tloge("testStateMachineQuitNow: exception while waiting " + e.getMessage());
             }
         }
 
-        // Only three records because we executed quitNow.
-        assertEquals(3, smQuitNowTest.getLogRecCount());
+        tlog("testStateMachineQuiteNow: logRecs=" + smQuitNowTest.mLogRecs);
+        assertEquals(3, smQuitNowTest.mLogRecs.size());
 
-        LogRec lr;
-
-        lr = smQuitNowTest.getLogRec(0);
+        Iterator<LogRec> itr = smQuitNowTest.mLogRecs.iterator();
+        LogRec lr = itr.next();
         assertEquals(1, lr.getWhat());
         assertEquals(smQuitNowTest.mS1, lr.getState());
         assertEquals(smQuitNowTest.mS1, lr.getOriginalState());
 
-        lr = smQuitNowTest.getLogRec(1);
+        lr = itr.next();
         assertEquals(EXIT, lr.getInfo());
         assertEquals(smQuitNowTest.mS1, lr.getState());
 
-        lr = smQuitNowTest.getLogRec(2);
+        lr = itr.next();
         assertEquals(ON_QUITTING, lr.getInfo());
 
-        synchronized (smQuitNowTest.mWaitUntilTestDone) {
-            smQuitNowTest.mWaitUntilTestDone.notifyAll();
-        }
-        if (smQuitNowTest.isDbg()) Log.d(TAG, "testStateMachineQuitNow X");
+        if (smQuitNowTest.isDbg()) tlog("testStateMachineQuitNow X");
     }
 
     /**
@@ -303,39 +305,39 @@
             @Override
             public void enter() {
                 // Test transitions in enter on the initial state work
-                addLogRec(ENTER, mS1);
+                addLogRec(ENTER);
                 transitionTo(mS2);
-                Log.d(TAG, "S1.enter");
+                log("S1.enter");
             }
             @Override
             public void exit() {
-                // Test that message is HSM_INIT_CMD
-                addLogRec(EXIT, mS1);
-                Log.d(TAG, "S1.exit");
+                addLogRec(EXIT);
+                log("S1.exit");
             }
         }
 
         class S2 extends State {
             @Override
             public void enter() {
-                addLogRec(ENTER, mS2);
-                Log.d(TAG, "S2.enter");
+                addLogRec(ENTER);
+                log("S2.enter");
             }
             @Override
             public void exit() {
-                addLogRec(EXIT, mS2);
-                assertEquals(TEST_CMD_1, getCurrentMessage().what);
-
                 // Test transition in exit work
                 transitionTo(mS4);
-                Log.d(TAG, "S2.exit");
+
+                assertEquals(TEST_CMD_1, getCurrentMessage().what);
+                addLogRec(EXIT);
+
+                log("S2.exit");
             }
             @Override
             public boolean processMessage(Message message) {
                 // Start a transition to S3 but it will be
                 // changed to a transition to S4 in exit
                 transitionTo(mS3);
-                Log.d(TAG, "S2.processMessage");
+                log("S2.processMessage");
                 return HANDLED;
             }
         }
@@ -343,28 +345,28 @@
         class S3 extends State {
             @Override
             public void enter() {
-                addLogRec(ENTER, mS3);
-                Log.d(TAG, "S3.enter");
+                addLogRec(ENTER);
+                log("S3.enter");
             }
             @Override
             public void exit() {
-                addLogRec(EXIT, mS3);
-                Log.d(TAG, "S3.exit");
+                addLogRec(EXIT);
+                log("S3.exit");
             }
         }
 
         class S4 extends State {
             @Override
             public void enter() {
-                addLogRec(ENTER, mS4);
+                addLogRec(ENTER);
                 // Test that we can do halting in an enter/exit
                 transitionToHaltingState();
-                Log.d(TAG, "S4.enter");
+                log("S4.enter");
             }
             @Override
             public void exit() {
-                addLogRec(EXIT, mS4);
-                Log.d(TAG, "S4.exit");
+                addLogRec(EXIT);
+                log("S4.exit");
             }
         }
 
@@ -390,7 +392,7 @@
             new StateMachineEnterExitTransitionToTest("smEnterExitTranstionToTest");
         smEnterExitTranstionToTest.start();
         if (smEnterExitTranstionToTest.isDbg()) {
-            Log.d(TAG, "testStateMachineEnterExitTransitionToTest E");
+            tlog("testStateMachineEnterExitTransitionToTest E");
         }
 
         synchronized (smEnterExitTranstionToTest) {
@@ -400,13 +402,14 @@
                 // wait for the messages to be handled
                 smEnterExitTranstionToTest.wait();
             } catch (InterruptedException e) {
-                Log.e(TAG, "testStateMachineEnterExitTransitionToTest: exception while waiting "
+                tloge("testStateMachineEnterExitTransitionToTest: exception while waiting "
                     + e.getMessage());
             }
         }
 
-        assertEquals(smEnterExitTranstionToTest.getLogRecCount(), 9);
+        dumpLogRecs(smEnterExitTranstionToTest);
 
+        assertEquals(9, smEnterExitTranstionToTest.getLogRecCount());
         LogRec lr;
 
         lr = smEnterExitTranstionToTest.getLogRec(0);
@@ -425,29 +428,44 @@
         assertEquals(TEST_CMD_1, lr.getWhat());
         assertEquals(smEnterExitTranstionToTest.mS2, lr.getState());
         assertEquals(smEnterExitTranstionToTest.mS2, lr.getOriginalState());
+        assertEquals(smEnterExitTranstionToTest.mS3, lr.getDestState());
 
         lr = smEnterExitTranstionToTest.getLogRec(4);
-        assertEquals(EXIT, lr.getInfo());
+        assertEquals(TEST_CMD_1, lr.getWhat());
         assertEquals(smEnterExitTranstionToTest.mS2, lr.getState());
+        assertEquals(smEnterExitTranstionToTest.mS2, lr.getOriginalState());
+        assertEquals(smEnterExitTranstionToTest.mS4, lr.getDestState());
+        assertEquals(EXIT, lr.getInfo());
 
         lr = smEnterExitTranstionToTest.getLogRec(5);
+        assertEquals(TEST_CMD_1, lr.getWhat());
         assertEquals(ENTER, lr.getInfo());
         assertEquals(smEnterExitTranstionToTest.mS3, lr.getState());
+        assertEquals(smEnterExitTranstionToTest.mS3, lr.getOriginalState());
+        assertEquals(smEnterExitTranstionToTest.mS4, lr.getDestState());
 
         lr = smEnterExitTranstionToTest.getLogRec(6);
+        assertEquals(TEST_CMD_1, lr.getWhat());
         assertEquals(EXIT, lr.getInfo());
         assertEquals(smEnterExitTranstionToTest.mS3, lr.getState());
+        assertEquals(smEnterExitTranstionToTest.mS3, lr.getOriginalState());
+        assertEquals(smEnterExitTranstionToTest.mS4, lr.getDestState());
 
         lr = smEnterExitTranstionToTest.getLogRec(7);
+        assertEquals(TEST_CMD_1, lr.getWhat());
         assertEquals(ENTER, lr.getInfo());
         assertEquals(smEnterExitTranstionToTest.mS4, lr.getState());
+        assertEquals(smEnterExitTranstionToTest.mS4, lr.getOriginalState());
+        assertEquals(smEnterExitTranstionToTest.mS4, lr.getDestState());
 
         lr = smEnterExitTranstionToTest.getLogRec(8);
+        assertEquals(TEST_CMD_1, lr.getWhat());
         assertEquals(EXIT, lr.getInfo());
         assertEquals(smEnterExitTranstionToTest.mS4, lr.getState());
+        assertEquals(smEnterExitTranstionToTest.mS4, lr.getOriginalState());
 
         if (smEnterExitTranstionToTest.isDbg()) {
-            Log.d(TAG, "testStateMachineEnterExitTransitionToTest X");
+            tlog("testStateMachineEnterExitTransitionToTest X");
         }
     }
 
@@ -495,7 +513,7 @@
 
         StateMachine0 sm0 = new StateMachine0("sm0");
         sm0.start();
-        if (sm0.isDbg()) Log.d(TAG, "testStateMachine0 E");
+        if (sm0.isDbg()) tlog("testStateMachine0 E");
 
         synchronized (sm0) {
             // Send 6 messages
@@ -507,13 +525,15 @@
                 // wait for the messages to be handled
                 sm0.wait();
             } catch (InterruptedException e) {
-                Log.e(TAG, "testStateMachine0: exception while waiting " + e.getMessage());
+                tloge("testStateMachine0: exception while waiting " + e.getMessage());
             }
         }
 
         assertEquals(6, sm0.getLogRecCount());
         assertEquals(3, sm0.getLogRecSize());
 
+        dumpLogRecs(sm0);
+
         LogRec lr;
         lr = sm0.getLogRec(0);
         assertEquals(TEST_CMD_4, lr.getWhat());
@@ -530,7 +550,7 @@
         assertEquals(sm0.mS1, lr.getState());
         assertEquals(sm0.mS1, lr.getOriginalState());
 
-        if (sm0.isDbg()) Log.d(TAG, "testStateMachine0 X");
+        if (sm0.isDbg()) tlog("testStateMachine0 X");
     }
 
     /**
@@ -550,7 +570,7 @@
 
             // Set the initial state
             setInitialState(mS1);
-            if (DBG) Log.d(TAG, "StateMachine1: ctor X");
+            if (DBG) log("StateMachine1: ctor X");
         }
 
         class S1 extends State {
@@ -595,7 +615,7 @@
     public void testStateMachine1() throws Exception {
         StateMachine1 sm1 = new StateMachine1("sm1");
         sm1.start();
-        if (sm1.isDbg()) Log.d(TAG, "testStateMachine1 E");
+        if (sm1.isDbg()) tlog("testStateMachine1 E");
 
         synchronized (sm1) {
             // Send two messages
@@ -606,7 +626,7 @@
                 // wait for the messages to be handled
                 sm1.wait();
             } catch (InterruptedException e) {
-                Log.e(TAG, "testStateMachine1: exception while waiting " + e.getMessage());
+                tloge("testStateMachine1: exception while waiting " + e.getMessage());
             }
         }
 
@@ -629,7 +649,7 @@
         assertEquals(2, sm1.mEnterCount);
         assertEquals(2, sm1.mExitCount);
 
-        if (sm1.isDbg()) Log.d(TAG, "testStateMachine1 X");
+        if (sm1.isDbg()) tlog("testStateMachine1 X");
     }
 
     /**
@@ -651,7 +671,7 @@
 
             // Set the initial state
             setInitialState(mS1);
-            if (DBG) Log.d(TAG, "StateMachine2: ctor X");
+            if (DBG) log("StateMachine2: ctor X");
         }
 
         class S1 extends State {
@@ -702,7 +722,7 @@
     public void testStateMachine2() throws Exception {
         StateMachine2 sm2 = new StateMachine2("sm2");
         sm2.start();
-        if (sm2.isDbg()) Log.d(TAG, "testStateMachine2 E");
+        if (sm2.isDbg()) tlog("testStateMachine2 E");
 
         synchronized (sm2) {
             // Send two messages
@@ -713,7 +733,7 @@
                 // wait for the messages to be handled
                 sm2.wait();
             } catch (InterruptedException e) {
-                Log.e(TAG, "testStateMachine2: exception while waiting " + e.getMessage());
+                tloge("testStateMachine2: exception while waiting " + e.getMessage());
             }
         }
 
@@ -739,7 +759,7 @@
         assertTrue(sm2.mDidEnter);
         assertTrue(sm2.mDidExit);
 
-        if (sm2.isDbg()) Log.d(TAG, "testStateMachine2 X");
+        if (sm2.isDbg()) tlog("testStateMachine2 X");
     }
 
     /**
@@ -760,7 +780,7 @@
 
             // Set the initial state will be the child
             setInitialState(mChildState);
-            if (DBG) Log.d(TAG, "StateMachine3: ctor X");
+            if (DBG) log("StateMachine3: ctor X");
         }
 
         class ParentState extends State {
@@ -796,7 +816,7 @@
     public void testStateMachine3() throws Exception {
         StateMachine3 sm3 = new StateMachine3("sm3");
         sm3.start();
-        if (sm3.isDbg()) Log.d(TAG, "testStateMachine3 E");
+        if (sm3.isDbg()) tlog("testStateMachine3 E");
 
         synchronized (sm3) {
             // Send two messages
@@ -807,7 +827,7 @@
                 // wait for the messages to be handled
                 sm3.wait();
             } catch (InterruptedException e) {
-                Log.e(TAG, "testStateMachine3: exception while waiting " + e.getMessage());
+                tloge("testStateMachine3: exception while waiting " + e.getMessage());
             }
         }
 
@@ -824,7 +844,7 @@
         assertEquals(sm3.mParentState, lr.getState());
         assertEquals(sm3.mChildState, lr.getOriginalState());
 
-        if (sm3.isDbg()) Log.d(TAG, "testStateMachine3 X");
+        if (sm3.isDbg()) tlog("testStateMachine3 X");
     }
 
     /**
@@ -847,7 +867,7 @@
 
             // Set the initial state will be child 1
             setInitialState(mChildState1);
-            if (DBG) Log.d(TAG, "StateMachine4: ctor X");
+            if (DBG) log("StateMachine4: ctor X");
         }
 
         class ParentState extends State {
@@ -892,7 +912,7 @@
     public void testStateMachine4() throws Exception {
         StateMachine4 sm4 = new StateMachine4("sm4");
         sm4.start();
-        if (sm4.isDbg()) Log.d(TAG, "testStateMachine4 E");
+        if (sm4.isDbg()) tlog("testStateMachine4 E");
 
         synchronized (sm4) {
             // Send two messages
@@ -903,7 +923,7 @@
                 // wait for the messages to be handled
                 sm4.wait();
             } catch (InterruptedException e) {
-                Log.e(TAG, "testStateMachine4: exception while waiting " + e.getMessage());
+                tloge("testStateMachine4: exception while waiting " + e.getMessage());
             }
         }
 
@@ -921,7 +941,7 @@
         assertEquals(sm4.mParentState, lr.getState());
         assertEquals(sm4.mChildState2, lr.getOriginalState());
 
-        if (sm4.isDbg()) Log.d(TAG, "testStateMachine4 X");
+        if (sm4.isDbg()) tlog("testStateMachine4 X");
     }
 
     /**
@@ -947,7 +967,7 @@
 
             // Set the initial state will be the child
             setInitialState(mChildState1);
-            if (DBG) Log.d(TAG, "StateMachine5: ctor X");
+            if (DBG) log("StateMachine5: ctor X");
         }
 
         class ParentState1 extends State {
@@ -1187,7 +1207,7 @@
     public void testStateMachine5() throws Exception {
         StateMachine5 sm5 = new StateMachine5("sm5");
         sm5.start();
-        if (sm5.isDbg()) Log.d(TAG, "testStateMachine5 E");
+        if (sm5.isDbg()) tlog("testStateMachine5 E");
 
         synchronized (sm5) {
             // Send 6 messages
@@ -1202,7 +1222,7 @@
                 // wait for the messages to be handled
                 sm5.wait();
             } catch (InterruptedException e) {
-                Log.e(TAG, "testStateMachine5: exception while waiting " + e.getMessage());
+                tloge("testStateMachine5: exception while waiting " + e.getMessage());
             }
         }
 
@@ -1255,7 +1275,7 @@
         assertEquals(sm5.mParentState2, lr.getState());
         assertEquals(sm5.mParentState2, lr.getOriginalState());
 
-        if (sm5.isDbg()) Log.d(TAG, "testStateMachine5 X");
+        if (sm5.isDbg()) tlog("testStateMachine5 X");
     }
 
     /**
@@ -1274,7 +1294,7 @@
 
             // Set the initial state
             setInitialState(mS1);
-            if (DBG) Log.d(TAG, "StateMachine6: ctor X");
+            if (DBG) log("StateMachine6: ctor X");
         }
 
         class S1 extends State {
@@ -1315,7 +1335,7 @@
 
         StateMachine6 sm6 = new StateMachine6("sm6");
         sm6.start();
-        if (sm6.isDbg()) Log.d(TAG, "testStateMachine6 E");
+        if (sm6.isDbg()) tlog("testStateMachine6 E");
 
         synchronized (sm6) {
             // Send a message
@@ -1325,7 +1345,7 @@
                 // wait for the messages to be handled
                 sm6.wait();
             } catch (InterruptedException e) {
-                Log.e(TAG, "testStateMachine6: exception while waiting " + e.getMessage());
+                tloge("testStateMachine6: exception while waiting " + e.getMessage());
             }
         }
 
@@ -1336,11 +1356,11 @@
          */
         long arrivalTimeDiff = sm6.mArrivalTimeMsg2 - sm6.mArrivalTimeMsg1;
         long expectedDelay = DELAY_TIME - DELAY_FUDGE;
-        if (sm6.isDbg()) Log.d(TAG, "testStateMachine6: expect " + arrivalTimeDiff
+        if (sm6.isDbg()) tlog("testStateMachine6: expect " + arrivalTimeDiff
                                     + " >= " + expectedDelay);
         assertTrue(arrivalTimeDiff >= expectedDelay);
 
-        if (sm6.isDbg()) Log.d(TAG, "testStateMachine6 X");
+        if (sm6.isDbg()) tlog("testStateMachine6 X");
     }
 
     /**
@@ -1361,7 +1381,7 @@
 
             // Set the initial state
             setInitialState(mS1);
-            if (DBG) Log.d(TAG, "StateMachine7: ctor X");
+            if (DBG) log("StateMachine7: ctor X");
         }
 
         class S1 extends State {
@@ -1421,7 +1441,7 @@
 
         StateMachine7 sm7 = new StateMachine7("sm7");
         sm7.start();
-        if (sm7.isDbg()) Log.d(TAG, "testStateMachine7 E");
+        if (sm7.isDbg()) tlog("testStateMachine7 E");
 
         synchronized (sm7) {
             // Send a message
@@ -1431,7 +1451,7 @@
                 // wait for the messages to be handled
                 sm7.wait();
             } catch (InterruptedException e) {
-                Log.e(TAG, "testStateMachine7: exception while waiting " + e.getMessage());
+                tloge("testStateMachine7: exception while waiting " + e.getMessage());
             }
         }
 
@@ -1442,11 +1462,11 @@
          */
         long arrivalTimeDiff = sm7.mArrivalTimeMsg3 - sm7.mArrivalTimeMsg2;
         long expectedDelay = sm7.SM7_DELAY_TIME - SM7_DELAY_FUDGE;
-        if (sm7.isDbg()) Log.d(TAG, "testStateMachine7: expect " + arrivalTimeDiff
+        if (sm7.isDbg()) tlog("testStateMachine7: expect " + arrivalTimeDiff
                                     + " >= " + expectedDelay);
         assertTrue(arrivalTimeDiff >= expectedDelay);
 
-        if (sm7.isDbg()) Log.d(TAG, "testStateMachine7 X");
+        if (sm7.isDbg()) tlog("testStateMachine7 X");
     }
 
     /**
@@ -1494,9 +1514,9 @@
     @SmallTest
     public void testStateMachineUnhandledMessage() throws Exception {
 
-        StateMachineUnhandledMessage sm = new StateMachineUnhandledMessage("sm");
+        StateMachineUnhandledMessage sm = new StateMachineUnhandledMessage("smUnhandledMessage");
         sm.start();
-        if (sm.isDbg()) Log.d(TAG, "testStateMachineUnhandledMessage E");
+        if (sm.isDbg()) tlog("testStateMachineUnhandledMessage E");
 
         synchronized (sm) {
             // Send 2 messages
@@ -1508,15 +1528,15 @@
                 // wait for the messages to be handled
                 sm.wait();
             } catch (InterruptedException e) {
-                Log.e(TAG, "testStateMachineUnhandledMessage: exception while waiting "
+                tloge("testStateMachineUnhandledMessage: exception while waiting "
                         + e.getMessage());
             }
         }
 
-        assertEquals(sm.getLogRecCount(), 2);
+        assertEquals(2, sm.getLogRecSize());
         assertEquals(2, sm.mUnhandledMessageCount);
 
-        if (sm.isDbg()) Log.d(TAG, "testStateMachineUnhandledMessage X");
+        if (sm.isDbg()) tlog("testStateMachineUnhandledMessage X");
     }
 
     /**
@@ -1569,7 +1589,7 @@
 
     @MediumTest
     public void testStateMachineSharedThread() throws Exception {
-        if (DBG) Log.d(TAG, "testStateMachineSharedThread E");
+        if (DBG) tlog("testStateMachineSharedThread E");
 
         // Create and start the handler thread
         HandlerThread smThread = new HandlerThread("testStateMachineSharedThread");
@@ -1578,7 +1598,8 @@
         // Create the state machines
         StateMachineSharedThread sms[] = new StateMachineSharedThread[10];
         for (int i = 0; i < sms.length; i++) {
-            sms[i] = new StateMachineSharedThread("sm", smThread.getLooper(), sms.length);
+            sms[i] = new StateMachineSharedThread("smSharedThread",
+                        smThread.getLooper(), sms.length);
             sms[i].start();
         }
 
@@ -1594,14 +1615,14 @@
             try {
                 waitObject.wait();
             } catch (InterruptedException e) {
-                Log.e(TAG, "testStateMachineSharedThread: exception while waiting "
+                tloge("testStateMachineSharedThread: exception while waiting "
                         + e.getMessage());
             }
         }
 
         for (StateMachineSharedThread sm : sms) {
-            assertEquals(sm.getLogRecCount(), 4);
-            for (int i = 0; i < sm.getLogRecCount(); i++) {
+            assertEquals(4, sm.getLogRecCount());
+            for (int i = 0; i < sm.getLogRecSize(); i++) {
                 LogRec lr = sm.getLogRec(i);
                 assertEquals(i+1, lr.getWhat());
                 assertEquals(sm.mS1, lr.getState());
@@ -1609,12 +1630,168 @@
             }
         }
 
-        if (DBG) Log.d(TAG, "testStateMachineSharedThread X");
+        if (DBG) tlog("testStateMachineSharedThread X");
+    }
+
+    static class Hsm1 extends StateMachine {
+        private static final String HSM1_TAG = "hsm1";
+
+        public static final int CMD_1 = 1;
+        public static final int CMD_2 = 2;
+        public static final int CMD_3 = 3;
+        public static final int CMD_4 = 4;
+        public static final int CMD_5 = 5;
+
+        public static Hsm1 makeHsm1() {
+            Log.d(HSM1_TAG, "makeHsm1 E");
+            Hsm1 sm = new Hsm1(HSM1_TAG);
+            sm.start();
+            Log.d(HSM1_TAG, "makeHsm1 X");
+            return sm;
+        }
+
+        Hsm1(String name) {
+            super(name);
+            log("ctor E");
+
+            // Add states, use indentation to show hierarchy
+            addState(mP1);
+                addState(mS1, mP1);
+                addState(mS2, mP1);
+            addState(mP2);
+
+            // Set the initial state
+            setInitialState(mS1);
+            log("ctor X");
+        }
+
+        class P1 extends State {
+            @Override
+            public void enter() {
+                log("P1.enter");
+            }
+            @Override
+            public void exit() {
+                log("P1.exit");
+            }
+            @Override
+            public boolean processMessage(Message message) {
+                boolean retVal;
+                log("P1.processMessage what=" + message.what);
+                switch(message.what) {
+                case CMD_2:
+                    // CMD_2 will arrive in mS2 before CMD_3
+                    sendMessage(CMD_3);
+                    deferMessage(message);
+                    transitionTo(mS2);
+                    retVal = true;
+                    break;
+                default:
+                    // Any message we don't understand in this state invokes unhandledMessage
+                    retVal = false;
+                    break;
+                }
+                return retVal;
+            }
+        }
+
+        class S1 extends State {
+            @Override
+            public void enter() {
+                log("S1.enter");
+            }
+            @Override
+            public void exit() {
+                log("S1.exit");
+            }
+            @Override
+            public boolean processMessage(Message message) {
+                log("S1.processMessage what=" + message.what);
+                if (message.what == CMD_1) {
+                    // Transition to ourself to show that enter/exit is called
+                    transitionTo(mS1);
+                    return HANDLED;
+                } else {
+                    // Let parent process all other messages
+                    return NOT_HANDLED;
+                }
+            }
+        }
+
+        class S2 extends State {
+            @Override
+            public void enter() {
+                log("S2.enter");
+            }
+            @Override
+            public void exit() {
+                log("S2.exit");
+            }
+            @Override
+            public boolean processMessage(Message message) {
+                boolean retVal;
+                log("S2.processMessage what=" + message.what);
+                switch(message.what) {
+                case(CMD_2):
+                    sendMessage(CMD_4);
+                    retVal = true;
+                    break;
+                case(CMD_3):
+                    deferMessage(message);
+                    transitionTo(mP2);
+                    retVal = true;
+                    break;
+                default:
+                    retVal = false;
+                    break;
+                }
+                return retVal;
+            }
+        }
+
+        class P2 extends State {
+            @Override
+            public void enter() {
+                log("P2.enter");
+                sendMessage(CMD_5);
+            }
+            @Override
+            public void exit() {
+                log("P2.exit");
+            }
+            @Override
+            public boolean processMessage(Message message) {
+                log("P2.processMessage what=" + message.what);
+                switch(message.what) {
+                case(CMD_3):
+                    break;
+                case(CMD_4):
+                    break;
+                case(CMD_5):
+                    transitionToHaltingState();
+                    break;
+                }
+                return HANDLED;
+            }
+        }
+
+        @Override
+        protected void onHalting() {
+            log("halting");
+            synchronized (this) {
+                this.notifyAll();
+            }
+        }
+
+        P1 mP1 = new P1();
+        S1 mS1 = new S1();
+        S2 mS2 = new S2();
+        P2 mP2 = new P2();
     }
 
     @MediumTest
     public void testHsm1() throws Exception {
-        if (DBG) Log.d(TAG, "testHsm1 E");
+        if (DBG) tlog("testHsm1 E");
 
         Hsm1 sm = Hsm1.makeHsm1();
 
@@ -1627,11 +1804,14 @@
             try {
                 sm.wait();
             } catch (InterruptedException e) {
-                Log.e(TAG, "testHsm1: exception while waiting " + e.getMessage());
+                tloge("testHsm1: exception while waiting " + e.getMessage());
             }
         }
 
+        dumpLogRecs(sm);
+
         assertEquals(7, sm.getLogRecCount());
+
         LogRec lr = sm.getLogRec(0);
         assertEquals(Hsm1.CMD_1, lr.getWhat());
         assertEquals(sm.mS1, lr.getState());
@@ -1667,162 +1847,14 @@
         assertEquals(sm.mP2, lr.getState());
         assertEquals(sm.mP2, lr.getOriginalState());
 
-        if (DBG) Log.d(TAG, "testStateMachineSharedThread X");
-    }
-}
-
-class Hsm1 extends StateMachine {
-    private static final String TAG = "hsm1";
-
-    public static final int CMD_1 = 1;
-    public static final int CMD_2 = 2;
-    public static final int CMD_3 = 3;
-    public static final int CMD_4 = 4;
-    public static final int CMD_5 = 5;
-
-    public static Hsm1 makeHsm1() {
-        Log.d(TAG, "makeHsm1 E");
-        Hsm1 sm = new Hsm1("hsm1");
-        sm.start();
-        Log.d(TAG, "makeHsm1 X");
-        return sm;
+        if (DBG) tlog("testStateMachineSharedThread X");
     }
 
-    Hsm1(String name) {
-        super(name);
-        Log.d(TAG, "ctor E");
-
-        // Add states, use indentation to show hierarchy
-        addState(mP1);
-            addState(mS1, mP1);
-            addState(mS2, mP1);
-        addState(mP2);
-
-        // Set the initial state
-        setInitialState(mS1);
-        Log.d(TAG, "ctor X");
+    private void tlog(String s) {
+        Log.d(TAG, s);
     }
 
-    class P1 extends State {
-        @Override
-        public void enter() {
-            Log.d(TAG, "P1.enter");
-        }
-        @Override
-        public void exit() {
-            Log.d(TAG, "P1.exit");
-        }
-        @Override
-        public boolean processMessage(Message message) {
-            boolean retVal;
-            Log.d(TAG, "P1.processMessage what=" + message.what);
-            switch(message.what) {
-            case CMD_2:
-                // CMD_2 will arrive in mS2 before CMD_3
-                sendMessage(CMD_3);
-                deferMessage(message);
-                transitionTo(mS2);
-                retVal = true;
-                break;
-            default:
-                // Any message we don't understand in this state invokes unhandledMessage
-                retVal = false;
-                break;
-            }
-            return retVal;
-        }
+    private void tloge(String s) {
+        Log.e(TAG, s);
     }
-
-    class S1 extends State {
-        @Override
-        public void enter() {
-            Log.d(TAG, "S1.enter");
-        }
-        @Override
-        public void exit() {
-            Log.d(TAG, "S1.exit");
-        }
-        @Override
-        public boolean processMessage(Message message) {
-            Log.d(TAG, "S1.processMessage what=" + message.what);
-            if (message.what == CMD_1) {
-                // Transition to ourself to show that enter/exit is called
-                transitionTo(mS1);
-                return HANDLED;
-            } else {
-                // Let parent process all other messages
-                return NOT_HANDLED;
-            }
-        }
-    }
-
-    class S2 extends State {
-        @Override
-        public void enter() {
-            Log.d(TAG, "S2.enter");
-        }
-        @Override
-        public void exit() {
-            Log.d(TAG, "S2.exit");
-        }
-        @Override
-        public boolean processMessage(Message message) {
-            boolean retVal;
-            Log.d(TAG, "S2.processMessage what=" + message.what);
-            switch(message.what) {
-            case(CMD_2):
-                sendMessage(CMD_4);
-                retVal = true;
-                break;
-            case(CMD_3):
-                deferMessage(message);
-                transitionTo(mP2);
-                retVal = true;
-                break;
-            default:
-                retVal = false;
-                break;
-            }
-            return retVal;
-        }
-    }
-
-    class P2 extends State {
-        @Override
-        public void enter() {
-            Log.d(TAG, "P2.enter");
-            sendMessage(CMD_5);
-        }
-        @Override
-        public void exit() {
-            Log.d(TAG, "P2.exit");
-        }
-        @Override
-        public boolean processMessage(Message message) {
-            Log.d(TAG, "P2.processMessage what=" + message.what);
-            switch(message.what) {
-            case(CMD_3):
-                break;
-            case(CMD_4):
-                break;
-            case(CMD_5):
-                transitionToHaltingState();
-                break;
-            }
-            return HANDLED;
-        }
-    }
-
-    @Override
-    protected void onHalting() {
-        Log.d(TAG, "halting");
-        synchronized (this) {
-            this.notifyAll();
-        }
-    }
-
-    P1 mP1 = new P1();
-    S1 mS1 = new S1();
-    S2 mS2 = new S2();
-    P2 mP2 = new P2();
 }
diff --git a/data/keyboards/Generic.kl b/data/keyboards/Generic.kl
index 225c11a..1413319 100644
--- a/data/keyboards/Generic.kl
+++ b/data/keyboards/Generic.kl
@@ -243,8 +243,8 @@
 # key 221 "KEY_SHOP"
 # key 222 "KEY_ALTERASE"
 # key 223 "KEY_CANCEL"
-# key 224 "KEY_BRIGHTNESSDOWN"
-# key 225 "KEY_BRIGHTNESSUP"
+key 224   BRIGHTNESS_DOWN
+key 225   BRIGHTNESS_UP
 key 226   HEADSETHOOK
 
 key 256   BUTTON_1
@@ -404,6 +404,9 @@
 # key 503 KEY_BRL_DOT7
 # key 504 KEY_BRL_DOT8
 
+# Keys defined by HID usages
+key usage 0x0c006F BRIGHTNESS_UP
+key usage 0x0c0070 BRIGHTNESS_DOWN
 
 # Joystick and game controller axes.
 # Axes that are not mapped will be assigned generic axis numbers by the input subsystem.
diff --git a/data/keyboards/Vendor_05ac_Product_0239.kl b/data/keyboards/Vendor_05ac_Product_0239.kl
index 6bd3753..b0c358e 100644
--- a/data/keyboards/Vendor_05ac_Product_0239.kl
+++ b/data/keyboards/Vendor_05ac_Product_0239.kl
@@ -112,8 +112,8 @@
 key 164   MEDIA_PLAY_PAUSE
 key 165   MEDIA_PREVIOUS
 # key 204  show gadgets
-# key 224  reduce brightness
-# key 225  increase brightness
+key 224   BRIGHTNESS_DOWN
+key 225   BRIGHTNESS_UP
 # key 229  blank special function on F5
 # key 230  blank special function on F6
 key 464   FUNCTION
diff --git a/include/androidfw/KeycodeLabels.h b/include/androidfw/KeycodeLabels.h
index 538949d..3e12f26 100644
--- a/include/androidfw/KeycodeLabels.h
+++ b/include/androidfw/KeycodeLabels.h
@@ -244,6 +244,8 @@
     { "RO", 217 },
     { "KANA", 218 },
     { "ASSIST", 219 },
+    { "BRIGHTNESS_DOWN", 220 },
+    { "BRIGHTNESS_UP", 221 },
 
     // NOTE: If you add a new keycode here you must also add it to several other files.
     //       Refer to frameworks/base/core/java/android/view/KeyEvent.java for the full list.
diff --git a/libs/androidfw/Input.cpp b/libs/androidfw/Input.cpp
index 97b0ec1..8996f6f 100644
--- a/libs/androidfw/Input.cpp
+++ b/libs/androidfw/Input.cpp
@@ -72,6 +72,8 @@
         case AKEYCODE_MEDIA_RECORD:
         case AKEYCODE_MEDIA_FAST_FORWARD:
         case AKEYCODE_MUTE:
+        case AKEYCODE_BRIGHTNESS_DOWN:
+        case AKEYCODE_BRIGHTNESS_UP:
             return true;
     }
     
@@ -108,6 +110,8 @@
         case AKEYCODE_CAMERA:
         case AKEYCODE_FOCUS:
         case AKEYCODE_SEARCH:
+        case AKEYCODE_BRIGHTNESS_DOWN:
+        case AKEYCODE_BRIGHTNESS_UP:
             return true;
     }
     
diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp
index 5c2b388..7e645d2 100644
--- a/libs/hwui/Caches.cpp
+++ b/libs/hwui/Caches.cpp
@@ -466,9 +466,9 @@
 // Tiling
 ///////////////////////////////////////////////////////////////////////////////
 
-void Caches::startTiling(GLuint x, GLuint y, GLuint width, GLuint height, bool opaque) {
+void Caches::startTiling(GLuint x, GLuint y, GLuint width, GLuint height, bool discard) {
     if (extensions.hasTiledRendering() && !debugOverdraw) {
-        glStartTilingQCOM(x, y, width, height, (opaque ? GL_NONE : GL_COLOR_BUFFER_BIT0_QCOM));
+        glStartTilingQCOM(x, y, width, height, (discard ? GL_NONE : GL_COLOR_BUFFER_BIT0_QCOM));
     }
 }
 
diff --git a/libs/hwui/Caches.h b/libs/hwui/Caches.h
index ae188be..1c4d05f 100644
--- a/libs/hwui/Caches.h
+++ b/libs/hwui/Caches.h
@@ -215,7 +215,7 @@
     bool disableScissor();
     void setScissorEnabled(bool enabled);
 
-    void startTiling(GLuint x, GLuint y, GLuint width, GLuint height, bool opaque);
+    void startTiling(GLuint x, GLuint y, GLuint width, GLuint height, bool discard);
     void endTiling();
 
     /**
diff --git a/libs/hwui/DisplayListLogBuffer.cpp b/libs/hwui/DisplayListLogBuffer.cpp
index f204644..f039fcd 100644
--- a/libs/hwui/DisplayListLogBuffer.cpp
+++ b/libs/hwui/DisplayListLogBuffer.cpp
@@ -18,9 +18,8 @@
 
 // BUFFER_SIZE size must be one more than a multiple of COMMAND_SIZE to ensure
 // that mStart always points at the next command, not just the next item
-#define COMMAND_SIZE 2
 #define NUM_COMMANDS 50
-#define BUFFER_SIZE ((NUM_COMMANDS * COMMAND_SIZE) + 1)
+#define BUFFER_SIZE ((NUM_COMMANDS) + 1)
 
 /**
  * DisplayListLogBuffer is a utility class which logs the most recent display
@@ -57,7 +56,7 @@
 
 
 DisplayListLogBuffer::DisplayListLogBuffer() {
-    mBufferFirst = (int*) malloc(BUFFER_SIZE * sizeof(int));
+    mBufferFirst = (OpLog*) malloc(BUFFER_SIZE * sizeof(OpLog));
     mStart = mBufferFirst;
     mBufferLast = mBufferFirst + BUFFER_SIZE - 1;
     mEnd = mStart;
@@ -71,42 +70,30 @@
  * Called from DisplayListRenderer to output the current buffer into the
  * specified FILE. This only happens in a dumpsys/bugreport operation.
  */
-void DisplayListLogBuffer::outputCommands(FILE *file, const char* opNames[])
+void DisplayListLogBuffer::outputCommands(FILE *file)
 {
-    int *tmpBufferPtr = mStart;
+    OpLog* tmpBufferPtr = mStart;
     while (true) {
         if (tmpBufferPtr == mEnd) {
             break;
         }
-        int level = *tmpBufferPtr++;
+        OpLog* nextOp = tmpBufferPtr++;
         if (tmpBufferPtr > mBufferLast) {
             tmpBufferPtr = mBufferFirst;
         }
-        int op = *tmpBufferPtr++;
-        if (tmpBufferPtr > mBufferLast) {
-            tmpBufferPtr = mBufferFirst;
-        }
-        uint32_t count = (level + 1) * 2;
-        char indent[count + 1];
-        for (uint32_t i = 0; i < count; i++) {
-            indent[i] = ' ';
-        }
-        indent[count] = '\0';
-        fprintf(file, "%s%s\n", indent, opNames[op]);
+
+        fprintf(file, "%*s%s\n", tmpBufferPtr->level*2, "", tmpBufferPtr->label);
     }
 }
 
-void DisplayListLogBuffer::writeCommand(int level, int op) {
-    writeInt(level);
-    writeInt(op);
-}
-
 /**
- * Store the given value in the buffer and increment/wrap the mEnd
- * and mStart values as appropriate.
+ * Store the given level and label in the buffer and increment/wrap the mEnd
+ * and mStart values as appropriate. Label should point to static memory.
  */
-void DisplayListLogBuffer::writeInt(int value) {
-    *((int*)mEnd) = value;
+void DisplayListLogBuffer::writeCommand(int level, const char* label) {
+    mEnd->level = level;
+    mEnd->label = label;
+
     if (mEnd == mBufferLast) {
         mEnd = mBufferFirst;
     } else {
diff --git a/libs/hwui/DisplayListLogBuffer.h b/libs/hwui/DisplayListLogBuffer.h
index 5d689bb..c884789 100644
--- a/libs/hwui/DisplayListLogBuffer.h
+++ b/libs/hwui/DisplayListLogBuffer.h
@@ -31,19 +31,23 @@
     friend class Singleton<DisplayListLogBuffer>;
 
 public:
-    void writeCommand(int level, int op);
-    void writeInt(int value);
-    void outputCommands(FILE *file, const char* opNames[]);
+    void writeCommand(int level, const char* label);
+    void outputCommands(FILE *file);
 
     bool isEmpty() {
         return (mStart == mEnd);
     }
 
+    struct OpLog {
+        int level;
+        const char* label;
+    };
+
 private:
-    int *mBufferFirst; // where the memory starts
-    int* mStart;       // where the current command stream starts
-    int* mEnd;         // where the current commands end
-    int* mBufferLast;  // where the buffer memory ends
+    OpLog* mBufferFirst; // where the memory starts
+    OpLog* mStart;       // where the current command stream starts
+    OpLog* mEnd;         // where the current commands end
+    OpLog* mBufferLast;  // where the buffer memory ends
 
 };
 
diff --git a/libs/hwui/DisplayListOp.h b/libs/hwui/DisplayListOp.h
new file mode 100644
index 0000000..a4de56d
--- /dev/null
+++ b/libs/hwui/DisplayListOp.h
@@ -0,0 +1,1138 @@
+/*
+ * 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_HWUI_DISPLAY_OPERATION_H
+#define ANDROID_HWUI_DISPLAY_OPERATION_H
+
+#include <SkXfermode.h>
+
+#include "OpenGLRenderer.h"
+#include "DisplayListRenderer.h"
+#include "utils/LinearAllocator.h"
+
+#define CRASH() do { \
+    *(int *)(uintptr_t)0xbbadbeef = 0; \
+    ((void(*)())0)(); /* More reliable, but doesn't say BBADBEEF */ \
+} while(false)
+
+#define MATRIX_STRING "[%.2f %.2f %.2f] [%.2f %.2f %.2f] [%.2f %.2f %.2f]"
+#define MATRIX_ARGS(m) \
+    m->get(0), m->get(1), m->get(2), \
+    m->get(3), m->get(4), m->get(5), \
+    m->get(6), m->get(7), m->get(8)
+#define RECT_STRING "%.2f %.2f %.2f %.2f"
+#define RECT_ARGS(r) \
+    r.left, r.top, r.right, r.bottom
+
+// Use OP_LOG for logging with arglist, OP_LOGS if just printing char*
+#define OP_LOGS(s) OP_LOG("%s", s)
+#define OP_LOG(s, ...) ALOGD( "%*s--%p " s, level * 2, "", this, __VA_ARGS__ )
+
+
+namespace android {
+namespace uirenderer {
+
+/**
+ * Structure for storing canvas operations when they are recorded into a DisplayList, so that they
+ * may be replayed to an OpenGLRenderer.
+ *
+ * To avoid individual memory allocations, DisplayListOps may only be allocated into a
+ * LinearAllocator's managed memory buffers.  Each pointer held by a DisplayListOp is either a
+ * pointer into memory also allocated in the LinearAllocator (mostly for text and float buffers) or
+ * references a externally refcounted object (Sk... and Skia... objects). ~DisplayListOp() is
+ * never called as LinearAllocators are simply discarded, so no memory management should be done in
+ * this class.
+ */
+class DisplayListOp {
+public:
+    // These objects should always be allocated with a LinearAllocator, and never destroyed/deleted.
+    // standard new() intentionally not implemented, and delete/deconstructor should never be used.
+    virtual ~DisplayListOp() { CRASH(); }
+    static void operator delete(void* ptr) { CRASH(); }
+    /** static void* operator new(size_t size); PURPOSELY OMITTED **/
+    static void* operator new(size_t size, LinearAllocator& allocator) {
+        return allocator.alloc(size);
+    }
+
+    enum OpLogFlag {
+        kOpLogFlag_Recurse = 0x1,
+        kOpLogFlag_JSON = 0x2 // TODO: add?
+    };
+
+    //TODO: for draw batching, DrawOps should override a virtual sub-method, with
+    // DrawOps::apply deferring operations to a different list if possible
+    virtual status_t replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, int saveCount,
+            uint32_t level, bool caching, int multipliedAlpha) = 0;
+
+    virtual void output(int level, uint32_t flags = 0) = 0;
+
+    // NOTE: it would be nice to declare constants and overriding the implementation in each op to
+    // point at the constants, but that seems to require a .cpp file
+    virtual const char* name() = 0;
+};
+
+class StateOp : public DisplayListOp {
+public:
+    StateOp() {};
+
+    virtual ~StateOp() {}
+
+    virtual status_t replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, int saveCount,
+            uint32_t level, bool caching, int multipliedAlpha) {
+        applyState(renderer, saveCount);
+        return DrawGlInfo::kStatusDone;
+    }
+
+    virtual void applyState(OpenGLRenderer& renderer, int saveCount) = 0;
+};
+
+class DrawOp : public DisplayListOp {
+public:
+    DrawOp(SkPaint* paint)
+            : mPaint(paint), mQuickRejected(false) {}
+
+    virtual status_t replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, int saveCount,
+            uint32_t level, bool caching, int multipliedAlpha) {
+        if (mQuickRejected && CC_LIKELY(flags & DisplayList::kReplayFlag_ClipChildren)) {
+            return DrawGlInfo::kStatusDone;
+        }
+
+        return applyDraw(renderer, dirty, level, caching, multipliedAlpha);
+    }
+
+    virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level,
+            bool caching, int multipliedAlpha) = 0;
+
+    // returns true if bounds exist
+    virtual bool getLocalBounds(Rect& localBounds) { return false; }
+
+    // TODO: better refine localbounds usage
+    void setQuickRejected(bool quickRejected) { mQuickRejected = quickRejected; }
+    bool getQuickRejected() { return mQuickRejected; }
+
+protected:
+    SkPaint* getPaint(OpenGLRenderer& renderer) {
+        return renderer.filterPaint(mPaint);
+    }
+
+    SkPaint* mPaint; // should be accessed via getPaint() when applying
+    bool mQuickRejected;
+};
+
+class DrawBoundedOp : public DrawOp {
+public:
+    DrawBoundedOp(float left, float top, float right, float bottom, SkPaint* paint)
+            : DrawOp(paint), mLocalBounds(left, top, right, bottom) {}
+
+    // default constructor for area, to be overridden in child constructor body
+    DrawBoundedOp(SkPaint* paint)
+            : DrawOp(paint) {}
+
+    bool getLocalBounds(Rect& localBounds) {
+        localBounds.set(mLocalBounds);
+        return true;
+    }
+
+protected:
+    Rect mLocalBounds; // displayed area in LOCAL coord. doesn't incorporate stroke, so check paint
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// STATE OPERATIONS - these may affect the state of the canvas/renderer, but do
+//         not directly draw or alter output
+///////////////////////////////////////////////////////////////////////////////
+
+class SaveOp : public StateOp {
+public:
+    SaveOp(int flags)
+            : mFlags(flags) {}
+
+    virtual void applyState(OpenGLRenderer& renderer, int saveCount) {
+        renderer.save(mFlags);
+    }
+
+    virtual void output(int level, uint32_t flags = 0) {
+        OP_LOG("Save flags %x", mFlags);
+    }
+
+    virtual const char* name() { return "Save"; }
+
+private:
+    int mFlags;
+};
+
+class RestoreToCountOp : public StateOp {
+public:
+    RestoreToCountOp(int count)
+            : mCount(count) {}
+
+    virtual void applyState(OpenGLRenderer& renderer, int saveCount) {
+        renderer.restoreToCount(saveCount + mCount);
+
+    }
+
+    virtual void output(int level, uint32_t flags = 0) {
+        OP_LOG("Restore to count %d", mCount);
+    }
+
+    virtual const char* name() { return "RestoreToCount"; }
+
+private:
+    int mCount;
+};
+
+class SaveLayerOp : public StateOp {
+public:
+    SaveLayerOp(float left, float top, float right, float bottom, SkPaint* paint, int flags)
+            : mArea(left, top, right, bottom), mPaint(paint), mFlags(flags) {}
+
+    virtual void applyState(OpenGLRenderer& renderer, int saveCount) {
+        SkPaint* paint = renderer.filterPaint(mPaint);
+        renderer.saveLayer(mArea.left, mArea.top, mArea.right, mArea.bottom, paint, mFlags);
+    }
+
+    virtual void output(int level, uint32_t flags = 0) {
+        OP_LOG("SaveLayer of area " RECT_STRING, RECT_ARGS(mArea));
+    }
+
+    virtual const char* name() { return "SaveLayer"; }
+
+private:
+    Rect mArea;
+    SkPaint* mPaint;
+    int mFlags;
+};
+
+class SaveLayerAlphaOp : public StateOp {
+public:
+    SaveLayerAlphaOp(float left, float top, float right, float bottom, int alpha, int flags)
+            : mArea(left, top, right, bottom), mAlpha(alpha), mFlags(flags) {}
+
+    virtual void applyState(OpenGLRenderer& renderer, int saveCount) {
+        renderer.saveLayerAlpha(mArea.left, mArea.top, mArea.right, mArea.bottom, mAlpha, mFlags);
+    }
+
+    virtual void output(int level, uint32_t flags = 0) {
+        OP_LOG("SaveLayerAlpha of area " RECT_STRING, RECT_ARGS(mArea));
+    }
+
+    virtual const char* name() { return "SaveLayerAlpha"; }
+private:
+    Rect mArea;
+    int mAlpha;
+    int mFlags;
+};
+
+class TranslateOp : public StateOp {
+public:
+    TranslateOp(float dx, float dy)
+            : mDx(dx), mDy(dy) {}
+
+    virtual void applyState(OpenGLRenderer& renderer, int saveCount) {
+        renderer.translate(mDx, mDy);
+    }
+
+    virtual void output(int level, uint32_t flags = 0) {
+        OP_LOG("Translate by %f %f", mDx, mDy);
+    }
+
+    virtual const char* name() { return "Translate"; }
+
+private:
+    float mDx;
+    float mDy;
+};
+
+class RotateOp : public StateOp {
+public:
+    RotateOp(float degrees)
+            : mDegrees(degrees) {}
+
+    virtual void applyState(OpenGLRenderer& renderer, int saveCount) {
+        renderer.rotate(mDegrees);
+    }
+
+    virtual void output(int level, uint32_t flags = 0) {
+        OP_LOG("Rotate by %f degrees", mDegrees);
+    }
+
+    virtual const char* name() { return "Rotate"; }
+
+private:
+    float mDegrees;
+};
+
+class ScaleOp : public StateOp {
+public:
+    ScaleOp(float sx, float sy)
+            : mSx(sx), mSy(sy) {}
+
+    virtual void applyState(OpenGLRenderer& renderer, int saveCount) {
+        renderer.scale(mSx, mSy);
+    }
+
+    virtual void output(int level, uint32_t flags = 0) {
+        OP_LOG("Scale by %f %f", mSx, mSy);
+    }
+
+    virtual const char* name() { return "Scale"; }
+
+private:
+    float mSx;
+    float mSy;
+};
+
+class SkewOp : public StateOp {
+public:
+    SkewOp(float sx, float sy)
+            : mSx(sx), mSy(sy) {}
+
+    virtual void applyState(OpenGLRenderer& renderer, int saveCount) {
+        renderer.skew(mSx, mSy);
+    }
+
+    virtual void output(int level, uint32_t flags = 0) {
+        OP_LOG("Skew by %f %f", mSx, mSy);
+    }
+
+    virtual const char* name() { return "Skew"; }
+
+private:
+    float mSx;
+    float mSy;
+};
+
+class SetMatrixOp : public StateOp {
+public:
+    SetMatrixOp(SkMatrix* matrix)
+            : mMatrix(matrix) {}
+
+    virtual void applyState(OpenGLRenderer& renderer, int saveCount) {
+        renderer.setMatrix(mMatrix);
+    }
+
+    virtual void output(int level, uint32_t flags = 0) {
+        OP_LOG("SetMatrix " MATRIX_STRING, MATRIX_ARGS(mMatrix));
+    }
+
+    virtual const char* name() { return "SetMatrix"; }
+
+private:
+    SkMatrix* mMatrix;
+};
+
+class ConcatMatrixOp : public StateOp {
+public:
+    ConcatMatrixOp(SkMatrix* matrix)
+            : mMatrix(matrix) {}
+
+    virtual void applyState(OpenGLRenderer& renderer, int saveCount) {
+        renderer.concatMatrix(mMatrix);
+    }
+
+    virtual void output(int level, uint32_t flags = 0) {
+        OP_LOG("ConcatMatrix " MATRIX_STRING, MATRIX_ARGS(mMatrix));
+    }
+
+    virtual const char* name() { return "ConcatMatrix"; }
+
+private:
+    SkMatrix* mMatrix;
+};
+
+class ClipRectOp : public StateOp {
+public:
+    ClipRectOp(float left, float top, float right, float bottom, SkRegion::Op op)
+            : mArea(left, top, right, bottom), mOp(op) {}
+
+    virtual void applyState(OpenGLRenderer& renderer, int saveCount) {
+        renderer.clipRect(mArea.left, mArea.top, mArea.right, mArea.bottom, mOp);
+    }
+
+    virtual void output(int level, uint32_t flags = 0) {
+        OP_LOG("ClipRect " RECT_STRING, RECT_ARGS(mArea));
+    }
+
+    virtual const char* name() { return "ClipRect"; }
+
+private:
+    Rect mArea;
+    SkRegion::Op mOp;
+};
+
+class ClipPathOp : public StateOp {
+public:
+    ClipPathOp(SkPath* path, SkRegion::Op op)
+            : mPath(path), mOp(op) {}
+
+    virtual void applyState(OpenGLRenderer& renderer, int saveCount) {
+        renderer.clipPath(mPath, mOp);
+    }
+
+    virtual void output(int level, uint32_t flags = 0) {
+        SkRect bounds = mPath->getBounds();
+        OP_LOG("ClipPath bounds " RECT_STRING,
+                bounds.left(), bounds.top(), bounds.right(), bounds.bottom());
+    }
+
+    virtual const char* name() { return "ClipPath"; }
+
+private:
+    SkPath* mPath;
+    SkRegion::Op mOp;
+};
+
+class ClipRegionOp : public StateOp {
+public:
+    ClipRegionOp(SkRegion* region, SkRegion::Op op)
+            : mRegion(region), mOp(op) {}
+
+    virtual void applyState(OpenGLRenderer& renderer, int saveCount) {
+        renderer.clipRegion(mRegion, mOp);
+    }
+
+    virtual void output(int level, uint32_t flags = 0) {
+        SkIRect bounds = mRegion->getBounds();
+        OP_LOG("ClipRegion bounds %d %d %d %d",
+                bounds.left(), bounds.top(), bounds.right(), bounds.bottom());
+    }
+
+    virtual const char* name() { return "ClipRegion"; }
+
+private:
+    SkRegion* mRegion;
+    SkRegion::Op mOp;
+};
+
+class ResetShaderOp : public StateOp {
+public:
+    virtual void applyState(OpenGLRenderer& renderer, int saveCount) {
+        renderer.resetShader();
+    }
+
+    virtual void output(int level, uint32_t flags = 0) {
+        OP_LOGS("ResetShader");
+    }
+
+    virtual const char* name() { return "ResetShader"; }
+};
+
+class SetupShaderOp : public StateOp {
+public:
+    SetupShaderOp(SkiaShader* shader)
+            : mShader(shader) {}
+    virtual void applyState(OpenGLRenderer& renderer, int saveCount) {
+        renderer.setupShader(mShader);
+    }
+
+    virtual void output(int level, uint32_t flags = 0) {
+        OP_LOG("SetupShader, shader %p", mShader);
+    }
+
+    virtual const char* name() { return "SetupShader"; }
+
+private:
+    SkiaShader* mShader;
+};
+
+class ResetColorFilterOp : public StateOp {
+public:
+    virtual void applyState(OpenGLRenderer& renderer, int saveCount) {
+        renderer.resetColorFilter();
+    }
+
+    virtual void output(int level, uint32_t flags = 0) {
+        OP_LOGS("ResetColorFilter");
+    }
+
+    virtual const char* name() { return "ResetColorFilter"; }
+};
+
+class SetupColorFilterOp : public StateOp {
+public:
+    SetupColorFilterOp(SkiaColorFilter* colorFilter)
+            : mColorFilter(colorFilter) {}
+
+    virtual void applyState(OpenGLRenderer& renderer, int saveCount) {
+        renderer.setupColorFilter(mColorFilter);
+    }
+
+    virtual void output(int level, uint32_t flags = 0) {
+        OP_LOG("SetupColorFilter, filter %p", mColorFilter);
+    }
+
+    virtual const char* name() { return "SetupColorFilter"; }
+
+private:
+    SkiaColorFilter* mColorFilter;
+};
+
+class ResetShadowOp : public StateOp {
+public:
+    virtual void applyState(OpenGLRenderer& renderer, int saveCount) {
+        renderer.resetShadow();
+    }
+
+    virtual void output(int level, uint32_t flags = 0) {
+        OP_LOGS("ResetShadow");
+    }
+
+    virtual const char* name() { return "ResetShadow"; }
+};
+
+class SetupShadowOp : public StateOp {
+public:
+    SetupShadowOp(float radius, float dx, float dy, int color)
+            : mRadius(radius), mDx(dx), mDy(dy), mColor(color) {}
+
+    virtual void applyState(OpenGLRenderer& renderer, int saveCount) {
+        renderer.setupShadow(mRadius, mDx, mDy, mColor);
+    }
+
+    virtual void output(int level, uint32_t flags = 0) {
+        OP_LOG("SetupShadow, radius %f, %f, %f, color %#x", mRadius, mDx, mDy, mColor);
+    }
+
+    virtual const char* name() { return "SetupShadow"; }
+
+private:
+    float mRadius;
+    float mDx;
+    float mDy;
+    int mColor;
+};
+
+class ResetPaintFilterOp : public StateOp {
+public:
+    virtual void applyState(OpenGLRenderer& renderer, int saveCount) {
+        renderer.resetPaintFilter();
+    }
+
+    virtual void output(int level, uint32_t flags = 0) {
+        OP_LOGS("ResetPaintFilter");
+    }
+
+    virtual const char* name() { return "ResetPaintFilter"; }
+};
+
+class SetupPaintFilterOp : public StateOp {
+public:
+    SetupPaintFilterOp(int clearBits, int setBits)
+            : mClearBits(clearBits), mSetBits(setBits) {}
+
+    virtual void applyState(OpenGLRenderer& renderer, int saveCount) {
+        renderer.setupPaintFilter(mClearBits, mSetBits);
+    }
+
+    virtual void output(int level, uint32_t flags = 0) {
+        OP_LOG("SetupPaintFilter, clear %#x, set %#x", mClearBits, mSetBits);
+    }
+
+    virtual const char* name() { return "SetupPaintFilter"; }
+
+private:
+    int mClearBits;
+    int mSetBits;
+};
+
+
+///////////////////////////////////////////////////////////////////////////////
+// DRAW OPERATIONS - these are operations that can draw to the canvas's device
+///////////////////////////////////////////////////////////////////////////////
+
+class DrawBitmapOp : public DrawBoundedOp {
+public:
+    DrawBitmapOp(SkBitmap* bitmap, float left, float top, SkPaint* paint)
+            : DrawBoundedOp(left, top, left + bitmap->width(), top + bitmap->height(),
+                    paint),
+            mBitmap(bitmap) {}
+
+    virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level,
+            bool caching, int multipliedAlpha) {
+        SkPaint* paint = getPaint(renderer);
+        int oldAlpha = -1;
+        if (caching && multipliedAlpha < 255) {
+            oldAlpha = paint->getAlpha();
+            paint->setAlpha(multipliedAlpha);
+        }
+        status_t ret = renderer.drawBitmap(mBitmap, mLocalBounds.left, mLocalBounds.top, paint);
+        if (oldAlpha >= 0) {
+            paint->setAlpha(oldAlpha);
+        }
+        return ret;
+    }
+
+    virtual void output(int level, uint32_t flags) {
+        OP_LOG("Draw bitmap %p at %f %f", mBitmap, mLocalBounds.left, mLocalBounds.top);
+    }
+
+    virtual const char* name() { return "DrawBitmap"; }
+
+protected:
+    SkBitmap* mBitmap;
+};
+
+class DrawBitmapMatrixOp : public DrawBoundedOp {
+public:
+    DrawBitmapMatrixOp(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint)
+            : DrawBoundedOp(paint), mBitmap(bitmap), mMatrix(matrix) {
+        mLocalBounds.set(0, 0, bitmap->width(), bitmap->height());
+        const mat4 transform(*matrix);
+        transform.mapRect(mLocalBounds);
+    }
+
+    virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level,
+            bool caching, int multipliedAlpha) {
+        return renderer.drawBitmap(mBitmap, mMatrix, getPaint(renderer));
+    }
+
+    virtual void output(int level, uint32_t flags) {
+        OP_LOG("Draw bitmap %p matrix " MATRIX_STRING, mBitmap, MATRIX_ARGS(mMatrix));
+    }
+
+    virtual const char* name() { return "DrawBitmap"; }
+
+private:
+    SkBitmap* mBitmap;
+    SkMatrix* mMatrix;
+};
+
+class DrawBitmapRectOp : public DrawBoundedOp {
+public:
+    DrawBitmapRectOp(SkBitmap* bitmap, float srcLeft, float srcTop, float srcRight, float srcBottom,
+            float dstLeft, float dstTop, float dstRight, float dstBottom, SkPaint* paint)
+            : DrawBoundedOp(dstLeft, dstTop, dstRight, dstBottom, paint),
+            mBitmap(bitmap), mSrc(srcLeft, srcTop, srcRight, srcBottom) {}
+
+    virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level,
+            bool caching, int multipliedAlpha) {
+        return renderer.drawBitmap(mBitmap, mSrc.left, mSrc.top, mSrc.right, mSrc.bottom,
+                mLocalBounds.left, mLocalBounds.top, mLocalBounds.right, mLocalBounds.bottom,
+                getPaint(renderer));
+    }
+
+    virtual void output(int level, uint32_t flags) {
+        OP_LOG("Draw bitmap %p src="RECT_STRING", dst="RECT_STRING,
+                mBitmap, RECT_ARGS(mSrc), RECT_ARGS(mLocalBounds));
+    }
+
+    virtual const char* name() { return "DrawBitmapRect"; }
+
+private:
+    SkBitmap* mBitmap;
+    Rect mSrc;
+};
+
+class DrawBitmapDataOp : public DrawBitmapOp {
+public:
+    DrawBitmapDataOp(SkBitmap* bitmap, float left, float top, SkPaint* paint)
+            : DrawBitmapOp(bitmap, left, top, paint) {}
+
+    virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level,
+            bool caching, int multipliedAlpha) {
+        return renderer.drawBitmapData(mBitmap, mLocalBounds.left,
+                mLocalBounds.top, getPaint(renderer));
+    }
+
+    virtual void output(int level, uint32_t flags) {
+        OP_LOG("Draw bitmap %p", mBitmap);
+    }
+
+    virtual const char* name() { return "DrawBitmapData"; }
+};
+
+class DrawBitmapMeshOp : public DrawOp {
+public:
+    DrawBitmapMeshOp(SkBitmap* bitmap, int meshWidth, int meshHeight,
+            float* vertices, int* colors, SkPaint* paint)
+            : DrawOp(paint), mBitmap(bitmap), mMeshWidth(meshWidth), mMeshHeight(meshHeight),
+            mVertices(vertices), mColors(colors) {}
+
+    virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level,
+            bool caching, int multipliedAlpha) {
+        return renderer.drawBitmapMesh(mBitmap, mMeshWidth, mMeshHeight,
+                mVertices, mColors, getPaint(renderer));
+    }
+
+    virtual void output(int level, uint32_t flags) {
+        OP_LOG("Draw bitmap %p mesh %d x %d", mBitmap, mMeshWidth, mMeshHeight);
+    }
+
+    virtual const char* name() { return "DrawBitmapMesh"; }
+
+private:
+    SkBitmap* mBitmap;
+    int mMeshWidth;
+    int mMeshHeight;
+    float* mVertices;
+    int* mColors;
+};
+
+class DrawPatchOp : public DrawBoundedOp {
+public:
+    DrawPatchOp(SkBitmap* bitmap, const int32_t* xDivs,
+            const int32_t* yDivs, const uint32_t* colors, uint32_t width, uint32_t height,
+            int8_t numColors, float left, float top, float right, float bottom,
+            int alpha, SkXfermode::Mode mode)
+            : DrawBoundedOp(left, top, right, bottom, 0),
+            mBitmap(bitmap), mxDivs(xDivs), myDivs(yDivs),
+            mColors(colors), mxDivsCount(width), myDivsCount(height),
+            mNumColors(numColors), mAlpha(alpha), mMode(mode) {};
+
+    virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level,
+            bool caching, int multipliedAlpha) {
+        // NOTE: not calling the virtual method, which takes a paint
+        return renderer.drawPatch(mBitmap, mxDivs, myDivs, mColors,
+                mxDivsCount, myDivsCount, mNumColors,
+                mLocalBounds.left, mLocalBounds.top,
+                mLocalBounds.right, mLocalBounds.bottom, mAlpha, mMode);
+    }
+
+    virtual void output(int level, uint32_t flags) {
+        OP_LOG("Draw patch "RECT_STRING, RECT_ARGS(mLocalBounds));
+    }
+
+    virtual const char* name() { return "DrawPatch"; }
+
+private:
+    SkBitmap* mBitmap;
+    const int32_t* mxDivs;
+    const int32_t* myDivs;
+    const uint32_t* mColors;
+    uint32_t mxDivsCount;
+    uint32_t myDivsCount;
+    int8_t mNumColors;
+    int mAlpha;
+    SkXfermode::Mode mMode;
+};
+
+class DrawColorOp : public DrawOp {
+public:
+    DrawColorOp(int color, SkXfermode::Mode mode)
+            : DrawOp(0), mColor(color), mMode(mode) {};
+
+    virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level,
+            bool caching, int multipliedAlpha) {
+        return renderer.drawColor(mColor, mMode);
+    }
+
+    virtual void output(int level, uint32_t flags) {
+        OP_LOG("Draw color %#x, mode %d", mColor, mMode);
+    }
+
+    virtual const char* name() { return "DrawColor"; }
+
+private:
+    int mColor;
+    SkXfermode::Mode mMode;
+};
+
+class DrawStrokableOp : public DrawBoundedOp {
+public:
+    DrawStrokableOp(float left, float top, float right, float bottom, SkPaint* paint)
+            : DrawBoundedOp(left, top, right, bottom, paint) {};
+
+    bool getLocalBounds(Rect& localBounds) {
+        if (mPaint && mPaint->getStyle() != SkPaint::kFill_Style) {
+            float outset = mPaint->getStrokeWidth() * 0.5f;
+            localBounds.set(mLocalBounds.left - outset, mLocalBounds.top - outset,
+                    mLocalBounds.right + outset, mLocalBounds.bottom + outset);
+        } else {
+            localBounds.set(mLocalBounds);
+        }
+        return true;
+    }
+};
+
+class DrawRectOp : public DrawStrokableOp {
+public:
+    DrawRectOp(float left, float top, float right, float bottom, SkPaint* paint)
+            : DrawStrokableOp(left, top, right, bottom, paint) {}
+
+    virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level,
+            bool caching, int multipliedAlpha) {
+        return renderer.drawRect(mLocalBounds.left, mLocalBounds.top,
+                mLocalBounds.right, mLocalBounds.bottom, getPaint(renderer));
+    }
+
+    virtual void output(int level, uint32_t flags) {
+        OP_LOG("Draw Rect "RECT_STRING, RECT_ARGS(mLocalBounds));
+    }
+
+    virtual const char* name() { return "DrawRect"; }
+};
+
+class DrawRectsOp : public DrawOp {
+public:
+    DrawRectsOp(const float* rects, int count, SkPaint* paint)
+            : DrawOp(paint), mRects(rects), mCount(count) {}
+
+    virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level,
+            bool caching, int multipliedAlpha) {
+        return renderer.drawRects(mRects, mCount, getPaint(renderer));
+    }
+
+    virtual void output(int level, uint32_t flags) {
+        OP_LOG("Draw Rects count %d", mCount);
+    }
+
+    virtual const char* name() { return "DrawRects"; }
+
+private:
+    const float* mRects;
+    int mCount;
+};
+
+class DrawRoundRectOp : public DrawStrokableOp {
+public:
+    DrawRoundRectOp(float left, float top, float right, float bottom,
+            float rx, float ry, SkPaint* paint)
+            : DrawStrokableOp(left, top, right, bottom, paint), mRx(rx), mRy(ry) {}
+
+    virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level,
+            bool caching, int multipliedAlpha) {
+        return renderer.drawRoundRect(mLocalBounds.left, mLocalBounds.top,
+                mLocalBounds.right, mLocalBounds.bottom, mRx, mRy, getPaint(renderer));
+    }
+
+    virtual void output(int level, uint32_t flags) {
+        OP_LOG("Draw RoundRect "RECT_STRING", rx %f, ry %f", RECT_ARGS(mLocalBounds), mRx, mRy);
+    }
+
+    virtual const char* name() { return "DrawRoundRect"; }
+
+private:
+    float mRx;
+    float mRy;
+};
+
+class DrawCircleOp : public DrawStrokableOp {
+public:
+    DrawCircleOp(float x, float y, float radius, SkPaint* paint)
+            : DrawStrokableOp(x - radius, y - radius, x + radius, y + radius, paint),
+            mX(x), mY(y), mRadius(radius) {}
+
+    virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level,
+            bool caching, int multipliedAlpha) {
+        return renderer.drawCircle(mX, mY, mRadius, getPaint(renderer));
+    }
+
+    virtual void output(int level, uint32_t flags) {
+        OP_LOG("Draw Circle x %f, y %f, r %f", mX, mY, mRadius);
+    }
+
+    virtual const char* name() { return "DrawCircle"; }
+
+private:
+    float mX;
+    float mY;
+    float mRadius;
+};
+
+class DrawOvalOp : public DrawStrokableOp {
+public:
+    DrawOvalOp(float left, float top, float right, float bottom, SkPaint* paint)
+            : DrawStrokableOp(left, top, right, bottom, paint) {}
+
+    virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level,
+            bool caching, int multipliedAlpha) {
+        return renderer.drawOval(mLocalBounds.left, mLocalBounds.top,
+                mLocalBounds.right, mLocalBounds.bottom, getPaint(renderer));
+    }
+
+    virtual void output(int level, uint32_t flags) {
+        OP_LOG("Draw Oval "RECT_STRING, RECT_ARGS(mLocalBounds));
+    }
+
+    virtual const char* name() { return "DrawOval"; }
+};
+
+class DrawArcOp : public DrawStrokableOp {
+public:
+    DrawArcOp(float left, float top, float right, float bottom,
+            float startAngle, float sweepAngle, bool useCenter, SkPaint* paint)
+            : DrawStrokableOp(left, top, right, bottom, paint),
+            mStartAngle(startAngle), mSweepAngle(sweepAngle), mUseCenter(useCenter) {}
+
+    virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level,
+            bool caching, int multipliedAlpha) {
+        return renderer.drawArc(mLocalBounds.left, mLocalBounds.top,
+                mLocalBounds.right, mLocalBounds.bottom,
+                mStartAngle, mSweepAngle, mUseCenter, getPaint(renderer));
+    }
+
+    virtual void output(int level, uint32_t flags) {
+        OP_LOG("Draw Arc "RECT_STRING", start %f, sweep %f, useCenter %d",
+                RECT_ARGS(mLocalBounds), mStartAngle, mSweepAngle, mUseCenter);
+    }
+
+    virtual const char* name() { return "DrawArc"; }
+
+private:
+    float mStartAngle;
+    float mSweepAngle;
+    bool mUseCenter;
+};
+
+class DrawPathOp : public DrawBoundedOp {
+public:
+    DrawPathOp(SkPath* path, SkPaint* paint)
+            : DrawBoundedOp(paint), mPath(path) {
+        float left, top, offset;
+        uint32_t width, height;
+        computePathBounds(path, paint, left, top, offset, width, height);
+        left -= offset;
+        top -= offset;
+        mLocalBounds.set(left, top, left + width, top + height);
+    }
+
+    virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level,
+            bool caching, int multipliedAlpha) {
+        return renderer.drawPath(mPath, getPaint(renderer));
+    }
+
+    virtual void output(int level, uint32_t flags) {
+        OP_LOG("Draw Path %p in "RECT_STRING, mPath, RECT_ARGS(mLocalBounds));
+    }
+
+    virtual const char* name() { return "DrawPath"; }
+
+private:
+    SkPath* mPath;
+};
+
+class DrawLinesOp : public DrawOp {
+public:
+    DrawLinesOp(float* points, int count, SkPaint* paint)
+            : DrawOp(paint), mPoints(points), mCount(count) {
+        /* TODO: inherit from DrawBoundedOp and calculate localbounds something like:
+        for (int i = 0; i < count; i += 2) {
+            mLocalBounds.left = fminf(mLocalBounds.left, points[i]);
+            mLocalBounds.right = fmaxf(mLocalBounds.right, points[i]);
+            mLocalBounds.top = fminf(mLocalBounds.top, points[i+1]);
+            mLocalBounds.bottom = fmaxf(mLocalBounds.bottom, points[i+1]);
+        }
+        */
+    }
+
+    virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level,
+            bool caching, int multipliedAlpha) {
+        return renderer.drawLines(mPoints, mCount, getPaint(renderer));
+    }
+
+    virtual void output(int level, uint32_t flags) {
+        OP_LOG("Draw Lines count %d", mCount);
+    }
+
+    virtual const char* name() { return "DrawLines"; }
+
+protected:
+    float* mPoints;
+    int mCount;
+};
+
+class DrawPointsOp : public DrawLinesOp {
+public:
+    DrawPointsOp(float* points, int count, SkPaint* paint)
+            : DrawLinesOp(points, count, paint) {}
+
+    virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level,
+            bool caching, int multipliedAlpha) {
+        return renderer.drawPoints(mPoints, mCount, getPaint(renderer));
+    }
+
+    virtual void output(int level, uint32_t flags) {
+        OP_LOG("Draw Points count %d", mCount);
+    }
+
+    virtual const char* name() { return "DrawPoints"; }
+};
+
+class DrawSomeTextOp : public DrawOp {
+public:
+    DrawSomeTextOp(const char* text, int bytesCount, int count, SkPaint* paint)
+            : DrawOp(paint), mText(text), mBytesCount(bytesCount), mCount(count) {};
+
+    virtual void output(int level, uint32_t flags) {
+        OP_LOG("Draw some text, %d bytes", mBytesCount);
+    }
+protected:
+    const char* mText;
+    int mBytesCount;
+    int mCount;
+};
+
+class DrawTextOnPathOp : public DrawSomeTextOp {
+public:
+    DrawTextOnPathOp(const char* text, int bytesCount, int count,
+            SkPath* path, float hOffset, float vOffset, SkPaint* paint)
+            : DrawSomeTextOp(text, bytesCount, count, paint),
+            mPath(path), mHOffset(hOffset), mVOffset(vOffset) {
+        /* TODO: inherit from DrawBounded and init mLocalBounds */
+    }
+
+    virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level,
+            bool caching, int multipliedAlpha) {
+        return renderer.drawTextOnPath(mText, mBytesCount, mCount, mPath,
+                mHOffset, mVOffset, getPaint(renderer));
+    }
+
+    virtual const char* name() { return "DrawTextOnPath"; }
+
+private:
+    SkPath* mPath;
+    float mHOffset;
+    float mVOffset;
+};
+
+class DrawPosTextOp : public DrawSomeTextOp {
+public:
+    DrawPosTextOp(const char* text, int bytesCount, int count,
+            const float* positions, SkPaint* paint)
+            : DrawSomeTextOp(text, bytesCount, count, paint), mPositions(positions) {
+        /* TODO: inherit from DrawBounded and init mLocalBounds */
+    }
+
+    virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level,
+            bool caching, int multipliedAlpha) {
+        return renderer.drawPosText(mText, mBytesCount, mCount, mPositions, getPaint(renderer));
+    }
+
+    virtual const char* name() { return "DrawPosText"; }
+
+private:
+    const float* mPositions;
+};
+
+class DrawTextOp : public DrawBoundedOp {
+public:
+    DrawTextOp(const char* text, int bytesCount, int count, float x, float y,
+            const float* positions, SkPaint* paint, float length)
+            : DrawBoundedOp(paint), mText(text), mBytesCount(bytesCount), mCount(count),
+            mX(x), mY(y), mPositions(positions), mLength(length) {
+        SkPaint::FontMetrics metrics;
+        paint->getFontMetrics(&metrics, 0.0f);
+        mLocalBounds.set(mX, mY + metrics.fTop, mX + length, mY + metrics.fBottom);
+    }
+
+    virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level,
+            bool caching, int multipliedAlpha) {
+        return renderer.drawText(mText, mBytesCount, mCount, mX, mY,
+                mPositions, getPaint(renderer), mLength);
+    }
+
+    virtual void output(int level, uint32_t flags) {
+        OP_LOG("Draw Text of count %d, bytes %d", mCount, mBytesCount);
+    }
+
+    virtual const char* name() { return "DrawText"; }
+
+private:
+    const char* mText;
+    int mBytesCount;
+    int mCount;
+    float mX;
+    float mY;
+    const float* mPositions;
+    float mLength;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// SPECIAL DRAW OPERATIONS
+///////////////////////////////////////////////////////////////////////////////
+
+class DrawFunctorOp : public DrawOp {
+public:
+    DrawFunctorOp(Functor* functor)
+            : DrawOp(0), mFunctor(functor) {}
+
+    virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level,
+            bool caching, int multipliedAlpha) {
+        renderer.startMark("GL functor");
+        status_t ret = renderer.callDrawGLFunction(mFunctor, dirty);
+        renderer.endMark();
+        return ret;
+    }
+
+    virtual void output(int level, uint32_t flags) {
+        OP_LOG("Draw Functor %p", mFunctor);
+    }
+
+    virtual const char* name() { return "DrawFunctor"; }
+
+private:
+    Functor* mFunctor;
+};
+
+class DrawDisplayListOp : public DrawOp {
+public:
+    DrawDisplayListOp(DisplayList* displayList, int flags)
+            : DrawOp(0), mDisplayList(displayList), mFlags(flags) {}
+    virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level,
+            bool caching, int multipliedAlpha) {
+        return renderer.drawDisplayList(mDisplayList, dirty, mFlags, level + 1);
+    }
+
+    virtual void output(int level, uint32_t flags) {
+        OP_LOG("Draw Display List %p, flags %#x", mDisplayList, mFlags);
+        if (mDisplayList && (flags & kOpLogFlag_Recurse)) {
+            mDisplayList->output(level + 1);
+        }
+    }
+
+    virtual const char* name() { return "DrawDisplayList"; }
+
+private:
+    DisplayList* mDisplayList;
+    int mFlags;
+};
+
+class DrawLayerOp : public DrawOp {
+public:
+    DrawLayerOp(Layer* layer, float x, float y, SkPaint* paint)
+            : DrawOp(paint), mLayer(layer), mX(x), mY(y) {}
+
+    virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level,
+            bool caching, int multipliedAlpha) {
+        int oldAlpha = -1;
+
+        if (caching && multipliedAlpha < 255) {
+            oldAlpha = mLayer->getAlpha();
+            mLayer->setAlpha(multipliedAlpha);
+        }
+        status_t ret = renderer.drawLayer(mLayer, mX, mY, getPaint(renderer));
+        if (oldAlpha >= 0) {
+            mLayer->setAlpha(oldAlpha);
+        }
+        return ret;
+    }
+
+    virtual void output(int level, uint32_t flags) {
+        OP_LOG("Draw Layer %p at %f %f", mLayer, mX, mY);
+    }
+
+    virtual const char* name() { return "DrawLayer"; }
+
+private:
+    Layer* mLayer;
+    float mX;
+    float mY;
+};
+
+}; // namespace uirenderer
+}; // namespace android
+
+#endif // ANDROID_HWUI_DISPLAY_OPERATION_H
diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp
index f0c9ce4..5cb629e 100644
--- a/libs/hwui/DisplayListRenderer.cpp
+++ b/libs/hwui/DisplayListRenderer.cpp
@@ -21,6 +21,7 @@
 #include <private/hwui/DrawGlInfo.h>
 
 #include "DisplayListLogBuffer.h"
+#include "DisplayListOp.h"
 #include "DisplayListRenderer.h"
 #include "Caches.h"
 
@@ -31,53 +32,6 @@
 // Display list
 ///////////////////////////////////////////////////////////////////////////////
 
-const char* DisplayList::OP_NAMES[] = {
-    "Save",
-    "Restore",
-    "RestoreToCount",
-    "SaveLayer",
-    "SaveLayerAlpha",
-    "Translate",
-    "Rotate",
-    "Scale",
-    "Skew",
-    "SetMatrix",
-    "ConcatMatrix",
-    "ClipRect",
-    "ClipPath",
-    "ClipRegion",
-    "DrawDisplayList",
-    "DrawLayer",
-    "DrawBitmap",
-    "DrawBitmapMatrix",
-    "DrawBitmapRect",
-    "DrawBitmapData",
-    "DrawBitmapMesh",
-    "DrawPatch",
-    "DrawColor",
-    "DrawRect",
-    "DrawRoundRect",
-    "DrawCircle",
-    "DrawOval",
-    "DrawArc",
-    "DrawPath",
-    "DrawLines",
-    "DrawPoints",
-    "DrawTextOnPath",
-    "DrawPosText",
-    "DrawText",
-    "DrawRects",
-    "ResetShader",
-    "SetupShader",
-    "ResetColorFilter",
-    "SetupColorFilter",
-    "ResetShadow",
-    "SetupShadow",
-    "ResetPaintFilter",
-    "SetupPaintFilter",
-    "DrawGLFunction"
-};
-
 void DisplayList::outputLogBuffer(int fd) {
     DisplayListLogBuffer& logBuffer = DisplayListLogBuffer::getInstance();
     if (logBuffer.isEmpty()) {
@@ -87,7 +41,7 @@
     FILE *file = fdopen(fd, "a");
 
     fprintf(file, "\nRecent DisplayList operations\n");
-    logBuffer.outputCommands(file, OP_NAMES);
+    logBuffer.outputCommands(file);
 
     String8 cachesLog;
     Caches::getInstance().dumpMemoryUsage(cachesLog);
@@ -116,9 +70,7 @@
 }
 
 void DisplayList::clearResources() {
-    sk_free((void*) mReader.base());
-    mReader.setMemory(NULL, 0);
-
+    mDisplayListData = NULL;
     delete mTransformMatrix;
     delete mTransformCamera;
     delete mTransformMatrix3D;
@@ -200,7 +152,6 @@
 }
 
 void DisplayList::initFromDisplayListRenderer(const DisplayListRenderer& recorder, bool reusing) {
-
     if (reusing) {
         // re-using display list - clear out previous allocations
         clearResources();
@@ -208,16 +159,13 @@
 
     init();
 
-    const SkWriter32& writer = recorder.writeStream();
-    if (writer.size() == 0) {
+    mDisplayListData = recorder.getDisplayListData();
+    mSize = mDisplayListData->allocator.usedSize();
+
+    if (mSize == 0) {
         return;
     }
 
-    mSize = writer.size();
-    void* buffer = sk_malloc_throw(mSize);
-    writer.flatten(buffer);
-    mReader.setMemory(buffer, mSize);
-
     mFunctorCount = recorder.getFunctorCount();
 
     Caches& caches = Caches::getInstance();
@@ -312,392 +260,17 @@
  * This function is a simplified version of replay(), where we simply retrieve and log the
  * display list. This function should remain in sync with the replay() function.
  */
-void DisplayList::output(OpenGLRenderer& renderer, uint32_t level) {
-    TextContainer text;
-
-    uint32_t count = (level + 1) * 2;
-    char indent[count + 1];
-    for (uint32_t i = 0; i < count; i++) {
-        indent[i] = ' ';
-    }
-    indent[count] = '\0';
-    ALOGD("%sStart display list (%p, %s, render=%d)", (char*) indent + 2, this,
+void DisplayList::output(uint32_t level) {
+    ALOGD("%*sStart display list (%p, %s, render=%d)", level * 2, "", this,
             mName.string(), isRenderable());
 
-    ALOGD("%s%s %d", indent, "Save", SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
-    int saveCount = renderer.getSaveCount() - 1;
-
-    outputViewProperties(renderer, (char*) indent);
-    mReader.rewind();
-
-    while (!mReader.eof()) {
-        int op = mReader.readInt();
-        if (op & OP_MAY_BE_SKIPPED_MASK) {
-            int skip = mReader.readInt();
-            ALOGD("%sSkip %d", (char*) indent, skip);
-            op &= ~OP_MAY_BE_SKIPPED_MASK;
-        }
-
-        switch (op) {
-            case DrawGLFunction: {
-                Functor *functor = (Functor *) getInt();
-                ALOGD("%s%s %p", (char*) indent, OP_NAMES[op], functor);
-            }
-            break;
-            case Save: {
-                int rendererNum = getInt();
-                ALOGD("%s%s %d", (char*) indent, OP_NAMES[op], rendererNum);
-            }
-            break;
-            case Restore: {
-                ALOGD("%s%s", (char*) indent, OP_NAMES[op]);
-            }
-            break;
-            case RestoreToCount: {
-                int restoreCount = saveCount + getInt();
-                ALOGD("%s%s %d", (char*) indent, OP_NAMES[op], restoreCount);
-            }
-            break;
-            case SaveLayer: {
-                float f1 = getFloat();
-                float f2 = getFloat();
-                float f3 = getFloat();
-                float f4 = getFloat();
-                SkPaint* paint = getPaint(renderer);
-                int flags = getInt();
-                ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p, 0x%x", (char*) indent,
-                        OP_NAMES[op], f1, f2, f3, f4, paint, flags);
-            }
-            break;
-            case SaveLayerAlpha: {
-                float f1 = getFloat();
-                float f2 = getFloat();
-                float f3 = getFloat();
-                float f4 = getFloat();
-                int alpha = getInt();
-                int flags = getInt();
-                ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %d, 0x%x", (char*) indent,
-                        OP_NAMES[op], f1, f2, f3, f4, alpha, flags);
-            }
-            break;
-            case Translate: {
-                float f1 = getFloat();
-                float f2 = getFloat();
-                ALOGD("%s%s %.2f, %.2f", (char*) indent, OP_NAMES[op], f1, f2);
-            }
-            break;
-            case Rotate: {
-                float rotation = getFloat();
-                ALOGD("%s%s %.2f", (char*) indent, OP_NAMES[op], rotation);
-            }
-            break;
-            case Scale: {
-                float sx = getFloat();
-                float sy = getFloat();
-                ALOGD("%s%s %.2f, %.2f", (char*) indent, OP_NAMES[op], sx, sy);
-            }
-            break;
-            case Skew: {
-                float sx = getFloat();
-                float sy = getFloat();
-                ALOGD("%s%s %.2f, %.2f", (char*) indent, OP_NAMES[op], sx, sy);
-            }
-            break;
-            case SetMatrix: {
-                SkMatrix* matrix = getMatrix();
-                ALOGD("%s%s %p", (char*) indent, OP_NAMES[op], matrix);
-            }
-            break;
-            case ConcatMatrix: {
-                SkMatrix* matrix = getMatrix();
-                ALOGD("%s%s new concat %p: [%f, %f, %f]   [%f, %f, %f]   [%f, %f, %f]",
-                        (char*) indent, OP_NAMES[op], matrix, matrix->get(0), matrix->get(1),
-                        matrix->get(2), matrix->get(3), matrix->get(4), matrix->get(5),
-                        matrix->get(6), matrix->get(7), matrix->get(8));
-            }
-            break;
-            case ClipRect: {
-                float f1 = getFloat();
-                float f2 = getFloat();
-                float f3 = getFloat();
-                float f4 = getFloat();
-                int regionOp = getInt();
-                ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %d", (char*) indent, OP_NAMES[op],
-                        f1, f2, f3, f4, regionOp);
-            }
-            break;
-            case ClipPath: {
-                SkPath* path = getPath();
-                int regionOp = getInt();
-                ALOGD("%s%s %d", (char*) indent, OP_NAMES[op], regionOp);
-            }
-            break;
-            case ClipRegion: {
-                SkRegion* region = getRegion();
-                int regionOp = getInt();
-                ALOGD("%s%s %d", (char*) indent, OP_NAMES[op], regionOp);
-            }
-            break;
-            case DrawDisplayList: {
-                DisplayList* displayList = getDisplayList();
-                int32_t flags = getInt();
-                ALOGD("%s%s %p, %dx%d, 0x%x %d", (char*) indent, OP_NAMES[op],
-                        displayList, mWidth, mHeight, flags, level + 1);
-                renderer.outputDisplayList(displayList, level + 1);
-            }
-            break;
-            case DrawLayer: {
-                Layer* layer = (Layer*) getInt();
-                float x = getFloat();
-                float y = getFloat();
-                SkPaint* paint = getPaint(renderer);
-                ALOGD("%s%s %p, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
-                        layer, x, y, paint);
-            }
-            break;
-            case DrawBitmap: {
-                SkBitmap* bitmap = getBitmap();
-                float x = getFloat();
-                float y = getFloat();
-                SkPaint* paint = getPaint(renderer);
-                ALOGD("%s%s %p, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
-                        bitmap, x, y, paint);
-            }
-            break;
-            case DrawBitmapMatrix: {
-                SkBitmap* bitmap = getBitmap();
-                SkMatrix* matrix = getMatrix();
-                SkPaint* paint = getPaint(renderer);
-                ALOGD("%s%s %p, %p, %p", (char*) indent, OP_NAMES[op],
-                        bitmap, matrix, paint);
-            }
-            break;
-            case DrawBitmapRect: {
-                SkBitmap* bitmap = getBitmap();
-                float f1 = getFloat();
-                float f2 = getFloat();
-                float f3 = getFloat();
-                float f4 = getFloat();
-                float f5 = getFloat();
-                float f6 = getFloat();
-                float f7 = getFloat();
-                float f8 = getFloat();
-                SkPaint* paint = getPaint(renderer);
-                ALOGD("%s%s %p, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %p",
-                        (char*) indent, OP_NAMES[op], bitmap, f1, f2, f3, f4, f5, f6, f7, f8, paint);
-            }
-            break;
-            case DrawBitmapData: {
-                SkBitmap* bitmap = getBitmapData();
-                float x = getFloat();
-                float y = getFloat();
-                SkPaint* paint = getPaint(renderer);
-                ALOGD("%s%s %.2f, %.2f, %p", (char*) indent, OP_NAMES[op], x, y, paint);
-            }
-            break;
-            case DrawBitmapMesh: {
-                int verticesCount = 0;
-                uint32_t colorsCount = 0;
-                SkBitmap* bitmap = getBitmap();
-                uint32_t meshWidth = getInt();
-                uint32_t meshHeight = getInt();
-                float* vertices = getFloats(verticesCount);
-                bool hasColors = getInt();
-                int* colors = hasColors ? getInts(colorsCount) : NULL;
-                SkPaint* paint = getPaint(renderer);
-                ALOGD("%s%s", (char*) indent, OP_NAMES[op]);
-            }
-            break;
-            case DrawPatch: {
-                int32_t* xDivs = NULL;
-                int32_t* yDivs = NULL;
-                uint32_t* colors = NULL;
-                uint32_t xDivsCount = 0;
-                uint32_t yDivsCount = 0;
-                int8_t numColors = 0;
-                SkBitmap* bitmap = getBitmap();
-                xDivs = getInts(xDivsCount);
-                yDivs = getInts(yDivsCount);
-                colors = getUInts(numColors);
-                float left = getFloat();
-                float top = getFloat();
-                float right = getFloat();
-                float bottom = getFloat();
-                int alpha = getInt();
-                SkXfermode::Mode mode = (SkXfermode::Mode) getInt();
-                ALOGD("%s%s %.2f, %.2f, %.2f, %.2f", (char*) indent, OP_NAMES[op],
-                        left, top, right, bottom);
-            }
-            break;
-            case DrawColor: {
-                int color = getInt();
-                int xferMode = getInt();
-                ALOGD("%s%s 0x%x %d", (char*) indent, OP_NAMES[op], color, xferMode);
-            }
-            break;
-            case DrawRect: {
-                float f1 = getFloat();
-                float f2 = getFloat();
-                float f3 = getFloat();
-                float f4 = getFloat();
-                SkPaint* paint = getPaint(renderer);
-                ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
-                        f1, f2, f3, f4, paint);
-            }
-            break;
-            case DrawRoundRect: {
-                float f1 = getFloat();
-                float f2 = getFloat();
-                float f3 = getFloat();
-                float f4 = getFloat();
-                float f5 = getFloat();
-                float f6 = getFloat();
-                SkPaint* paint = getPaint(renderer);
-                ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %p",
-                        (char*) indent, OP_NAMES[op], f1, f2, f3, f4, f5, f6, paint);
-            }
-            break;
-            case DrawCircle: {
-                float f1 = getFloat();
-                float f2 = getFloat();
-                float f3 = getFloat();
-                SkPaint* paint = getPaint(renderer);
-                ALOGD("%s%s %.2f, %.2f, %.2f, %p",
-                        (char*) indent, OP_NAMES[op], f1, f2, f3, paint);
-            }
-            break;
-            case DrawOval: {
-                float f1 = getFloat();
-                float f2 = getFloat();
-                float f3 = getFloat();
-                float f4 = getFloat();
-                SkPaint* paint = getPaint(renderer);
-                ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p",
-                        (char*) indent, OP_NAMES[op], f1, f2, f3, f4, paint);
-            }
-            break;
-            case DrawArc: {
-                float f1 = getFloat();
-                float f2 = getFloat();
-                float f3 = getFloat();
-                float f4 = getFloat();
-                float f5 = getFloat();
-                float f6 = getFloat();
-                int i1 = getInt();
-                SkPaint* paint = getPaint(renderer);
-                ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %d, %p",
-                        (char*) indent, OP_NAMES[op], f1, f2, f3, f4, f5, f6, i1, paint);
-            }
-            break;
-            case DrawPath: {
-                SkPath* path = getPath();
-                SkPaint* paint = getPaint(renderer);
-                ALOGD("%s%s %p, %p", (char*) indent, OP_NAMES[op], path, paint);
-            }
-            break;
-            case DrawLines: {
-                int count = 0;
-                float* points = getFloats(count);
-                SkPaint* paint = getPaint(renderer);
-                ALOGD("%s%s", (char*) indent, OP_NAMES[op]);
-            }
-            break;
-            case DrawPoints: {
-                int count = 0;
-                float* points = getFloats(count);
-                SkPaint* paint = getPaint(renderer);
-                ALOGD("%s%s", (char*) indent, OP_NAMES[op]);
-            }
-            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();
-                int positionsCount = 0;
-                float* positions = getFloats(positionsCount);
-                SkPaint* paint = getPaint(renderer);
-                ALOGD("%s%s %s, %d, %d, %p", (char*) indent, OP_NAMES[op],
-                        text.text(), text.length(), count, paint);
-            }
-            break;
-            case DrawText: {
-                getText(&text);
-                int32_t count = getInt();
-                float x = getFloat();
-                float y = getFloat();
-                int32_t positionsCount = 0;
-                float* positions = getFloats(positionsCount);
-                SkPaint* paint = getPaint(renderer);
-                float length = getFloat();
-                ALOGD("%s%s %s, %d, %d, %p", (char*) indent, OP_NAMES[op],
-                        text.text(), text.length(), count, paint);
-            }
-            break;
-            case DrawRects: {
-                int32_t count = 0;
-                float* rects = getFloats(count);
-                SkPaint* paint = getPaint(renderer);
-                ALOGD("%s%s %d, %p", (char*) indent, OP_NAMES[op], count / 4, paint);
-            }
-            break;
-            case ResetShader: {
-                ALOGD("%s%s", (char*) indent, OP_NAMES[op]);
-            }
-            break;
-            case SetupShader: {
-                SkiaShader* shader = getShader();
-                ALOGD("%s%s %p", (char*) indent, OP_NAMES[op], shader);
-            }
-            break;
-            case ResetColorFilter: {
-                ALOGD("%s%s", (char*) indent, OP_NAMES[op]);
-            }
-            break;
-            case SetupColorFilter: {
-                SkiaColorFilter *colorFilter = getColorFilter();
-                ALOGD("%s%s %p", (char*) indent, OP_NAMES[op], colorFilter);
-            }
-            break;
-            case ResetShadow: {
-                ALOGD("%s%s", (char*) indent, OP_NAMES[op]);
-            }
-            break;
-            case SetupShadow: {
-                float radius = getFloat();
-                float dx = getFloat();
-                float dy = getFloat();
-                int color = getInt();
-                ALOGD("%s%s %.2f, %.2f, %.2f, 0x%x", (char*) indent, OP_NAMES[op],
-                        radius, dx, dy, color);
-            }
-            break;
-            case ResetPaintFilter: {
-                ALOGD("%s%s", (char*) indent, OP_NAMES[op]);
-            }
-            break;
-            case SetupPaintFilter: {
-                int clearBits = getInt();
-                int setBits = getInt();
-                ALOGD("%s%s 0x%x, 0x%x", (char*) indent, OP_NAMES[op], clearBits, setBits);
-            }
-            break;
-            default:
-                ALOGD("Display List error: op not handled: %s%s",
-                        (char*) indent, OP_NAMES[op]);
-                break;
-        }
+    ALOGD("%*s%s %d", level * 4, "", "Save", SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
+    outputViewProperties(level);
+    int flags = DisplayListOp::kOpLogFlag_Recurse;
+    for (unsigned int i = 0; i < mDisplayListData->displayListOps.size(); i++) {
+        mDisplayListData->displayListOps[i]->output(level, flags);
     }
-    ALOGD("%sDone (%p, %s)", (char*) indent + 2, this, mName.string());
+    ALOGD("%*sDone (%p, %s)", level * 2, "", this, mName.string());
 }
 
 void DisplayList::updateMatrix() {
@@ -743,115 +316,68 @@
     }
 }
 
-void DisplayList::outputViewProperties(OpenGLRenderer& renderer, char* indent) {
+void DisplayList::outputViewProperties(uint32_t level) {
     updateMatrix();
     if (mLeft != 0 || mTop != 0) {
-        ALOGD("%s%s %d, %d", indent, "Translate (left, top)", mLeft, mTop);
+        ALOGD("%*sTranslate (left, top) %d, %d", level * 2, "", mLeft, mTop);
     }
     if (mStaticMatrix) {
-        ALOGD("%s%s %p: [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f]",
-                indent, "ConcatMatrix (static)", mStaticMatrix,
-                mStaticMatrix->get(0), mStaticMatrix->get(1),
-                mStaticMatrix->get(2), mStaticMatrix->get(3),
-                mStaticMatrix->get(4), mStaticMatrix->get(5),
-                mStaticMatrix->get(6), mStaticMatrix->get(7),
-                mStaticMatrix->get(8));
+        ALOGD("%*sConcatMatrix (static) %p: " MATRIX_STRING,
+                level * 2, "", mStaticMatrix, MATRIX_ARGS(mStaticMatrix));
     }
     if (mAnimationMatrix) {
-        ALOGD("%s%s %p: [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f]",
-                indent, "ConcatMatrix (animation)", mAnimationMatrix,
-                mAnimationMatrix->get(0), mAnimationMatrix->get(1),
-                mAnimationMatrix->get(2), mAnimationMatrix->get(3),
-                mAnimationMatrix->get(4), mAnimationMatrix->get(5),
-                mAnimationMatrix->get(6), mAnimationMatrix->get(7),
-                mAnimationMatrix->get(8));
+        ALOGD("%*sConcatMatrix (animation) %p: " MATRIX_STRING,
+                level * 2, "", mAnimationMatrix, MATRIX_ARGS(mStaticMatrix));
     }
     if (mMatrixFlags != 0) {
         if (mMatrixFlags == TRANSLATION) {
-            ALOGD("%s%s %f, %f", indent, "Translate", mTranslationX, mTranslationY);
+            ALOGD("%*sTranslate %f, %f", level * 2, "", mTranslationX, mTranslationY);
         } else {
-            ALOGD("%s%s %p: [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f]",
-                    indent, "ConcatMatrix", mTransformMatrix,
-                    mTransformMatrix->get(0), mTransformMatrix->get(1),
-                    mTransformMatrix->get(2), mTransformMatrix->get(3),
-                    mTransformMatrix->get(4), mTransformMatrix->get(5),
-                    mTransformMatrix->get(6), mTransformMatrix->get(7),
-                    mTransformMatrix->get(8));
+            ALOGD("%*sConcatMatrix %p: " MATRIX_STRING,
+                    level * 2, "", mTransformMatrix, MATRIX_ARGS(mTransformMatrix));
         }
     }
     if (mAlpha < 1 && !mCaching) {
         if (!mHasOverlappingRendering) {
-            ALOGD("%s%s %.2f", indent, "SetAlpha", mAlpha);
+            ALOGD("%*sSetAlpha %.2f", level * 2, "", mAlpha);
         } else {
             int flags = SkCanvas::kHasAlphaLayer_SaveFlag;
             if (mClipChildren) {
                 flags |= SkCanvas::kClipToLayer_SaveFlag;
             }
-            ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %d, 0x%x", indent, "SaveLayerAlpha",
+            ALOGD("%*sSaveLayerAlpha %.2f, %.2f, %.2f, %.2f, %d, 0x%x", level * 2, "",
                     (float) 0, (float) 0, (float) mRight - mLeft, (float) mBottom - mTop,
                     mMultipliedAlpha, flags);
         }
     }
     if (mClipChildren) {
-        ALOGD("%s%s %.2f, %.2f, %.2f, %.2f", indent, "ClipRect", 0.0f, 0.0f,
+        ALOGD("%*sClipRect %.2f, %.2f, %.2f, %.2f", level * 2, "", 0.0f, 0.0f,
                 (float) mRight - mLeft, (float) mBottom - mTop);
     }
 }
 
 void DisplayList::setViewProperties(OpenGLRenderer& renderer, uint32_t level) {
-#if DEBUG_DISPLAY_LIST
-        uint32_t count = (level + 1) * 2;
-        char indent[count + 1];
-        for (uint32_t i = 0; i < count; i++) {
-            indent[i] = ' ';
-        }
-        indent[count] = '\0';
+#if DEBUG_DISPLAYLIST
+    outputViewProperties(level);
 #endif
     updateMatrix();
     if (mLeft != 0 || mTop != 0) {
-        DISPLAY_LIST_LOGD("%s%s %d, %d", indent, "Translate (left, top)", mLeft, mTop);
         renderer.translate(mLeft, mTop);
     }
     if (mStaticMatrix) {
-        DISPLAY_LIST_LOGD(
-                "%s%s %p: [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f]",
-                indent, "ConcatMatrix (static)", mStaticMatrix,
-                mStaticMatrix->get(0), mStaticMatrix->get(1),
-                mStaticMatrix->get(2), mStaticMatrix->get(3),
-                mStaticMatrix->get(4), mStaticMatrix->get(5),
-                mStaticMatrix->get(6), mStaticMatrix->get(7),
-                mStaticMatrix->get(8));
         renderer.concatMatrix(mStaticMatrix);
     } else if (mAnimationMatrix) {
-        DISPLAY_LIST_LOGD(
-                "%s%s %p: [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f]",
-                indent, "ConcatMatrix (animation)", mAnimationMatrix,
-                mAnimationMatrix->get(0), mAnimationMatrix->get(1),
-                mAnimationMatrix->get(2), mAnimationMatrix->get(3),
-                mAnimationMatrix->get(4), mAnimationMatrix->get(5),
-                mAnimationMatrix->get(6), mAnimationMatrix->get(7),
-                mAnimationMatrix->get(8));
         renderer.concatMatrix(mAnimationMatrix);
     }
     if (mMatrixFlags != 0) {
         if (mMatrixFlags == TRANSLATION) {
-            DISPLAY_LIST_LOGD("%s%s %f, %f", indent, "Translate", mTranslationX, mTranslationY);
             renderer.translate(mTranslationX, mTranslationY);
         } else {
-            DISPLAY_LIST_LOGD(
-                    "%s%s %p: [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f]",
-                    indent, "ConcatMatrix", mTransformMatrix,
-                    mTransformMatrix->get(0), mTransformMatrix->get(1),
-                    mTransformMatrix->get(2), mTransformMatrix->get(3),
-                    mTransformMatrix->get(4), mTransformMatrix->get(5),
-                    mTransformMatrix->get(6), mTransformMatrix->get(7),
-                    mTransformMatrix->get(8));
             renderer.concatMatrix(mTransformMatrix);
         }
     }
     if (mAlpha < 1 && !mCaching) {
         if (!mHasOverlappingRendering) {
-            DISPLAY_LIST_LOGD("%s%s %.2f", indent, "SetAlpha", mAlpha);
             renderer.setAlpha(mAlpha);
         } else {
             // TODO: should be able to store the size of a DL at record time and not
@@ -861,53 +387,35 @@
             if (mClipChildren) {
                 flags |= SkCanvas::kClipToLayer_SaveFlag;
             }
-            DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %d, 0x%x", indent, "SaveLayerAlpha",
-                    (float) 0, (float) 0, (float) mRight - mLeft, (float) mBottom - mTop,
-                    mMultipliedAlpha, flags);
             renderer.saveLayerAlpha(0, 0, mRight - mLeft, mBottom - mTop,
                     mMultipliedAlpha, flags);
         }
     }
     if (mClipChildren) {
-        DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f", indent, "ClipRect", 0.0f, 0.0f,
-                (float) mRight - mLeft, (float) mBottom - mTop);
         renderer.clipRect(0, 0, mRight - mLeft, mBottom - mTop,
                 SkRegion::kIntersect_Op);
     }
 }
 
-/**
- * Changes to replay(), specifically those involving opcode or parameter changes, should be mimicked
- * in the output() function, since that function processes the same list of opcodes for the
- * purposes of logging display list info for a given view.
- */
 status_t DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, uint32_t level) {
     status_t drawGlStatus = DrawGlInfo::kStatusDone;
-    TextContainer text;
-    mReader.rewind();
 
 #if DEBUG_DISPLAY_LIST
-    uint32_t count = (level + 1) * 2;
-    char indent[count + 1];
-    for (uint32_t i = 0; i < count; i++) {
-        indent[i] = ' ';
-    }
-    indent[count] = '\0';
     Rect* clipRect = renderer.getClipRect();
-    DISPLAY_LIST_LOGD("%sStart display list (%p, %s), clipRect: %.0f, %.f, %.0f, %.0f",
-            (char*) indent + 2, this, mName.string(), clipRect->left, clipRect->top,
+    DISPLAY_LIST_LOGD("%*sStart display list (%p, %s), clipRect: %.0f, %.f, %.0f, %.0f",
+            (level+1)*2, "", this, mName.string(), clipRect->left, clipRect->top,
             clipRect->right, clipRect->bottom);
 #endif
 
     renderer.startMark(mName.string());
 
     int restoreTo = renderer.save(SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
-    DISPLAY_LIST_LOGD("%s%s %d %d", indent, "Save",
+    DISPLAY_LIST_LOGD("%*sSave %d %d", level * 2, "",
             SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag, restoreTo);
     setViewProperties(renderer, level);
 
     if (renderer.quickRejectNoScissor(0, 0, mWidth, mHeight)) {
-        DISPLAY_LIST_LOGD("%s%s %d", (char*) indent, "RestoreToCount", restoreTo);
+        DISPLAY_LIST_LOGD("%*sRestoreToCount %d", level * 2, "", restoreTo);
         renderer.restoreToCount(restoreTo);
         renderer.endMark();
         return drawGlStatus;
@@ -915,469 +423,22 @@
 
     DisplayListLogBuffer& logBuffer = DisplayListLogBuffer::getInstance();
     int saveCount = renderer.getSaveCount() - 1;
-
-    while (!mReader.eof()) {
-        int op = mReader.readInt();
-        if (op & OP_MAY_BE_SKIPPED_MASK) {
-            int32_t skip = mReader.readInt();
-            if (CC_LIKELY(flags & kReplayFlag_ClipChildren)) {
-                mReader.skip(skip);
-                DISPLAY_LIST_LOGD("%s%s skipping %d bytes", (char*) indent,
-                        OP_NAMES[op & ~OP_MAY_BE_SKIPPED_MASK], skip);
-                continue;
-            } else {
-                op &= ~OP_MAY_BE_SKIPPED_MASK;
-            }
-        }
-        logBuffer.writeCommand(level, op);
-
+    for (unsigned int i = 0; i < mDisplayListData->displayListOps.size(); i++) {
+        DisplayListOp *op = mDisplayListData->displayListOps[i];
 #if DEBUG_DISPLAY_LIST_OPS_AS_EVENTS
-        Caches::getInstance().eventMark(strlen(OP_NAMES[op]), OP_NAMES[op]);
+        Caches::getInstance().eventMark(strlen(op->name()), op->name());
 #endif
 
-        switch (op) {
-            case DrawGLFunction: {
-                Functor *functor = (Functor *) getInt();
-                DISPLAY_LIST_LOGD("%s%s %p", (char*) indent, OP_NAMES[op], functor);
-                renderer.startMark("GL functor");
-                drawGlStatus |= renderer.callDrawGLFunction(functor, dirty);
-                renderer.endMark();
-            }
-            break;
-            case Save: {
-                int32_t rendererNum = getInt();
-                DISPLAY_LIST_LOGD("%s%s %d", (char*) indent, OP_NAMES[op], rendererNum);
-                renderer.save(rendererNum);
-            }
-            break;
-            case Restore: {
-                DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
-                renderer.restore();
-            }
-            break;
-            case RestoreToCount: {
-                int32_t restoreCount = saveCount + getInt();
-                DISPLAY_LIST_LOGD("%s%s %d", (char*) indent, OP_NAMES[op], restoreCount);
-                renderer.restoreToCount(restoreCount);
-            }
-            break;
-            case SaveLayer: {
-                float f1 = getFloat();
-                float f2 = getFloat();
-                float f3 = getFloat();
-                float f4 = getFloat();
-                SkPaint* paint = getPaint(renderer);
-                int32_t flags = getInt();
-                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p, 0x%x", (char*) indent,
-                        OP_NAMES[op], f1, f2, f3, f4, paint, flags);
-                renderer.saveLayer(f1, f2, f3, f4, paint, flags);
-            }
-            break;
-            case SaveLayerAlpha: {
-                float f1 = getFloat();
-                float f2 = getFloat();
-                float f3 = getFloat();
-                float f4 = getFloat();
-                int32_t alpha = getInt();
-                int32_t flags = getInt();
-                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %d, 0x%x", (char*) indent,
-                        OP_NAMES[op], f1, f2, f3, f4, alpha, flags);
-                renderer.saveLayerAlpha(f1, f2, f3, f4, alpha, flags);
-            }
-            break;
-            case Translate: {
-                float f1 = getFloat();
-                float f2 = getFloat();
-                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f", (char*) indent, OP_NAMES[op], f1, f2);
-                renderer.translate(f1, f2);
-            }
-            break;
-            case Rotate: {
-                float rotation = getFloat();
-                DISPLAY_LIST_LOGD("%s%s %.2f", (char*) indent, OP_NAMES[op], rotation);
-                renderer.rotate(rotation);
-            }
-            break;
-            case Scale: {
-                float sx = getFloat();
-                float sy = getFloat();
-                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f", (char*) indent, OP_NAMES[op], sx, sy);
-                renderer.scale(sx, sy);
-            }
-            break;
-            case Skew: {
-                float sx = getFloat();
-                float sy = getFloat();
-                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f", (char*) indent, OP_NAMES[op], sx, sy);
-                renderer.skew(sx, sy);
-            }
-            break;
-            case SetMatrix: {
-                SkMatrix* matrix = getMatrix();
-                DISPLAY_LIST_LOGD("%s%s %p", (char*) indent, OP_NAMES[op], matrix);
-                renderer.setMatrix(matrix);
-            }
-            break;
-            case ConcatMatrix: {
-                SkMatrix* matrix = getMatrix();
-                DISPLAY_LIST_LOGD(
-                        "%s%s %p: [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f]",
-                        (char*) indent, OP_NAMES[op], matrix,
-                        matrix->get(0), matrix->get(1), matrix->get(2),
-                        matrix->get(3), matrix->get(4), matrix->get(5),
-                        matrix->get(6), matrix->get(7), matrix->get(8));
-                renderer.concatMatrix(matrix);
-            }
-            break;
-            case ClipRect: {
-                float f1 = getFloat();
-                float f2 = getFloat();
-                float f3 = getFloat();
-                float f4 = getFloat();
-                int32_t regionOp = getInt();
-                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %d", (char*) indent, OP_NAMES[op],
-                        f1, f2, f3, f4, regionOp);
-                renderer.clipRect(f1, f2, f3, f4, (SkRegion::Op) regionOp);
-            }
-            break;
-            case ClipPath: {
-                SkPath* path = getPath();
-                int32_t regionOp = getInt();
-                DISPLAY_LIST_LOGD("%s%s %d", (char*) indent, OP_NAMES[op], regionOp);
-                renderer.clipPath(path, (SkRegion::Op) regionOp);
-            }
-            break;
-            case ClipRegion: {
-                SkRegion* region = getRegion();
-                int32_t regionOp = getInt();
-                DISPLAY_LIST_LOGD("%s%s %d", (char*) indent, OP_NAMES[op], regionOp);
-                renderer.clipRegion(region, (SkRegion::Op) regionOp);
-            }
-            break;
-            case DrawDisplayList: {
-                DisplayList* displayList = getDisplayList();
-                int32_t flags = getInt();
-                DISPLAY_LIST_LOGD("%s%s %p, %dx%d, 0x%x %d", (char*) indent, OP_NAMES[op],
-                        displayList, mWidth, mHeight, flags, level + 1);
-                drawGlStatus |= renderer.drawDisplayList(displayList, dirty, flags, level + 1);
-            }
-            break;
-            case DrawLayer: {
-                int oldAlpha = -1;
-                Layer* layer = (Layer*) getInt();
-                float x = getFloat();
-                float y = getFloat();
-                SkPaint* paint = getPaint(renderer);
-                if (mCaching && mMultipliedAlpha < 255) {
-                    oldAlpha = layer->getAlpha();
-                    layer->setAlpha(mMultipliedAlpha);
-                }
-                DISPLAY_LIST_LOGD("%s%s %p, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
-                        layer, x, y, paint);
-                drawGlStatus |= renderer.drawLayer(layer, x, y, paint);
-                if (oldAlpha >= 0) {
-                    layer->setAlpha(oldAlpha);
-                }
-            }
-            break;
-            case DrawBitmap: {
-                int oldAlpha = -1;
-                SkBitmap* bitmap = getBitmap();
-                float x = getFloat();
-                float y = getFloat();
-                SkPaint* paint = getPaint(renderer);
-                if (mCaching && mMultipliedAlpha < 255) {
-                    oldAlpha = paint->getAlpha();
-                    paint->setAlpha(mMultipliedAlpha);
-                }
-                DISPLAY_LIST_LOGD("%s%s %p, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
-                        bitmap, x, y, paint);
-                drawGlStatus |= renderer.drawBitmap(bitmap, x, y, paint);
-                if (oldAlpha >= 0) {
-                    paint->setAlpha(oldAlpha);
-                }
-            }
-            break;
-            case DrawBitmapMatrix: {
-                SkBitmap* bitmap = getBitmap();
-                SkMatrix* matrix = getMatrix();
-                SkPaint* paint = getPaint(renderer);
-                DISPLAY_LIST_LOGD("%s%s %p, %p, %p", (char*) indent, OP_NAMES[op],
-                        bitmap, matrix, paint);
-                drawGlStatus |= renderer.drawBitmap(bitmap, matrix, paint);
-            }
-            break;
-            case DrawBitmapRect: {
-                SkBitmap* bitmap = getBitmap();
-                float f1 = getFloat();
-                float f2 = getFloat();
-                float f3 = getFloat();
-                float f4 = getFloat();
-                float f5 = getFloat();
-                float f6 = getFloat();
-                float f7 = getFloat();
-                float f8 = getFloat();
-                SkPaint* paint = getPaint(renderer);
-                DISPLAY_LIST_LOGD("%s%s %p, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %p",
-                        (char*) indent, OP_NAMES[op], bitmap,
-                        f1, f2, f3, f4, f5, f6, f7, f8,paint);
-                drawGlStatus |= renderer.drawBitmap(bitmap, f1, f2, f3, f4, f5, f6, f7, f8, paint);
-            }
-            break;
-            case DrawBitmapData: {
-                SkBitmap* bitmap = getBitmapData();
-                float x = getFloat();
-                float y = getFloat();
-                SkPaint* paint = getPaint(renderer);
-                DISPLAY_LIST_LOGD("%s%s %p, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
-                        bitmap, x, y, paint);
-                drawGlStatus |= renderer.drawBitmap(bitmap, x, y, paint);
-            }
-            break;
-            case DrawBitmapMesh: {
-                int32_t verticesCount = 0;
-                uint32_t colorsCount = 0;
-
-                SkBitmap* bitmap = getBitmap();
-                uint32_t meshWidth = getInt();
-                uint32_t meshHeight = getInt();
-                float* vertices = getFloats(verticesCount);
-                bool hasColors = getInt();
-                int32_t* colors = hasColors ? getInts(colorsCount) : NULL;
-                SkPaint* paint = getPaint(renderer);
-
-                DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
-                drawGlStatus |= renderer.drawBitmapMesh(bitmap, meshWidth, meshHeight, vertices,
-                        colors, paint);
-            }
-            break;
-            case DrawPatch: {
-                int32_t* xDivs = NULL;
-                int32_t* yDivs = NULL;
-                uint32_t* colors = NULL;
-                uint32_t xDivsCount = 0;
-                uint32_t yDivsCount = 0;
-                int8_t numColors = 0;
-
-                SkBitmap* bitmap = getBitmap();
-
-                xDivs = getInts(xDivsCount);
-                yDivs = getInts(yDivsCount);
-                colors = getUInts(numColors);
-
-                float left = getFloat();
-                float top = getFloat();
-                float right = getFloat();
-                float bottom = getFloat();
-
-                int alpha = getInt();
-                SkXfermode::Mode mode = (SkXfermode::Mode) getInt();
-
-                DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
-                drawGlStatus |= renderer.drawPatch(bitmap, xDivs, yDivs, colors,
-                        xDivsCount, yDivsCount, numColors, left, top, right, bottom,
-                        alpha, mode);
-            }
-            break;
-            case DrawColor: {
-                int32_t color = getInt();
-                int32_t xferMode = getInt();
-                DISPLAY_LIST_LOGD("%s%s 0x%x %d", (char*) indent, OP_NAMES[op], color, xferMode);
-                drawGlStatus |= renderer.drawColor(color, (SkXfermode::Mode) xferMode);
-            }
-            break;
-            case DrawRect: {
-                float f1 = getFloat();
-                float f2 = getFloat();
-                float f3 = getFloat();
-                float f4 = getFloat();
-                SkPaint* paint = getPaint(renderer);
-                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
-                        f1, f2, f3, f4, paint);
-                drawGlStatus |= renderer.drawRect(f1, f2, f3, f4, paint);
-            }
-            break;
-            case DrawRoundRect: {
-                float f1 = getFloat();
-                float f2 = getFloat();
-                float f3 = getFloat();
-                float f4 = getFloat();
-                float f5 = getFloat();
-                float f6 = getFloat();
-                SkPaint* paint = getPaint(renderer);
-                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %p",
-                        (char*) indent, OP_NAMES[op], f1, f2, f3, f4, f5, f6, paint);
-                drawGlStatus |= renderer.drawRoundRect(f1, f2, f3, f4, f5, f6, paint);
-            }
-            break;
-            case DrawCircle: {
-                float f1 = getFloat();
-                float f2 = getFloat();
-                float f3 = getFloat();
-                SkPaint* paint = getPaint(renderer);
-                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %p",
-                        (char*) indent, OP_NAMES[op], f1, f2, f3, paint);
-                drawGlStatus |= renderer.drawCircle(f1, f2, f3, paint);
-            }
-            break;
-            case DrawOval: {
-                float f1 = getFloat();
-                float f2 = getFloat();
-                float f3 = getFloat();
-                float f4 = getFloat();
-                SkPaint* paint = getPaint(renderer);
-                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p",
-                        (char*) indent, OP_NAMES[op], f1, f2, f3, f4, paint);
-                drawGlStatus |= renderer.drawOval(f1, f2, f3, f4, paint);
-            }
-            break;
-            case DrawArc: {
-                float f1 = getFloat();
-                float f2 = getFloat();
-                float f3 = getFloat();
-                float f4 = getFloat();
-                float f5 = getFloat();
-                float f6 = getFloat();
-                int32_t i1 = getInt();
-                SkPaint* paint = getPaint(renderer);
-                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %d, %p",
-                        (char*) indent, OP_NAMES[op], f1, f2, f3, f4, f5, f6, i1, paint);
-                drawGlStatus |= renderer.drawArc(f1, f2, f3, f4, f5, f6, i1 == 1, paint);
-            }
-            break;
-            case DrawPath: {
-                SkPath* path = getPath();
-                SkPaint* paint = getPaint(renderer);
-                DISPLAY_LIST_LOGD("%s%s %p, %p", (char*) indent, OP_NAMES[op], path, paint);
-                drawGlStatus |= renderer.drawPath(path, paint);
-            }
-            break;
-            case DrawLines: {
-                int32_t count = 0;
-                float* points = getFloats(count);
-                SkPaint* paint = getPaint(renderer);
-                DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
-                drawGlStatus |= renderer.drawLines(points, count, paint);
-            }
-            break;
-            case DrawPoints: {
-                int32_t count = 0;
-                float* points = getFloats(count);
-                SkPaint* paint = getPaint(renderer);
-                DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
-                drawGlStatus |= renderer.drawPoints(points, count, paint);
-            }
-            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);
-                drawGlStatus |= renderer.drawTextOnPath(text.text(), text.length(), count, path,
-                        hOffset, vOffset, paint);
-            }
-            break;
-            case DrawPosText: {
-                getText(&text);
-                int32_t count = getInt();
-                int32_t positionsCount = 0;
-                float* positions = getFloats(positionsCount);
-                SkPaint* paint = getPaint(renderer);
-                DISPLAY_LIST_LOGD("%s%s %s, %d, %d, %p", (char*) indent,
-                        OP_NAMES[op], text.text(), text.length(), count, paint);
-                drawGlStatus |= renderer.drawPosText(text.text(), text.length(), count,
-                        positions, paint);
-            }
-            break;
-            case DrawText: {
-                getText(&text);
-                int32_t count = getInt();
-                float x = getFloat();
-                float y = getFloat();
-                int32_t positionsCount = 0;
-                float* positions = getFloats(positionsCount);
-                SkPaint* paint = getPaint(renderer);
-                float length = getFloat();
-                DISPLAY_LIST_LOGD("%s%s %s, %d, %d, %.2f, %.2f, %p, %.2f", (char*) indent,
-                        OP_NAMES[op], text.text(), text.length(), count, x, y, paint, length);
-                drawGlStatus |= renderer.drawText(text.text(), text.length(), count,
-                        x, y, positions, paint, length);
-            }
-            break;
-            case DrawRects: {
-                int32_t count = 0;
-                float* rects = getFloats(count);
-                SkPaint* paint = getPaint(renderer);
-                DISPLAY_LIST_LOGD("%s%s %d, %p", (char*) indent, OP_NAMES[op], count, paint);
-                drawGlStatus |= renderer.drawRects(rects, count / 4, paint);
-            }
-            break;
-            case ResetShader: {
-                DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
-                renderer.resetShader();
-            }
-            break;
-            case SetupShader: {
-                SkiaShader* shader = getShader();
-                DISPLAY_LIST_LOGD("%s%s %p", (char*) indent, OP_NAMES[op], shader);
-                renderer.setupShader(shader);
-            }
-            break;
-            case ResetColorFilter: {
-                DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
-                renderer.resetColorFilter();
-            }
-            break;
-            case SetupColorFilter: {
-                SkiaColorFilter *colorFilter = getColorFilter();
-                DISPLAY_LIST_LOGD("%s%s %p", (char*) indent, OP_NAMES[op], colorFilter);
-                renderer.setupColorFilter(colorFilter);
-            }
-            break;
-            case ResetShadow: {
-                DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
-                renderer.resetShadow();
-            }
-            break;
-            case SetupShadow: {
-                float radius = getFloat();
-                float dx = getFloat();
-                float dy = getFloat();
-                int32_t color = getInt();
-                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, 0x%x", (char*) indent, OP_NAMES[op],
-                        radius, dx, dy, color);
-                renderer.setupShadow(radius, dx, dy, color);
-            }
-            break;
-            case ResetPaintFilter: {
-                DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
-                renderer.resetPaintFilter();
-            }
-            break;
-            case SetupPaintFilter: {
-                int32_t clearBits = getInt();
-                int32_t setBits = getInt();
-                DISPLAY_LIST_LOGD("%s%s 0x%x, 0x%x", (char*) indent, OP_NAMES[op],
-                        clearBits, setBits);
-                renderer.setupPaintFilter(clearBits, setBits);
-            }
-            break;
-            default:
-                DISPLAY_LIST_LOGD("Display List error: op not handled: %s%s",
-                        (char*) indent, OP_NAMES[op]);
-                break;
-        }
+        drawGlStatus |= op->replay(renderer, dirty, flags,
+                saveCount, level, mCaching, mMultipliedAlpha);
+        logBuffer.writeCommand(level, op->name());
     }
 
-    DISPLAY_LIST_LOGD("%s%s %d", (char*) indent, "RestoreToCount", restoreTo);
+    DISPLAY_LIST_LOGD("%*sRestoreToCount %d", level * 2, "", restoreTo);
     renderer.restoreToCount(restoreTo);
     renderer.endMark();
 
-    DISPLAY_LIST_LOGD("%sDone (%p, %s), returning %d", (char*) indent + 2, this, mName.string(),
+    DISPLAY_LIST_LOGD("%*sDone (%p, %s), returning %d", (level + 1) * 2, "", this, mName.string(),
             drawGlStatus);
     return drawGlStatus;
 }
@@ -1387,7 +448,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 DisplayListRenderer::DisplayListRenderer():
-        mCaches(Caches::getInstance()), mWriter(MIN_WRITER_SIZE),
+        mCaches(Caches::getInstance()), mDisplayListData(new DisplayListData),
         mTranslateX(0.0f), mTranslateY(0.0f), mHasTranslate(false),
         mHasDrawOps(false), mFunctorCount(0) {
 }
@@ -1397,8 +458,7 @@
 }
 
 void DisplayListRenderer::reset() {
-    mWriter.reset();
-
+    mDisplayListData = new DisplayListData();
     mCaches.resourceCache.lock();
 
     for (size_t i = 0; i < mBitmapResources.size(); i++) {
@@ -1493,7 +553,7 @@
 
 void DisplayListRenderer::finish() {
     insertRestoreToCount();
-    insertTranlate();
+    insertTranslate();
 }
 
 void DisplayListRenderer::interrupt() {
@@ -1504,15 +564,13 @@
 
 status_t DisplayListRenderer::callDrawGLFunction(Functor *functor, Rect& dirty) {
     // Ignore dirty during recording, it matters only when we replay
-    addOp(DisplayList::DrawGLFunction);
-    addInt((int) functor);
+    addDrawOp(new (alloc()) DrawFunctorOp(functor));
     mFunctorCount++;
     return DrawGlInfo::kStatusDone; // No invalidate needed at record-time
 }
 
 int DisplayListRenderer::save(int flags) {
-    addOp(DisplayList::Save);
-    addInt(flags);
+    addStateOp(new (alloc()) SaveOp(flags));
     return OpenGLRenderer::save(flags);
 }
 
@@ -1523,31 +581,25 @@
     }
 
     mRestoreSaveCount--;
-    insertTranlate();
+    insertTranslate();
     OpenGLRenderer::restore();
 }
 
 void DisplayListRenderer::restoreToCount(int saveCount) {
     mRestoreSaveCount = saveCount;
-    insertTranlate();
+    insertTranslate();
     OpenGLRenderer::restoreToCount(saveCount);
 }
 
 int DisplayListRenderer::saveLayer(float left, float top, float right, float bottom,
         SkPaint* p, int flags) {
-    addOp(DisplayList::SaveLayer);
-    addBounds(left, top, right, bottom);
-    addPaint(p);
-    addInt(flags);
+    addStateOp(new (alloc()) SaveLayerOp(left, top, right, bottom, p, flags));
     return OpenGLRenderer::save(flags);
 }
 
 int DisplayListRenderer::saveLayerAlpha(float left, float top, float right, float bottom,
         int alpha, int flags) {
-    addOp(DisplayList::SaveLayerAlpha);
-    addBounds(left, top, right, bottom);
-    addInt(alpha);
-    addInt(flags);
+    addStateOp(new (alloc()) SaveLayerAlphaOp(left, top, right, bottom, alpha, flags));
     return OpenGLRenderer::save(flags);
 }
 
@@ -1560,54 +612,47 @@
 }
 
 void DisplayListRenderer::rotate(float degrees) {
-    addOp(DisplayList::Rotate);
-    addFloat(degrees);
+    addStateOp(new (alloc()) RotateOp(degrees));
     OpenGLRenderer::rotate(degrees);
 }
 
 void DisplayListRenderer::scale(float sx, float sy) {
-    addOp(DisplayList::Scale);
-    addPoint(sx, sy);
+    addStateOp(new (alloc()) ScaleOp(sx, sy));
     OpenGLRenderer::scale(sx, sy);
 }
 
 void DisplayListRenderer::skew(float sx, float sy) {
-    addOp(DisplayList::Skew);
-    addPoint(sx, sy);
+    addStateOp(new (alloc()) SkewOp(sx, sy));
     OpenGLRenderer::skew(sx, sy);
 }
 
 void DisplayListRenderer::setMatrix(SkMatrix* matrix) {
-    addOp(DisplayList::SetMatrix);
-    addMatrix(matrix);
+    matrix = refMatrix(matrix);
+    addStateOp(new (alloc()) SetMatrixOp(matrix));
     OpenGLRenderer::setMatrix(matrix);
 }
 
 void DisplayListRenderer::concatMatrix(SkMatrix* matrix) {
-    addOp(DisplayList::ConcatMatrix);
-    addMatrix(matrix);
+    matrix = refMatrix(matrix);
+    addStateOp(new (alloc()) ConcatMatrixOp(matrix));
     OpenGLRenderer::concatMatrix(matrix);
 }
 
 bool DisplayListRenderer::clipRect(float left, float top, float right, float bottom,
         SkRegion::Op op) {
-    addOp(DisplayList::ClipRect);
-    addBounds(left, top, right, bottom);
-    addInt(op);
+    addStateOp(new (alloc()) ClipRectOp(left, top, right, bottom, op));
     return OpenGLRenderer::clipRect(left, top, right, bottom, op);
 }
 
 bool DisplayListRenderer::clipPath(SkPath* path, SkRegion::Op op) {
-    addOp(DisplayList::ClipPath);
-    addPath(path);
-    addInt(op);
+    path = refPath(path);
+    addStateOp(new (alloc()) ClipPathOp(path, op));
     return OpenGLRenderer::clipPath(path, op);
 }
 
 bool DisplayListRenderer::clipRegion(SkRegion* region, SkRegion::Op op) {
-    addOp(DisplayList::ClipRegion);
-    addRegion(region);
-    addInt(op);
+    region = refRegion(region);
+    addStateOp(new (alloc()) ClipRegionOp(region, op));
     return OpenGLRenderer::clipRegion(region, op);
 }
 
@@ -1616,84 +661,71 @@
     // dirty is an out parameter and should not be recorded,
     // it matters only when replaying the display list
 
-    addOp(DisplayList::DrawDisplayList);
-    addDisplayList(displayList);
-    addInt(flags);
+    // TODO: To be safe, the display list should be ref-counted in the
+    //       resources cache, but we rely on the caller (UI toolkit) to
+    //       do the right thing for now
+
+    addDrawOp(new (alloc()) DrawDisplayListOp(displayList, flags));
     return DrawGlInfo::kStatusDone;
 }
 
 status_t DisplayListRenderer::drawLayer(Layer* layer, float x, float y, SkPaint* paint) {
-    addOp(DisplayList::DrawLayer);
-    addLayer(layer);
-    addPoint(x, y);
-    addPaint(paint);
+    mLayers.add(layer);
+    mCaches.resourceCache.incrementRefcount(layer);
+    paint = refPaint(paint);
+
+    addDrawOp(new (alloc()) DrawLayerOp(layer, x, y, paint));
     return DrawGlInfo::kStatusDone;
 }
 
 status_t DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint) {
-    const bool reject = quickRejectNoScissor(left, top,
-            left + bitmap->width(), top + bitmap->height());
-    uint32_t* location = addOp(DisplayList::DrawBitmap, reject);
-    addBitmap(bitmap);
-    addPoint(left, top);
-    addPaint(paint);
-    addSkip(location);
+    bitmap = refBitmap(bitmap);
+    paint = refPaint(paint);
+
+    addDrawOp(new (alloc()) DrawBitmapOp(bitmap, left, top, paint));
     return DrawGlInfo::kStatusDone;
 }
 
 status_t DisplayListRenderer::drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint) {
-    Rect r(0.0f, 0.0f, bitmap->width(), bitmap->height());
-    const mat4 transform(*matrix);
-    transform.mapRect(r);
+    bitmap = refBitmap(bitmap);
+    matrix = refMatrix(matrix);
+    paint = refPaint(paint);
 
-    const bool reject = quickRejectNoScissor(r.left, r.top, r.right, r.bottom);
-    uint32_t* location = addOp(DisplayList::DrawBitmapMatrix, reject);
-    addBitmap(bitmap);
-    addMatrix(matrix);
-    addPaint(paint);
-    addSkip(location);
+    addDrawOp(new (alloc()) DrawBitmapMatrixOp(bitmap, matrix, paint));
     return DrawGlInfo::kStatusDone;
 }
 
 status_t DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop,
         float srcRight, float srcBottom, float dstLeft, float dstTop,
         float dstRight, float dstBottom, SkPaint* paint) {
-    const bool reject = quickRejectNoScissor(dstLeft, dstTop, dstRight, dstBottom);
-    uint32_t* location = addOp(DisplayList::DrawBitmapRect, reject);
-    addBitmap(bitmap);
-    addBounds(srcLeft, srcTop, srcRight, srcBottom);
-    addBounds(dstLeft, dstTop, dstRight, dstBottom);
-    addPaint(paint);
-    addSkip(location);
+    bitmap = refBitmap(bitmap);
+    paint = refPaint(paint);
+
+    addDrawOp(new (alloc()) DrawBitmapRectOp(bitmap,
+                    srcLeft, srcTop, srcRight, srcBottom,
+                    dstLeft, dstTop, dstRight, dstBottom, paint));
     return DrawGlInfo::kStatusDone;
 }
 
 status_t DisplayListRenderer::drawBitmapData(SkBitmap* bitmap, float left, float top,
         SkPaint* paint) {
-    const bool reject = quickRejectNoScissor(left, top,
-            left + bitmap->width(), top + bitmap->height());
-    uint32_t* location = addOp(DisplayList::DrawBitmapData, reject);
-    addBitmapData(bitmap);
-    addPoint(left, top);
-    addPaint(paint);
-    addSkip(location);
+    bitmap = refBitmapData(bitmap);
+    paint = refPaint(paint);
+
+    addDrawOp(new (alloc()) DrawBitmapDataOp(bitmap, left, top, paint));
     return DrawGlInfo::kStatusDone;
 }
 
 status_t DisplayListRenderer::drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int meshHeight,
         float* vertices, int* colors, SkPaint* paint) {
-    addOp(DisplayList::DrawBitmapMesh);
-    addBitmap(bitmap);
-    addInt(meshWidth);
-    addInt(meshHeight);
-    addFloats(vertices, (meshWidth + 1) * (meshHeight + 1) * 2);
-    if (colors) {
-        addInt(1);
-        addInts(colors, (meshWidth + 1) * (meshHeight + 1));
-    } else {
-        addInt(0);
-    }
-    addPaint(paint);
+    int count = (meshWidth + 1) * (meshHeight + 1) * 2;
+    bitmap = refBitmap(bitmap);
+    vertices = refBuffer<float>(vertices, count);
+    paint = refPaint(paint);
+    colors = refBuffer<int>(colors, count);
+
+    addDrawOp(new (alloc()) DrawBitmapMeshOp(bitmap, meshWidth, meshHeight,
+                    vertices, colors, paint));
     return DrawGlInfo::kStatusDone;
 }
 
@@ -1704,132 +736,114 @@
     SkXfermode::Mode mode;
     OpenGLRenderer::getAlphaAndModeDirect(paint, &alpha, &mode);
 
-    const bool reject = quickRejectNoScissor(left, top, right, bottom);
-    uint32_t* location = addOp(DisplayList::DrawPatch, reject);
-    addBitmap(bitmap);
-    addInts(xDivs, width);
-    addInts(yDivs, height);
-    addUInts(colors, numColors);
-    addBounds(left, top, right, bottom);
-    addInt(alpha);
-    addInt(mode);
-    addSkip(location);
+    bitmap = refBitmap(bitmap);
+    xDivs = refBuffer<int>(xDivs, width);
+    yDivs = refBuffer<int>(yDivs, height);
+    colors = refBuffer<uint32_t>(colors, numColors);
+
+    addDrawOp(new (alloc()) DrawPatchOp(bitmap, xDivs, yDivs, colors, width, height, numColors,
+                    left, top, right, bottom, alpha, mode));
     return DrawGlInfo::kStatusDone;
 }
 
 status_t DisplayListRenderer::drawColor(int color, SkXfermode::Mode mode) {
-    addOp(DisplayList::DrawColor);
-    addInt(color);
-    addInt(mode);
+    addDrawOp(new (alloc()) DrawColorOp(color, mode));
     return DrawGlInfo::kStatusDone;
 }
 
 status_t DisplayListRenderer::drawRect(float left, float top, float right, float bottom,
         SkPaint* paint) {
-    const bool reject = paint->getStyle() == SkPaint::kFill_Style &&
-            quickRejectNoScissor(left, top, right, bottom);
-    uint32_t* location = addOp(DisplayList::DrawRect, reject);
-    addBounds(left, top, right, bottom);
-    addPaint(paint);
-    addSkip(location);
+    paint = refPaint(paint);
+    addDrawOp(new (alloc()) DrawRectOp(left, top, right, bottom, paint));
     return DrawGlInfo::kStatusDone;
 }
 
 status_t DisplayListRenderer::drawRoundRect(float left, float top, float right, float bottom,
         float rx, float ry, SkPaint* paint) {
-    const bool reject = paint->getStyle() == SkPaint::kFill_Style &&
-            quickRejectNoScissor(left, top, right, bottom);
-    uint32_t* location = addOp(DisplayList::DrawRoundRect, reject);
-    addBounds(left, top, right, bottom);
-    addPoint(rx, ry);
-    addPaint(paint);
-    addSkip(location);
+    paint = refPaint(paint);
+    addDrawOp(new (alloc()) DrawRoundRectOp(left, top, right, bottom, rx, ry, paint));
     return DrawGlInfo::kStatusDone;
 }
 
 status_t DisplayListRenderer::drawCircle(float x, float y, float radius, SkPaint* paint) {
-    addOp(DisplayList::DrawCircle);
-    addPoint(x, y);
-    addFloat(radius);
-    addPaint(paint);
+    paint = refPaint(paint);
+    addDrawOp(new (alloc()) DrawCircleOp(x, y, radius, paint));
     return DrawGlInfo::kStatusDone;
 }
 
 status_t DisplayListRenderer::drawOval(float left, float top, float right, float bottom,
         SkPaint* paint) {
-    addOp(DisplayList::DrawOval);
-    addBounds(left, top, right, bottom);
-    addPaint(paint);
+    paint = refPaint(paint);
+    addDrawOp(new (alloc()) DrawOvalOp(left, top, right, bottom, paint));
     return DrawGlInfo::kStatusDone;
 }
 
 status_t DisplayListRenderer::drawArc(float left, float top, float right, float bottom,
         float startAngle, float sweepAngle, bool useCenter, SkPaint* paint) {
-    addOp(DisplayList::DrawArc);
-    addBounds(left, top, right, bottom);
-    addPoint(startAngle, sweepAngle);
-    addInt(useCenter ? 1 : 0);
-    addPaint(paint);
+    paint = refPaint(paint);
+    addDrawOp(new (alloc()) DrawArcOp(left, top, right, bottom,
+                    startAngle, sweepAngle, useCenter, paint));
     return DrawGlInfo::kStatusDone;
 }
 
 status_t DisplayListRenderer::drawPath(SkPath* path, SkPaint* paint) {
-    float left, top, offset;
-    uint32_t width, height;
-    computePathBounds(path, paint, left, top, offset, width, height);
+    path = refPath(path);
+    paint = refPaint(paint);
 
-    left -= offset;
-    top -= offset;
-
-    const bool reject = quickRejectNoScissor(left, top, left + width, top + height);
-    uint32_t* location = addOp(DisplayList::DrawPath, reject);
-    addPath(path);
-    addPaint(paint);
-    addSkip(location);
+    addDrawOp(new (alloc()) DrawPathOp(path, paint));
     return DrawGlInfo::kStatusDone;
 }
 
 status_t DisplayListRenderer::drawLines(float* points, int count, SkPaint* paint) {
-    addOp(DisplayList::DrawLines);
-    addFloats(points, count);
-    addPaint(paint);
+    points = refBuffer<float>(points, count);
+    paint = refPaint(paint);
+
+    addDrawOp(new (alloc()) DrawLinesOp(points, count, paint));
     return DrawGlInfo::kStatusDone;
 }
 
 status_t DisplayListRenderer::drawPoints(float* points, int count, SkPaint* paint) {
-    addOp(DisplayList::DrawPoints);
-    addFloats(points, count);
-    addPaint(paint);
+    points = refBuffer<float>(points, count);
+    paint = refPaint(paint);
+
+    addDrawOp(new (alloc()) DrawPointsOp(points, count, paint));
     return DrawGlInfo::kStatusDone;
 }
 
 status_t DisplayListRenderer::drawTextOnPath(const char* text, int bytesCount, int count,
         SkPath* path, float hOffset, float vOffset, SkPaint* paint) {
     if (!text || count <= 0) return DrawGlInfo::kStatusDone;
-    addOp(DisplayList::DrawTextOnPath);
-    addText(text, bytesCount);
-    addInt(count);
-    addPath(path);
-    addFloat(hOffset);
-    addFloat(vOffset);
+
     paint->setAntiAlias(true);
-    SkPaint* addedPaint = addPaint(paint);
-    FontRenderer& fontRenderer = mCaches.fontRenderer->getFontRenderer(addedPaint);
-    fontRenderer.precache(addedPaint, text, count, *mSnapshot->transform);
+    text = refText(text, bytesCount);
+    path = refPath(path);
+    paint = refPaint(paint);
+
+    DrawOp* op = new (alloc()) DrawTextOnPathOp(text, bytesCount, count, path,
+            hOffset, vOffset, paint);
+    if (addDrawOp(op)) {
+        // precache if draw operation is visible
+        FontRenderer& fontRenderer = mCaches.fontRenderer->getFontRenderer(paint);
+        fontRenderer.precache(paint, text, count, *mSnapshot->transform);
+    }
     return DrawGlInfo::kStatusDone;
 }
 
 status_t DisplayListRenderer::drawPosText(const char* text, int bytesCount, int count,
         const float* positions, SkPaint* paint) {
     if (!text || count <= 0) return DrawGlInfo::kStatusDone;
-    addOp(DisplayList::DrawPosText);
-    addText(text, bytesCount);
-    addInt(count);
-    addFloats(positions, count * 2);
+
     paint->setAntiAlias(true);
-    SkPaint* addedPaint = addPaint(paint);
-    FontRenderer& fontRenderer = mCaches.fontRenderer->getFontRenderer(addedPaint);
-    fontRenderer.precache(addedPaint, text, count, *mSnapshot->transform);
+    text = refText(text, bytesCount);
+    positions = refBuffer<float>(positions, count * 2);
+    paint = refPaint(paint);
+
+    DrawOp* op = new (alloc()) DrawPosTextOp(text, bytesCount, count, positions, paint);
+    if (addDrawOp(op)) {
+        // precache if draw operation is visible
+        FontRenderer& fontRenderer = mCaches.fontRenderer->getFontRenderer(paint);
+        fontRenderer.precache(paint, text, count, *mSnapshot->transform);
+    }
     return DrawGlInfo::kStatusDone;
 }
 
@@ -1847,75 +861,96 @@
     paint->setAntiAlias(true);
     if (length < 0.0f) length = paint->measureText(text, bytesCount);
 
-    bool reject = false;
-    if (CC_LIKELY(paint->getTextAlign() == SkPaint::kLeft_Align)) {
-        SkPaint::FontMetrics metrics;
-        paint->getFontMetrics(&metrics, 0.0f);
-        reject = quickRejectNoScissor(x, y + metrics.fTop, x + length, y + metrics.fBottom);
-    }
+    text = refText(text, bytesCount);
+    positions = refBuffer<float>(positions, count * 2);
+    paint = refPaint(paint);
 
-    uint32_t* location = addOp(DisplayList::DrawText, reject);
-    addText(text, bytesCount);
-    addInt(count);
-    addFloat(x);
-    addFloat(y);
-    addFloats(positions, count * 2);
-    SkPaint* addedPaint = addPaint(paint);
-    if (!reject) {
-        FontRenderer& fontRenderer = mCaches.fontRenderer->getFontRenderer(addedPaint);
-        fontRenderer.precache(addedPaint, text, count, *mSnapshot->transform);
+    DrawOp* op = new (alloc()) DrawTextOp(text, bytesCount, count, x, y, positions, paint, length);
+    if (addDrawOp(op)) {
+        // precache if draw operation is visible
+        FontRenderer& fontRenderer = mCaches.fontRenderer->getFontRenderer(paint);
+        fontRenderer.precache(paint, text, count, *mSnapshot->transform);
     }
-    addFloat(length);
-    addSkip(location);
     return DrawGlInfo::kStatusDone;
 }
 
 status_t DisplayListRenderer::drawRects(const float* rects, int count, SkPaint* paint) {
     if (count <= 0) return DrawGlInfo::kStatusDone;
 
-    addOp(DisplayList::DrawRects);
-    addFloats(rects, count * 4);
-    addPaint(paint);
+    rects = refBuffer<float>(rects, count);
+    paint = refPaint(paint);
+    addDrawOp(new (alloc()) DrawRectsOp(rects, count, paint));
     return DrawGlInfo::kStatusDone;
 }
 
 void DisplayListRenderer::resetShader() {
-    addOp(DisplayList::ResetShader);
+    addStateOp(new (alloc()) ResetShaderOp());
 }
 
 void DisplayListRenderer::setupShader(SkiaShader* shader) {
-    addOp(DisplayList::SetupShader);
-    addShader(shader);
+    shader = refShader(shader);
+    addStateOp(new (alloc()) SetupShaderOp(shader));
 }
 
 void DisplayListRenderer::resetColorFilter() {
-    addOp(DisplayList::ResetColorFilter);
+    addStateOp(new (alloc()) ResetColorFilterOp());
 }
 
 void DisplayListRenderer::setupColorFilter(SkiaColorFilter* filter) {
-    addOp(DisplayList::SetupColorFilter);
-    addColorFilter(filter);
+    filter = refColorFilter(filter);
+    addStateOp(new (alloc()) SetupColorFilterOp(filter));
 }
 
 void DisplayListRenderer::resetShadow() {
-    addOp(DisplayList::ResetShadow);
+    addStateOp(new (alloc()) ResetShadowOp());
 }
 
 void DisplayListRenderer::setupShadow(float radius, float dx, float dy, int color) {
-    addOp(DisplayList::SetupShadow);
-    addFloat(radius);
-    addPoint(dx, dy);
-    addInt(color);
+    addStateOp(new (alloc()) SetupShadowOp(radius, dx, dy, color));
 }
 
 void DisplayListRenderer::resetPaintFilter() {
-    addOp(DisplayList::ResetPaintFilter);
+    addStateOp(new (alloc()) ResetPaintFilterOp());
 }
 
 void DisplayListRenderer::setupPaintFilter(int clearBits, int setBits) {
-    addOp(DisplayList::SetupPaintFilter);
-    addInt(clearBits);
-    addInt(setBits);
+    addStateOp(new (alloc()) SetupPaintFilterOp(clearBits, setBits));
+}
+
+void DisplayListRenderer::insertRestoreToCount() {
+    if (mRestoreSaveCount >= 0) {
+        DisplayListOp* op = new (alloc()) RestoreToCountOp(mRestoreSaveCount);
+        mDisplayListData->displayListOps.add(op);
+        mRestoreSaveCount = -1;
+    }
+}
+
+void DisplayListRenderer::insertTranslate() {
+    if (mHasTranslate) {
+        if (mTranslateX != 0.0f || mTranslateY != 0.0f) {
+            DisplayListOp* op = new (alloc()) TranslateOp(mTranslateX, mTranslateY);
+            mDisplayListData->displayListOps.add(op);
+            mTranslateX = mTranslateY = 0.0f;
+        }
+        mHasTranslate = false;
+    }
+}
+
+void DisplayListRenderer::addStateOp(StateOp* op) {
+    addOpInternal(op);
+}
+
+bool DisplayListRenderer::addDrawOp(DrawOp* op) {
+    bool rejected = false;
+    Rect localBounds;
+    if (op->getLocalBounds(localBounds)) {
+        rejected = quickRejectNoScissor(localBounds.left, localBounds.top,
+                localBounds.right, localBounds.bottom);
+        op->setQuickRejected(rejected);
+    }
+    mHasDrawOps = true;
+    addOpInternal(op);
+    return !rejected;
 }
 
 }; // namespace uirenderer
diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h
index f55f1f2..b25288b 100644
--- a/libs/hwui/DisplayListRenderer.h
+++ b/libs/hwui/DisplayListRenderer.h
@@ -31,6 +31,7 @@
 
 #include "DisplayListLogBuffer.h"
 #include "OpenGLRenderer.h"
+#include "utils/LinearAllocator.h"
 
 namespace android {
 namespace uirenderer {
@@ -60,6 +61,18 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 class DisplayListRenderer;
+class DisplayListOp;
+class DrawOp;
+class StateOp;
+
+/**
+ * Refcounted structure that holds data used in display list stream
+ */
+class DisplayListData: public LightRefBase<DisplayListData> {
+public:
+    LinearAllocator allocator;
+    Vector<DisplayListOp*> displayListOps;
+};
 
 /**
  * Replays recorded drawing commands.
@@ -69,66 +82,13 @@
     DisplayList(const DisplayListRenderer& recorder);
     ANDROID_API ~DisplayList();
 
-    // IMPORTANT: Update the intialization of OP_NAMES in the .cpp file
-    //            when modifying this file
-    enum Op {
-        // Non-drawing operations
-        Save = 0,
-        Restore,
-        RestoreToCount,
-        SaveLayer,
-        SaveLayerAlpha,
-        Translate,
-        Rotate,
-        Scale,
-        Skew,
-        SetMatrix,
-        ConcatMatrix,
-        ClipRect,
-        ClipPath,
-        ClipRegion,
-        // Drawing operations
-        DrawDisplayList,
-        DrawLayer,
-        DrawBitmap,
-        DrawBitmapMatrix,
-        DrawBitmapRect,
-        DrawBitmapData,
-        DrawBitmapMesh,
-        DrawPatch,
-        DrawColor,
-        DrawRect,
-        DrawRoundRect,
-        DrawCircle,
-        DrawOval,
-        DrawArc,
-        DrawPath,
-        DrawLines,
-        DrawPoints,
-        DrawTextOnPath,
-        DrawPosText,
-        DrawText,
-        DrawRects,
-        ResetShader,
-        SetupShader,
-        ResetColorFilter,
-        SetupColorFilter,
-        ResetShadow,
-        SetupShadow,
-        ResetPaintFilter,
-        SetupPaintFilter,
-        DrawGLFunction,
-    };
-
     // See flags defined in DisplayList.java
     enum ReplayFlag {
         kReplayFlag_ClipChildren = 0x1
     };
 
-    static const char* OP_NAMES[];
-
     void setViewProperties(OpenGLRenderer& renderer, uint32_t level);
-    void outputViewProperties(OpenGLRenderer& renderer, char* indent);
+    void outputViewProperties(uint32_t level);
 
     ANDROID_API size_t getSize();
     ANDROID_API static void destroyDisplayListDeferred(DisplayList* displayList);
@@ -138,7 +98,7 @@
 
     status_t replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, uint32_t level = 0);
 
-    void output(OpenGLRenderer& renderer, uint32_t level = 0);
+    void output(uint32_t level = 0);
 
     ANDROID_API void reset();
 
@@ -423,78 +383,6 @@
         const char* mText;
     };
 
-    SkBitmap* getBitmap() {
-        return (SkBitmap*) getInt();
-    }
-
-    SkBitmap* getBitmapData() {
-        return (SkBitmap*) getInt();
-    }
-
-    SkiaShader* getShader() {
-        return (SkiaShader*) getInt();
-    }
-
-    SkiaColorFilter* getColorFilter() {
-        return (SkiaColorFilter*) getInt();
-    }
-
-    inline int32_t getIndex() {
-        return mReader.readInt();
-    }
-
-    inline int32_t getInt() {
-        return mReader.readInt();
-    }
-
-    inline uint32_t getUInt() {
-        return mReader.readU32();
-    }
-
-    SkMatrix* getMatrix() {
-        return (SkMatrix*) getInt();
-    }
-
-    SkPath* getPath() {
-        return (SkPath*) getInt();
-    }
-
-    SkRegion* getRegion() {
-        return (SkRegion*) getInt();
-    }
-
-    SkPaint* getPaint(OpenGLRenderer& renderer) {
-        return renderer.filterPaint((SkPaint*) getInt());
-    }
-
-    DisplayList* getDisplayList() {
-        return (DisplayList*) getInt();
-    }
-
-    inline float getFloat() {
-        return mReader.readScalar();
-    }
-
-    int32_t* getInts(uint32_t& count) {
-        count = getInt();
-        return (int32_t*) mReader.skip(count * sizeof(int32_t));
-    }
-
-    uint32_t* getUInts(int8_t& count) {
-        count = getInt();
-        return (uint32_t*) mReader.skip(count * sizeof(uint32_t));
-    }
-
-    float* getFloats(int32_t& count) {
-        count = getInt();
-        return (float*) mReader.skip(count * sizeof(float));
-    }
-
-    void getText(TextContainer* text) {
-        size_t length = text->mByteLength = getInt();
-        text->mText = (const char*) mReader.skip(length);
-    }
-
     Vector<SkBitmap*> mBitmapResources;
     Vector<SkBitmap*> mOwnedBitmapResources;
     Vector<SkiaColorFilter*> mFilterResources;
@@ -507,7 +395,7 @@
     Vector<SkiaShader*> mShaders;
     Vector<Layer*> mLayers;
 
-    mutable SkFlattenableReadBuffer mReader;
+    sp<DisplayListData> mDisplayListData;
 
     size_t mSize;
 
@@ -634,8 +522,8 @@
 
     ANDROID_API void reset();
 
-    const SkWriter32& writeStream() const {
-        return mWriter;
+    sp<DisplayListData> getDisplayListData() const {
+        return mDisplayListData;
     }
 
     const Vector<SkBitmap*>& getBitmapResources() const {
@@ -683,102 +571,32 @@
     }
 
 private:
-    void insertRestoreToCount() {
-        if (mRestoreSaveCount >= 0) {
-            mWriter.writeInt(DisplayList::RestoreToCount);
-            addInt(mRestoreSaveCount);
-            mRestoreSaveCount = -1;
-        }
-    }
+    void insertRestoreToCount();
+    void insertTranslate();
 
-    void insertTranlate() {
-        if (mHasTranslate) {
-            if (mTranslateX != 0.0f || mTranslateY != 0.0f) {
-                mWriter.writeInt(DisplayList::Translate);
-                addPoint(mTranslateX, mTranslateY);
-                mTranslateX = mTranslateY = 0.0f;
-            }
-            mHasTranslate = false;
-        }
-    }
-
-    inline void addOp(const DisplayList::Op drawOp) {
+    LinearAllocator& alloc() { return mDisplayListData->allocator; }
+    void addStateOp(StateOp* op);
+    bool addDrawOp(DrawOp* op); // returns true if op not rejected
+    void addOpInternal(DisplayListOp* op) {
         insertRestoreToCount();
-        insertTranlate();
-        mWriter.writeInt(drawOp);
-        mHasDrawOps = mHasDrawOps || drawOp >= DisplayList::DrawDisplayList;
+        insertTranslate();
+        mDisplayListData->displayListOps.add(op);
     }
 
-    uint32_t* addOp(const DisplayList::Op drawOp, const bool reject) {
-        insertRestoreToCount();
-        insertTranlate();
-        mHasDrawOps = mHasDrawOps || drawOp >= DisplayList::DrawDisplayList;
-        if (reject) {
-            mWriter.writeInt(OP_MAY_BE_SKIPPED_MASK | drawOp);
-            mWriter.writeInt(0xdeaddead);
-            mBufferSize = mWriter.size();
-            return mWriter.peek32(mBufferSize - sizeof(int32_t));
-        }
-        mWriter.writeInt(drawOp);
-        return NULL;
+    template<class T>
+    inline T* refBuffer(const T* srcBuffer, int32_t count) {
+        if (srcBuffer == NULL) return NULL;
+        T* dstBuffer = (T*) mDisplayListData->allocator.alloc(count * sizeof(T));
+        memcpy(dstBuffer, srcBuffer, count * sizeof(T));
+        return dstBuffer;
     }
 
-    inline void addSkip(uint32_t* location) {
-        if (location) {
-            *location = (int32_t) (mWriter.size() - mBufferSize);
-        }
+    inline char* refText(const char* text, size_t byteLength) {
+        return (char*) refBuffer<uint8_t>((uint8_t*)text, byteLength);
     }
 
-    inline void addInt(int32_t value) {
-        mWriter.writeInt(value);
-    }
-
-    inline void addSize(uint32_t w, uint32_t h) {
-        mWriter.writeInt(w);
-        mWriter.writeInt(h);
-    }
-
-    void addInts(const int32_t* values, uint32_t count) {
-        mWriter.writeInt(count);
-        mWriter.write(values, count * sizeof(int32_t));
-    }
-
-    void addUInts(const uint32_t* values, int8_t count) {
-        mWriter.writeInt(count);
-        mWriter.write(values, count * sizeof(uint32_t));
-    }
-
-    inline void addFloat(float value) {
-        mWriter.writeScalar(value);
-    }
-
-    void addFloats(const float* values, int32_t count) {
-        mWriter.writeInt(count);
-        mWriter.write(values, count * sizeof(float));
-    }
-
-    inline void addPoint(float x, float y) {
-        mWriter.writeScalar(x);
-        mWriter.writeScalar(y);
-    }
-
-    inline void addBounds(float left, float top, float right, float bottom) {
-        mWriter.writeScalar(left);
-        mWriter.writeScalar(top);
-        mWriter.writeScalar(right);
-        mWriter.writeScalar(bottom);
-    }
-
-    inline void addText(const void* text, size_t byteLength) {
-        mWriter.writeInt(byteLength);
-        mWriter.writePad(text, byteLength);
-    }
-
-    inline void addPath(SkPath* path) {
-        if (!path) {
-            addInt((int) NULL);
-            return;
-        }
+    inline SkPath* refPath(SkPath* path) {
+        if (!path) return NULL;
 
         SkPath* pathCopy = mPathMap.valueFor(path);
         if (pathCopy == NULL || pathCopy->getGenerationID() != path->getGenerationID()) {
@@ -792,13 +610,11 @@
             mCaches.resourceCache.incrementRefcount(path);
             mSourcePaths.add(path);
         }
-
-        addInt((int) pathCopy);
+        return pathCopy;
     }
 
-    inline SkPaint* addPaint(SkPaint* paint) {
+    inline SkPaint* refPaint(SkPaint* paint) {
         if (!paint) {
-            addInt((int) NULL);
             return paint;
         }
 
@@ -810,14 +626,11 @@
             mPaints.add(paintCopy);
         }
 
-        addInt((int) paintCopy);
-
         return paintCopy;
     }
 
-    inline SkRegion* addRegion(SkRegion* region) {
+    inline SkRegion* refRegion(SkRegion* region) {
         if (!region) {
-            addInt((int) NULL);
             return region;
         }
 
@@ -830,53 +643,35 @@
             mRegions.add(regionCopy);
         }
 
-        addInt((int) regionCopy);
-
         return regionCopy;
     }
 
-    inline void addDisplayList(DisplayList* displayList) {
-        // TODO: To be safe, the display list should be ref-counted in the
-        //       resources cache, but we rely on the caller (UI toolkit) to
-        //       do the right thing for now
-        addInt((int) displayList);
-    }
-
-    inline void addMatrix(SkMatrix* matrix) {
+    inline SkMatrix* refMatrix(SkMatrix* matrix) {
         // Copying the matrix is cheap and prevents against the user changing the original
         // matrix before the operation that uses it
         SkMatrix* copy = new SkMatrix(*matrix);
-        addInt((int) copy);
         mMatrices.add(copy);
+        return copy;
     }
 
-    inline void addLayer(Layer* layer) {
-        addInt((int) layer);
-        mLayers.add(layer);
-        mCaches.resourceCache.incrementRefcount(layer);
-    }
-
-    inline void addBitmap(SkBitmap* bitmap) {
+    inline SkBitmap* refBitmap(SkBitmap* bitmap) {
         // Note that this assumes the bitmap is immutable. There are cases this won't handle
         // correctly, such as creating the bitmap from scratch, drawing with it, changing its
         // contents, and drawing again. The only fix would be to always copy it the first time,
         // which doesn't seem worth the extra cycles for this unlikely case.
-        addInt((int) bitmap);
         mBitmapResources.add(bitmap);
         mCaches.resourceCache.incrementRefcount(bitmap);
+        return bitmap;
     }
 
-    void addBitmapData(SkBitmap* bitmap) {
-        addInt((int) bitmap);
+    inline SkBitmap* refBitmapData(SkBitmap* bitmap) {
         mOwnedBitmapResources.add(bitmap);
         mCaches.resourceCache.incrementRefcount(bitmap);
+        return bitmap;
     }
 
-    inline void addShader(SkiaShader* shader) {
-        if (!shader) {
-            addInt((int) NULL);
-            return;
-        }
+    inline SkiaShader* refShader(SkiaShader* shader) {
+        if (!shader) return NULL;
 
         SkiaShader* shaderCopy = mShaderMap.valueFor(shader);
         // TODO: We also need to handle generation ID changes in compose shaders
@@ -887,14 +682,13 @@
             mShaders.add(shaderCopy);
             mCaches.resourceCache.incrementRefcount(shaderCopy);
         }
-
-        addInt((int) shaderCopy);
+        return shaderCopy;
     }
 
-    inline void addColorFilter(SkiaColorFilter* colorFilter) {
-        addInt((int) colorFilter);
+    inline SkiaColorFilter* refColorFilter(SkiaColorFilter* colorFilter) {
         mFilterResources.add(colorFilter);
         mCaches.resourceCache.incrementRefcount(colorFilter);
+        return colorFilter;
     }
 
     Vector<SkBitmap*> mBitmapResources;
@@ -919,12 +713,10 @@
 
     Vector<Layer*> mLayers;
 
-    uint32_t mBufferSize;
-
     int mRestoreSaveCount;
 
     Caches& mCaches;
-    SkWriter32 mWriter;
+    sp<DisplayListData> mDisplayListData;
 
     float mTranslateX;
     float mTranslateY;
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 1fa1b20..6a05789 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -142,6 +142,18 @@
 // Setup
 ///////////////////////////////////////////////////////////////////////////////
 
+void OpenGLRenderer::setName(const char* name) {
+    if (name) {
+        mName.setTo(name);
+    } else {
+        mName.clear();
+    }
+}
+
+const char* OpenGLRenderer::getName() const {
+    return mName.string();
+}
+
 bool OpenGLRenderer::isDeferred() {
     return false;
 }
@@ -206,8 +218,10 @@
     // the back buffer for this frame.
     if (mCaches.extensions.hasDiscardFramebuffer() &&
             left <= 0.0f && top <= 0.0f && right >= mWidth && bottom >= mHeight) {
-        const GLenum attachments[] = { getTargetFbo() == 0 ? (const GLenum) GL_COLOR_EXT :
-                (const GLenum) GL_COLOR_ATTACHMENT0, GL_STENCIL_EXT };
+        const bool isFbo = getTargetFbo() == 0;
+        const GLenum attachments[] = {
+                isFbo ? (const GLenum) GL_COLOR_EXT : (const GLenum) GL_COLOR_ATTACHMENT0,
+                isFbo ? (const GLenum) GL_STENCIL_EXT : (const GLenum) GL_STENCIL_ATTACHMENT };
         glDiscardFramebufferEXT(GL_FRAMEBUFFER, 1, attachments);
     }
 }
@@ -816,7 +830,7 @@
     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
             layer->getTexture(), 0);
 
-    startTiling(mSnapshot, !layer->isBlend());
+    startTiling(mSnapshot, true);
 
     // Clear the FBO, expand the clear region by 1 to get nice bilinear filtering
     mCaches.enableScissor();
@@ -1101,7 +1115,7 @@
         rects.push(r.fTop);
         rects.push(r.fRight);
         rects.push(r.fBottom);
-        count++;
+        count += 4;
         it.next();
     }
 
@@ -1265,7 +1279,7 @@
 
         glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, buffer);
 
-        startTiling(layer->clipRect, layer->layer.getHeight(), !layer->isBlend());
+        startTiling(layer->clipRect, layer->layer.getHeight());
     }
 }
 
@@ -1744,7 +1758,7 @@
 
 void OpenGLRenderer::outputDisplayList(DisplayList* displayList, uint32_t level) {
     if (displayList) {
-        displayList->output(*this, level);
+        displayList->output(level);
     }
 }
 
@@ -2094,7 +2108,6 @@
  */
 void OpenGLRenderer::drawConvexPath(const SkPath& path, SkPaint* paint) {
     int color = paint->getColor();
-    SkPaint::Style style = paint->getStyle();
     SkXfermode::Mode mode = getXfermode(paint->getXfermode());
     bool isAA = paint->isAntiAlias();
 
@@ -3205,8 +3218,7 @@
     Vertex mesh[count * 6];
     Vertex* vertex = mesh;
 
-    for (int i = 0; i < count; i++) {
-        int index = i * 4;
+    for (int index = 0; index < count; index += 4) {
         float l = rects[index + 0];
         float t = rects[index + 1];
         float r = rects[index + 2];
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index 594580e..750b3d2 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -64,6 +64,19 @@
     virtual ~OpenGLRenderer();
 
     /**
+     * Sets the name of this renderer. The name is optional and
+     * empty by default. If the pointer is null the name is set
+     * to the empty string.
+     */
+    ANDROID_API void setName(const char* name);
+
+    /**
+     * Returns the name of this renderer as UTF8 string.
+     * The returned pointer is never null.
+     */
+    ANDROID_API const char* getName() const;
+
+    /**
      * Read externally defined properties to control the behavior
      * of the renderer.
      */
@@ -904,6 +917,9 @@
     // No-ops start/endTiling when set
     bool mSuppressTiling;
 
+    // Optional name of the renderer
+    String8 mName;
+
     friend class DisplayListRenderer;
 
 }; // class OpenGLRenderer
diff --git a/libs/hwui/Patch.cpp b/libs/hwui/Patch.cpp
index e490151..45c619e 100644
--- a/libs/hwui/Patch.cpp
+++ b/libs/hwui/Patch.cpp
@@ -122,8 +122,6 @@
     float rescaleX = 1.0f;
     float rescaleY = 1.0f;
 
-    const float meshWidth = right - left;
-
     if (xStretchCount > 0) {
         uint32_t stretchSize = 0;
         for (uint32_t i = 1; i < mXCount; i += 2) {
diff --git a/libs/hwui/PathRenderer.cpp b/libs/hwui/PathRenderer.cpp
index dd13d79..d59e36f 100644
--- a/libs/hwui/PathRenderer.cpp
+++ b/libs/hwui/PathRenderer.cpp
@@ -596,7 +596,6 @@
     SkPath::Iter iter(path, forceClose);
     SkPoint pts[4];
     SkPath::Verb v;
-    Vertex* newVertex = 0;
     while (SkPath::kDone_Verb != (v = iter.next(pts))) {
             switch (v) {
                 case SkPath::kMove_Verb:
diff --git a/libs/hwui/Rect.h b/libs/hwui/Rect.h
index 80f39ff90..5f4bb5a 100644
--- a/libs/hwui/Rect.h
+++ b/libs/hwui/Rect.h
@@ -171,22 +171,19 @@
     }
 
 private:
-    static inline float min(float a, float b) { return (a < b) ? a : b; }
-    static inline float max(float a, float b) { return (a > b) ? a : b; }
-
     void intersectWith(Rect& tmp) const {
-        tmp.left = max(left, tmp.left);
-        tmp.top = max(top, tmp.top);
-        tmp.right = min(right, tmp.right);
-        tmp.bottom = min(bottom, tmp.bottom);
+        tmp.left = fmaxf(left, tmp.left);
+        tmp.top = fmaxf(top, tmp.top);
+        tmp.right = fminf(right, tmp.right);
+        tmp.bottom = fminf(bottom, tmp.bottom);
     }
 
     Rect intersectWith(float l, float t, float r, float b) const {
         Rect tmp;
-        tmp.left = max(left, l);
-        tmp.top = max(top, t);
-        tmp.right = min(right, r);
-        tmp.bottom = min(bottom, b);
+        tmp.left = fmaxf(left, l);
+        tmp.top = fmaxf(top, t);
+        tmp.right = fminf(right, r);
+        tmp.bottom = fminf(bottom, b);
         return tmp;
     }
 
diff --git a/media/java/android/media/AudioRecord.java b/media/java/android/media/AudioRecord.java
index 772cb4c..5383d08 100644
--- a/media/java/android/media/AudioRecord.java
+++ b/media/java/android/media/AudioRecord.java
@@ -290,6 +290,10 @@
             mChannelCount = 2;
             mChannels = AudioFormat.CHANNEL_IN_STEREO;
             break;
+        case (AudioFormat.CHANNEL_IN_FRONT | AudioFormat.CHANNEL_IN_BACK):
+            mChannelCount = 2;
+            mChannels = channelConfig;
+            break;
         default:
             mChannelCount = 0;
             mChannels = AudioFormat.CHANNEL_INVALID;
@@ -464,6 +468,7 @@
             break;
         case AudioFormat.CHANNEL_IN_STEREO:
         case AudioFormat.CHANNEL_CONFIGURATION_STEREO:
+        case (AudioFormat.CHANNEL_IN_FRONT | AudioFormat.CHANNEL_IN_BACK):
             channelCount = 2;
             break;
         case AudioFormat.CHANNEL_INVALID:
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
index fc0ff55..16007c4 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
@@ -71,7 +71,7 @@
     // database gets upgraded properly. At a minimum, please confirm that 'upgradeVersion'
     // is properly propagated through your change.  Not doing so will result in a loss of user
     // settings.
-    private static final int DATABASE_VERSION = 96;
+    private static final int DATABASE_VERSION = 97;
 
     private Context mContext;
     private int mUserHandle;
@@ -1536,6 +1536,11 @@
             upgradeVersion = 96;
         }
 
+        if (upgradeVersion == 96) {
+            // NOP bump due to a reverted change that some people got on upgrade.
+            upgradeVersion = 97;
+        }
+
         // *** Remember to update DATABASE_VERSION above!
 
         if (upgradeVersion != currentVersion) {
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index c40e26d..48edc73 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -189,7 +189,7 @@
     <string name="quick_settings_location_label" msgid="3292451598267467545">"الموقع المستخدم"</string>
     <string name="quick_settings_media_device_label" msgid="1302906836372603762">"جهاز الوسائط"</string>
     <string name="quick_settings_rssi_label" msgid="7725671335550695589">"RSSI"</string>
-    <string name="quick_settings_rssi_emergency_only" msgid="2713774041672886750">"مكالمات الطوارئ فقط"</string>
+    <string name="quick_settings_rssi_emergency_only" msgid="2713774041672886750">"مكالمات طوارئ فقط"</string>
     <string name="quick_settings_settings_label" msgid="5326556592578065401">"الإعدادات"</string>
     <string name="quick_settings_time_label" msgid="4635969182239736408">"الوقت"</string>
     <string name="quick_settings_user_label" msgid="5238995632130897840">"أنا"</string>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 81ac841..3d0ddd4 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -118,8 +118,8 @@
     <string name="accessibility_two_bars" msgid="6437363648385206679">"два деления"</string>
     <string name="accessibility_three_bars" msgid="2648241415119396648">"три деления"</string>
     <string name="accessibility_signal_full" msgid="9122922886519676839">"надежный сигнал"</string>
-    <string name="accessibility_desc_on" msgid="2385254693624345265">"ВКЛ"</string>
-    <string name="accessibility_desc_off" msgid="6475508157786853157">"ВЫКЛ"</string>
+    <string name="accessibility_desc_on" msgid="2385254693624345265">"Вкл."</string>
+    <string name="accessibility_desc_off" msgid="6475508157786853157">"Выкл."</string>
     <string name="accessibility_desc_connected" msgid="8366256693719499665">"Подключено"</string>
     <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
     <string name="accessibility_data_connection_1x" msgid="994133468120244018">"1 X"</string>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index 91214d1..7666f7d 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -197,8 +197,8 @@
     <string name="quick_settings_wifi_not_connected" msgid="7171904845345573431">"Ej ansluten"</string>
     <string name="quick_settings_wifi_no_network" msgid="2221993077220856376">"Inget nätverk"</string>
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi är inaktiverat"</string>
-    <string name="quick_settings_wifi_display_label" msgid="6893592964463624333">"Wi-Fi visas"</string>
-    <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Trådlös visning"</string>
+    <string name="quick_settings_wifi_display_label" msgid="6893592964463624333">"Trådlös skärm"</string>
+    <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Trådlös skärm"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Ljusstyrka"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
     <string name="status_bar_help_title" msgid="1199237744086469217">"Meddelanden visas här"</string>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 7750e77..f43eabe 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -35,10 +35,10 @@
     <string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Поточні"</string>
     <string name="status_bar_latest_events_title" msgid="6594767438577593172">"Сповіщення"</string>
     <string name="battery_low_title" msgid="2783104807551211639">"Підключіть зарядний пристрій"</string>
-    <string name="battery_low_subtitle" msgid="1752040062087829196">"Батарея виснажується."</string>
+    <string name="battery_low_subtitle" msgid="1752040062087829196">"Акумулятор розряджається."</string>
     <string name="battery_low_percent_format" msgid="1077244949318261761">"Залишилося <xliff:g id="NUMBER">%d%%</xliff:g>"</string>
     <string name="invalid_charger" msgid="4549105996740522523">"Заряджання USB не підтримується."\n"Використовуйте лише наданий у комплекті зарядний пристрій."</string>
-    <string name="battery_low_why" msgid="7279169609518386372">"Викор. батареї"</string>
+    <string name="battery_low_why" msgid="7279169609518386372">"Використання акумулятора"</string>
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Налаштування"</string>
     <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Режим польоту"</string>
@@ -85,11 +85,11 @@
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Збільшення екрана."</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth під’єднано."</string>
     <string name="accessibility_bluetooth_disconnected" msgid="7416648669976870175">"Bluetooth від’єднано."</string>
-    <string name="accessibility_no_battery" msgid="358343022352820946">"Немає заряду батареї."</string>
-    <string name="accessibility_battery_one_bar" msgid="7774887721891057523">"Одна смужка заряду батареї."</string>
-    <string name="accessibility_battery_two_bars" msgid="8500650438735009973">"Дві смужки заряду батареї."</string>
-    <string name="accessibility_battery_three_bars" msgid="2302983330865040446">"Три смужки заряду батареї."</string>
-    <string name="accessibility_battery_full" msgid="8909122401720158582">"Повний заряд батареї"</string>
+    <string name="accessibility_no_battery" msgid="358343022352820946">"Акумулятор розряджений."</string>
+    <string name="accessibility_battery_one_bar" msgid="7774887721891057523">"Заряд акумулятора: одна смужка."</string>
+    <string name="accessibility_battery_two_bars" msgid="8500650438735009973">"Заряд акумулятора: дві смужки."</string>
+    <string name="accessibility_battery_three_bars" msgid="2302983330865040446">"Заряд акумулятора: три смужки."</string>
+    <string name="accessibility_battery_full" msgid="8909122401720158582">"Акумулятор заряджений."</string>
     <string name="accessibility_no_phone" msgid="4894708937052611281">"Немає сигналу телефону."</string>
     <string name="accessibility_phone_one_bar" msgid="687699278132664115">"Одна смужка сигналу телефону."</string>
     <string name="accessibility_phone_two_bars" msgid="8384905382804815201">"Дві смужки сигналу телефону."</string>
@@ -134,7 +134,7 @@
     <string name="accessibility_no_sim" msgid="8274017118472455155">"Немає SIM-карти."</string>
     <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Прив’язка Bluetooth."</string>
     <string name="accessibility_airplane_mode" msgid="834748999790763092">"Режим польоту."</string>
-    <string name="accessibility_battery_level" msgid="7451474187113371965">"Відсотків батареї: <xliff:g id="NUMBER">%d</xliff:g>."</string>
+    <string name="accessibility_battery_level" msgid="7451474187113371965">"Заряд акумулятора: <xliff:g id="NUMBER">%d</xliff:g>."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Налаштування системи."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Сповіщення."</string>
     <string name="accessibility_remove_notification" msgid="3603099514902182350">"Очистити сповіщення."</string>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationController.java
index 776cf36..0944b40 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationController.java
@@ -120,7 +120,7 @@
 
                 int[] idOut = new int[1];
                 mNotificationService.enqueueNotificationWithTag(
-                        mContext.getPackageName(),
+                        mContext.getPackageName(), mContext.getBasePackageName(),
                         null, 
                         GPS_NOTIFICATION_ID, 
                         n,
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index d1fb2b0..8135d22 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -4408,7 +4408,7 @@
                     sendCloseSystemWindows();
                 }
                 int result = ActivityManagerNative.getDefault()
-                        .startActivityAsUser(null, mHomeIntent,
+                        .startActivityAsUser(null, null, mHomeIntent,
                                 mHomeIntent.resolveTypeIfNeeded(mContext.getContentResolver()),
                                 null, null, 0,
                                 ActivityManager.START_FLAG_ONLY_IF_NEEDED,
@@ -4480,12 +4480,21 @@
             default:
                 return false;
         }
+        int owningUid;
+        String owningPackage;
+        if (win != null) {
+            owningUid = win.getOwningUid();
+            owningPackage = win.getOwningPackage();
+        } else {
+            owningUid = android.os.Process.myUid();
+            owningPackage = mContext.getBasePackageName();
+        }
         if (pattern.length == 1) {
             // One-shot vibration
-            mVibrator.vibrate(pattern[0]);
+            mVibrator.vibrate(owningUid, owningPackage, pattern[0]);
         } else {
             // Pattern vibration
-            mVibrator.vibrate(pattern, -1);
+            mVibrator.vibrate(owningUid, owningPackage, pattern, -1);
         }
         return true;
     }
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardActivityLauncher.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardActivityLauncher.java
index 4c19caa..6539db3 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardActivityLauncher.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardActivityLauncher.java
@@ -219,6 +219,7 @@
                 try {
                     WaitResult result = ActivityManagerNative.getDefault().startActivityAndWait(
                             null /*caller*/,
+                            null /*caller pkg*/,
                             intent,
                             intent.resolveTypeIfNeeded(getContext().getContentResolver()),
                             null /*resultTo*/,
diff --git a/services/java/com/android/server/AppOpsService.java b/services/java/com/android/server/AppOpsService.java
index bf2a5ae..335917e 100644
--- a/services/java/com/android/server/AppOpsService.java
+++ b/services/java/com/android/server/AppOpsService.java
@@ -203,9 +203,9 @@
 
     @Override
     public void setMode(int code, int uid, String packageName, int mode) {
-        uid = handleIncomingUid(uid);
+        verifyIncomingUid(uid);
         synchronized (this) {
-            Op op = getOpLocked(code, uid, packageName, true);
+            Op op = getOpLocked(AppOpsManager.opToSwitch(code), uid, packageName, true);
             if (op != null) {
                 if (op.mode != mode) {
                     op.mode = mode;
@@ -217,9 +217,9 @@
 
     @Override
     public int checkOperation(int code, int uid, String packageName) {
-        uid = handleIncomingUid(uid);
+        verifyIncomingUid(uid);
         synchronized (this) {
-            Op op = getOpLocked(code, uid, packageName, false);
+            Op op = getOpLocked(AppOpsManager.opToSwitch(code), uid, packageName, false);
             if (op == null) {
                 return AppOpsManager.MODE_ALLOWED;
             }
@@ -229,24 +229,27 @@
 
     @Override
     public int noteOperation(int code, int uid, String packageName) {
-        uid = handleIncomingUid(uid);
+        verifyIncomingUid(uid);
         synchronized (this) {
-            Op op = getOpLocked(code, uid, packageName, true);
-            if (op == null) {
+            Ops ops = getOpsLocked(uid, packageName, true);
+            if (ops == null) {
                 if (DEBUG) Log.d(TAG, "noteOperation: no op for code " + code + " uid " + uid
                         + " package " + packageName);
                 return AppOpsManager.MODE_IGNORED;
             }
+            Op op = getOpLocked(ops, code, true);
             if (op.duration == -1) {
                 Slog.w(TAG, "Noting op not finished: uid " + uid + " pkg " + packageName
                         + " code " + code + " time=" + op.time + " duration=" + op.duration);
             }
             op.duration = 0;
-            if (op.mode != AppOpsManager.MODE_ALLOWED) {
-                if (DEBUG) Log.d(TAG, "noteOperation: reject #" + op.mode + " for code " + code
-                        + " uid " + uid + " package " + packageName);
+            final int switchCode = AppOpsManager.opToSwitch(code);
+            final Op switchOp = switchCode != code ? getOpLocked(ops, switchCode, true) : op;
+            if (switchOp.mode != AppOpsManager.MODE_ALLOWED) {
+                if (DEBUG) Log.d(TAG, "noteOperation: reject #" + op.mode + " for code "
+                        + switchCode + " (" + code + ") uid " + uid + " package " + packageName);
                 op.rejectTime = System.currentTimeMillis();
-                return op.mode;
+                return switchOp.mode;
             }
             if (DEBUG) Log.d(TAG, "noteOperation: allowing code " + code + " uid " + uid
                     + " package " + packageName);
@@ -257,19 +260,22 @@
 
     @Override
     public int startOperation(int code, int uid, String packageName) {
-        uid = handleIncomingUid(uid);
+        verifyIncomingUid(uid);
         synchronized (this) {
-            Op op = getOpLocked(code, uid, packageName, true);
-            if (op == null) {
+            Ops ops = getOpsLocked(uid, packageName, true);
+            if (ops == null) {
                 if (DEBUG) Log.d(TAG, "startOperation: no op for code " + code + " uid " + uid
                         + " package " + packageName);
                 return AppOpsManager.MODE_IGNORED;
             }
-            if (op.mode != AppOpsManager.MODE_ALLOWED) {
-                if (DEBUG) Log.d(TAG, "startOperation: reject #" + op.mode + " for code " + code
-                        + " uid " + uid + " package " + packageName);
+            Op op = getOpLocked(ops, code, true);
+            final int switchCode = AppOpsManager.opToSwitch(code);
+            final Op switchOp = switchCode != code ? getOpLocked(ops, switchCode, true) : op;
+            if (switchOp.mode != AppOpsManager.MODE_ALLOWED) {
+                if (DEBUG) Log.d(TAG, "startOperation: reject #" + op.mode + " for code "
+                        + switchCode + " (" + code + ") uid " + uid + " package " + packageName);
                 op.rejectTime = System.currentTimeMillis();
-                return op.mode;
+                return switchOp.mode;
             }
             if (DEBUG) Log.d(TAG, "startOperation: allowing code " + code + " uid " + uid
                     + " package " + packageName);
@@ -284,7 +290,7 @@
 
     @Override
     public void finishOperation(int code, int uid, String packageName) {
-        uid = handleIncomingUid(uid);
+        verifyIncomingUid(uid);
         synchronized (this) {
             Op op = getOpLocked(code, uid, packageName, true);
             if (op == null) {
@@ -305,16 +311,15 @@
         }
     }
 
-    private int handleIncomingUid(int uid) {
+    private void verifyIncomingUid(int uid) {
         if (uid == Binder.getCallingUid()) {
-            return uid;
+            return;
         }
         if (Binder.getCallingPid() == Process.myPid()) {
-            return uid;
+            return;
         }
         mContext.enforcePermission(android.Manifest.permission.UPDATE_APP_OPS_STATS,
                 Binder.getCallingPid(), Binder.getCallingUid(), null);
-        return uid;
     }
 
     private Ops getOpsLocked(int uid, String packageName, boolean edit) {
@@ -377,6 +382,10 @@
         if (ops == null) {
             return null;
         }
+        return getOpLocked(ops, code, edit);
+    }
+
+    private Op getOpLocked(Ops ops, int code, boolean edit) {
         Op op = ops.get(code);
         if (op == null) {
             if (!edit) {
diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java
index 7cfa8c2..4cfe5d5 100644
--- a/services/java/com/android/server/ConnectivityService.java
+++ b/services/java/com/android/server/ConnectivityService.java
@@ -194,6 +194,7 @@
     private int mNetworkPreference;
     private int mActiveDefaultNetwork = -1;
     // 0 is full bad, 100 is full good
+    private int mDefaultInetCondition = 0;
     private int mDefaultInetConditionPublished = 0;
     private boolean mInetConditionChangeInFlight = false;
     private int mDefaultConnectionSequence = 0;
@@ -1729,10 +1730,6 @@
                 intent.putExtra(ConnectivityManager.EXTRA_OTHER_NETWORK_INFO, switchTo);
             } else {
                 mDefaultInetConditionPublished = 0; // we're not connected anymore
-                if (DBG) {
-                    log("handleDisconnect: net=" + mActiveDefaultNetwork +
-                            ", published condition=" + mDefaultInetConditionPublished);
-                }
                 intent.putExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, true);
             }
         }
@@ -1923,10 +1920,6 @@
                 intent.putExtra(ConnectivityManager.EXTRA_OTHER_NETWORK_INFO, switchTo);
             } else {
                 mDefaultInetConditionPublished = 0;
-                if (DBG) {
-                    log("handleConnectionFailure: net=" + mActiveDefaultNetwork +
-                            ", published condition=" + mDefaultInetConditionPublished);
-                }
                 intent.putExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, true);
             }
         }
@@ -2071,10 +2064,6 @@
             mDefaultInetConditionPublished = 0;
             mDefaultConnectionSequence++;
             mInetConditionChangeInFlight = false;
-            if (DBG) {
-                log("handleConnect: net=" + newNetType +
-                        ", published condition=" + mDefaultInetConditionPublished);
-            }
             // Don't do this - if we never sign in stay, grey
             //reportNetworkCondition(mActiveDefaultNetwork, 100);
         }
@@ -2790,8 +2779,7 @@
                 {
                     int netType = msg.arg1;
                     int sequence = msg.arg2;
-                    int condition = (Integer)msg.obj;
-                    handleInetConditionHoldEnd(netType, sequence, condition);
+                    handleInetConditionHoldEnd(netType, sequence);
                     break;
                 }
                 case EVENT_SET_NETWORK_PREFERENCE:
@@ -3004,13 +2992,14 @@
         if (VDBG) {
             log("handleInetConditionChange: net=" +
                     netType + ", condition=" + condition +
-                    " mActiveDefaultNetwork=" + mActiveDefaultNetwork);
+                    ",mActiveDefaultNetwork=" + mActiveDefaultNetwork);
         }
+        mDefaultInetCondition = condition;
         int delay;
         if (mInetConditionChangeInFlight == false) {
             if (VDBG) log("handleInetConditionChange: starting a change hold");
             // setup a new hold to debounce this
-            if (condition > 50) {
+            if (mDefaultInetCondition > 50) {
                 delay = Settings.Global.getInt(mContext.getContentResolver(),
                         Settings.Global.INET_CONDITION_DEBOUNCE_UP_DELAY, 500);
             } else {
@@ -3019,16 +3008,18 @@
             }
             mInetConditionChangeInFlight = true;
             mHandler.sendMessageDelayed(mHandler.obtainMessage(EVENT_INET_CONDITION_HOLD_END,
-                    mActiveDefaultNetwork, mDefaultConnectionSequence, new Integer(condition)), delay);
+                    mActiveDefaultNetwork, mDefaultConnectionSequence), delay);
         } else {
             // we've set the new condition, when this hold ends that will get picked up
             if (VDBG) log("handleInetConditionChange: currently in hold - not setting new end evt");
         }
     }
 
-    private void handleInetConditionHoldEnd(int netType, int sequence, int condition) {
+    private void handleInetConditionHoldEnd(int netType, int sequence) {
         if (DBG) {
-            log("handleInetConditionHoldEnd: net=" + netType + ", condition=" + condition);
+            log("handleInetConditionHoldEnd: net=" + netType +
+                    ", condition=" + mDefaultInetCondition +
+                    ", published condition=" + mDefaultInetConditionPublished);
         }
         mInetConditionChangeInFlight = false;
 
@@ -3040,13 +3031,19 @@
             if (DBG) log("handleInetConditionHoldEnd: event hold for obsolete network - ignoring");
             return;
         }
-
+        // TODO: Figure out why this optimization sometimes causes a
+        //       change in mDefaultInetCondition to be missed and the
+        //       UI to not be updated.
+        //if (mDefaultInetConditionPublished == mDefaultInetCondition) {
+        //    if (DBG) log("no change in condition - aborting");
+        //    return;
+        //}
         NetworkInfo networkInfo = mNetTrackers[mActiveDefaultNetwork].getNetworkInfo();
         if (networkInfo.isConnected() == false) {
             if (DBG) log("handleInetConditionHoldEnd: default network not connected - ignoring");
             return;
         }
-        mDefaultInetConditionPublished = condition;
+        mDefaultInetConditionPublished = mDefaultInetCondition;
         sendInetConditionBroadcast(networkInfo);
         return;
     }
diff --git a/services/java/com/android/server/EntropyMixer.java b/services/java/com/android/server/EntropyMixer.java
index 4632374..8c0d260 100644
--- a/services/java/com/android/server/EntropyMixer.java
+++ b/services/java/com/android/server/EntropyMixer.java
@@ -142,6 +142,7 @@
             out.println(SystemProperties.get("ro.bootloader"));
             out.println(SystemProperties.get("ro.hardware"));
             out.println(SystemProperties.get("ro.revision"));
+            out.println(SystemProperties.get("ro.build.fingerprint"));
             out.println(new Object().hashCode());
             out.println(System.currentTimeMillis());
             out.println(System.nanoTime());
diff --git a/services/java/com/android/server/NotificationManagerService.java b/services/java/com/android/server/NotificationManagerService.java
index 37d7ce7..d121653 100644
--- a/services/java/com/android/server/NotificationManagerService.java
+++ b/services/java/com/android/server/NotificationManagerService.java
@@ -23,6 +23,7 @@
 import android.app.ActivityManager;
 import android.app.ActivityManagerNative;
 import android.app.AppGlobals;
+import android.app.AppOpsManager;
 import android.app.IActivityManager;
 import android.app.INotificationManager;
 import android.app.ITransientNotification;
@@ -35,6 +36,7 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.res.Resources;
@@ -62,21 +64,17 @@
 import android.util.Xml;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityManager;
-import android.widget.RemoteViews;
 import android.widget.Toast;
 
 import com.android.internal.statusbar.StatusBarNotification;
-import com.android.internal.util.FastXmlSerializer;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlSerializer;
 
 import java.io.File;
 import java.io.FileDescriptor;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.util.ArrayList;
@@ -156,6 +154,8 @@
     private ArrayList<NotificationRecord> mLights = new ArrayList<NotificationRecord>();
     private NotificationRecord mLedNotification;
 
+    private final AppOpsManager mAppOps;
+
     // Notification control database. For now just contains disabled packages.
     private AtomicFile mPolicyFile;
     private HashSet<String> mBlockedPackages = new HashSet<String>();
@@ -218,79 +218,35 @@
         }
     }
 
-    private void writeBlockDb() {
-        synchronized(mBlockedPackages) {
-            FileOutputStream outfile = null;
-            try {
-                outfile = mPolicyFile.startWrite();
-
-                XmlSerializer out = new FastXmlSerializer();
-                out.setOutput(outfile, "utf-8");
-
-                out.startDocument(null, true);
-
-                out.startTag(null, TAG_BODY); {
-                    out.attribute(null, ATTR_VERSION, String.valueOf(DB_VERSION));
-                    out.startTag(null, TAG_BLOCKED_PKGS); {
-                        // write all known network policies
-                        for (String pkg : mBlockedPackages) {
-                            out.startTag(null, TAG_PACKAGE); {
-                                out.attribute(null, ATTR_NAME, pkg);
-                            } out.endTag(null, TAG_PACKAGE);
-                        }
-                    } out.endTag(null, TAG_BLOCKED_PKGS);
-                } out.endTag(null, TAG_BODY);
-
-                out.endDocument();
-
-                mPolicyFile.finishWrite(outfile);
-            } catch (IOException e) {
-                if (outfile != null) {
-                    mPolicyFile.failWrite(outfile);
-                }
-            }
-        }
-    }
-
-    public boolean areNotificationsEnabledForPackage(String pkg) {
+    /**
+     * Use this when you just want to know if notifications are OK for this package.
+     */
+    public boolean areNotificationsEnabledForPackage(String pkg, int uid) {
         checkCallerIsSystem();
-        return areNotificationsEnabledForPackageInt(pkg);
+        return (mAppOps.checkOpNoThrow(AppOpsManager.OP_POST_NOTIFICATION, uid, pkg)
+                == AppOpsManager.MODE_ALLOWED);
     }
 
-    // Unchecked. Not exposed via Binder, but can be called in the course of enqueue*().
-    private boolean areNotificationsEnabledForPackageInt(String pkg) {
-        final boolean enabled = !mBlockedPackages.contains(pkg);
-        if (DBG) {
-            Slog.v(TAG, "notifications are " + (enabled?"en":"dis") + "abled for " + pkg);
+    /** Use this when you actually want to post a notification or toast.
+     *
+     * Unchecked. Not exposed via Binder, but can be called in the course of enqueue*().
+     */
+    private boolean noteNotificationOp(String pkg, int uid) {
+        if (mAppOps.noteOpNoThrow(AppOpsManager.OP_POST_NOTIFICATION, uid, pkg)
+                != AppOpsManager.MODE_ALLOWED) {
+            Slog.v(TAG, "notifications are disabled by AppOps for " + pkg);
+            return false;
         }
-        return enabled;
+        return true;
     }
 
-    public void setNotificationsEnabledForPackage(String pkg, boolean enabled) {
+    public void setNotificationsEnabledForPackage(String pkg, int uid, boolean enabled) {
         checkCallerIsSystem();
-        if (DBG) {
+        if (true||DBG) {
             Slog.v(TAG, (enabled?"en":"dis") + "abling notifications for " + pkg);
         }
-        if (enabled) {
-            mBlockedPackages.remove(pkg);
-        } else {
-            mBlockedPackages.add(pkg);
-
-            // Now, cancel any outstanding notifications that are part of a just-disabled app
-            if (ENABLE_BLOCKED_NOTIFICATIONS) {
-                synchronized (mNotificationList) {
-                    final int N = mNotificationList.size();
-                    for (int i=0; i<N; i++) {
-                        final NotificationRecord r = mNotificationList.get(i);
-                        if (r.pkg.equals(pkg)) {
-                            cancelNotificationLocked(r, false);
-                        }
-                    }
-                }
-            }
-            // Don't bother canceling toasts, they'll go away soon enough.
-        }
-        writeBlockDb();
+        mAppOps.setMode(AppOpsManager.OP_POST_NOTIFICATION, uid, pkg,
+                enabled ? AppOpsManager.MODE_ALLOWED : AppOpsManager.MODE_IGNORED);
     }
 
 
@@ -322,6 +278,7 @@
     private static final class NotificationRecord
     {
         final String pkg;
+        final String basePkg;
         final String tag;
         final int id;
         final int uid;
@@ -331,10 +288,11 @@
         final int score;
         IBinder statusBarKey;
 
-        NotificationRecord(String pkg, String tag, int id, int uid, int initialPid,
+        NotificationRecord(String pkg, String basePkg, String tag, int id, int uid, int initialPid,
                 int userId, int score, Notification notification)
         {
             this.pkg = pkg;
+            this.basePkg = basePkg;
             this.tag = tag;
             this.id = id;
             this.uid = uid;
@@ -628,7 +586,9 @@
         mToastQueue = new ArrayList<ToastRecord>();
         mHandler = new WorkerHandler();
 
-        loadBlockDb();
+        mAppOps = (AppOpsManager)context.getSystemService(Context.APP_OPS_SERVICE);
+
+        importOldBlockDb();
 
         mStatusBar = statusBar;
         statusBar.setNotificationCallbacks(mNotificationCallbacks);
@@ -685,6 +645,28 @@
         observer.observe();
     }
 
+    /**
+     * Read the old XML-based app block database and import those blockages into the AppOps system.
+     */
+    private void importOldBlockDb() {
+        loadBlockDb();
+
+        PackageManager pm = mContext.getPackageManager();
+        for (String pkg : mBlockedPackages) {
+            PackageInfo info = null;
+            try {
+                info = pm.getPackageInfo(pkg, 0);
+                setNotificationsEnabledForPackage(pkg, info.applicationInfo.uid, false);
+            } catch (NameNotFoundException e) {
+                // forget you
+            }
+        }
+        mBlockedPackages.clear();
+        if (mPolicyFile != null) {
+            mPolicyFile.delete();
+        }
+    }
+
     void systemReady() {
         mAudioService = IAudioService.Stub.asInterface(
                 ServiceManager.getService(Context.AUDIO_SERVICE));
@@ -706,9 +688,11 @@
 
         final boolean isSystemToast = ("android".equals(pkg));
 
-        if (ENABLE_BLOCKED_TOASTS && !isSystemToast && !areNotificationsEnabledForPackageInt(pkg)) {
-            Slog.e(TAG, "Suppressing toast from package " + pkg + " by user request.");
-            return;
+        if (ENABLE_BLOCKED_TOASTS && !noteNotificationOp(pkg, Binder.getCallingUid())) {
+            if (!isSystemToast) {
+                Slog.e(TAG, "Suppressing toast from package " + pkg + " by user request.");
+                return;
+            }
         }
 
         synchronized (mToastQueue) {
@@ -898,10 +882,10 @@
 
     // Notifications
     // ============================================================================
-    public void enqueueNotificationWithTag(String pkg, String tag, int id, Notification notification,
-            int[] idOut, int userId)
+    public void enqueueNotificationWithTag(String pkg, String basePkg, String tag, int id,
+            Notification notification, int[] idOut, int userId)
     {
-        enqueueNotificationInternal(pkg, Binder.getCallingUid(), Binder.getCallingPid(),
+        enqueueNotificationInternal(pkg, basePkg, Binder.getCallingUid(), Binder.getCallingPid(),
                 tag, id, notification, idOut, userId);
     }
     
@@ -911,8 +895,8 @@
 
     // Not exposed via Binder; for system use only (otherwise malicious apps could spoof the
     // uid/pid of another application)
-    public void enqueueNotificationInternal(String pkg, int callingUid, int callingPid,
-            String tag, int id, Notification notification, int[] idOut, int userId)
+    public void enqueueNotificationInternal(String pkg, String basePkg, int callingUid,
+            int callingPid, String tag, int id, Notification notification, int[] idOut, int userId)
     {
         if (DBG) {
             Slog.v(TAG, "enqueueNotificationInternal: pkg=" + pkg + " id=" + id + " notification=" + notification);
@@ -982,9 +966,11 @@
         // 3. Apply local rules
 
         // blocked apps
-        if (ENABLE_BLOCKED_NOTIFICATIONS && !isSystemNotification && !areNotificationsEnabledForPackageInt(pkg)) {
-            score = JUNK_SCORE;
-            Slog.e(TAG, "Suppressing notification from package " + pkg + " by user request.");
+        if (ENABLE_BLOCKED_NOTIFICATIONS && !noteNotificationOp(pkg, callingUid)) {
+            if (!isSystemNotification) {
+                score = JUNK_SCORE;
+                Slog.e(TAG, "Suppressing notification from package " + pkg + " by user request.");
+            }
         }
 
         if (DBG) {
@@ -1000,7 +986,7 @@
         final boolean canInterrupt = (score >= SCORE_INTERRUPTION_THRESHOLD);
 
         synchronized (mNotificationList) {
-            NotificationRecord r = new NotificationRecord(pkg, tag, id, 
+            NotificationRecord r = new NotificationRecord(pkg, basePkg, tag, id,
                     callingUid, callingPid, userId,
                     score,
                     notification);
@@ -1157,15 +1143,16 @@
                         // does not have the VIBRATE permission.
                         long identity = Binder.clearCallingIdentity();
                         try {
-                            mVibrator.vibrate(useDefaultVibrate ? mDefaultVibrationPattern
-                                                                : mFallbackVibrationPattern,
+                            mVibrator.vibrate(r.uid, r.basePkg,
+                                useDefaultVibrate ? mDefaultVibrationPattern
+                                    : mFallbackVibrationPattern,
                                 ((notification.flags & Notification.FLAG_INSISTENT) != 0) ? 0: -1);
                         } finally {
                             Binder.restoreCallingIdentity(identity);
                         }
                     } else if (notification.vibrate.length > 1) {
                         // If you want your own vibration pattern, you need the VIBRATE permission
-                        mVibrator.vibrate(notification.vibrate,
+                        mVibrator.vibrate(r.uid, r.basePkg, notification.vibrate,
                             ((notification.flags & Notification.FLAG_INSISTENT) != 0) ? 0: -1);
                     }
                 }
diff --git a/services/java/com/android/server/UiModeManagerService.java b/services/java/com/android/server/UiModeManagerService.java
index 0e456f1..062be01 100644
--- a/services/java/com/android/server/UiModeManagerService.java
+++ b/services/java/com/android/server/UiModeManagerService.java
@@ -494,7 +494,7 @@
             if (Sandman.shouldStartDockApp(mContext, homeIntent)) {
                 try {
                     int result = ActivityManagerNative.getDefault().startActivityWithConfig(
-                            null, homeIntent, null, null, null, 0, 0,
+                            null, null, homeIntent, null, null, null, 0, 0,
                             mConfiguration, null, UserHandle.USER_CURRENT);
                     if (result >= ActivityManager.START_SUCCESS) {
                         dockAppStarted = true;
diff --git a/services/java/com/android/server/VibratorService.java b/services/java/com/android/server/VibratorService.java
index 69379f1..9065525 100644
--- a/services/java/com/android/server/VibratorService.java
+++ b/services/java/com/android/server/VibratorService.java
@@ -178,12 +178,23 @@
         return doVibratorExists();
     }
 
-    public void vibrate(String packageName, long milliseconds, IBinder token) {
+    private void verifyIncomingUid(int uid) {
+        if (uid == Binder.getCallingUid()) {
+            return;
+        }
+        if (Binder.getCallingPid() == Process.myPid()) {
+            return;
+        }
+        mContext.enforcePermission(android.Manifest.permission.UPDATE_APP_OPS_STATS,
+                Binder.getCallingPid(), Binder.getCallingUid(), null);
+    }
+
+    public void vibrate(int uid, String packageName, long milliseconds, IBinder token) {
         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.VIBRATE)
                 != PackageManager.PERMISSION_GRANTED) {
             throw new SecurityException("Requires VIBRATE permission");
         }
-        int uid = Binder.getCallingUid();
+        verifyIncomingUid(uid);
         // We're running in the system server so we cannot crash. Check for a
         // timeout of 0 or negative. This will ensure that a vibration has
         // either a timeout of > 0 or a non-null pattern.
@@ -219,12 +230,13 @@
         return true;
     }
 
-    public void vibratePattern(String packageName, long[] pattern, int repeat, IBinder token) {
+    public void vibratePattern(int uid, String packageName, long[] pattern, int repeat,
+            IBinder token) {
         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.VIBRATE)
                 != PackageManager.PERMISSION_GRANTED) {
             throw new SecurityException("Requires VIBRATE permission");
         }
-        int uid = Binder.getCallingUid();
+        verifyIncomingUid(uid);
         // so wakelock calls will succeed
         long identity = Binder.clearCallingIdentity();
         try {
@@ -454,7 +466,7 @@
         //synchronized (mInputDeviceVibrators) {
         //    return !mInputDeviceVibrators.isEmpty() || vibratorExists();
         //}
-        return vibratorExists();
+        return true || vibratorExists();
     }
 
     private void doVibratorOn(long millis, int uid) {
diff --git a/services/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/java/com/android/server/accessibility/AccessibilityManagerService.java
index b7c3450..bb040bf 100644
--- a/services/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -254,7 +254,7 @@
                             state.mTouchExplorationGrantedServices.remove(comp);
                             persistComponentNamesToSettingLocked(
                                     Settings.Secure.
-                                            TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES,
+                                    TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES,
                                     state.mEnabledServices, userId);
                             return;
                         }
@@ -534,6 +534,9 @@
             // No touch exploration.
             userState.mIsTouchExplorationEnabled = false;
 
+            // No touch enhanced web accessibility.
+            userState.mIsEnhancedWebAccessibilityEnabled = false;
+
             // Hook the automation service up.
             mUiAutomationService = new Service(mCurrentUserId, componentName,
                     accessibilityServiceInfo, true);
@@ -559,11 +562,11 @@
         synchronized (mLock) {
             UserState userState = getCurrentUserStateLocked();
             // Stash the old state so we can restore it when the keyguard is gone.
-            mTempStateChangeForCurrentUserMemento.initialize(mCurrentUserId,
-                    getCurrentUserStateLocked());
+            mTempStateChangeForCurrentUserMemento.initialize(getCurrentUserStateLocked());
             // Set the temporary state.
             userState.mIsAccessibilityEnabled = true;
-            userState.mIsTouchExplorationEnabled= touchExplorationEnabled;
+            userState.mIsTouchExplorationEnabled = touchExplorationEnabled;
+            userState.mIsEnhancedWebAccessibilityEnabled = false;
             userState.mIsDisplayMagnificationEnabled = false;
             userState.mEnabledServices.clear();
             userState.mEnabledServices.add(service);
@@ -842,12 +845,10 @@
                 userState.mEnabledServices);
     }
 
-    private void populateTouchExplorationGrantedAccessibilityServicesLocked(
-            UserState userState) {
+    private void populateTouchExplorationGrantedAccessibilityServicesLocked(UserState userState) {
         populateComponentNamesFromSettingLocked(
                 Settings.Secure.TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES,
-                userState.mUserId,
-                userState.mTouchExplorationGrantedServices);
+                userState.mUserId, userState.mTouchExplorationGrantedServices);
     }
 
     /**
@@ -896,6 +897,7 @@
             userState.mComponentNameToServiceMap.put(service.mComponentName, service);
             scheduleUpdateInputFilter(userState);
             tryEnableTouchExplorationLocked(service);
+            tryEnableEnhancedWebAccessibilityLocked(service);
         } catch (RemoteException e) {
             /* do nothing */
         }
@@ -918,6 +920,7 @@
         service.dispose();
         scheduleUpdateInputFilter(userState);
         tryDisableTouchExplorationLocked(service);
+        tryDisableEnhancedWebAccessibilityLocked(service);
         return removed;
     }
 
@@ -937,7 +940,7 @@
     private boolean canDispathEventLocked(Service service, AccessibilityEvent event,
             int handledFeedbackTypes) {
 
-        if (!service.canReceiveEvents()) {
+        if (!service.canReceiveEventsLocked()) {
             return false;
         }
 
@@ -1142,7 +1145,8 @@
 
     private void showEnableTouchExplorationDialog(final Service service) {
         String label = service.mResolveInfo.loadLabel(
-                mContext.getPackageManager()).toString();
+
+        mContext.getPackageManager()).toString();
         synchronized (mLock) {
             final UserState state = getCurrentUserStateLocked();
             if (state.mIsTouchExplorationEnabled) {
@@ -1155,35 +1159,35 @@
             mEnableTouchExplorationDialog = new AlertDialog.Builder(mContext)
                 .setIconAttribute(android.R.attr.alertDialogIcon)
                 .setPositiveButton(android.R.string.ok, new OnClickListener() {
-                    @Override
-                    public void onClick(DialogInterface dialog, int which) {
-                        // The user allowed the service to toggle touch exploration.
-                        state.mTouchExplorationGrantedServices.add(service.mComponentName);
-                        persistComponentNamesToSettingLocked(
-                                Settings.Secure.TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES,
-                                       state.mTouchExplorationGrantedServices, state.mUserId);
-                        // Enable touch exploration.
-                        Settings.Secure.putIntForUser(mContext.getContentResolver(),
-                                Settings.Secure.TOUCH_EXPLORATION_ENABLED, 1,
-                                service.mUserId);
-                    }
-                })
-                .setNegativeButton(android.R.string.cancel, new OnClickListener() {
-                    @Override
-                    public void onClick(DialogInterface dialog, int which) {
-                        dialog.dismiss();
-                    }
-                })
-                .setTitle(R.string.enable_explore_by_touch_warning_title)
-                .setMessage(mContext.getString(
-                        R.string.enable_explore_by_touch_warning_message, label))
-                .create();
-            mEnableTouchExplorationDialog.getWindow().setType(
-                    WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
-            mEnableTouchExplorationDialog.getWindow().getAttributes().privateFlags
-                    |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
-            mEnableTouchExplorationDialog.setCanceledOnTouchOutside(true);
-            mEnableTouchExplorationDialog.show();
+                     @Override
+                     public void onClick(DialogInterface dialog, int which) {
+                         // The user allowed the service to toggle touch exploration.
+                         state.mTouchExplorationGrantedServices.add(service.mComponentName);
+                         persistComponentNamesToSettingLocked(
+                                 Settings.Secure.TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES,
+                                 state.mTouchExplorationGrantedServices, state.mUserId);
+                         // Enable touch exploration.
+                         Settings.Secure.putIntForUser(mContext.getContentResolver(),
+                                 Settings.Secure.TOUCH_EXPLORATION_ENABLED, 1,
+                                 service.mUserId);
+                     }
+                 })
+                 .setNegativeButton(android.R.string.cancel, new OnClickListener() {
+                     @Override
+                     public void onClick(DialogInterface dialog, int which) {
+                         dialog.dismiss();
+                     }
+                 })
+                 .setTitle(R.string.enable_explore_by_touch_warning_title)
+                 .setMessage(mContext.getString(
+                         R.string.enable_explore_by_touch_warning_message, label))
+                 .create();
+             mEnableTouchExplorationDialog.getWindow().setType(
+                     WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
+             mEnableTouchExplorationDialog.getWindow().getAttributes().privateFlags
+                     |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
+             mEnableTouchExplorationDialog.setCanceledOnTouchOutside(true);
+             mEnableTouchExplorationDialog.show();
         }
     }
 
@@ -1203,12 +1207,15 @@
         populateInstalledAccessibilityServiceLocked(userState);
         populateEnabledAccessibilityServicesLocked(userState);
         populateTouchExplorationGrantedAccessibilityServicesLocked(userState);
+        populatedEnhancedWebAccessibilityEnabledChangedLocked(userState);
 
         handleTouchExplorationEnabledSettingChangedLocked(userState);
         handleDisplayMagnificationEnabledSettingChangedLocked(userState);
         handleAccessibilityEnabledSettingChangedLocked(userState);
+        handleTouchExplorationGrantedAccessibilityServicesChangedLocked(userState);
 
         performServiceManagementLocked(userState);
+
         scheduleUpdateInputFilter(userState);
         scheduleSendStateToClientsLocked(userState);
     }
@@ -1242,50 +1249,144 @@
 
     private void handleTouchExplorationGrantedAccessibilityServicesChangedLocked(
             UserState userState) {
+        Settings.Secure.putIntForUser(mContext.getContentResolver(),
+                Settings.Secure.TOUCH_EXPLORATION_ENABLED, 0, userState.mUserId);
         final int serviceCount = userState.mServices.size();
         for (int i = 0; i < serviceCount; i++) {
             Service service = userState.mServices.get(i);
-            if (service.mRequestTouchExplorationMode
-                    && userState.mTouchExplorationGrantedServices.contains(
-                            service.mComponentName)) {
-                tryEnableTouchExplorationLocked(service);
-                return;
-            }
-        }
-        if (userState.mIsTouchExplorationEnabled) {
-            Settings.Secure.putIntForUser(mContext.getContentResolver(),
-                    Settings.Secure.TOUCH_EXPLORATION_ENABLED, 0, userState.mUserId);
+            tryEnableTouchExplorationLocked(service);
         }
     }
 
-    private void tryEnableTouchExplorationLocked(final Service service) {
+    private void populatedEnhancedWebAccessibilityEnabledChangedLocked(UserState userState) {
+        userState.mIsEnhancedWebAccessibilityEnabled = Settings.Secure.getIntForUser(
+                mContext.getContentResolver(), Settings.Secure.ACCESSIBILITY_SCRIPT_INJECTION,
+                0, userState.mUserId) == 1;
+    }
+
+    private void tryEnableTouchExplorationLocked(Service service) {
+        if (!service.canReceiveEventsLocked() || !service.mRequestTouchExplorationMode) {
+            return;
+        }
         UserState userState = getUserStateLocked(service.mUserId);
-        if (!userState.mIsTouchExplorationEnabled && service.mRequestTouchExplorationMode
-                && service.canReceiveEvents()) {
-            final boolean canToggleTouchExploration =
-                    userState.mTouchExplorationGrantedServices.contains(service.mComponentName);
-            if (!service.mIsAutomation && !canToggleTouchExploration) {
-                showEnableTouchExplorationDialog(service);
+        if (userState.mIsTouchExplorationEnabled) {
+            return;
+        }
+        // UI test automation service can always enable it.
+        if (service.mIsAutomation) {
+            Settings.Secure.putIntForUser(mContext.getContentResolver(),
+                    Settings.Secure.TOUCH_EXPLORATION_ENABLED, 1, service.mUserId);
+            return;
+        }
+        if (service.mResolveInfo.serviceInfo.applicationInfo.targetSdkVersion
+                <= Build.VERSION_CODES.JELLY_BEAN_MR1) {
+            // Up to JB-MR1 we had a white list with services that can enable touch
+            // exploration. When a service is first started we show a dialog to the
+            // use to get a permission to white list the service.
+            if (!userState.mTouchExplorationGrantedServices.contains(service.mComponentName)) {
+                if (mEnableTouchExplorationDialog == null
+                        || (mEnableTouchExplorationDialog != null
+                            && !mEnableTouchExplorationDialog.isShowing())) {
+                    showEnableTouchExplorationDialog(service);
+                }
             } else {
                 Settings.Secure.putIntForUser(mContext.getContentResolver(),
-                        Settings.Secure.TOUCH_EXPLORATION_ENABLED, 1, userState.mUserId);
+                        Settings.Secure.TOUCH_EXPLORATION_ENABLED, 1, service.mUserId);
+            }
+        } else {
+            // Starting in JB-MR2 we request a permission to allow a service to enable
+            // touch exploration and do not care if the service is in the white list.
+            if (mContext.getPackageManager().checkPermission(
+                    android.Manifest.permission.CAN_REQUEST_TOUCH_EXPLORATION_MODE,
+                    service.mComponentName.getPackageName()) == PackageManager.PERMISSION_GRANTED) {
+                Settings.Secure.putIntForUser(mContext.getContentResolver(),
+                        Settings.Secure.TOUCH_EXPLORATION_ENABLED, 1, service.mUserId);
             }
         }
     }
 
     private void tryDisableTouchExplorationLocked(Service service) {
+        if (!service.mRequestTouchExplorationMode) {
+            return;
+        }
         UserState userState = getUserStateLocked(service.mUserId);
-        if (userState.mIsTouchExplorationEnabled) {
-            final int serviceCount = userState.mServices.size();
-            for (int i = 0; i < serviceCount; i++) {
-                Service other = userState.mServices.get(i);
-                if (other != service && other.mRequestTouchExplorationMode) {
-                    return;
+        if (!userState.mIsTouchExplorationEnabled) {
+            return;
+        }
+        final int serviceCount = userState.mServices.size();
+        for (int i = 0; i < serviceCount; i++) {
+            Service other = userState.mServices.get(i);
+            if (other != service) {
+                if (service.mResolveInfo.serviceInfo.applicationInfo.targetSdkVersion
+                        <= Build.VERSION_CODES.JELLY_BEAN_MR1) {
+                    // Up to JB-MR1 we had a white list with services that can enable touch
+                    // exploration. When a service is first started we show a dialog to the
+                    // use to get a permission to white list the service.
+                    if (other.mRequestTouchExplorationMode &&
+                            userState.mTouchExplorationGrantedServices.contains(
+                                    service.mComponentName)) {
+                        // A white-listed service wants touch exploration, do not disable.
+                        return;
+                    }
+                } else {
+                    // Starting in JB-MR2 we request a permission to allow a service to enable
+                    // touch exploration and do not care if the service is in the white list.
+                    if (other.mRequestTouchExplorationMode && (service.mIsAutomation
+                            || mContext.getPackageManager().checkPermission(
+                                    android.Manifest.permission.CAN_REQUEST_TOUCH_EXPLORATION_MODE,
+                                    service.mComponentName.getPackageName())
+                                    == PackageManager.PERMISSION_GRANTED)) {
+                        // A service with permission wants touch exploration, do not disable.
+                        return;
+                    }
                 }
             }
-            Settings.Secure.putIntForUser(mContext.getContentResolver(),
-                    Settings.Secure.TOUCH_EXPLORATION_ENABLED, 0, userState.mUserId);
         }
+        Settings.Secure.putIntForUser(mContext.getContentResolver(),
+                Settings.Secure.TOUCH_EXPLORATION_ENABLED, 0, userState.mUserId);
+    }
+
+    private void tryEnableEnhancedWebAccessibilityLocked(Service service) {
+        if (!service.canReceiveEventsLocked() || !service.mRequestEnhancedWebAccessibility ) {
+            return;
+        }
+        UserState userState = getUserStateLocked(service.mUserId);
+        if (userState.mIsEnhancedWebAccessibilityEnabled) {
+            return;
+        }
+        // Requested and can enabled, do it.
+        if (service.mRequestEnhancedWebAccessibility
+                && canEnabledEnhancedWebAccessibility(service)) {
+            Settings.Secure.putIntForUser(mContext.getContentResolver(),
+                    Settings.Secure.ACCESSIBILITY_SCRIPT_INJECTION, 1, userState.mUserId);
+        }
+    }
+
+    private void tryDisableEnhancedWebAccessibilityLocked(Service service) {
+        if (!service.mRequestEnhancedWebAccessibility) {
+            return;
+        }
+        UserState userState = getUserStateLocked(service.mUserId);
+        if (!userState.mIsEnhancedWebAccessibilityEnabled) {
+            return;
+        }
+        final int serviceCount = userState.mServices.size();
+        for (int i = 0; i < serviceCount; i++) {
+            Service other = userState.mServices.get(i);
+            if (other != service && other.mRequestEnhancedWebAccessibility
+                    && canEnabledEnhancedWebAccessibility(other)) {
+                // One service requests the feature, do not disable.
+                return;
+            }
+        }
+        Settings.Secure.putIntForUser(mContext.getContentResolver(),
+                Settings.Secure.ACCESSIBILITY_SCRIPT_INJECTION, 0, service.mUserId);
+    }
+
+    private boolean canEnabledEnhancedWebAccessibility(Service service) {
+        return (service.mIsAutomation || mContext.getPackageManager().checkPermission(
+                android.Manifest.permission.CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY,
+                service.mComponentName.getPackageName()) == PackageManager.PERMISSION_GRANTED);
     }
 
     @Override
@@ -1410,7 +1511,7 @@
                 } break;
                 case MSG_UPDATE_INPUT_FILTER: {
                     UserState userState = (UserState) msg.obj;
-                    updateInputFilter(userState);                        
+                    updateInputFilter(userState);
                 } break;
             }
         }
@@ -1494,6 +1595,8 @@
 
         boolean mRequestTouchExplorationMode;
 
+        boolean mRequestEnhancedWebAccessibility;
+
         int mFetchFlags;
 
         long mNotificationTimeout;
@@ -1547,9 +1650,6 @@
             mIsAutomation = isAutomation;
             if (!isAutomation) {
                 mCanRetrieveScreenContent = accessibilityServiceInfo.getCanRetrieveWindowContent();
-                mRequestTouchExplorationMode =
-                    (accessibilityServiceInfo.flags
-                            & AccessibilityServiceInfo.FLAG_REQUEST_TOUCH_EXPLORATION_MODE) != 0;
                 mIntent = new Intent().setComponent(mComponentName);
                 mIntent.putExtra(Intent.EXTRA_CLIENT_LABEL,
                         com.android.internal.R.string.accessibility_binding_label);
@@ -1582,18 +1682,28 @@
                     & AccessibilityServiceInfo.FLAG_REPORT_VIEW_IDS) != 0 ?
                             AccessibilityNodeInfo.FLAG_REPORT_VIEW_IDS : 0;
 
-            mRequestTouchExplorationMode = (info.flags
-                    & AccessibilityServiceInfo.FLAG_REQUEST_TOUCH_EXPLORATION_MODE) != 0;
+            if (mResolveInfo != null) {
+                mRequestTouchExplorationMode = (info.flags
+                            & AccessibilityServiceInfo.FLAG_REQUEST_TOUCH_EXPLORATION_MODE) != 0;
+                mRequestEnhancedWebAccessibility = (info.flags
+                           & AccessibilityServiceInfo.FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY) != 0;
+            }
 
             // If this service is up and running we may have to enable touch
-            // exploration, otherwise this will happen when the service connects.
+            // exploration or enhanced web accessibility, otherwise this will
+            // happen when the service connects.
             synchronized (mLock) {
-                if (canReceiveEvents()) {
+                if (canReceiveEventsLocked()) {
                     if (mRequestTouchExplorationMode) {
                         tryEnableTouchExplorationLocked(this);
                     } else {
                         tryDisableTouchExplorationLocked(this);
                     }
+                    if (mRequestEnhancedWebAccessibility) {
+                        tryEnableEnhancedWebAccessibilityLocked(this);
+                    } else {
+                        tryDisableEnhancedWebAccessibilityLocked(this);
+                    }
                 }
             }
         }
@@ -1630,7 +1740,7 @@
             return false;
         }
 
-        public boolean canReceiveEvents() {
+        public boolean canReceiveEventsLocked() {
             return (mEventTypes != 0 && mFeedbackType != 0 && mService != null);
         }
 
@@ -2260,7 +2370,11 @@
             | AccessibilityNodeInfo.ACTION_NEXT_HTML_ELEMENT
             | AccessibilityNodeInfo.ACTION_PREVIOUS_HTML_ELEMENT
             | AccessibilityNodeInfo.ACTION_SCROLL_FORWARD
-            | AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD;
+            | AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD
+            | AccessibilityNodeInfo.ACTION_COPY
+            | AccessibilityNodeInfo.ACTION_PASTE
+            | AccessibilityNodeInfo.ACTION_CUT
+            | AccessibilityNodeInfo.ACTION_SET_SELECTION;
 
         private static final int RETRIEVAL_ALLOWING_EVENT_TYPES =
             AccessibilityEvent.TYPE_VIEW_CLICKED
@@ -2497,6 +2611,7 @@
 
         public boolean mIsAccessibilityEnabled;
         public boolean mIsTouchExplorationEnabled;
+        public boolean mIsEnhancedWebAccessibilityEnabled;
         public boolean mIsDisplayMagnificationEnabled;
 
         public UserState(int userId) {
@@ -2508,15 +2623,17 @@
         public int mUserId = UserHandle.USER_NULL;
         public boolean mIsAccessibilityEnabled;
         public boolean mIsTouchExplorationEnabled;
+        public boolean mIsEnhancedWebAccessibilityEnabled;
         public boolean mIsDisplayMagnificationEnabled;
         public final Set<ComponentName> mEnabledServices = new HashSet<ComponentName>();
         public final Set<ComponentName> mTouchExplorationGrantedServices =
                 new HashSet<ComponentName>();
 
-        public void initialize(int userId, UserState userState) {
-            mUserId = userId;
+        public void initialize(UserState userState) {
+            mUserId = userState.mUserId;
             mIsAccessibilityEnabled = userState.mIsAccessibilityEnabled;
             mIsTouchExplorationEnabled = userState.mIsTouchExplorationEnabled;
+            mIsEnhancedWebAccessibilityEnabled = userState.mIsEnhancedWebAccessibilityEnabled;
             mIsDisplayMagnificationEnabled = userState.mIsDisplayMagnificationEnabled;
             mEnabledServices.clear();
             mEnabledServices.addAll(userState.mEnabledServices);
@@ -2527,6 +2644,7 @@
         public void applyTo(UserState userState) {
             userState.mIsAccessibilityEnabled = mIsAccessibilityEnabled;
             userState.mIsTouchExplorationEnabled = mIsTouchExplorationEnabled;
+            userState.mIsEnhancedWebAccessibilityEnabled = mIsEnhancedWebAccessibilityEnabled;
             userState.mIsDisplayMagnificationEnabled = mIsDisplayMagnificationEnabled;
             userState.mEnabledServices.clear();
             userState.mEnabledServices.addAll(mEnabledServices);
@@ -2538,6 +2656,7 @@
             mUserId = UserHandle.USER_NULL;
             mIsAccessibilityEnabled = false;
             mIsTouchExplorationEnabled = false;
+            mIsEnhancedWebAccessibilityEnabled = false;
             mIsDisplayMagnificationEnabled = false;
             mEnabledServices.clear();
             mTouchExplorationGrantedServices.clear();
@@ -2561,6 +2680,9 @@
         private final Uri mTouchExplorationGrantedAccessibilityServicesUri = Settings.Secure
                 .getUriFor(Settings.Secure.TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES);
 
+        private final Uri mAccessibilityScriptInjectionUri = Settings.Secure
+                .getUriFor(Settings.Secure.ACCESSIBILITY_SCRIPT_INJECTION);
+
         public AccessibilityContentObserver(Handler handler) {
             super(handler);
         }
@@ -2577,6 +2699,8 @@
             contentResolver.registerContentObserver(
                     mTouchExplorationGrantedAccessibilityServicesUri,
                     false, this, UserHandle.USER_ALL);
+            contentResolver.registerContentObserver(mAccessibilityScriptInjectionUri,
+                    false, this, UserHandle.USER_ALL);
         }
 
         @Override
@@ -2630,6 +2754,14 @@
                         handleTouchExplorationGrantedAccessibilityServicesChangedLocked(userState);
                     }
                 }
+            } else if (mAccessibilityScriptInjectionUri.equals(uri)) {
+                synchronized (mLock) {
+                    // We will update when the automation service dies.
+                    if (mUiAutomationService == null) {
+                        UserState userState = getCurrentUserStateLocked();
+                        populatedEnhancedWebAccessibilityEnabledChangedLocked(userState);
+                    }
+                }
             }
         }
     }
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index ca60a93..252cae2 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -624,7 +624,6 @@
     /**
      * Thread-local storage used to carry caller permissions over through
      * indirect content-provider access.
-     * @see #ActivityManagerService.openContentUri()
      */
     private class Identity {
         public int pid;
@@ -831,18 +830,6 @@
             = new ArrayList<ProcessChangeItem>();
 
     /**
-     * Callback of last caller to {@link #requestPss}.
-     */
-    Runnable mRequestPssCallback;
-
-    /**
-     * Remaining processes for which we are waiting results from the last
-     * call to {@link #requestPss}.
-     */
-    final ArrayList<ProcessRecord> mRequestPssList
-            = new ArrayList<ProcessRecord>();
-    
-    /**
      * Runtime statistics collection thread.  This object's lock is used to
      * protect all related state.
      */
@@ -1231,7 +1218,7 @@
                     
                     try {
                         int[] outId = new int[1];
-                        inm.enqueueNotificationWithTag("android", null,
+                        inm.enqueueNotificationWithTag("android", "android", null,
                                 R.string.heavy_weight_notification,
                                 notification, outId, root.userId);
                     } catch (RuntimeException e) {
@@ -2309,7 +2296,7 @@
             if (app == null || app.instrumentationClass == null) {
                 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
                 mMainStack.startActivityLocked(null, intent, null, aInfo,
-                        null, null, 0, 0, 0, 0, null, false, null);
+                        null, null, 0, 0, 0, null, 0, null, false, null);
             }
         }
 
@@ -2387,7 +2374,7 @@
                     intent.setComponent(new ComponentName(
                             ri.activityInfo.packageName, ri.activityInfo.name));
                     mMainStack.startActivityLocked(null, intent, null, ri.activityInfo,
-                            null, null, 0, 0, 0, 0, null, false, null);
+                            null, null, 0, 0, 0, null, 0, null, false, null);
                 }
             }
         }
@@ -2522,27 +2509,28 @@
         mPendingActivityLaunches.clear();
     }
 
-    public final int startActivity(IApplicationThread caller,
+    public final int startActivity(IApplicationThread caller, String callingPackage,
             Intent intent, String resolvedType, IBinder resultTo,
             String resultWho, int requestCode, int startFlags,
             String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
-        return startActivityAsUser(caller, intent, resolvedType, resultTo, resultWho, requestCode,
+        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
+                resultWho, requestCode,
                 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
     }
 
-    public final int startActivityAsUser(IApplicationThread caller,
+    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
             Intent intent, String resolvedType, IBinder resultTo,
             String resultWho, int requestCode, int startFlags,
             String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
         enforceNotIsolatedCaller("startActivity");
         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
                 false, true, "startActivity", null);
-        return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
+        return mMainStack.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
                 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
                 null, null, options, userId);
     }
 
-    public final WaitResult startActivityAndWait(IApplicationThread caller,
+    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
             Intent intent, String resolvedType, IBinder resultTo,
             String resultWho, int requestCode, int startFlags, String profileFile,
             ParcelFileDescriptor profileFd, Bundle options, int userId) {
@@ -2550,20 +2538,20 @@
         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
                 false, true, "startActivityAndWait", null);
         WaitResult res = new WaitResult();
-        mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
+        mMainStack.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
                 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
                 res, null, options, UserHandle.getCallingUserId());
         return res;
     }
 
-    public final int startActivityWithConfig(IApplicationThread caller,
+    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
             Intent intent, String resolvedType, IBinder resultTo,
             String resultWho, int requestCode, int startFlags, Configuration config,
             Bundle options, int userId) {
         enforceNotIsolatedCaller("startActivityWithConfig");
         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
                 false, true, "startActivityWithConfig", null);
-        int ret = mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
+        int ret = mMainStack.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
                 resultTo, resultWho, requestCode, startFlags,
                 null, null, null, config, options, userId);
         return ret;
@@ -2684,7 +2672,7 @@
             final long origId = Binder.clearCallingIdentity();
             int res = mMainStack.startActivityLocked(r.app.thread, intent,
                     r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null,
-                    resultWho, requestCode, -1, r.launchedFromUid, 0,
+                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
                     options, false, null);
             Binder.restoreCallingIdentity(origId);
 
@@ -2696,38 +2684,38 @@
         }
     }
 
-    final int startActivityInPackage(int uid,
+    final int startActivityInPackage(int uid, String callingPackage,
             Intent intent, String resolvedType, IBinder resultTo,
             String resultWho, int requestCode, int startFlags, Bundle options, int userId) {
 
         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
                 false, true, "startActivityInPackage", null);
 
-        int ret = mMainStack.startActivityMayWait(null, uid, intent, resolvedType,
+        int ret = mMainStack.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
                 resultTo, resultWho, requestCode, startFlags,
                 null, null, null, null, options, userId);
         return ret;
     }
 
-    public final int startActivities(IApplicationThread caller,
+    public final int startActivities(IApplicationThread caller, String callingPackage,
             Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
             int userId) {
         enforceNotIsolatedCaller("startActivities");
         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
                 false, true, "startActivity", null);
-        int ret = mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo,
-                options, userId);
+        int ret = mMainStack.startActivities(caller, -1, callingPackage, intents,
+                resolvedTypes, resultTo, options, userId);
         return ret;
     }
 
-    final int startActivitiesInPackage(int uid,
+    final int startActivitiesInPackage(int uid, String callingPackage,
             Intent[] intents, String[] resolvedTypes, IBinder resultTo,
             Bundle options, int userId) {
 
         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
                 false, true, "startActivityInPackage", null);
-        int ret = mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo,
-                options, userId);
+        int ret = mMainStack.startActivities(null, uid, callingPackage, intents, resolvedTypes,
+                resultTo, options, userId);
         return ret;
     }
 
@@ -6743,7 +6731,6 @@
 
     /**
      * Drop a content provider from a ProcessRecord's bookkeeping
-     * @param cpr
      */
     public void removeContentProvider(IBinder connection, boolean stable) {
         enforceNotIsolatedCaller("removeContentProvider");
@@ -12665,7 +12652,8 @@
                                 destIntent.getComponent(), 0, srec.userId);
                         int res = mMainStack.startActivityLocked(srec.app.thread, destIntent,
                                 null, aInfo, parent.appToken, null,
-                                0, -1, parent.launchedFromUid, 0, null, true, null);
+                                0, -1, parent.launchedFromUid, parent.launchedFromPackage,
+                                0, null, true, null);
                         foundParentInTask = res == ActivityManager.START_SUCCESS;
                     } catch (RemoteException e) {
                         foundParentInTask = false;
@@ -12687,6 +12675,14 @@
         return srec.launchedFromUid;
     }
 
+    public String getLaunchedFromPackage(IBinder activityToken) {
+        ActivityRecord srec = ActivityRecord.forToken(activityToken);
+        if (srec == null) {
+            return null;
+        }
+        return srec.launchedFromPackage;
+    }
+
     // =========================================================
     // LIFETIME MANAGEMENT
     // =========================================================
diff --git a/services/java/com/android/server/am/ActivityRecord.java b/services/java/com/android/server/am/ActivityRecord.java
index 3af2287..ba2e47a 100644
--- a/services/java/com/android/server/am/ActivityRecord.java
+++ b/services/java/com/android/server/am/ActivityRecord.java
@@ -59,6 +59,7 @@
     final IApplicationToken.Stub appToken; // window manager token
     final ActivityInfo info; // all about me
     final int launchedFromUid; // always the uid who started the activity.
+    final String launchedFromPackage; // always the package who started the activity.
     final int userId;          // Which user is this running for?
     final Intent intent;    // the original intent that generated us
     final ComponentName realActivity;  // the intent component, or target of an alias.
@@ -135,6 +136,7 @@
         pw.print(prefix); pw.print("packageName="); pw.print(packageName);
                 pw.print(" processName="); pw.println(processName);
         pw.print(prefix); pw.print("launchedFromUid="); pw.print(launchedFromUid);
+                pw.print(" launchedFromPackage="); pw.println(launchedFromPackage);
                 pw.print(" userId="); pw.println(userId);
         pw.print(prefix); pw.print("app="); pw.println(app);
         pw.print(prefix); pw.println(intent.toInsecureStringWithClip());
@@ -325,7 +327,7 @@
     }
 
     ActivityRecord(ActivityManagerService _service, ActivityStack _stack, ProcessRecord _caller,
-            int _launchedFromUid, Intent _intent, String _resolvedType,
+            int _launchedFromUid, String _launchedFromPackage, Intent _intent, String _resolvedType,
             ActivityInfo aInfo, Configuration _configuration,
             ActivityRecord _resultTo, String _resultWho, int _reqCode,
             boolean _componentSpecified) {
@@ -334,6 +336,7 @@
         appToken = new Token(this);
         info = aInfo;
         launchedFromUid = _launchedFromUid;
+        launchedFromPackage = _launchedFromPackage;
         userId = UserHandle.getUserId(aInfo.applicationInfo.uid);
         intent = _intent;
         shortComponentName = _intent.getComponent().flattenToShortString();
diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java
index de9dda4..526b24f 100644
--- a/services/java/com/android/server/am/ActivityStack.java
+++ b/services/java/com/android/server/am/ActivityStack.java
@@ -2483,7 +2483,7 @@
     final int startActivityLocked(IApplicationThread caller,
             Intent intent, String resolvedType, ActivityInfo aInfo, IBinder resultTo,
             String resultWho, int requestCode,
-            int callingPid, int callingUid, int startFlags, Bundle options,
+            int callingPid, int callingUid, String callingPackage, int startFlags, Bundle options,
             boolean componentSpecified, ActivityRecord[] outActivity) {
 
         int err = ActivityManager.START_SUCCESS;
@@ -2620,7 +2620,7 @@
             }
         }
 
-        ActivityRecord r = new ActivityRecord(mService, this, callerApp, callingUid,
+        ActivityRecord r = new ActivityRecord(mService, this, callerApp, callingUid, callingPackage,
                 intent, resolvedType, aInfo, mService.mConfiguration,
                 resultRecord, resultWho, requestCode, componentSpecified);
         if (outActivity != null) {
@@ -3095,7 +3095,7 @@
     }
 
     final int startActivityMayWait(IApplicationThread caller, int callingUid,
-            Intent intent, String resolvedType, IBinder resultTo,
+            String callingPackage, Intent intent, String resolvedType, IBinder resultTo,
             String resultWho, int requestCode, int startFlags, String profileFile,
             ParcelFileDescriptor profileFd, WaitResult outResult, Configuration config,
             Bundle options, int userId) {
@@ -3202,7 +3202,7 @@
             
             int res = startActivityLocked(caller, intent, resolvedType,
                     aInfo, resultTo, resultWho, requestCode, callingPid, callingUid,
-                    startFlags, options, componentSpecified, null);
+                    callingPackage, startFlags, options, componentSpecified, null);
             
             if (mConfigWillChange && mMainStack) {
                 // If the caller also wants to switch to a new configuration,
@@ -3253,7 +3253,7 @@
         }
     }
     
-    final int startActivities(IApplicationThread caller, int callingUid,
+    final int startActivities(IApplicationThread caller, int callingUid, String callingPackage,
             Intent[] intents, String[] resolvedTypes, IBinder resultTo,
             Bundle options, int userId) {
         if (intents == null) {
@@ -3316,7 +3316,7 @@
                         theseOptions = null;
                     }
                     int res = startActivityLocked(caller, intent, resolvedTypes[i],
-                            aInfo, resultTo, null, -1, callingPid, callingUid,
+                            aInfo, resultTo, null, -1, callingPid, callingUid, callingPackage,
                             0, theseOptions, componentSpecified, outActivity);
                     if (res < 0) {
                         return res;
diff --git a/services/java/com/android/server/am/PendingIntentRecord.java b/services/java/com/android/server/am/PendingIntentRecord.java
index 8ee303f..8ab71dd 100644
--- a/services/java/com/android/server/am/PendingIntentRecord.java
+++ b/services/java/com/android/server/am/PendingIntentRecord.java
@@ -246,11 +246,12 @@
                                 }
                                 allIntents[allIntents.length-1] = finalIntent;
                                 allResolvedTypes[allResolvedTypes.length-1] = resolvedType;
-                                owner.startActivitiesInPackage(uid, allIntents,
+                                owner.startActivitiesInPackage(uid, key.packageName, allIntents,
                                         allResolvedTypes, resultTo, options, userId);
                             } else {
-                                owner.startActivityInPackage(uid, finalIntent, resolvedType,
-                                        resultTo, resultWho, requestCode, 0, options, userId);
+                                owner.startActivityInPackage(uid, key.packageName, finalIntent,
+                                        resolvedType, resultTo, resultWho, requestCode, 0,
+                                        options, userId);
                             }
                         } catch (RuntimeException e) {
                             Slog.w(ActivityManagerService.TAG,
diff --git a/services/java/com/android/server/am/ServiceRecord.java b/services/java/com/android/server/am/ServiceRecord.java
index 84e824a..b06c60a 100644
--- a/services/java/com/android/server/am/ServiceRecord.java
+++ b/services/java/com/android/server/am/ServiceRecord.java
@@ -369,8 +369,9 @@
                     }
                     try {
                         int[] outId = new int[1];
-                        nm.enqueueNotificationInternal(localPackageName, appUid, appPid,
-                                null, localForegroundId, localForegroundNoti, outId, userId);
+                        nm.enqueueNotificationInternal(localPackageName, localPackageName,
+                                appUid, appPid, null, localForegroundId, localForegroundNoti,
+                                outId, userId);
                     } catch (RuntimeException e) {
                         Slog.w(ActivityManagerService.TAG,
                                 "Error showing notification for service", e);
diff --git a/services/java/com/android/server/net/NetworkPolicyManagerService.java b/services/java/com/android/server/net/NetworkPolicyManagerService.java
index cbd2a0f..3ae652a 100644
--- a/services/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -828,7 +828,7 @@
             final String packageName = mContext.getPackageName();
             final int[] idReceived = new int[1];
             mNotifManager.enqueueNotificationWithTag(
-                    packageName, tag, 0x0, builder.getNotification(), idReceived,
+                    packageName, packageName, tag, 0x0, builder.getNotification(), idReceived,
                     UserHandle.USER_OWNER);
             mActiveNotifs.add(tag);
         } catch (RemoteException e) {
@@ -863,7 +863,7 @@
         try {
             final String packageName = mContext.getPackageName();
             final int[] idReceived = new int[1];
-            mNotifManager.enqueueNotificationWithTag(packageName, tag,
+            mNotifManager.enqueueNotificationWithTag(packageName, packageName, tag,
                     0x0, builder.getNotification(), idReceived, UserHandle.USER_OWNER);
             mActiveNotifs.add(tag);
         } catch (RemoteException e) {
diff --git a/services/java/com/android/server/updates/ConfigUpdateInstallReceiver.java b/services/java/com/android/server/updates/ConfigUpdateInstallReceiver.java
index 4480151..b065310 100644
--- a/services/java/com/android/server/updates/ConfigUpdateInstallReceiver.java
+++ b/services/java/com/android/server/updates/ConfigUpdateInstallReceiver.java
@@ -77,7 +77,7 @@
                     // get the certificate from Settings.Secure
                     X509Certificate cert = getCert(context.getContentResolver());
                     // get the content path from the extras
-                    String altContent = getAltContent(intent);
+                    byte[] altContent = getAltContent(intent);
                     // get the version from the extras
                     int altVersion = getVersionFromIntent(intent);
                     // get the previous value from the extras
@@ -172,28 +172,26 @@
         }
     }
 
-    private String getAltContent(Intent i) throws IOException {
-        String contents = IoUtils.readFileAsString(getContentFromIntent(i));
-        return contents.trim();
+    private byte[] getAltContent(Intent i) throws IOException {
+        return IoUtils.readFileAsByteArray(getContentFromIntent(i));
     }
 
-    private String getCurrentContent() {
+    private byte[] getCurrentContent() {
         try {
-            return IoUtils.readFileAsString(updateContent.getCanonicalPath()).trim();
+            return IoUtils.readFileAsByteArray(updateContent.getCanonicalPath());
         } catch (IOException e) {
             Slog.i(TAG, "Failed to read current content, assuming first update!");
             return null;
         }
     }
 
-    private static String getCurrentHash(String content) {
+    private static String getCurrentHash(byte[] content) {
         if (content == null) {
             return "0";
         }
         try {
             MessageDigest dgst = MessageDigest.getInstance("SHA512");
-            byte[] encoded = content.getBytes();
-            byte[] fingerprint = dgst.digest(encoded);
+            byte[] fingerprint = dgst.digest(content);
             return IntegralToString.bytesToHexString(fingerprint, false);
         } catch (NoSuchAlgorithmException e) {
             throw new AssertionError(e);
@@ -213,17 +211,17 @@
         return current.equals(required);
     }
 
-    private boolean verifySignature(String content, int version, String requiredPrevious,
+    private boolean verifySignature(byte[] content, int version, String requiredPrevious,
                                    String signature, X509Certificate cert) throws Exception {
         Signature signer = Signature.getInstance("SHA512withRSA");
         signer.initVerify(cert);
-        signer.update(content.getBytes());
+        signer.update(content);
         signer.update(Long.toString(version).getBytes());
         signer.update(requiredPrevious.getBytes());
         return signer.verify(Base64.decode(signature.getBytes(), Base64.DEFAULT));
     }
 
-    private void writeUpdate(File dir, File file, String content) throws IOException {
+    private void writeUpdate(File dir, File file, byte[] content) throws IOException {
         FileOutputStream out = null;
         File tmp = null;
         try {
@@ -240,7 +238,7 @@
             tmp.setReadable(true, false);
             // write to it
             out = new FileOutputStream(tmp);
-            out.write(content.getBytes());
+            out.write(content);
             // sync to disk
             out.getFD().sync();
             // atomic rename
@@ -255,8 +253,8 @@
         }
     }
 
-    private void install(String content, int version) throws IOException {
+    protected void install(byte[] content, int version) throws IOException {
         writeUpdate(updateDir, updateContent, content);
-        writeUpdate(updateDir, updateVersion, Long.toString(version));
+        writeUpdate(updateDir, updateVersion, Long.toString(version).getBytes());
     }
 }
diff --git a/services/java/com/android/server/updates/TZInfoInstallReceiver.java b/services/java/com/android/server/updates/TZInfoInstallReceiver.java
new file mode 100644
index 0000000..83adbdb
--- /dev/null
+++ b/services/java/com/android/server/updates/TZInfoInstallReceiver.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2013 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.updates;
+
+import android.util.Base64;
+import android.util.Slog;
+
+import java.io.IOException;
+
+public class TZInfoInstallReceiver extends ConfigUpdateInstallReceiver {
+
+    public TZInfoInstallReceiver() {
+        super("/data/misc/zoneinfo/", "tzdata", "metadata/", "version");
+    }
+
+    @Override
+    protected void install(byte[] encodedContent, int version) throws IOException {
+        super.install(Base64.decode(encodedContent, Base64.DEFAULT), version);
+    }
+}
diff --git a/services/java/com/android/server/usb/UsbDebuggingManager.java b/services/java/com/android/server/usb/UsbDebuggingManager.java
index 1bb3a2c..93d3114 100644
--- a/services/java/com/android/server/usb/UsbDebuggingManager.java
+++ b/services/java/com/android/server/usb/UsbDebuggingManager.java
@@ -151,6 +151,7 @@
         private static final int MESSAGE_ADB_ALLOW = 3;
         private static final int MESSAGE_ADB_DENY = 4;
         private static final int MESSAGE_ADB_CONFIRM = 5;
+        private static final int MESSAGE_ADB_CLEAR = 6;
 
         public UsbDebuggingHandler(Looper looper) {
             super(looper);
@@ -214,6 +215,10 @@
                     showConfirmationDialog(key, mFingerprints);
                     break;
                 }
+
+                case MESSAGE_ADB_CLEAR:
+                    deleteKeyFile();
+                    break;
             }
         }
     }
@@ -257,17 +262,25 @@
         }
     }
 
-    private void writeKey(String key) {
+    private File getUserKeyFile() {
         File dataDir = Environment.getDataDirectory();
         File adbDir = new File(dataDir, ADB_DIRECTORY);
 
         if (!adbDir.exists()) {
             Slog.e(TAG, "ADB data directory does not exist");
-            return;
+            return null;
         }
 
+        return new File(adbDir, ADB_KEYS_FILE);
+    }
+
+    private void writeKey(String key) {
         try {
-            File keyFile = new File(adbDir, ADB_KEYS_FILE);
+            File keyFile = getUserKeyFile();
+
+            if (keyFile == null) {
+                return;
+            }
 
             if (!keyFile.exists()) {
                 keyFile.createNewFile();
@@ -286,6 +299,12 @@
         }
     }
 
+    private void deleteKeyFile() {
+        File keyFile = getUserKeyFile();
+        if (keyFile != null) {
+            keyFile.delete();
+        }
+    }
 
     public void setAdbEnabled(boolean enabled) {
         mHandler.sendEmptyMessage(enabled ? UsbDebuggingHandler.MESSAGE_ADB_ENABLED
@@ -303,6 +322,9 @@
         mHandler.sendEmptyMessage(UsbDebuggingHandler.MESSAGE_ADB_DENY);
     }
 
+    public void clearUsbDebuggingKeys() {
+        mHandler.sendEmptyMessage(UsbDebuggingHandler.MESSAGE_ADB_CLEAR);
+    }
 
     public void dump(FileDescriptor fd, PrintWriter pw) {
         pw.println("  USB Debugging State:");
diff --git a/services/java/com/android/server/usb/UsbDeviceManager.java b/services/java/com/android/server/usb/UsbDeviceManager.java
index 8fa6de5..87aa8cce 100644
--- a/services/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/java/com/android/server/usb/UsbDeviceManager.java
@@ -864,6 +864,15 @@
         }
     }
 
+    public void clearUsbDebuggingKeys() {
+        if (mDebuggingManager != null) {
+            mDebuggingManager.clearUsbDebuggingKeys();
+        } else {
+            throw new RuntimeException("Cannot clear Usb Debugging keys, "
+                        + "UsbDebuggingManager not enabled");
+        }
+    }
+
     public void dump(FileDescriptor fd, PrintWriter pw) {
         if (mHandler != null) {
             mHandler.dump(fd, pw);
diff --git a/services/java/com/android/server/usb/UsbService.java b/services/java/com/android/server/usb/UsbService.java
index 3918d15..36669b1 100644
--- a/services/java/com/android/server/usb/UsbService.java
+++ b/services/java/com/android/server/usb/UsbService.java
@@ -255,6 +255,12 @@
     }
 
     @Override
+    public void clearUsbDebuggingKeys() {
+        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
+        mDeviceManager.clearUsbDebuggingKeys();
+    }
+
+    @Override
     public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
         final IndentingPrintWriter pw = new IndentingPrintWriter(writer, "  ");
diff --git a/services/java/com/android/server/wm/WindowState.java b/services/java/com/android/server/wm/WindowState.java
index cb11be3..a335958 100644
--- a/services/java/com/android/server/wm/WindowState.java
+++ b/services/java/com/android/server/wm/WindowState.java
@@ -382,6 +382,16 @@
     }
 
     @Override
+    public int getOwningUid() {
+        return mSession.mUid;
+    }
+
+    @Override
+    public String getOwningPackage() {
+        return mAttrs.packageName;
+    }
+
+    @Override
     public void computeFrameLw(Rect pf, Rect df, Rect cf, Rect vf) {
         mHaveFrame = true;
 
diff --git a/services/jni/com_android_server_BatteryService.cpp b/services/jni/com_android_server_BatteryService.cpp
index e6133af..485c289 100644
--- a/services/jni/com_android_server_BatteryService.cpp
+++ b/services/jni/com_android_server_BatteryService.cpp
@@ -33,6 +33,8 @@
 #include <unistd.h>
 #include <dirent.h>
 #include <linux/ioctl.h>
+#include <utils/Vector.h>
+#include <utils/String8.h>
 
 namespace android {
 
@@ -70,21 +72,28 @@
 static BatteryManagerConstants gConstants;
 
 struct PowerSupplyPaths {
-    char* acOnlinePath;
-    char* usbOnlinePath;
-    char* wirelessOnlinePath;
-    char* batteryStatusPath;
-    char* batteryHealthPath;
-    char* batteryPresentPath;
-    char* batteryCapacityPath;
-    char* batteryVoltagePath;
-    char* batteryTemperaturePath;
-    char* batteryTechnologyPath;
+    String8 batteryStatusPath;
+    String8 batteryHealthPath;
+    String8 batteryPresentPath;
+    String8 batteryCapacityPath;
+    String8 batteryVoltagePath;
+    String8 batteryTemperaturePath;
+    String8 batteryTechnologyPath;
 };
 static PowerSupplyPaths gPaths;
 
+static Vector<String8> gChargerNames;
+
 static int gVoltageDivisor = 1;
 
+enum PowerSupplyType {
+     ANDROID_POWER_SUPPLY_TYPE_UNKNOWN = 0,
+     ANDROID_POWER_SUPPLY_TYPE_AC,
+     ANDROID_POWER_SUPPLY_TYPE_USB,
+     ANDROID_POWER_SUPPLY_TYPE_WIRELESS,
+     ANDROID_POWER_SUPPLY_TYPE_BATTERY
+};
+
 static jint getBatteryStatus(const char* status)
 {
     switch (status[0]) {
@@ -133,13 +142,13 @@
     }
 }
 
-static int readFromFile(const char* path, char* buf, size_t size)
+static int readFromFile(const String8& path, char* buf, size_t size)
 {
     if (!path)
         return -1;
-    int fd = open(path, O_RDONLY, 0);
+    int fd = open(path.string(), O_RDONLY, 0);
     if (fd == -1) {
-        ALOGE("Could not open '%s'", path);
+        ALOGE("Could not open '%s'", path.string());
         return -1;
     }
     
@@ -156,7 +165,7 @@
     return count;
 }
 
-static void setBooleanField(JNIEnv* env, jobject obj, const char* path, jfieldID fieldID)
+static void setBooleanField(JNIEnv* env, jobject obj, const String8& path, jfieldID fieldID)
 {
     const int SIZE = 16;
     char buf[SIZE];
@@ -170,7 +179,7 @@
     env->SetBooleanField(obj, fieldID, value);
 }
 
-static void setIntField(JNIEnv* env, jobject obj, const char* path, jfieldID fieldID)
+static void setIntField(JNIEnv* env, jobject obj, const String8& path, jfieldID fieldID)
 {
     const int SIZE = 128;
     char buf[SIZE];
@@ -182,7 +191,7 @@
     env->SetIntField(obj, fieldID, value);
 }
 
-static void setVoltageField(JNIEnv* env, jobject obj, const char* path, jfieldID fieldID)
+static void setVoltageField(JNIEnv* env, jobject obj, const String8& path, jfieldID fieldID)
 {
     const int SIZE = 128;
     char buf[SIZE];
@@ -195,12 +204,30 @@
     env->SetIntField(obj, fieldID, value);
 }
 
+static PowerSupplyType readPowerSupplyType(const String8& path) {
+    const int SIZE = 128;
+    char buf[SIZE];
+    int length = readFromFile(path, buf, SIZE);
+
+    if (length <= 0)
+        return ANDROID_POWER_SUPPLY_TYPE_UNKNOWN;
+    if (buf[length - 1] == '\n')
+        buf[length - 1] = 0;
+    if (strcmp(buf, "Battery") == 0)
+        return ANDROID_POWER_SUPPLY_TYPE_BATTERY;
+    else if (strcmp(buf, "Mains") == 0 || strcmp(buf, "USB_DCP") == 0 ||
+             strcmp(buf, "USB_CDP") == 0 || strcmp(buf, "USB_ACA") == 0)
+        return ANDROID_POWER_SUPPLY_TYPE_AC;
+    else if (strcmp(buf, "USB") == 0)
+        return ANDROID_POWER_SUPPLY_TYPE_USB;
+    else if (strcmp(buf, "Wireless") == 0)
+        return ANDROID_POWER_SUPPLY_TYPE_WIRELESS;
+    else
+        return ANDROID_POWER_SUPPLY_TYPE_UNKNOWN;
+}
 
 static void android_server_BatteryService_update(JNIEnv* env, jobject obj)
 {
-    setBooleanField(env, obj, gPaths.acOnlinePath, gFieldIds.mAcOnline);
-    setBooleanField(env, obj, gPaths.usbOnlinePath, gFieldIds.mUsbOnline);
-    setBooleanField(env, obj, gPaths.wirelessOnlinePath, gFieldIds.mWirelessOnline);
     setBooleanField(env, obj, gPaths.batteryPresentPath, gFieldIds.mBatteryPresent);
     
     setIntField(env, obj, gPaths.batteryCapacityPath, gFieldIds.mBatteryLevel);
@@ -221,16 +248,54 @@
 
     if (readFromFile(gPaths.batteryTechnologyPath, buf, SIZE) > 0)
         env->SetObjectField(obj, gFieldIds.mBatteryTechnology, env->NewStringUTF(buf));
+
+    unsigned int i;
+    String8 path;
+    jboolean acOnline = false;
+    jboolean usbOnline = false;
+    jboolean wirelessOnline = false;
+
+    for (i = 0; i < gChargerNames.size(); i++) {
+        path.clear();
+        path.appendFormat("%s/%s/online", POWER_SUPPLY_PATH,
+                          gChargerNames[i].string());
+
+        if (readFromFile(path, buf, SIZE) > 0) {
+            if (buf[0] != '0') {
+                path.clear();
+                path.appendFormat("%s/%s/type", POWER_SUPPLY_PATH,
+                                  gChargerNames[i].string());
+                switch(readPowerSupplyType(path)) {
+                case ANDROID_POWER_SUPPLY_TYPE_AC:
+                    acOnline = true;
+                    break;
+                case ANDROID_POWER_SUPPLY_TYPE_USB:
+                    usbOnline = true;
+                    break;
+                case ANDROID_POWER_SUPPLY_TYPE_WIRELESS:
+                    wirelessOnline = true;
+                    break;
+                default:
+                    ALOGW("%s: Unknown power supply type",
+                          gChargerNames[i].string());
+                }
+            }
+        }
+    }
+
+    env->SetBooleanField(obj, gFieldIds.mAcOnline, acOnline);
+    env->SetBooleanField(obj, gFieldIds.mUsbOnline, usbOnline);
+    env->SetBooleanField(obj, gFieldIds.mWirelessOnline, wirelessOnline);
 }
 
 static JNINativeMethod sMethods[] = {
      /* name, signature, funcPtr */
-	{"native_update", "()V", (void*)android_server_BatteryService_update},
+        {"native_update", "()V", (void*)android_server_BatteryService_update},
 };
 
 int register_android_server_BatteryService(JNIEnv* env)
 {
-    char    path[PATH_MAX];
+    String8 path;
     struct dirent* entry;
 
     DIR* dir = opendir(POWER_SUPPLY_PATH);
@@ -247,76 +312,72 @@
 
             char buf[20];
             // Look for "type" file in each subdirectory
-            snprintf(path, sizeof(path), "%s/%s/type", POWER_SUPPLY_PATH, name);
-            int length = readFromFile(path, buf, sizeof(buf));
-            if (length > 0) {
-                if (buf[length - 1] == '\n')
-                    buf[length - 1] = 0;
+            path.clear();
+            path.appendFormat("%s/%s/type", POWER_SUPPLY_PATH, name);
+            switch(readPowerSupplyType(path)) {
+            case ANDROID_POWER_SUPPLY_TYPE_AC:
+            case ANDROID_POWER_SUPPLY_TYPE_USB:
+            case ANDROID_POWER_SUPPLY_TYPE_WIRELESS:
+                path.clear();
+                path.appendFormat("%s/%s/online", POWER_SUPPLY_PATH, name);
+                if (access(path.string(), R_OK) == 0)
+                    gChargerNames.add(String8(name));
+                break;
 
-                if (strcmp(buf, "Mains") == 0) {
-                    snprintf(path, sizeof(path), "%s/%s/online", POWER_SUPPLY_PATH, name);
-                    if (access(path, R_OK) == 0)
-                        gPaths.acOnlinePath = strdup(path);
-                }
-                else if (strcmp(buf, "USB") == 0) {
-                    snprintf(path, sizeof(path), "%s/%s/online", POWER_SUPPLY_PATH, name);
-                    if (access(path, R_OK) == 0)
-                        gPaths.usbOnlinePath = strdup(path);
-                }
-                else if (strcmp(buf, "Wireless") == 0) {
-                    snprintf(path, sizeof(path), "%s/%s/online", POWER_SUPPLY_PATH, name);
-                    if (access(path, R_OK) == 0)
-                        gPaths.wirelessOnlinePath = strdup(path);
-                }
-                else if (strcmp(buf, "Battery") == 0) {
-                    snprintf(path, sizeof(path), "%s/%s/status", POWER_SUPPLY_PATH, name);
-                    if (access(path, R_OK) == 0)
-                        gPaths.batteryStatusPath = strdup(path);
-                    snprintf(path, sizeof(path), "%s/%s/health", POWER_SUPPLY_PATH, name);
-                    if (access(path, R_OK) == 0)
-                        gPaths.batteryHealthPath = strdup(path);
-                    snprintf(path, sizeof(path), "%s/%s/present", POWER_SUPPLY_PATH, name);
-                    if (access(path, R_OK) == 0)
-                        gPaths.batteryPresentPath = strdup(path);
-                    snprintf(path, sizeof(path), "%s/%s/capacity", POWER_SUPPLY_PATH, name);
-                    if (access(path, R_OK) == 0)
-                        gPaths.batteryCapacityPath = strdup(path);
+            case ANDROID_POWER_SUPPLY_TYPE_BATTERY:
+                path.clear();
+                path.appendFormat("%s/%s/status", POWER_SUPPLY_PATH, name);
+                if (access(path, R_OK) == 0)
+                    gPaths.batteryStatusPath = path;
+                path.clear();
+                path.appendFormat("%s/%s/health", POWER_SUPPLY_PATH, name);
+                if (access(path, R_OK) == 0)
+                    gPaths.batteryHealthPath = path;
+                path.clear();
+                path.appendFormat("%s/%s/present", POWER_SUPPLY_PATH, name);
+                if (access(path, R_OK) == 0)
+                    gPaths.batteryPresentPath = path;
+                path.clear();
+                path.appendFormat("%s/%s/capacity", POWER_SUPPLY_PATH, name);
+                if (access(path, R_OK) == 0)
+                    gPaths.batteryCapacityPath = path;
 
-                    snprintf(path, sizeof(path), "%s/%s/voltage_now", POWER_SUPPLY_PATH, name);
-                    if (access(path, R_OK) == 0) {
-                        gPaths.batteryVoltagePath = strdup(path);
-                        // voltage_now is in microvolts, not millivolts
-                        gVoltageDivisor = 1000;
-                    } else {
-                        snprintf(path, sizeof(path), "%s/%s/batt_vol", POWER_SUPPLY_PATH, name);
-                        if (access(path, R_OK) == 0)
-                            gPaths.batteryVoltagePath = strdup(path);
-                    }
-
-                    snprintf(path, sizeof(path), "%s/%s/temp", POWER_SUPPLY_PATH, name);
-                    if (access(path, R_OK) == 0) {
-                        gPaths.batteryTemperaturePath = strdup(path);
-                    } else {
-                        snprintf(path, sizeof(path), "%s/%s/batt_temp", POWER_SUPPLY_PATH, name);
-                        if (access(path, R_OK) == 0)
-                            gPaths.batteryTemperaturePath = strdup(path);
-                    }
-
-                    snprintf(path, sizeof(path), "%s/%s/technology", POWER_SUPPLY_PATH, name);
+                path.clear();
+                path.appendFormat("%s/%s/voltage_now", POWER_SUPPLY_PATH, name);
+                if (access(path, R_OK) == 0) {
+                    gPaths.batteryVoltagePath = path;
+                    // voltage_now is in microvolts, not millivolts
+                    gVoltageDivisor = 1000;
+                } else {
+                    path.clear();
+                    path.appendFormat("%s/%s/batt_vol", POWER_SUPPLY_PATH, name);
                     if (access(path, R_OK) == 0)
-                        gPaths.batteryTechnologyPath = strdup(path);
+                            gPaths.batteryVoltagePath = path;
                 }
+
+                path.clear();
+                path.appendFormat("%s/%s/temp", POWER_SUPPLY_PATH, name);
+                if (access(path, R_OK) == 0) {
+                    gPaths.batteryTemperaturePath = path;
+                } else {
+                    path.clear();
+                    path.appendFormat("%s/%s/batt_temp", POWER_SUPPLY_PATH, name);
+                    if (access(path, R_OK) == 0)
+                            gPaths.batteryTemperaturePath = path;
+                }
+
+                path.clear();
+                path.appendFormat("%s/%s/technology", POWER_SUPPLY_PATH, name);
+                if (access(path, R_OK) == 0)
+                    gPaths.batteryTechnologyPath = path;
+                break;
             }
         }
         closedir(dir);
     }
 
-    if (!gPaths.acOnlinePath)
-        ALOGE("acOnlinePath not found");
-    if (!gPaths.usbOnlinePath)
-        ALOGE("usbOnlinePath not found");
-    if (!gPaths.wirelessOnlinePath)
-        ALOGE("wirelessOnlinePath not found");
+    if (!gChargerNames.size())
+        ALOGE("No charger supplies found");
     if (!gPaths.batteryStatusPath)
         ALOGE("batteryStatusPath not found");
     if (!gPaths.batteryHealthPath)
diff --git a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
index 47ce130..8b9f718 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
@@ -864,7 +864,8 @@
 
     private Future<String> expectEnqueueNotification() throws Exception {
         final FutureCapture<String> tag = new FutureCapture<String>();
-        mNotifManager.enqueueNotificationWithTag(isA(String.class), capture(tag.capture), anyInt(),
+        mNotifManager.enqueueNotificationWithTag(isA(String.class), isA(String.class),
+                capture(tag.capture), anyInt(),
                 isA(Notification.class), isA(int[].class), UserHandle.myUserId());
         return tag;
     }
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 6241a49..cd2a600 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -59,19 +59,19 @@
 public class TelephonyManager {
     private static final String TAG = "TelephonyManager";
 
-    private static Context sContext;
     private static ITelephonyRegistry sRegistry;
+    private final Context mContext;
 
     /** @hide */
     public TelephonyManager(Context context) {
-        if (sContext == null) {
-            Context appContext = context.getApplicationContext();
-            if (appContext != null) {
-                sContext = appContext;
-            } else {
-                sContext = context;
-            }
+        Context appContext = context.getApplicationContext();
+        if (appContext != null) {
+            mContext = appContext;
+        } else {
+            mContext = context;
+        }
 
+        if (sRegistry == null) {
             sRegistry = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService(
                     "telephony.registry"));
         }
@@ -79,6 +79,7 @@
 
     /** @hide */
     private TelephonyManager() {
+        mContext = null;
     }
 
     private static TelephonyManager sInstance = new TelephonyManager();
@@ -276,7 +277,7 @@
      */
     public List<NeighboringCellInfo> getNeighboringCellInfo() {
         try {
-            return getITelephony().getNeighboringCellInfo();
+            return getITelephony().getNeighboringCellInfo(mContext.getBasePackageName());
         } catch (RemoteException ex) {
             return null;
         } catch (NullPointerException ex) {
@@ -361,7 +362,7 @@
      * This function returns the type of the phone, depending
      * on the network mode.
      *
-     * @param network mode
+     * @param networkMode
      * @return Phone Type
      *
      * @hide
@@ -1199,7 +1200,7 @@
      *               LISTEN_ flags.
      */
     public void listen(PhoneStateListener listener, int events) {
-        String pkgForDebug = sContext != null ? sContext.getPackageName() : "<unknown>";
+        String pkgForDebug = mContext != null ? mContext.getPackageName() : "<unknown>";
         try {
             Boolean notifyNow = (getITelephony() != null);
             sRegistry.listen(pkgForDebug, listener.callback, events, notifyNow);
@@ -1277,8 +1278,8 @@
      * @hide pending API review
      */
     public boolean isVoiceCapable() {
-        if (sContext == null) return true;
-        return sContext.getResources().getBoolean(
+        if (mContext == null) return true;
+        return mContext.getResources().getBoolean(
                 com.android.internal.R.bool.config_voice_capable);
     }
 
@@ -1294,8 +1295,8 @@
      * @hide pending API review
      */
     public boolean isSmsCapable() {
-        if (sContext == null) return true;
-        return sContext.getResources().getBoolean(
+        if (mContext == null) return true;
+        return mContext.getResources().getBoolean(
                 com.android.internal.R.bool.config_sms_capable);
     }
 
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index d5f0467..1449ab1 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -42,7 +42,7 @@
      * Place a call to the specified number.
      * @param number the number to be called.
      */
-    void call(String number);
+    void call(String callingPackage, String number);
 
     /**
      * If there is currently a call in progress, show the call screen.
@@ -218,7 +218,7 @@
     /**
      * Returns the neighboring cell information of the device.
      */
-    List<NeighboringCellInfo> getNeighboringCellInfo();
+    List<NeighboringCellInfo> getNeighboringCellInfo(String callingPkg);
 
      int getCallState();
      int getDataActivity();
diff --git a/telephony/java/com/android/internal/telephony/SmsRawData.aidl b/telephony/java/com/android/internal/telephony/SmsRawData.aidl
deleted file mode 100644
index b0b3e4f..0000000
--- a/telephony/java/com/android/internal/telephony/SmsRawData.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
-** Copyright 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.
-*/
-
-package com.android.internal.telephony;
-
-parcelable SmsRawData;
diff --git a/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java b/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java
index 6b9f4c3..fbdd333 100644
--- a/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java
+++ b/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java
@@ -219,7 +219,7 @@
                             UserHandle.USER_CURRENT);
                 }
 
-                mResult = mAm.startActivityAndWait(null, mLaunchIntent, mimeType,
+                mResult = mAm.startActivityAndWait(null, null, mLaunchIntent, mimeType,
                         null, null, 0, mLaunchIntent.getFlags(), null, null, null,
                         UserHandle.USER_CURRENT);
             } catch (RemoteException e) {
diff --git a/tests/MemoryUsage/src/com/android/tests/memoryusage/MemoryUsageTest.java b/tests/MemoryUsage/src/com/android/tests/memoryusage/MemoryUsageTest.java
index b550957..397ef13 100644
--- a/tests/MemoryUsage/src/com/android/tests/memoryusage/MemoryUsageTest.java
+++ b/tests/MemoryUsage/src/com/android/tests/memoryusage/MemoryUsageTest.java
@@ -275,7 +275,7 @@
                             UserHandle.USER_CURRENT);
                 }
 
-                mAm.startActivityAndWait(null, mLaunchIntent, mimeType,
+                mAm.startActivityAndWait(null, null, mLaunchIntent, mimeType,
                         null, null, 0, mLaunchIntent.getFlags(), null, null, null,
                         UserHandle.USER_CURRENT_OR_SELF);
             } catch (RemoteException e) {
diff --git a/tests/RenderScriptTests/Balls/src/com/example/android/rs/balls/BallsRS.java b/tests/RenderScriptTests/Balls/src/com/example/android/rs/balls/BallsRS.java
index 8cab9b8..d9d182c 100644
--- a/tests/RenderScriptTests/Balls/src/com/example/android/rs/balls/BallsRS.java
+++ b/tests/RenderScriptTests/Balls/src/com/example/android/rs/balls/BallsRS.java
@@ -20,8 +20,9 @@
 import android.renderscript.*;
 import android.util.Log;
 
+
 public class BallsRS {
-    public static final int PART_COUNT = 900;
+    public static final int PART_COUNT = 4000;
 
     public BallsRS() {
     }
@@ -30,11 +31,12 @@
     private RenderScriptGL mRS;
     private ScriptC_balls mScript;
     private ScriptC_ball_physics mPhysicsScript;
-    private ProgramFragment mPFLines;
     private ProgramFragment mPFPoints;
-    private ProgramVertex mPV;
     private ScriptField_Point mPoints;
     private ScriptField_VpConsts mVpConsts;
+    private ScriptField_BallGrid mGrid;
+    private ScriptField_Ball mBalls;
+    private Allocation mGridCache;
 
     void updateProjectionMatrices() {
         mVpConsts = new ScriptField_VpConsts(mRS, 1,
@@ -56,8 +58,8 @@
                     "  vec4 pos = vec4(0.0, 0.0, 0.0, 1.0);\n" +
                     "  pos.xy = ATTRIB_position;\n" +
                     "  gl_Position = UNI_MVP * pos;\n" +
-                    "  varColor = vec4(1.0, 1.0, 1.0, 1.0);\n" +
-                    "  gl_PointSize = ATTRIB_size;\n" +
+                    "  varColor = ATTRIB_color;\n" +
+                    "  gl_PointSize = 12.0;\n" +
                     "}\n";
         sb.setShader(t);
         sb.addConstant(mVpConsts.getType());
@@ -84,22 +86,21 @@
         return builder.create();
     }
 
-    public void init(RenderScriptGL rs, Resources res, int width, int height) {
-        mRS = rs;
-        mRes = res;
-
-        ProgramFragmentFixedFunction.Builder pfb = new ProgramFragmentFixedFunction.Builder(rs);
+    private void createPF(int width, int height) {
+        ProgramFragmentFixedFunction.Builder pfb = new ProgramFragmentFixedFunction.Builder(mRS);
         pfb.setPointSpriteTexCoordinateReplacement(true);
         pfb.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.MODULATE,
                            ProgramFragmentFixedFunction.Builder.Format.RGBA, 0);
         pfb.setVaryingColor(true);
         mPFPoints = pfb.create();
+    }
 
-        pfb = new ProgramFragmentFixedFunction.Builder(rs);
-        pfb.setVaryingColor(true);
-        mPFLines = pfb.create();
+    public void init(RenderScriptGL rs, Resources res, int width, int height) {
+        mRS = rs;
+        mRes = res;
 
-        android.util.Log.e("rs", "Load texture");
+        createPF(width, height);
+
         mPFPoints.bindTexture(loadTexture(R.drawable.flares), 0);
 
         mPoints = new ScriptField_Point(mRS, PART_COUNT, Allocation.USAGE_SCRIPT);
@@ -109,16 +110,22 @@
         smb.addIndexSetType(Mesh.Primitive.POINT);
         Mesh smP = smb.create();
 
-        mPhysicsScript = new ScriptC_ball_physics(mRS, mRes, R.raw.ball_physics);
+        mGrid = ScriptField_BallGrid.create2D(mRS, (width + 99) / 100, (height + 99) / 100);
+        mGridCache = Allocation.createSized(mRS, Element.F32_2(mRS), PART_COUNT);
+        mBalls = new ScriptField_Ball(mRS, PART_COUNT, Allocation.USAGE_SCRIPT);
 
-        mScript = new ScriptC_balls(mRS, mRes, R.raw.balls);
+        mPhysicsScript = new ScriptC_ball_physics(mRS);
+        mPhysicsScript.set_gGridCache(mGridCache);
+        mPhysicsScript.set_gBalls(mBalls.getAllocation());
+
+        mScript = new ScriptC_balls(mRS);
         mScript.set_partMesh(smP);
         mScript.set_physics_script(mPhysicsScript);
         mScript.bind_point(mPoints);
-        mScript.bind_balls1(new ScriptField_Ball(mRS, PART_COUNT, Allocation.USAGE_SCRIPT));
-        mScript.bind_balls2(new ScriptField_Ball(mRS, PART_COUNT, Allocation.USAGE_SCRIPT));
+        mScript.bind_balls(mBalls);
+        mScript.set_gGrid(mGrid.getAllocation());
+        mScript.bind_gGridCache(mGridCache);
 
-        mScript.set_gPFLines(mPFLines);
         mScript.set_gPFPoints(mPFPoints);
         createProgramVertex();
 
@@ -126,6 +133,7 @@
 
         mPhysicsScript.set_gMinPos(new Float2(5, 5));
         mPhysicsScript.set_gMaxPos(new Float2(width - 5, height - 5));
+        mPhysicsScript.set_gGrid(mGrid.getAllocation());
 
         mScript.invoke_initParts(width, height);
 
@@ -133,7 +141,7 @@
     }
 
     public void newTouchPosition(float x, float y, float pressure, int id) {
-        mPhysicsScript.invoke_touch(x, y, pressure, id);
+        mPhysicsScript.invoke_touch(x, y, pressure * mRS.getWidth() / 1280, id);
     }
 
     public void setAccel(float x, float y) {
diff --git a/tests/RenderScriptTests/Balls/src/com/example/android/rs/balls/ball_physics.rs b/tests/RenderScriptTests/Balls/src/com/example/android/rs/balls/ball_physics.rs
index 8a3db6d..5b5d2e0 100644
--- a/tests/RenderScriptTests/Balls/src/com/example/android/rs/balls/ball_physics.rs
+++ b/tests/RenderScriptTests/Balls/src/com/example/android/rs/balls/ball_physics.rs
@@ -10,6 +10,13 @@
 
 static float2 touchPos[10];
 static float touchPressure[10];
+static const float gDT = 1.f / 30.f;
+
+rs_allocation gGrid;
+rs_allocation gGridCache;
+rs_allocation gBalls;
+
+float gScale = 1.f;
 
 void touch(float x, float y, float pressure, int id) {
     if (id >= 10) {
@@ -21,126 +28,128 @@
     touchPressure[id] = pressure;
 }
 
-void root(const Ball_t *ballIn, Ball_t *ballOut, const BallControl_t *ctl, uint32_t x) {
-    float2 fv = {0, 0};
-    float2 pos = ballIn->position;
+void root(Ball_t *ball, uint32_t x) {
+    float2 fv = 0;
+    float pressure = 0;
+    float2 pos = ball->position;
+    int2 gridPos[9];
 
-    int arcID = -1;
-    float arcInvStr = 100000;
+    gridPos[0] = convert_int2((ball->position / 100.f) /*- 0.4999f*/);
+    gridPos[1] = (int2){gridPos[0].x - 1, gridPos[0].y - 1};
+    gridPos[2] = (int2){gridPos[0].x + 0, gridPos[0].y - 1};
+    gridPos[3] = (int2){gridPos[0].x + 1, gridPos[0].y - 1};
+    gridPos[4] = (int2){gridPos[0].x - 1, gridPos[0].y};
+    gridPos[5] = (int2){gridPos[0].x + 1, gridPos[0].y};
+    gridPos[6] = (int2){gridPos[0].x - 1, gridPos[0].y + 1};
+    gridPos[7] = (int2){gridPos[0].x + 0, gridPos[0].y + 1};
+    gridPos[8] = (int2){gridPos[0].x + 1, gridPos[0].y + 1};
 
-    const Ball_t * bPtr = rsGetElementAt(ctl->ain, 0);
-    for (uint32_t xin = 0; xin < ctl->dimX; xin++) {
-        float2 vec = bPtr[xin].position - pos;
-        float2 vec2 = vec * vec;
-        float len2 = vec2.x + vec2.y;
+    for (int gct=0; gct < 9; gct++) {
+        if ((gridPos[gct].x >= rsAllocationGetDimX(gGrid)) ||
+            (gridPos[gct].x < 0) ||
+            (gridPos[gct].y >= rsAllocationGetDimY(gGrid)) ||
+            (gridPos[gct].y < 0)) {
+            continue;
+        }
+        //rsDebug("grid ", gridPos[gct]);
+        const BallGrid_t *bg = (const BallGrid_t *)rsGetElementAt(gGrid, gridPos[gct].x, gridPos[gct].y);
 
-        if (len2 < 10000) {
-            //float minDist = ballIn->size + bPtr[xin].size;
-            float forceScale = ballIn->size * bPtr[xin].size;
-            forceScale *= forceScale;
+        for (int cidx = 0; cidx < bg->count; cidx++) {
+            float2 bcptr = rsGetElementAt_float2(gGridCache, bg->cacheIdx + cidx);
+            float2 vec = bcptr - pos;
+            float2 vec2 = vec * vec;
+            float len2 = vec2.x + vec2.y;
 
-            if (len2 > 16 /* (minDist*minDist)*/)  {
-                // Repulsion
-                float len = sqrt(len2);
-                fv -= (vec / (len * len * len)) * 20000.f * forceScale;
-            } else {
-                if (len2 < 1) {
-                    if (xin == x) {
-                        continue;
-                    }
-                    ballOut->delta = 0.f;
-                    ballOut->position = ballIn->position;
-                    if (xin > x) {
-                        ballOut->position.x += 1.f;
-                    } else {
-                        ballOut->position.x -= 1.f;
-                    }
-                    //ballOut->color.rgb = 1.f;
-                    //ballOut->arcID = -1;
-                    //ballOut->arcStr = 0;
-                    continue;
-                }
-                // Collision
-                float2 axis = normalize(vec);
-                float e1 = dot(axis, ballIn->delta);
-                float e2 = dot(axis, bPtr[xin].delta);
-                float e = (e1 - e2) * 0.45f;
-                if (e1 > 0) {
-                    fv -= axis * e;
-                } else {
-                    fv += axis * e;
-                }
+            if ((len2 < 10000.f) && (len2 > 0.f)) {
+                float t = native_powr(len2, 1.5f) + 16.0f;
+                float2 pfv = (vec / t) * 16000.f;
+                pressure += length(pfv);
+                fv -= pfv;
             }
         }
     }
 
-    fv /= ballIn->size * ballIn->size * ballIn->size;
-    fv -= gGravityVector * 4.f;
-    fv *= ctl->dt;
+    //fv /= ball->size * ball->size * ball->size;
+    fv -= gGravityVector * 4.f * gScale;
+    fv *= gDT;
 
     for (int i=0; i < 10; i++) {
         if (touchPressure[i] > 0.1f) {
-            float2 vec = touchPos[i] - ballIn->position;
+            float2 vec = touchPos[i] - ball->position;
             float2 vec2 = vec * vec;
             float len2 = max(2.f, vec2.x + vec2.y);
-            fv -= (vec / len2) * touchPressure[i] * 300.f;
+            float2 pfv = (vec / len2) * touchPressure[i] * 500.f * gScale;
+            pressure += length(pfv);
+            fv -= pfv;
         }
     }
 
-    ballOut->delta = (ballIn->delta * (1.f - 0.004f)) + fv;
-    ballOut->position = ballIn->position + (ballOut->delta * ctl->dt);
+    ball->delta = (ball->delta * (1.f - 0.008f)) + fv;
+    ball->position = ball->position + (ball->delta * gDT);
 
-    const float wallForce = 400.f;
-    if (ballOut->position.x > (gMaxPos.x - 20.f)) {
-        float d = gMaxPos.x - ballOut->position.x;
+    const float wallForce = 400.f * gScale;
+    if (ball->position.x > (gMaxPos.x - 20.f)) {
+        float d = gMaxPos.x - ball->position.x;
         if (d < 0.f) {
-            if (ballOut->delta.x > 0) {
-                ballOut->delta.x *= -0.7f;
+            if (ball->delta.x > 0) {
+                ball->delta.x *= -0.7f;
             }
-            ballOut->position.x = gMaxPos.x;
+            ball->position.x = gMaxPos.x - 1.f;
         } else {
-            ballOut->delta.x -= min(wallForce / (d * d), 10.f);
+            ball->delta.x -= min(wallForce / (d * d), 10.f);
         }
     }
 
-    if (ballOut->position.x < (gMinPos.x + 20.f)) {
-        float d = ballOut->position.x - gMinPos.x;
+    if (ball->position.x < (gMinPos.x + 20.f)) {
+        float d = ball->position.x - gMinPos.x;
         if (d < 0.f) {
-            if (ballOut->delta.x < 0) {
-                ballOut->delta.x *= -0.7f;
+            if (ball->delta.x < 0) {
+                ball->delta.x *= -0.7f;
             }
-            ballOut->position.x = gMinPos.x + 1.f;
+            ball->position.x = gMinPos.x + 1.f;
         } else {
-            ballOut->delta.x += min(wallForce / (d * d), 10.f);
+            ball->delta.x += min(wallForce / (d * d), 10.f);
         }
     }
 
-    if (ballOut->position.y > (gMaxPos.y - 20.f)) {
-        float d = gMaxPos.y - ballOut->position.y;
+    if (ball->position.y > (gMaxPos.y - 20.f)) {
+        float d = gMaxPos.y - ball->position.y;
         if (d < 0.f) {
-            if (ballOut->delta.y > 0) {
-                ballOut->delta.y *= -0.7f;
+            if (ball->delta.y > 0) {
+                ball->delta.y *= -0.7f;
             }
-            ballOut->position.y = gMaxPos.y;
+            ball->position.y = gMaxPos.y - 1.f;
         } else {
-            ballOut->delta.y -= min(wallForce / (d * d), 10.f);
+            ball->delta.y -= min(wallForce / (d * d), 10.f);
         }
     }
 
-    if (ballOut->position.y < (gMinPos.y + 20.f)) {
-        float d = ballOut->position.y - gMinPos.y;
+    if (ball->position.y < (gMinPos.y + 20.f)) {
+        float d = ball->position.y - gMinPos.y;
         if (d < 0.f) {
-            if (ballOut->delta.y < 0) {
-                ballOut->delta.y *= -0.7f;
+            if (ball->delta.y < 0) {
+                ball->delta.y *= -0.7f;
             }
-            ballOut->position.y = gMinPos.y + 1.f;
+            ball->position.y = gMinPos.y + 1.f;
         } else {
-            ballOut->delta.y += min(wallForce / (d * d * d), 10.f);
+            ball->delta.y += min(wallForce / (d * d * d), 10.f);
         }
     }
 
-    ballOut->size = ballIn->size;
+    // low pressure ~500, high ~2500
+    pressure = max(pressure - 400.f, 0.f);
+    ball->pressure = pressure;
 
-    //rsDebug("physics pos out", ballOut->position);
+    //rsDebug("p ", pressure);
+
+    float4 color = 1.f;
+    color.r = pow(pressure, 0.25f) / 12.f;
+    color.b = 1.f - color.r;
+    color.g = sin(pressure / 1500.f * 3.14f);
+    color.rgb = max(color.rgb, (float3)0);
+    color.rgb = normalize(color.rgb);
+    ball->color = rsPackColorTo8888(color);
+
+    //rsDebug("physics pos out", ball->position);
 }
 
diff --git a/tests/RenderScriptTests/Balls/src/com/example/android/rs/balls/balls.rs b/tests/RenderScriptTests/Balls/src/com/example/android/rs/balls/balls.rs
index dcdd586..9be9f38 100644
--- a/tests/RenderScriptTests/Balls/src/com/example/android/rs/balls/balls.rs
+++ b/tests/RenderScriptTests/Balls/src/com/example/android/rs/balls/balls.rs
@@ -8,12 +8,15 @@
 #pragma stateStore(parent)
 
 rs_program_fragment gPFPoints;
-rs_program_fragment gPFLines;
 rs_mesh partMesh;
 
+rs_allocation gGrid;
+BallGrid_t *unused1;
+float2 *gGridCache;
+
 typedef struct __attribute__((packed, aligned(4))) Point {
     float2 position;
-    float size;
+    uchar4 color;
 } Point_t;
 Point_t *point;
 
@@ -24,58 +27,78 @@
 
 rs_script physics_script;
 
-Ball_t *balls1;
-Ball_t *balls2;
-
-static int frame = 0;
 
 void initParts(int w, int h)
 {
-    uint32_t dimX = rsAllocationGetDimX(rsGetAllocation(balls1));
+    uint32_t dimX = rsAllocationGetDimX(rsGetAllocation(balls));
 
     for (uint32_t ct=0; ct < dimX; ct++) {
-        balls1[ct].position.x = rsRand(0.f, (float)w);
-        balls1[ct].position.y = rsRand(0.f, (float)h);
-        balls1[ct].delta.x = 0.f;
-        balls1[ct].delta.y = 0.f;
-        balls1[ct].size = 1.f;
-
-        float r = rsRand(100.f);
-        if (r > 90.f) {
-            balls1[ct].size += pow(10.f, rsRand(0.f, 2.f)) * 0.07f;
-        }
+        balls[ct].position.x = rsRand(0.f, (float)w);
+        balls[ct].position.y = rsRand(0.f, (float)h);
+        balls[ct].delta.x = 0.f;
+        balls[ct].delta.y = 0.f;
     }
 }
 
-
-
 int root() {
     rsgClearColor(0.f, 0.f, 0.f, 1.f);
 
-    BallControl_t bc;
-    Ball_t *bout;
+    int2 gridDims = (int2){ rsAllocationGetDimX(gGrid),
+                            rsAllocationGetDimY(gGrid) };
 
-    if (frame & 1) {
-        bc.ain = rsGetAllocation(balls2);
-        bc.aout = rsGetAllocation(balls1);
-        bout = balls1;
-    } else {
-        bc.ain = rsGetAllocation(balls1);
-        bc.aout = rsGetAllocation(balls2);
-        bout = balls2;
+    rs_allocation ain = rsGetAllocation(balls);
+    int32_t dimX = rsAllocationGetDimX(ain);
+
+    // Binning
+    // Clear the particle list
+    for (uint32_t ct=0; ct < dimX; ct++) {
+        balls[ct].next = -1;
     }
 
-    bc.dimX = rsAllocationGetDimX(bc.ain);
-    bc.dt = 1.f / 30.f;
-
-    rsForEach(physics_script, bc.ain, bc.aout, &bc, sizeof(bc));
-
-    for (uint32_t ct=0; ct < bc.dimX; ct++) {
-        point[ct].position = bout[ct].position;
-        point[ct].size = 6.f /*+ bout[ct].color.g * 6.f*/ * bout[ct].size;
+    // Clear the grid
+    for (uint32_t y=0; y < gridDims.y; y++) {
+        for (uint32_t x=0; x < gridDims.x; x++) {
+            BallGrid_t *bg = (BallGrid_t *)rsGetElementAt(gGrid, x, y);
+            bg->count = 0;
+            bg->idx = -1;
+        }
     }
 
-    frame++;
+    // Create the particle list per grid
+    for (uint32_t ct=0; ct < dimX; ct++) {
+        int2 p = convert_int2(balls[ct].position / 100.f);
+        p.x = rsClamp(p.x, 0, (int)(gridDims.x-1));
+        p.y = rsClamp(p.y, 0, (int)(gridDims.y-1));
+        BallGrid_t *bg = (BallGrid_t *)rsGetElementAt(gGrid, p.x, p.y);
+        bg->count ++;
+        balls[ct].next = bg->idx;
+        bg->idx = ct;
+    }
+
+    // Create the sorted grid cache
+    uint32_t gridIdx = 0;
+    for (uint32_t y=0; y < gridDims.y; y++) {
+        for (uint32_t x=0; x < gridDims.x; x++) {
+            BallGrid_t *bg = (BallGrid_t *)rsGetElementAt(gGrid, x, y);
+            bg->cacheIdx = gridIdx;
+
+            int idx = bg->idx;
+            while (idx >= 0) {
+                const Ball_t * bPtr = &balls[idx];
+                gGridCache[gridIdx++] = bPtr->position;
+                idx = bPtr->next;
+            }
+        }
+    }
+
+
+    rsForEach(physics_script, ain, ain);
+
+    for (uint32_t ct=0; ct < dimX; ct++) {
+        point[ct].position = balls[ct].position;
+        point[ct].color = balls[ct].color;
+    }
+
     rsgBindProgramFragment(gPFPoints);
     rsgDrawMesh(partMesh);
     return 1;
diff --git a/tests/RenderScriptTests/Balls/src/com/example/android/rs/balls/balls.rsh b/tests/RenderScriptTests/Balls/src/com/example/android/rs/balls/balls.rsh
index fc886f9..ebe23f8 100644
--- a/tests/RenderScriptTests/Balls/src/com/example/android/rs/balls/balls.rsh
+++ b/tests/RenderScriptTests/Balls/src/com/example/android/rs/balls/balls.rsh
@@ -2,17 +2,18 @@
 typedef struct __attribute__((packed, aligned(4))) Ball {
     float2 delta;
     float2 position;
-    //float3 color;
-    float size;
+    uchar4 color;
+    float pressure;
+    //float size;
+    int32_t next;
     //int arcID;
     //float arcStr;
 } Ball_t;
 Ball_t *balls;
 
 
-typedef struct BallControl {
-    uint32_t dimX;
-    rs_allocation ain;
-    rs_allocation aout;
-    float dt;
-} BallControl_t;
+typedef struct BallGrid {
+    int32_t idx;
+    int32_t count;
+    int32_t cacheIdx;
+} BallGrid_t;
diff --git a/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java b/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
index ec39aab..4345098 100644
--- a/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
+++ b/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
@@ -796,6 +796,7 @@
                     INotificationManager directLine = mNM.getService();
                     directLine.enqueueNotificationWithTag(
                             getPackageName(),
+                            getPackageName(),
                             null, 
                             100, 
                             n,
@@ -821,7 +822,8 @@
                     INotificationManager directLine = mNM.getService();
                     directLine.enqueueNotificationWithTag(
                             getPackageName(),
-                            null, 
+                            getPackageName(),
+                            null,
                             200, 
                             n,
                             idOut,
@@ -846,7 +848,8 @@
                     INotificationManager directLine = mNM.getService();
                     directLine.enqueueNotificationWithTag(
                             getPackageName(),
-                            null, 
+                            getPackageName(),
+                            null,
                             1, 
                             n,
                             idOut,
diff --git a/tests/permission/src/com/android/framework/permission/tests/VibratorServicePermissionTest.java b/tests/permission/src/com/android/framework/permission/tests/VibratorServicePermissionTest.java
index 2416828..90b6abc 100644
--- a/tests/permission/src/com/android/framework/permission/tests/VibratorServicePermissionTest.java
+++ b/tests/permission/src/com/android/framework/permission/tests/VibratorServicePermissionTest.java
@@ -20,6 +20,7 @@
 
 import android.os.Binder;
 import android.os.IVibratorService;
+import android.os.Process;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.test.suitebuilder.annotation.SmallTest;
@@ -46,7 +47,7 @@
      */
     public void testVibrate() throws RemoteException {
         try {
-            mVibratorService.vibrate(null, 2000, new Binder());
+            mVibratorService.vibrate(Process.myUid(), null, 2000, new Binder());
             fail("vibrate did not throw SecurityException as expected");
         } catch (SecurityException e) {
             // expected
@@ -62,7 +63,7 @@
      */
     public void testVibratePattern() throws RemoteException {
         try {
-            mVibratorService.vibratePattern(null, new long[] {0}, 0, new Binder());
+            mVibratorService.vibratePattern(Process.myUid(), null, new long[] {0}, 0, new Binder());
             fail("vibratePattern did not throw SecurityException as expected");
         } catch (SecurityException e) {
             // expected