Merge "Don't sync from adapters that haven't opted in to restricted accounts" into jb-mr2-dev
diff --git a/Android.mk b/Android.mk
index e70f9f3..5bf4d41 100644
--- a/Android.mk
+++ b/Android.mk
@@ -124,6 +124,8 @@
 	core/java/android/hardware/display/IDisplayManagerCallback.aidl \
 	core/java/android/hardware/input/IInputManager.aidl \
 	core/java/android/hardware/input/IInputDevicesChangedListener.aidl \
+	core/java/android/hardware/location/IGeofenceHardware.aidl \
+	core/java/android/hardware/location/IGeofenceHardwareCallback.aidl \
 	core/java/android/hardware/usb/IUsbManager.aidl \
 	core/java/android/net/IConnectivityManager.aidl \
 	core/java/android/net/INetworkManagementEventObserver.aidl \
@@ -207,10 +209,12 @@
 	location/java/android/location/ICountryDetector.aidl \
 	location/java/android/location/ICountryListener.aidl \
 	location/java/android/location/IGeocodeProvider.aidl \
+	location/java/android/location/IGeofenceProvider.aidl \
 	location/java/android/location/IGpsStatusListener.aidl \
 	location/java/android/location/IGpsStatusProvider.aidl \
 	location/java/android/location/ILocationListener.aidl \
 	location/java/android/location/ILocationManager.aidl \
+	location/java/android/location/IGpsGeofenceHardware.aidl \
 	location/java/android/location/INetInitiatedListener.aidl \
 	location/java/com/android/internal/location/ILocationProvider.aidl \
 	media/java/android/media/IAudioService.aidl \
diff --git a/api/current.txt b/api/current.txt
index 1e1f01c..7451a93 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -69,6 +69,7 @@
     field public static final java.lang.String INTERNAL_SYSTEM_WINDOW = "android.permission.INTERNAL_SYSTEM_WINDOW";
     field public static final java.lang.String INTERNET = "android.permission.INTERNET";
     field public static final java.lang.String KILL_BACKGROUND_PROCESSES = "android.permission.KILL_BACKGROUND_PROCESSES";
+    field public static final java.lang.String LOCATION_HARDWARE = "android.permission.LOCATION_HARDWARE";
     field public static final java.lang.String MANAGE_ACCOUNTS = "android.permission.MANAGE_ACCOUNTS";
     field public static final java.lang.String MANAGE_APP_TOKENS = "android.permission.MANAGE_APP_TOKENS";
     field public static final java.lang.String MASTER_CLEAR = "android.permission.MASTER_CLEAR";
@@ -10443,6 +10444,43 @@
 
 }
 
+package android.hardware.location {
+
+  public final class GeofenceHardware {
+    method public boolean addCircularFence(int, double, double, double, int, int, int, int, int, android.hardware.location.GeofenceHardwareCallback);
+    method public int[] getMonitoringTypesAndStatus();
+    method public boolean pauseGeofence(int, int);
+    method public boolean registerForMonitorStateChangeCallback(int, android.hardware.location.GeofenceHardwareCallback);
+    method public boolean removeGeofence(int, int);
+    method public boolean resumeGeofence(int, int, int);
+    method public boolean unregisterForMonitorStateChangeCallback(int, android.hardware.location.GeofenceHardwareCallback);
+    field public static final int GEOFENCE_ENTERED = 1; // 0x1
+    field public static final int GEOFENCE_ERROR_ID_EXISTS = 2; // 0x2
+    field public static final int GEOFENCE_ERROR_ID_UNKNOWN = 3; // 0x3
+    field public static final int GEOFENCE_ERROR_INVALID_TRANSITION = 4; // 0x4
+    field public static final int GEOFENCE_ERROR_TOO_MANY_GEOFENCES = 1; // 0x1
+    field public static final int GEOFENCE_EXITED = 2; // 0x2
+    field public static final int GEOFENCE_FAILURE = 5; // 0x5
+    field public static final int GEOFENCE_SUCCESS = 0; // 0x0
+    field public static final int GEOFENCE_UNCERTAIN = 4; // 0x4
+    field public static final int MONITORING_TYPE_GPS_HARDWARE = 0; // 0x0
+    field public static final int MONITOR_CURRENTLY_AVAILABLE = 0; // 0x0
+    field public static final int MONITOR_CURRENTLY_UNAVAILABLE = 1; // 0x1
+    field public static final int MONITOR_UNSUPPORTED = 2; // 0x2
+  }
+
+  public abstract class GeofenceHardwareCallback {
+    ctor public GeofenceHardwareCallback();
+    method public void onGeofenceAdd(int, int);
+    method public void onGeofenceChange(int, int, android.location.Location, long, int);
+    method public void onGeofencePause(int, int);
+    method public void onGeofenceRemove(int, int);
+    method public void onGeofenceResume(int, int);
+    method public void onMonitoringSystemChange(int, boolean, android.location.Location);
+  }
+
+}
+
 package android.hardware.usb {
 
   public class UsbAccessory implements android.os.Parcelable {
@@ -16835,7 +16873,6 @@
     method public static final void setThreadPriority(int, int) throws java.lang.IllegalArgumentException, java.lang.SecurityException;
     method public static final void setThreadPriority(int) throws java.lang.IllegalArgumentException, java.lang.SecurityException;
     method public static final deprecated boolean supportsProcesses();
-    field public static final int BLUETOOTH_GID = 2000; // 0x7d0
     field public static final int FIRST_APPLICATION_UID = 10000; // 0x2710
     field public static final int LAST_APPLICATION_UID = 19999; // 0x4e1f
     field public static final int PHONE_UID = 1001; // 0x3e9
@@ -18442,6 +18479,7 @@
   }
 
   protected static abstract interface ContactsContract.ContactsColumns {
+    field public static final java.lang.String CONTACT_LAST_UPDATED_TIMESTAMP = "contact_last_updated_timestamp";
     field public static final java.lang.String DISPLAY_NAME = "display_name";
     field public static final java.lang.String HAS_PHONE_NUMBER = "has_phone_number";
     field public static final java.lang.String IN_VISIBLE_GROUP = "in_visible_group";
@@ -18506,6 +18544,16 @@
     field public static final java.lang.String TIMES_USED = "times_used";
   }
 
+  public static final class ContactsContract.DeletedContacts implements android.provider.ContactsContract.DeletedContactsColumns {
+    field public static final android.net.Uri CONTENT_URI;
+    field public static final long DAYS_KEPT_MILLISECONDS = 2592000000L; // 0x9a7ec800L
+  }
+
+  protected static abstract interface ContactsContract.DeletedContactsColumns {
+    field public static final java.lang.String CONTACT_DELETED_TIMESTAMP = "contact_deleted_timestamp";
+    field public static final java.lang.String CONTACT_ID = "contact_id";
+  }
+
   public static final class ContactsContract.Directory implements android.provider.BaseColumns {
     method public static void notifyDirectoryChange(android.content.ContentResolver);
     field public static final java.lang.String ACCOUNT_NAME = "accountName";
@@ -18585,6 +18633,7 @@
   public static final class ContactsContract.Intents {
     ctor public ContactsContract.Intents();
     field public static final java.lang.String ATTACH_IMAGE = "com.android.contacts.action.ATTACH_IMAGE";
+    field public static final java.lang.String CONTACTS_DATABASE_CREATED = "android.provider.Contacts.DATABASE_CREATED";
     field public static final java.lang.String EXTRA_CREATE_DESCRIPTION = "com.android.contacts.action.CREATE_DESCRIPTION";
     field public static final java.lang.String EXTRA_FORCE_CREATE = "com.android.contacts.action.FORCE_CREATE";
     field public static final java.lang.String INVITE_CONTACT = "com.android.contacts.action.INVITE_CONTACT";
@@ -19649,8 +19698,7 @@
     method public int getUsage();
     method public void ioReceive();
     method public void ioSend();
-    method public synchronized void resize(int);
-    method public synchronized void resize(int, int);
+    method public deprecated synchronized void resize(int);
     method public void setFromFieldPacker(int, android.renderscript.FieldPacker);
     method public void setFromFieldPacker(int, int, android.renderscript.FieldPacker);
     method public void setSurface(android.view.Surface);
@@ -27589,8 +27637,6 @@
     method public synchronized int getMinimumFontSize();
     method public synchronized int getMinimumLogicalFontSize();
     method public deprecated synchronized android.webkit.WebSettings.PluginState getPluginState();
-    method public deprecated synchronized boolean getPluginsEnabled();
-    method public deprecated synchronized java.lang.String getPluginsPath();
     method public synchronized java.lang.String getSansSerifFontFamily();
     method public boolean getSaveFormData();
     method public deprecated boolean getSavePassword();
@@ -27636,8 +27682,6 @@
     method public synchronized void setMinimumLogicalFontSize(int);
     method public void setNeedInitialFocus(boolean);
     method public deprecated synchronized void setPluginState(android.webkit.WebSettings.PluginState);
-    method public deprecated synchronized void setPluginsEnabled(boolean);
-    method public deprecated synchronized void setPluginsPath(java.lang.String);
     method public deprecated synchronized void setRenderPriority(android.webkit.WebSettings.RenderPriority);
     method public synchronized void setSansSerifFontFamily(java.lang.String);
     method public void setSaveFormData(boolean);
diff --git a/cmds/app_process/Android.mk b/cmds/app_process/Android.mk
index b39c335..b9afe40 100644
--- a/cmds/app_process/Android.mk
+++ b/cmds/app_process/Android.mk
@@ -7,6 +7,7 @@
 LOCAL_SHARED_LIBRARIES := \
 	libcutils \
 	libutils \
+	liblog \
 	libbinder \
 	libandroid_runtime
 
@@ -27,6 +28,7 @@
 LOCAL_SHARED_LIBRARIES := \
 	libcutils \
 	libutils \
+	liblog \
 	libbinder \
 	libandroid_runtime
 
diff --git a/cmds/bootanimation/Android.mk b/cmds/bootanimation/Android.mk
index 8c46b21..d5ff84e 100644
--- a/cmds/bootanimation/Android.mk
+++ b/cmds/bootanimation/Android.mk
@@ -9,6 +9,7 @@
 
 LOCAL_SHARED_LIBRARIES := \
 	libcutils \
+	liblog \
 	libandroidfw \
 	libutils \
 	libbinder \
diff --git a/cmds/input/src/com/android/commands/input/Input.java b/cmds/input/src/com/android/commands/input/Input.java
index cdbc405..e43501c 100644
--- a/cmds/input/src/com/android/commands/input/Input.java
+++ b/cmds/input/src/com/android/commands/input/Input.java
@@ -75,11 +75,14 @@
                             Float.parseFloat(args[3]), Float.parseFloat(args[4]), -1);
                     return;
                 }
-            } else if (command.equals("touchscreen") || command.equals("touchpad")) {
+            } else if (command.equals("touchscreen") || command.equals("touchpad")
+                    || command.equals("touchnavigation")) {
                 // determine input source
                 int inputSource = InputDevice.SOURCE_TOUCHSCREEN;
                 if (command.equals("touchpad")) {
                     inputSource = InputDevice.SOURCE_TOUCHPAD;
+                } else if (command.equals("touchnavigation")) {
+                    inputSource = InputDevice.SOURCE_TOUCH_NAVIGATION;
                 }
                 // determine subcommand
                 if (args.length > 1) {
@@ -247,8 +250,9 @@
         System.err.println("usage: input ...");
         System.err.println("       input text <string>");
         System.err.println("       input keyevent <key code number or name>");
-        System.err.println("       input [touchscreen|touchpad] tap <x> <y>");
-        System.err.println("       input [touchscreen|touchpad] swipe <x1> <y1> <x2> <y2> [duration(ms)]");
+        System.err.println("       input [touchscreen|touchpad|touchnavigation] tap <x> <y>");
+        System.err.println("       input [touchscreen|touchpad|touchnavigation] swipe "
+                + "<x1> <y1> <x2> <y2> [duration(ms)]");
         System.err.println("       input trackball press");
         System.err.println("       input trackball roll <dx> <dy>");
     }
diff --git a/cmds/system_server/Android.mk b/cmds/system_server/Android.mk
index ad537977..3083e31 100644
--- a/cmds/system_server/Android.mk
+++ b/cmds/system_server/Android.mk
@@ -7,7 +7,8 @@
 LOCAL_SHARED_LIBRARIES := \
 	libutils \
 	libbinder \
-	libsystem_server 
+	libsystem_server \
+	liblog
 
 LOCAL_C_INCLUDES := \
 	$(JNI_H_INCLUDE)
@@ -17,4 +18,3 @@
 include $(BUILD_EXECUTABLE)
 
 include $(LOCAL_PATH)/library/Android.mk
-
diff --git a/cmds/system_server/library/Android.mk b/cmds/system_server/library/Android.mk
index c42424c..d78474e 100644
--- a/cmds/system_server/library/Android.mk
+++ b/cmds/system_server/library/Android.mk
@@ -16,10 +16,11 @@
 	libandroid_runtime \
 	libsensorservice \
 	libsurfaceflinger \
-    libinput \
+	libinput \
 	libutils \
 	libbinder \
-	libcutils
+	libcutils \
+	liblog
 
 LOCAL_MODULE:= libsystem_server
 
diff --git a/core/java/android/accounts/CantAddAccountActivity.java b/core/java/android/accounts/CantAddAccountActivity.java
new file mode 100644
index 0000000..e1717a6
--- /dev/null
+++ b/core/java/android/accounts/CantAddAccountActivity.java
@@ -0,0 +1,40 @@
+/*
+ * 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 android.accounts;
+
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.View;
+
+import com.android.internal.R;
+
+/**
+ * @hide
+ * Just shows an error message about the account restrictions for the limited user.
+ */
+public class CantAddAccountActivity extends Activity {
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.app_not_authorized);
+    }
+
+    public void onCancelButtonClicked(View view) {
+        onBackPressed();
+    }
+}
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index aca4f9c..c99051b 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -1853,6 +1853,15 @@
             return true;
         }
 
+        case KILL_UID_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            int uid = data.readInt();
+            String reason = data.readString();
+            killUid(uid, reason);
+            reply.writeNoException();
+            return true;
+        }
+
         }
 
         return super.onTransact(code, data, reply, flags);
@@ -3335,6 +3344,7 @@
         data.writeString(reason);
         data.writeInt(secure ? 1 : 0);
         mRemote.transact(KILL_PIDS_TRANSACTION, data, reply, 0);
+        reply.readException();
         boolean res = reply.readInt() != 0;
         data.recycle();
         reply.recycle();
@@ -4229,5 +4239,17 @@
         reply.recycle();
     }
 
+    public void killUid(int uid, String reason) throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeInt(uid);
+        data.writeString(reason);
+        mRemote.transact(KILL_UID_TRANSACTION, data, reply, 0);
+        reply.readException();
+        data.recycle();
+        reply.recycle();
+    }
+
     private IBinder mRemote;
 }
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 68a2397..e6ce963 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -4322,6 +4322,10 @@
             GLUtils.setTracingLevel(1);
         }
 
+        // Allow application-generated systrace messages if we're debuggable.
+        boolean appTracingAllowed = (data.appInfo.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0;
+        Trace.setAppTracingAllowed(appTracingAllowed);
+
         /**
          * Initialize the default http proxy in this process for the reasons we set the time zone.
          */
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index cf4c729..fa8839a 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -373,6 +373,8 @@
 
     public void reportTopActivityExtras(IBinder token, Bundle extras) throws RemoteException;
 
+    public void killUid(int uid, String reason) throws RemoteException;
+
     /*
      * Private non-Binder interfaces
      */
@@ -632,4 +634,5 @@
     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;
+    int KILL_UID_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+164;
 }
diff --git a/core/java/android/hardware/location/GeofenceHardware.java b/core/java/android/hardware/location/GeofenceHardware.java
new file mode 100644
index 0000000..35bbb9c
--- /dev/null
+++ b/core/java/android/hardware/location/GeofenceHardware.java
@@ -0,0 +1,439 @@
+/*
+ * 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 android.hardware.location;
+
+import android.content.Context;
+import android.location.Location;
+import android.os.RemoteException;
+import android.util.Log;
+
+import java.lang.ref.WeakReference;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+
+/**
+ * This class handles geofences managed by various hardware subsystems. It contains
+ * the public APIs that is needed to accomplish the task.
+ *
+ * <p>The APIs should not be called directly by the app developers. A higher level api
+ * which abstracts the hardware should be used instead. All the checks are done by the higher
+ * level public API. Any needed locking should be handled by the higher level API.
+ *
+ * <p> There are 3 states associated with a Geofence: Inside, Outside, Unknown.
+ * There are 3 transitions: {@link #GEOFENCE_ENTERED}, {@link #GEOFENCE_EXITED},
+ * {@link #GEOFENCE_UNCERTAIN}. The APIs only expose the transitions.
+ *
+ * <p> Inside state: The hardware subsystem is reasonably confident that the user is inside
+ * the geofence. Outside state: The hardware subsystem is reasonably confident that the user
+ * is outside the geofence Unknown state: Unknown state can be interpreted as a state in which the
+ * monitoring subsystem isn't confident enough that the user is either inside or
+ * outside the Geofence. If the accuracy does not improve for a sufficient period of time,
+ * the {@link #GEOFENCE_UNCERTAIN} transition would be triggered. If the accuracy improves later,
+ * an appropriate transition would be triggered. The "reasonably confident" parameter
+ * depends on the hardware system and the positioning algorithms used.
+ * For instance, {@link #MONITORING_TYPE_GPS_HARDWARE} uses 95% as a confidence level.
+ */
+public final class GeofenceHardware {
+    private IGeofenceHardware mService;
+
+    // Hardware systems that do geofence monitoring.
+    static final int NUM_MONITORS = 1;
+
+    /**
+     * Constant for geofence monitoring done by the GPS hardware.
+     */
+    public static final int MONITORING_TYPE_GPS_HARDWARE = 0;
+
+    /**
+     * Constant to indiciate that the monitoring system is currently
+     * available for monitoring geofences.
+     */
+    public static final int MONITOR_CURRENTLY_AVAILABLE = 0;
+
+    /**
+     * Constant to indiciate that the monitoring system is currently
+     * unavailable for monitoring geofences.
+     */
+    public static final int MONITOR_CURRENTLY_UNAVAILABLE = 1;
+
+    /**
+     * Constant to indiciate that the monitoring system is unsupported
+     * for hardware geofence monitoring.
+     */
+    public static final int MONITOR_UNSUPPORTED = 2;
+
+    // The following constants need to match geofence flags in gps.h
+    /**
+     * The constant to indicate that the user has entered the geofence.
+     */
+    public static final int GEOFENCE_ENTERED = 1<<0L;
+
+    /**
+     * The constant to indicate that the user has exited the geofence.
+     */
+    public static final int GEOFENCE_EXITED = 1<<1L;
+
+    /**
+     * The constant to indicate that the user is uncertain with respect to a
+     * geofence.                                                  nn
+     */
+    public static final int GEOFENCE_UNCERTAIN = 1<<2L;
+
+    /**
+     * The constant used to indicate success of the particular geofence call
+     */
+    public static final int GEOFENCE_SUCCESS = 0;
+
+    /**
+     * The constant used to indicate that too many geofences have been registered.
+     */
+    public static final int GEOFENCE_ERROR_TOO_MANY_GEOFENCES = 1;
+
+    /**
+     * The constant used to indicate that the geofence id already exists.
+     */
+    public static final int GEOFENCE_ERROR_ID_EXISTS  = 2;
+
+    /**
+     * The constant used to indicate that the geofence id is unknown.
+     */
+    public static final int GEOFENCE_ERROR_ID_UNKNOWN = 3;
+
+    /**
+     * The constant used to indicate that the transition requested for the geofence is invalid.
+     */
+    public static final int GEOFENCE_ERROR_INVALID_TRANSITION = 4;
+
+    /**
+     * The constant used to indicate that the geofence operation has failed.
+     */
+    public static final int GEOFENCE_FAILURE = 5;
+
+    static final int GPS_GEOFENCE_UNAVAILABLE = 1<<0L;
+    static final int GPS_GEOFENCE_AVAILABLE = 1<<1L;
+
+    private HashMap<GeofenceHardwareCallback, GeofenceHardwareCallbackWrapper>
+            mCallbacks = new HashMap<GeofenceHardwareCallback, GeofenceHardwareCallbackWrapper>();
+    /**
+     * @hide
+     */
+    public GeofenceHardware(IGeofenceHardware service) {
+        mService = service;
+    }
+
+    /**
+     * Returns all the hardware geofence monitoring systems and their status.
+     * Status can be one of {@link #MONITOR_CURRENTLY_AVAILABLE},
+     * {@link #MONITOR_CURRENTLY_UNAVAILABLE} or {@link #MONITOR_UNSUPPORTED}
+     *
+     * <p> Some supported hardware monitoring systems might not be available
+     * for monitoring geofences in certain scenarios. For example, when a user
+     * enters a building, the GPS hardware subsystem might not be able monitor
+     * geofences and will change from {@link #MONITOR_CURRENTLY_AVAILABLE} to
+     * {@link #MONITOR_CURRENTLY_UNAVAILABLE}.
+     *
+     * <p> Requires {@link android.Manifest.permission#LOCATION_HARDWARE} permission to access
+     * geofencing in hardware.
+     *
+     * @return An array indexed by the various monitoring types and their status.
+     *         An array of length 0 is returned in case of errors.
+     */
+    public int[] getMonitoringTypesAndStatus() {
+        try {
+            return mService.getMonitoringTypesAndStatus();
+        } catch (RemoteException e) {
+        }
+        return new int[0];
+    }
+
+    /**
+     * Creates a circular geofence which is monitored by subsystems in the hardware.
+     *
+     * <p> When the device detects that is has entered, exited or is uncertain
+     * about the area specified by the geofence, the given callback will be called.
+     *
+     * <p> The {@link GeofenceHardwareCallback#onGeofenceChange} callback will be called,
+     * with the following parameters
+     * <ul>
+     * <li> The geofence Id
+     * <li> The location object indicating the last known location.
+     * <li> The transition associated with the geofence. One of
+     *      {@link #GEOFENCE_ENTERED}, {@link #GEOFENCE_EXITED}, {@link #GEOFENCE_UNCERTAIN}
+     * <li> The timestamp when the geofence transition occured.
+     * <li> The monitoring type ({@link #MONITORING_TYPE_GPS_HARDWARE} is one such example)
+     *      that was used.
+     * </ul>
+     *
+     * <p> The geofence will be monitored by the subsystem specified by monitoring_type parameter.
+     * The application does not need to hold a wakelock when the monitoring
+     * is being done by the underlying hardware subsystem. If the same geofence Id is being
+     * monitored by two different monitoring systems, the same id can be used for both calls, as
+     * long as the same callback object is used.
+     *
+     * <p> Requires {@link android.Manifest.permission#ACCESS_FINE_LOCATION} permission when
+     * {@link #MONITORING_TYPE_GPS_HARDWARE} is used.
+     *
+     * <p> Requires {@link android.Manifest.permission#LOCATION_HARDWARE} permission to access
+     * geofencing in hardware.
+     *
+     * <p>This API should not be called directly by the app developers. A higher level api
+     * which abstracts the hardware should be used instead. All the checks are done by the higher
+     * level public API. Any needed locking should be handled by the higher level API.
+     *
+     * @param latitude Latitude of the area to be monitored.
+     * @param longitude Longitude of the area to be monitored.
+     * @param radius Radius (in meters) of the area to be monitored.
+     * @param lastTransition The current state of the geofence. Can be one of
+     *        {@link #GEOFENCE_ENTERED}, {@link #GEOFENCE_EXITED},
+     *        {@link #GEOFENCE_UNCERTAIN}.
+     * @param monitorTransitions Bitwise OR of {@link #GEOFENCE_ENTERED},
+     *        {@link #GEOFENCE_EXITED}, {@link #GEOFENCE_UNCERTAIN}
+     * @param notificationResponsivenes Defines the best-effort description
+     *        of how soon should the callback be called when the transition
+     *        associated with the Geofence is triggered. For instance, if
+     *        set to 1000 millseconds with {@link #GEOFENCE_ENTERED},
+     *        the callback will be called 1000 milliseconds within entering
+     *        the geofence. This parameter is defined in milliseconds.
+     * @param unknownTimer The time limit after which the
+     *        {@link #GEOFENCE_UNCERTAIN} transition
+     *        should be triggered. This paramter is defined in milliseconds.
+     * @param monitoringType The type of the hardware subsystem that should be used
+     *        to monitor the geofence.
+     * @param callback {@link GeofenceHardwareCallback} that will be use to notify the
+     *        transition.
+     * @return true on success.
+     */
+    public boolean addCircularFence(int geofenceId, double latitude, double longitude,
+            double radius, int lastTransition,int monitorTransitions, int notificationResponsivenes,
+            int unknownTimer, int monitoringType, GeofenceHardwareCallback callback) {
+        try {
+            return mService.addCircularFence(geofenceId, latitude, longitude, radius,
+                    lastTransition, monitorTransitions, notificationResponsivenes, unknownTimer,
+                    monitoringType, getCallbackWrapper(callback));
+        } catch (RemoteException e) {
+        }
+        return false;
+    }
+
+    /**
+     * Removes a geofence added by {@link #addCircularFence} call.
+     *
+     * <p> Requires {@link android.Manifest.permission#ACCESS_FINE_LOCATION} permission when
+     * {@link #MONITORING_TYPE_GPS_HARDWARE} is used.
+     *
+     * <p> Requires {@link android.Manifest.permission#LOCATION_HARDWARE} permission to access
+     * geofencing in hardware.
+     *
+     * <p>This API should not be called directly by the app developers. A higher level api
+     * which abstracts the hardware should be used instead. All the checks are done by the higher
+     * level public API. Any needed locking should be handled by the higher level API.
+     *
+     * @param geofenceId The id of the geofence.
+     * @param monitoringType The type of the hardware subsystem that should be used
+     *        to monitor the geofence.
+     * @return true on success.
+     */
+   public boolean removeGeofence(int geofenceId, int monitoringType) {
+       try {
+           return mService.removeGeofence(geofenceId, monitoringType);
+       } catch (RemoteException e) {
+       }
+       return false;
+   }
+
+    /**
+     * Pauses the monitoring of a geofence added by {@link #addCircularFence} call.
+     *
+     * <p> Requires {@link android.Manifest.permission#ACCESS_FINE_LOCATION} permission when
+     * {@link #MONITORING_TYPE_GPS_HARDWARE} is used.
+     *
+     * <p> Requires {@link android.Manifest.permission#LOCATION_HARDWARE} permission to access
+     * geofencing in hardware.
+     *
+     * <p>This API should not be called directly by the app developers. A higher level api
+     * which abstracts the hardware should be used instead. All the checks are done by the higher
+     * level public API. Any needed locking should be handled by the higher level API.
+     *
+     * @param geofenceId The id of the geofence.
+     * @param monitoringType The type of the hardware subsystem that should be used
+     *        to monitor the geofence.
+     * @return true on success.
+     */
+    public boolean pauseGeofence(int geofenceId, int monitoringType) {
+        try {
+            return mService.pauseGeofence(geofenceId, monitoringType);
+        } catch (RemoteException e) {
+        }
+        return false;
+    }
+
+    /**
+     * Resumes the monitoring of a geofence added by {@link #pauseGeofence} call.
+     *
+     * <p> Requires {@link android.Manifest.permission#ACCESS_FINE_LOCATION} permission when
+     * {@link #MONITORING_TYPE_GPS_HARDWARE} is used.
+     *
+     * <p> Requires {@link android.Manifest.permission#LOCATION_HARDWARE} permission to access
+     * geofencing in hardware.
+     *
+     * <p>This API should not be called directly by the app developers. A higher level api
+     * which abstracts the hardware should be used instead. All the checks are done by the higher
+     * level public API. Any needed locking should be handled by the higher level API.
+     *
+     * @param geofenceId The id of the geofence.
+     * @param monitorTransition Bitwise OR of {@link #GEOFENCE_ENTERED},
+     *        {@link #GEOFENCE_EXITED}, {@link #GEOFENCE_UNCERTAIN}
+     * @param monitoringType The type of the hardware subsystem that should be used
+     *        to monitor the geofence.
+     * @return true on success.
+     */
+    public boolean resumeGeofence(int geofenceId, int monitorTransition, int monitoringType) {
+        try {
+            return mService.resumeGeofence(geofenceId, monitorTransition, monitoringType);
+        } catch (RemoteException e) {
+        }
+        return false;
+    }
+
+    /**
+     * Register the callback to be notified when the state of a hardware geofence
+     * monitoring system changes. For instance, it can change from
+     * {@link #MONITOR_CURRENTLY_AVAILABLE} to {@link #MONITOR_CURRENTLY_UNAVAILABLE}
+     *
+     * <p> Requires {@link android.Manifest.permission#ACCESS_FINE_LOCATION} permission when
+     * {@link #MONITORING_TYPE_GPS_HARDWARE} is used.
+     *
+     * <p> Requires {@link android.Manifest.permission#LOCATION_HARDWARE} permission to access
+     * geofencing in hardware.
+     *
+     * <p>This API should not be called directly by the app developers. A higher level api
+     * which abstracts the hardware should be used instead. All the checks are done by the higher
+     * level public API. Any needed locking should be handled by the higher level API.
+     *
+     * <p> The same callback object can be used to be informed of geofence transitions
+     * and state changes of the underlying hardware subsystem.
+     *
+     * @param monitoringType Type of the monitor
+     * @param callback Callback that will be called.
+     * @return true on success
+     */
+    public boolean registerForMonitorStateChangeCallback(int monitoringType,
+            GeofenceHardwareCallback callback) {
+        try {
+            return mService.registerForMonitorStateChangeCallback(monitoringType,
+                    getCallbackWrapper(callback));
+        } catch (RemoteException e) {
+        }
+        return false;
+    }
+
+    /**
+     * Unregister the callback that was used with {@link #registerForMonitorStateChangeCallback}
+     * to notify when the state of the hardware geofence monitoring system changes.
+     *
+     * <p> Requires {@link android.Manifest.permission#ACCESS_FINE_LOCATION} permission when
+     * {@link #MONITORING_TYPE_GPS_HARDWARE} is used.
+     *
+     * <p> Requires {@link android.Manifest.permission#LOCATION_HARDWARE} permission to access
+     * geofencing in hardware.
+     *
+     * <p>This API should not be called directly by the app developers. A higher level api
+     * which abstracts the hardware should be used instead. All the checks are done by the higher
+     * level public API. Any needed locking should be handled by the higher level API.
+     *
+     * @param monitoringType Type of the monitor
+     * @param callback Callback that will be called.
+     * @return true on success
+     */
+    public boolean unregisterForMonitorStateChangeCallback(int monitoringType,
+            GeofenceHardwareCallback callback) {
+        boolean  result = false;
+        try {
+            result = mService.unregisterForMonitorStateChangeCallback(monitoringType,
+                    getCallbackWrapper(callback));
+            if (result) removeCallback(callback);
+
+        } catch (RemoteException e) {
+        }
+        return result;
+    }
+
+
+    private void removeCallback(GeofenceHardwareCallback callback) {
+        synchronized (mCallbacks) {
+            mCallbacks.remove(callback);
+        }
+    }
+
+    private GeofenceHardwareCallbackWrapper getCallbackWrapper(GeofenceHardwareCallback callback) {
+        synchronized (mCallbacks) {
+            GeofenceHardwareCallbackWrapper wrapper = mCallbacks.get(callback);
+            if (wrapper == null) {
+                wrapper = new GeofenceHardwareCallbackWrapper(callback);
+                mCallbacks.put(callback, wrapper);
+            }
+            return wrapper;
+        }
+    }
+
+    class GeofenceHardwareCallbackWrapper extends IGeofenceHardwareCallback.Stub {
+        private WeakReference<GeofenceHardwareCallback> mCallback;
+
+        GeofenceHardwareCallbackWrapper(GeofenceHardwareCallback c) {
+            mCallback = new WeakReference<GeofenceHardwareCallback>(c);
+        }
+
+        public void onMonitoringSystemChange(int monitoringType, boolean available,
+                Location location) {
+            GeofenceHardwareCallback c = mCallback.get();
+            if (c != null) c.onMonitoringSystemChange(monitoringType, available, location);
+        }
+
+        public void onGeofenceChange(int geofenceId, int transition, Location location,
+                long timestamp, int monitoringType) {
+            GeofenceHardwareCallback c = mCallback.get();
+            if (c != null) {
+                c.onGeofenceChange(geofenceId, transition, location, timestamp,
+                        monitoringType);
+            }
+        }
+
+        public void onGeofenceAdd(int geofenceId, int status) {
+            GeofenceHardwareCallback c = mCallback.get();
+            if (c != null) c.onGeofenceAdd(geofenceId, status);
+        }
+
+        public void onGeofenceRemove(int geofenceId, int status) {
+            GeofenceHardwareCallback c = mCallback.get();
+            if (c != null) {
+                c.onGeofenceRemove(geofenceId, status);
+                removeCallback(c);
+            }
+        }
+
+        public void onGeofencePause(int geofenceId, int status) {
+            GeofenceHardwareCallback c = mCallback.get();
+            if (c != null) c.onGeofencePause(geofenceId, status);
+        }
+
+        public void onGeofenceResume(int geofenceId, int status) {
+            GeofenceHardwareCallback c = mCallback.get();
+            if (c != null) c.onGeofenceResume(geofenceId, status);
+        }
+    }
+}
diff --git a/core/java/android/hardware/location/GeofenceHardwareCallback.java b/core/java/android/hardware/location/GeofenceHardwareCallback.java
new file mode 100644
index 0000000..8ab582a
--- /dev/null
+++ b/core/java/android/hardware/location/GeofenceHardwareCallback.java
@@ -0,0 +1,100 @@
+/*
+ * 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 android.hardware.location;
+
+import android.location.Location;
+
+/**
+ * The callback class associated with the APIs in {@link GeofenceHardware}
+ */
+public abstract class GeofenceHardwareCallback {
+
+    /**
+     * The callback called when the state of a monitoring system changes.
+     * {@link GeofenceHardware#MONITORING_TYPE_GPS_HARDWARE} is an example of a
+     * monitoring system.
+     *
+     * @param monitoringType The type of the monitoring system.
+     * @param available Indicates whether the system is currently available or not.
+     * @param location The last known location according to the monitoring system.
+     */
+    public void onMonitoringSystemChange(int monitoringType, boolean available, Location location) {
+    }
+
+    /**
+     * The callback called when there is a transition to report for the specific
+     * geofence.
+     *
+     * @param geofenceId The geofence ID of the geofence
+     * @param transition One of {@link GeofenceHardware#GEOFENCE_ENTERED},
+     *        {@link GeofenceHardware#GEOFENCE_EXITED}, {@link GeofenceHardware#GEOFENCE_UNCERTAIN}
+     * @param location The last known location according to the monitoring system.
+     * @param timestamp The timestamp (elapsed real time in milliseconds) when the transition was
+     *        detected
+     * @param monitoringType Type of the monitoring system.
+     */
+    public void onGeofenceChange(int geofenceId, int transition, Location location,
+            long timestamp, int monitoringType) {
+    }
+
+    /**
+     * The callback called to notify the success or failure of the add call.
+     *
+     * @param geofenceId The ID of the geofence.
+     * @param status One of {@link GeofenceHardware#GEOFENCE_SUCCESS},
+     *        {@link GeofenceHardware#GEOFENCE_ERROR_ID_EXISTS},
+     *        {@link GeofenceHardware#GEOFENCE_ERROR_INVALID_TRANSITION},
+     *        {@link GeofenceHardware#GEOFENCE_ERROR_TOO_MANY_GEOFENCES},
+     *        {@link GeofenceHardware#GEOFENCE_FAILURE}
+     */
+    public void onGeofenceAdd(int geofenceId, int status) {
+    }
+
+    /**
+     * The callback called to notify the success or failure of the remove call.
+     *
+     * @param geofenceId The ID of the geofence.
+     * @param status  One of {@link GeofenceHardware#GEOFENCE_SUCCESS},
+     *        {@link GeofenceHardware#GEOFENCE_ERROR_ID_UNKNOWN},
+     *        {@link GeofenceHardware#GEOFENCE_FAILURE}
+     */
+    public void onGeofenceRemove(int geofenceId, int status) {
+    }
+
+    /**
+     * The callback called to notify the success or failure of the pause call.
+     *
+     * @param geofenceId The ID of the geofence.
+     * @param status One of {@link GeofenceHardware#GEOFENCE_SUCCESS},
+     *        {@link GeofenceHardware#GEOFENCE_ERROR_ID_UNKNOWN},
+     *        {@link GeofenceHardware#GEOFENCE_FAILURE}
+     */
+    public void onGeofencePause(int geofenceId, int status) {
+    }
+
+    /**
+     * The callback called to notify the success or failure of the resume call.
+     *
+     * @param geofenceId The ID of the geofence.
+     * @param status One of {@link GeofenceHardware#GEOFENCE_SUCCESS},
+     *        {@link GeofenceHardware#GEOFENCE_ERROR_ID_UNKNOWN},
+     *        {@link GeofenceHardware#GEOFENCE_ERROR_INVALID_TRANSITION},
+     *        {@link GeofenceHardware#GEOFENCE_FAILURE}
+     */
+    public void onGeofenceResume(int geofenceId, int status) {
+    }
+}
diff --git a/core/java/android/hardware/location/GeofenceHardwareImpl.java b/core/java/android/hardware/location/GeofenceHardwareImpl.java
new file mode 100644
index 0000000..21f1ea6
--- /dev/null
+++ b/core/java/android/hardware/location/GeofenceHardwareImpl.java
@@ -0,0 +1,599 @@
+/*
+ * 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 android.hardware.location;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.location.IGpsGeofenceHardware;
+import android.location.Location;
+import android.location.LocationManager;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.os.PowerManager;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.SystemClock;
+import android.util.Log;
+import android.util.SparseArray;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+
+/**
+ * This class manages the geofences which are handled by hardware.
+ *
+ * @hide
+ */
+public final class GeofenceHardwareImpl {
+    private static final String TAG = "GeofenceHardwareImpl";
+    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+
+    private final Context mContext;
+    private static GeofenceHardwareImpl sInstance;
+    private PowerManager.WakeLock mWakeLock;
+    private SparseArray<IGeofenceHardwareCallback> mGeofences =
+            new SparseArray<IGeofenceHardwareCallback>();
+    private ArrayList<IGeofenceHardwareCallback>[] mCallbacks =
+            new ArrayList[GeofenceHardware.NUM_MONITORS];
+
+    private IGpsGeofenceHardware mGpsService;
+
+    private int[] mSupportedMonitorTypes = new int[GeofenceHardware.NUM_MONITORS];
+
+    // mGeofenceHandler message types
+    private static final int GEOFENCE_TRANSITION_CALLBACK = 1;
+    private static final int ADD_GEOFENCE_CALLBACK = 2;
+    private static final int REMOVE_GEOFENCE_CALLBACK = 3;
+    private static final int PAUSE_GEOFENCE_CALLBACK = 4;
+    private static final int RESUME_GEOFENCE_CALLBACK = 5;
+    private static final int ADD_GEOFENCE = 6;
+    private static final int REMOVE_GEOFENCE = 7;
+
+    // mCallbacksHandler message types
+    private static final int GPS_GEOFENCE_STATUS = 1;
+    private static final int CALLBACK_ADD = 2;
+    private static final int CALLBACK_REMOVE = 3;
+
+    // The following constants need to match GpsLocationFlags enum in gps.h
+    private static final int LOCATION_INVALID = 0;
+    private static final int LOCATION_HAS_LAT_LONG = 1;
+    private static final int LOCATION_HAS_ALTITUDE = 2;
+    private static final int LOCATION_HAS_SPEED = 4;
+    private static final int LOCATION_HAS_BEARING = 8;
+    private static final int LOCATION_HAS_ACCURACY = 16;
+
+    // Resolution level constants used for permission checks.
+    // These constants must be in increasing order of finer resolution.
+    private static final int RESOLUTION_LEVEL_NONE = 1;
+    private static final int RESOLUTION_LEVEL_COARSE = 2;
+    private static final int RESOLUTION_LEVEL_FINE = 3;
+
+    // GPS Geofence errors. Should match gps.h constants.
+    private static final int GPS_GEOFENCE_OPERATION_SUCCESS = 0;
+    private static final int GPS_GEOFENCE_ERROR_TOO_MANY_GEOFENCES = 100;
+    private static final int GPS_GEOFENCE_ERROR_ID_EXISTS  = -101;
+    private static final int GPS_GEOFENCE_ERROR_ID_UNKNOWN = -102;
+    private static final int GPS_GEOFENCE_ERROR_INVALID_TRANSITION = -103;
+    private static final int GPS_GEOFENCE_ERROR_GENERIC = -149;
+
+
+
+    public synchronized static GeofenceHardwareImpl getInstance(Context context) {
+        if (sInstance == null) {
+            sInstance = new GeofenceHardwareImpl(context);
+        }
+        return sInstance;
+    }
+
+    private GeofenceHardwareImpl(Context context) {
+        mContext = context;
+        // Init everything to unsupported.
+        setMonitorAvailability(GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE,
+                GeofenceHardware.MONITOR_UNSUPPORTED);
+
+    }
+
+    private void acquireWakeLock() {
+        if (mWakeLock == null) {
+            PowerManager powerManager =
+                    (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
+            mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
+        }
+        mWakeLock.acquire();
+    }
+
+    private void releaseWakeLock() {
+        if (mWakeLock.isHeld()) mWakeLock.release();
+    }
+
+    private void updateGpsHardwareAvailability() {
+        //Check which monitors are available.
+        boolean gpsSupported;
+        try {
+            gpsSupported = mGpsService.isHardwareGeofenceSupported();
+        } catch (RemoteException e) {
+            Log.e(TAG, "Remote Exception calling LocationManagerService");
+            gpsSupported = false;
+        }
+
+        if (gpsSupported) {
+            // Its assumed currently available at startup.
+            // native layer will update later.
+            setMonitorAvailability(GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE,
+                    GeofenceHardware.MONITOR_CURRENTLY_AVAILABLE);
+        }
+    }
+
+    public void setGpsHardwareGeofence(IGpsGeofenceHardware service) {
+        if (mGpsService == null) {
+            mGpsService = service;
+            updateGpsHardwareAvailability();
+        } else if (service == null) {
+            mGpsService = null;
+            Log.w(TAG, "GPS Geofence Hardware service seems to have crashed");
+        } else {
+            Log.e(TAG, "Error: GpsService being set again.");
+        }
+    }
+
+    public int[] getMonitoringTypesAndStatus() {
+        synchronized (mSupportedMonitorTypes) {
+            return mSupportedMonitorTypes;
+        }
+    }
+
+    public boolean addCircularFence(int geofenceId, double latitude, double longitude,
+            double radius, int lastTransition,int monitorTransitions, int notificationResponsivenes,
+            int unknownTimer, int monitoringType, IGeofenceHardwareCallback callback) {
+        // This API is not thread safe. Operations on the same geofence need to be serialized
+        // by upper layers
+        if (DEBUG) {
+            Log.d(TAG, "addCircularFence: GeofenceId: " + geofenceId + "Latitude: " + latitude +
+                    "Longitude: " + longitude + "Radius: " + radius + "LastTransition: "
+                    + lastTransition + "MonitorTransition: " + monitorTransitions +
+                    "NotificationResponsiveness: " + notificationResponsivenes +
+                    "UnKnown Timer: " + unknownTimer + "MonitoringType: " + monitoringType);
+
+        }
+        boolean result;
+        Message m = mGeofenceHandler.obtainMessage(ADD_GEOFENCE, callback);
+        m.arg1 = geofenceId;
+        mGeofenceHandler.sendMessage(m);
+
+        switch (monitoringType) {
+            case GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE:
+                if (mGpsService == null) return false;
+                try {
+                    result = mGpsService.addCircularHardwareGeofence(geofenceId, latitude,
+                            longitude, radius, lastTransition, monitorTransitions,
+                            notificationResponsivenes, unknownTimer);
+                } catch (RemoteException e) {
+                    Log.e(TAG, "AddGeofence: Remote Exception calling LocationManagerService");
+                    result = false;
+                }
+                break;
+            default:
+                result = false;
+        }
+        if (!result) {
+            m = mGeofenceHandler.obtainMessage(REMOVE_GEOFENCE);
+            m.arg1 = geofenceId;
+            mGeofenceHandler.sendMessage(m);
+        }
+
+        if (DEBUG) Log.d(TAG, "addCircularFence: Result is: " + result);
+        return result;
+    }
+
+    public boolean removeGeofence(int geofenceId, int monitoringType) {
+        // This API is not thread safe. Operations on the same geofence need to be serialized
+        // by upper layers
+        if (DEBUG) Log.d(TAG, "Remove Geofence: GeofenceId: " + geofenceId);
+        boolean result = false;
+        switch (monitoringType) {
+            case GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE:
+                if (mGpsService == null) return false;
+                try {
+                    result = mGpsService.removeHardwareGeofence(geofenceId);
+                } catch (RemoteException e) {
+                    Log.e(TAG, "RemoveGeofence: Remote Exception calling LocationManagerService");
+                    result = false;
+                }
+                break;
+            default:
+                result = false;
+        }
+        if (DEBUG) Log.d(TAG, "removeGeofence: Result is: " + result);
+        return result;
+    }
+
+    public boolean pauseGeofence(int geofenceId, int monitoringType) {
+        // This API is not thread safe. Operations on the same geofence need to be serialized
+        // by upper layers
+        if (DEBUG) Log.d(TAG, "Pause Geofence: GeofenceId: " + geofenceId);
+        boolean result;
+        switch (monitoringType) {
+            case GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE:
+                if (mGpsService == null) return false;
+                try {
+                    result = mGpsService.pauseHardwareGeofence(geofenceId);
+                } catch (RemoteException e) {
+                    Log.e(TAG, "PauseGeofence: Remote Exception calling LocationManagerService");
+                    result = false;
+                }
+                break;
+            default:
+                result = false;
+        }
+        if (DEBUG) Log.d(TAG, "pauseGeofence: Result is: " + result);
+        return result;
+    }
+
+
+    public boolean resumeGeofence(int geofenceId, int monitorTransition, int monitoringType) {
+        // This API is not thread safe. Operations on the same geofence need to be serialized
+        // by upper layers
+        if (DEBUG) Log.d(TAG, "Resume Geofence: GeofenceId: " + geofenceId);
+        boolean result;
+        switch (monitoringType) {
+            case GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE:
+                if (mGpsService == null) return false;
+                try {
+                    result = mGpsService.resumeHardwareGeofence(geofenceId, monitorTransition);
+                } catch (RemoteException e) {
+                    Log.e(TAG, "ResumeGeofence: Remote Exception calling LocationManagerService");
+                    result = false;
+                }
+                break;
+            default:
+                result = false;
+        }
+        if (DEBUG) Log.d(TAG, "resumeGeofence: Result is: " + result);
+        return result;
+    }
+
+    public boolean registerForMonitorStateChangeCallback(int monitoringType,
+            IGeofenceHardwareCallback callback) {
+        Message m = mCallbacksHandler.obtainMessage(CALLBACK_ADD, callback);
+        m.arg1 = monitoringType;
+        mCallbacksHandler.sendMessage(m);
+        return true;
+    }
+
+    public boolean unregisterForMonitorStateChangeCallback(int monitoringType,
+            IGeofenceHardwareCallback callback) {
+        Message m = mCallbacksHandler.obtainMessage(CALLBACK_REMOVE, callback);
+        m.arg1 = monitoringType;
+        mCallbacksHandler.sendMessage(m);
+        return true;
+    }
+
+    private Location getLocation(int flags, double latitude,
+            double longitude, double altitude, float speed, float bearing, float accuracy,
+            long timestamp) {
+        if (DEBUG) Log.d(TAG, "GetLocation: " + flags + ":" + latitude);
+        Location location = new Location(LocationManager.GPS_PROVIDER);
+        if ((flags & LOCATION_HAS_LAT_LONG) == LOCATION_HAS_LAT_LONG) {
+            location.setLatitude(latitude);
+            location.setLongitude(longitude);
+            location.setTime(timestamp);
+            // It would be nice to push the elapsed real-time timestamp
+            // further down the stack, but this is still useful
+            location.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos());
+        }
+        if ((flags & LOCATION_HAS_ALTITUDE) == LOCATION_HAS_ALTITUDE) {
+            location.setAltitude(altitude);
+        } else {
+            location.removeAltitude();
+        }
+        if ((flags & LOCATION_HAS_SPEED) == LOCATION_HAS_SPEED) {
+            location.setSpeed(speed);
+        } else {
+            location.removeSpeed();
+        }
+        if ((flags & LOCATION_HAS_BEARING) == LOCATION_HAS_BEARING) {
+            location.setBearing(bearing);
+        } else {
+            location.removeBearing();
+        }
+        if ((flags & LOCATION_HAS_ACCURACY) == LOCATION_HAS_ACCURACY) {
+            location.setAccuracy(accuracy);
+        } else {
+            location.removeAccuracy();
+        }
+        return location;
+    }
+
+    /**
+     * called from GpsLocationProvider to report geofence transition
+     */
+    public void reportGpsGeofenceTransition(int geofenceId, int flags, double latitude,
+            double longitude, double altitude, float speed, float bearing, float accuracy,
+            long timestamp, int transition, long transitionTimestamp) {
+        if (DEBUG) Log.d(TAG, "GeofenceTransition: Flags: " + flags + " Lat: " + latitude +
+            " Long: " + longitude + " Altitude: " + altitude + " Speed: " + speed + " Bearing: " +
+            bearing + " Accuracy: " + accuracy + " Timestamp: " + timestamp + " Transition: " +
+            transition + " TransitionTimestamp: " + transitionTimestamp);
+        Location location = getLocation(flags, latitude, longitude, altitude, speed, bearing,
+                accuracy, timestamp);
+        GeofenceTransition t = new GeofenceTransition(geofenceId, transition, timestamp, location);
+        acquireWakeLock();
+        Message m = mGeofenceHandler.obtainMessage(GEOFENCE_TRANSITION_CALLBACK, t);
+        mGeofenceHandler.sendMessage(m);
+    }
+
+    /**
+     * called from GpsLocationProvider to report GPS status change.
+     */
+    public void reportGpsGeofenceStatus(int status, int flags, double latitude,
+            double longitude, double altitude, float speed, float bearing, float accuracy,
+            long timestamp) {
+        Location location = getLocation(flags, latitude, longitude, altitude, speed, bearing,
+                accuracy, timestamp);
+        boolean available = false;
+        if (status == GeofenceHardware.GPS_GEOFENCE_AVAILABLE) available = true;
+
+        int val = (available ? GeofenceHardware.MONITOR_CURRENTLY_UNAVAILABLE :
+                GeofenceHardware.MONITOR_CURRENTLY_AVAILABLE);
+        setMonitorAvailability(GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE, val);
+
+        acquireWakeLock();
+        Message m = mCallbacksHandler.obtainMessage(GPS_GEOFENCE_STATUS, location);
+        m.arg1 = val;
+        mCallbacksHandler.sendMessage(m);
+    }
+
+    /**
+     * called from GpsLocationProvider add geofence callback.
+     */
+    public void reportGpsGeofenceAddStatus(int geofenceId, int status) {
+        if (DEBUG) Log.d(TAG, "Add Callback: GPS : Id: " + geofenceId + " Status: " + status);
+        acquireWakeLock();
+        Message m = mGeofenceHandler.obtainMessage(ADD_GEOFENCE_CALLBACK);
+        m.arg1 = geofenceId;
+        m.arg2 = getGeofenceStatus(status);
+        mGeofenceHandler.sendMessage(m);
+    }
+
+    /**
+     * called from GpsLocationProvider remove geofence callback.
+     */
+    public void reportGpsGeofenceRemoveStatus(int geofenceId, int status) {
+        if (DEBUG) Log.d(TAG, "Remove Callback: GPS : Id: " + geofenceId + " Status: " + status);
+        acquireWakeLock();
+        Message m = mGeofenceHandler.obtainMessage(REMOVE_GEOFENCE_CALLBACK);
+        m.arg1 = geofenceId;
+        m.arg2 = getGeofenceStatus(status);
+        mGeofenceHandler.sendMessage(m);
+    }
+
+    /**
+     * called from GpsLocationProvider pause geofence callback.
+     */
+    public void reportGpsGeofencePauseStatus(int geofenceId, int status) {
+        if (DEBUG) Log.d(TAG, "Pause Callback: GPS : Id: " + geofenceId + " Status: " + status);
+        acquireWakeLock();
+        Message m = mGeofenceHandler.obtainMessage(PAUSE_GEOFENCE_CALLBACK);
+        m.arg1 = geofenceId;
+        m.arg2 = getGeofenceStatus(status);
+        mGeofenceHandler.sendMessage(m);
+    }
+
+    /**
+     * called from GpsLocationProvider resume geofence callback.
+     */
+    public void reportGpsGeofenceResumeStatus(int geofenceId, int status) {
+        if (DEBUG) Log.d(TAG, "Resume Callback: GPS : Id: " + geofenceId + " Status: " + status);
+        acquireWakeLock();
+        Message m = mGeofenceHandler.obtainMessage(RESUME_GEOFENCE_CALLBACK);
+        m.arg1 = geofenceId;
+        m.arg2 = getGeofenceStatus(status);
+        mGeofenceHandler.sendMessage(m);
+    }
+
+    // All operations on mGeofences
+    private Handler mGeofenceHandler = new Handler() {
+        @Override
+        public void handleMessage(Message msg) {
+            int geofenceId;
+            int status;
+            IGeofenceHardwareCallback callback;
+            switch (msg.what) {
+                case ADD_GEOFENCE:
+                    geofenceId = msg.arg1;
+                    callback = (IGeofenceHardwareCallback) msg.obj;
+                    mGeofences.put(geofenceId, callback);
+                    break;
+                case REMOVE_GEOFENCE:
+                    geofenceId = msg.arg1;
+                    mGeofences.remove(geofenceId);
+                    break;
+                case ADD_GEOFENCE_CALLBACK:
+                    geofenceId = msg.arg1;
+                    callback = mGeofences.get(geofenceId);
+                    if (callback == null) return;
+
+                    try {
+                        callback.onGeofenceAdd(geofenceId, msg.arg2);
+                    } catch (RemoteException e) {Log.i(TAG, "Remote Exception:" + e);}
+                    releaseWakeLock();
+                    break;
+                case REMOVE_GEOFENCE_CALLBACK:
+                    geofenceId = msg.arg1;
+                    callback = mGeofences.get(geofenceId);
+                    if (callback == null) return;
+
+                    try {
+                        callback.onGeofenceRemove(geofenceId, msg.arg2);
+                    } catch (RemoteException e) {}
+                    mGeofences.remove(geofenceId);
+                    releaseWakeLock();
+                    break;
+
+                case PAUSE_GEOFENCE_CALLBACK:
+                    geofenceId = msg.arg1;
+                    callback = mGeofences.get(geofenceId);
+                    if (callback == null) return;
+
+                    try {
+                        callback.onGeofencePause(geofenceId, msg.arg2);
+                    } catch (RemoteException e) {}
+                    releaseWakeLock();
+                    break;
+
+                case RESUME_GEOFENCE_CALLBACK:
+                    geofenceId = msg.arg1;
+                    callback = mGeofences.get(geofenceId);
+                    if (callback == null) return;
+
+                    try {
+                        callback.onGeofenceResume(geofenceId, msg.arg2);
+                    } catch (RemoteException e) {}
+                    releaseWakeLock();
+                    break;
+
+                case GEOFENCE_TRANSITION_CALLBACK:
+                    GeofenceTransition geofenceTransition = (GeofenceTransition)(msg.obj);
+                    callback = mGeofences.get(geofenceTransition.mGeofenceId);
+
+                    if (DEBUG) Log.d(TAG, "GeofenceTransistionCallback: GPS : GeofenceId: " +
+                            geofenceTransition.mGeofenceId +
+                            "Transition: " + geofenceTransition.mTransition +
+                            "Location: " + geofenceTransition.mLocation + ":" + mGeofences);
+
+                    try {
+                        callback.onGeofenceChange(
+                                geofenceTransition.mGeofenceId, geofenceTransition.mTransition,
+                                geofenceTransition.mLocation, geofenceTransition.mTimestamp,
+                                GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE);
+                    } catch (RemoteException e) {}
+                    releaseWakeLock();
+                    break;
+            }
+        }
+    };
+
+    // All operations on mCallbacks
+    private Handler mCallbacksHandler = new Handler() {
+        @Override
+        public void handleMessage(Message msg) {
+            int monitoringType;
+            ArrayList<IGeofenceHardwareCallback> callbackList;
+            IGeofenceHardwareCallback callback;
+
+            switch (msg.what) {
+                case GPS_GEOFENCE_STATUS:
+                    Location location = (Location) msg.obj;
+                    int val = msg.arg1;
+                    boolean available;
+                    available = (val == GeofenceHardware.MONITOR_CURRENTLY_AVAILABLE ?
+                            true : false);
+                    callbackList = mCallbacks[GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE];
+                    if (callbackList == null) return;
+
+                    if (DEBUG) Log.d(TAG, "MonitoringSystemChangeCallback: GPS : " + available);
+
+                    for (IGeofenceHardwareCallback c: callbackList) {
+                        try {
+                            c.onMonitoringSystemChange(
+                                    GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE, available,
+                                    location);
+                        } catch (RemoteException e) {}
+                    }
+                    releaseWakeLock();
+                    break;
+                case CALLBACK_ADD:
+                    monitoringType = msg.arg1;
+                    callback = (IGeofenceHardwareCallback) msg.obj;
+                    callbackList = mCallbacks[monitoringType];
+                    if (callbackList == null) {
+                        callbackList = new ArrayList<IGeofenceHardwareCallback>();
+                        mCallbacks[monitoringType] = callbackList;
+                    }
+                    if (!callbackList.contains(callback)) callbackList.add(callback);
+                    break;
+                case CALLBACK_REMOVE:
+                    monitoringType = msg.arg1;
+                    callback = (IGeofenceHardwareCallback) msg.obj;
+                    callbackList = mCallbacks[monitoringType];
+                    if (callbackList != null) {
+                        callbackList.remove(callback);
+                    }
+                    break;
+            }
+        }
+    };
+
+    private class GeofenceTransition {
+        private int mGeofenceId, mTransition;
+        private long mTimestamp;
+        private Location mLocation;
+
+        GeofenceTransition(int geofenceId, int transition, long timestamp, Location location) {
+            mGeofenceId = geofenceId;
+            mTransition = transition;
+            mTimestamp = timestamp;
+            mLocation = location;
+        }
+    }
+
+    private void setMonitorAvailability(int monitor, int val) {
+        synchronized (mSupportedMonitorTypes) {
+            mSupportedMonitorTypes[monitor] = val;
+        }
+    }
+
+
+    int getMonitoringResolutionLevel(int monitoringType) {
+        switch (monitoringType) {
+            case GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE:
+                return RESOLUTION_LEVEL_FINE;
+        }
+        return RESOLUTION_LEVEL_NONE;
+    }
+
+    int getAllowedResolutionLevel(int pid, int uid) {
+        if (mContext.checkPermission(android.Manifest.permission.ACCESS_FINE_LOCATION,
+                pid, uid) == PackageManager.PERMISSION_GRANTED) {
+            return RESOLUTION_LEVEL_FINE;
+        } else if (mContext.checkPermission(android.Manifest.permission.ACCESS_COARSE_LOCATION,
+                pid, uid) == PackageManager.PERMISSION_GRANTED) {
+            return RESOLUTION_LEVEL_COARSE;
+        } else {
+            return RESOLUTION_LEVEL_NONE;
+        }
+    }
+
+    private int getGeofenceStatus(int status) {
+        switch (status) {
+            case GPS_GEOFENCE_OPERATION_SUCCESS:
+                return GeofenceHardware.GEOFENCE_SUCCESS;
+            case GPS_GEOFENCE_ERROR_GENERIC:
+                return GeofenceHardware.GEOFENCE_FAILURE;
+            case GPS_GEOFENCE_ERROR_ID_EXISTS:
+                return GeofenceHardware.GEOFENCE_ERROR_ID_EXISTS;
+            case GPS_GEOFENCE_ERROR_INVALID_TRANSITION:
+                return GeofenceHardware.GEOFENCE_ERROR_INVALID_TRANSITION;
+            case GPS_GEOFENCE_ERROR_TOO_MANY_GEOFENCES:
+                return GeofenceHardware.GEOFENCE_ERROR_TOO_MANY_GEOFENCES;
+            case GPS_GEOFENCE_ERROR_ID_UNKNOWN:
+                return GeofenceHardware.GEOFENCE_ERROR_ID_UNKNOWN;
+        }
+        return -1;
+    }
+}
diff --git a/core/java/android/hardware/location/GeofenceHardwareService.java b/core/java/android/hardware/location/GeofenceHardwareService.java
new file mode 100644
index 0000000..0eccee6
--- /dev/null
+++ b/core/java/android/hardware/location/GeofenceHardwareService.java
@@ -0,0 +1,134 @@
+/*
+ * 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 android.hardware.location;
+
+import android.Manifest;
+import android.app.Service;
+import android.content.Context;
+import android.content.Intent;
+import android.location.IGpsGeofenceHardware;
+import android.os.Binder;
+import android.os.IBinder;
+
+/**
+ * Service that handles hardware geofencing.
+ *
+ * @hide
+ */
+public class GeofenceHardwareService extends Service {
+    private GeofenceHardwareImpl mGeofenceHardwareImpl;
+    private Context mContext;
+
+    @Override
+    public void onCreate() {
+        mContext = this;
+        mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
+    }
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        return mBinder;
+    }
+
+    @Override
+    public boolean onUnbind(Intent intent) {
+        return false;
+    }
+
+    @Override
+    public void onDestroy() {
+        mGeofenceHardwareImpl = null;
+    }
+
+
+    private void checkPermission(int pid, int uid, int monitoringType) {
+        if (mGeofenceHardwareImpl.getAllowedResolutionLevel(pid, uid) <
+                mGeofenceHardwareImpl.getMonitoringResolutionLevel(monitoringType)) {
+            throw new SecurityException("Insufficient permissions to access hardware geofence for"
+                    + " type: " + monitoringType);
+        }
+    }
+
+    private IBinder mBinder = new IGeofenceHardware.Stub() {
+        public void setGpsGeofenceHardware(IGpsGeofenceHardware service) {
+            mGeofenceHardwareImpl.setGpsHardwareGeofence(service);
+        }
+
+        public int[] getMonitoringTypesAndStatus() {
+            mContext.enforceCallingPermission(Manifest.permission.LOCATION_HARDWARE,
+                    "Location Hardware permission not granted to access hardware geofence");
+
+            return mGeofenceHardwareImpl.getMonitoringTypesAndStatus();
+        }
+
+        public boolean addCircularFence(int id, double lat, double longitude, double radius,
+                int lastTransition, int monitorTransitions, int
+                notificationResponsiveness, int unknownTimer, int monitoringType,
+                IGeofenceHardwareCallback callback) {
+            mContext.enforceCallingPermission(Manifest.permission.LOCATION_HARDWARE,
+                    "Location Hardware permission not granted to access hardware geofence");
+            checkPermission(Binder.getCallingPid(), Binder.getCallingUid(), monitoringType);
+            return mGeofenceHardwareImpl.addCircularFence(id, lat, longitude, radius,
+                    lastTransition, monitorTransitions, notificationResponsiveness, unknownTimer,
+                    monitoringType, callback);
+        }
+
+        public boolean removeGeofence(int id, int monitoringType) {
+            mContext.enforceCallingPermission(Manifest.permission.LOCATION_HARDWARE,
+                    "Location Hardware permission not granted to access hardware geofence");
+
+            checkPermission(Binder.getCallingPid(), Binder.getCallingUid(), monitoringType);
+            return mGeofenceHardwareImpl.removeGeofence(id, monitoringType);
+        }
+
+        public boolean pauseGeofence(int id, int monitoringType) {
+            mContext.enforceCallingPermission(Manifest.permission.LOCATION_HARDWARE,
+                    "Location Hardware permission not granted to access hardware geofence");
+
+            checkPermission(Binder.getCallingPid(), Binder.getCallingUid(), monitoringType);
+            return mGeofenceHardwareImpl.pauseGeofence(id, monitoringType);
+        }
+
+        public boolean resumeGeofence(int id, int monitorTransitions, int monitoringType) {
+            mContext.enforceCallingPermission(Manifest.permission.LOCATION_HARDWARE,
+                    "Location Hardware permission not granted to access hardware geofence");
+
+            checkPermission(Binder.getCallingPid(), Binder.getCallingUid(), monitoringType);
+            return mGeofenceHardwareImpl.resumeGeofence(id, monitorTransitions, monitoringType);
+        }
+
+        public boolean registerForMonitorStateChangeCallback(int monitoringType,
+                IGeofenceHardwareCallback callback) {
+            mContext.enforceCallingPermission(Manifest.permission.LOCATION_HARDWARE,
+                    "Location Hardware permission not granted to access hardware geofence");
+
+            checkPermission(Binder.getCallingPid(), Binder.getCallingUid(), monitoringType);
+            return mGeofenceHardwareImpl.registerForMonitorStateChangeCallback(monitoringType,
+                    callback);
+        }
+
+        public boolean unregisterForMonitorStateChangeCallback(int monitoringType,
+                IGeofenceHardwareCallback callback) {
+            mContext.enforceCallingPermission(Manifest.permission.LOCATION_HARDWARE,
+                    "Location Hardware permission not granted to access hardware geofence");
+
+            checkPermission(Binder.getCallingPid(), Binder.getCallingUid(), monitoringType);
+            return mGeofenceHardwareImpl.unregisterForMonitorStateChangeCallback(monitoringType,
+                    callback);
+        }
+    };
+}
diff --git a/core/java/android/hardware/location/IGeofenceHardware.aidl b/core/java/android/hardware/location/IGeofenceHardware.aidl
new file mode 100644
index 0000000..4ba02b8
--- /dev/null
+++ b/core/java/android/hardware/location/IGeofenceHardware.aidl
@@ -0,0 +1,36 @@
+/*
+ * 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/LICENS   E-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.location;
+
+import android.location.IGpsGeofenceHardware;
+import android.hardware.location.IGeofenceHardwareCallback;
+
+/** @hide */
+interface IGeofenceHardware {
+    void setGpsGeofenceHardware(in IGpsGeofenceHardware service);
+    int[] getMonitoringTypesAndStatus();
+    boolean addCircularFence(int id, double lat, double longitude, double radius,
+            int lastTransition, int monitorTransitions, int notificationResponsiveness,
+            int unknownTimer, int monitoringType, in IGeofenceHardwareCallback callback);
+    boolean removeGeofence(int id, int monitoringType);
+    boolean pauseGeofence(int id, int monitoringType);
+    boolean resumeGeofence(int id, int monitorTransitions, int monitoringType);
+    boolean registerForMonitorStateChangeCallback(int monitoringType,
+            IGeofenceHardwareCallback callback);
+    boolean unregisterForMonitorStateChangeCallback(int monitoringType,
+            IGeofenceHardwareCallback callback);
+}
diff --git a/core/java/android/hardware/location/IGeofenceHardwareCallback.aidl b/core/java/android/hardware/location/IGeofenceHardwareCallback.aidl
new file mode 100644
index 0000000..678fc49
--- /dev/null
+++ b/core/java/android/hardware/location/IGeofenceHardwareCallback.aidl
@@ -0,0 +1,30 @@
+/*
+ * 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 android.hardware.location;
+
+import android.location.Location;
+
+/** @hide */
+oneway interface IGeofenceHardwareCallback {
+   void onMonitoringSystemChange(int monitoringType, boolean available, in Location location);
+   void onGeofenceChange(int geofenceId, int transition, in Location location,
+            long timestamp, int monitoringType);
+   void onGeofenceAdd(int geofenceId, int status);
+   void onGeofenceRemove(int geofenceId, int status);
+   void onGeofencePause(int geofenceId, int status);
+   void onGeofenceResume(int geofenceId, int status);
+}
diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java
index facab4c..476b4ea 100644
--- a/core/java/android/os/Process.java
+++ b/core/java/android/os/Process.java
@@ -166,11 +166,6 @@
     public static final int LAST_SHARED_APPLICATION_GID = 59999;
 
     /**
-     * Defines a secondary group id for access to the bluetooth hardware.
-     */
-    public static final int BLUETOOTH_GID = 2000;
-
-    /**
      * Standard priority of application threads.
      * Use with {@link #setThreadPriority(int)} and
      * {@link #setThreadPriority(int, int)}, <b>not</b> with the normal
diff --git a/core/java/android/os/Trace.java b/core/java/android/os/Trace.java
index 27ed6b6..310b12c 100644
--- a/core/java/android/os/Trace.java
+++ b/core/java/android/os/Trace.java
@@ -19,41 +19,55 @@
 import android.util.Log;
 
 /**
- * Writes trace events to the kernel trace buffer.  These trace events can be
- * collected using the "atrace" program for offline analysis.
+ * Writes trace events to the system trace buffer.  These trace events can be
+ * collected and visualized using the Systrace tool.
  *
  * This tracing mechanism is independent of the method tracing mechanism
  * offered by {@link Debug#startMethodTracing}.  In particular, it enables
- * tracing of events that occur across processes.
+ * tracing of events that occur across multiple processes.
  *
  * @hide
  */
 public final class Trace {
+    /*
+     * Writes trace events to the kernel trace buffer.  These trace events can be
+     * collected using the "atrace" program for offline analysis.
+     */
+
     private static final String TAG = "Trace";
 
     // These tags must be kept in sync with system/core/include/cutils/trace.h.
+    /** @hide */
     public static final long TRACE_TAG_NEVER = 0;
+    /** @hide */
     public static final long TRACE_TAG_ALWAYS = 1L << 0;
+    /** @hide */
     public static final long TRACE_TAG_GRAPHICS = 1L << 1;
+    /** @hide */
     public static final long TRACE_TAG_INPUT = 1L << 2;
+    /** @hide */
     public static final long TRACE_TAG_VIEW = 1L << 3;
+    /** @hide */
     public static final long TRACE_TAG_WEBVIEW = 1L << 4;
+    /** @hide */
     public static final long TRACE_TAG_WINDOW_MANAGER = 1L << 5;
+    /** @hide */
     public static final long TRACE_TAG_ACTIVITY_MANAGER = 1L << 6;
+    /** @hide */
     public static final long TRACE_TAG_SYNC_MANAGER = 1L << 7;
+    /** @hide */
     public static final long TRACE_TAG_AUDIO = 1L << 8;
+    /** @hide */
     public static final long TRACE_TAG_VIDEO = 1L << 9;
+    /** @hide */
     public static final long TRACE_TAG_CAMERA = 1L << 10;
+    /** @hide */
     public static final long TRACE_TAG_HAL = 1L << 11;
+    /** @hide */
+    public static final long TRACE_TAG_APP = 1L << 12;
+
     private static final long TRACE_TAG_NOT_READY = 1L << 63;
-
-    public static final int TRACE_FLAGS_START_BIT = 1;
-    public static final String[] TRACE_TAGS = {
-        "Graphics", "Input", "View", "WebView", "Window Manager",
-        "Activity Manager", "Sync Manager", "Audio", "Video", "Camera", "HAL",
-    };
-
-    public static final String PROPERTY_TRACE_TAG_ENABLEFLAGS = "debug.atrace.tags.enableflags";
+    private static final int MAX_SECTION_NAME_LEN = 127;
 
     // Must be volatile to avoid word tearing.
     private static volatile long sEnabledTags = TRACE_TAG_NOT_READY;
@@ -62,6 +76,7 @@
     private static native void nativeTraceCounter(long tag, String name, int value);
     private static native void nativeTraceBegin(long tag, String name);
     private static native void nativeTraceEnd(long tag);
+    private static native void nativeSetAppTracingAllowed(boolean allowed);
 
     static {
         // We configure two separate change callbacks, one in Trace.cpp and one here.  The
@@ -111,6 +126,8 @@
      *
      * @param traceTag The trace tag to check.
      * @return True if the trace tag is valid.
+     *
+     * @hide
      */
     public static boolean isTagEnabled(long traceTag) {
         long tags = sEnabledTags;
@@ -126,6 +143,8 @@
      * @param traceTag The trace tag.
      * @param counterName The counter name to appear in the trace.
      * @param counterValue The counter value.
+     *
+     * @hide
      */
     public static void traceCounter(long traceTag, String counterName, int counterValue) {
         if (isTagEnabled(traceTag)) {
@@ -134,11 +153,28 @@
     }
 
     /**
-     * Writes a trace message to indicate that a given method has begun.
-     * Must be followed by a call to {@link #traceEnd} using the same tag.
+     * Set whether application tracing is allowed for this process.  This is intended to be set
+     * once at application start-up time based on whether the application is debuggable.
+     *
+     * @hide
+     */
+    public static void setAppTracingAllowed(boolean allowed) {
+        nativeSetAppTracingAllowed(allowed);
+
+        // Setting whether app tracing is allowed may change the tags, so we update the cached
+        // tags here.
+        cacheEnabledTags();
+    }
+
+    /**
+     * Writes a trace message to indicate that a given section of code has
+     * begun. Must be followed by a call to {@link #traceEnd} using the same
+     * tag.
      *
      * @param traceTag The trace tag.
      * @param methodName The method name to appear in the trace.
+     *
+     * @hide
      */
     public static void traceBegin(long traceTag, String methodName) {
         if (isTagEnabled(traceTag)) {
@@ -151,10 +187,48 @@
      * Must be called exactly once for each call to {@link #traceBegin} using the same tag.
      *
      * @param traceTag The trace tag.
+     *
+     * @hide
      */
     public static void traceEnd(long traceTag) {
         if (isTagEnabled(traceTag)) {
             nativeTraceEnd(traceTag);
         }
     }
+
+    /**
+     * Writes a trace message to indicate that a given section of code has begun. This call must
+     * be followed by a corresponding call to {@link #traceEnd()} on the same thread.
+     *
+     * <p class="note"> At this time the vertical bar character '|', newline character '\n', and
+     * null character '\0' are used internally by the tracing mechanism.  If sectionName contains
+     * these characters they will be replaced with a space character in the trace.
+     *
+     * @param sectionName The name of the code section to appear in the trace.  This may be at
+     * most 127 Unicode code units long.
+     *
+     * @hide
+     */
+    public static void traceBegin(String sectionName) {
+        if (isTagEnabled(TRACE_TAG_APP)) {
+            if (sectionName.length() > MAX_SECTION_NAME_LEN) {
+                throw new IllegalArgumentException("sectionName is too long");
+            }
+            nativeTraceBegin(TRACE_TAG_APP, sectionName);
+        }
+    }
+
+    /**
+     * Writes a trace message to indicate that a given section of code has ended. This call must
+     * be preceeded by a corresponding call to {@link #traceBegin(String)}. Calling this method
+     * will mark the end of the most recently begun section of code, so care must be taken to
+     * ensure that traceBegin / traceEnd pairs are properly nested and called from the same thread.
+     *
+     * @hide
+     */
+    public static void traceEnd() {
+        if (isTagEnabled(TRACE_TAG_APP)) {
+            nativeTraceEnd(TRACE_TAG_APP);
+        }
+    }
 }
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index 367d576..c41c35e 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -35,9 +35,7 @@
 import android.database.DatabaseUtils;
 import android.graphics.Rect;
 import android.net.Uri;
-import android.os.Bundle;
 import android.os.RemoteException;
-import android.os.UserHandle;
 import android.text.TextUtils;
 import android.util.DisplayMetrics;
 import android.util.Pair;
@@ -939,6 +937,15 @@
          * its row id changed as a result of a sync or aggregation.
          */
         public static final String LOOKUP_KEY = "lookup";
+
+        /**
+         * Timestamp (milliseconds since epoch) of when this contact was last updated.  This
+         * includes updates to all data associated with this contact including raw contacts.  Any
+         * modification (including deletes and inserts) of underlying contact data are also
+         * reflected in this timestamp.
+         */
+        public static final String CONTACT_LAST_UPDATED_TIMESTAMP =
+                "contact_last_updated_timestamp";
     }
 
     /**
@@ -2113,6 +2120,56 @@
         return id >= Profile.MIN_ID;
     }
 
+    protected interface DeletedContactsColumns {
+
+        /**
+         * A reference to the {@link ContactsContract.Contacts#_ID} that was deleted.
+         * <P>Type: INTEGER</P>
+         */
+        public static final String CONTACT_ID = "contact_id";
+
+        /**
+         * Time (milliseconds since epoch) that the contact was deleted.
+         */
+        public static final String CONTACT_DELETED_TIMESTAMP = "contact_deleted_timestamp";
+    }
+
+    /**
+     * Constants for the deleted contact table.  This table holds a log of deleted contacts.
+     * <p>
+     * Log older than {@link #DAYS_KEPT_MILLISECONDS} may be deleted.
+     */
+    public static final class DeletedContacts implements DeletedContactsColumns {
+
+        /**
+         * This utility class cannot be instantiated
+         */
+        private DeletedContacts() {
+        }
+
+        /**
+         * The content:// style URI for this table, which requests a directory of raw contact rows
+         * matching the selection criteria.
+         */
+        public static final Uri CONTENT_URI = Uri.withAppendedPath(AUTHORITY_URI,
+                "deleted_contacts");
+
+        /**
+         * Number of days that the delete log will be kept.  After this time, delete records may be
+         * deleted.
+         *
+         * @hide
+         */
+        private static final int DAYS_KEPT = 30;
+
+        /**
+         * Milliseconds that the delete log will be kept.  After this time, delete records may be
+         * deleted.
+         */
+        public static final long DAYS_KEPT_MILLISECONDS = 1000L * 60L * 60L * 24L * (long)DAYS_KEPT;
+    }
+
+
     protected interface RawContactsColumns {
         /**
          * A reference to the {@link ContactsContract.Contacts#_ID} that this
@@ -7909,6 +7966,13 @@
                 "android.provider.Contacts.SEARCH_SUGGESTION_CREATE_CONTACT_CLICKED";
 
         /**
+         * This is the intent that is fired when the contacts database is created. <p> The
+         * READ_CONTACT permission is required to receive these broadcasts.
+         */
+        public static final String CONTACTS_DATABASE_CREATED =
+                "android.provider.Contacts.DATABASE_CREATED";
+
+        /**
          * Starts an Activity that lets the user pick a contact to attach an image to.
          * After picking the contact it launches the image cropper in face detection mode.
          */
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java
index 8055077..8308459 100644
--- a/core/java/android/view/HardwareRenderer.java
+++ b/core/java/android/view/HardwareRenderer.java
@@ -1368,7 +1368,7 @@
                         callbacks.onHardwarePreDraw(canvas);
 
                         if (displayList != null) {
-                            status = drawDisplayList(attachInfo, canvas, displayList, status);
+                            status |= drawDisplayList(attachInfo, canvas, displayList, status);
                         } else {
                             // Shouldn't reach here
                             view.draw(canvas);
diff --git a/core/java/android/view/LayoutInflater.java b/core/java/android/view/LayoutInflater.java
index 26a5b26..85695fc 100644
--- a/core/java/android/view/LayoutInflater.java
+++ b/core/java/android/view/LayoutInflater.java
@@ -19,6 +19,7 @@
 import android.graphics.Canvas;
 import android.os.Handler;
 import android.os.Message;
+import android.os.Trace;
 import android.widget.FrameLayout;
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
@@ -423,6 +424,8 @@
      */
     public View inflate(XmlPullParser parser, ViewGroup root, boolean attachToRoot) {
         synchronized (mConstructorArgs) {
+            Trace.traceBegin(Trace.TRACE_TAG_VIEW, "inflate");
+
             final AttributeSet attrs = Xml.asAttributeSet(parser);
             Context lastContext = (Context)mConstructorArgs[0];
             mConstructorArgs[0] = mContext;
@@ -520,6 +523,8 @@
                 mConstructorArgs[1] = null;
             }
 
+            Trace.traceEnd(Trace.TRACE_TAG_VIEW);
+
             return result;
         }
     }
@@ -547,6 +552,8 @@
         Class<? extends View> clazz = null;
 
         try {
+            Trace.traceBegin(Trace.TRACE_TAG_VIEW, name);
+
             if (constructor == null) {
                 // Class not found in the cache, see if it's real, and try to add it
                 clazz = mContext.getClassLoader().loadClass(
@@ -615,6 +622,8 @@
                     + (clazz == null ? "<unknown>" : clazz.getName()));
             ie.initCause(e);
             throw ie;
+        } finally {
+            Trace.traceEnd(Trace.TRACE_TAG_VIEW);
         }
     }
 
diff --git a/core/java/android/view/SimulatedDpad.java b/core/java/android/view/SimulatedDpad.java
deleted file mode 100644
index c889328..0000000
--- a/core/java/android/view/SimulatedDpad.java
+++ /dev/null
@@ -1,298 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.view;
-
-import android.app.SearchManager;
-import android.content.ActivityNotFoundException;
-import android.content.Context;
-import android.content.Intent;
-import android.os.Handler;
-import android.os.Message;
-import android.os.SystemClock;
-import android.os.SystemProperties;
-import android.os.UserHandle;
-import android.util.Log;
-
-/**
- * This class creates DPAD events from TouchNavigation events.
- * 
- * @see ViewRootImpl
- */
-
-//TODO: Make this class an internal class of ViewRootImpl.java
-class SimulatedDpad {
-
-    private static final String TAG = "SimulatedDpad";
-
-    // Maximum difference in milliseconds between the down and up of a touch
-    // event for it to be considered a tap
-    // TODO:Read this value from a configuration file
-    private static final int MAX_TAP_TIME = 250;
-    // Where the cutoff is for determining an edge swipe
-    private static final float EDGE_SWIPE_THRESHOLD = 0.9f;
-    private static final int MSG_FLICK = 313;
-    // TODO: Pass touch slop from the input device
-    private static final int TOUCH_SLOP = 30;
-    // The position of the previous TouchNavigation event
-    private float mLastTouchNavigationXPosition;
-    private float mLastTouchNavigationYPosition;
-    // Where the Touch Navigation was initially pressed
-    private float mTouchNavigationEnterXPosition;
-    private float mTouchNavigationEnterYPosition;
-    // When the most recent ACTION_HOVER_ENTER occurred
-    private long mLastTouchNavigationStartTimeMs = 0;
-    // When the most recent direction key was sent
-    private long mLastTouchNavigationKeySendTimeMs = 0;
-    // When the most recent touch event of any type occurred
-    private long mLastTouchNavigationEventTimeMs = 0;
-    // Did the swipe begin in a valid region
-    private boolean mEdgeSwipePossible;
-
-    private final Context mContext;
-
-    // How quickly keys were sent;
-    private int mKeySendRateMs = 0;
-    private int mLastKeySent;
-    // Last movement in device screen pixels
-    private float mLastMoveX = 0;
-    private float mLastMoveY = 0;
-    // Offset from the initial touch. Gets reset as direction keys are sent.
-    private float mAccumulatedX;
-    private float mAccumulatedY;
-
-    // Change in position allowed during tap events
-    private float mTouchSlop;
-    private float mTouchSlopSquared;
-    // Has the TouchSlop constraint been invalidated
-    private boolean mAlwaysInTapRegion = true;
-
-    // Information from the most recent event.
-    // Used to determine what device sent the event during a fling.
-    private int mLastSource;
-    private int mLastMetaState;
-    private int mLastDeviceId;
-
-    // TODO: Currently using screen dimensions tuned to a Galaxy Nexus, need to
-    // read this from a config file instead
-    private int mDistancePerTick;
-    private int mDistancePerTickSquared;
-    // Highest rate that the flinged events can occur at before dying out
-    private int mMaxRepeatDelay;
-    // The square of the minimum distance needed for a flick to register
-    private int mMinFlickDistanceSquared;
-    // How quickly the repeated events die off
-    private float mFlickDecay;
-
-    public SimulatedDpad(Context context) {
-        mDistancePerTick = SystemProperties.getInt("persist.vr_dist_tick", 64);
-        mDistancePerTickSquared = mDistancePerTick * mDistancePerTick;
-        mMaxRepeatDelay = SystemProperties.getInt("persist.vr_repeat_delay", 300);
-        mMinFlickDistanceSquared = SystemProperties.getInt("persist.vr_min_flick", 20);
-        mMinFlickDistanceSquared *= mMinFlickDistanceSquared;
-        mFlickDecay = Float.parseFloat(SystemProperties.get(
-                "persist.sys.vr_flick_decay", "1.3"));
-        mTouchSlop = TOUCH_SLOP;
-        mTouchSlopSquared = mTouchSlop * mTouchSlop;
-
-        mContext = context;
-    }
-
-    private final Handler mHandler = new Handler(true /*async*/) {
-            @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-                case MSG_FLICK: {
-                    final long time = SystemClock.uptimeMillis();
-                    ViewRootImpl viewroot = (ViewRootImpl) msg.obj;
-                    // Send the key
-                    viewroot.enqueueInputEvent(new KeyEvent(time, time,
-                            KeyEvent.ACTION_DOWN, msg.arg2, 0, mLastMetaState,
-                            mLastDeviceId, 0, KeyEvent.FLAG_FALLBACK, mLastSource));
-                    viewroot.enqueueInputEvent(new KeyEvent(time, time,
-                            KeyEvent.ACTION_UP, msg.arg2, 0, mLastMetaState,
-                            mLastDeviceId, 0, KeyEvent.FLAG_FALLBACK, mLastSource));
-
-                    // Increase the delay by the decay factor and resend
-                    final int delay = (int) Math.ceil(mFlickDecay * msg.arg1);
-                    if (delay <= mMaxRepeatDelay) {
-                        Message msgCopy = Message.obtain(msg);
-                        msgCopy.arg1 = delay;
-                        msgCopy.setAsynchronous(true);
-                        mHandler.sendMessageDelayed(msgCopy, delay);
-                    }
-                    break;
-                }
-            }
-        }
-    };
-
-    public void updateTouchNavigation(ViewRootImpl viewroot, MotionEvent event,
-            boolean synthesizeNewKeys) {
-        if (!synthesizeNewKeys) {
-            mHandler.removeMessages(MSG_FLICK);
-        }
-        InputDevice device = event.getDevice();
-        if (device == null) {
-            return;
-        }
-        // Store what time the TouchNavigation event occurred
-        final long time = SystemClock.uptimeMillis();
-        switch (event.getAction()) {
-            case MotionEvent.ACTION_DOWN:
-                mLastTouchNavigationStartTimeMs = time;
-                mAlwaysInTapRegion = true;
-                mTouchNavigationEnterXPosition = event.getX();
-                mTouchNavigationEnterYPosition = event.getY();
-                mAccumulatedX = 0;
-                mAccumulatedY = 0;
-                mLastMoveX = 0;
-                mLastMoveY = 0;
-                if (device.getMotionRange(MotionEvent.AXIS_Y).getMax()
-                        * EDGE_SWIPE_THRESHOLD < event.getY()) {
-                    // Did the swipe begin in a valid region
-                    mEdgeSwipePossible = true;
-                }
-                // Clear any flings
-                if (synthesizeNewKeys) {
-                    mHandler.removeMessages(MSG_FLICK);
-                }
-                break;
-            case MotionEvent.ACTION_MOVE:
-                // Determine whether the move is slop or an intentional move
-                float deltaX = event.getX() - mTouchNavigationEnterXPosition;
-                float deltaY = event.getY() - mTouchNavigationEnterYPosition;
-                if (mTouchSlopSquared < deltaX * deltaX + deltaY * deltaY) {
-                    mAlwaysInTapRegion = false;
-                }
-                // Checks if the swipe has crossed the midpoint
-                // and if our swipe gesture is complete
-                if (event.getY() < (device.getMotionRange(MotionEvent.AXIS_Y).getMax()
-                        * .5) && mEdgeSwipePossible) {
-                    mEdgeSwipePossible = false;
-
-                    Intent intent =
-                            ((SearchManager)mContext.getSystemService(Context.SEARCH_SERVICE))
-                            .getAssistIntent(mContext, false, UserHandle.USER_CURRENT_OR_SELF);
-                    if (intent != null) {
-                        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-                        try {
-                            mContext.startActivity(intent);
-                        } catch (ActivityNotFoundException e){
-                            Log.e(TAG, "Could not start search activity");
-                        }
-                    } else {
-                        Log.e(TAG, "Could not find a search activity");
-                    }
-                }
-                // Find the difference in position between the two most recent
-                // TouchNavigation events
-                mLastMoveX = event.getX() - mLastTouchNavigationXPosition;
-                mLastMoveY = event.getY() - mLastTouchNavigationYPosition;
-                mAccumulatedX += mLastMoveX;
-                mAccumulatedY += mLastMoveY;
-                float mAccumulatedXSquared = mAccumulatedX * mAccumulatedX;
-                float mAccumulatedYSquared = mAccumulatedY * mAccumulatedY;
-                // Determine if we've moved far enough to send a key press
-                if (mAccumulatedXSquared > mDistancePerTickSquared ||
-                        mAccumulatedYSquared > mDistancePerTickSquared) {
-                    float dominantAxis;
-                    float sign;
-                    boolean isXAxis;
-                    int key;
-                    int repeatCount = 0;
-                    // Determine dominant axis
-                    if (mAccumulatedXSquared > mAccumulatedYSquared) {
-                        dominantAxis = mAccumulatedX;
-                        isXAxis = true;
-                    } else {
-                        dominantAxis = mAccumulatedY;
-                        isXAxis = false;
-                    }
-                    // Determine sign of axis
-                    sign = (dominantAxis > 0) ? 1 : -1;
-                    // Determine key to send
-                    if (isXAxis) {
-                        key = (sign == 1) ? KeyEvent.KEYCODE_DPAD_RIGHT :
-                                KeyEvent.KEYCODE_DPAD_LEFT;
-                    } else {
-                        key = (sign == 1) ? KeyEvent.KEYCODE_DPAD_DOWN : KeyEvent.KEYCODE_DPAD_UP;
-                    }
-                    // Send key until maximum distance constraint is satisfied
-                    while (dominantAxis * dominantAxis > mDistancePerTickSquared) {
-                        repeatCount++;
-                        dominantAxis -= sign * mDistancePerTick;
-                        if (synthesizeNewKeys) {
-                            viewroot.enqueueInputEvent(new KeyEvent(time, time,
-                                    KeyEvent.ACTION_DOWN, key, 0, event.getMetaState(),
-                                    event.getDeviceId(), 0, KeyEvent.FLAG_FALLBACK,
-                                    event.getSource()));
-                            viewroot.enqueueInputEvent(new KeyEvent(time, time,
-                                    KeyEvent.ACTION_UP, key, 0, event.getMetaState(),
-                                    event.getDeviceId(), 0, KeyEvent.FLAG_FALLBACK,
-                                    event.getSource()));
-                        }
-                    }
-                    // Save new axis values
-                    mAccumulatedX = isXAxis ? dominantAxis : 0;
-                    mAccumulatedY = isXAxis ? 0 : dominantAxis;
-
-                    mLastKeySent = key;
-                    mKeySendRateMs = (int) (time - mLastTouchNavigationKeySendTimeMs) / repeatCount;
-                    mLastTouchNavigationKeySendTimeMs = time;
-                }
-                break;
-            case MotionEvent.ACTION_UP:
-                if (time - mLastTouchNavigationStartTimeMs < MAX_TAP_TIME && mAlwaysInTapRegion) {
-                    if (synthesizeNewKeys) {
-                        viewroot.enqueueInputEvent(new KeyEvent(mLastTouchNavigationStartTimeMs,
-                                    time, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_CENTER, 0,
-                                    event.getMetaState(), event.getDeviceId(), 0,
-                                    KeyEvent.FLAG_FALLBACK, event.getSource()));
-                        viewroot.enqueueInputEvent(new KeyEvent(mLastTouchNavigationStartTimeMs,
-                                    time, KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DPAD_CENTER, 0,
-                                    event.getMetaState(), event.getDeviceId(), 0,
-                                    KeyEvent.FLAG_FALLBACK, event.getSource()));
-                    }
-                } else {
-                    float xMoveSquared = mLastMoveX * mLastMoveX;
-                    float yMoveSquared = mLastMoveY * mLastMoveY;
-                    // Determine whether the last gesture was a fling.
-                    if (mMinFlickDistanceSquared <= xMoveSquared + yMoveSquared &&
-                            time - mLastTouchNavigationEventTimeMs <= MAX_TAP_TIME &&
-                            mKeySendRateMs <= mMaxRepeatDelay && mKeySendRateMs > 0) {
-                        mLastDeviceId = event.getDeviceId();
-                        mLastSource = event.getSource();
-                        mLastMetaState = event.getMetaState();
-
-                        if (synthesizeNewKeys) {
-                            Message message = Message.obtain(mHandler, MSG_FLICK,
-                                    mKeySendRateMs, mLastKeySent, viewroot);
-                            message.setAsynchronous(true);
-                            mHandler.sendMessageDelayed(message, mKeySendRateMs);
-                        }
-                    }
-                }
-                mEdgeSwipePossible = false;
-                break;
-        }
-
-        // Store touch event position and time
-        mLastTouchNavigationEventTimeMs = time;
-        mLastTouchNavigationXPosition = event.getX();
-        mLastTouchNavigationYPosition = event.getY();
-    }
-}
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 22586f6..c1db4c6 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -2923,8 +2923,6 @@
     private final static int MSG_DISPATCH_DONE_ANIMATING = 22;
     private final static int MSG_INVALIDATE_WORLD = 23;
     private final static int MSG_WINDOW_MOVED = 24;
-    private final static int MSG_ENQUEUE_X_AXIS_KEY_REPEAT = 25;
-    private final static int MSG_ENQUEUE_Y_AXIS_KEY_REPEAT = 26;
 
     final class ViewRootHandler extends Handler {
         @Override
@@ -2974,10 +2972,6 @@
                     return "MSG_DISPATCH_DONE_ANIMATING";
                 case MSG_WINDOW_MOVED:
                     return "MSG_WINDOW_MOVED";
-                case MSG_ENQUEUE_X_AXIS_KEY_REPEAT:
-                    return "MSG_ENQUEUE_X_AXIS_KEY_REPEAT";
-                case MSG_ENQUEUE_Y_AXIS_KEY_REPEAT:
-                    return "MSG_ENQUEUE_Y_AXIS_KEY_REPEAT";
             }
             return super.getMessageName(message);
         }
@@ -3200,18 +3194,6 @@
                     invalidateWorld(mView);
                 }
             } break;
-            case MSG_ENQUEUE_X_AXIS_KEY_REPEAT:
-            case MSG_ENQUEUE_Y_AXIS_KEY_REPEAT: {
-                KeyEvent oldEvent = (KeyEvent)msg.obj;
-                KeyEvent e = KeyEvent.changeTimeRepeat(oldEvent, SystemClock.uptimeMillis(),
-                        oldEvent.getRepeatCount() + 1);
-                if (mAttachInfo.mHasWindowFocus) {
-                    enqueueInputEvent(e);
-                    Message m = obtainMessage(msg.what, e);
-                    m.setAsynchronous(true);
-                    sendMessageDelayed(m, mViewConfiguration.getKeyRepeatDelay());
-                }
-            } break;
             }
         }
     }
@@ -3877,37 +3859,34 @@
     }
 
     /**
-     * Performs default processing of unhandled input events.
+     * Performs synthesis of new input events from unhandled input events.
      */
     final class SyntheticInputStage extends InputStage {
-        private final TrackballAxis mTrackballAxisX = new TrackballAxis();
-        private final TrackballAxis mTrackballAxisY = new TrackballAxis();
-        private long mLastTrackballTime;
-
-        private int mLastJoystickXDirection;
-        private int mLastJoystickYDirection;
-        private int mLastJoystickXKeyCode;
-        private int mLastJoystickYKeyCode;
-
-        private SimulatedDpad mSimulatedDpad;
+        private final SyntheticTrackballHandler mTrackball = new SyntheticTrackballHandler();
+        private final SyntheticJoystickHandler mJoystick = new SyntheticJoystickHandler();
+        private final SyntheticTouchNavigationHandler mTouchNavigation =
+                new SyntheticTouchNavigationHandler();
 
         public SyntheticInputStage() {
             super(null);
-            mSimulatedDpad = new SimulatedDpad(mContext);
         }
 
         @Override
         protected int onProcess(QueuedInputEvent q) {
             q.mFlags |= QueuedInputEvent.FLAG_RESYNTHESIZED;
             if (q.mEvent instanceof MotionEvent) {
-                final int source = q.mEvent.getSource();
+                final MotionEvent event = (MotionEvent)q.mEvent;
+                final int source = event.getSource();
                 if ((source & InputDevice.SOURCE_CLASS_TRACKBALL) != 0) {
-                    return processTrackballEvent(q);
+                    mTrackball.process(event);
+                    return FINISH_HANDLED;
                 } else if ((source & InputDevice.SOURCE_CLASS_JOYSTICK) != 0) {
-                    return processJoystickEvent(q);
+                    mJoystick.process(event);
+                    return FINISH_HANDLED;
                 } else if ((source & InputDevice.SOURCE_TOUCH_NAVIGATION)
                         == InputDevice.SOURCE_TOUCH_NAVIGATION) {
-                    return processTouchNavigationEvent(q);
+                    mTouchNavigation.process(event);
+                    return FINISH_HANDLED;
                 }
             }
             return FORWARD;
@@ -3918,49 +3897,55 @@
             if ((q.mFlags & QueuedInputEvent.FLAG_RESYNTHESIZED) == 0) {
                 // Cancel related synthetic events if any prior stage has handled the event.
                 if (q.mEvent instanceof MotionEvent) {
-                    final int source = q.mEvent.getSource();
+                    final MotionEvent event = (MotionEvent)q.mEvent;
+                    final int source = event.getSource();
                     if ((source & InputDevice.SOURCE_CLASS_TRACKBALL) != 0) {
-                        cancelTrackballEvent(q);
+                        mTrackball.cancel(event);
                     } else if ((source & InputDevice.SOURCE_CLASS_JOYSTICK) != 0) {
-                        cancelJoystickEvent(q);
+                        mJoystick.cancel(event);
                     } else if ((source & InputDevice.SOURCE_TOUCH_NAVIGATION)
                             == InputDevice.SOURCE_TOUCH_NAVIGATION) {
-                        cancelTouchNavigationEvent(q);
+                        mTouchNavigation.cancel(event);
                     }
                 }
             }
             super.onDeliverToNext(q);
         }
+    }
 
-        private int processTrackballEvent(QueuedInputEvent q) {
-            final MotionEvent event = (MotionEvent)q.mEvent;
+    /**
+     * Creates dpad events from unhandled trackball movements.
+     */
+    final class SyntheticTrackballHandler {
+        private final TrackballAxis mX = new TrackballAxis();
+        private final TrackballAxis mY = new TrackballAxis();
+        private long mLastTime;
 
+        public void process(MotionEvent event) {
             // Translate the trackball event into DPAD keys and try to deliver those.
-            final TrackballAxis x = mTrackballAxisX;
-            final TrackballAxis y = mTrackballAxisY;
             long curTime = SystemClock.uptimeMillis();
-            if ((mLastTrackballTime + MAX_TRACKBALL_DELAY) < curTime) {
+            if ((mLastTime + MAX_TRACKBALL_DELAY) < curTime) {
                 // It has been too long since the last movement,
                 // so restart at the beginning.
-                x.reset(0);
-                y.reset(0);
-                mLastTrackballTime = curTime;
+                mX.reset(0);
+                mY.reset(0);
+                mLastTime = curTime;
             }
 
             final int action = event.getAction();
             final int metaState = event.getMetaState();
             switch (action) {
                 case MotionEvent.ACTION_DOWN:
-                    x.reset(2);
-                    y.reset(2);
+                    mX.reset(2);
+                    mY.reset(2);
                     enqueueInputEvent(new KeyEvent(curTime, curTime,
                             KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_CENTER, 0, metaState,
                             KeyCharacterMap.VIRTUAL_KEYBOARD, 0, KeyEvent.FLAG_FALLBACK,
                             InputDevice.SOURCE_KEYBOARD));
                     break;
                 case MotionEvent.ACTION_UP:
-                    x.reset(2);
-                    y.reset(2);
+                    mX.reset(2);
+                    mY.reset(2);
                     enqueueInputEvent(new KeyEvent(curTime, curTime,
                             KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DPAD_CENTER, 0, metaState,
                             KeyCharacterMap.VIRTUAL_KEYBOARD, 0, KeyEvent.FLAG_FALLBACK,
@@ -3968,14 +3953,14 @@
                     break;
             }
 
-            if (DEBUG_TRACKBALL) Log.v(TAG, "TB X=" + x.position + " step="
-                    + x.step + " dir=" + x.dir + " acc=" + x.acceleration
+            if (DEBUG_TRACKBALL) Log.v(TAG, "TB X=" + mX.position + " step="
+                    + mX.step + " dir=" + mX.dir + " acc=" + mX.acceleration
                     + " move=" + event.getX()
-                    + " / Y=" + y.position + " step="
-                    + y.step + " dir=" + y.dir + " acc=" + y.acceleration
+                    + " / Y=" + mY.position + " step="
+                    + mY.step + " dir=" + mY.dir + " acc=" + mY.acceleration
                     + " move=" + event.getY());
-            final float xOff = x.collect(event.getX(), event.getEventTime(), "X");
-            final float yOff = y.collect(event.getY(), event.getEventTime(), "Y");
+            final float xOff = mX.collect(event.getX(), event.getEventTime(), "X");
+            final float yOff = mY.collect(event.getY(), event.getEventTime(), "Y");
 
             // Generate DPAD events based on the trackball movement.
             // We pick the axis that has moved the most as the direction of
@@ -3987,20 +3972,20 @@
             int movement = 0;
             float accel = 1;
             if (xOff > yOff) {
-                movement = x.generate();
+                movement = mX.generate();
                 if (movement != 0) {
                     keycode = movement > 0 ? KeyEvent.KEYCODE_DPAD_RIGHT
                             : KeyEvent.KEYCODE_DPAD_LEFT;
-                    accel = x.acceleration;
-                    y.reset(2);
+                    accel = mX.acceleration;
+                    mY.reset(2);
                 }
             } else if (yOff > 0) {
-                movement = y.generate();
+                movement = mY.generate();
                 if (movement != 0) {
                     keycode = movement > 0 ? KeyEvent.KEYCODE_DPAD_DOWN
                             : KeyEvent.KEYCODE_DPAD_UP;
-                    accel = y.acceleration;
-                    x.reset(2);
+                    accel = mY.acceleration;
+                    mX.reset(2);
                 }
             }
 
@@ -4034,16 +4019,12 @@
                             KeyCharacterMap.VIRTUAL_KEYBOARD, 0, KeyEvent.FLAG_FALLBACK,
                             InputDevice.SOURCE_KEYBOARD));
                 }
-                mLastTrackballTime = curTime;
+                mLastTime = curTime;
             }
-
-            // Unfortunately we can't tell whether the application consumed the keys, so
-            // we always consider the trackball event handled.
-            return FINISH_HANDLED;
         }
 
-        private void cancelTrackballEvent(QueuedInputEvent q) {
-            mLastTrackballTime = Integer.MIN_VALUE;
+        public void cancel(MotionEvent event) {
+            mLastTime = Integer.MIN_VALUE;
 
             // If we reach this, we consumed a trackball event.
             // Because we will not translate the trackball event into a key event,
@@ -4052,19 +4033,220 @@
                 ensureTouchMode(false);
             }
         }
+    }
 
-        private int processJoystickEvent(QueuedInputEvent q) {
-            final MotionEvent event = (MotionEvent)q.mEvent;
-            updateJoystickDirection(event, true);
-            return FINISH_HANDLED;
+    /**
+     * Maintains state information for a single trackball axis, generating
+     * discrete (DPAD) movements based on raw trackball motion.
+     */
+    static final class TrackballAxis {
+        /**
+         * The maximum amount of acceleration we will apply.
+         */
+        static final float MAX_ACCELERATION = 20;
+
+        /**
+         * The maximum amount of time (in milliseconds) between events in order
+         * for us to consider the user to be doing fast trackball movements,
+         * and thus apply an acceleration.
+         */
+        static final long FAST_MOVE_TIME = 150;
+
+        /**
+         * Scaling factor to the time (in milliseconds) between events to how
+         * much to multiple/divide the current acceleration.  When movement
+         * is < FAST_MOVE_TIME this multiplies the acceleration; when >
+         * FAST_MOVE_TIME it divides it.
+         */
+        static final float ACCEL_MOVE_SCALING_FACTOR = (1.0f/40);
+
+        static final float FIRST_MOVEMENT_THRESHOLD = 0.5f;
+        static final float SECOND_CUMULATIVE_MOVEMENT_THRESHOLD = 2.0f;
+        static final float SUBSEQUENT_INCREMENTAL_MOVEMENT_THRESHOLD = 1.0f;
+
+        float position;
+        float acceleration = 1;
+        long lastMoveTime = 0;
+        int step;
+        int dir;
+        int nonAccelMovement;
+
+        void reset(int _step) {
+            position = 0;
+            acceleration = 1;
+            lastMoveTime = 0;
+            step = _step;
+            dir = 0;
         }
 
-        private void cancelJoystickEvent(QueuedInputEvent q) {
-            final MotionEvent event = (MotionEvent)q.mEvent;
-            updateJoystickDirection(event, false);
+        /**
+         * Add trackball movement into the state.  If the direction of movement
+         * has been reversed, the state is reset before adding the
+         * movement (so that you don't have to compensate for any previously
+         * collected movement before see the result of the movement in the
+         * new direction).
+         *
+         * @return Returns the absolute value of the amount of movement
+         * collected so far.
+         */
+        float collect(float off, long time, String axis) {
+            long normTime;
+            if (off > 0) {
+                normTime = (long)(off * FAST_MOVE_TIME);
+                if (dir < 0) {
+                    if (DEBUG_TRACKBALL) Log.v(TAG, axis + " reversed to positive!");
+                    position = 0;
+                    step = 0;
+                    acceleration = 1;
+                    lastMoveTime = 0;
+                }
+                dir = 1;
+            } else if (off < 0) {
+                normTime = (long)((-off) * FAST_MOVE_TIME);
+                if (dir > 0) {
+                    if (DEBUG_TRACKBALL) Log.v(TAG, axis + " reversed to negative!");
+                    position = 0;
+                    step = 0;
+                    acceleration = 1;
+                    lastMoveTime = 0;
+                }
+                dir = -1;
+            } else {
+                normTime = 0;
+            }
+
+            // The number of milliseconds between each movement that is
+            // considered "normal" and will not result in any acceleration
+            // or deceleration, scaled by the offset we have here.
+            if (normTime > 0) {
+                long delta = time - lastMoveTime;
+                lastMoveTime = time;
+                float acc = acceleration;
+                if (delta < normTime) {
+                    // The user is scrolling rapidly, so increase acceleration.
+                    float scale = (normTime-delta) * ACCEL_MOVE_SCALING_FACTOR;
+                    if (scale > 1) acc *= scale;
+                    if (DEBUG_TRACKBALL) Log.v(TAG, axis + " accelerate: off="
+                            + off + " normTime=" + normTime + " delta=" + delta
+                            + " scale=" + scale + " acc=" + acc);
+                    acceleration = acc < MAX_ACCELERATION ? acc : MAX_ACCELERATION;
+                } else {
+                    // The user is scrolling slowly, so decrease acceleration.
+                    float scale = (delta-normTime) * ACCEL_MOVE_SCALING_FACTOR;
+                    if (scale > 1) acc /= scale;
+                    if (DEBUG_TRACKBALL) Log.v(TAG, axis + " deccelerate: off="
+                            + off + " normTime=" + normTime + " delta=" + delta
+                            + " scale=" + scale + " acc=" + acc);
+                    acceleration = acc > 1 ? acc : 1;
+                }
+            }
+            position += off;
+            return Math.abs(position);
         }
 
-        private void updateJoystickDirection(MotionEvent event, boolean synthesizeNewKeys) {
+        /**
+         * Generate the number of discrete movement events appropriate for
+         * the currently collected trackball movement.
+         *
+         * @return Returns the number of discrete movements, either positive
+         * or negative, or 0 if there is not enough trackball movement yet
+         * for a discrete movement.
+         */
+        int generate() {
+            int movement = 0;
+            nonAccelMovement = 0;
+            do {
+                final int dir = position >= 0 ? 1 : -1;
+                switch (step) {
+                    // If we are going to execute the first step, then we want
+                    // to do this as soon as possible instead of waiting for
+                    // a full movement, in order to make things look responsive.
+                    case 0:
+                        if (Math.abs(position) < FIRST_MOVEMENT_THRESHOLD) {
+                            return movement;
+                        }
+                        movement += dir;
+                        nonAccelMovement += dir;
+                        step = 1;
+                        break;
+                    // If we have generated the first movement, then we need
+                    // to wait for the second complete trackball motion before
+                    // generating the second discrete movement.
+                    case 1:
+                        if (Math.abs(position) < SECOND_CUMULATIVE_MOVEMENT_THRESHOLD) {
+                            return movement;
+                        }
+                        movement += dir;
+                        nonAccelMovement += dir;
+                        position -= SECOND_CUMULATIVE_MOVEMENT_THRESHOLD * dir;
+                        step = 2;
+                        break;
+                    // After the first two, we generate discrete movements
+                    // consistently with the trackball, applying an acceleration
+                    // if the trackball is moving quickly.  This is a simple
+                    // acceleration on top of what we already compute based
+                    // on how quickly the wheel is being turned, to apply
+                    // a longer increasing acceleration to continuous movement
+                    // in one direction.
+                    default:
+                        if (Math.abs(position) < SUBSEQUENT_INCREMENTAL_MOVEMENT_THRESHOLD) {
+                            return movement;
+                        }
+                        movement += dir;
+                        position -= dir * SUBSEQUENT_INCREMENTAL_MOVEMENT_THRESHOLD;
+                        float acc = acceleration;
+                        acc *= 1.1f;
+                        acceleration = acc < MAX_ACCELERATION ? acc : acceleration;
+                        break;
+                }
+            } while (true);
+        }
+    }
+
+    /**
+     * Creates dpad events from unhandled joystick movements.
+     */
+    final class SyntheticJoystickHandler extends Handler {
+        private final static int MSG_ENQUEUE_X_AXIS_KEY_REPEAT = 1;
+        private final static int MSG_ENQUEUE_Y_AXIS_KEY_REPEAT = 2;
+
+        private int mLastXDirection;
+        private int mLastYDirection;
+        private int mLastXKeyCode;
+        private int mLastYKeyCode;
+
+        public SyntheticJoystickHandler() {
+            super(true);
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case MSG_ENQUEUE_X_AXIS_KEY_REPEAT:
+                case MSG_ENQUEUE_Y_AXIS_KEY_REPEAT: {
+                    KeyEvent oldEvent = (KeyEvent)msg.obj;
+                    KeyEvent e = KeyEvent.changeTimeRepeat(oldEvent,
+                            SystemClock.uptimeMillis(),
+                            oldEvent.getRepeatCount() + 1);
+                    if (mAttachInfo.mHasWindowFocus) {
+                        enqueueInputEvent(e);
+                        Message m = obtainMessage(msg.what, e);
+                        m.setAsynchronous(true);
+                        sendMessageDelayed(m, ViewConfiguration.getKeyRepeatDelay());
+                    }
+                } break;
+            }
+        }
+
+        public void process(MotionEvent event) {
+            update(event, true);
+        }
+
+        public void cancel(MotionEvent event) {
+            update(event, false);
+        }
+
+        private void update(MotionEvent event, boolean synthesizeNewKeys) {
             final long time = event.getEventTime();
             final int metaState = event.getMetaState();
             final int deviceId = event.getDeviceId();
@@ -4082,51 +4264,51 @@
                 yDirection = joystickAxisValueToDirection(event.getY());
             }
 
-            if (xDirection != mLastJoystickXDirection) {
-                if (mLastJoystickXKeyCode != 0) {
-                    mHandler.removeMessages(MSG_ENQUEUE_X_AXIS_KEY_REPEAT);
+            if (xDirection != mLastXDirection) {
+                if (mLastXKeyCode != 0) {
+                    removeMessages(MSG_ENQUEUE_X_AXIS_KEY_REPEAT);
                     enqueueInputEvent(new KeyEvent(time, time,
-                            KeyEvent.ACTION_UP, mLastJoystickXKeyCode, 0, metaState,
+                            KeyEvent.ACTION_UP, mLastXKeyCode, 0, metaState,
                             deviceId, 0, KeyEvent.FLAG_FALLBACK, source));
-                    mLastJoystickXKeyCode = 0;
+                    mLastXKeyCode = 0;
                 }
 
-                mLastJoystickXDirection = xDirection;
+                mLastXDirection = xDirection;
 
                 if (xDirection != 0 && synthesizeNewKeys) {
-                    mLastJoystickXKeyCode = xDirection > 0
+                    mLastXKeyCode = xDirection > 0
                             ? KeyEvent.KEYCODE_DPAD_RIGHT : KeyEvent.KEYCODE_DPAD_LEFT;
                     final KeyEvent e = new KeyEvent(time, time,
-                            KeyEvent.ACTION_DOWN, mLastJoystickXKeyCode, 0, metaState,
+                            KeyEvent.ACTION_DOWN, mLastXKeyCode, 0, metaState,
                             deviceId, 0, KeyEvent.FLAG_FALLBACK, source);
                     enqueueInputEvent(e);
-                    Message m = mHandler.obtainMessage(MSG_ENQUEUE_X_AXIS_KEY_REPEAT, e);
+                    Message m = obtainMessage(MSG_ENQUEUE_X_AXIS_KEY_REPEAT, e);
                     m.setAsynchronous(true);
-                    mHandler.sendMessageDelayed(m, ViewConfiguration.getKeyRepeatTimeout());
+                    sendMessageDelayed(m, ViewConfiguration.getKeyRepeatTimeout());
                 }
             }
 
-            if (yDirection != mLastJoystickYDirection) {
-                if (mLastJoystickYKeyCode != 0) {
-                    mHandler.removeMessages(MSG_ENQUEUE_Y_AXIS_KEY_REPEAT);
+            if (yDirection != mLastYDirection) {
+                if (mLastYKeyCode != 0) {
+                    removeMessages(MSG_ENQUEUE_Y_AXIS_KEY_REPEAT);
                     enqueueInputEvent(new KeyEvent(time, time,
-                            KeyEvent.ACTION_UP, mLastJoystickYKeyCode, 0, metaState,
+                            KeyEvent.ACTION_UP, mLastYKeyCode, 0, metaState,
                             deviceId, 0, KeyEvent.FLAG_FALLBACK, source));
-                    mLastJoystickYKeyCode = 0;
+                    mLastYKeyCode = 0;
                 }
 
-                mLastJoystickYDirection = yDirection;
+                mLastYDirection = yDirection;
 
                 if (yDirection != 0 && synthesizeNewKeys) {
-                    mLastJoystickYKeyCode = yDirection > 0
+                    mLastYKeyCode = yDirection > 0
                             ? KeyEvent.KEYCODE_DPAD_DOWN : KeyEvent.KEYCODE_DPAD_UP;
                     final KeyEvent e = new KeyEvent(time, time,
-                            KeyEvent.ACTION_DOWN, mLastJoystickYKeyCode, 0, metaState,
+                            KeyEvent.ACTION_DOWN, mLastYKeyCode, 0, metaState,
                             deviceId, 0, KeyEvent.FLAG_FALLBACK, source);
                     enqueueInputEvent(e);
-                    Message m = mHandler.obtainMessage(MSG_ENQUEUE_Y_AXIS_KEY_REPEAT, e);
+                    Message m = obtainMessage(MSG_ENQUEUE_Y_AXIS_KEY_REPEAT, e);
                     m.setAsynchronous(true);
-                    mHandler.sendMessageDelayed(m, ViewConfiguration.getKeyRepeatTimeout());
+                    sendMessageDelayed(m, ViewConfiguration.getKeyRepeatTimeout());
                 }
             }
         }
@@ -4140,17 +4322,419 @@
                 return 0;
             }
         }
+    }
 
-        private int processTouchNavigationEvent(QueuedInputEvent q) {
-            final MotionEvent event = (MotionEvent)q.mEvent;
-            mSimulatedDpad.updateTouchNavigation(ViewRootImpl.this, event, true);
-            return FINISH_HANDLED;
+    /**
+     * Creates dpad events from unhandled touch navigation movements.
+     */
+    final class SyntheticTouchNavigationHandler extends Handler {
+        private static final String LOCAL_TAG = "SyntheticTouchNavigationHandler";
+        private static final boolean LOCAL_DEBUG = false;
+
+        // Assumed nominal width and height in millimeters of a touch navigation pad,
+        // if no resolution information is available from the input system.
+        private static final float DEFAULT_WIDTH_MILLIMETERS = 48;
+        private static final float DEFAULT_HEIGHT_MILLIMETERS = 48;
+
+        /* TODO: These constants should eventually be moved to ViewConfiguration. */
+
+        // Tap timeout in milliseconds.
+        private static final int TAP_TIMEOUT = 250;
+
+        // The maximum distance traveled for a gesture to be considered a tap in millimeters.
+        private static final int TAP_SLOP_MILLIMETERS = 5;
+
+        // The nominal distance traveled to move by one unit.
+        private static final int TICK_DISTANCE_MILLIMETERS = 12;
+
+        // Minimum and maximum fling velocity in ticks per second.
+        // The minimum velocity should be set such that we perform enough ticks per
+        // second that the fling appears to be fluid.  For example, if we set the minimum
+        // to 2 ticks per second, then there may be up to half a second delay between the next
+        // to last and last ticks which is noticeably discrete and jerky.  This value should
+        // probably not be set to anything less than about 4.
+        // If fling accuracy is a problem then consider tuning the tick distance instead.
+        private static final float MIN_FLING_VELOCITY_TICKS_PER_SECOND = 6f;
+        private static final float MAX_FLING_VELOCITY_TICKS_PER_SECOND = 20f;
+
+        // Fling velocity decay factor applied after each new key is emitted.
+        // This parameter controls the deceleration and overall duration of the fling.
+        // The fling stops automatically when its velocity drops below the minimum
+        // fling velocity defined above.
+        private static final float FLING_TICK_DECAY = 0.8f;
+
+        /* The input device that we are tracking. */
+
+        private int mCurrentDeviceId = -1;
+        private int mCurrentSource;
+        private boolean mCurrentDeviceSupported;
+
+        /* Configuration for the current input device. */
+
+        // The tap timeout and scaled slop.
+        private int mConfigTapTimeout;
+        private float mConfigTapSlop;
+
+        // The scaled tick distance.  A movement of this amount should generally translate
+        // into a single dpad event in a given direction.
+        private float mConfigTickDistance;
+
+        // The minimum and maximum scaled fling velocity.
+        private float mConfigMinFlingVelocity;
+        private float mConfigMaxFlingVelocity;
+
+        /* Tracking state. */
+
+        // The velocity tracker for detecting flings.
+        private VelocityTracker mVelocityTracker;
+
+        // The active pointer id, or -1 if none.
+        private int mActivePointerId = -1;
+
+        // Time and location where tracking started.
+        private long mStartTime;
+        private float mStartX;
+        private float mStartY;
+
+        // Most recently observed position.
+        private float mLastX;
+        private float mLastY;
+
+        // Accumulated movement delta since the last direction key was sent.
+        private float mAccumulatedX;
+        private float mAccumulatedY;
+
+        // Set to true if any movement was delivered to the app.
+        // Implies that tap slop was exceeded.
+        private boolean mConsumedMovement;
+
+        // The most recently sent key down event.
+        // The keycode remains set until the direction changes or a fling ends
+        // so that repeated key events may be generated as required.
+        private long mPendingKeyDownTime;
+        private int mPendingKeyCode = KeyEvent.KEYCODE_UNKNOWN;
+        private int mPendingKeyRepeatCount;
+        private int mPendingKeyMetaState;
+
+        // The current fling velocity while a fling is in progress.
+        private boolean mFlinging;
+        private float mFlingVelocity;
+
+        public SyntheticTouchNavigationHandler() {
+            super(true);
         }
 
-        private void cancelTouchNavigationEvent(QueuedInputEvent q) {
-            final MotionEvent event = (MotionEvent)q.mEvent;
-            mSimulatedDpad.updateTouchNavigation(ViewRootImpl.this, event, false);
+        public void process(MotionEvent event) {
+            // Update the current device information.
+            final long time = event.getEventTime();
+            final int deviceId = event.getDeviceId();
+            final int source = event.getSource();
+            if (mCurrentDeviceId != deviceId || mCurrentSource != source) {
+                finishKeys(time);
+                finishTracking(time);
+                mCurrentDeviceId = deviceId;
+                mCurrentSource = source;
+                mCurrentDeviceSupported = false;
+                InputDevice device = event.getDevice();
+                if (device != null) {
+                    // In order to support an input device, we must know certain
+                    // characteristics about it, such as its size and resolution.
+                    InputDevice.MotionRange xRange = device.getMotionRange(MotionEvent.AXIS_X);
+                    InputDevice.MotionRange yRange = device.getMotionRange(MotionEvent.AXIS_Y);
+                    if (xRange != null && yRange != null) {
+                        mCurrentDeviceSupported = true;
+
+                        // Infer the resolution if it not actually known.
+                        float xRes = xRange.getResolution();
+                        if (xRes <= 0) {
+                            xRes = xRange.getRange() / DEFAULT_WIDTH_MILLIMETERS;
+                        }
+                        float yRes = yRange.getResolution();
+                        if (yRes <= 0) {
+                            yRes = yRange.getRange() / DEFAULT_HEIGHT_MILLIMETERS;
+                        }
+                        float nominalRes = (xRes + yRes) * 0.5f;
+
+                        // Precompute all of the configuration thresholds we will need.
+                        mConfigTapTimeout = TAP_TIMEOUT;
+                        mConfigTapSlop = TAP_SLOP_MILLIMETERS * nominalRes;
+                        mConfigTickDistance = TICK_DISTANCE_MILLIMETERS * nominalRes;
+                        mConfigMinFlingVelocity =
+                                MIN_FLING_VELOCITY_TICKS_PER_SECOND * mConfigTickDistance;
+                        mConfigMaxFlingVelocity =
+                                MAX_FLING_VELOCITY_TICKS_PER_SECOND * mConfigTickDistance;
+
+                        if (LOCAL_DEBUG) {
+                            Log.d(LOCAL_TAG, "Configured device " + mCurrentDeviceId
+                                    + " (" + Integer.toHexString(mCurrentSource) + "): "
+                                    + "mConfigTapTimeout=" + mConfigTapTimeout
+                                    + ", mConfigTapSlop=" + mConfigTapSlop
+                                    + ", mConfigTickDistance=" + mConfigTickDistance
+                                    + ", mConfigMinFlingVelocity=" + mConfigMinFlingVelocity
+                                    + ", mConfigMaxFlingVelocity=" + mConfigMaxFlingVelocity);
+                        }
+                    }
+                }
+            }
+            if (!mCurrentDeviceSupported) {
+                return;
+            }
+
+            // Handle the event.
+            final int action = event.getActionMasked();
+            switch (action) {
+                case MotionEvent.ACTION_DOWN: {
+                    boolean caughtFling = mFlinging;
+                    finishKeys(time);
+                    finishTracking(time);
+                    mActivePointerId = event.getPointerId(0);
+                    mVelocityTracker = VelocityTracker.obtain();
+                    mVelocityTracker.addMovement(event);
+                    mStartTime = time;
+                    mStartX = event.getX();
+                    mStartY = event.getY();
+                    mLastX = mStartX;
+                    mLastY = mStartY;
+                    mAccumulatedX = 0;
+                    mAccumulatedY = 0;
+
+                    // If we caught a fling, then pretend that the tap slop has already
+                    // been exceeded to suppress taps whose only purpose is to stop the fling.
+                    mConsumedMovement = caughtFling;
+                    break;
+                }
+
+                case MotionEvent.ACTION_MOVE:
+                case MotionEvent.ACTION_UP: {
+                    if (mActivePointerId < 0) {
+                        break;
+                    }
+                    final int index = event.findPointerIndex(mActivePointerId);
+                    if (index < 0) {
+                        finishKeys(time);
+                        finishTracking(time);
+                        break;
+                    }
+
+                    mVelocityTracker.addMovement(event);
+                    final float x = event.getX(index);
+                    final float y = event.getY(index);
+                    mAccumulatedX += x - mLastX;
+                    mAccumulatedY += y - mLastY;
+                    mLastX = x;
+                    mLastY = y;
+
+                    // Consume any accumulated movement so far.
+                    final int metaState = event.getMetaState();
+                    consumeAccumulatedMovement(time, metaState);
+
+                    // Detect taps and flings.
+                    if (action == MotionEvent.ACTION_UP) {
+                        if (!mConsumedMovement
+                                && Math.hypot(mLastX - mStartX, mLastY - mStartY) < mConfigTapSlop
+                                && time <= mStartTime + mConfigTapTimeout) {
+                            // It's a tap!
+                            finishKeys(time);
+                            sendKeyDownOrRepeat(time, KeyEvent.KEYCODE_DPAD_CENTER, metaState);
+                            sendKeyUp(time);
+                        } else if (mConsumedMovement
+                                && mPendingKeyCode != KeyEvent.KEYCODE_UNKNOWN) {
+                            // It might be a fling.
+                            mVelocityTracker.computeCurrentVelocity(1000, mConfigMaxFlingVelocity);
+                            final float vx = mVelocityTracker.getXVelocity(mActivePointerId);
+                            final float vy = mVelocityTracker.getYVelocity(mActivePointerId);
+                            if (!startFling(time, vx, vy)) {
+                                finishKeys(time);
+                            }
+                        }
+                        finishTracking(time);
+                    }
+                    break;
+                }
+
+                case MotionEvent.ACTION_CANCEL: {
+                    finishKeys(time);
+                    finishTracking(time);
+                    break;
+                }
+            }
         }
+
+        public void cancel(MotionEvent event) {
+            if (mCurrentDeviceId == event.getDeviceId()
+                    && mCurrentSource == event.getSource()) {
+                final long time = event.getEventTime();
+                finishKeys(time);
+                finishTracking(time);
+            }
+        }
+
+        private void finishKeys(long time) {
+            cancelFling();
+            sendKeyUp(time);
+        }
+
+        private void finishTracking(long time) {
+            if (mActivePointerId >= 0) {
+                mActivePointerId = -1;
+                mVelocityTracker.recycle();
+                mVelocityTracker = null;
+            }
+        }
+
+        private void consumeAccumulatedMovement(long time, int metaState) {
+            final float absX = Math.abs(mAccumulatedX);
+            final float absY = Math.abs(mAccumulatedY);
+            if (absX >= absY) {
+                if (absX >= mConfigTickDistance) {
+                    mAccumulatedX = consumeAccumulatedMovement(time, metaState, mAccumulatedX,
+                            KeyEvent.KEYCODE_DPAD_LEFT, KeyEvent.KEYCODE_DPAD_RIGHT);
+                    mAccumulatedY = 0;
+                    mConsumedMovement = true;
+                }
+            } else {
+                if (absY >= mConfigTickDistance) {
+                    mAccumulatedY = consumeAccumulatedMovement(time, metaState, mAccumulatedY,
+                            KeyEvent.KEYCODE_DPAD_UP, KeyEvent.KEYCODE_DPAD_DOWN);
+                    mAccumulatedX = 0;
+                    mConsumedMovement = true;
+                }
+            }
+        }
+
+        private float consumeAccumulatedMovement(long time, int metaState,
+                float accumulator, int negativeKeyCode, int positiveKeyCode) {
+            while (accumulator <= -mConfigTickDistance) {
+                sendKeyDownOrRepeat(time, negativeKeyCode, metaState);
+                accumulator += mConfigTickDistance;
+            }
+            while (accumulator >= mConfigTickDistance) {
+                sendKeyDownOrRepeat(time, positiveKeyCode, metaState);
+                accumulator -= mConfigTickDistance;
+            }
+            return accumulator;
+        }
+
+        private void sendKeyDownOrRepeat(long time, int keyCode, int metaState) {
+            if (mPendingKeyCode != keyCode) {
+                sendKeyUp(time);
+                mPendingKeyDownTime = time;
+                mPendingKeyCode = keyCode;
+                mPendingKeyRepeatCount = 0;
+            } else {
+                mPendingKeyRepeatCount += 1;
+            }
+            mPendingKeyMetaState = metaState;
+
+            // Note: Normally we would pass FLAG_LONG_PRESS when the repeat count is 1
+            // but it doesn't quite make sense when simulating the events in this way.
+            if (LOCAL_DEBUG) {
+                Log.d(LOCAL_TAG, "Sending key down: keyCode=" + mPendingKeyCode
+                        + ", repeatCount=" + mPendingKeyRepeatCount
+                        + ", metaState=" + Integer.toHexString(mPendingKeyMetaState));
+            }
+            enqueueInputEvent(new KeyEvent(mPendingKeyDownTime, time,
+                    KeyEvent.ACTION_DOWN, mPendingKeyCode, mPendingKeyRepeatCount,
+                    mPendingKeyMetaState, mCurrentDeviceId,
+                    KeyEvent.FLAG_FALLBACK, mCurrentSource));
+        }
+
+        private void sendKeyUp(long time) {
+            if (mPendingKeyCode != KeyEvent.KEYCODE_UNKNOWN) {
+                if (LOCAL_DEBUG) {
+                    Log.d(LOCAL_TAG, "Sending key up: keyCode=" + mPendingKeyCode
+                            + ", metaState=" + Integer.toHexString(mPendingKeyMetaState));
+                }
+                enqueueInputEvent(new KeyEvent(mPendingKeyDownTime, time,
+                        KeyEvent.ACTION_UP, mPendingKeyCode, 0, mPendingKeyMetaState,
+                        mCurrentDeviceId, 0, KeyEvent.FLAG_FALLBACK,
+                        mCurrentSource));
+                mPendingKeyCode = KeyEvent.KEYCODE_UNKNOWN;
+            }
+        }
+
+        private boolean startFling(long time, float vx, float vy) {
+            if (LOCAL_DEBUG) {
+                Log.d(LOCAL_TAG, "Considering fling: vx=" + vx + ", vy=" + vy
+                        + ", min=" + mConfigMinFlingVelocity);
+            }
+
+            // Flings must be oriented in the same direction as the preceding movements.
+            switch (mPendingKeyCode) {
+                case KeyEvent.KEYCODE_DPAD_LEFT:
+                    if (-vx >= mConfigMinFlingVelocity
+                            && Math.abs(vy) < mConfigMinFlingVelocity) {
+                        mFlingVelocity = -vx;
+                        break;
+                    }
+                    return false;
+
+                case KeyEvent.KEYCODE_DPAD_RIGHT:
+                    if (vx >= mConfigMinFlingVelocity
+                            && Math.abs(vy) < mConfigMinFlingVelocity) {
+                        mFlingVelocity = vx;
+                        break;
+                    }
+                    return false;
+
+                case KeyEvent.KEYCODE_DPAD_UP:
+                    if (-vy >= mConfigMinFlingVelocity
+                            && Math.abs(vx) < mConfigMinFlingVelocity) {
+                        mFlingVelocity = -vy;
+                        break;
+                    }
+                    return false;
+
+                case KeyEvent.KEYCODE_DPAD_DOWN:
+                    if (vy >= mConfigMinFlingVelocity
+                            && Math.abs(vx) < mConfigMinFlingVelocity) {
+                        mFlingVelocity = vy;
+                        break;
+                    }
+                    return false;
+            }
+
+            // Post the first fling event.
+            mFlinging = postFling(time);
+            return mFlinging;
+        }
+
+        private boolean postFling(long time) {
+            // The idea here is to estimate the time when the pointer would have
+            // traveled one tick distance unit given the current fling velocity.
+            // This effect creates continuity of motion.
+            if (mFlingVelocity >= mConfigMinFlingVelocity) {
+                long delay = (long)(mConfigTickDistance / mFlingVelocity * 1000);
+                postAtTime(mFlingRunnable, time + delay);
+                if (LOCAL_DEBUG) {
+                    Log.d(LOCAL_TAG, "Posted fling: velocity="
+                            + mFlingVelocity + ", delay=" + delay
+                            + ", keyCode=" + mPendingKeyCode);
+                }
+                return true;
+            }
+            return false;
+        }
+
+        private void cancelFling() {
+            if (mFlinging) {
+                removeCallbacks(mFlingRunnable);
+                mFlinging = false;
+            }
+        }
+
+        private final Runnable mFlingRunnable = new Runnable() {
+            @Override
+            public void run() {
+                final long time = SystemClock.uptimeMillis();
+                sendKeyDownOrRepeat(time, mPendingKeyCode, mPendingKeyMetaState);
+                mFlingVelocity *= FLING_TICK_DECAY;
+                if (!postFling(time)) {
+                    mFlinging = false;
+                    finishKeys(time);
+                }
+            }
+        };
     }
 
     /**
@@ -5487,174 +6071,6 @@
         }
     }
 
-    /**
-     * Maintains state information for a single trackball axis, generating
-     * discrete (DPAD) movements based on raw trackball motion.
-     */
-    static final class TrackballAxis {
-        /**
-         * The maximum amount of acceleration we will apply.
-         */
-        static final float MAX_ACCELERATION = 20;
-
-        /**
-         * The maximum amount of time (in milliseconds) between events in order
-         * for us to consider the user to be doing fast trackball movements,
-         * and thus apply an acceleration.
-         */
-        static final long FAST_MOVE_TIME = 150;
-
-        /**
-         * Scaling factor to the time (in milliseconds) between events to how
-         * much to multiple/divide the current acceleration.  When movement
-         * is < FAST_MOVE_TIME this multiplies the acceleration; when >
-         * FAST_MOVE_TIME it divides it.
-         */
-        static final float ACCEL_MOVE_SCALING_FACTOR = (1.0f/40);
-
-        static final float FIRST_MOVEMENT_THRESHOLD = 0.5f;
-        static final float SECOND_CUMULATIVE_MOVEMENT_THRESHOLD = 2.0f;
-        static final float SUBSEQUENT_INCREMENTAL_MOVEMENT_THRESHOLD = 1.0f;
-
-        float position;
-        float acceleration = 1;
-        long lastMoveTime = 0;
-        int step;
-        int dir;
-        int nonAccelMovement;
-
-        void reset(int _step) {
-            position = 0;
-            acceleration = 1;
-            lastMoveTime = 0;
-            step = _step;
-            dir = 0;
-        }
-
-        /**
-         * Add trackball movement into the state.  If the direction of movement
-         * has been reversed, the state is reset before adding the
-         * movement (so that you don't have to compensate for any previously
-         * collected movement before see the result of the movement in the
-         * new direction).
-         *
-         * @return Returns the absolute value of the amount of movement
-         * collected so far.
-         */
-        float collect(float off, long time, String axis) {
-            long normTime;
-            if (off > 0) {
-                normTime = (long)(off * FAST_MOVE_TIME);
-                if (dir < 0) {
-                    if (DEBUG_TRACKBALL) Log.v(TAG, axis + " reversed to positive!");
-                    position = 0;
-                    step = 0;
-                    acceleration = 1;
-                    lastMoveTime = 0;
-                }
-                dir = 1;
-            } else if (off < 0) {
-                normTime = (long)((-off) * FAST_MOVE_TIME);
-                if (dir > 0) {
-                    if (DEBUG_TRACKBALL) Log.v(TAG, axis + " reversed to negative!");
-                    position = 0;
-                    step = 0;
-                    acceleration = 1;
-                    lastMoveTime = 0;
-                }
-                dir = -1;
-            } else {
-                normTime = 0;
-            }
-
-            // The number of milliseconds between each movement that is
-            // considered "normal" and will not result in any acceleration
-            // or deceleration, scaled by the offset we have here.
-            if (normTime > 0) {
-                long delta = time - lastMoveTime;
-                lastMoveTime = time;
-                float acc = acceleration;
-                if (delta < normTime) {
-                    // The user is scrolling rapidly, so increase acceleration.
-                    float scale = (normTime-delta) * ACCEL_MOVE_SCALING_FACTOR;
-                    if (scale > 1) acc *= scale;
-                    if (DEBUG_TRACKBALL) Log.v(TAG, axis + " accelerate: off="
-                            + off + " normTime=" + normTime + " delta=" + delta
-                            + " scale=" + scale + " acc=" + acc);
-                    acceleration = acc < MAX_ACCELERATION ? acc : MAX_ACCELERATION;
-                } else {
-                    // The user is scrolling slowly, so decrease acceleration.
-                    float scale = (delta-normTime) * ACCEL_MOVE_SCALING_FACTOR;
-                    if (scale > 1) acc /= scale;
-                    if (DEBUG_TRACKBALL) Log.v(TAG, axis + " deccelerate: off="
-                            + off + " normTime=" + normTime + " delta=" + delta
-                            + " scale=" + scale + " acc=" + acc);
-                    acceleration = acc > 1 ? acc : 1;
-                }
-            }
-            position += off;
-            return Math.abs(position);
-        }
-
-        /**
-         * Generate the number of discrete movement events appropriate for
-         * the currently collected trackball movement.
-         *
-         * @return Returns the number of discrete movements, either positive
-         * or negative, or 0 if there is not enough trackball movement yet
-         * for a discrete movement.
-         */
-        int generate() {
-            int movement = 0;
-            nonAccelMovement = 0;
-            do {
-                final int dir = position >= 0 ? 1 : -1;
-                switch (step) {
-                    // If we are going to execute the first step, then we want
-                    // to do this as soon as possible instead of waiting for
-                    // a full movement, in order to make things look responsive.
-                    case 0:
-                        if (Math.abs(position) < FIRST_MOVEMENT_THRESHOLD) {
-                            return movement;
-                        }
-                        movement += dir;
-                        nonAccelMovement += dir;
-                        step = 1;
-                        break;
-                    // If we have generated the first movement, then we need
-                    // to wait for the second complete trackball motion before
-                    // generating the second discrete movement.
-                    case 1:
-                        if (Math.abs(position) < SECOND_CUMULATIVE_MOVEMENT_THRESHOLD) {
-                            return movement;
-                        }
-                        movement += dir;
-                        nonAccelMovement += dir;
-                        position -= SECOND_CUMULATIVE_MOVEMENT_THRESHOLD * dir;
-                        step = 2;
-                        break;
-                    // After the first two, we generate discrete movements
-                    // consistently with the trackball, applying an acceleration
-                    // if the trackball is moving quickly.  This is a simple
-                    // acceleration on top of what we already compute based
-                    // on how quickly the wheel is being turned, to apply
-                    // a longer increasing acceleration to continuous movement
-                    // in one direction.
-                    default:
-                        if (Math.abs(position) < SUBSEQUENT_INCREMENTAL_MOVEMENT_THRESHOLD) {
-                            return movement;
-                        }
-                        movement += dir;
-                        position -= dir * SUBSEQUENT_INCREMENTAL_MOVEMENT_THRESHOLD;
-                        float acc = acceleration;
-                        acc *= 1.1f;
-                        acceleration = acc < MAX_ACCELERATION ? acc : acceleration;
-                        break;
-                }
-            } while (true);
-        }
-    }
-
     public static final class CalledFromWrongThreadException extends AndroidRuntimeException {
         public CalledFromWrongThreadException(String msg) {
             super(msg);
diff --git a/core/java/android/webkit/WebSettings.java b/core/java/android/webkit/WebSettings.java
index d901d0a..8ae0021 100644
--- a/core/java/android/webkit/WebSettings.java
+++ b/core/java/android/webkit/WebSettings.java
@@ -1004,6 +1004,7 @@
      * @param flag true if plugins should be enabled
      * @deprecated This method has been deprecated in favor of
      *             {@link #setPluginState}
+     * @hide Since API level {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}
      */
     @Deprecated
     public synchronized void setPluginsEnabled(boolean flag) {
@@ -1032,6 +1033,7 @@
      * @param pluginsPath a String path to the directory containing plugins
      * @deprecated This method is no longer used as plugins are loaded from
      *             their own APK via the system's package manager.
+     * @hide Since API level {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}
      */
     @Deprecated
     public synchronized void setPluginsPath(String pluginsPath) {
@@ -1224,6 +1226,7 @@
      * @return true if plugins are enabled
      * @see #setPluginsEnabled
      * @deprecated This method has been replaced by {@link #getPluginState}
+     * @hide Since API level {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}
      */
     @Deprecated
     public synchronized boolean getPluginsEnabled() {
@@ -1249,6 +1252,7 @@
      * @return an empty string
      * @deprecated This method is no longer used as plugins are loaded from
      * their own APK via the system's package manager.
+     * @hide Since API level {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}
      */
     @Deprecated
     public synchronized String getPluginsPath() {
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 3fa0940..94dadb4 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -2606,7 +2606,7 @@
             mGlobalLayoutListenerAddedFilter = false;
         }
 
-        if (mAdapter != null) {
+        if (mAdapter != null && mDataSetObserver != null) {
             mAdapter.unregisterDataSetObserver(mDataSetObserver);
             mDataSetObserver = null;
         }
diff --git a/core/java/android/widget/Spinner.java b/core/java/android/widget/Spinner.java
index b6895a5..e3de0b9 100644
--- a/core/java/android/widget/Spinner.java
+++ b/core/java/android/widget/Spinner.java
@@ -494,20 +494,23 @@
 
         // Make selected view and position it
         mFirstPosition = mSelectedPosition;
-        View sel = makeAndAddView(mSelectedPosition);
-        int width = sel.getMeasuredWidth();
-        int selectedOffset = childrenLeft;
-        final int layoutDirection = getLayoutDirection();
-        final int absoluteGravity = Gravity.getAbsoluteGravity(mGravity, layoutDirection);
-        switch (absoluteGravity & Gravity.HORIZONTAL_GRAVITY_MASK) {
-            case Gravity.CENTER_HORIZONTAL:
-                selectedOffset = childrenLeft + (childrenWidth / 2) - (width / 2);
-                break;
-            case Gravity.RIGHT:
-                selectedOffset = childrenLeft + childrenWidth - width;
-                break;
+
+        if (mAdapter != null) {
+            View sel = makeAndAddView(mSelectedPosition);
+            int width = sel.getMeasuredWidth();
+            int selectedOffset = childrenLeft;
+            final int layoutDirection = getLayoutDirection();
+            final int absoluteGravity = Gravity.getAbsoluteGravity(mGravity, layoutDirection);
+            switch (absoluteGravity & Gravity.HORIZONTAL_GRAVITY_MASK) {
+                case Gravity.CENTER_HORIZONTAL:
+                    selectedOffset = childrenLeft + (childrenWidth / 2) - (width / 2);
+                    break;
+                case Gravity.RIGHT:
+                    selectedOffset = childrenLeft + childrenWidth - width;
+                    break;
+            }
+            sel.offsetLeftAndRight(selectedOffset);
         }
-        sel.offsetLeftAndRight(selectedOffset);
 
         // Flush any cached views that did not get reused above
         mRecycler.clear();
diff --git a/core/java/com/android/internal/widget/ScrollingTabContainerView.java b/core/java/com/android/internal/widget/ScrollingTabContainerView.java
index b620568..04931e7 100644
--- a/core/java/com/android/internal/widget/ScrollingTabContainerView.java
+++ b/core/java/com/android/internal/widget/ScrollingTabContainerView.java
@@ -179,6 +179,9 @@
                 animateToTab(position);
             }
         }
+        if (mTabSpinner != null && position >= 0) {
+            mTabSpinner.setSelection(position);
+        }
     }
 
     public void setContentHeight(int contentHeight) {
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index 66cea9d7..3e5586e 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -179,6 +179,7 @@
 	libandroidfw \
 	libexpat \
 	libnativehelper \
+	liblog \
 	libcutils \
 	libutils \
 	libbinder \
diff --git a/core/jni/android/graphics/Canvas.cpp b/core/jni/android/graphics/Canvas.cpp
index 9a9f6c8..11c7053 100644
--- a/core/jni/android/graphics/Canvas.cpp
+++ b/core/jni/android/graphics/Canvas.cpp
@@ -77,7 +77,14 @@
     }
 
     static SkCanvas* initRaster(JNIEnv* env, jobject, SkBitmap* bitmap) {
-        return bitmap ? new SkCanvas(*bitmap) : new SkCanvas;
+        if (bitmap) {
+            return new SkCanvas(*bitmap);
+        } else {
+            // Create an empty bitmap device to prevent callers from crashing
+            // if they attempt to draw into this canvas.
+            SkBitmap emptyBitmap;
+            return new SkCanvas(emptyBitmap);
+        }
     }
     
     static void copyCanvasState(JNIEnv* env, jobject clazz,
diff --git a/core/jni/android_os_Trace.cpp b/core/jni/android_os_Trace.cpp
index f028c86d..00ecd0a 100644
--- a/core/jni/android_os_Trace.cpp
+++ b/core/jni/android_os_Trace.cpp
@@ -18,6 +18,9 @@
 
 #include <JNIHelp.h>
 #include <ScopedUtfChars.h>
+#include <ScopedStringChars.h>
+
+#include <utils/String8.h>
 
 #include <cutils/trace.h>
 #include <cutils/log.h>
@@ -36,8 +39,20 @@
 
 static void android_os_Trace_nativeTraceBegin(JNIEnv* env, jclass clazz,
         jlong tag, jstring nameStr) {
-    ScopedUtfChars name(env, nameStr);
-    atrace_begin(tag, name.c_str());
+    const size_t MAX_SECTION_NAME_LEN = 127;
+    ScopedStringChars jchars(env, nameStr);
+    String8 utf8Chars(reinterpret_cast<const char16_t*>(jchars.get()),
+            jchars.size());
+    size_t size = utf8Chars.size();
+    char* str = utf8Chars.lockBuffer(size);
+    for (size_t i = 0; i < size; i++) {
+        char c = str[i];
+        if (c == '\0' || c == '\n' || c == '|') {
+            str[i] = ' ';
+        }
+    }
+    utf8Chars.unlockBuffer();
+    atrace_begin(tag, utf8Chars.string());
 }
 
 static void android_os_Trace_nativeTraceEnd(JNIEnv* env, jclass clazz,
@@ -45,6 +60,11 @@
     atrace_end(tag);
 }
 
+static void android_os_Trace_nativeSetAppTracingAllowed(JNIEnv* env,
+        jclass clazz, jboolean allowed) {
+    atrace_set_debuggable(allowed);
+}
+
 static JNINativeMethod gTraceMethods[] = {
     /* name, signature, funcPtr */
     { "nativeGetEnabledTags",
@@ -59,6 +79,9 @@
     { "nativeTraceEnd",
             "(J)V",
             (void*)android_os_Trace_nativeTraceEnd },
+    { "nativeSetAppTracingAllowed",
+            "(Z)V",
+            (void*)android_os_Trace_nativeSetAppTracingAllowed },
 };
 
 int register_android_os_Trace(JNIEnv* env) {
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 90e3b8d..6b4fe79 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -616,6 +616,14 @@
         android:label="@string/permlab_installLocationProvider"
         android:description="@string/permdesc_installLocationProvider" />
 
+    <!-- Allows an application to use location features in hardware,
+         such as the geofencing api
+         Protected by signature|system protection level -->
+    <permission android:name="android.permission.LOCATION_HARDWARE"
+        android:permissionGroup="android.permission-group.LOCATION"
+        android:protectionLevel="signature|system" />
+    <uses-permission android:name="android.permission.LOCATION_HARDWARE"/>
+
     <!-- ======================================= -->
     <!-- Permissions for accessing networks -->
     <!-- ======================================= -->
@@ -2264,6 +2272,14 @@
                 android:process=":ui">
         </activity>
 
+        <activity android:name="android.accounts.CantAddAccountActivity"
+                android:excludeFromRecents="true"
+                android:exported="true"
+                android:theme="@android:style/Theme.Holo.Dialog"
+                android:label="@string/error_message_title"
+                android:process=":ui">
+        </activity>
+
         <activity android:name="android.accounts.GrantCredentialsPermissionActivity"
                 android:excludeFromRecents="true"
                 android:exported="true"
@@ -2350,6 +2366,9 @@
             android:permission="android.permission.MASTER_CLEAR"
             android:exported="true" />
 
+        <service android:name="android.hardware.location.GeofenceHardwareService"
+            android:permission="android.permission.LOCATION_HARDWARE"
+            android:exported="false" />
     </application>
 
 </manifest>
diff --git a/core/res/res/anim/rotation_animation_xfade_exit.xml b/core/res/res/anim/rotation_animation_xfade_exit.xml
index 7300724..1dedde4 100644
--- a/core/res/res/anim/rotation_animation_xfade_exit.xml
+++ b/core/res/res/anim/rotation_animation_xfade_exit.xml
@@ -18,6 +18,6 @@
 
 <set xmlns:android="http://schemas.android.com/apk/res/android">
     <alpha android:fromAlpha="1.0" android:toAlpha="0.0"
-            android:duration="500"
+            android:duration="150"
             android:interpolator="@interpolator/decelerate_quad" />
 </set>
diff --git a/core/res/res/drawable-hdpi/menu_popup_panel_holo_dark.9.png b/core/res/res/drawable-hdpi/menu_popup_panel_holo_dark.9.png
new file mode 100644
index 0000000..e5ff886
--- /dev/null
+++ b/core/res/res/drawable-hdpi/menu_popup_panel_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/menu_popup_panel_holo_light.9.png b/core/res/res/drawable-hdpi/menu_popup_panel_holo_light.9.png
new file mode 100644
index 0000000..06d1653
--- /dev/null
+++ b/core/res/res/drawable-hdpi/menu_popup_panel_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/menu_popup_panel_holo_dark.9.png b/core/res/res/drawable-mdpi/menu_popup_panel_holo_dark.9.png
new file mode 100644
index 0000000..2020a42
--- /dev/null
+++ b/core/res/res/drawable-mdpi/menu_popup_panel_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/menu_popup_panel_holo_light.9.png b/core/res/res/drawable-mdpi/menu_popup_panel_holo_light.9.png
new file mode 100644
index 0000000..7cae402
--- /dev/null
+++ b/core/res/res/drawable-mdpi/menu_popup_panel_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/menu_popup_panel_holo_dark.9.png b/core/res/res/drawable-xhdpi/menu_popup_panel_holo_dark.9.png
new file mode 100644
index 0000000..e85b0c2
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/menu_popup_panel_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/menu_popup_panel_holo_light.9.png b/core/res/res/drawable-xhdpi/menu_popup_panel_holo_light.9.png
new file mode 100644
index 0000000..eea215d
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/menu_popup_panel_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable/menu_panel_holo_dark.xml b/core/res/res/drawable/menu_panel_holo_dark.xml
new file mode 100644
index 0000000..658a3ac
--- /dev/null
+++ b/core/res/res/drawable/menu_panel_holo_dark.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_above_anchor="true" android:drawable="@android:drawable/menu_popup_panel_holo_dark" />
+    <item android:drawable="@android:drawable/menu_dropdown_panel_holo_dark" />
+</selector>
diff --git a/core/res/res/drawable/menu_panel_holo_light.xml b/core/res/res/drawable/menu_panel_holo_light.xml
new file mode 100644
index 0000000..a37e934
--- /dev/null
+++ b/core/res/res/drawable/menu_panel_holo_light.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_above_anchor="true" android:drawable="@android:drawable/menu_popup_panel_holo_light" />
+    <item android:drawable="@android:drawable/menu_dropdown_panel_holo_light" />
+</selector>
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 1e266ed..ce76d40 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -621,6 +621,10 @@
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Laat die program toe om te verander hoe netwerkgebruik teenoor programme gemeet word. Nie vir gebruik deur normale programme nie."</string>
     <string name="permlab_accessNotifications" msgid="7673416487873432268">"kry toegang tot kennisgewings"</string>
     <string name="permdesc_accessNotifications" msgid="458457742683431387">"Laat die program toe om kennisgewings op te haal, te bestudeer en te verwyder, insluitende die kennisgewings wat deur ander programme geplaas is."</string>
+    <!-- no translation found for permlab_bindNotificationListenerService (7057764742211656654) -->
+    <skip />
+    <!-- no translation found for permdesc_bindNotificationListenerService (985697918576902986) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Stel wagwoordreëls"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Beheer lengte en watter karakters wat in die skermontsluit-wagwoorde gebruik word."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Monitor pogings om skerm te ontsluit"</string>
@@ -1048,8 +1052,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Teksaksies"</string>
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Bergingspasie word min"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Sommige stelselfunksies werk moontlik nie"</string>
-    <string name="app_running_notification_title" msgid="4625479411505090209">"<xliff:g id="APP_NAME">%1$s</xliff:g> loop"</string>
-    <string name="app_running_notification_text" msgid="3368349329989620597">"<xliff:g id="APP_NAME">%1$s</xliff:g> loop tans"</string>
+    <!-- no translation found for app_running_notification_title (8718335121060787914) -->
+    <skip />
+    <!-- no translation found for app_running_notification_text (4653586947747330058) -->
+    <skip />
     <string name="ok" msgid="5970060430562524910">"OK"</string>
     <string name="cancel" msgid="6442560571259935130">"Kanselleer"</string>
     <string name="yes" msgid="5362982303337969312">"OK"</string>
@@ -1267,6 +1273,8 @@
     <string name="accessibility_binding_label" msgid="4148120742096474641">"Toeganklikheid"</string>
     <string name="wallpaper_binding_label" msgid="1240087844304687662">"Muurpapier"</string>
     <string name="chooser_wallpaper" msgid="7873476199295190279">"Verander muurpapier"</string>
+    <!-- no translation found for notification_listener_binding_label (2014162835481906429) -->
+    <skip />
     <string name="vpn_title" msgid="19615213552042827">"VPN geaktiveer"</string>
     <string name="vpn_title_long" msgid="6400714798049252294">"VPN is geaktiveer deur <xliff:g id="APP">%s</xliff:g>"</string>
     <string name="vpn_text" msgid="3011306607126450322">"Raak om die netwerk te bestuur."</string>
@@ -1370,6 +1378,10 @@
     <string name="action_bar_home_description" msgid="5293600496601490216">"Navigeer tuis"</string>
     <string name="action_bar_up_description" msgid="2237496562952152589">"Navigeer op"</string>
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"Meer opsies"</string>
+    <!-- no translation found for action_bar_home_description_format (7965984360903693903) -->
+    <skip />
+    <!-- no translation found for action_bar_home_subtitle_description_format (6985546530471780727) -->
+    <skip />
     <string name="storage_internal" msgid="4891916833657929263">"Interne geheue"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"SD-kaart"</string>
     <string name="storage_usb" msgid="3017954059538517278">"USB-berging"</string>
@@ -1479,4 +1491,6 @@
     <string name="error_message_title" msgid="4510373083082500195">"Fout"</string>
     <string name="app_no_restricted_accounts" msgid="5322164210667258876">"Hierdie program werk nie met rekeninge vir beperkte gebruikers nie"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Geen program gevind om hierdie handeling te hanteer nie"</string>
+    <!-- no translation found for revoke (5404479185228271586) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 54dfd50e..132d4cc 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -621,6 +621,10 @@
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"ከመተግበሪያዎች በተለየ መልኩ እንዴት የአውታረ መረብ አጠቃቀም እንደተመዘገበ ለመቀየር ለመተግበሪያው ይፈቅዳሉ።ለመደበኛ መተግበሪያዎች አገልግሎት አይውልም።"</string>
     <string name="permlab_accessNotifications" msgid="7673416487873432268">"ማሳወቂያዎችን ይድረሱ"</string>
     <string name="permdesc_accessNotifications" msgid="458457742683431387">"መተግበሪያው ማሳወቂያዎችን እንዲያስመጣ፣ እንዲመረምር እና እንዲያጸዳ ያስችለዋል፣ በሌሎች መተግበሪያዎች የተለጠፉትንም ጨምሮ።"</string>
+    <!-- no translation found for permlab_bindNotificationListenerService (7057764742211656654) -->
+    <skip />
+    <!-- no translation found for permdesc_bindNotificationListenerService (985697918576902986) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"የይለፍ ቃል ድንቦች አዘጋጅ"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"በማያ-መክፈት የተፈቀዱ የይለፍ ቃል ርዝመት እና ቁምፊዎች ተቆጣጠር።"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"የማሳያ-ክፈት ሙከራዎችን አሳይ"</string>
@@ -1048,8 +1052,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"የፅሁፍ እርምጃዎች"</string>
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"የማከማቻ ቦታ እያለቀ ነው"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"አንዳንድ የስርዓት ተግባራት ላይሰሩ ይችላሉ"</string>
-    <string name="app_running_notification_title" msgid="4625479411505090209">"<xliff:g id="APP_NAME">%1$s</xliff:g> በማሄድ ላይ"</string>
-    <string name="app_running_notification_text" msgid="3368349329989620597">"<xliff:g id="APP_NAME">%1$s</xliff:g> በአሁኑ ጊዜ እያሄደ ነው"</string>
+    <!-- no translation found for app_running_notification_title (8718335121060787914) -->
+    <skip />
+    <!-- no translation found for app_running_notification_text (4653586947747330058) -->
+    <skip />
     <string name="ok" msgid="5970060430562524910">"እሺ"</string>
     <string name="cancel" msgid="6442560571259935130">"ይቅር"</string>
     <string name="yes" msgid="5362982303337969312">"እሺ"</string>
@@ -1267,6 +1273,8 @@
     <string name="accessibility_binding_label" msgid="4148120742096474641">"ተደራሽነት"</string>
     <string name="wallpaper_binding_label" msgid="1240087844304687662">"ልጣፍ"</string>
     <string name="chooser_wallpaper" msgid="7873476199295190279">"ልጣፍ ለውጥ"</string>
+    <!-- no translation found for notification_listener_binding_label (2014162835481906429) -->
+    <skip />
     <string name="vpn_title" msgid="19615213552042827">"VPN ነቅቷል።"</string>
     <string name="vpn_title_long" msgid="6400714798049252294">"VPN በ<xliff:g id="APP">%s</xliff:g>ገብሯል"</string>
     <string name="vpn_text" msgid="3011306607126450322">"አውታረመረብ ለማደራጀት  ንካ።"</string>
@@ -1370,6 +1378,10 @@
     <string name="action_bar_home_description" msgid="5293600496601490216">"መነሻ ዳስስ"</string>
     <string name="action_bar_up_description" msgid="2237496562952152589">"አስስ"</string>
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"ተጨማሪ አማራጮች"</string>
+    <!-- no translation found for action_bar_home_description_format (7965984360903693903) -->
+    <skip />
+    <!-- no translation found for action_bar_home_subtitle_description_format (6985546530471780727) -->
+    <skip />
     <string name="storage_internal" msgid="4891916833657929263">"ውስጣዊ ማከማቻ"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"SD ካርድ"</string>
     <string name="storage_usb" msgid="3017954059538517278">"የUSB  ማከማቻ"</string>
@@ -1479,4 +1491,6 @@
     <string name="error_message_title" msgid="4510373083082500195">"ስህተት"</string>
     <string name="app_no_restricted_accounts" msgid="5322164210667258876">"ይህ መተግበሪያ የተገደቡ ተጠቃሚዎች መለያዎችን አይደግፍም"</string>
     <string name="app_not_found" msgid="3429141853498927379">"ይህን እርምጃ የሚያከናውን ምንም መተግበሪያ አልተገኘም"</string>
+    <!-- no translation found for revoke (5404479185228271586) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 0c6cd78..e13c0f2 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -621,6 +621,10 @@
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"للسماح للتطبيق بتعديل كيفية حساب استخدام الشبكة في التطبيقات. ليس للاستخدام بواسطة التطبيقات العادية."</string>
     <string name="permlab_accessNotifications" msgid="7673416487873432268">"إشعارات الدخول"</string>
     <string name="permdesc_accessNotifications" msgid="458457742683431387">"يتيح للتطبيق استرجاع الإشعارات وفحصها ومسحها، بما في ذلك تلك التي نشرتها تطبيقات أخرى."</string>
+    <!-- no translation found for permlab_bindNotificationListenerService (7057764742211656654) -->
+    <skip />
+    <!-- no translation found for permdesc_bindNotificationListenerService (985697918576902986) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"تعيين قواعد كلمة المرور"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"يمكنك التحكم في الطول والأحرف المسموح بها في كلمات مرور إلغاء تأمين الشاشة."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"مراقبة محاولات إلغاء قفل الشاشة"</string>
@@ -1048,8 +1052,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"إجراءات النص"</string>
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"مساحة التخزين منخفضة"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"قد لا تعمل بعض وظائف النظام"</string>
-    <string name="app_running_notification_title" msgid="4625479411505090209">"<xliff:g id="APP_NAME">%1$s</xliff:g> قيد التشغيل"</string>
-    <string name="app_running_notification_text" msgid="3368349329989620597">"<xliff:g id="APP_NAME">%1$s</xliff:g> قيد التشغيل حاليًا"</string>
+    <!-- no translation found for app_running_notification_title (8718335121060787914) -->
+    <skip />
+    <!-- no translation found for app_running_notification_text (4653586947747330058) -->
+    <skip />
     <string name="ok" msgid="5970060430562524910">"موافق"</string>
     <string name="cancel" msgid="6442560571259935130">"إلغاء"</string>
     <string name="yes" msgid="5362982303337969312">"موافق"</string>
@@ -1267,6 +1273,8 @@
     <string name="accessibility_binding_label" msgid="4148120742096474641">"إمكانية الدخول"</string>
     <string name="wallpaper_binding_label" msgid="1240087844304687662">"الخلفية"</string>
     <string name="chooser_wallpaper" msgid="7873476199295190279">"تغيير الخلفية"</string>
+    <!-- no translation found for notification_listener_binding_label (2014162835481906429) -->
+    <skip />
     <string name="vpn_title" msgid="19615213552042827">"تم تنشيط الشبكة الظاهرية الخاصة (VPN)"</string>
     <string name="vpn_title_long" msgid="6400714798049252294">"تم تنشيط VPN بواسطة <xliff:g id="APP">%s</xliff:g>"</string>
     <string name="vpn_text" msgid="3011306607126450322">"المس لإدارة الشبكة."</string>
@@ -1370,6 +1378,10 @@
     <string name="action_bar_home_description" msgid="5293600496601490216">"التنقل إلى الشاشة الرئيسية"</string>
     <string name="action_bar_up_description" msgid="2237496562952152589">"التنقل إلى أعلى"</string>
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"المزيد من الخيارات"</string>
+    <!-- no translation found for action_bar_home_description_format (7965984360903693903) -->
+    <skip />
+    <!-- no translation found for action_bar_home_subtitle_description_format (6985546530471780727) -->
+    <skip />
     <string name="storage_internal" msgid="4891916833657929263">"وحدة تخزين داخلية"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"بطاقة SD"</string>
     <string name="storage_usb" msgid="3017954059538517278">"وحدة تخزين USB"</string>
@@ -1479,4 +1491,6 @@
     <string name="error_message_title" msgid="4510373083082500195">"خطأ"</string>
     <string name="app_no_restricted_accounts" msgid="5322164210667258876">"لا يوفر هذا التطبيق حسابات للمستخدمين المقيّدين"</string>
     <string name="app_not_found" msgid="3429141853498927379">"لم يتم العثور على تطبيق يمكنه التعامل مع هذا الإجراء."</string>
+    <!-- no translation found for revoke (5404479185228271586) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index e6c9ee7..6653ac1 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -621,6 +621,10 @@
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Дазваляе прыкладанням змяняць метад уліку выкарыстання сеткі прыкладаннямі. Не для выкарыстання звычайнымі прыкладаннямі."</string>
     <string name="permlab_accessNotifications" msgid="7673416487873432268">"доступ да паведамленняў"</string>
     <string name="permdesc_accessNotifications" msgid="458457742683431387">"Дазваляе прыкладанню атрымлiваць, правяраць i выдаляць апавяшчэннi, у тым лiку апублiкаваныя iншымi прыкладаннямi."</string>
+    <!-- no translation found for permlab_bindNotificationListenerService (7057764742211656654) -->
+    <skip />
+    <!-- no translation found for permdesc_bindNotificationListenerService (985697918576902986) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Устанавіць правілы паролю"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Кіраванне даўжынёй і колькасцю знакаў у паролі разблакоўкі экрана."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Сачыць за спробамі разблакоўкі экрана"</string>
@@ -1048,8 +1052,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Дзеянні з тэкстам"</string>
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Месца для захавання на зыходзе"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Некаторыя сістэмныя функцыі могуць не працаваць"</string>
-    <string name="app_running_notification_title" msgid="4625479411505090209">"Прыкладанне <xliff:g id="APP_NAME">%1$s</xliff:g> працуе"</string>
-    <string name="app_running_notification_text" msgid="3368349329989620597">"Прыкладанне <xliff:g id="APP_NAME">%1$s</xliff:g> зараз працуе"</string>
+    <!-- no translation found for app_running_notification_title (8718335121060787914) -->
+    <skip />
+    <!-- no translation found for app_running_notification_text (4653586947747330058) -->
+    <skip />
     <string name="ok" msgid="5970060430562524910">"ОК"</string>
     <string name="cancel" msgid="6442560571259935130">"Адмяніць"</string>
     <string name="yes" msgid="5362982303337969312">"ОК"</string>
@@ -1267,6 +1273,8 @@
     <string name="accessibility_binding_label" msgid="4148120742096474641">"Спецыяльныя магчымасці"</string>
     <string name="wallpaper_binding_label" msgid="1240087844304687662">"Шпалеры"</string>
     <string name="chooser_wallpaper" msgid="7873476199295190279">"Змена шпалер"</string>
+    <!-- no translation found for notification_listener_binding_label (2014162835481906429) -->
+    <skip />
     <string name="vpn_title" msgid="19615213552042827">"VPN актываваны"</string>
     <string name="vpn_title_long" msgid="6400714798049252294">"VPN актывуецца прыкладаннем <xliff:g id="APP">%s</xliff:g>"</string>
     <string name="vpn_text" msgid="3011306607126450322">"Дакраніцеся, каб кіраваць сеткай."</string>
@@ -1370,6 +1378,10 @@
     <string name="action_bar_home_description" msgid="5293600496601490216">"Перайсці да пачатковай старонкі"</string>
     <string name="action_bar_up_description" msgid="2237496562952152589">"Перайсці ўверх"</string>
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"Больш налад"</string>
+    <!-- no translation found for action_bar_home_description_format (7965984360903693903) -->
+    <skip />
+    <!-- no translation found for action_bar_home_subtitle_description_format (6985546530471780727) -->
+    <skip />
     <string name="storage_internal" msgid="4891916833657929263">"Унутраная памяць"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"SD-карта"</string>
     <string name="storage_usb" msgid="3017954059538517278">"USB-назапашвальнік"</string>
@@ -1479,4 +1491,6 @@
     <string name="error_message_title" msgid="4510373083082500195">"Памылка"</string>
     <string name="app_no_restricted_accounts" msgid="5322164210667258876">"Гэтае прыкладанне не падтрымлівае уліковыя запісы для карыстальнікаў з абмежаванымі правамі"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Прыкладанне для гэтага дзеяння не знойдзенае"</string>
+    <!-- no translation found for revoke (5404479185228271586) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 79600f7..3d3e195 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -621,6 +621,10 @@
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Разрешава на приложението да променя това как употребата на мрежа се отчита спрямо приложенията. Не е предназначено за нормални приложения."</string>
     <string name="permlab_accessNotifications" msgid="7673416487873432268">"достъп до известията"</string>
     <string name="permdesc_accessNotifications" msgid="458457742683431387">"Разрешава на приложението да извлича, преглежда и изчиства известия, включително публикуваните от други приложения."</string>
+    <!-- no translation found for permlab_bindNotificationListenerService (7057764742211656654) -->
+    <skip />
+    <!-- no translation found for permdesc_bindNotificationListenerService (985697918576902986) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Задаване на правила за паролата"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Контролирайте дължината и разрешените знаци за паролите за отключване на екрана."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Наблюдаване на опитите за отключване на екрана"</string>
@@ -1048,8 +1052,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Действия с текста"</string>
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Мястото в хранилището е на изчерпване"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Възможно е някои функции на системата да не работят"</string>
-    <string name="app_running_notification_title" msgid="4625479411505090209">"<xliff:g id="APP_NAME">%1$s</xliff:g> се изпълнява"</string>
-    <string name="app_running_notification_text" msgid="3368349329989620597">"Понастоящем <xliff:g id="APP_NAME">%1$s</xliff:g> се изпълнява"</string>
+    <!-- no translation found for app_running_notification_title (8718335121060787914) -->
+    <skip />
+    <!-- no translation found for app_running_notification_text (4653586947747330058) -->
+    <skip />
     <string name="ok" msgid="5970060430562524910">"OK"</string>
     <string name="cancel" msgid="6442560571259935130">"Отказ"</string>
     <string name="yes" msgid="5362982303337969312">"OK"</string>
@@ -1267,6 +1273,8 @@
     <string name="accessibility_binding_label" msgid="4148120742096474641">"Достъпност"</string>
     <string name="wallpaper_binding_label" msgid="1240087844304687662">"Тапет"</string>
     <string name="chooser_wallpaper" msgid="7873476199295190279">"Промяна на тапета"</string>
+    <!-- no translation found for notification_listener_binding_label (2014162835481906429) -->
+    <skip />
     <string name="vpn_title" msgid="19615213552042827">"VPN е активирана"</string>
     <string name="vpn_title_long" msgid="6400714798049252294">"VPN е активирана от <xliff:g id="APP">%s</xliff:g>"</string>
     <string name="vpn_text" msgid="3011306607126450322">"Докоснете за управление на мрежата."</string>
@@ -1370,6 +1378,10 @@
     <string name="action_bar_home_description" msgid="5293600496601490216">"Придвижване към „Начало“"</string>
     <string name="action_bar_up_description" msgid="2237496562952152589">"Придвижване нагоре"</string>
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"Още опции"</string>
+    <!-- no translation found for action_bar_home_description_format (7965984360903693903) -->
+    <skip />
+    <!-- no translation found for action_bar_home_subtitle_description_format (6985546530471780727) -->
+    <skip />
     <string name="storage_internal" msgid="4891916833657929263">"Вътрешно хранилище"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"SD карта"</string>
     <string name="storage_usb" msgid="3017954059538517278">"USB хранилище"</string>
@@ -1479,4 +1491,6 @@
     <string name="error_message_title" msgid="4510373083082500195">"Грешка"</string>
     <string name="app_no_restricted_accounts" msgid="5322164210667258876">"Това приложение не поддържа профили за потребители с ограничения"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Няма намерено приложение за извършване на това действие"</string>
+    <!-- no translation found for revoke (5404479185228271586) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 975dc40..c96bef8 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -621,6 +621,10 @@
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Permet que l\'aplicació modifiqui la manera com es calcula l\'ús de la xarxa per part de les aplicacions. No indicat per a les aplicacions normals."</string>
     <string name="permlab_accessNotifications" msgid="7673416487873432268">"accedeix a les notificacions"</string>
     <string name="permdesc_accessNotifications" msgid="458457742683431387">"Permet que l\'aplicació recuperi, examini i esborri les notificacions, incloses les que han publicat altres aplicacions."</string>
+    <!-- no translation found for permlab_bindNotificationListenerService (7057764742211656654) -->
+    <skip />
+    <!-- no translation found for permdesc_bindNotificationListenerService (985697918576902986) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Defineix les normes de contrasenya"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Controla la longitud i els caràcters permesos a les contrasenyes de desbloqueig de pantalla."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Control d\'intents de desbloqueig de pantalla"</string>
@@ -1048,8 +1052,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Accions de text"</string>
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"S\'està acabant l\'espai d\'emmagatzematge"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"És possible que algunes funcions del sistema no funcionin"</string>
-    <string name="app_running_notification_title" msgid="4625479411505090209">"<xliff:g id="APP_NAME">%1$s</xliff:g> s\'està executant"</string>
-    <string name="app_running_notification_text" msgid="3368349329989620597">"<xliff:g id="APP_NAME">%1$s</xliff:g> s\'està executant en aquests moments"</string>
+    <!-- no translation found for app_running_notification_title (8718335121060787914) -->
+    <skip />
+    <!-- no translation found for app_running_notification_text (4653586947747330058) -->
+    <skip />
     <string name="ok" msgid="5970060430562524910">"D\'acord"</string>
     <string name="cancel" msgid="6442560571259935130">"Cancel·la"</string>
     <string name="yes" msgid="5362982303337969312">"D\'acord"</string>
@@ -1267,6 +1273,8 @@
     <string name="accessibility_binding_label" msgid="4148120742096474641">"Accessibilitat"</string>
     <string name="wallpaper_binding_label" msgid="1240087844304687662">"Fons de pantalla"</string>
     <string name="chooser_wallpaper" msgid="7873476199295190279">"Canvia el fons de pantalla"</string>
+    <!-- no translation found for notification_listener_binding_label (2014162835481906429) -->
+    <skip />
     <string name="vpn_title" msgid="19615213552042827">"VPN activada"</string>
     <string name="vpn_title_long" msgid="6400714798049252294">"<xliff:g id="APP">%s</xliff:g> ha activat VPN"</string>
     <string name="vpn_text" msgid="3011306607126450322">"Toca per gestionar la xarxa."</string>
@@ -1370,6 +1378,10 @@
     <string name="action_bar_home_description" msgid="5293600496601490216">"Torna a la pàgina d\'inici"</string>
     <string name="action_bar_up_description" msgid="2237496562952152589">"Mou cap a dalt"</string>
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"Més opcions"</string>
+    <!-- no translation found for action_bar_home_description_format (7965984360903693903) -->
+    <skip />
+    <!-- no translation found for action_bar_home_subtitle_description_format (6985546530471780727) -->
+    <skip />
     <string name="storage_internal" msgid="4891916833657929263">"Emmagatzematge intern"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"Targeta SD"</string>
     <string name="storage_usb" msgid="3017954059538517278">"Emmagatzematge USB"</string>
@@ -1479,4 +1491,6 @@
     <string name="error_message_title" msgid="4510373083082500195">"Error"</string>
     <string name="app_no_restricted_accounts" msgid="5322164210667258876">"Aquesta aplicació no admet comptes per a usuaris limitats"</string>
     <string name="app_not_found" msgid="3429141853498927379">"No s\'ha trobat cap aplicació per processar aquesta acció"</string>
+    <!-- no translation found for revoke (5404479185228271586) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 0adebe9..4738834 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -621,6 +621,10 @@
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Umožňuje aplikaci upravit způsob výpočtu využití sítě aplikacemi. Toto oprávnění není určeno pro běžné aplikace."</string>
     <string name="permlab_accessNotifications" msgid="7673416487873432268">"přístup k oznámením"</string>
     <string name="permdesc_accessNotifications" msgid="458457742683431387">"Umožňuje aplikacím načítat, zobrazovat a mazat oznámení včetně těch přidaných jinými aplikacemi."</string>
+    <!-- no translation found for permlab_bindNotificationListenerService (7057764742211656654) -->
+    <skip />
+    <!-- no translation found for permdesc_bindNotificationListenerService (985697918576902986) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Nastavit pravidla pro heslo"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Řídit délku hesel pro odemčení obrazovky a povolené znaky."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Sledovat pokusy o odemčení obrazovky"</string>
@@ -1048,8 +1052,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Operace s textem"</string>
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"V úložišti je málo místa"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Některé systémové funkce nemusí fungovat"</string>
-    <string name="app_running_notification_title" msgid="4625479411505090209">"Aplikace <xliff:g id="APP_NAME">%1$s</xliff:g> je spuštěna"</string>
-    <string name="app_running_notification_text" msgid="3368349329989620597">"Aplikace <xliff:g id="APP_NAME">%1$s</xliff:g> je aktuálně spuštěná"</string>
+    <!-- no translation found for app_running_notification_title (8718335121060787914) -->
+    <skip />
+    <!-- no translation found for app_running_notification_text (4653586947747330058) -->
+    <skip />
     <string name="ok" msgid="5970060430562524910">"OK"</string>
     <string name="cancel" msgid="6442560571259935130">"Zrušit"</string>
     <string name="yes" msgid="5362982303337969312">"OK"</string>
@@ -1267,6 +1273,8 @@
     <string name="accessibility_binding_label" msgid="4148120742096474641">"Usnadnění"</string>
     <string name="wallpaper_binding_label" msgid="1240087844304687662">"Tapeta"</string>
     <string name="chooser_wallpaper" msgid="7873476199295190279">"Změnit tapetu"</string>
+    <!-- no translation found for notification_listener_binding_label (2014162835481906429) -->
+    <skip />
     <string name="vpn_title" msgid="19615213552042827">"Síť VPN je aktivována"</string>
     <string name="vpn_title_long" msgid="6400714798049252294">"Aplikace <xliff:g id="APP">%s</xliff:g> aktivovala síť VPN"</string>
     <string name="vpn_text" msgid="3011306607126450322">"Dotykem zobrazíte správu sítě."</string>
@@ -1370,6 +1378,10 @@
     <string name="action_bar_home_description" msgid="5293600496601490216">"Přejít na plochu"</string>
     <string name="action_bar_up_description" msgid="2237496562952152589">"Přejít nahoru"</string>
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"Další možnosti"</string>
+    <!-- no translation found for action_bar_home_description_format (7965984360903693903) -->
+    <skip />
+    <!-- no translation found for action_bar_home_subtitle_description_format (6985546530471780727) -->
+    <skip />
     <string name="storage_internal" msgid="4891916833657929263">"Interní úložiště"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"Karta SD"</string>
     <string name="storage_usb" msgid="3017954059538517278">"Úložiště USB"</string>
@@ -1479,4 +1491,6 @@
     <string name="error_message_title" msgid="4510373083082500195">"Chyba"</string>
     <string name="app_no_restricted_accounts" msgid="5322164210667258876">"Tato aplikace u omezeného počtu uživatelů nepodporuje účty"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Aplikace potřebná k provedení této akce nebyla nalezena"</string>
+    <!-- no translation found for revoke (5404479185228271586) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index d2676c9..6c16e56 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -621,6 +621,10 @@
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Tillader, at appen kan ændre den måde, som netværksforbrug udregnes på i forhold til apps. Anvendes ikke af normale apps."</string>
     <string name="permlab_accessNotifications" msgid="7673416487873432268">"adgang til underretninger"</string>
     <string name="permdesc_accessNotifications" msgid="458457742683431387">"Tillader, at appen kan hente, undersøge og rydde underretninger, herunder dem, der er sendt af andre apps."</string>
+    <!-- no translation found for permlab_bindNotificationListenerService (7057764742211656654) -->
+    <skip />
+    <!-- no translation found for permdesc_bindNotificationListenerService (985697918576902986) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Indstil regler for adgangskode"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Kontroller længden samt tilladte tegn i adgangskoder til oplåsning af skærmen."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Overvåg forsøg på oplåsning af skærm"</string>
@@ -1048,8 +1052,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Teksthandlinger"</string>
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Der er snart ikke mere lagerplads"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Nogle systemfunktioner virker måske ikke"</string>
-    <string name="app_running_notification_title" msgid="4625479411505090209">"<xliff:g id="APP_NAME">%1$s</xliff:g> kører"</string>
-    <string name="app_running_notification_text" msgid="3368349329989620597">"<xliff:g id="APP_NAME">%1$s</xliff:g> kører i øjeblikket"</string>
+    <!-- no translation found for app_running_notification_title (8718335121060787914) -->
+    <skip />
+    <!-- no translation found for app_running_notification_text (4653586947747330058) -->
+    <skip />
     <string name="ok" msgid="5970060430562524910">"OK"</string>
     <string name="cancel" msgid="6442560571259935130">"Annuller"</string>
     <string name="yes" msgid="5362982303337969312">"OK"</string>
@@ -1267,6 +1273,8 @@
     <string name="accessibility_binding_label" msgid="4148120742096474641">"Tilgængelighed"</string>
     <string name="wallpaper_binding_label" msgid="1240087844304687662">"Tapet"</string>
     <string name="chooser_wallpaper" msgid="7873476199295190279">"Skift tapet"</string>
+    <!-- no translation found for notification_listener_binding_label (2014162835481906429) -->
+    <skip />
     <string name="vpn_title" msgid="19615213552042827">"VPN er aktiveret."</string>
     <string name="vpn_title_long" msgid="6400714798049252294">"VPN aktiveres af <xliff:g id="APP">%s</xliff:g>"</string>
     <string name="vpn_text" msgid="3011306607126450322">"Tryk for at administrere netværket."</string>
@@ -1370,6 +1378,10 @@
     <string name="action_bar_home_description" msgid="5293600496601490216">"Naviger hjem"</string>
     <string name="action_bar_up_description" msgid="2237496562952152589">"Naviger op"</string>
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"Flere valgmuligheder"</string>
+    <!-- no translation found for action_bar_home_description_format (7965984360903693903) -->
+    <skip />
+    <!-- no translation found for action_bar_home_subtitle_description_format (6985546530471780727) -->
+    <skip />
     <string name="storage_internal" msgid="4891916833657929263">"Internt lager"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"SD-kort"</string>
     <string name="storage_usb" msgid="3017954059538517278">"USB-lager"</string>
@@ -1479,4 +1491,6 @@
     <string name="error_message_title" msgid="4510373083082500195">"Fejl"</string>
     <string name="app_no_restricted_accounts" msgid="5322164210667258876">"Denne applikation understøtter ikke konti for brugere med begrænsede rettigheder"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Der blev ikke fundet nogen applikation, der kan håndtere denne handling"</string>
+    <!-- no translation found for revoke (5404479185228271586) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 6a488c7..ead4004 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -621,6 +621,10 @@
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Ermöglicht der App, die Art und Weise zu ändern, wie der Netzwerkverbrauch im Hinblick auf Apps berechnet wird. Nicht für normale Apps vorgesehen."</string>
     <string name="permlab_accessNotifications" msgid="7673416487873432268">"Auf Benachrichtigungen zugreifen"</string>
     <string name="permdesc_accessNotifications" msgid="458457742683431387">"Ermöglicht der App das Abrufen, Überprüfen und Löschen von Benachrichtigungen, einschließlich Benachrichtigungen, die von anderen Apps gepostet wurden"</string>
+    <!-- no translation found for permlab_bindNotificationListenerService (7057764742211656654) -->
+    <skip />
+    <!-- no translation found for permdesc_bindNotificationListenerService (985697918576902986) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Passwortregeln festlegen"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Zulässige Länge und Zeichen für Passwörter zum Entsperren des Bildschirms festlegen"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Versuche zum Entsperren des Displays überwachen"</string>
@@ -1048,8 +1052,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Textaktionen"</string>
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Der Speicherplatz wird knapp"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Einige Systemfunktionen funktionieren möglicherweise nicht."</string>
-    <string name="app_running_notification_title" msgid="4625479411505090209">"<xliff:g id="APP_NAME">%1$s</xliff:g> wird ausgeführt."</string>
-    <string name="app_running_notification_text" msgid="3368349329989620597">"<xliff:g id="APP_NAME">%1$s</xliff:g> wird gerade ausgeführt."</string>
+    <!-- no translation found for app_running_notification_title (8718335121060787914) -->
+    <skip />
+    <!-- no translation found for app_running_notification_text (4653586947747330058) -->
+    <skip />
     <string name="ok" msgid="5970060430562524910">"OK"</string>
     <string name="cancel" msgid="6442560571259935130">"Abbrechen"</string>
     <string name="yes" msgid="5362982303337969312">"OK"</string>
@@ -1267,6 +1273,8 @@
     <string name="accessibility_binding_label" msgid="4148120742096474641">"Bedienungshilfen"</string>
     <string name="wallpaper_binding_label" msgid="1240087844304687662">"Hintergrund"</string>
     <string name="chooser_wallpaper" msgid="7873476199295190279">"Hintergrund ändern"</string>
+    <!-- no translation found for notification_listener_binding_label (2014162835481906429) -->
+    <skip />
     <string name="vpn_title" msgid="19615213552042827">"VPN aktiviert"</string>
     <string name="vpn_title_long" msgid="6400714798049252294">"VPN wurde von <xliff:g id="APP">%s</xliff:g> aktiviert."</string>
     <string name="vpn_text" msgid="3011306607126450322">"Zum Verwalten des Netzwerks berühren"</string>
@@ -1370,6 +1378,10 @@
     <string name="action_bar_home_description" msgid="5293600496601490216">"Zur Startseite navigieren"</string>
     <string name="action_bar_up_description" msgid="2237496562952152589">"Nach oben navigieren"</string>
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"Weitere Optionen"</string>
+    <!-- no translation found for action_bar_home_description_format (7965984360903693903) -->
+    <skip />
+    <!-- no translation found for action_bar_home_subtitle_description_format (6985546530471780727) -->
+    <skip />
     <string name="storage_internal" msgid="4891916833657929263">"Interner Speicher"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"SD-Karte"</string>
     <string name="storage_usb" msgid="3017954059538517278">"USB-Speicher"</string>
@@ -1479,4 +1491,6 @@
     <string name="error_message_title" msgid="4510373083082500195">"Fehler"</string>
     <string name="app_no_restricted_accounts" msgid="5322164210667258876">"Diese App unterstützt keine Konten für eingeschränkte Nutzer."</string>
     <string name="app_not_found" msgid="3429141853498927379">"Für diese Aktion wurde keine App gefunden."</string>
+    <!-- no translation found for revoke (5404479185228271586) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 21b014c..ac4ec2e 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -621,6 +621,10 @@
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Επιτρέπει στην εφαρμογή την τροποποίηση του τρόπου υπολογισμού της χρήσης δικτύου έναντι των εφαρμογών. Δεν προορίζεται για χρήση από συνήθεις εφαρμογές."</string>
     <string name="permlab_accessNotifications" msgid="7673416487873432268">"πρόσβαση στις ειδοποιήσεις"</string>
     <string name="permdesc_accessNotifications" msgid="458457742683431387">"Επιτρέπει στην εφαρμογή να ανακτά, να εξετάζει και να απαλείφει ειδοποιήσεις, συμπεριλαμβανομένων εκείνων που δημοσιεύονται από άλλες εφαρμογές."</string>
+    <!-- no translation found for permlab_bindNotificationListenerService (7057764742211656654) -->
+    <skip />
+    <!-- no translation found for permdesc_bindNotificationListenerService (985697918576902986) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Ορισμός κανόνων κωδικού πρόσβασης"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Έλεγχος του μεγέθους και των χαρακτήρων που επιτρέπονται στους κωδικούς πρόσβασης ξεκλειδώματος οθόνης."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Παρακολούθηση προσπαθειών ξεκλειδώματος οθόνης"</string>
@@ -1048,8 +1052,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Ενέργειες κειμένου"</string>
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Ο χώρος αποθήκευσης εξαντλείται"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Ορισμένες λειτουργίες συστήματος ενδέχεται να μην λειτουργούν"</string>
-    <string name="app_running_notification_title" msgid="4625479411505090209">"Η εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g> εκτελείται"</string>
-    <string name="app_running_notification_text" msgid="3368349329989620597">"Η εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g> εκτελείται τώρα."</string>
+    <!-- no translation found for app_running_notification_title (8718335121060787914) -->
+    <skip />
+    <!-- no translation found for app_running_notification_text (4653586947747330058) -->
+    <skip />
     <string name="ok" msgid="5970060430562524910">"OK"</string>
     <string name="cancel" msgid="6442560571259935130">"Ακύρωση"</string>
     <string name="yes" msgid="5362982303337969312">"OK"</string>
@@ -1267,6 +1273,8 @@
     <string name="accessibility_binding_label" msgid="4148120742096474641">"Προσβασιμότητα"</string>
     <string name="wallpaper_binding_label" msgid="1240087844304687662">"Ταπετσαρία"</string>
     <string name="chooser_wallpaper" msgid="7873476199295190279">"Αλλαγή ταπετσαρίας"</string>
+    <!-- no translation found for notification_listener_binding_label (2014162835481906429) -->
+    <skip />
     <string name="vpn_title" msgid="19615213552042827">"Το VPN ενεργοποιήθηκε"</string>
     <string name="vpn_title_long" msgid="6400714798049252294">"Το VPN ενεργοποιήθηκε από την εφαρμογή <xliff:g id="APP">%s</xliff:g>"</string>
     <string name="vpn_text" msgid="3011306607126450322">"Αγγίξτε για τη διαχείριση του δικτύου."</string>
@@ -1370,6 +1378,10 @@
     <string name="action_bar_home_description" msgid="5293600496601490216">"Πλοήγηση στην αρχική σελίδα"</string>
     <string name="action_bar_up_description" msgid="2237496562952152589">"Πλοήγηση προς τα επάνω"</string>
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"Περισσότερες επιλογές"</string>
+    <!-- no translation found for action_bar_home_description_format (7965984360903693903) -->
+    <skip />
+    <!-- no translation found for action_bar_home_subtitle_description_format (6985546530471780727) -->
+    <skip />
     <string name="storage_internal" msgid="4891916833657929263">"Εσωτερικός χώρος αποθήκευσης"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"Κάρτα SD"</string>
     <string name="storage_usb" msgid="3017954059538517278">"Χώρος αποθήκευσης USB"</string>
@@ -1479,4 +1491,6 @@
     <string name="error_message_title" msgid="4510373083082500195">"Σφάλμα"</string>
     <string name="app_no_restricted_accounts" msgid="5322164210667258876">"Αυτή η εφαρμογή δεν υποστηρίζει λογαριασμούς για περιορισμένους χρήστες"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Δεν υπάρχει εφαρμογή για τη διαχείριση αυτής της ενέργειας"</string>
+    <!-- no translation found for revoke (5404479185228271586) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index ae698e1..5285532 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -621,6 +621,10 @@
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Allows the app to modify how network usage is accounted against apps. Not for use by normal apps."</string>
     <string name="permlab_accessNotifications" msgid="7673416487873432268">"access notifications"</string>
     <string name="permdesc_accessNotifications" msgid="458457742683431387">"Allows the app to retrieve, examine, and clear notifications, including those posted by other apps."</string>
+    <!-- no translation found for permlab_bindNotificationListenerService (7057764742211656654) -->
+    <skip />
+    <!-- no translation found for permdesc_bindNotificationListenerService (985697918576902986) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Set password rules"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Control the length and the characters allowed in screen-unlock passwords."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Monitor screen-unlock attempts"</string>
@@ -1048,8 +1052,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Text actions"</string>
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Storage space running out"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Some system functions may not work"</string>
-    <string name="app_running_notification_title" msgid="4625479411505090209">"<xliff:g id="APP_NAME">%1$s</xliff:g> running"</string>
-    <string name="app_running_notification_text" msgid="3368349329989620597">"<xliff:g id="APP_NAME">%1$s</xliff:g> is currently running"</string>
+    <!-- no translation found for app_running_notification_title (8718335121060787914) -->
+    <skip />
+    <!-- no translation found for app_running_notification_text (4653586947747330058) -->
+    <skip />
     <string name="ok" msgid="5970060430562524910">"OK"</string>
     <string name="cancel" msgid="6442560571259935130">"Cancel"</string>
     <string name="yes" msgid="5362982303337969312">"OK"</string>
@@ -1267,6 +1273,8 @@
     <string name="accessibility_binding_label" msgid="4148120742096474641">"Accessibility"</string>
     <string name="wallpaper_binding_label" msgid="1240087844304687662">"Wallpaper"</string>
     <string name="chooser_wallpaper" msgid="7873476199295190279">"Change wallpaper"</string>
+    <!-- no translation found for notification_listener_binding_label (2014162835481906429) -->
+    <skip />
     <string name="vpn_title" msgid="19615213552042827">"VPN activated"</string>
     <string name="vpn_title_long" msgid="6400714798049252294">"VPN is activated by <xliff:g id="APP">%s</xliff:g>"</string>
     <string name="vpn_text" msgid="3011306607126450322">"Touch to manage the network."</string>
@@ -1370,6 +1378,10 @@
     <string name="action_bar_home_description" msgid="5293600496601490216">"Navigate home"</string>
     <string name="action_bar_up_description" msgid="2237496562952152589">"Navigate up"</string>
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"More options"</string>
+    <!-- no translation found for action_bar_home_description_format (7965984360903693903) -->
+    <skip />
+    <!-- no translation found for action_bar_home_subtitle_description_format (6985546530471780727) -->
+    <skip />
     <string name="storage_internal" msgid="4891916833657929263">"Internal storage"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"SD card"</string>
     <string name="storage_usb" msgid="3017954059538517278">"USB storage"</string>
@@ -1479,4 +1491,6 @@
     <string name="error_message_title" msgid="4510373083082500195">"Error"</string>
     <string name="app_no_restricted_accounts" msgid="5322164210667258876">"This application does not support accounts for limited users"</string>
     <string name="app_not_found" msgid="3429141853498927379">"No application found to handle this action"</string>
+    <!-- no translation found for revoke (5404479185228271586) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index f3f0afc..20f0c33 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -621,6 +621,10 @@
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Permite que la aplicación modifique cómo se registra el uso de red en relación con las aplicaciones. Las aplicaciones normales no deben usar este permiso."</string>
     <string name="permlab_accessNotifications" msgid="7673416487873432268">"acceder a las notificaciones"</string>
     <string name="permdesc_accessNotifications" msgid="458457742683431387">"Permite que la aplicación recupere, examine y elimine notificaciones, incluidas aquellas publicadas por otras aplicaciones."</string>
+    <!-- no translation found for permlab_bindNotificationListenerService (7057764742211656654) -->
+    <skip />
+    <!-- no translation found for permdesc_bindNotificationListenerService (985697918576902986) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Establecer reglas de contraseña"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Controlar la longitud y los caracteres permitidos en las contraseñas para desbloquear la pantalla"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Supervisa los intentos para desbloquear la pantalla"</string>
@@ -1048,8 +1052,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Acciones de texto"</string>
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Queda poco espacio de almacenamiento"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Es posible que algunas funciones del sistema no estén disponibles."</string>
-    <string name="app_running_notification_title" msgid="4625479411505090209">"<xliff:g id="APP_NAME">%1$s</xliff:g> en ejecución"</string>
-    <string name="app_running_notification_text" msgid="3368349329989620597">"<xliff:g id="APP_NAME">%1$s</xliff:g> se está ejecutando en este momento."</string>
+    <!-- no translation found for app_running_notification_title (8718335121060787914) -->
+    <skip />
+    <!-- no translation found for app_running_notification_text (4653586947747330058) -->
+    <skip />
     <string name="ok" msgid="5970060430562524910">"Aceptar"</string>
     <string name="cancel" msgid="6442560571259935130">"Cancelar"</string>
     <string name="yes" msgid="5362982303337969312">"Aceptar"</string>
@@ -1267,6 +1273,8 @@
     <string name="accessibility_binding_label" msgid="4148120742096474641">"Accesibilidad"</string>
     <string name="wallpaper_binding_label" msgid="1240087844304687662">"Papel tapiz"</string>
     <string name="chooser_wallpaper" msgid="7873476199295190279">"Cambiar fondo de pantalla"</string>
+    <!-- no translation found for notification_listener_binding_label (2014162835481906429) -->
+    <skip />
     <string name="vpn_title" msgid="19615213552042827">"VPN activada"</string>
     <string name="vpn_title_long" msgid="6400714798049252294">"VPN está activado por <xliff:g id="APP">%s</xliff:g>"</string>
     <string name="vpn_text" msgid="3011306607126450322">"Toca para administrar la red."</string>
@@ -1370,6 +1378,10 @@
     <string name="action_bar_home_description" msgid="5293600496601490216">"Desplazarse hasta la página principal"</string>
     <string name="action_bar_up_description" msgid="2237496562952152589">"Desplazarse hacia arriba"</string>
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"Más opciones"</string>
+    <!-- no translation found for action_bar_home_description_format (7965984360903693903) -->
+    <skip />
+    <!-- no translation found for action_bar_home_subtitle_description_format (6985546530471780727) -->
+    <skip />
     <string name="storage_internal" msgid="4891916833657929263">"Almacenamiento interno"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"Tarjeta SD"</string>
     <string name="storage_usb" msgid="3017954059538517278">"Almacenamiento USB"</string>
@@ -1479,4 +1491,6 @@
     <string name="error_message_title" msgid="4510373083082500195">"Error"</string>
     <string name="app_no_restricted_accounts" msgid="5322164210667258876">"Esta aplicación no admite cuentas para usuarios restringidos."</string>
     <string name="app_not_found" msgid="3429141853498927379">"No se encontró una aplicación para manejar esta acción."</string>
+    <!-- no translation found for revoke (5404479185228271586) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index d3e63af..7dc03bec 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -621,6 +621,10 @@
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Permite que la aplicación modifique cómo se registra el uso de red en relación con las aplicaciones. Las aplicaciones normales no deben usar este permiso."</string>
     <string name="permlab_accessNotifications" msgid="7673416487873432268">"acceder a las notificaciones"</string>
     <string name="permdesc_accessNotifications" msgid="458457742683431387">"Permite que la aplicación recupere, examine y borre notificaciones, incluidas las que han publicado otras aplicaciones."</string>
+    <!-- no translation found for permlab_bindNotificationListenerService (7057764742211656654) -->
+    <skip />
+    <!-- no translation found for permdesc_bindNotificationListenerService (985697918576902986) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Establecimiento de reglas de contraseña"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Controlar la longitud y los caracteres permitidos en las contraseñas de bloqueo de pantalla"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Control de intentos de bloqueo de pantalla"</string>
@@ -1048,8 +1052,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Acciones de texto"</string>
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Queda poco espacio"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Es posible que algunas funciones del sistema no funcionen."</string>
-    <string name="app_running_notification_title" msgid="4625479411505090209">"<xliff:g id="APP_NAME">%1$s</xliff:g> se está ejecutando"</string>
-    <string name="app_running_notification_text" msgid="3368349329989620597">"<xliff:g id="APP_NAME">%1$s</xliff:g> se está ejecutando."</string>
+    <!-- no translation found for app_running_notification_title (8718335121060787914) -->
+    <skip />
+    <!-- no translation found for app_running_notification_text (4653586947747330058) -->
+    <skip />
     <string name="ok" msgid="5970060430562524910">"Aceptar"</string>
     <string name="cancel" msgid="6442560571259935130">"Cancelar"</string>
     <string name="yes" msgid="5362982303337969312">"Aceptar"</string>
@@ -1267,6 +1273,8 @@
     <string name="accessibility_binding_label" msgid="4148120742096474641">"Accesibilidad"</string>
     <string name="wallpaper_binding_label" msgid="1240087844304687662">"Fondo de pantalla"</string>
     <string name="chooser_wallpaper" msgid="7873476199295190279">"Cambiar fondo de pantalla"</string>
+    <!-- no translation found for notification_listener_binding_label (2014162835481906429) -->
+    <skip />
     <string name="vpn_title" msgid="19615213552042827">"VPN activada"</string>
     <string name="vpn_title_long" msgid="6400714798049252294">"VPN activada por <xliff:g id="APP">%s</xliff:g>"</string>
     <string name="vpn_text" msgid="3011306607126450322">"Toca para administrar la red."</string>
@@ -1370,6 +1378,10 @@
     <string name="action_bar_home_description" msgid="5293600496601490216">"Ir al escritorio"</string>
     <string name="action_bar_up_description" msgid="2237496562952152589">"Desplazarse hacia arriba"</string>
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"Más opciones"</string>
+    <!-- no translation found for action_bar_home_description_format (7965984360903693903) -->
+    <skip />
+    <!-- no translation found for action_bar_home_subtitle_description_format (6985546530471780727) -->
+    <skip />
     <string name="storage_internal" msgid="4891916833657929263">"Almacenamiento interno"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"Tarjeta SD"</string>
     <string name="storage_usb" msgid="3017954059538517278">"Almacenamiento USB"</string>
@@ -1479,4 +1491,6 @@
     <string name="error_message_title" msgid="4510373083082500195">"Error"</string>
     <string name="app_no_restricted_accounts" msgid="5322164210667258876">"Esta aplicación no admite cuentas de usuarios limitados."</string>
     <string name="app_not_found" msgid="3429141853498927379">"No se ha encontrado ninguna aplicación que pueda realizar esta acción."</string>
+    <!-- no translation found for revoke (5404479185228271586) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index bb00bfc..e78e169 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -621,6 +621,10 @@
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Võimaldab rakendusel muuta võrgukasutuse loendamist rakenduste suhtes. Mitte kasutada tavarakenduste puhul."</string>
     <string name="permlab_accessNotifications" msgid="7673416487873432268">"juurdepääsu märguanded"</string>
     <string name="permdesc_accessNotifications" msgid="458457742683431387">"Võimaldab rakendusel tuua, kontrollida ja kustutada märguandeid, sh neid, mille on postitanud teised rakendused."</string>
+    <!-- no translation found for permlab_bindNotificationListenerService (7057764742211656654) -->
+    <skip />
+    <!-- no translation found for permdesc_bindNotificationListenerService (985697918576902986) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Parooli reeglite määramine"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Kontrollige ekraaniluku avamise paroolide pikkust ja tähemärke."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Ekraani avamiskatsed"</string>
@@ -1048,8 +1052,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Tekstitoimingud"</string>
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Talletusruum saab täis"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Mõned süsteemifunktsioonid ei pruugi töötada"</string>
-    <string name="app_running_notification_title" msgid="4625479411505090209">"<xliff:g id="APP_NAME">%1$s</xliff:g> töötab"</string>
-    <string name="app_running_notification_text" msgid="3368349329989620597">"<xliff:g id="APP_NAME">%1$s</xliff:g> töötab praegu"</string>
+    <!-- no translation found for app_running_notification_title (8718335121060787914) -->
+    <skip />
+    <!-- no translation found for app_running_notification_text (4653586947747330058) -->
+    <skip />
     <string name="ok" msgid="5970060430562524910">"OK"</string>
     <string name="cancel" msgid="6442560571259935130">"Tühista"</string>
     <string name="yes" msgid="5362982303337969312">"OK"</string>
@@ -1267,6 +1273,8 @@
     <string name="accessibility_binding_label" msgid="4148120742096474641">"Juurdepääsetavus"</string>
     <string name="wallpaper_binding_label" msgid="1240087844304687662">"Taustapilt"</string>
     <string name="chooser_wallpaper" msgid="7873476199295190279">"Muutke taustapilti"</string>
+    <!-- no translation found for notification_listener_binding_label (2014162835481906429) -->
+    <skip />
     <string name="vpn_title" msgid="19615213552042827">"VPN on aktiveeritud"</string>
     <string name="vpn_title_long" msgid="6400714798049252294">"VPN-i aktiveeris <xliff:g id="APP">%s</xliff:g>"</string>
     <string name="vpn_text" msgid="3011306607126450322">"Võrgu haldamiseks puudutage."</string>
@@ -1370,6 +1378,10 @@
     <string name="action_bar_home_description" msgid="5293600496601490216">"Liigu avalehele"</string>
     <string name="action_bar_up_description" msgid="2237496562952152589">"Liigu üles"</string>
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"Rohkem valikuid"</string>
+    <!-- no translation found for action_bar_home_description_format (7965984360903693903) -->
+    <skip />
+    <!-- no translation found for action_bar_home_subtitle_description_format (6985546530471780727) -->
+    <skip />
     <string name="storage_internal" msgid="4891916833657929263">"Sisemine salvestusruum"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"SD-kaart"</string>
     <string name="storage_usb" msgid="3017954059538517278">"USB-mäluseade"</string>
@@ -1479,4 +1491,6 @@
     <string name="error_message_title" msgid="4510373083082500195">"Viga"</string>
     <string name="app_no_restricted_accounts" msgid="5322164210667258876">"Rakendus ei toeta piiratud õigustega kasutajate kontosid"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Selle toimingu käsitlemiseks ei leitud ühtegi rakendust"</string>
+    <!-- no translation found for revoke (5404479185228271586) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 322cbee..3ab64c0 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -621,6 +621,10 @@
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"به برنامه اجازه می‎دهد تا نحوه محاسبه کاربرد شبکه در برنامه را تغییر دهد. برای استفاده برنامه‎های عادی نیست."</string>
     <string name="permlab_accessNotifications" msgid="7673416487873432268">"اعلان‌های دسترسی"</string>
     <string name="permdesc_accessNotifications" msgid="458457742683431387">"به برنامه اجازه می‌دهد به بازیابی، بررسی و پاک کردن اعلان‌ها از جمله موارد پست شده توسط سایر برنامه‌ها بپردازد."</string>
+    <!-- no translation found for permlab_bindNotificationListenerService (7057764742211656654) -->
+    <skip />
+    <!-- no translation found for permdesc_bindNotificationListenerService (985697918576902986) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"تنظیم قوانین رمز ورود"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"طول و نویسه‎های مجاز در گذرواژه‌های بازکردن قفل صفحه را کنترل کنید."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"نمایش تلاش‌های قفل گشایی صفحه"</string>
@@ -1048,8 +1052,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"عملکردهای متنی"</string>
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"فضای ذخیره‌سازی رو به اتمام است"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"برخی از عملکردهای سیستم ممکن است کار نکنند"</string>
-    <string name="app_running_notification_title" msgid="4625479411505090209">"<xliff:g id="APP_NAME">%1$s</xliff:g> در حال اجرا"</string>
-    <string name="app_running_notification_text" msgid="3368349329989620597">"<xliff:g id="APP_NAME">%1$s</xliff:g> در حال حاضر در حال اجرا است"</string>
+    <!-- no translation found for app_running_notification_title (8718335121060787914) -->
+    <skip />
+    <!-- no translation found for app_running_notification_text (4653586947747330058) -->
+    <skip />
     <string name="ok" msgid="5970060430562524910">"تأیید"</string>
     <string name="cancel" msgid="6442560571259935130">"لغو"</string>
     <string name="yes" msgid="5362982303337969312">"تأیید"</string>
@@ -1267,6 +1273,8 @@
     <string name="accessibility_binding_label" msgid="4148120742096474641">"قابلیت دسترسی"</string>
     <string name="wallpaper_binding_label" msgid="1240087844304687662">"تصویر زمینه"</string>
     <string name="chooser_wallpaper" msgid="7873476199295190279">"تغییر تصویر زمینه"</string>
+    <!-- no translation found for notification_listener_binding_label (2014162835481906429) -->
+    <skip />
     <string name="vpn_title" msgid="19615213552042827">"VPN فعال شد"</string>
     <string name="vpn_title_long" msgid="6400714798049252294">"VPN توسط <xliff:g id="APP">%s</xliff:g> فعال شده است"</string>
     <string name="vpn_text" msgid="3011306607126450322">"برای مدیریت شبکه لمس کنید."</string>
@@ -1370,6 +1378,10 @@
     <string name="action_bar_home_description" msgid="5293600496601490216">"رفتن به صفحهٔ اصلی"</string>
     <string name="action_bar_up_description" msgid="2237496562952152589">"حرکت به بالا"</string>
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"سایر گزینه‌ها"</string>
+    <!-- no translation found for action_bar_home_description_format (7965984360903693903) -->
+    <skip />
+    <!-- no translation found for action_bar_home_subtitle_description_format (6985546530471780727) -->
+    <skip />
     <string name="storage_internal" msgid="4891916833657929263">"حافظهٔ داخلی"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"کارت SD"</string>
     <string name="storage_usb" msgid="3017954059538517278">"حافظهٔ USB"</string>
@@ -1479,4 +1491,6 @@
     <string name="error_message_title" msgid="4510373083082500195">"خطا"</string>
     <string name="app_no_restricted_accounts" msgid="5322164210667258876">"این برنامه حساب‌های تعداد محدودی از کاربران را پشتیبانی نمی‌کند"</string>
     <string name="app_not_found" msgid="3429141853498927379">"برنامه‌ای برای انجام این عملکرد موجود نیست"</string>
+    <!-- no translation found for revoke (5404479185228271586) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 0f71020..86a9fae 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -621,6 +621,10 @@
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Antaa sovelluksen muokata, miten sovellusten verkonkäyttöä lasketaan. Ei tavallisten sovellusten käyttöön."</string>
     <string name="permlab_accessNotifications" msgid="7673416487873432268">"käytä ilmoituksia"</string>
     <string name="permdesc_accessNotifications" msgid="458457742683431387">"Antaa sovelluksen noutaa, tutkia ja tyhjentää ilmoituksia (myös muiden sovelluksien lähettämiä)."</string>
+    <!-- no translation found for permlab_bindNotificationListenerService (7057764742211656654) -->
+    <skip />
+    <!-- no translation found for permdesc_bindNotificationListenerService (985697918576902986) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Aseta salasanasäännöt"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Hallinnoi ruudun lukituksenpoistosalasanoissa sallittuja merkkejä ja salasanan pituutta."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Tarkkaile ruudun lukituksen poistoyrityksiä"</string>
@@ -1048,8 +1052,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Tekstitoiminnot"</string>
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Tallennustila loppumassa"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Kaikki järjestelmätoiminnot eivät välttämättä toimi"</string>
-    <string name="app_running_notification_title" msgid="4625479411505090209">"<xliff:g id="APP_NAME">%1$s</xliff:g> on käynnissä"</string>
-    <string name="app_running_notification_text" msgid="3368349329989620597">"<xliff:g id="APP_NAME">%1$s</xliff:g> on käynnissä"</string>
+    <!-- no translation found for app_running_notification_title (8718335121060787914) -->
+    <skip />
+    <!-- no translation found for app_running_notification_text (4653586947747330058) -->
+    <skip />
     <string name="ok" msgid="5970060430562524910">"OK"</string>
     <string name="cancel" msgid="6442560571259935130">"Peruuta"</string>
     <string name="yes" msgid="5362982303337969312">"OK"</string>
@@ -1267,6 +1273,8 @@
     <string name="accessibility_binding_label" msgid="4148120742096474641">"Esteettömyys"</string>
     <string name="wallpaper_binding_label" msgid="1240087844304687662">"Taustakuva"</string>
     <string name="chooser_wallpaper" msgid="7873476199295190279">"Vaihda taustakuvaa"</string>
+    <!-- no translation found for notification_listener_binding_label (2014162835481906429) -->
+    <skip />
     <string name="vpn_title" msgid="19615213552042827">"VPN on aktivoitu"</string>
     <string name="vpn_title_long" msgid="6400714798049252294">"<xliff:g id="APP">%s</xliff:g> on aktivoinut VPN-yhteyden"</string>
     <string name="vpn_text" msgid="3011306607126450322">"Voit hallinnoida verkkoa koskettamalla."</string>
@@ -1370,6 +1378,10 @@
     <string name="action_bar_home_description" msgid="5293600496601490216">"Siirry etusivulle"</string>
     <string name="action_bar_up_description" msgid="2237496562952152589">"Siirry ylös"</string>
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"Lisää asetuksia"</string>
+    <!-- no translation found for action_bar_home_description_format (7965984360903693903) -->
+    <skip />
+    <!-- no translation found for action_bar_home_subtitle_description_format (6985546530471780727) -->
+    <skip />
     <string name="storage_internal" msgid="4891916833657929263">"Sisäinen tallennustila"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"SD-kortti"</string>
     <string name="storage_usb" msgid="3017954059538517278">"USB-tallennustila"</string>
@@ -1479,4 +1491,6 @@
     <string name="error_message_title" msgid="4510373083082500195">"Virhe"</string>
     <string name="app_no_restricted_accounts" msgid="5322164210667258876">"Tämä sovellus ei tue rajoitettujen käyttäjien tilejä"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Tätä toimintoa käsittelevää sovellusta ei löydy"</string>
+    <!-- no translation found for revoke (5404479185228271586) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 2026f56..3b539da8 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -621,6 +621,10 @@
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Permet à l\'application de modifier l\'utilisation du réseau par les autres applications. Les applications standards ne doivent pas utiliser cette fonctionnalité."</string>
     <string name="permlab_accessNotifications" msgid="7673416487873432268">"accéder aux notifications"</string>
     <string name="permdesc_accessNotifications" msgid="458457742683431387">"Permet aux applications de récupérer, d\'examiner et d\'autoriser les notifications, y compris celles envoyées par d\'autres applications."</string>
+    <!-- no translation found for permlab_bindNotificationListenerService (7057764742211656654) -->
+    <skip />
+    <!-- no translation found for permdesc_bindNotificationListenerService (985697918576902986) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Définir les règles du mot de passe"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Choisir le nombre et le type de caractères autorisés dans les mots de passe de déverrouillage de l\'écran"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Gérer les tentatives de déverrouillage de l\'écran"</string>
@@ -1048,8 +1052,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Actions sur le texte"</string>
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Espace de stockage bientôt saturé"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Il est possible que certaines fonctionnalités du système ne soient pas opérationnelles."</string>
-    <string name="app_running_notification_title" msgid="4625479411505090209">"<xliff:g id="APP_NAME">%1$s</xliff:g> en cours d\'exécution"</string>
-    <string name="app_running_notification_text" msgid="3368349329989620597">"<xliff:g id="APP_NAME">%1$s</xliff:g> est en cours d\'exécution."</string>
+    <!-- no translation found for app_running_notification_title (8718335121060787914) -->
+    <skip />
+    <!-- no translation found for app_running_notification_text (4653586947747330058) -->
+    <skip />
     <string name="ok" msgid="5970060430562524910">"OK"</string>
     <string name="cancel" msgid="6442560571259935130">"Annuler"</string>
     <string name="yes" msgid="5362982303337969312">"OK"</string>
@@ -1267,6 +1273,8 @@
     <string name="accessibility_binding_label" msgid="4148120742096474641">"Accessibilité"</string>
     <string name="wallpaper_binding_label" msgid="1240087844304687662">"Fond d\'écran"</string>
     <string name="chooser_wallpaper" msgid="7873476199295190279">"Changer de fond d\'écran"</string>
+    <!-- no translation found for notification_listener_binding_label (2014162835481906429) -->
+    <skip />
     <string name="vpn_title" msgid="19615213552042827">"VPN activé"</string>
     <string name="vpn_title_long" msgid="6400714798049252294">"VPN activé par <xliff:g id="APP">%s</xliff:g>"</string>
     <string name="vpn_text" msgid="3011306607126450322">"Appuyez ici pour gérer le réseau."</string>
@@ -1370,6 +1378,10 @@
     <string name="action_bar_home_description" msgid="5293600496601490216">"Retour à l\'accueil"</string>
     <string name="action_bar_up_description" msgid="2237496562952152589">"Parcourir vers le haut"</string>
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"Plus d\'options"</string>
+    <!-- no translation found for action_bar_home_description_format (7965984360903693903) -->
+    <skip />
+    <!-- no translation found for action_bar_home_subtitle_description_format (6985546530471780727) -->
+    <skip />
     <string name="storage_internal" msgid="4891916833657929263">"Mémoire de stockage interne"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"Carte SD"</string>
     <string name="storage_usb" msgid="3017954059538517278">"Mémoire de stockage USB"</string>
@@ -1479,4 +1491,6 @@
     <string name="error_message_title" msgid="4510373083082500195">"Erreur"</string>
     <string name="app_no_restricted_accounts" msgid="5322164210667258876">"Les comptes des utilisateurs en accès limité ne sont pas acceptés pour cette application."</string>
     <string name="app_not_found" msgid="3429141853498927379">"Aucune application trouvée pour gérer cette action."</string>
+    <!-- no translation found for revoke (5404479185228271586) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 1b3e6d7..ac20919 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -621,6 +621,10 @@
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"एप्लिकेशन को यह संशोधित करने देता है कि एप्‍लिकेशन की तुलना में नेटवर्क उपयोग का मूल्यांकन कैसे किया जाता है. सामान्‍य एप्‍लिकेशन द्वारा उपयोग करने के लिए नहीं."</string>
     <string name="permlab_accessNotifications" msgid="7673416487873432268">"सूचनाओं तक पहुंचें"</string>
     <string name="permdesc_accessNotifications" msgid="458457742683431387">"एप्लिकेशन को सूचनाओं को प्राप्त करने, जांच करने, और साफ़ करने देता है, जिनमें अन्य एप्लिकेशन के द्वारा पोस्ट की गई सूचनाएं भी शामिल हैं."</string>
+    <!-- no translation found for permlab_bindNotificationListenerService (7057764742211656654) -->
+    <skip />
+    <!-- no translation found for permdesc_bindNotificationListenerService (985697918576902986) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"पासवर्ड नियम सेट करें"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"स्‍क्रीन-अनलॉक पासवर्ड में अनुमति प्राप्त लंबाई और वर्णों को नियंत्रित करें."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"स्‍क्रीन-अनलॉक के प्रयासों पर निगरानी रखें"</string>
@@ -1048,8 +1052,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"पाठ क्रियाएं"</string>
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"संग्रहण स्‍थान समाप्‍त हो रहा है"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"हो सकता है कुछ सिस्टम फ़ंक्शन कार्य न करें"</string>
-    <string name="app_running_notification_title" msgid="4625479411505090209">"<xliff:g id="APP_NAME">%1$s</xliff:g> चल रहा है"</string>
-    <string name="app_running_notification_text" msgid="3368349329989620597">"<xliff:g id="APP_NAME">%1$s</xliff:g> वर्तमान में चल रहा है"</string>
+    <!-- no translation found for app_running_notification_title (8718335121060787914) -->
+    <skip />
+    <!-- no translation found for app_running_notification_text (4653586947747330058) -->
+    <skip />
     <string name="ok" msgid="5970060430562524910">"ठीक"</string>
     <string name="cancel" msgid="6442560571259935130">"रद्द करें"</string>
     <string name="yes" msgid="5362982303337969312">"ठीक"</string>
@@ -1267,6 +1273,8 @@
     <string name="accessibility_binding_label" msgid="4148120742096474641">"पहुंच-योग्यता"</string>
     <string name="wallpaper_binding_label" msgid="1240087844304687662">"वॉलपेपर"</string>
     <string name="chooser_wallpaper" msgid="7873476199295190279">"वॉलपेपर बदलें"</string>
+    <!-- no translation found for notification_listener_binding_label (2014162835481906429) -->
+    <skip />
     <string name="vpn_title" msgid="19615213552042827">"VPN सक्रिय"</string>
     <string name="vpn_title_long" msgid="6400714798049252294">"VPN को <xliff:g id="APP">%s</xliff:g> द्वारा सक्रिय किया गया है"</string>
     <string name="vpn_text" msgid="3011306607126450322">"नेटवर्क प्रबंधित करने के लिए स्‍पर्श करें."</string>
@@ -1370,6 +1378,10 @@
     <string name="action_bar_home_description" msgid="5293600496601490216">"होम पर नेविगेट करें"</string>
     <string name="action_bar_up_description" msgid="2237496562952152589">"ऊपर नेविगेट करें"</string>
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"अधिक विकल्प"</string>
+    <!-- no translation found for action_bar_home_description_format (7965984360903693903) -->
+    <skip />
+    <!-- no translation found for action_bar_home_subtitle_description_format (6985546530471780727) -->
+    <skip />
     <string name="storage_internal" msgid="4891916833657929263">"आंतरिक संग्रहण"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"SD कार्ड"</string>
     <string name="storage_usb" msgid="3017954059538517278">"USB संग्रहण"</string>
@@ -1479,4 +1491,6 @@
     <string name="error_message_title" msgid="4510373083082500195">"त्रुटि"</string>
     <string name="app_no_restricted_accounts" msgid="5322164210667258876">"यह एप्लिकेशन सीमित उपयोगकर्ताओं के खातों का समर्थन नहीं करता है"</string>
     <string name="app_not_found" msgid="3429141853498927379">"इस कार्यवाही को प्रबंधित करने के लिए कोई एप्लिकेशन नहीं मिला"</string>
+    <!-- no translation found for revoke (5404479185228271586) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 7b1eee3..9569a6c 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -621,6 +621,10 @@
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Omogućuje aplikaciji izmjenu načina upotrebe mreže u odnosu na aplikacije. Nije namijenjeno uobičajenim aplikacijama."</string>
     <string name="permlab_accessNotifications" msgid="7673416487873432268">"pristup obavijestima"</string>
     <string name="permdesc_accessNotifications" msgid="458457742683431387">"Omogućuje aplikaciji dohvaćanje, pregledavanje i brisanje obavijesti, uključujući obavijesti drugih aplikacija."</string>
+    <!-- no translation found for permlab_bindNotificationListenerService (7057764742211656654) -->
+    <skip />
+    <!-- no translation found for permdesc_bindNotificationListenerService (985697918576902986) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Postavi pravila zaporke"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Upravljajte duljinom zaporki za otključavanje zaslona i dopuštenim znakovima u tim zaporkama."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Nadgledaj pokušaje otključavanja zaslona"</string>
@@ -1048,8 +1052,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Radnje s tekstom"</string>
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Ponestaje prostora za pohranu"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Neke sistemske funkcije možda neće raditi"</string>
-    <string name="app_running_notification_title" msgid="4625479411505090209">"Izvodi se aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <string name="app_running_notification_text" msgid="3368349329989620597">"Trenutačno se izvodi aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+    <!-- no translation found for app_running_notification_title (8718335121060787914) -->
+    <skip />
+    <!-- no translation found for app_running_notification_text (4653586947747330058) -->
+    <skip />
     <string name="ok" msgid="5970060430562524910">"U redu"</string>
     <string name="cancel" msgid="6442560571259935130">"Odustani"</string>
     <string name="yes" msgid="5362982303337969312">"U redu"</string>
@@ -1267,6 +1273,8 @@
     <string name="accessibility_binding_label" msgid="4148120742096474641">"Dostupnost"</string>
     <string name="wallpaper_binding_label" msgid="1240087844304687662">"Pozadinska slika"</string>
     <string name="chooser_wallpaper" msgid="7873476199295190279">"Promjena pozadinske slike"</string>
+    <!-- no translation found for notification_listener_binding_label (2014162835481906429) -->
+    <skip />
     <string name="vpn_title" msgid="19615213552042827">"VPN aktiviran"</string>
     <string name="vpn_title_long" msgid="6400714798049252294">"Aplikacija <xliff:g id="APP">%s</xliff:g> aktivirala je VPN"</string>
     <string name="vpn_text" msgid="3011306607126450322">"Dodirnite za upravljanje mrežom."</string>
@@ -1370,6 +1378,10 @@
     <string name="action_bar_home_description" msgid="5293600496601490216">"Kreni na početnu"</string>
     <string name="action_bar_up_description" msgid="2237496562952152589">"Kreni gore"</string>
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"Više opcija"</string>
+    <!-- no translation found for action_bar_home_description_format (7965984360903693903) -->
+    <skip />
+    <!-- no translation found for action_bar_home_subtitle_description_format (6985546530471780727) -->
+    <skip />
     <string name="storage_internal" msgid="4891916833657929263">"Interna pohrana"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"SD kartica"</string>
     <string name="storage_usb" msgid="3017954059538517278">"USB pohrana"</string>
@@ -1479,4 +1491,6 @@
     <string name="error_message_title" msgid="4510373083082500195">"Pogreška"</string>
     <string name="app_no_restricted_accounts" msgid="5322164210667258876">"Aplikacija ne podržava račune za ograničene korisnike"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Nije pronađena aplikacija za upravljanje ovom radnjom"</string>
+    <!-- no translation found for revoke (5404479185228271586) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index fc1d663..61e3707 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -621,6 +621,10 @@
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Lehetővé teszi az alkalmazás számára annak módosítását, hogy a hálózathasználatot hogyan számolják el az alkalmazások esetében. Normál alkalmazások nem használhatják."</string>
     <string name="permlab_accessNotifications" msgid="7673416487873432268">"hozzáférési értesítések"</string>
     <string name="permdesc_accessNotifications" msgid="458457742683431387">"Lehetővé teszi, hogy az alkalmazás értesítéseket kérdezzen le, vizsgáljon és tisztítson meg, beleértve az egyéb alkalmazások által közzétett értesítéseket is."</string>
+    <!-- no translation found for permlab_bindNotificationListenerService (7057764742211656654) -->
+    <skip />
+    <!-- no translation found for permdesc_bindNotificationListenerService (985697918576902986) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Jelszavakkal kapcsolatos szabályok beállítása"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"A képernyőzár-feloldási jelszavakban engedélyezett karakterek és hosszúság vezérlése."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Képernyőzár-feloldási kísérletek figyelése"</string>
@@ -1048,8 +1052,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Műveletek szöveggel"</string>
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Kevés a szabad terület"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Előfordulhat, hogy néhány rendszerfunkció nem működik."</string>
-    <string name="app_running_notification_title" msgid="4625479411505090209">"A(z) <xliff:g id="APP_NAME">%1$s</xliff:g> fut"</string>
-    <string name="app_running_notification_text" msgid="3368349329989620597">"A(z) <xliff:g id="APP_NAME">%1$s</xliff:g> jelenleg fut"</string>
+    <!-- no translation found for app_running_notification_title (8718335121060787914) -->
+    <skip />
+    <!-- no translation found for app_running_notification_text (4653586947747330058) -->
+    <skip />
     <string name="ok" msgid="5970060430562524910">"OK"</string>
     <string name="cancel" msgid="6442560571259935130">"Mégse"</string>
     <string name="yes" msgid="5362982303337969312">"OK"</string>
@@ -1267,6 +1273,8 @@
     <string name="accessibility_binding_label" msgid="4148120742096474641">"Kisegítő lehetőségek"</string>
     <string name="wallpaper_binding_label" msgid="1240087844304687662">"Háttérkép"</string>
     <string name="chooser_wallpaper" msgid="7873476199295190279">"Háttérkép megváltoztatása"</string>
+    <!-- no translation found for notification_listener_binding_label (2014162835481906429) -->
+    <skip />
     <string name="vpn_title" msgid="19615213552042827">"VPN aktiválva"</string>
     <string name="vpn_title_long" msgid="6400714798049252294">"A(z) <xliff:g id="APP">%s</xliff:g> aktiválta a VPN-t"</string>
     <string name="vpn_text" msgid="3011306607126450322">"Érintse meg a hálózat kezeléséhez."</string>
@@ -1370,6 +1378,10 @@
     <string name="action_bar_home_description" msgid="5293600496601490216">"Ugrás a főoldalra"</string>
     <string name="action_bar_up_description" msgid="2237496562952152589">"Felfele mozgás"</string>
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"További lehetőségek"</string>
+    <!-- no translation found for action_bar_home_description_format (7965984360903693903) -->
+    <skip />
+    <!-- no translation found for action_bar_home_subtitle_description_format (6985546530471780727) -->
+    <skip />
     <string name="storage_internal" msgid="4891916833657929263">"Belső tárhely"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"SD-kártya"</string>
     <string name="storage_usb" msgid="3017954059538517278">"USB-tár"</string>
@@ -1479,4 +1491,6 @@
     <string name="error_message_title" msgid="4510373083082500195">"Hiba"</string>
     <string name="app_no_restricted_accounts" msgid="5322164210667258876">"Ez az alkalmazás nem támogatja a korlátozott jogokkal rendelkező felhasználói fiókokat."</string>
     <string name="app_not_found" msgid="3429141853498927379">"Nincs megfelelő alkalmazás a művelet elvégzésére."</string>
+    <!-- no translation found for revoke (5404479185228271586) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 2a9f2fc..f4664e9 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -621,6 +621,10 @@
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Mengizinkan apl memodifikasi cara penggunaan jaringan diperhitungkan terhadap apl. Tidak untuk digunakan oleh apl normal."</string>
     <string name="permlab_accessNotifications" msgid="7673416487873432268">"mengakses pemberitahuan"</string>
     <string name="permdesc_accessNotifications" msgid="458457742683431387">"Mengizinkan aplikasi mengambil, memeriksa, dan menghapus pemberitahuan, termasuk pemberitahuan yang diposkan oleh aplikasi lain."</string>
+    <!-- no translation found for permlab_bindNotificationListenerService (7057764742211656654) -->
+    <skip />
+    <!-- no translation found for permdesc_bindNotificationListenerService (985697918576902986) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Setel aturan sandi"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Kontrol panjang dan karakter yang diizinkan dalam sandi pembuka layar."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Upaya pembukaan kunci layar monitor"</string>
@@ -1048,8 +1052,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Tindakan teks"</string>
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Ruang penyimpanan hampir habis"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Beberapa fungsi sistem mungkin tidak dapat bekerja"</string>
-    <string name="app_running_notification_title" msgid="4625479411505090209">"<xliff:g id="APP_NAME">%1$s</xliff:g> berjalan"</string>
-    <string name="app_running_notification_text" msgid="3368349329989620597">"<xliff:g id="APP_NAME">%1$s</xliff:g> sedang berjalan"</string>
+    <!-- no translation found for app_running_notification_title (8718335121060787914) -->
+    <skip />
+    <!-- no translation found for app_running_notification_text (4653586947747330058) -->
+    <skip />
     <string name="ok" msgid="5970060430562524910">"Oke"</string>
     <string name="cancel" msgid="6442560571259935130">"Batal"</string>
     <string name="yes" msgid="5362982303337969312">"Oke"</string>
@@ -1267,6 +1273,8 @@
     <string name="accessibility_binding_label" msgid="4148120742096474641">"Aksesibilitas"</string>
     <string name="wallpaper_binding_label" msgid="1240087844304687662">"Wallpaper"</string>
     <string name="chooser_wallpaper" msgid="7873476199295190279">"Ubah wallpaper"</string>
+    <!-- no translation found for notification_listener_binding_label (2014162835481906429) -->
+    <skip />
     <string name="vpn_title" msgid="19615213552042827">"VPN diaktifkan"</string>
     <string name="vpn_title_long" msgid="6400714798049252294">"VPN diaktifkan oleh <xliff:g id="APP">%s</xliff:g>"</string>
     <string name="vpn_text" msgid="3011306607126450322">"Sentuh untuk mengelola jaringan."</string>
@@ -1370,6 +1378,10 @@
     <string name="action_bar_home_description" msgid="5293600496601490216">"Navigasi ke beranda"</string>
     <string name="action_bar_up_description" msgid="2237496562952152589">"Navigasi naik"</string>
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"Opsi lainnya"</string>
+    <!-- no translation found for action_bar_home_description_format (7965984360903693903) -->
+    <skip />
+    <!-- no translation found for action_bar_home_subtitle_description_format (6985546530471780727) -->
+    <skip />
     <string name="storage_internal" msgid="4891916833657929263">"Penyimpanan internal"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"Kartu SD"</string>
     <string name="storage_usb" msgid="3017954059538517278">"Penyimpanan USB"</string>
@@ -1479,4 +1491,6 @@
     <string name="error_message_title" msgid="4510373083082500195">"Kesalahan"</string>
     <string name="app_no_restricted_accounts" msgid="5322164210667258876">"Aplikasi ini tidak mendukung akun untuk pengguna terbatas"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Tidak ada aplikasi yang ditemukan untuk menangani tindakan ini"</string>
+    <!-- no translation found for revoke (5404479185228271586) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 2273459..592492a 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -621,6 +621,10 @@
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Consente all\'applicazione di modificare il calcolo dell\'utilizzo della rete tra le applicazioni. Da non usare per normali applicazioni."</string>
     <string name="permlab_accessNotifications" msgid="7673416487873432268">"accesso a notifiche"</string>
     <string name="permdesc_accessNotifications" msgid="458457742683431387">"Consente all\'app di recuperare, esaminare e cancellare notifiche, comprese quelle pubblicate da altre app."</string>
+    <!-- no translation found for permlab_bindNotificationListenerService (7057764742211656654) -->
+    <skip />
+    <!-- no translation found for permdesc_bindNotificationListenerService (985697918576902986) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Imposta regole password"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Controlla la lunghezza e i caratteri ammessi nelle password di sblocco dello schermo."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Monitora tentativi di sblocco dello schermo"</string>
@@ -1048,8 +1052,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Azioni testo"</string>
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Spazio di archiviazione in esaurimento"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Alcune funzioni di sistema potrebbero non funzionare"</string>
-    <string name="app_running_notification_title" msgid="4625479411505090209">"<xliff:g id="APP_NAME">%1$s</xliff:g> in esecuzione"</string>
-    <string name="app_running_notification_text" msgid="3368349329989620597">"<xliff:g id="APP_NAME">%1$s</xliff:g> è attualmente in esecuzione"</string>
+    <!-- no translation found for app_running_notification_title (8718335121060787914) -->
+    <skip />
+    <!-- no translation found for app_running_notification_text (4653586947747330058) -->
+    <skip />
     <string name="ok" msgid="5970060430562524910">"OK"</string>
     <string name="cancel" msgid="6442560571259935130">"Annulla"</string>
     <string name="yes" msgid="5362982303337969312">"OK"</string>
@@ -1267,6 +1273,8 @@
     <string name="accessibility_binding_label" msgid="4148120742096474641">"Accessibilità"</string>
     <string name="wallpaper_binding_label" msgid="1240087844304687662">"Sfondo"</string>
     <string name="chooser_wallpaper" msgid="7873476199295190279">"Cambia sfondo"</string>
+    <!-- no translation found for notification_listener_binding_label (2014162835481906429) -->
+    <skip />
     <string name="vpn_title" msgid="19615213552042827">"VPN attiva"</string>
     <string name="vpn_title_long" msgid="6400714798049252294">"VPN attivata da <xliff:g id="APP">%s</xliff:g>"</string>
     <string name="vpn_text" msgid="3011306607126450322">"Tocca per gestire la rete."</string>
@@ -1370,6 +1378,10 @@
     <string name="action_bar_home_description" msgid="5293600496601490216">"Vai alla home page"</string>
     <string name="action_bar_up_description" msgid="2237496562952152589">"Vai in alto"</string>
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"Altre opzioni"</string>
+    <!-- no translation found for action_bar_home_description_format (7965984360903693903) -->
+    <skip />
+    <!-- no translation found for action_bar_home_subtitle_description_format (6985546530471780727) -->
+    <skip />
     <string name="storage_internal" msgid="4891916833657929263">"Memoria interna"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"Scheda SD"</string>
     <string name="storage_usb" msgid="3017954059538517278">"Archivio USB"</string>
@@ -1479,4 +1491,6 @@
     <string name="error_message_title" msgid="4510373083082500195">"Errore"</string>
     <string name="app_no_restricted_accounts" msgid="5322164210667258876">"Questa applicazione non supporta account di utenti con limitazioni"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Nessuna applicazione trovata in grado di gestire questa azione"</string>
+    <!-- no translation found for revoke (5404479185228271586) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 8c7c74e..97c52c5 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -621,6 +621,10 @@
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"הרשאה זו מאפשרת ליישום לשנות את אופן החישוב של נתוני שימוש ברשת מול כל יישום. לא מיועד לשימוש ביישומים רגילים."</string>
     <string name="permlab_accessNotifications" msgid="7673416487873432268">"גישה להתראות"</string>
     <string name="permdesc_accessNotifications" msgid="458457742683431387">"מאפשר ליישום לאחזר, לבדוק ולמחוק התראות, כולל כאלה שפורסמו על ידי יישומים אחרים."</string>
+    <!-- no translation found for permlab_bindNotificationListenerService (7057764742211656654) -->
+    <skip />
+    <!-- no translation found for permdesc_bindNotificationListenerService (985697918576902986) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"הגדר כללי סיסמה"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"שלוט באורך ובתווים המותרים בסיסמאות לביטול נעילת מסך."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"עקוב אחר ניסיונות לביטול נעילת מסך"</string>
@@ -1048,8 +1052,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"פעולות טקסט"</string>
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"שטח האחסון אוזל"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"ייתכן שפונקציות מערכת מסוימות לא יפעלו"</string>
-    <string name="app_running_notification_title" msgid="4625479411505090209">"<xliff:g id="APP_NAME">%1$s</xliff:g> פועל"</string>
-    <string name="app_running_notification_text" msgid="3368349329989620597">"<xliff:g id="APP_NAME">%1$s</xliff:g> פועל כרגע"</string>
+    <!-- no translation found for app_running_notification_title (8718335121060787914) -->
+    <skip />
+    <!-- no translation found for app_running_notification_text (4653586947747330058) -->
+    <skip />
     <string name="ok" msgid="5970060430562524910">"אישור"</string>
     <string name="cancel" msgid="6442560571259935130">"ביטול"</string>
     <string name="yes" msgid="5362982303337969312">"אישור"</string>
@@ -1267,6 +1273,8 @@
     <string name="accessibility_binding_label" msgid="4148120742096474641">"נגישות"</string>
     <string name="wallpaper_binding_label" msgid="1240087844304687662">"טפט"</string>
     <string name="chooser_wallpaper" msgid="7873476199295190279">"שנה טפט"</string>
+    <!-- no translation found for notification_listener_binding_label (2014162835481906429) -->
+    <skip />
     <string name="vpn_title" msgid="19615213552042827">"VPN מופעל"</string>
     <string name="vpn_title_long" msgid="6400714798049252294">"VPN מופעל על ידי <xliff:g id="APP">%s</xliff:g>"</string>
     <string name="vpn_text" msgid="3011306607126450322">"גע כדי לנהל את הרשת."</string>
@@ -1370,6 +1378,10 @@
     <string name="action_bar_home_description" msgid="5293600496601490216">"נווט לדף הבית"</string>
     <string name="action_bar_up_description" msgid="2237496562952152589">"נווט למעלה"</string>
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"אפשרויות נוספות"</string>
+    <!-- no translation found for action_bar_home_description_format (7965984360903693903) -->
+    <skip />
+    <!-- no translation found for action_bar_home_subtitle_description_format (6985546530471780727) -->
+    <skip />
     <string name="storage_internal" msgid="4891916833657929263">"אחסון פנימי"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"כרטיס SD"</string>
     <string name="storage_usb" msgid="3017954059538517278">"אחסון USB"</string>
@@ -1479,4 +1491,6 @@
     <string name="error_message_title" msgid="4510373083082500195">"שגיאה"</string>
     <string name="app_no_restricted_accounts" msgid="5322164210667258876">"היישום הזה לא תומך בחשבונות עבור משתמשים מוגבלים"</string>
     <string name="app_not_found" msgid="3429141853498927379">"לא נמצא יישום שתומך בפעולה זו"</string>
+    <!-- no translation found for revoke (5404479185228271586) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 4ec756e..0abacb1 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -621,6 +621,10 @@
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"アプリに対するネットワーク利用の計算方法を変更することをアプリに許可します。通常のアプリでは使用しません。"</string>
     <string name="permlab_accessNotifications" msgid="7673416487873432268">"通知にアクセス"</string>
     <string name="permdesc_accessNotifications" msgid="458457742683431387">"通知(他のアプリから投稿されたものも含む)を取得、調査、クリアすることをアプリに許可します。"</string>
+    <!-- no translation found for permlab_bindNotificationListenerService (7057764742211656654) -->
+    <skip />
+    <!-- no translation found for permdesc_bindNotificationListenerService (985697918576902986) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"パスワードルールの設定"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"画面ロック解除パスワードの長さと使用できる文字を制御します。"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"画面ロック解除試行の監視"</string>
@@ -1048,8 +1052,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"テキスト操作"</string>
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"空き容量わずか"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"一部のシステム機能が動作しない可能性があります"</string>
-    <string name="app_running_notification_title" msgid="4625479411505090209">"<xliff:g id="APP_NAME">%1$s</xliff:g>を実行中"</string>
-    <string name="app_running_notification_text" msgid="3368349329989620597">"現在<xliff:g id="APP_NAME">%1$s</xliff:g>を実行しています"</string>
+    <!-- no translation found for app_running_notification_title (8718335121060787914) -->
+    <skip />
+    <!-- no translation found for app_running_notification_text (4653586947747330058) -->
+    <skip />
     <string name="ok" msgid="5970060430562524910">"OK"</string>
     <string name="cancel" msgid="6442560571259935130">"キャンセル"</string>
     <string name="yes" msgid="5362982303337969312">"OK"</string>
@@ -1267,6 +1273,8 @@
     <string name="accessibility_binding_label" msgid="4148120742096474641">"ユーザー補助"</string>
     <string name="wallpaper_binding_label" msgid="1240087844304687662">"壁紙"</string>
     <string name="chooser_wallpaper" msgid="7873476199295190279">"壁紙を変更"</string>
+    <!-- no translation found for notification_listener_binding_label (2014162835481906429) -->
+    <skip />
     <string name="vpn_title" msgid="19615213552042827">"VPNが有効になりました"</string>
     <string name="vpn_title_long" msgid="6400714798049252294">"VPNが<xliff:g id="APP">%s</xliff:g>により有効化されました"</string>
     <string name="vpn_text" msgid="3011306607126450322">"タップしてネットワークを管理します。"</string>
@@ -1370,6 +1378,10 @@
     <string name="action_bar_home_description" msgid="5293600496601490216">"ホームへ移動"</string>
     <string name="action_bar_up_description" msgid="2237496562952152589">"上へ移動"</string>
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"その他のオプション"</string>
+    <!-- no translation found for action_bar_home_description_format (7965984360903693903) -->
+    <skip />
+    <!-- no translation found for action_bar_home_subtitle_description_format (6985546530471780727) -->
+    <skip />
     <string name="storage_internal" msgid="4891916833657929263">"内部ストレージ"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"SDカード"</string>
     <string name="storage_usb" msgid="3017954059538517278">"USBストレージ"</string>
@@ -1479,4 +1491,6 @@
     <string name="error_message_title" msgid="4510373083082500195">"エラー"</string>
     <string name="app_no_restricted_accounts" msgid="5322164210667258876">"このアプリでは限定ユーザー用のアカウントはサポートしていません"</string>
     <string name="app_not_found" msgid="3429141853498927379">"この操作を行うアプリが見つかりません"</string>
+    <!-- no translation found for revoke (5404479185228271586) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index e6010ac..b07878c 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -621,6 +621,10 @@
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"애플리케이션이 애플리케이션의 네트워크 사용량을 계산하는 방식을 수정할 수 있도록 허용합니다. 일반 애플리케이션에서는 사용하지 않습니다."</string>
     <string name="permlab_accessNotifications" msgid="7673416487873432268">"알림 액세스"</string>
     <string name="permdesc_accessNotifications" msgid="458457742683431387">"앱이 다른 앱에서 게시한 알림을 비롯하여 알림을 검색하고 살펴보며 삭제할 수 있도록 허용합니다."</string>
+    <!-- no translation found for permlab_bindNotificationListenerService (7057764742211656654) -->
+    <skip />
+    <!-- no translation found for permdesc_bindNotificationListenerService (985697918576902986) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"비밀번호 규칙 설정"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"화면 잠금해제 비밀번호에 허용되는 길이 및 문자 수를 제어합니다."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"화면 잠금해제 시도 모니터링"</string>
@@ -1048,8 +1052,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"텍스트 작업"</string>
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"저장 공간이 부족함"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"일부 시스템 기능이 작동하지 않을 수 있습니다."</string>
-    <string name="app_running_notification_title" msgid="4625479411505090209">"<xliff:g id="APP_NAME">%1$s</xliff:g> 실행 중"</string>
-    <string name="app_running_notification_text" msgid="3368349329989620597">"<xliff:g id="APP_NAME">%1$s</xliff:g>이(가) 현재 실행 중입니다."</string>
+    <!-- no translation found for app_running_notification_title (8718335121060787914) -->
+    <skip />
+    <!-- no translation found for app_running_notification_text (4653586947747330058) -->
+    <skip />
     <string name="ok" msgid="5970060430562524910">"확인"</string>
     <string name="cancel" msgid="6442560571259935130">"취소"</string>
     <string name="yes" msgid="5362982303337969312">"확인"</string>
@@ -1267,6 +1273,8 @@
     <string name="accessibility_binding_label" msgid="4148120742096474641">"접근성"</string>
     <string name="wallpaper_binding_label" msgid="1240087844304687662">"배경화면"</string>
     <string name="chooser_wallpaper" msgid="7873476199295190279">"배경화면 변경"</string>
+    <!-- no translation found for notification_listener_binding_label (2014162835481906429) -->
+    <skip />
     <string name="vpn_title" msgid="19615213552042827">"VPN이 활성화됨"</string>
     <string name="vpn_title_long" msgid="6400714798049252294">"VPN이 <xliff:g id="APP">%s</xliff:g>에 의해 활성화됨"</string>
     <string name="vpn_text" msgid="3011306607126450322">"네트워크를 관리하려면 터치하세요."</string>
@@ -1370,6 +1378,10 @@
     <string name="action_bar_home_description" msgid="5293600496601490216">"홈 탐색"</string>
     <string name="action_bar_up_description" msgid="2237496562952152589">"위로 탐색"</string>
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"옵션 더보기"</string>
+    <!-- no translation found for action_bar_home_description_format (7965984360903693903) -->
+    <skip />
+    <!-- no translation found for action_bar_home_subtitle_description_format (6985546530471780727) -->
+    <skip />
     <string name="storage_internal" msgid="4891916833657929263">"내부 저장소"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"SD 카드"</string>
     <string name="storage_usb" msgid="3017954059538517278">"USB 저장소"</string>
@@ -1479,4 +1491,6 @@
     <string name="error_message_title" msgid="4510373083082500195">"오류"</string>
     <string name="app_no_restricted_accounts" msgid="5322164210667258876">"이 애플리케이션은 제한된 사용자를 위한 계정을 지원하지 않습니다."</string>
     <string name="app_not_found" msgid="3429141853498927379">"이 작업을 처리하는 애플리케이션을 찾을 수 없습니다."</string>
+    <!-- no translation found for revoke (5404479185228271586) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index e8d7c26..1b7b68e 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -621,6 +621,10 @@
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Leidžiama programai keisti, kaip tinklas naudojamas, palyginti su programomis. Neskirta naudoti įprastoms programoms."</string>
     <string name="permlab_accessNotifications" msgid="7673416487873432268">"pasiekti pranešimus"</string>
     <string name="permdesc_accessNotifications" msgid="458457742683431387">"Programai leidžiama gauti, patikrinti ir išvalyti pranešimus, įskaitant pranešimus, kuriuos paskelbė kitos programos."</string>
+    <!-- no translation found for permlab_bindNotificationListenerService (7057764742211656654) -->
+    <skip />
+    <!-- no translation found for permdesc_bindNotificationListenerService (985697918576902986) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Nustatyti slaptažodžio taisykles"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Valdyti leidžiamą ekrano atrakinimo slaptažodžių ilgį ir leidžiamus naudoti simbolius."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Stebėti bandymus atrakinti ekraną"</string>
@@ -1048,8 +1052,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Teksto veiksmai"</string>
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Mažėja laisvos saugyklos vietos"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Kai kurios sistemos funkcijos gali neveikti"</string>
-    <string name="app_running_notification_title" msgid="4625479411505090209">"„<xliff:g id="APP_NAME">%1$s</xliff:g>“ paleista"</string>
-    <string name="app_running_notification_text" msgid="3368349329989620597">"„<xliff:g id="APP_NAME">%1$s</xliff:g>“ šiuo metu paleista"</string>
+    <!-- no translation found for app_running_notification_title (8718335121060787914) -->
+    <skip />
+    <!-- no translation found for app_running_notification_text (4653586947747330058) -->
+    <skip />
     <string name="ok" msgid="5970060430562524910">"Gerai"</string>
     <string name="cancel" msgid="6442560571259935130">"Atšaukti"</string>
     <string name="yes" msgid="5362982303337969312">"Gerai"</string>
@@ -1267,6 +1273,8 @@
     <string name="accessibility_binding_label" msgid="4148120742096474641">"Pasiekiamumas"</string>
     <string name="wallpaper_binding_label" msgid="1240087844304687662">"Darbalaukio fonas"</string>
     <string name="chooser_wallpaper" msgid="7873476199295190279">"Keisti darbalaukio foną"</string>
+    <!-- no translation found for notification_listener_binding_label (2014162835481906429) -->
+    <skip />
     <string name="vpn_title" msgid="19615213552042827">"VPN suaktyvintas"</string>
     <string name="vpn_title_long" msgid="6400714798049252294">"VPN suaktyvino „<xliff:g id="APP">%s</xliff:g>“"</string>
     <string name="vpn_text" msgid="3011306607126450322">"Palieskite, kad valdytumėte tinklą."</string>
@@ -1370,6 +1378,10 @@
     <string name="action_bar_home_description" msgid="5293600496601490216">"Naršyti pagrindinį puslapį"</string>
     <string name="action_bar_up_description" msgid="2237496562952152589">"Naršyti į viršų"</string>
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"Daugiau parinkčių"</string>
+    <!-- no translation found for action_bar_home_description_format (7965984360903693903) -->
+    <skip />
+    <!-- no translation found for action_bar_home_subtitle_description_format (6985546530471780727) -->
+    <skip />
     <string name="storage_internal" msgid="4891916833657929263">"Vidinė atmintis"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"SD kortelė"</string>
     <string name="storage_usb" msgid="3017954059538517278">"USB atmintis"</string>
@@ -1479,4 +1491,6 @@
     <string name="error_message_title" msgid="4510373083082500195">"Klaida"</string>
     <string name="app_no_restricted_accounts" msgid="5322164210667258876">"Ši programa nepalaiko apribotų naudotojų paskyrų"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Nerasta programa šiam veiksmui apdoroti"</string>
+    <!-- no translation found for revoke (5404479185228271586) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index f134005..9ae5381d 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -621,6 +621,10 @@
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Ļauj lietotnei mainīt to, kā tīkla lietojums tiek uzskaitīts saistībā ar lietotnēm. Atļauja neattiecas uz parastām lietotnēm."</string>
     <string name="permlab_accessNotifications" msgid="7673416487873432268">"piekļuve paziņojumiem"</string>
     <string name="permdesc_accessNotifications" msgid="458457742683431387">"Ļauj lietotnei izgūt, pārbaudīt un dzēst paziņojumus, tostarp lietotņu publicētos paziņojumus."</string>
+    <!-- no translation found for permlab_bindNotificationListenerService (7057764742211656654) -->
+    <skip />
+    <!-- no translation found for permdesc_bindNotificationListenerService (985697918576902986) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Paroles kārtulu iestatīšana"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Kontrolē ekrāna atbloķēšanas parolē atļautās rakstzīmes un garumu."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Ekrāna atbloķēšanas mēģinājumu pārraudzīšana"</string>
@@ -1048,8 +1052,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Teksta darbības"</string>
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Paliek maz brīvas vietas"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Dažas sistēmas funkcijas var nedarboties."</string>
-    <string name="app_running_notification_title" msgid="4625479411505090209">"Lietotne <xliff:g id="APP_NAME">%1$s</xliff:g> darbojas"</string>
-    <string name="app_running_notification_text" msgid="3368349329989620597">"Lietotne <xliff:g id="APP_NAME">%1$s</xliff:g> pašlaik darbojas"</string>
+    <!-- no translation found for app_running_notification_title (8718335121060787914) -->
+    <skip />
+    <!-- no translation found for app_running_notification_text (4653586947747330058) -->
+    <skip />
     <string name="ok" msgid="5970060430562524910">"Labi"</string>
     <string name="cancel" msgid="6442560571259935130">"Atcelt"</string>
     <string name="yes" msgid="5362982303337969312">"Labi"</string>
@@ -1267,6 +1273,8 @@
     <string name="accessibility_binding_label" msgid="4148120742096474641">"Pieejamība"</string>
     <string name="wallpaper_binding_label" msgid="1240087844304687662">"Fona tapete"</string>
     <string name="chooser_wallpaper" msgid="7873476199295190279">"Tapetes maiņa"</string>
+    <!-- no translation found for notification_listener_binding_label (2014162835481906429) -->
+    <skip />
     <string name="vpn_title" msgid="19615213552042827">"VPN ir aktivizēts."</string>
     <string name="vpn_title_long" msgid="6400714798049252294">"Lietojumprogramma <xliff:g id="APP">%s</xliff:g> aktivizēja VPN."</string>
     <string name="vpn_text" msgid="3011306607126450322">"Pieskarieties, lai pārvaldītu tīklu."</string>
@@ -1370,6 +1378,10 @@
     <string name="action_bar_home_description" msgid="5293600496601490216">"Pārvietoties uz sākuma ekrānu"</string>
     <string name="action_bar_up_description" msgid="2237496562952152589">"Pārvietoties augšup"</string>
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"Vairāk opciju"</string>
+    <!-- no translation found for action_bar_home_description_format (7965984360903693903) -->
+    <skip />
+    <!-- no translation found for action_bar_home_subtitle_description_format (6985546530471780727) -->
+    <skip />
     <string name="storage_internal" msgid="4891916833657929263">"Iekšējā atmiņa"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"SD karte"</string>
     <string name="storage_usb" msgid="3017954059538517278">"USB atmiņa"</string>
@@ -1479,4 +1491,6 @@
     <string name="error_message_title" msgid="4510373083082500195">"Kļūda"</string>
     <string name="app_no_restricted_accounts" msgid="5322164210667258876">"Šajā lietojumprogrammā netiek atbalstīti ierobežotu lietotāju konti."</string>
     <string name="app_not_found" msgid="3429141853498927379">"Netika atrasta neviena lietojumprogramma, kas var veikt šo darbību."</string>
+    <!-- no translation found for revoke (5404479185228271586) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index 3091e7d..bbde90d 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -621,6 +621,10 @@
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Membenarkan apl untuk mengubah suai bagaimana penggunaan rangkaian diambil kira terhadap apl. Bukan untuk digunakan oleh apl biasa."</string>
     <string name="permlab_accessNotifications" msgid="7673416487873432268">"pemberitahuan akses"</string>
     <string name="permdesc_accessNotifications" msgid="458457742683431387">"Membenarkan apl untuk mendapatkan semula, memeriksa dan memadam bersih pemberitahuan, termasuk yang disiarkan oleh apl lain."</string>
+    <!-- no translation found for permlab_bindNotificationListenerService (7057764742211656654) -->
+    <skip />
+    <!-- no translation found for permdesc_bindNotificationListenerService (985697918576902986) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Tetapkan peraturan kata laluan"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Mengawal panjang dan aksara yang dibenarkan dalam kata laluan buka kunci skrin."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Memantau percubaan buka kunci skrin"</string>
@@ -1048,8 +1052,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Tindakan teks"</string>
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Ruang storan semakin berkurangan"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Beberapa fungsi sistem mungkin tidak berfungsi"</string>
-    <string name="app_running_notification_title" msgid="4625479411505090209">"<xliff:g id="APP_NAME">%1$s</xliff:g> berjalan"</string>
-    <string name="app_running_notification_text" msgid="3368349329989620597">"<xliff:g id="APP_NAME">%1$s</xliff:g> sedang berjalan"</string>
+    <!-- no translation found for app_running_notification_title (8718335121060787914) -->
+    <skip />
+    <!-- no translation found for app_running_notification_text (4653586947747330058) -->
+    <skip />
     <string name="ok" msgid="5970060430562524910">"OK"</string>
     <string name="cancel" msgid="6442560571259935130">"Batal"</string>
     <string name="yes" msgid="5362982303337969312">"OK"</string>
@@ -1267,6 +1273,8 @@
     <string name="accessibility_binding_label" msgid="4148120742096474641">"Kebolehaksesan"</string>
     <string name="wallpaper_binding_label" msgid="1240087844304687662">"Kertas dinding"</string>
     <string name="chooser_wallpaper" msgid="7873476199295190279">"Tukar kertas dinding"</string>
+    <!-- no translation found for notification_listener_binding_label (2014162835481906429) -->
+    <skip />
     <string name="vpn_title" msgid="19615213552042827">"VPN diaktifkan"</string>
     <string name="vpn_title_long" msgid="6400714798049252294">"VPN diaktifkan oleh <xliff:g id="APP">%s</xliff:g>"</string>
     <string name="vpn_text" msgid="3011306607126450322">"Sentuh untuk mengurus rangkaian."</string>
@@ -1370,6 +1378,10 @@
     <string name="action_bar_home_description" msgid="5293600496601490216">"Navigasi laman utama"</string>
     <string name="action_bar_up_description" msgid="2237496562952152589">"Navigasi ke atas"</string>
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"Lagi pilihan"</string>
+    <!-- no translation found for action_bar_home_description_format (7965984360903693903) -->
+    <skip />
+    <!-- no translation found for action_bar_home_subtitle_description_format (6985546530471780727) -->
+    <skip />
     <string name="storage_internal" msgid="4891916833657929263">"Storan dalaman"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"Kad SD"</string>
     <string name="storage_usb" msgid="3017954059538517278">"Storan USB"</string>
@@ -1479,4 +1491,6 @@
     <string name="error_message_title" msgid="4510373083082500195">"Ralat"</string>
     <string name="app_no_restricted_accounts" msgid="5322164210667258876">"Aplikasi ini tidak menyokong akaun untuk pengguna terhad"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Tidak menemui aplikasi untuk mengendalikan tindakan ini"</string>
+    <!-- no translation found for revoke (5404479185228271586) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 9d39ac8..3bb5022 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -621,6 +621,10 @@
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Lar appen endre hvordan nettverksbruk regnes ut for apper. Ikke beregnet på vanlige apper."</string>
     <string name="permlab_accessNotifications" msgid="7673416487873432268">"varseltilgang"</string>
     <string name="permdesc_accessNotifications" msgid="458457742683431387">"Lar appen hente, gjennomgå og fjerne varsler, inkludert de som sendes fra andre apper."</string>
+    <!-- no translation found for permlab_bindNotificationListenerService (7057764742211656654) -->
+    <skip />
+    <!-- no translation found for permdesc_bindNotificationListenerService (985697918576902986) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Angi passordregler"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Kontroller tillatt lengde og tillatte tegn i passord for opplåsing av skjerm."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Overvåk forsøk på opplåsing av skjerm"</string>
@@ -1048,8 +1052,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Teksthandlinger"</string>
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Lite ledig lagringsplass"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Enkelte systemfunksjoner fungerer muligens ikke slik de skal"</string>
-    <string name="app_running_notification_title" msgid="4625479411505090209">"<xliff:g id="APP_NAME">%1$s</xliff:g> kjører"</string>
-    <string name="app_running_notification_text" msgid="3368349329989620597">"<xliff:g id="APP_NAME">%1$s</xliff:g> kjører for øyeblikket"</string>
+    <!-- no translation found for app_running_notification_title (8718335121060787914) -->
+    <skip />
+    <!-- no translation found for app_running_notification_text (4653586947747330058) -->
+    <skip />
     <string name="ok" msgid="5970060430562524910">"OK"</string>
     <string name="cancel" msgid="6442560571259935130">"Avbryt"</string>
     <string name="yes" msgid="5362982303337969312">"OK"</string>
@@ -1267,6 +1273,8 @@
     <string name="accessibility_binding_label" msgid="4148120742096474641">"Tilgjengelighet"</string>
     <string name="wallpaper_binding_label" msgid="1240087844304687662">"Bakgrunnsbilde"</string>
     <string name="chooser_wallpaper" msgid="7873476199295190279">"Velg bakgrunnsbilde"</string>
+    <!-- no translation found for notification_listener_binding_label (2014162835481906429) -->
+    <skip />
     <string name="vpn_title" msgid="19615213552042827">"VPN er aktivert"</string>
     <string name="vpn_title_long" msgid="6400714798049252294">"VPN er aktivert av <xliff:g id="APP">%s</xliff:g>"</string>
     <string name="vpn_text" msgid="3011306607126450322">"Trykk for å administrere nettverket."</string>
@@ -1370,6 +1378,10 @@
     <string name="action_bar_home_description" msgid="5293600496601490216">"Gå til startsiden"</string>
     <string name="action_bar_up_description" msgid="2237496562952152589">"Gå opp"</string>
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"Flere alternativer"</string>
+    <!-- no translation found for action_bar_home_description_format (7965984360903693903) -->
+    <skip />
+    <!-- no translation found for action_bar_home_subtitle_description_format (6985546530471780727) -->
+    <skip />
     <string name="storage_internal" msgid="4891916833657929263">"Intern lagring"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"SD-kort"</string>
     <string name="storage_usb" msgid="3017954059538517278">"USB-lagring"</string>
@@ -1479,4 +1491,6 @@
     <string name="error_message_title" msgid="4510373083082500195">"Feil"</string>
     <string name="app_no_restricted_accounts" msgid="5322164210667258876">"Denne appen støtter ikke kontoer for brukere med begrensninger"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Finner ingen apper som kan utføre denne handlingen"</string>
+    <!-- no translation found for revoke (5404479185228271586) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index b0a6d30..4d71f08 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -621,6 +621,10 @@
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Hiermee kan een app aanpassen hoe het netwerkgebruik wordt toegekend aan apps. Dit wordt niet gebruikt door normale apps."</string>
     <string name="permlab_accessNotifications" msgid="7673416487873432268">"toegang tot meldingen"</string>
     <string name="permdesc_accessNotifications" msgid="458457742683431387">"Hiermee kan de app meldingen ophalen, onderzoeken en wissen, waaronder meldingen die zijn verzonden door andere apps."</string>
+    <!-- no translation found for permlab_bindNotificationListenerService (7057764742211656654) -->
+    <skip />
+    <!-- no translation found for permdesc_bindNotificationListenerService (985697918576902986) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Wachtwoordregels instellen"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"De lengte en tekens beheren die zijn toegestaan in wachtwoorden voor schermontgrendeling."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Pogingen voor schermontgrendeling bijhouden"</string>
@@ -1048,8 +1052,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Tekstacties"</string>
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Opslagruimte is bijna vol"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Bepaalde systeemfuncties werken mogelijk niet"</string>
-    <string name="app_running_notification_title" msgid="4625479411505090209">"<xliff:g id="APP_NAME">%1$s</xliff:g> is actief"</string>
-    <string name="app_running_notification_text" msgid="3368349329989620597">"<xliff:g id="APP_NAME">%1$s</xliff:g> is momenteel actief"</string>
+    <!-- no translation found for app_running_notification_title (8718335121060787914) -->
+    <skip />
+    <!-- no translation found for app_running_notification_text (4653586947747330058) -->
+    <skip />
     <string name="ok" msgid="5970060430562524910">"OK"</string>
     <string name="cancel" msgid="6442560571259935130">"Annuleren"</string>
     <string name="yes" msgid="5362982303337969312">"OK"</string>
@@ -1267,6 +1273,8 @@
     <string name="accessibility_binding_label" msgid="4148120742096474641">"Toegankelijkheid"</string>
     <string name="wallpaper_binding_label" msgid="1240087844304687662">"Achtergrond"</string>
     <string name="chooser_wallpaper" msgid="7873476199295190279">"Achtergrond wijzigen"</string>
+    <!-- no translation found for notification_listener_binding_label (2014162835481906429) -->
+    <skip />
     <string name="vpn_title" msgid="19615213552042827">"VPN is geactiveerd"</string>
     <string name="vpn_title_long" msgid="6400714798049252294">"VPN wordt geactiveerd door <xliff:g id="APP">%s</xliff:g>"</string>
     <string name="vpn_text" msgid="3011306607126450322">"Raak aan om het netwerk te beheren."</string>
@@ -1370,6 +1378,10 @@
     <string name="action_bar_home_description" msgid="5293600496601490216">"Navigeren naar startpositie"</string>
     <string name="action_bar_up_description" msgid="2237496562952152589">"Omhoog navigeren"</string>
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"Meer opties"</string>
+    <!-- no translation found for action_bar_home_description_format (7965984360903693903) -->
+    <skip />
+    <!-- no translation found for action_bar_home_subtitle_description_format (6985546530471780727) -->
+    <skip />
     <string name="storage_internal" msgid="4891916833657929263">"Interne opslag"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"SD-kaart"</string>
     <string name="storage_usb" msgid="3017954059538517278">"USB-opslag"</string>
@@ -1479,4 +1491,6 @@
     <string name="error_message_title" msgid="4510373083082500195">"Fout"</string>
     <string name="app_no_restricted_accounts" msgid="5322164210667258876">"Deze app ondersteunt geen accounts voor beperkte gebruikers"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Er is geen app gevonden om deze actie uit te voeren"</string>
+    <!-- no translation found for revoke (5404479185228271586) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 0414be8..f4fe466 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -621,6 +621,10 @@
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Pozwala aplikacji na zmienianie sposobu rozliczania wykorzystania sieci przez aplikacje. Nieprzeznaczone dla zwykłych aplikacji."</string>
     <string name="permlab_accessNotifications" msgid="7673416487873432268">"dostęp do powiadomień"</string>
     <string name="permdesc_accessNotifications" msgid="458457742683431387">"Umożliwia aplikacji pobieranie, sprawdzanie i usuwanie powiadomień, także tych, które pochodzą z innych aplikacji."</string>
+    <!-- no translation found for permlab_bindNotificationListenerService (7057764742211656654) -->
+    <skip />
+    <!-- no translation found for permdesc_bindNotificationListenerService (985697918576902986) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Określ reguły hasła"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Kontrolowanie długości haseł odblokowania ekranu i dozwolonych w nich znaków"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Monitoruj próby odblokowania ekranu"</string>
@@ -1048,8 +1052,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Działania na tekście"</string>
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Kończy się miejsce"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Niektóre funkcje systemu mogą nie działać"</string>
-    <string name="app_running_notification_title" msgid="4625479411505090209">"Aplikacja <xliff:g id="APP_NAME">%1$s</xliff:g> uruchomiona"</string>
-    <string name="app_running_notification_text" msgid="3368349329989620597">"Aplikacja <xliff:g id="APP_NAME">%1$s</xliff:g> jest uruchomiona"</string>
+    <!-- no translation found for app_running_notification_title (8718335121060787914) -->
+    <skip />
+    <!-- no translation found for app_running_notification_text (4653586947747330058) -->
+    <skip />
     <string name="ok" msgid="5970060430562524910">"OK"</string>
     <string name="cancel" msgid="6442560571259935130">"Anuluj"</string>
     <string name="yes" msgid="5362982303337969312">"OK"</string>
@@ -1267,6 +1273,8 @@
     <string name="accessibility_binding_label" msgid="4148120742096474641">"Ułatwienia dostępu"</string>
     <string name="wallpaper_binding_label" msgid="1240087844304687662">"Tapeta"</string>
     <string name="chooser_wallpaper" msgid="7873476199295190279">"Zmień tapetę"</string>
+    <!-- no translation found for notification_listener_binding_label (2014162835481906429) -->
+    <skip />
     <string name="vpn_title" msgid="19615213552042827">"VPN aktywny"</string>
     <string name="vpn_title_long" msgid="6400714798049252294">"Obsługa sieci VPN została włączona przez aplikację <xliff:g id="APP">%s</xliff:g>"</string>
     <string name="vpn_text" msgid="3011306607126450322">"Dotknij, aby zarządzać siecią."</string>
@@ -1370,6 +1378,10 @@
     <string name="action_bar_home_description" msgid="5293600496601490216">"Przejdź do strony głównej"</string>
     <string name="action_bar_up_description" msgid="2237496562952152589">"Przejdź wyżej"</string>
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"Więcej opcji"</string>
+    <!-- no translation found for action_bar_home_description_format (7965984360903693903) -->
+    <skip />
+    <!-- no translation found for action_bar_home_subtitle_description_format (6985546530471780727) -->
+    <skip />
     <string name="storage_internal" msgid="4891916833657929263">"Pamięć wewnętrzna"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"Karta SD"</string>
     <string name="storage_usb" msgid="3017954059538517278">"Nośnik USB"</string>
@@ -1479,4 +1491,6 @@
     <string name="error_message_title" msgid="4510373083082500195">"Błąd"</string>
     <string name="app_no_restricted_accounts" msgid="5322164210667258876">"Ta aplikacja nie obsługuje kont użytkowników z ograniczeniami"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Nie znaleziono aplikacji do obsługi tej akcji"</string>
+    <!-- no translation found for revoke (5404479185228271586) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 5eba00c..36751b1 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -621,6 +621,10 @@
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Permite que a aplicação modifique o modo como a utilização da rede é contabilizada em relação a aplicações. Nunca é necessário para aplicações normais."</string>
     <string name="permlab_accessNotifications" msgid="7673416487873432268">"aceder às notificações"</string>
     <string name="permdesc_accessNotifications" msgid="458457742683431387">"Permite que a aplicação obtenha, examine e limpe notificações, incluindo as que foram publicadas por outras aplicações."</string>
+    <!-- no translation found for permlab_bindNotificationListenerService (7057764742211656654) -->
+    <skip />
+    <!-- no translation found for permdesc_bindNotificationListenerService (985697918576902986) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Definir regras de palavra-passe"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Controlar o comprimento e os caracteres permitidos nas palavras-passe de desbloqueio do ecrã."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Monitorizar tentativas de desbloqueio do ecrã"</string>
@@ -1048,8 +1052,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Acções de texto"</string>
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Está quase sem espaço de armazenamento"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Algumas funções do sistema poderão não funcionar"</string>
-    <string name="app_running_notification_title" msgid="4625479411505090209">"<xliff:g id="APP_NAME">%1$s</xliff:g> em execução"</string>
-    <string name="app_running_notification_text" msgid="3368349329989620597">"<xliff:g id="APP_NAME">%1$s</xliff:g> está a ser executado"</string>
+    <!-- no translation found for app_running_notification_title (8718335121060787914) -->
+    <skip />
+    <!-- no translation found for app_running_notification_text (4653586947747330058) -->
+    <skip />
     <string name="ok" msgid="5970060430562524910">"OK"</string>
     <string name="cancel" msgid="6442560571259935130">"Cancelar"</string>
     <string name="yes" msgid="5362982303337969312">"OK"</string>
@@ -1267,6 +1273,8 @@
     <string name="accessibility_binding_label" msgid="4148120742096474641">"Acessibilidade"</string>
     <string name="wallpaper_binding_label" msgid="1240087844304687662">"Imagem de fundo"</string>
     <string name="chooser_wallpaper" msgid="7873476199295190279">"Alterar imagem de fundo"</string>
+    <!-- no translation found for notification_listener_binding_label (2014162835481906429) -->
+    <skip />
     <string name="vpn_title" msgid="19615213552042827">"VPN ativada"</string>
     <string name="vpn_title_long" msgid="6400714798049252294">"A VPN foi ativada pelo <xliff:g id="APP">%s</xliff:g>"</string>
     <string name="vpn_text" msgid="3011306607126450322">"Toque para gerir a rede."</string>
@@ -1370,6 +1378,10 @@
     <string name="action_bar_home_description" msgid="5293600496601490216">"Navegar para página inicial"</string>
     <string name="action_bar_up_description" msgid="2237496562952152589">"Navegar para cima"</string>
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"Mais opções"</string>
+    <!-- no translation found for action_bar_home_description_format (7965984360903693903) -->
+    <skip />
+    <!-- no translation found for action_bar_home_subtitle_description_format (6985546530471780727) -->
+    <skip />
     <string name="storage_internal" msgid="4891916833657929263">"memória de armazenamento interno"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"Cartão SD"</string>
     <string name="storage_usb" msgid="3017954059538517278">"Armazenamento USB"</string>
@@ -1479,4 +1491,6 @@
     <string name="error_message_title" msgid="4510373083082500195">"Erro"</string>
     <string name="app_no_restricted_accounts" msgid="5322164210667258876">"Esta aplicação não suporta contas de utilizadores limitados"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Não foram encontradas aplicações para executar esta ação"</string>
+    <!-- no translation found for revoke (5404479185228271586) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 6b0d18a..61716fe 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -621,6 +621,10 @@
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Permite que o aplicativo modifique como o uso da rede é contabilizado em relação aos aplicativos. Não deve ser usado em aplicativos normais."</string>
     <string name="permlab_accessNotifications" msgid="7673416487873432268">"acessar notificações"</string>
     <string name="permdesc_accessNotifications" msgid="458457742683431387">"Permite que o aplicativo recupere, examine e limpe notificações, inclusive as postadas por outros aplicativos."</string>
+    <!-- no translation found for permlab_bindNotificationListenerService (7057764742211656654) -->
+    <skip />
+    <!-- no translation found for permdesc_bindNotificationListenerService (985697918576902986) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Definir regras para senha"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Controle o tamanho e os caracteres permitidos nas senhas de desbloqueio de tela."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Monitorar tentativas de desbloqueio da tela"</string>
@@ -1048,8 +1052,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Ações de texto"</string>
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Pouco espaço de armazenamento"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Algumas funções do sistema podem não funcionar"</string>
-    <string name="app_running_notification_title" msgid="4625479411505090209">"<xliff:g id="APP_NAME">%1$s</xliff:g> em execução"</string>
-    <string name="app_running_notification_text" msgid="3368349329989620597">"<xliff:g id="APP_NAME">%1$s</xliff:g> está em execução"</string>
+    <!-- no translation found for app_running_notification_title (8718335121060787914) -->
+    <skip />
+    <!-- no translation found for app_running_notification_text (4653586947747330058) -->
+    <skip />
     <string name="ok" msgid="5970060430562524910">"OK"</string>
     <string name="cancel" msgid="6442560571259935130">"Cancelar"</string>
     <string name="yes" msgid="5362982303337969312">"OK"</string>
@@ -1267,6 +1273,8 @@
     <string name="accessibility_binding_label" msgid="4148120742096474641">"Acessibilidade"</string>
     <string name="wallpaper_binding_label" msgid="1240087844304687662">"Plano de fundo"</string>
     <string name="chooser_wallpaper" msgid="7873476199295190279">"Alterar plano de fundo"</string>
+    <!-- no translation found for notification_listener_binding_label (2014162835481906429) -->
+    <skip />
     <string name="vpn_title" msgid="19615213552042827">"VPN ativada"</string>
     <string name="vpn_title_long" msgid="6400714798049252294">"A VPN está ativada por <xliff:g id="APP">%s</xliff:g>"</string>
     <string name="vpn_text" msgid="3011306607126450322">"Toque para gerenciar a rede."</string>
@@ -1370,6 +1378,10 @@
     <string name="action_bar_home_description" msgid="5293600496601490216">"Navegar na página inicial"</string>
     <string name="action_bar_up_description" msgid="2237496562952152589">"Navegar para cima"</string>
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"Mais opções"</string>
+    <!-- no translation found for action_bar_home_description_format (7965984360903693903) -->
+    <skip />
+    <!-- no translation found for action_bar_home_subtitle_description_format (6985546530471780727) -->
+    <skip />
     <string name="storage_internal" msgid="4891916833657929263">"Armazenamento interno"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"Cartão SD"</string>
     <string name="storage_usb" msgid="3017954059538517278">"Armazenamento USB"</string>
@@ -1415,7 +1427,7 @@
     <string name="default_audio_route_name" product="tablet" msgid="4617053898167127471">"Tablet"</string>
     <string name="default_audio_route_name" product="default" msgid="4239291273420140123">"Telefone"</string>
     <string name="default_audio_route_name_headphones" msgid="8119971843803439110">"Fones de ouvido"</string>
-    <string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Alto-falantes do dock"</string>
+    <string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Alto-falantes da dock"</string>
     <string name="default_media_route_name_hdmi" msgid="2450970399023478055">"HDMI"</string>
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"Sistema"</string>
     <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Áudio Bluetooth"</string>
@@ -1479,4 +1491,6 @@
     <string name="error_message_title" msgid="4510373083082500195">"Erro"</string>
     <string name="app_no_restricted_accounts" msgid="5322164210667258876">"O aplicativo não suporta contas para usuários limitados"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Nenhum aplicativo encontrado para executar a ação"</string>
+    <!-- no translation found for revoke (5404479185228271586) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-rm/strings.xml b/core/res/res/values-rm/strings.xml
index 99fd59d..ba863cb 100644
--- a/core/res/res/values-rm/strings.xml
+++ b/core/res/res/values-rm/strings.xml
@@ -1040,6 +1040,10 @@
     <skip />
     <!-- no translation found for permdesc_accessNotifications (458457742683431387) -->
     <skip />
+    <!-- no translation found for permlab_bindNotificationListenerService (7057764742211656654) -->
+    <skip />
+    <!-- no translation found for permdesc_bindNotificationListenerService (985697918576902986) -->
+    <skip />
     <!-- no translation found for policylab_limitPassword (4497420728857585791) -->
     <skip />
     <!-- no translation found for policydesc_limitPassword (3252114203919510394) -->
@@ -1634,9 +1638,9 @@
     <skip />
     <!-- no translation found for low_internal_storage_view_text (6640505817617414371) -->
     <skip />
-    <!-- no translation found for app_running_notification_title (4625479411505090209) -->
+    <!-- no translation found for app_running_notification_title (8718335121060787914) -->
     <skip />
-    <!-- no translation found for app_running_notification_text (3368349329989620597) -->
+    <!-- no translation found for app_running_notification_text (4653586947747330058) -->
     <skip />
     <string name="ok" msgid="5970060430562524910">"OK"</string>
     <string name="cancel" msgid="6442560571259935130">"Interrumper"</string>
@@ -1989,6 +1993,8 @@
     <string name="accessibility_binding_label" msgid="4148120742096474641">"Agids d\'access"</string>
     <string name="wallpaper_binding_label" msgid="1240087844304687662">"Fund davos"</string>
     <string name="chooser_wallpaper" msgid="7873476199295190279">"Midar il fund davos"</string>
+    <!-- no translation found for notification_listener_binding_label (2014162835481906429) -->
+    <skip />
     <!-- no translation found for vpn_title (19615213552042827) -->
     <skip />
     <!-- no translation found for vpn_title_long (6400714798049252294) -->
@@ -2178,6 +2184,10 @@
     <skip />
     <!-- no translation found for action_menu_overflow_description (2295659037509008453) -->
     <skip />
+    <!-- no translation found for action_bar_home_description_format (7965984360903693903) -->
+    <skip />
+    <!-- no translation found for action_bar_home_subtitle_description_format (6985546530471780727) -->
+    <skip />
     <!-- no translation found for storage_internal (4891916833657929263) -->
     <skip />
     <!-- no translation found for storage_sd_card (3282948861378286745) -->
@@ -2397,4 +2407,6 @@
     <skip />
     <!-- no translation found for app_not_found (3429141853498927379) -->
     <skip />
+    <!-- no translation found for revoke (5404479185228271586) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index b11cc2f..003f932 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -621,6 +621,10 @@
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Permite aplicaţiei să modifice modul în care este calculată utilizarea reţelei pentru aplicaţii. Nu se utilizează de aplicaţiile obişnuite."</string>
     <string name="permlab_accessNotifications" msgid="7673416487873432268">"accesare notificări"</string>
     <string name="permdesc_accessNotifications" msgid="458457742683431387">"Permite aplicației să recupereze, să examineze și să șteargă notificări, inclusiv pe cele postate de alte aplicații."</string>
+    <!-- no translation found for permlab_bindNotificationListenerService (7057764742211656654) -->
+    <skip />
+    <!-- no translation found for permdesc_bindNotificationListenerService (985697918576902986) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Setaţi reguli pentru parolă"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Stabiliţi lungimea şi tipul de caractere permise în parolele pentru deblocarea ecranului."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Monitorizaţi încercările de deblocare a ecranului"</string>
@@ -1048,8 +1052,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Acţiuni pentru text"</string>
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Spaţiul de stocare aproape ocupat"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Este posibil ca unele funcţii de sistem să nu funcţioneze"</string>
-    <string name="app_running_notification_title" msgid="4625479411505090209">"<xliff:g id="APP_NAME">%1$s</xliff:g> rulează"</string>
-    <string name="app_running_notification_text" msgid="3368349329989620597">"<xliff:g id="APP_NAME">%1$s</xliff:g> rulează acum"</string>
+    <!-- no translation found for app_running_notification_title (8718335121060787914) -->
+    <skip />
+    <!-- no translation found for app_running_notification_text (4653586947747330058) -->
+    <skip />
     <string name="ok" msgid="5970060430562524910">"OK"</string>
     <string name="cancel" msgid="6442560571259935130">"Anulaţi"</string>
     <string name="yes" msgid="5362982303337969312">"OK"</string>
@@ -1267,6 +1273,8 @@
     <string name="accessibility_binding_label" msgid="4148120742096474641">"Accesibilitate"</string>
     <string name="wallpaper_binding_label" msgid="1240087844304687662">"Imagine de fundal"</string>
     <string name="chooser_wallpaper" msgid="7873476199295190279">"Modificaţi imaginea de fundal"</string>
+    <!-- no translation found for notification_listener_binding_label (2014162835481906429) -->
+    <skip />
     <string name="vpn_title" msgid="19615213552042827">"VPN activat"</string>
     <string name="vpn_title_long" msgid="6400714798049252294">"VPN este activată de <xliff:g id="APP">%s</xliff:g>"</string>
     <string name="vpn_text" msgid="3011306607126450322">"Atingeţi pentru a gestiona reţeaua."</string>
@@ -1370,6 +1378,10 @@
     <string name="action_bar_home_description" msgid="5293600496601490216">"Navigaţi la ecranul de pornire"</string>
     <string name="action_bar_up_description" msgid="2237496562952152589">"Navigaţi în sus"</string>
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"Mai multe opţiuni"</string>
+    <!-- no translation found for action_bar_home_description_format (7965984360903693903) -->
+    <skip />
+    <!-- no translation found for action_bar_home_subtitle_description_format (6985546530471780727) -->
+    <skip />
     <string name="storage_internal" msgid="4891916833657929263">"Stocare internă"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"Card SD"</string>
     <string name="storage_usb" msgid="3017954059538517278">"Dsipozitiv de stocare USB"</string>
@@ -1479,4 +1491,6 @@
     <string name="error_message_title" msgid="4510373083082500195">"Eroare"</string>
     <string name="app_no_restricted_accounts" msgid="5322164210667258876">"Această aplicație nu acceptă conturile pentru utilizatori cu permisiuni limitate"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Nicio aplicație pentru gestionarea acestei acțiuni"</string>
+    <!-- no translation found for revoke (5404479185228271586) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 3da7211..2c8dfe8 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -621,6 +621,10 @@
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Приложение сможет изменять порядок расчета использования сетевых ресурсов различными программами. Это разрешение не используется обычными приложениями."</string>
     <string name="permlab_accessNotifications" msgid="7673416487873432268">"доступ к уведомлениям"</string>
     <string name="permdesc_accessNotifications" msgid="458457742683431387">"Приложение сможет получать, проверять и удалять уведомления, включая те, что опубликованы другими приложениями."</string>
+    <!-- no translation found for permlab_bindNotificationListenerService (7057764742211656654) -->
+    <skip />
+    <!-- no translation found for permdesc_bindNotificationListenerService (985697918576902986) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Правила выбора паролей"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Контролировать длину и символы при вводе паролей для снятия блокировки экрана."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Отслеживать попытки снятия блокировки экрана"</string>
@@ -1048,8 +1052,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Операции с текстом"</string>
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Заканчивается свободное место"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Некоторые системные функции могут не работать"</string>
-    <string name="app_running_notification_title" msgid="4625479411505090209">"Приложение <xliff:g id="APP_NAME">%1$s</xliff:g> выполняется"</string>
-    <string name="app_running_notification_text" msgid="3368349329989620597">"Приложение <xliff:g id="APP_NAME">%1$s</xliff:g> выполняется в данный момент"</string>
+    <!-- no translation found for app_running_notification_title (8718335121060787914) -->
+    <skip />
+    <!-- no translation found for app_running_notification_text (4653586947747330058) -->
+    <skip />
     <string name="ok" msgid="5970060430562524910">"ОК"</string>
     <string name="cancel" msgid="6442560571259935130">"Отмена"</string>
     <string name="yes" msgid="5362982303337969312">"ОК"</string>
@@ -1267,6 +1273,8 @@
     <string name="accessibility_binding_label" msgid="4148120742096474641">"Спец. возможности"</string>
     <string name="wallpaper_binding_label" msgid="1240087844304687662">"Фоновый рисунок"</string>
     <string name="chooser_wallpaper" msgid="7873476199295190279">"Сменить обои"</string>
+    <!-- no translation found for notification_listener_binding_label (2014162835481906429) -->
+    <skip />
     <string name="vpn_title" msgid="19615213552042827">"Сеть VPN активна"</string>
     <string name="vpn_title_long" msgid="6400714798049252294">"Сеть VPN активирована приложением <xliff:g id="APP">%s</xliff:g>"</string>
     <string name="vpn_text" msgid="3011306607126450322">"Нажмите, чтобы открыть настройки."</string>
@@ -1370,6 +1378,10 @@
     <string name="action_bar_home_description" msgid="5293600496601490216">"Перейти на главную"</string>
     <string name="action_bar_up_description" msgid="2237496562952152589">"Перейти вверх"</string>
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"Ещё"</string>
+    <!-- no translation found for action_bar_home_description_format (7965984360903693903) -->
+    <skip />
+    <!-- no translation found for action_bar_home_subtitle_description_format (6985546530471780727) -->
+    <skip />
     <string name="storage_internal" msgid="4891916833657929263">"Внутренняя память"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"SD-карта"</string>
     <string name="storage_usb" msgid="3017954059538517278">"USB-накопитель"</string>
@@ -1479,4 +1491,6 @@
     <string name="error_message_title" msgid="4510373083082500195">"Ошибка"</string>
     <string name="app_no_restricted_accounts" msgid="5322164210667258876">"Приложение не поддерживает аккаунты с ограниченным доступом"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Невозможно обработать это действие"</string>
+    <!-- no translation found for revoke (5404479185228271586) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 9ffe30d..80a2c31 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -621,6 +621,10 @@
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Umožňuje aplikácii upraviť používanie siete jednotlivými aplikáciami. Bežné aplikácie toto nastavenie nepoužívajú."</string>
     <string name="permlab_accessNotifications" msgid="7673416487873432268">"prístup k upozorneniam"</string>
     <string name="permdesc_accessNotifications" msgid="458457742683431387">"Umožňuje aplikácii načítať, zobrazovať a mazať upozornenia vrátane tých, ktoré boli uverejnené inými aplikáciami."</string>
+    <!-- no translation found for permlab_bindNotificationListenerService (7057764742211656654) -->
+    <skip />
+    <!-- no translation found for permdesc_bindNotificationListenerService (985697918576902986) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Nastaviť pravidlá pre heslo"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Ovládanie dĺžky hesiel na odomknutie obrazovky a v nich používané znaky."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Sledovať pokusy o odomknutie obrazovky"</string>
@@ -1048,8 +1052,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Operácie s textom"</string>
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Nedostatok ukladacieho priestoru"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Niektoré systémové funkcie nemusia fungovať"</string>
-    <string name="app_running_notification_title" msgid="4625479411505090209">"Aplikácia <xliff:g id="APP_NAME">%1$s</xliff:g> je spustená"</string>
-    <string name="app_running_notification_text" msgid="3368349329989620597">"Aplikácia <xliff:g id="APP_NAME">%1$s</xliff:g> je práve spustená"</string>
+    <!-- no translation found for app_running_notification_title (8718335121060787914) -->
+    <skip />
+    <!-- no translation found for app_running_notification_text (4653586947747330058) -->
+    <skip />
     <string name="ok" msgid="5970060430562524910">"OK"</string>
     <string name="cancel" msgid="6442560571259935130">"Zrušiť"</string>
     <string name="yes" msgid="5362982303337969312">"OK"</string>
@@ -1267,6 +1273,8 @@
     <string name="accessibility_binding_label" msgid="4148120742096474641">"Zjednodušenie"</string>
     <string name="wallpaper_binding_label" msgid="1240087844304687662">"Tapeta"</string>
     <string name="chooser_wallpaper" msgid="7873476199295190279">"Zmeniť tapetu"</string>
+    <!-- no translation found for notification_listener_binding_label (2014162835481906429) -->
+    <skip />
     <string name="vpn_title" msgid="19615213552042827">"Sieť VPN je aktivovaná"</string>
     <string name="vpn_title_long" msgid="6400714798049252294">"Aplikáciu <xliff:g id="APP">%s</xliff:g> aktivovala sieť VPN"</string>
     <string name="vpn_text" msgid="3011306607126450322">"Dotykom môžete spravovať sieť."</string>
@@ -1370,6 +1378,10 @@
     <string name="action_bar_home_description" msgid="5293600496601490216">"Prejsť na plochu"</string>
     <string name="action_bar_up_description" msgid="2237496562952152589">"Prejsť na"</string>
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"Viac možností"</string>
+    <!-- no translation found for action_bar_home_description_format (7965984360903693903) -->
+    <skip />
+    <!-- no translation found for action_bar_home_subtitle_description_format (6985546530471780727) -->
+    <skip />
     <string name="storage_internal" msgid="4891916833657929263">"Interné úložisko"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"Karta SD"</string>
     <string name="storage_usb" msgid="3017954059538517278">"Ukladací priestor USB"</string>
@@ -1479,4 +1491,6 @@
     <string name="error_message_title" msgid="4510373083082500195">"Chyba"</string>
     <string name="app_no_restricted_accounts" msgid="5322164210667258876">"Táto aplikácia nepodporuje účty v prípade používateľov s obmedzením"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Aplikácia potrebná na spracovanie tejto akcie sa nenašla"</string>
+    <!-- no translation found for revoke (5404479185228271586) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index ac1b6ad..766b605 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -621,6 +621,10 @@
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Programu omogoča, da spremeni uporabo omrežja na podlagi programov. Ni za uporabo z navadnimi programi."</string>
     <string name="permlab_accessNotifications" msgid="7673416487873432268">"dostop do obvestil"</string>
     <string name="permdesc_accessNotifications" msgid="458457742683431387">"Dovoli aplikaciji, da prenese, razišče in izbriše obvestila, tudi tista, ki so jih objavile druge aplikacije."</string>
+    <!-- no translation found for permlab_bindNotificationListenerService (7057764742211656654) -->
+    <skip />
+    <!-- no translation found for permdesc_bindNotificationListenerService (985697918576902986) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Nastavitev pravil za geslo"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Nadzor nad dolžino in znaki, ki so dovoljeni v geslih za odklepanje zaslona."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"nadzor nad poskusi odklepanja zaslona"</string>
@@ -1048,8 +1052,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Besedilna dejanja"</string>
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Prostor za shranjevanje bo pošel"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Nekatere sistemske funkcije morda ne delujejo"</string>
-    <string name="app_running_notification_title" msgid="4625479411505090209">"Izvaja se aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <string name="app_running_notification_text" msgid="3368349329989620597">"Trenutno se izvaja aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+    <!-- no translation found for app_running_notification_title (8718335121060787914) -->
+    <skip />
+    <!-- no translation found for app_running_notification_text (4653586947747330058) -->
+    <skip />
     <string name="ok" msgid="5970060430562524910">"V redu"</string>
     <string name="cancel" msgid="6442560571259935130">"Prekliči"</string>
     <string name="yes" msgid="5362982303337969312">"V redu"</string>
@@ -1267,6 +1273,8 @@
     <string name="accessibility_binding_label" msgid="4148120742096474641">"Pripomočki za osebe s posebnimi potrebami"</string>
     <string name="wallpaper_binding_label" msgid="1240087844304687662">"Ozadje"</string>
     <string name="chooser_wallpaper" msgid="7873476199295190279">"Spreminjanje ozadja"</string>
+    <!-- no translation found for notification_listener_binding_label (2014162835481906429) -->
+    <skip />
     <string name="vpn_title" msgid="19615213552042827">"VPN aktiviran"</string>
     <string name="vpn_title_long" msgid="6400714798049252294">"VPN je aktiviral program <xliff:g id="APP">%s</xliff:g>"</string>
     <string name="vpn_text" msgid="3011306607126450322">"Dotaknite se, če želite upravljati omrežje."</string>
@@ -1370,6 +1378,10 @@
     <string name="action_bar_home_description" msgid="5293600496601490216">"Krmarjenje domov"</string>
     <string name="action_bar_up_description" msgid="2237496562952152589">"Krmarjenje navzgor"</string>
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"Več možnosti"</string>
+    <!-- no translation found for action_bar_home_description_format (7965984360903693903) -->
+    <skip />
+    <!-- no translation found for action_bar_home_subtitle_description_format (6985546530471780727) -->
+    <skip />
     <string name="storage_internal" msgid="4891916833657929263">"Notranji pomnilnik"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"Kartica SD"</string>
     <string name="storage_usb" msgid="3017954059538517278">"Pomnilnik USB"</string>
@@ -1479,4 +1491,6 @@
     <string name="error_message_title" msgid="4510373083082500195">"Napaka"</string>
     <string name="app_no_restricted_accounts" msgid="5322164210667258876">"Ta aplikacija ne podpira računov za uporabnike z omejitvami"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Najdena ni bila nobena aplikacija za izvedbo tega dejanja"</string>
+    <!-- no translation found for revoke (5404479185228271586) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 7e8cf01..15b9ec5 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -621,6 +621,10 @@
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Дозвољава апликацији да измени начин на који апликације користе мрежу. Не користе је уобичајене апликације."</string>
     <string name="permlab_accessNotifications" msgid="7673416487873432268">"приступ обавештењима"</string>
     <string name="permdesc_accessNotifications" msgid="458457742683431387">"Дозвољава апликацији да преузима, испитује и брише обавештења, укључујући она која постављају друге апликације."</string>
+    <!-- no translation found for permlab_bindNotificationListenerService (7057764742211656654) -->
+    <skip />
+    <!-- no translation found for permdesc_bindNotificationListenerService (985697918576902986) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Подешавање правила за лозинку"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Контролишите дужину и знакове дозвољене у лозинкама за откључавање екрана."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Надгледање покушаја откључавања екрана"</string>
@@ -1048,8 +1052,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Радње у вези са текстом"</string>
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Простор за складиштење је на измаку"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Неке системске функције можда не функционишу"</string>
-    <string name="app_running_notification_title" msgid="4625479411505090209">"<xliff:g id="APP_NAME">%1$s</xliff:g> је покренута"</string>
-    <string name="app_running_notification_text" msgid="3368349329989620597">"<xliff:g id="APP_NAME">%1$s</xliff:g> је тренутно покренута"</string>
+    <!-- no translation found for app_running_notification_title (8718335121060787914) -->
+    <skip />
+    <!-- no translation found for app_running_notification_text (4653586947747330058) -->
+    <skip />
     <string name="ok" msgid="5970060430562524910">"Потврди"</string>
     <string name="cancel" msgid="6442560571259935130">"Откажи"</string>
     <string name="yes" msgid="5362982303337969312">"Потврди"</string>
@@ -1267,6 +1273,8 @@
     <string name="accessibility_binding_label" msgid="4148120742096474641">"Приступачност"</string>
     <string name="wallpaper_binding_label" msgid="1240087844304687662">"Позадина"</string>
     <string name="chooser_wallpaper" msgid="7873476199295190279">"Промена позадине"</string>
+    <!-- no translation found for notification_listener_binding_label (2014162835481906429) -->
+    <skip />
     <string name="vpn_title" msgid="19615213552042827">"VPN је активиран"</string>
     <string name="vpn_title_long" msgid="6400714798049252294">"Апликација <xliff:g id="APP">%s</xliff:g> је активирала VPN"</string>
     <string name="vpn_text" msgid="3011306607126450322">"Додирните да бисте управљали мрежом."</string>
@@ -1370,6 +1378,10 @@
     <string name="action_bar_home_description" msgid="5293600496601490216">"Кретање до Почетне"</string>
     <string name="action_bar_up_description" msgid="2237496562952152589">"Кретање нагоре"</string>
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"Још опција"</string>
+    <!-- no translation found for action_bar_home_description_format (7965984360903693903) -->
+    <skip />
+    <!-- no translation found for action_bar_home_subtitle_description_format (6985546530471780727) -->
+    <skip />
     <string name="storage_internal" msgid="4891916833657929263">"Интерна меморија"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"SD картица"</string>
     <string name="storage_usb" msgid="3017954059538517278">"USB меморија"</string>
@@ -1479,4 +1491,6 @@
     <string name="error_message_title" msgid="4510373083082500195">"Грешка"</string>
     <string name="app_no_restricted_accounts" msgid="5322164210667258876">"Ова апликација не подржава налоге за кориснике са ограничењем"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Није пронађена ниједна апликација која би могла да обави ову радњу"</string>
+    <!-- no translation found for revoke (5404479185228271586) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 5a54f71..291681c 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -621,6 +621,10 @@
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Tillåter att appen ändrar hur nätverksanvändning redovisas för appar. Används inte av vanliga appar."</string>
     <string name="permlab_accessNotifications" msgid="7673416487873432268">"få åtkomst till meddelanden"</string>
     <string name="permdesc_accessNotifications" msgid="458457742683431387">"Tillåter att appen hämtar, granskar och raderar meddelanden, även sådana som skickats av andra appar."</string>
+    <!-- no translation found for permlab_bindNotificationListenerService (7057764742211656654) -->
+    <skip />
+    <!-- no translation found for permdesc_bindNotificationListenerService (985697918576902986) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Ange lösenordsregler"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Bestäm hur många och vilka tecken som är tillåtna i skärmlåsets lösenord."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Övervaka försök att låsa upp skärmen"</string>
@@ -1048,8 +1052,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Textåtgärder"</string>
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Lagringsutrymmet börjar ta slut"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Det kan hända att vissa systemfunktioner inte fungerar"</string>
-    <string name="app_running_notification_title" msgid="4625479411505090209">"<xliff:g id="APP_NAME">%1$s</xliff:g> körs"</string>
-    <string name="app_running_notification_text" msgid="3368349329989620597">"<xliff:g id="APP_NAME">%1$s</xliff:g> körs"</string>
+    <!-- no translation found for app_running_notification_title (8718335121060787914) -->
+    <skip />
+    <!-- no translation found for app_running_notification_text (4653586947747330058) -->
+    <skip />
     <string name="ok" msgid="5970060430562524910">"OK"</string>
     <string name="cancel" msgid="6442560571259935130">"Avbryt"</string>
     <string name="yes" msgid="5362982303337969312">"OK"</string>
@@ -1267,6 +1273,8 @@
     <string name="accessibility_binding_label" msgid="4148120742096474641">"Tillgänglighet"</string>
     <string name="wallpaper_binding_label" msgid="1240087844304687662">"Bakgrund"</string>
     <string name="chooser_wallpaper" msgid="7873476199295190279">"Ändra bakgrund"</string>
+    <!-- no translation found for notification_listener_binding_label (2014162835481906429) -->
+    <skip />
     <string name="vpn_title" msgid="19615213552042827">"VPN är aktiverat"</string>
     <string name="vpn_title_long" msgid="6400714798049252294">"VPN aktiveras av <xliff:g id="APP">%s</xliff:g>"</string>
     <string name="vpn_text" msgid="3011306607126450322">"Tryck om du vill hantera nätverket."</string>
@@ -1370,6 +1378,10 @@
     <string name="action_bar_home_description" msgid="5293600496601490216">"Visa startsidan"</string>
     <string name="action_bar_up_description" msgid="2237496562952152589">"Navigera uppåt"</string>
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"Fler alternativ"</string>
+    <!-- no translation found for action_bar_home_description_format (7965984360903693903) -->
+    <skip />
+    <!-- no translation found for action_bar_home_subtitle_description_format (6985546530471780727) -->
+    <skip />
     <string name="storage_internal" msgid="4891916833657929263">"Internminne"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"SD-kort"</string>
     <string name="storage_usb" msgid="3017954059538517278">"USB-lagring"</string>
@@ -1479,4 +1491,6 @@
     <string name="error_message_title" msgid="4510373083082500195">"Fel"</string>
     <string name="app_no_restricted_accounts" msgid="5322164210667258876">"Appen har inte stöd för användarkonton med begränsningar"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Ingen app som kan hantera åtgärden hittades"</string>
+    <!-- no translation found for revoke (5404479185228271586) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 67b4608..c8f1343 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -621,6 +621,10 @@
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Huruhusu programu kurekebisha jinsi matumizi ya mtandao yana hesabika dhidi ya programu. Sio ya matumizi na programu za kawaida."</string>
     <string name="permlab_accessNotifications" msgid="7673416487873432268">"fikia arifa"</string>
     <string name="permdesc_accessNotifications" msgid="458457742683431387">"Huruhusu programu kurejesha, kuchunguza, na kuondoa arifa, ikiwa ni pamoja na zile zilizochapishwa na programu nyingine."</string>
+    <!-- no translation found for permlab_bindNotificationListenerService (7057764742211656654) -->
+    <skip />
+    <!-- no translation found for permdesc_bindNotificationListenerService (985697918576902986) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Weka kanuni za nenosiri"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Dhibiti urefu na vibambo vinavyoruhusiwa katika manenosiri ya kufungua skrini."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Chunguza majaribio ya kutofun gua skrini"</string>
@@ -1048,8 +1052,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Vitendo vya maandishi"</string>
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Nafasi ya kuhafadhi inakwisha"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Baadhi ya vipengee vya mfumo huenda visifanye kazi"</string>
-    <string name="app_running_notification_title" msgid="4625479411505090209">"<xliff:g id="APP_NAME">%1$s</xliff:g> inaendeshwa"</string>
-    <string name="app_running_notification_text" msgid="3368349329989620597">"<xliff:g id="APP_NAME">%1$s</xliff:g> inaendeshwa kwa sasa"</string>
+    <!-- no translation found for app_running_notification_title (8718335121060787914) -->
+    <skip />
+    <!-- no translation found for app_running_notification_text (4653586947747330058) -->
+    <skip />
     <string name="ok" msgid="5970060430562524910">"Sawa"</string>
     <string name="cancel" msgid="6442560571259935130">"Ghairi"</string>
     <string name="yes" msgid="5362982303337969312">"Sawa"</string>
@@ -1267,6 +1273,8 @@
     <string name="accessibility_binding_label" msgid="4148120742096474641">"Ufikiaji"</string>
     <string name="wallpaper_binding_label" msgid="1240087844304687662">"Mandhari"</string>
     <string name="chooser_wallpaper" msgid="7873476199295190279">"Badilisha mandhari"</string>
+    <!-- no translation found for notification_listener_binding_label (2014162835481906429) -->
+    <skip />
     <string name="vpn_title" msgid="19615213552042827">"VPN imewezeshwa"</string>
     <string name="vpn_title_long" msgid="6400714798049252294">"VPN imeamilishwa na <xliff:g id="APP">%s</xliff:g>"</string>
     <string name="vpn_text" msgid="3011306607126450322">"Gusa ili kudhibiti mtandao."</string>
@@ -1370,6 +1378,10 @@
     <string name="action_bar_home_description" msgid="5293600496601490216">"Abiri nyumbani"</string>
     <string name="action_bar_up_description" msgid="2237496562952152589">"Ongoza"</string>
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"Chaguo zaidi"</string>
+    <!-- no translation found for action_bar_home_description_format (7965984360903693903) -->
+    <skip />
+    <!-- no translation found for action_bar_home_subtitle_description_format (6985546530471780727) -->
+    <skip />
     <string name="storage_internal" msgid="4891916833657929263">"Hifadhi ya mfumo"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"Kadi ya SD"</string>
     <string name="storage_usb" msgid="3017954059538517278">"Hifadhi ya USB"</string>
@@ -1479,4 +1491,6 @@
     <string name="error_message_title" msgid="4510373083082500195">"Hitilafu"</string>
     <string name="app_no_restricted_accounts" msgid="5322164210667258876">"Programu hii haiwezi kutumiwa na akaunti za watumiaji waliowekewa vizuizi"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Hakuna programu iliyopatikana ili kushughulikia kitendo hiki"</string>
+    <!-- no translation found for revoke (5404479185228271586) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 2d56e38..66b3199 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -621,6 +621,10 @@
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"อนุญาตให้แอปพลิเคชันแก้ไขวิธีการบันทึกบัญชีการใช้งานเครือข่ายของแอปพลิเคชัน ไม่ใช้สำหรับแอปพลิเคชันทั่วไป"</string>
     <string name="permlab_accessNotifications" msgid="7673416487873432268">"เข้าถึงการแจ้งเตือน"</string>
     <string name="permdesc_accessNotifications" msgid="458457742683431387">"ทำให้แอปสามารถเรียกดู ตรวจสอบ และล้างการแจ้งเตือนได้ ซึ่งรวมถึงการแจ้งเตือนที่โพสต์โดยแอปอื่นๆ ด้วย"</string>
+    <!-- no translation found for permlab_bindNotificationListenerService (7057764742211656654) -->
+    <skip />
+    <!-- no translation found for permdesc_bindNotificationListenerService (985697918576902986) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"ตั้งค่ากฎรหัสผ่าน"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"ควบคุมความยาวและอักขระที่อนุญาตให้ใช้ในรหัสผ่านการปลดล็อกหน้าจอ"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"ตรวจสอบความพยายามในการปลดล็อกหน้าจอ"</string>
@@ -1048,8 +1052,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"การทำงานของข้อความ"</string>
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"พื้นที่จัดเก็บเหลือน้อย"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"บางฟังก์ชันระบบอาจไม่ทำงาน"</string>
-    <string name="app_running_notification_title" msgid="4625479411505090209">"<xliff:g id="APP_NAME">%1$s</xliff:g> กำลังทำงาน"</string>
-    <string name="app_running_notification_text" msgid="3368349329989620597">"<xliff:g id="APP_NAME">%1$s</xliff:g> กำลังทำงานในขณะนี้"</string>
+    <!-- no translation found for app_running_notification_title (8718335121060787914) -->
+    <skip />
+    <!-- no translation found for app_running_notification_text (4653586947747330058) -->
+    <skip />
     <string name="ok" msgid="5970060430562524910">"ตกลง"</string>
     <string name="cancel" msgid="6442560571259935130">"ยกเลิก"</string>
     <string name="yes" msgid="5362982303337969312">"ตกลง"</string>
@@ -1267,6 +1273,8 @@
     <string name="accessibility_binding_label" msgid="4148120742096474641">"การเข้าถึง"</string>
     <string name="wallpaper_binding_label" msgid="1240087844304687662">"วอลเปเปอร์"</string>
     <string name="chooser_wallpaper" msgid="7873476199295190279">"เปลี่ยนวอลเปเปอร์"</string>
+    <!-- no translation found for notification_listener_binding_label (2014162835481906429) -->
+    <skip />
     <string name="vpn_title" msgid="19615213552042827">"VPN เปิดใช้งานแล้ว"</string>
     <string name="vpn_title_long" msgid="6400714798049252294">"เปิดใช้งาน VPN โดย <xliff:g id="APP">%s</xliff:g>"</string>
     <string name="vpn_text" msgid="3011306607126450322">"แตะเพื่อจัดการเครือข่าย"</string>
@@ -1370,6 +1378,10 @@
     <string name="action_bar_home_description" msgid="5293600496601490216">"นำทางไปหน้าแรก"</string>
     <string name="action_bar_up_description" msgid="2237496562952152589">"นำทางขึ้น"</string>
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"ตัวเลือกเพิ่มเติม"</string>
+    <!-- no translation found for action_bar_home_description_format (7965984360903693903) -->
+    <skip />
+    <!-- no translation found for action_bar_home_subtitle_description_format (6985546530471780727) -->
+    <skip />
     <string name="storage_internal" msgid="4891916833657929263">"ที่จัดเก็บข้อมูลภายใน"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"การ์ด SD"</string>
     <string name="storage_usb" msgid="3017954059538517278">"ที่เก็บข้อมูล USB"</string>
@@ -1477,6 +1489,8 @@
     <string name="user_switched" msgid="3768006783166984410">"ผู้ใช้ปัจจุบัน <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="owner_name" msgid="2716755460376028154">"เจ้าของ"</string>
     <string name="error_message_title" msgid="4510373083082500195">"ข้อผิดพลาด"</string>
-    <string name="app_no_restricted_accounts" msgid="5322164210667258876">"แอปพลิเคชันนี้ไม่สนับสนุนบัญชีของผู้ใช้บางรายที่ถูกจำกัด"</string>
+    <string name="app_no_restricted_accounts" msgid="5322164210667258876">"แอปพลิเคชันนี้ไม่สนับสนุนบัญชีผู้ใช้ที่ถูกจำกัด"</string>
     <string name="app_not_found" msgid="3429141853498927379">"ไม่พบแอปพลิเคชันสำหรับการทำงานนี้"</string>
+    <!-- no translation found for revoke (5404479185228271586) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index beeb6c0..bd5f99d 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -621,6 +621,10 @@
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Pinapayagan ang app na baguhin kung paano isinasaalang-alang ang paggamit ng network laban sa apps. Hindi para sa paggamit ng normal na apps."</string>
     <string name="permlab_accessNotifications" msgid="7673416487873432268">"i-access ang mga notification"</string>
     <string name="permdesc_accessNotifications" msgid="458457742683431387">"Pinapayagan ang app na kumuha, sumuri, at mag-clear ng mga notification, kabilang ang mga na-post ng iba pang apps."</string>
+    <!-- no translation found for permlab_bindNotificationListenerService (7057764742211656654) -->
+    <skip />
+    <!-- no translation found for permdesc_bindNotificationListenerService (985697918576902986) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Magtakda ng mga panuntunan sa password"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Kontrolin ang haba at mga character na pinapayagan sa mga password sa pag-unlock ng screen."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Subaybayan ang mga pagsubok sa pag-unlock ng screen"</string>
@@ -1048,8 +1052,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Pagkilos ng teksto"</string>
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Nauubusan na ang puwang ng storage"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Maaaring hindi gumana nang tama ang ilang paggana ng system"</string>
-    <string name="app_running_notification_title" msgid="4625479411505090209">"Tumatakbo ang <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <string name="app_running_notification_text" msgid="3368349329989620597">"Kasalukuyang tumatakbo ang <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+    <!-- no translation found for app_running_notification_title (8718335121060787914) -->
+    <skip />
+    <!-- no translation found for app_running_notification_text (4653586947747330058) -->
+    <skip />
     <string name="ok" msgid="5970060430562524910">"OK"</string>
     <string name="cancel" msgid="6442560571259935130">"Kanselahin"</string>
     <string name="yes" msgid="5362982303337969312">"OK"</string>
@@ -1267,6 +1273,8 @@
     <string name="accessibility_binding_label" msgid="4148120742096474641">"Kakayahang Ma-access"</string>
     <string name="wallpaper_binding_label" msgid="1240087844304687662">"Wallpaper"</string>
     <string name="chooser_wallpaper" msgid="7873476199295190279">"Baguhin ang wallpaper"</string>
+    <!-- no translation found for notification_listener_binding_label (2014162835481906429) -->
+    <skip />
     <string name="vpn_title" msgid="19615213552042827">"Naka-activate ang VPN"</string>
     <string name="vpn_title_long" msgid="6400714798049252294">"Isinaaktibo ang VPN ng <xliff:g id="APP">%s</xliff:g>"</string>
     <string name="vpn_text" msgid="3011306607126450322">"Pindutin upang pamahalaan ang network."</string>
@@ -1370,6 +1378,10 @@
     <string name="action_bar_home_description" msgid="5293600496601490216">"Magnabiga sa home"</string>
     <string name="action_bar_up_description" msgid="2237496562952152589">"Magnabiga pataas"</string>
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"Higit pang mga pagpipilian"</string>
+    <!-- no translation found for action_bar_home_description_format (7965984360903693903) -->
+    <skip />
+    <!-- no translation found for action_bar_home_subtitle_description_format (6985546530471780727) -->
+    <skip />
     <string name="storage_internal" msgid="4891916833657929263">"Panloob na storage"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"SD card"</string>
     <string name="storage_usb" msgid="3017954059538517278">"USB storage"</string>
@@ -1479,4 +1491,6 @@
     <string name="error_message_title" msgid="4510373083082500195">"Error"</string>
     <string name="app_no_restricted_accounts" msgid="5322164210667258876">"Hindi sinusuportahan ng application na ito ang mga account para sa mga limitadong user"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Walang nakitang application na mangangasiwa sa pagkilos na ito"</string>
+    <!-- no translation found for revoke (5404479185228271586) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index c8d3ae4..79c3706 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -621,6 +621,10 @@
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Uygulamaya, ağın uygulamalara göre nasıl kullanılacağını değiştirme izni verir. Normal uygulamalar tarafından kullanılmak için değildir."</string>
     <string name="permlab_accessNotifications" msgid="7673416487873432268">"bildirimlere eriş"</string>
     <string name="permdesc_accessNotifications" msgid="458457742683431387">"Uygulamanın bildirimler almasına, bildirimleri incelemesine ve temizlemesine izin verir. Buna diğer uygulamalar tarafından yayınlanan bildirimler de dahildir."</string>
+    <!-- no translation found for permlab_bindNotificationListenerService (7057764742211656654) -->
+    <skip />
+    <!-- no translation found for permdesc_bindNotificationListenerService (985697918576902986) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Şifre kuralları ayarla"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Ekran kilidini açma şifrelerinde izin verilen uzunluğu ve karakterleri denetleme."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Ekran kilidini açma denemelerini izle"</string>
@@ -1048,8 +1052,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Metin eylemleri"</string>
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Depolama alanı bitiyor"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Bazı sistem işlevleri çalışmayabilir"</string>
-    <string name="app_running_notification_title" msgid="4625479411505090209">"<xliff:g id="APP_NAME">%1$s</xliff:g> çalışıyor"</string>
-    <string name="app_running_notification_text" msgid="3368349329989620597">"<xliff:g id="APP_NAME">%1$s</xliff:g> şu anda çalışıyor"</string>
+    <!-- no translation found for app_running_notification_title (8718335121060787914) -->
+    <skip />
+    <!-- no translation found for app_running_notification_text (4653586947747330058) -->
+    <skip />
     <string name="ok" msgid="5970060430562524910">"Tamam"</string>
     <string name="cancel" msgid="6442560571259935130">"İptal"</string>
     <string name="yes" msgid="5362982303337969312">"Tamam"</string>
@@ -1267,6 +1273,8 @@
     <string name="accessibility_binding_label" msgid="4148120742096474641">"Erişebilirlik"</string>
     <string name="wallpaper_binding_label" msgid="1240087844304687662">"Duvar Kağıdı"</string>
     <string name="chooser_wallpaper" msgid="7873476199295190279">"Duvar kağıdını değiştir"</string>
+    <!-- no translation found for notification_listener_binding_label (2014162835481906429) -->
+    <skip />
     <string name="vpn_title" msgid="19615213552042827">"VPN etkinleştirildi"</string>
     <string name="vpn_title_long" msgid="6400714798049252294">"VPN, <xliff:g id="APP">%s</xliff:g> tarafından etkinleştirildi"</string>
     <string name="vpn_text" msgid="3011306607126450322">"Ağı yönetmek için dokunun."</string>
@@ -1370,6 +1378,10 @@
     <string name="action_bar_home_description" msgid="5293600496601490216">"Ana sayfaya git"</string>
     <string name="action_bar_up_description" msgid="2237496562952152589">"Yukarı git"</string>
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"Diğer seçenekler"</string>
+    <!-- no translation found for action_bar_home_description_format (7965984360903693903) -->
+    <skip />
+    <!-- no translation found for action_bar_home_subtitle_description_format (6985546530471780727) -->
+    <skip />
     <string name="storage_internal" msgid="4891916833657929263">"Dahili depolama birimi"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"SD kart"</string>
     <string name="storage_usb" msgid="3017954059538517278">"USB bellek"</string>
@@ -1479,4 +1491,6 @@
     <string name="error_message_title" msgid="4510373083082500195">"Hata"</string>
     <string name="app_no_restricted_accounts" msgid="5322164210667258876">"Bu uygulama, kısıtlı kullanıcı hesaplarını desteklemiyor"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Bu eylemi gerçekleştirecek bir uygulama bulunamadı"</string>
+    <!-- no translation found for revoke (5404479185228271586) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 6f505b1..ad206d3 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -621,6 +621,10 @@
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Дозволяє програмі змінювати метод підрахунку того, як програми використовують мережу. Не для використання звичайними програмами."</string>
     <string name="permlab_accessNotifications" msgid="7673416487873432268">"отримувати доступ до сповіщень"</string>
     <string name="permdesc_accessNotifications" msgid="458457742683431387">"Дозволяє програмі отримувати, перевіряти й очищати сповіщення, зокрема опубліковані іншими програмами."</string>
+    <!-- no translation found for permlab_bindNotificationListenerService (7057764742211656654) -->
+    <skip />
+    <!-- no translation found for permdesc_bindNotificationListenerService (985697918576902986) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Устан. правила пароля"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Контролювати довжину паролів для розблокування екрана та дозволені в них символи."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Відстежув. спроби розблок. екрана"</string>
@@ -1048,8 +1052,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Дії з текстом"</string>
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Закінчується пам’ять"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Деякі системні функції можуть не працювати"</string>
-    <string name="app_running_notification_title" msgid="4625479411505090209">"<xliff:g id="APP_NAME">%1$s</xliff:g> працює"</string>
-    <string name="app_running_notification_text" msgid="3368349329989620597">"<xliff:g id="APP_NAME">%1$s</xliff:g> зараз працює"</string>
+    <!-- no translation found for app_running_notification_title (8718335121060787914) -->
+    <skip />
+    <!-- no translation found for app_running_notification_text (4653586947747330058) -->
+    <skip />
     <string name="ok" msgid="5970060430562524910">"OK"</string>
     <string name="cancel" msgid="6442560571259935130">"Скасувати"</string>
     <string name="yes" msgid="5362982303337969312">"OK"</string>
@@ -1267,6 +1273,8 @@
     <string name="accessibility_binding_label" msgid="4148120742096474641">"Доступність"</string>
     <string name="wallpaper_binding_label" msgid="1240087844304687662">"Фоновий мал."</string>
     <string name="chooser_wallpaper" msgid="7873476199295190279">"Змінити фоновий малюнок"</string>
+    <!-- no translation found for notification_listener_binding_label (2014162835481906429) -->
+    <skip />
     <string name="vpn_title" msgid="19615213552042827">"Мережу VPN активовано"</string>
     <string name="vpn_title_long" msgid="6400714798049252294">"Мережу VPN активовано програмою <xliff:g id="APP">%s</xliff:g>"</string>
     <string name="vpn_text" msgid="3011306607126450322">"Торкніться, щоб керувати мережею."</string>
@@ -1370,6 +1378,10 @@
     <string name="action_bar_home_description" msgid="5293600496601490216">"Перейти на головну"</string>
     <string name="action_bar_up_description" msgid="2237496562952152589">"Перейти вгору"</string>
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"Інші варіанти"</string>
+    <!-- no translation found for action_bar_home_description_format (7965984360903693903) -->
+    <skip />
+    <!-- no translation found for action_bar_home_subtitle_description_format (6985546530471780727) -->
+    <skip />
     <string name="storage_internal" msgid="4891916833657929263">"Внутрішня пам’ять"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"Карта SD"</string>
     <string name="storage_usb" msgid="3017954059538517278">"Носій USB"</string>
@@ -1479,4 +1491,6 @@
     <string name="error_message_title" msgid="4510373083082500195">"Помилка"</string>
     <string name="app_no_restricted_accounts" msgid="5322164210667258876">"Ця програма не підтримує облікові записи для обмежених користувачів"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Не знайдено програму для обробки цієї дії"</string>
+    <!-- no translation found for revoke (5404479185228271586) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 4fe8d65..4022f04 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -621,6 +621,10 @@
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Cho phép ứng dụng sửa đổi cách tính mức sử dụng mạng so với ứng dụng. Không dành cho các ứng dụng thông thường."</string>
     <string name="permlab_accessNotifications" msgid="7673416487873432268">"truy cập thông báo"</string>
     <string name="permdesc_accessNotifications" msgid="458457742683431387">"Cho phép ứng dụng truy xuất, kiểm tra và xóa thông báo, bao gồm những thông báo được đăng bởi các ứng dụng khác."</string>
+    <!-- no translation found for permlab_bindNotificationListenerService (7057764742211656654) -->
+    <skip />
+    <!-- no translation found for permdesc_bindNotificationListenerService (985697918576902986) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Đặt quy tắc mật khẩu"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Kiểm soát độ dài và ký tự được phép trong mật khẩu mở khóa màn hình."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Giám sát những lần thử mở khóa màn hình"</string>
@@ -1048,8 +1052,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Tác vụ văn bản"</string>
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Sắp hết dung lượng lưu trữ"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Một số chức năng hệ thống có thể không hoạt động"</string>
-    <string name="app_running_notification_title" msgid="4625479411505090209">"<xliff:g id="APP_NAME">%1$s</xliff:g> đang chạy"</string>
-    <string name="app_running_notification_text" msgid="3368349329989620597">"<xliff:g id="APP_NAME">%1$s</xliff:g> hiện đang chạy"</string>
+    <!-- no translation found for app_running_notification_title (8718335121060787914) -->
+    <skip />
+    <!-- no translation found for app_running_notification_text (4653586947747330058) -->
+    <skip />
     <string name="ok" msgid="5970060430562524910">"OK"</string>
     <string name="cancel" msgid="6442560571259935130">"Hủy"</string>
     <string name="yes" msgid="5362982303337969312">"OK"</string>
@@ -1267,6 +1273,8 @@
     <string name="accessibility_binding_label" msgid="4148120742096474641">"Khả năng truy cập"</string>
     <string name="wallpaper_binding_label" msgid="1240087844304687662">"Hình nền"</string>
     <string name="chooser_wallpaper" msgid="7873476199295190279">"Thay đổi hình nền"</string>
+    <!-- no translation found for notification_listener_binding_label (2014162835481906429) -->
+    <skip />
     <string name="vpn_title" msgid="19615213552042827">"Đã kích hoạt VPN"</string>
     <string name="vpn_title_long" msgid="6400714798049252294">"VPN được <xliff:g id="APP">%s</xliff:g> kích hoạt"</string>
     <string name="vpn_text" msgid="3011306607126450322">"Chạm để quản lý mạng."</string>
@@ -1370,6 +1378,10 @@
     <string name="action_bar_home_description" msgid="5293600496601490216">"Điều hướng về trang chủ"</string>
     <string name="action_bar_up_description" msgid="2237496562952152589">"Điều hướng lên trên"</string>
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"Tùy chọn khác"</string>
+    <!-- no translation found for action_bar_home_description_format (7965984360903693903) -->
+    <skip />
+    <!-- no translation found for action_bar_home_subtitle_description_format (6985546530471780727) -->
+    <skip />
     <string name="storage_internal" msgid="4891916833657929263">"Bộ nhớ trong"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"Thẻ SD"</string>
     <string name="storage_usb" msgid="3017954059538517278">"Bộ lưu trữ USB"</string>
@@ -1479,4 +1491,6 @@
     <string name="error_message_title" msgid="4510373083082500195">"Lỗi"</string>
     <string name="app_no_restricted_accounts" msgid="5322164210667258876">"Ứng dụng này không hỗ trợ tài khoản cho người dùng giới hạn"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Không tìm thấy ứng dụng nào để xử lý tác vụ này"</string>
+    <!-- no translation found for revoke (5404479185228271586) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index af1a2ea..5ebd3c7 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -621,6 +621,10 @@
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"允许该应用修改对于各应用的网络使用情况的统计方式。普通应用不应使用此权限。"</string>
     <string name="permlab_accessNotifications" msgid="7673416487873432268">"查看通知"</string>
     <string name="permdesc_accessNotifications" msgid="458457742683431387">"允许该应用检索、检查并清除通知,包括其他应用发布的通知。"</string>
+    <!-- no translation found for permlab_bindNotificationListenerService (7057764742211656654) -->
+    <skip />
+    <!-- no translation found for permdesc_bindNotificationListenerService (985697918576902986) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"设置密码规则"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"控制屏幕解锁密码所允许的长度和字符。"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"监视屏幕解锁尝试次数"</string>
@@ -1048,8 +1052,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"文字操作"</string>
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"存储空间不足"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"某些系统功能可能无法正常使用"</string>
-    <string name="app_running_notification_title" msgid="4625479411505090209">"<xliff:g id="APP_NAME">%1$s</xliff:g>正在运行"</string>
-    <string name="app_running_notification_text" msgid="3368349329989620597">"<xliff:g id="APP_NAME">%1$s</xliff:g>目前正在运行"</string>
+    <!-- no translation found for app_running_notification_title (8718335121060787914) -->
+    <skip />
+    <!-- no translation found for app_running_notification_text (4653586947747330058) -->
+    <skip />
     <string name="ok" msgid="5970060430562524910">"确定"</string>
     <string name="cancel" msgid="6442560571259935130">"取消"</string>
     <string name="yes" msgid="5362982303337969312">"确定"</string>
@@ -1267,6 +1273,8 @@
     <string name="accessibility_binding_label" msgid="4148120742096474641">"辅助功能"</string>
     <string name="wallpaper_binding_label" msgid="1240087844304687662">"壁纸"</string>
     <string name="chooser_wallpaper" msgid="7873476199295190279">"更改壁纸"</string>
+    <!-- no translation found for notification_listener_binding_label (2014162835481906429) -->
+    <skip />
     <string name="vpn_title" msgid="19615213552042827">"VPN 已激活"</string>
     <string name="vpn_title_long" msgid="6400714798049252294">"“<xliff:g id="APP">%s</xliff:g>”已激活 VPN"</string>
     <string name="vpn_text" msgid="3011306607126450322">"触摸可管理网络。"</string>
@@ -1370,6 +1378,10 @@
     <string name="action_bar_home_description" msgid="5293600496601490216">"导航首页"</string>
     <string name="action_bar_up_description" msgid="2237496562952152589">"向上导航"</string>
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"更多选项"</string>
+    <!-- no translation found for action_bar_home_description_format (7965984360903693903) -->
+    <skip />
+    <!-- no translation found for action_bar_home_subtitle_description_format (6985546530471780727) -->
+    <skip />
     <string name="storage_internal" msgid="4891916833657929263">"内存设备"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"SD 卡"</string>
     <string name="storage_usb" msgid="3017954059538517278">"USB 存储器"</string>
@@ -1479,4 +1491,6 @@
     <string name="error_message_title" msgid="4510373083082500195">"错误"</string>
     <string name="app_no_restricted_accounts" msgid="5322164210667258876">"此应用不支持受限用户的帐户"</string>
     <string name="app_not_found" msgid="3429141853498927379">"找不到可处理此操作的应用"</string>
+    <!-- no translation found for revoke (5404479185228271586) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index cea9369..a0c8c05 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -621,6 +621,10 @@
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"允許應用程式修改應用程式網路使用量的計算方式 (不建議一般應用程式使用)。"</string>
     <string name="permlab_accessNotifications" msgid="7673416487873432268">"存取通知"</string>
     <string name="permdesc_accessNotifications" msgid="458457742683431387">"允許應用程式擷取、檢查及清除通知 (包括由其他應用程式發佈的通知)。"</string>
+    <!-- no translation found for permlab_bindNotificationListenerService (7057764742211656654) -->
+    <skip />
+    <!-- no translation found for permdesc_bindNotificationListenerService (985697918576902986) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"設定密碼規則"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"控制螢幕解鎖密碼所允許的長度和字元。"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"監視螢幕解鎖嘗試次數"</string>
@@ -1048,8 +1052,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"文字動作"</string>
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"儲存空間即將用盡"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"部分系統功能可能無法運作"</string>
-    <string name="app_running_notification_title" msgid="4625479411505090209">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」正在執行"</string>
-    <string name="app_running_notification_text" msgid="3368349329989620597">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」目前正在執行"</string>
+    <!-- no translation found for app_running_notification_title (8718335121060787914) -->
+    <skip />
+    <!-- no translation found for app_running_notification_text (4653586947747330058) -->
+    <skip />
     <string name="ok" msgid="5970060430562524910">"確定"</string>
     <string name="cancel" msgid="6442560571259935130">"取消"</string>
     <string name="yes" msgid="5362982303337969312">"確定"</string>
@@ -1267,6 +1273,8 @@
     <string name="accessibility_binding_label" msgid="4148120742096474641">"協助工具"</string>
     <string name="wallpaper_binding_label" msgid="1240087844304687662">"桌布"</string>
     <string name="chooser_wallpaper" msgid="7873476199295190279">"變更桌布"</string>
+    <!-- no translation found for notification_listener_binding_label (2014162835481906429) -->
+    <skip />
     <string name="vpn_title" msgid="19615213552042827">"VPN 已啟用"</string>
     <string name="vpn_title_long" msgid="6400714798049252294">"<xliff:g id="APP">%s</xliff:g> 已啟用 VPN"</string>
     <string name="vpn_text" msgid="3011306607126450322">"輕觸即可管理網路。"</string>
@@ -1370,6 +1378,10 @@
     <string name="action_bar_home_description" msgid="5293600496601490216">"瀏覽首頁"</string>
     <string name="action_bar_up_description" msgid="2237496562952152589">"向上瀏覽"</string>
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"更多選項"</string>
+    <!-- no translation found for action_bar_home_description_format (7965984360903693903) -->
+    <skip />
+    <!-- no translation found for action_bar_home_subtitle_description_format (6985546530471780727) -->
+    <skip />
     <string name="storage_internal" msgid="4891916833657929263">"內部儲存空間"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"SD 卡"</string>
     <string name="storage_usb" msgid="3017954059538517278">"USB 儲存裝置"</string>
@@ -1479,4 +1491,6 @@
     <string name="error_message_title" msgid="4510373083082500195">"錯誤"</string>
     <string name="app_no_restricted_accounts" msgid="5322164210667258876">"這個應用程式不支援受限的使用者帳戶。"</string>
     <string name="app_not_found" msgid="3429141853498927379">"找不到支援此操作的應用程式"</string>
+    <!-- no translation found for revoke (5404479185228271586) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index 8bf3aae..7f62603 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -621,6 +621,10 @@
     <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Ivumela insiza ukuthi iguqule ukuthii ukusetshenziswa kwenethiwekhi kumiswa kanjani ezinsizeni. Ayisetshenziswa izinsiza ezijwayelekile."</string>
     <string name="permlab_accessNotifications" msgid="7673416487873432268">"finyelela kuzaziso"</string>
     <string name="permdesc_accessNotifications" msgid="458457742683431387">"Ivumela uhlelo lokusebenza ukuthi lithole, lihlole, liphinde lisuse izaziso, ezifaka lezo ezithunyelwe ezinye izinhlelo zokusebenza."</string>
+    <!-- no translation found for permlab_bindNotificationListenerService (7057764742211656654) -->
+    <skip />
+    <!-- no translation found for permdesc_bindNotificationListenerService (985697918576902986) -->
+    <skip />
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Misa imithetho yephasiwedi"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Lawula ubude nezinhlamvu ezivunyelwe kumaphasiwedi okuvula isikrini"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Gaka imizamo yokuvula isikrini"</string>
@@ -1048,8 +1052,10 @@
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Izenzo zombhalo"</string>
     <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Isikhala sokulondoloza siyaphela"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Eminye imisebenzi yohlelo ingahle ingasebenzi"</string>
-    <string name="app_running_notification_title" msgid="4625479411505090209">"I-<xliff:g id="APP_NAME">%1$s</xliff:g> iyasebenza"</string>
-    <string name="app_running_notification_text" msgid="3368349329989620597">"I-<xliff:g id="APP_NAME">%1$s</xliff:g> isebenza manje"</string>
+    <!-- no translation found for app_running_notification_title (8718335121060787914) -->
+    <skip />
+    <!-- no translation found for app_running_notification_text (4653586947747330058) -->
+    <skip />
     <string name="ok" msgid="5970060430562524910">"KULUNGILE"</string>
     <string name="cancel" msgid="6442560571259935130">"Khansela"</string>
     <string name="yes" msgid="5362982303337969312">"KULUNGILE"</string>
@@ -1267,6 +1273,8 @@
     <string name="accessibility_binding_label" msgid="4148120742096474641">"Ukufinyeleleka"</string>
     <string name="wallpaper_binding_label" msgid="1240087844304687662">"Iphephadonga"</string>
     <string name="chooser_wallpaper" msgid="7873476199295190279">"Shintsha iphephadonga"</string>
+    <!-- no translation found for notification_listener_binding_label (2014162835481906429) -->
+    <skip />
     <string name="vpn_title" msgid="19615213552042827">"I-VPN isiyasebenza"</string>
     <string name="vpn_title_long" msgid="6400714798049252294">"i-VPN ivuswe ngu <xliff:g id="APP">%s</xliff:g>"</string>
     <string name="vpn_text" msgid="3011306607126450322">"Thinta ukuze wengamele inethiwekhi."</string>
@@ -1370,6 +1378,10 @@
     <string name="action_bar_home_description" msgid="5293600496601490216">"Zulazulela ekhaya"</string>
     <string name="action_bar_up_description" msgid="2237496562952152589">"Zulazulela phezulu"</string>
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"Izinketho ezingaphezulu"</string>
+    <!-- no translation found for action_bar_home_description_format (7965984360903693903) -->
+    <skip />
+    <!-- no translation found for action_bar_home_subtitle_description_format (6985546530471780727) -->
+    <skip />
     <string name="storage_internal" msgid="4891916833657929263">"Isitoreji sangaphakathi"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"Ikhadi le-SD"</string>
     <string name="storage_usb" msgid="3017954059538517278">"Isitoreji se-USB"</string>
@@ -1479,4 +1491,6 @@
     <string name="error_message_title" msgid="4510373083082500195">"Iphutha"</string>
     <string name="app_no_restricted_accounts" msgid="5322164210667258876">"Lolu hlelo lokusebenza alusekeli ama-akhawunti wabasebenzisi abakhawulelwe"</string>
     <string name="app_not_found" msgid="3429141853498927379">"Alukho uhlelo lokusebenza olutholakele lokuphatha lesi senzo"</string>
+    <!-- no translation found for revoke (5404479185228271586) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values/arrays.xml b/core/res/res/values/arrays.xml
index f7ff77b..146607e 100644
--- a/core/res/res/values/arrays.xml
+++ b/core/res/res/values/arrays.xml
@@ -141,6 +141,10 @@
        <item>@drawable/menu_submenu_background</item>
        <item>@drawable/menu_dropdown_panel_holo_light</item>
        <item>@drawable/menu_dropdown_panel_holo_dark</item>
+       <item>@drawable/menu_popup_panel_holo_light</item>
+       <item>@drawable/menu_popup_panel_holo_dark</item>
+       <item>@drawable/menu_panel_holo_light</item>
+       <item>@drawable/menu_panel_holo_dark</item>
        <item>@drawable/overscroll_edge</item>
        <item>@drawable/overscroll_glow</item>
        <item>@drawable/spinner_16_outer_holo</item>
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 56c2235..f494d8c 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -1869,7 +1869,7 @@
 
     <style name="Widget.Holo.ListPopupWindow" parent="Widget.ListPopupWindow">
         <item name="android:dropDownSelector">@android:drawable/list_selector_holo_dark</item>
-        <item name="android:popupBackground">@android:drawable/menu_dropdown_panel_holo_dark</item>
+        <item name="android:popupBackground">@android:drawable/menu_panel_holo_dark</item>
         <item name="android:dropDownVerticalOffset">0dip</item>
         <item name="android:dropDownHorizontalOffset">0dip</item>
         <item name="android:dropDownWidth">wrap_content</item>
@@ -2242,7 +2242,7 @@
 
     <style name="Widget.Holo.Light.ListPopupWindow" parent="Widget.ListPopupWindow">
         <item name="android:dropDownSelector">@android:drawable/list_selector_holo_light</item>
-        <item name="android:popupBackground">@android:drawable/menu_dropdown_panel_holo_light</item>
+        <item name="android:popupBackground">@android:drawable/menu_panel_holo_light</item>
         <item name="android:dropDownVerticalOffset">0dip</item>
         <item name="android:dropDownHorizontalOffset">0dip</item>
         <item name="android:dropDownWidth">wrap_content</item>
diff --git a/core/tests/hosttests/test-apps/DownloadManagerTestApp/src/com/android/frameworks/downloadmanagertests/DownloadManagerTestApp.java b/core/tests/hosttests/test-apps/DownloadManagerTestApp/src/com/android/frameworks/downloadmanagertests/DownloadManagerTestApp.java
index 9c44d61..0518e64 100644
--- a/core/tests/hosttests/test-apps/DownloadManagerTestApp/src/com/android/frameworks/downloadmanagertests/DownloadManagerTestApp.java
+++ b/core/tests/hosttests/test-apps/DownloadManagerTestApp/src/com/android/frameworks/downloadmanagertests/DownloadManagerTestApp.java
@@ -265,8 +265,8 @@
      * @throws Exception if unsuccessful
      */
     public void runDownloadMultipleSwitching() throws Exception {
-        String filename = DOWNLOAD_500K_FILENAME;
-        long filesize = DOWNLOAD_500K_FILESIZE;
+        String filename = DOWNLOAD_5MB_FILENAME;
+        long filesize = DOWNLOAD_5MB_FILESIZE;
         doCommonDownloadSetup();
 
         String localDownloadDirectory = Environment.getExternalStorageDirectory().getPath();
@@ -340,8 +340,8 @@
      * @throws Exception if unsuccessful
      */
     public void runDownloadMultipleWiFiEnableDisable() throws Exception {
-        String filename = DOWNLOAD_500K_FILENAME;
-        long filesize = DOWNLOAD_500K_FILESIZE;
+        String filename = DOWNLOAD_5MB_FILENAME;
+        long filesize = DOWNLOAD_5MB_FILESIZE;
         doCommonDownloadSetup();
 
         String localDownloadDirectory = Environment.getExternalStorageDirectory().getPath();
@@ -409,8 +409,8 @@
      * @throws Exception if unsuccessful
      */
     public void runDownloadMultipleAirplaneModeEnableDisable() throws Exception {
-        String filename = DOWNLOAD_500K_FILENAME;
-        long filesize = DOWNLOAD_500K_FILESIZE;
+        String filename = DOWNLOAD_5MB_FILENAME;
+        long filesize = DOWNLOAD_5MB_FILESIZE;
         // make sure WiFi is enabled, and airplane mode is not on
         doCommonDownloadSetup();
 
diff --git a/data/fonts/DroidSerif-Bold.ttf b/data/fonts/DroidSerif-Bold.ttf
index 838d255..16a914e 100644
--- a/data/fonts/DroidSerif-Bold.ttf
+++ b/data/fonts/DroidSerif-Bold.ttf
Binary files differ
diff --git a/data/fonts/DroidSerif-BoldItalic.ttf b/data/fonts/DroidSerif-BoldItalic.ttf
index 0b1601f..50324fc 100644
--- a/data/fonts/DroidSerif-BoldItalic.ttf
+++ b/data/fonts/DroidSerif-BoldItalic.ttf
Binary files differ
diff --git a/data/fonts/DroidSerif-Italic.ttf b/data/fonts/DroidSerif-Italic.ttf
index 2972809..bb2757c 100644
--- a/data/fonts/DroidSerif-Italic.ttf
+++ b/data/fonts/DroidSerif-Italic.ttf
Binary files differ
diff --git a/data/fonts/DroidSerif-Regular.ttf b/data/fonts/DroidSerif-Regular.ttf
index 5b4fe81..da0a2cc 100644
--- a/data/fonts/DroidSerif-Regular.ttf
+++ b/data/fonts/DroidSerif-Regular.ttf
Binary files differ
diff --git a/data/fonts/Roboto-Italic.ttf b/data/fonts/Roboto-Italic.ttf
index bd57775..4642d6f 100644
--- a/data/fonts/Roboto-Italic.ttf
+++ b/data/fonts/Roboto-Italic.ttf
Binary files differ
diff --git a/docs/html/guide/topics/graphics/opengl.jd b/docs/html/guide/topics/graphics/opengl.jd
index 5630e63..3ec71b2 100644
--- a/docs/html/guide/topics/graphics/opengl.jd
+++ b/docs/html/guide/topics/graphics/opengl.jd
@@ -138,7 +138,7 @@
             <li>{@link android.opengl.GLES10}</li>
             <li>{@link android.opengl.GLES10Ext}</li>
             <li>{@link android.opengl.GLES11}</li>
-            <li>{@link android.opengl.GLES10Ext}</li>
+            <li>{@link android.opengl.GLES11Ext}</li>
           </ul>
         </li>
       <li>{@link javax.microedition.khronos.opengles} - This package provides the standard
@@ -289,13 +289,14 @@
     private final String vertexShaderCode =
 
         // This matrix member variable provides a hook to manipulate
-        // the coordinates of objects that use this vertex shader
+        // the coordinates of objects that use this vertex shader.
         "uniform mat4 uMVPMatrix;   \n" +
 
         "attribute vec4 vPosition;  \n" +
         "void main(){               \n" +
-
-        // the matrix must be included as part of gl_Position
+        // The matrix must be included as part of gl_Position
+        // Note that the uMVPMatrix factor *must be first* in order
+        // for the matrix multiplication product to be correct.
         " gl_Position = uMVPMatrix * vPosition; \n" +
 
         "}  \n";
diff --git a/docs/html/tools/debugging/debugging-ui.jd b/docs/html/tools/debugging/debugging-ui.jd
index 8ca5192..f927d08 100644
--- a/docs/html/tools/debugging/debugging-ui.jd
+++ b/docs/html/tools/debugging/debugging-ui.jd
@@ -60,7 +60,9 @@
 
   <p>The Hierarchy Viewer application allows you to debug and optimize your user interface. It
   provides a visual representation of the layout's View hierarchy (the View Hierarchy window)
-  and a magnified view of the display (the Pixel Perfect window).</p>
+  with performance information for each node in the layout,
+  and a magnified view of the display (the Pixel Perfect window) to closely examine the pixels
+  in your layout.</p>
 
   <p>Android <code>lint</code> is a static code scanning tool that helps you optimize the layouts and layout
   hierarchies of your applications, as well as detect other common coding problems. You can run it against your layout files or resource
diff --git a/docs/html/training/basics/firstapp/building-ui.jd b/docs/html/training/basics/firstapp/building-ui.jd
index 0f18861..2615bee 100644
--- a/docs/html/training/basics/firstapp/building-ui.jd
+++ b/docs/html/training/basics/firstapp/building-ui.jd
@@ -240,7 +240,7 @@
     &lt;string name="app_name">My First App&lt;/string>
     &lt;string name="edit_message">Enter a message&lt;/string>
     &lt;string name="button_send">Send&lt;/string>
-    &lt;string name="menu_settings">Settings&lt;/string>
+    &lt;string name="action_settings">Settings&lt;/string>
     &lt;string name="title_activity_main">MainActivity&lt;/string>
 &lt;/resources>
 </pre>
diff --git a/drm/jni/Android.mk b/drm/jni/Android.mk
index fff7eee..474b9b2 100644
--- a/drm/jni/Android.mk
+++ b/drm/jni/Android.mk
@@ -23,6 +23,7 @@
 
 LOCAL_SHARED_LIBRARIES := \
     libdrmframework \
+    liblog \
     libutils \
     libandroid_runtime \
     libnativehelper \
@@ -43,4 +44,3 @@
 LOCAL_MODULE_TAGS := optional
 
 include $(BUILD_SHARED_LIBRARY)
-
diff --git a/graphics/java/android/renderscript/Allocation.java b/graphics/java/android/renderscript/Allocation.java
index b8564b6..5751331 100644
--- a/graphics/java/android/renderscript/Allocation.java
+++ b/graphics/java/android/renderscript/Allocation.java
@@ -274,12 +274,20 @@
             }
         }
 
+        // don't need to account for USAGE_SHARED Allocations
+        if ((usage & USAGE_SHARED) == 0) {
+            int numBytes = t.getCount() * t.getElement().getBytesSize();
+            rs.addAllocSizeForGC(numBytes);
+            mGCSize = numBytes;
+        }
+
         mType = t;
         mUsage = usage;
 
         if (t != null) {
             updateCacheInfo(t);
         }
+
     }
 
     private void validateIsInt32() {
@@ -492,7 +500,9 @@
      */
     public void copyFromUnchecked(int[] d) {
         mRS.validate();
-        if (mCurrentDimY > 0) {
+        if (mCurrentDimZ > 0) {
+            copy3DRangeFromUnchecked(0, 0, 0, mCurrentDimX, mCurrentDimY, mCurrentDimZ, d);
+        } else if (mCurrentDimY > 0) {
             copy2DRangeFromUnchecked(0, 0, mCurrentDimX, mCurrentDimY, d);
         } else {
             copy1DRangeFromUnchecked(0, mCurrentCount, d);
@@ -507,7 +517,9 @@
      */
     public void copyFromUnchecked(short[] d) {
         mRS.validate();
-        if (mCurrentDimY > 0) {
+        if (mCurrentDimZ > 0) {
+            copy3DRangeFromUnchecked(0, 0, 0, mCurrentDimX, mCurrentDimY, mCurrentDimZ, d);
+        } else if (mCurrentDimY > 0) {
             copy2DRangeFromUnchecked(0, 0, mCurrentDimX, mCurrentDimY, d);
         } else {
             copy1DRangeFromUnchecked(0, mCurrentCount, d);
@@ -522,7 +534,9 @@
      */
     public void copyFromUnchecked(byte[] d) {
         mRS.validate();
-        if (mCurrentDimY > 0) {
+        if (mCurrentDimZ > 0) {
+            copy3DRangeFromUnchecked(0, 0, 0, mCurrentDimX, mCurrentDimY, mCurrentDimZ, d);
+        } else if (mCurrentDimY > 0) {
             copy2DRangeFromUnchecked(0, 0, mCurrentDimX, mCurrentDimY, d);
         } else {
             copy1DRangeFromUnchecked(0, mCurrentCount, d);
@@ -537,7 +551,9 @@
      */
     public void copyFromUnchecked(float[] d) {
         mRS.validate();
-        if (mCurrentDimY > 0) {
+        if (mCurrentDimZ > 0) {
+            copy3DRangeFromUnchecked(0, 0, 0, mCurrentDimX, mCurrentDimY, mCurrentDimZ, d);
+        } else if (mCurrentDimY > 0) {
             copy2DRangeFromUnchecked(0, 0, mCurrentDimX, mCurrentDimY, d);
         } else {
             copy1DRangeFromUnchecked(0, mCurrentCount, d);
@@ -553,7 +569,9 @@
      */
     public void copyFrom(int[] d) {
         mRS.validate();
-        if (mCurrentDimY > 0) {
+        if (mCurrentDimZ > 0) {
+            copy3DRangeFrom(0, 0, 0, mCurrentDimX, mCurrentDimY, mCurrentDimZ, d);
+        } else if (mCurrentDimY > 0) {
             copy2DRangeFrom(0, 0, mCurrentDimX, mCurrentDimY, d);
         } else {
             copy1DRangeFrom(0, mCurrentCount, d);
@@ -569,7 +587,9 @@
      */
     public void copyFrom(short[] d) {
         mRS.validate();
-        if (mCurrentDimY > 0) {
+        if (mCurrentDimZ > 0) {
+            copy3DRangeFrom(0, 0, 0, mCurrentDimX, mCurrentDimY, mCurrentDimZ, d);
+        } else if (mCurrentDimY > 0) {
             copy2DRangeFrom(0, 0, mCurrentDimX, mCurrentDimY, d);
         } else {
             copy1DRangeFrom(0, mCurrentCount, d);
@@ -585,7 +605,9 @@
      */
     public void copyFrom(byte[] d) {
         mRS.validate();
-        if (mCurrentDimY > 0) {
+        if (mCurrentDimZ > 0) {
+            copy3DRangeFrom(0, 0, 0, mCurrentDimX, mCurrentDimY, mCurrentDimZ, d);
+        } else if (mCurrentDimY > 0) {
             copy2DRangeFrom(0, 0, mCurrentDimX, mCurrentDimY, d);
         } else {
             copy1DRangeFrom(0, mCurrentCount, d);
@@ -601,7 +623,9 @@
      */
     public void copyFrom(float[] d) {
         mRS.validate();
-        if (mCurrentDimY > 0) {
+        if (mCurrentDimZ > 0) {
+            copy3DRangeFrom(0, 0, 0, mCurrentDimX, mCurrentDimY, mCurrentDimZ, d);
+        } else if (mCurrentDimY > 0) {
             copy2DRangeFrom(0, 0, mCurrentDimX, mCurrentDimY, d);
         } else {
             copy1DRangeFrom(0, mCurrentCount, d);
@@ -967,12 +991,144 @@
             Canvas c = new Canvas(newBitmap);
             c.drawBitmap(data, 0, 0, null);
             copy2DRangeFrom(xoff, yoff, newBitmap);
+            return;
         }
         validateBitmapFormat(data);
         validate2DRange(xoff, yoff, data.getWidth(), data.getHeight());
         mRS.nAllocationData2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID, data);
     }
 
+    private void validate3DRange(int xoff, int yoff, int zoff, int w, int h, int d) {
+        if (mAdaptedAllocation != null) {
+
+        } else {
+
+            if (xoff < 0 || yoff < 0 || zoff < 0) {
+                throw new RSIllegalArgumentException("Offset cannot be negative.");
+            }
+            if (h < 0 || w < 0 || d < 0) {
+                throw new RSIllegalArgumentException("Height or width cannot be negative.");
+            }
+            if (((xoff + w) > mCurrentDimX) || ((yoff + h) > mCurrentDimY) || ((zoff + d) > mCurrentDimZ)) {
+                throw new RSIllegalArgumentException("Updated region larger than allocation.");
+            }
+        }
+    }
+
+    /**
+     * @hide
+     *
+     */
+    void copy3DRangeFromUnchecked(int xoff, int yoff, int zoff, int w, int h, int d, byte[] data) {
+        mRS.validate();
+        validate3DRange(xoff, yoff, zoff, w, h, d);
+        mRS.nAllocationData3D(getIDSafe(), xoff, yoff, zoff, mSelectedLOD,
+                              w, h, d, data, data.length);
+    }
+
+    /**
+     * @hide
+     *
+     */
+    void copy3DRangeFromUnchecked(int xoff, int yoff, int zoff, int w, int h, int d, short[] data) {
+        mRS.validate();
+        validate3DRange(xoff, yoff, zoff, w, h, d);
+        mRS.nAllocationData3D(getIDSafe(), xoff, yoff, zoff, mSelectedLOD,
+                              w, h, d, data, data.length * 2);
+    }
+
+    /**
+     * @hide
+     *
+     */
+    void copy3DRangeFromUnchecked(int xoff, int yoff, int zoff, int w, int h, int d, int[] data) {
+        mRS.validate();
+        validate3DRange(xoff, yoff, zoff, w, h, d);
+        mRS.nAllocationData3D(getIDSafe(), xoff, yoff, zoff, mSelectedLOD,
+                              w, h, d, data, data.length * 4);
+    }
+
+    /**
+     * @hide
+     *
+     */
+    void copy3DRangeFromUnchecked(int xoff, int yoff, int zoff, int w, int h, int d, float[] data) {
+        mRS.validate();
+        validate3DRange(xoff, yoff, zoff, w, h, d);
+        mRS.nAllocationData3D(getIDSafe(), xoff, yoff, zoff, mSelectedLOD,
+                              w, h, d, data, data.length * 4);
+    }
+
+
+    /**
+     * @hide
+     * Copy a rectangular region from the array into the allocation.
+     * The incoming array is assumed to be tightly packed.
+     *
+     * @param xoff X offset of the region to update
+     * @param yoff Y offset of the region to update
+     * @param zoff Z offset of the region to update
+     * @param w Width of the incoming region to update
+     * @param h Height of the incoming region to update
+     * @param d Depth of the incoming region to update
+     * @param data to be placed into the allocation
+     */
+    public void copy3DRangeFrom(int xoff, int yoff, int zoff, int w, int h, int d, byte[] data) {
+        validateIsInt8();
+        copy3DRangeFromUnchecked(xoff, yoff, zoff, w, h, d, data);
+    }
+
+    /**
+     * @hide
+     *
+     */
+    public void copy3DRangeFrom(int xoff, int yoff, int zoff, int w, int h, int d, short[] data) {
+        validateIsInt16();
+        copy3DRangeFromUnchecked(xoff, yoff, zoff, w, h, d, data);
+    }
+
+    /**
+     * @hide
+     *
+     */
+    public void copy3DRangeFrom(int xoff, int yoff, int zoff, int w, int h, int d, int[] data) {
+        validateIsInt32();
+        copy3DRangeFromUnchecked(xoff, yoff, zoff, w, h, d, data);
+    }
+
+    /**
+     * @hide
+     *
+     */
+    public void copy3DRangeFrom(int xoff, int yoff, int zoff, int w, int h, int d, float[] data) {
+        validateIsFloat32();
+        copy3DRangeFromUnchecked(xoff, yoff, zoff, w, h, d, data);
+    }
+
+    /**
+     * @hide
+     * Copy a rectangular region into the allocation from another
+     * allocation.
+     *
+     * @param xoff X offset of the region to update.
+     * @param yoff Y offset of the region to update.
+     * @param w Width of the incoming region to update.
+     * @param h Height of the incoming region to update.
+     * @param d Depth of the incoming region to update.
+     * @param data source allocation.
+     * @param dataXoff X offset in data of the region to update.
+     * @param dataYoff Y offset in data of the region to update.
+     * @param dataZoff Z offset in data of the region to update
+     */
+    public void copy3DRangeFrom(int xoff, int yoff, int zoff, int w, int h, int d,
+                                Allocation data, int dataXoff, int dataYoff, int dataZoff) {
+        mRS.validate();
+        validate3DRange(xoff, yoff, zoff, w, h, d);
+        mRS.nAllocationData3D(getIDSafe(), xoff, yoff, zoff, mSelectedLOD,
+                              w, h, d, data.getID(mRS), dataXoff, dataYoff, dataZoff,
+                              data.mSelectedLOD);
+    }
+
 
     /**
      * Copy from the Allocation into a Bitmap.  The bitmap must
@@ -1050,6 +1206,10 @@
      * A new type will be created with the new dimension.
      *
      * @param dimX The new size of the allocation.
+     *
+     * @deprecated Renderscript objects should be immutable once
+     * created.  The replacement is to create a new allocation and copy the
+     * contents.
      */
     public synchronized void resize(int dimX) {
         if ((mType.getY() > 0)|| (mType.getZ() > 0) || mType.hasFaces() || mType.hasMipmaps()) {
@@ -1064,38 +1224,6 @@
         updateCacheInfo(mType);
     }
 
-    /**
-     * Resize a 2D allocation.  The contents of the allocation are
-     * preserved.  If new elements are allocated objects are created
-     * with null contents and the new region is otherwise undefined.
-     *
-     * If the new region is smaller the references of any objects
-     * outside the new region will be released.
-     *
-     * A new type will be created with the new dimension.
-     *
-     * @param dimX The new size of the allocation.
-     * @param dimY The new size of the allocation.
-     */
-    public synchronized void resize(int dimX, int dimY) {
-        if ((mType.getZ() > 0) || mType.hasFaces() || mType.hasMipmaps()) {
-            throw new RSInvalidStateException(
-                "Resize only support for 2D allocations at this time.");
-        }
-        if (mType.getY() == 0) {
-            throw new RSInvalidStateException(
-                "Resize only support for 2D allocations at this time.");
-        }
-        mRS.nAllocationResize2D(getID(mRS), dimX, dimY);
-        mRS.finish();  // Necessary because resize is fifoed and update is async.
-
-        int typeID = mRS.nAllocationGetType(getID(mRS));
-        mType = new Type(typeID, mRS);
-        mType.updateFromNative();
-        updateCacheInfo(mType);
-    }
-
-
 
     // creation
 
@@ -1117,6 +1245,7 @@
         if (type.getID(rs) == 0) {
             throw new RSInvalidStateException("Bad Type");
         }
+
         int id = rs.nAllocationCreateTyped(type.getID(rs), mips.mID, usage, 0);
         if (id == 0) {
             throw new RSRuntimeException("Allocation creation failed.");
@@ -1266,7 +1395,6 @@
             return alloc;
         }
 
-
         int id = rs.nAllocationCreateFromBitmap(t.getID(rs), mips.mID, b, usage);
         if (id == 0) {
             throw new RSRuntimeException("Load failed.");
diff --git a/graphics/java/android/renderscript/BaseObj.java b/graphics/java/android/renderscript/BaseObj.java
index f464f9b..c2ebc9f 100644
--- a/graphics/java/android/renderscript/BaseObj.java
+++ b/graphics/java/android/renderscript/BaseObj.java
@@ -71,6 +71,9 @@
     private int mID;
     private boolean mDestroyed;
     private String mName;
+
+    int mGCSize;
+
     RenderScript mRS;
 
     /**
@@ -135,6 +138,9 @@
             throw new RSInvalidStateException("Object already destroyed.");
         }
         mDestroyed = true;
+        if (mGCSize != 0) {
+            mRS.removeAllocSizeForGC(mGCSize);
+        }
         mRS.nObjDestroy(mID);
     }
 
diff --git a/graphics/java/android/renderscript/RenderScript.java b/graphics/java/android/renderscript/RenderScript.java
index bef28aa..d5af276 100644
--- a/graphics/java/android/renderscript/RenderScript.java
+++ b/graphics/java/android/renderscript/RenderScript.java
@@ -83,11 +83,7 @@
     native void nContextInitToClient(int con);
     native void nContextDeinitToClient(int con);
 
-    /**
-     * Name of the file that holds the object cache.
-     */
-    private static final String CACHE_PATH = "com.android.renderscript.cache";
-    static String mCachePath;
+    static File mCacheDir;
 
      /**
      * Sets the directory to use as a persistent storage for the
@@ -97,9 +93,8 @@
      * @param cacheDir A directory the current process can write to
      */
     public static void setupDiskCache(File cacheDir) {
-        File f = new File(cacheDir, CACHE_PATH);
-        mCachePath = f.getAbsolutePath();
-        f.mkdirs();
+        // Defer creation of cache path to nScriptCCreate().
+        mCacheDir = cacheDir;
     }
 
     public enum ContextType {
@@ -420,6 +415,46 @@
         rsnAllocationData2D(mContext, id, xoff, yoff, mip, face, b);
     }
 
+    native void rsnAllocationData3D(int con,
+                                    int dstAlloc, int dstXoff, int dstYoff, int dstZoff,
+                                    int dstMip,
+                                    int width, int height, int depth,
+                                    int srcAlloc, int srcXoff, int srcYoff, int srcZoff,
+                                    int srcMip);
+    synchronized void nAllocationData3D(int dstAlloc, int dstXoff, int dstYoff, int dstZoff,
+                                        int dstMip,
+                                        int width, int height, int depth,
+                                        int srcAlloc, int srcXoff, int srcYoff, int srcZoff,
+                                        int srcMip) {
+        validate();
+        rsnAllocationData3D(mContext,
+                            dstAlloc, dstXoff, dstYoff, dstZoff,
+                            dstMip, width, height, depth,
+                            srcAlloc, srcXoff, srcYoff, srcZoff, srcMip);
+    }
+
+    native void rsnAllocationData3D(int con, int id, int xoff, int yoff, int zoff, int mip, int w, int h, int depth, byte[] d, int sizeBytes);
+    synchronized void nAllocationData3D(int id, int xoff, int yoff, int zoff, int mip, int w, int h, int depth, byte[] d, int sizeBytes) {
+        validate();
+        rsnAllocationData3D(mContext, id, xoff, yoff, zoff, mip, w, h, depth, d, sizeBytes);
+    }
+    native void rsnAllocationData3D(int con, int id, int xoff, int yoff, int zoff, int mip, int w, int h, int depth, short[] d, int sizeBytes);
+    synchronized void nAllocationData3D(int id, int xoff, int yoff, int zoff, int mip, int w, int h, int depth, short[] d, int sizeBytes) {
+        validate();
+        rsnAllocationData3D(mContext, id, xoff, yoff, zoff, mip, w, h, depth, d, sizeBytes);
+    }
+    native void rsnAllocationData3D(int con, int id, int xoff, int yoff, int zoff, int mip, int w, int h, int depth, int[] d, int sizeBytes);
+    synchronized void nAllocationData3D(int id, int xoff, int yoff, int zoff, int mip, int w, int h, int depth, int[] d, int sizeBytes) {
+        validate();
+        rsnAllocationData3D(mContext, id, xoff, yoff, zoff, mip, w, h, depth, d, sizeBytes);
+    }
+    native void rsnAllocationData3D(int con, int id, int xoff, int yoff, int zoff, int mip, int w, int h, int depth, float[] d, int sizeBytes);
+    synchronized void nAllocationData3D(int id, int xoff, int yoff, int zoff, int mip, int w, int h, int depth, float[] d, int sizeBytes) {
+        validate();
+        rsnAllocationData3D(mContext, id, xoff, yoff, zoff, mip, w, h, depth, d, sizeBytes);
+    }
+
+
     native void rsnAllocationRead(int con, int id, byte[] d);
     synchronized void nAllocationRead(int id, byte[] d) {
         validate();
@@ -451,11 +486,6 @@
         validate();
         rsnAllocationResize1D(mContext, id, dimX);
     }
-    native void rsnAllocationResize2D(int con, int id, int dimX, int dimY);
-    synchronized void nAllocationResize2D(int id, int dimX, int dimY) {
-        validate();
-        rsnAllocationResize2D(mContext, id, dimX, dimY);
-    }
 
     native int  rsnFileA3DCreateFromAssetStream(int con, int assetStream);
     synchronized int nFileA3DCreateFromAssetStream(int assetStream) {
@@ -724,6 +754,8 @@
     int     mContext;
     @SuppressWarnings({"FieldCanBeLocal"})
     MessageThread mMessageThread;
+    GCThread mGCThread;
+
 
     Element mElement_U8;
     Element mElement_I8;
@@ -1006,6 +1038,49 @@
         }
     }
 
+    static class GCThread extends Thread {
+        RenderScript mRS;
+        boolean mRun = true;
+
+        int currentSize = 0;
+        final static int targetSize = 256*1024*1024; // call System.gc after 256MB of allocs
+
+        GCThread(RenderScript rs) {
+            super("RSGCThread");
+            mRS = rs;
+
+        }
+
+        public void run() {
+            while(mRun) {
+                boolean doGC = false;
+                synchronized(this) {
+                    if (currentSize >= targetSize) {
+                        doGC = true;
+                    }
+                }
+                if (doGC == true) {
+                    System.gc();
+                }
+                try {
+                    sleep(1, 0);
+                } catch(InterruptedException e) {
+                }
+            }
+            Log.d(LOG_TAG, "GCThread exiting.");
+        }
+
+        public synchronized void addAllocSize(int bytes) {
+            currentSize += bytes;
+        }
+
+        public synchronized void removeAllocSize(int bytes) {
+            currentSize -= bytes;
+        }
+
+    }
+
+
     RenderScript(Context ctx) {
         if (ctx != null) {
             mApplicationContext = ctx.getApplicationContext();
@@ -1028,6 +1103,15 @@
         return create(ctx, sdkVersion, ContextType.NORMAL);
     }
 
+    void addAllocSizeForGC(int bytes) {
+        mGCThread.addAllocSize(bytes);
+    }
+
+    void removeAllocSizeForGC(int bytes) {
+        mGCThread.removeAllocSize(bytes);
+    }
+
+
     /**
      * Create a basic RenderScript context.
      *
@@ -1044,7 +1128,9 @@
             throw new RSDriverException("Failed to create RS context.");
         }
         rs.mMessageThread = new MessageThread(rs);
+        rs.mGCThread = new GCThread(rs);
         rs.mMessageThread.start();
+        rs.mGCThread.start();
         return rs;
     }
 
@@ -1099,8 +1185,10 @@
         validate();
         nContextDeinitToClient(mContext);
         mMessageThread.mRun = false;
+        mGCThread.mRun = false;
         try {
             mMessageThread.join();
+            mGCThread.join();
         } catch(InterruptedException e) {
         }
 
diff --git a/graphics/java/android/renderscript/RenderScriptGL.java b/graphics/java/android/renderscript/RenderScriptGL.java
index 52034b1..fad8838 100644
--- a/graphics/java/android/renderscript/RenderScriptGL.java
+++ b/graphics/java/android/renderscript/RenderScriptGL.java
@@ -198,6 +198,9 @@
         }
         mMessageThread = new MessageThread(this);
         mMessageThread.start();
+        mGCThread = new GCThread(this);
+        mGCThread.start();
+
     }
 
     /**
diff --git a/graphics/java/android/renderscript/ScriptC.java b/graphics/java/android/renderscript/ScriptC.java
index 108b230..2f69775 100644
--- a/graphics/java/android/renderscript/ScriptC.java
+++ b/graphics/java/android/renderscript/ScriptC.java
@@ -60,8 +60,16 @@
             throw new RSRuntimeException("Loading of ScriptC script failed.");
         }
         setID(id);
+        mGCSize = 2 * 1024 * 1024;
+        rs.addAllocSizeForGC(mGCSize);
     }
 
+    /**
+     * Name of the file that holds the object cache.
+     */
+    private static final String CACHE_PATH = "com.android.renderscript.cache";
+
+    static String mCachePath;
 
     private static synchronized int internalCreate(RenderScript rs, Resources resources, int resourceID) {
         byte[] pgm;
@@ -94,7 +102,13 @@
 
         String resName = resources.getResourceEntryName(resourceID);
 
+        // Create the RS cache path if we haven't done so already.
+        if (mCachePath == null) {
+            File f = new File(rs.mCacheDir, CACHE_PATH);
+            mCachePath = f.getAbsolutePath();
+            f.mkdirs();
+        }
         Log.v(TAG, "Create script for resource = " + resName);
-        return rs.nScriptCCreate(resName, rs.mCachePath, pgm, pgmLength);
+        return rs.nScriptCCreate(resName, mCachePath, pgm, pgmLength);
     }
 }
diff --git a/graphics/jni/Android.mk b/graphics/jni/Android.mk
index 80d7728..e8beae53 100644
--- a/graphics/jni/Android.mk
+++ b/graphics/jni/Android.mk
@@ -10,6 +10,7 @@
         libnativehelper \
         libRS \
         libcutils \
+        liblog \
         libskia \
         libutils \
         libui \
diff --git a/graphics/jni/android_renderscript_RenderScript.cpp b/graphics/jni/android_renderscript_RenderScript.cpp
index 8757b19..460a516 100644
--- a/graphics/jni/android_renderscript_RenderScript.cpp
+++ b/graphics/jni/android_renderscript_RenderScript.cpp
@@ -725,6 +725,72 @@
 }
 
 static void
+nAllocationData3D_s(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint xoff, jint yoff, jint zoff, jint lod,
+                    jint w, jint h, jint d, jshortArray data, int sizeBytes)
+{
+    jint len = _env->GetArrayLength(data);
+    LOG_API("nAllocation3DData_s, con(%p), adapter(%p), xoff(%i), yoff(%i), w(%i), h(%i), len(%i)", con, (RsAllocation)alloc, xoff, yoff, zoff, w, h, d, len);
+    jshort *ptr = _env->GetShortArrayElements(data, NULL);
+    rsAllocation3DData(con, (RsAllocation)alloc, xoff, yoff, zoff, lod, w, h, d, ptr, sizeBytes, 0);
+    _env->ReleaseShortArrayElements(data, ptr, JNI_ABORT);
+}
+
+static void
+nAllocationData3D_b(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint xoff, jint yoff, jint zoff, jint lod,
+                    jint w, jint h, jint d, jbyteArray data, int sizeBytes)
+{
+    jint len = _env->GetArrayLength(data);
+    LOG_API("nAllocation3DData_b, con(%p), adapter(%p), xoff(%i), yoff(%i), w(%i), h(%i), len(%i)", con, (RsAllocation)alloc, xoff, yoff, zoff, w, h, d, len);
+    jbyte *ptr = _env->GetByteArrayElements(data, NULL);
+    rsAllocation3DData(con, (RsAllocation)alloc, xoff, yoff, zoff, lod, w, h, d, ptr, sizeBytes, 0);
+    _env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
+}
+
+static void
+nAllocationData3D_i(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint xoff, jint yoff, jint zoff, jint lod,
+                    jint w, jint h, jint d, jintArray data, int sizeBytes)
+{
+    jint len = _env->GetArrayLength(data);
+    LOG_API("nAllocation3DData_i, con(%p), adapter(%p), xoff(%i), yoff(%i), w(%i), h(%i), len(%i)", con, (RsAllocation)alloc, xoff, yoff, zoff, w, h, d, len);
+    jint *ptr = _env->GetIntArrayElements(data, NULL);
+    rsAllocation3DData(con, (RsAllocation)alloc, xoff, yoff, zoff, lod, w, h, d, ptr, sizeBytes, 0);
+    _env->ReleaseIntArrayElements(data, ptr, JNI_ABORT);
+}
+
+static void
+nAllocationData3D_f(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint xoff, jint yoff, jint zoff, jint lod,
+                    jint w, jint h, jint d, jfloatArray data, int sizeBytes)
+{
+    jint len = _env->GetArrayLength(data);
+    LOG_API("nAllocation3DData_f, con(%p), adapter(%p), xoff(%i), yoff(%i), w(%i), h(%i), len(%i)", con, (RsAllocation)alloc, xoff, yoff, zoff, w, h, d, len);
+    jfloat *ptr = _env->GetFloatArrayElements(data, NULL);
+    rsAllocation3DData(con, (RsAllocation)alloc, xoff, yoff, zoff, lod, w, h, d, ptr, sizeBytes, 0);
+    _env->ReleaseFloatArrayElements(data, ptr, JNI_ABORT);
+}
+
+static void
+nAllocationData3D_alloc(JNIEnv *_env, jobject _this, RsContext con,
+                        jint dstAlloc, jint dstXoff, jint dstYoff, jint dstZoff,
+                        jint dstMip,
+                        jint width, jint height, jint depth,
+                        jint srcAlloc, jint srcXoff, jint srcYoff, jint srcZoff,
+                        jint srcMip)
+{
+    LOG_API("nAllocationData3D_alloc, con(%p), dstAlloc(%p), dstXoff(%i), dstYoff(%i),"
+            " dstMip(%i), width(%i), height(%i),"
+            " srcAlloc(%p), srcXoff(%i), srcYoff(%i), srcMip(%i)",
+            con, (RsAllocation)dstAlloc, dstXoff, dstYoff, dstMip, dstFace,
+            width, height, (RsAllocation)srcAlloc, srcXoff, srcYoff, srcMip, srcFace);
+
+    rsAllocationCopy3DRange(con,
+                            (RsAllocation)dstAlloc,
+                            dstXoff, dstYoff, dstZoff, dstMip,
+                            width, height, depth,
+                            (RsAllocation)srcAlloc,
+                            srcXoff, srcYoff, srcZoff, srcMip);
+}
+
+static void
 nAllocationRead_i(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jintArray data)
 {
     jint len = _env->GetArrayLength(data);
@@ -782,13 +848,6 @@
     rsAllocationResize1D(con, (RsAllocation)alloc, dimX);
 }
 
-static void
-nAllocationResize2D(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint dimX, jint dimY)
-{
-    LOG_API("nAllocationResize1D, con(%p), alloc(%p), sizeX(%i), sizeY(%i)", con, (RsAllocation)alloc, dimX, dimY);
-    rsAllocationResize2D(con, (RsAllocation)alloc, dimX, dimY);
-}
-
 // -----------------------------------
 
 static int
@@ -1519,13 +1578,17 @@
 {"rsnAllocationData2D",              "(IIIIIIII[BI)V",                        (void*)nAllocationData2D_b },
 {"rsnAllocationData2D",              "(IIIIIIII[FI)V",                        (void*)nAllocationData2D_f },
 {"rsnAllocationData2D",              "(IIIIIIIIIIIII)V",                      (void*)nAllocationData2D_alloc },
+{"rsnAllocationData3D",              "(IIIIIIIII[II)V",                       (void*)nAllocationData3D_i },
+{"rsnAllocationData3D",              "(IIIIIIIII[SI)V",                       (void*)nAllocationData3D_s },
+{"rsnAllocationData3D",              "(IIIIIIIII[BI)V",                       (void*)nAllocationData3D_b },
+{"rsnAllocationData3D",              "(IIIIIIIII[FI)V",                       (void*)nAllocationData3D_f },
+{"rsnAllocationData3D",              "(IIIIIIIIIIIIII)V",                     (void*)nAllocationData3D_alloc },
 {"rsnAllocationRead",                "(II[I)V",                               (void*)nAllocationRead_i },
 {"rsnAllocationRead",                "(II[S)V",                               (void*)nAllocationRead_s },
 {"rsnAllocationRead",                "(II[B)V",                               (void*)nAllocationRead_b },
 {"rsnAllocationRead",                "(II[F)V",                               (void*)nAllocationRead_f },
 {"rsnAllocationGetType",             "(II)I",                                 (void*)nAllocationGetType},
 {"rsnAllocationResize1D",            "(III)V",                                (void*)nAllocationResize1D },
-{"rsnAllocationResize2D",            "(IIII)V",                               (void*)nAllocationResize2D },
 {"rsnAllocationGenerateMipmaps",     "(II)V",                                 (void*)nAllocationGenerateMipmaps },
 
 {"rsnScriptBindAllocation",          "(IIII)V",                               (void*)nScriptBindAllocation },
diff --git a/libs/hwui/Android.mk b/libs/hwui/Android.mk
index 06e658d..7b59bf2 100644
--- a/libs/hwui/Android.mk
+++ b/libs/hwui/Android.mk
@@ -58,7 +58,7 @@
 
 	LOCAL_CFLAGS += -DUSE_OPENGL_RENDERER -DGL_GLEXT_PROTOTYPES
 	LOCAL_MODULE_CLASS := SHARED_LIBRARIES
-	LOCAL_SHARED_LIBRARIES := libcutils libutils libGLESv2 libskia libui libRS libRScpp
+	LOCAL_SHARED_LIBRARIES := liblog libcutils libutils libGLESv2 libskia libui libRS libRScpp
 	LOCAL_MODULE := libhwui
 	LOCAL_MODULE_TAGS := optional
 
diff --git a/libs/hwui/Dither.cpp b/libs/hwui/Dither.cpp
index 9bc5c14..51f1e39 100644
--- a/libs/hwui/Dither.cpp
+++ b/libs/hwui/Dither.cpp
@@ -38,6 +38,10 @@
         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
 
         if (useFloatTexture) {
+            // We use a R16F texture, let's remap the alpha channel to the
+            // red channel to avoid changing the shader sampling code on GL ES 3.0+
+            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_RED);
+
             float dither = 1.0f / (255.0f * DITHER_KERNEL_SIZE * DITHER_KERNEL_SIZE);
             const GLfloat pattern[] = {
                  0 * dither,  8 * dither,  2 * dither, 10 * dither,
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 3730017..e18d922 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -1905,14 +1905,15 @@
 
 status_t OpenGLRenderer::drawDisplayList(DisplayList* displayList, Rect& dirty,
         int32_t replayFlags) {
+    status_t status;
     // All the usual checks and setup operations (quickReject, setupDraw, etc.)
     // will be performed by the display list itself
     if (displayList && displayList->isRenderable()) {
         if (CC_UNLIKELY(mCaches.drawDeferDisabled)) {
-            startFrame();
+            status = startFrame();
             ReplayStateStruct replayStruct(*this, dirty, replayFlags);
             displayList->replay(replayStruct, 0);
-            return replayStruct.mDrawGlStatus;
+            return status | replayStruct.mDrawGlStatus;
         }
 
         DeferredDisplayList deferredList;
@@ -1920,9 +1921,9 @@
         displayList->defer(deferStruct, 0);
 
         flushLayers();
-        startFrame();
+        status = startFrame();
 
-        return deferredList.flush(*this, dirty);
+        return status | deferredList.flush(*this, dirty);
     }
 
     return DrawGlInfo::kStatusDone;
diff --git a/libs/hwui/ProgramCache.cpp b/libs/hwui/ProgramCache.cpp
index 2479630..8eb85e5 100644
--- a/libs/hwui/ProgramCache.cpp
+++ b/libs/hwui/ProgramCache.cpp
@@ -186,7 +186,7 @@
         // ES 2.0
         "texture2D(ditherSampler, ditherTexCoords).a * " STR(DITHER_KERNEL_SIZE_INV_SQUARE),
         // ES 3.0
-        "texture2D(ditherSampler, ditherTexCoords).r"
+        "texture2D(ditherSampler, ditherTexCoords).a"
 };
 const char* gFS_Main_AddDitherToGradient =
         "    gradientColor += %s;\n";
diff --git a/location/java/android/location/IGeofenceProvider.aidl b/location/java/android/location/IGeofenceProvider.aidl
new file mode 100644
index 0000000..5a5fdc6
--- /dev/null
+++ b/location/java/android/location/IGeofenceProvider.aidl
@@ -0,0 +1,28 @@
+/*
+ * 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 android.location;
+
+import android.hardware.location.IGeofenceHardware;
+
+/**
+ * An interface for location providers implementing the Geofencing service
+ *
+ * {@hide}
+ */
+interface IGeofenceProvider {
+    void setGeofenceHardware(in IGeofenceHardware proxy);
+}
diff --git a/location/java/android/location/IGpsGeofenceHardware.aidl b/location/java/android/location/IGpsGeofenceHardware.aidl
new file mode 100644
index 0000000..764bf8e
--- /dev/null
+++ b/location/java/android/location/IGpsGeofenceHardware.aidl
@@ -0,0 +1,33 @@
+/*
+ * 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 android.location;
+
+/**
+ * GPS hardware geofence
+ *
+ * @hide
+ */
+interface IGpsGeofenceHardware
+{
+    boolean isHardwareGeofenceSupported();
+    boolean addCircularHardwareGeofence(int geofenceId, double latitude, double
+            longitude, double radius, int lastTransition, int monitorTransition,
+            int notificationResponsiveness, int unknownTimer);
+    boolean removeHardwareGeofence(int geofenceId);
+    boolean pauseHardwareGeofence(int geofenceId);
+    boolean resumeHardwareGeofence(int geofenceId, int monitorTransition);
+}
diff --git a/location/lib/java/com/android/location/provider/GeofenceProvider.java b/location/lib/java/com/android/location/provider/GeofenceProvider.java
new file mode 100644
index 0000000..2618f34
--- /dev/null
+++ b/location/lib/java/com/android/location/provider/GeofenceProvider.java
@@ -0,0 +1,67 @@
+/*
+ * 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.location.provider;
+
+import android.hardware.location.GeofenceHardware;
+import android.hardware.location.IGeofenceHardware;
+import android.os.IBinder;
+
+import android.location.IGeofenceProvider;
+import android.util.Log;
+
+import java.lang.Long;
+
+/**
+ * Base class for geofence providers implemented as unbundled services.
+ *
+ * <p>Geofence providers can be implemented as services and return the result of
+ * {@link com.android.location.provider.GeofenceProvider#getBinder()} in its getBinder() method.
+ *
+ * <p>IMPORTANT: This class is effectively a public API for unbundled
+ * applications, and must remain API stable. See README.txt in the root
+ * of this package for more information.
+ */
+public abstract class GeofenceProvider {
+
+    private GeofenceHardware mGeofenceHardware;
+
+    private IGeofenceProvider.Stub mProvider = new IGeofenceProvider.Stub() {
+        public void setGeofenceHardware(IGeofenceHardware hardwareProxy) {
+            mGeofenceHardware = new GeofenceHardware(hardwareProxy);
+            onGeofenceHardwareChange(mGeofenceHardware);
+        }
+    };
+
+    /**
+     * Returns the Binder interface for the geofence provider.
+     * This is intended to be used for the onBind() method of
+     * a service that implements a geofence service.
+     *
+     * @return the IBinder instance for the provider
+     */
+    public IBinder getBinder() {
+        return mProvider;
+    }
+
+    /**
+     * Called when GeofenceHardware object becomes available.
+     *
+     * @param geofenceHardware Geofence Hardware object. This can be null
+     *        when for some reason the service connection gets disconnected.
+     */
+    public abstract void onGeofenceHardwareChange(GeofenceHardware geofenceHardware);
+}
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index 773d7b6..637ac85 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -3534,6 +3534,9 @@
                     onNewPlaybackStateForRcc(msg.arg1 /* rccId */, msg.arg2 /* state */,
                             (RccPlaybackState)msg.obj /* newState */);
                     break;
+                case MSG_RCC_SEEK_REQUEST:
+                    onSetRemoteControlClientPlaybackPosition(msg.arg1 /* generationId */,
+                            ((Long)msg.obj).longValue() /* timeMs */);
 
                 case MSG_SET_RSX_CONNECTION_STATE:
                     onSetRsxConnectionState(msg.arg1/*available*/, msg.arg2/*address*/);
@@ -5867,7 +5870,16 @@
     }
 
     public void setRemoteControlClientPlaybackPosition(int generationId, long timeMs) {
-        sendMsg(mAudioHandler, MSG_RCC_SEEK_REQUEST, SENDMSG_QUEUE, generationId /* arg1 */,
+        // ignore position change requests if invalid generation ID
+        synchronized(mRCStack) {
+            synchronized(mCurrentRcLock) {
+                if (mCurrentRcClientGen != generationId) {
+                    return;
+                }
+            }
+        }
+        // discard any unprocessed seek request in the message queue, and replace with latest
+        sendMsg(mAudioHandler, MSG_RCC_SEEK_REQUEST, SENDMSG_REPLACE, generationId /* arg1 */,
                 0 /* arg2 ignored*/, new Long(timeMs) /* obj */, 0 /* delay */);
     }
 
diff --git a/media/java/android/media/MediaRouter.java b/media/java/android/media/MediaRouter.java
index 795c3c2..61c55a5 100644
--- a/media/java/android/media/MediaRouter.java
+++ b/media/java/android/media/MediaRouter.java
@@ -767,10 +767,19 @@
         boolean wantScan = false;
         boolean blockScan = false;
         WifiDisplay[] oldDisplays = oldStatus != null ?
-                oldStatus.getRememberedDisplays() : new WifiDisplay[0];
-        WifiDisplay[] newDisplays = newStatus.getRememberedDisplays();
-        WifiDisplay[] availableDisplays = newStatus.getAvailableDisplays();
-        WifiDisplay activeDisplay = newStatus.getActiveDisplay();
+                oldStatus.getRememberedDisplays() : WifiDisplay.EMPTY_ARRAY;
+        WifiDisplay[] newDisplays;
+        WifiDisplay[] availableDisplays;
+        WifiDisplay activeDisplay;
+
+        if (newStatus.getFeatureState() == WifiDisplayStatus.FEATURE_STATE_ON) {
+            newDisplays = newStatus.getRememberedDisplays();
+            availableDisplays = newStatus.getAvailableDisplays();
+            activeDisplay = newStatus.getActiveDisplay();
+        } else {
+            newDisplays = availableDisplays = WifiDisplay.EMPTY_ARRAY;
+            activeDisplay = null;
+        }
 
         for (int i = 0; i < newDisplays.length; i++) {
             final WifiDisplay d = newDisplays[i];
diff --git a/media/java/android/media/RemoteControlClient.java b/media/java/android/media/RemoteControlClient.java
index e076ef0..93bcf03 100644
--- a/media/java/android/media/RemoteControlClient.java
+++ b/media/java/android/media/RemoteControlClient.java
@@ -683,9 +683,12 @@
         /**
          * Called on the implementer to notify it that the playback head should be set at the given
          * position. If the position can be changed from its current value, the implementor of
-         * the interface should also update the playback position using
+         * the interface must also update the playback position using
          * {@link RemoteControlClient#setPlaybackState(int, long, int)} to reflect the actual new
          * position being used, regardless of whether it differs from the requested position.
+         * Failure to do so would cause the system to not know the new actual playback position,
+         * and user interface components would fail to show the user where playback resumed after
+         * the position was updated.
          * @param newPositionMs the new requested position in the current media, expressed in ms.
          */
         void onPlaybackPositionUpdate(long newPositionMs);
diff --git a/media/jni/Android.mk b/media/jni/Android.mk
index 6873060..416a2a1 100644
--- a/media/jni/Android.mk
+++ b/media/jni/Android.mk
@@ -28,6 +28,7 @@
     libmedia \
     libskia \
     libui \
+    liblog \
     libcutils \
     libgui \
     libstagefright \
diff --git a/media/jni/audioeffect/Android.mk b/media/jni/audioeffect/Android.mk
index b5d8b7b..3b1fb19 100644
--- a/media/jni/audioeffect/Android.mk
+++ b/media/jni/audioeffect/Android.mk
@@ -6,6 +6,7 @@
 	android_media_Visualizer.cpp
 
 LOCAL_SHARED_LIBRARIES := \
+	liblog \
 	libcutils \
 	libutils \
 	libandroid_runtime \
diff --git a/media/jni/mediaeditor/Android.mk b/media/jni/mediaeditor/Android.mk
index 040d2ab..6be7fdd 100644
--- a/media/jni/mediaeditor/Android.mk
+++ b/media/jni/mediaeditor/Android.mk
@@ -52,6 +52,7 @@
     libaudioutils \
     libbinder \
     libcutils \
+    liblog \
     libdl \
     libgui \
     libmedia \
diff --git a/media/jni/soundpool/Android.mk b/media/jni/soundpool/Android.mk
index 9b11bfa..5835b9f 100644
--- a/media/jni/soundpool/Android.mk
+++ b/media/jni/soundpool/Android.mk
@@ -5,6 +5,7 @@
 	android_media_SoundPool.cpp
 
 LOCAL_SHARED_LIBRARIES := \
+	liblog \
 	libcutils \
 	libutils \
 	libandroid_runtime \
diff --git a/media/libdrm/mobile1/Android.mk b/media/libdrm/mobile1/Android.mk
index b07d91c..7356f46 100644
--- a/media/libdrm/mobile1/Android.mk
+++ b/media/libdrm/mobile1/Android.mk
@@ -44,6 +44,7 @@
 LOCAL_SHARED_LIBRARIES :=   \
     libutils                \
     libcutils               \
+    liblog                  \
     libcrypto
 
 LOCAL_MODULE := libdrm1
@@ -69,12 +70,13 @@
     $(LOCAL_PATH)/include/parser \
     $(JNI_H_INCLUDE)    \
     $(call include-path-for, system-core)/cutils
-	
+
 
 LOCAL_SHARED_LIBRARIES := libdrm1 \
     libnativehelper               \
     libutils                      \
-    libcutils
+    libcutils                     \
+    liblog
 
 LOCAL_MODULE := libdrm1_jni
 
diff --git a/media/mca/filterfw/Android.mk b/media/mca/filterfw/Android.mk
index 1d69799..2a9448d 100644
--- a/media/mca/filterfw/Android.mk
+++ b/media/mca/filterfw/Android.mk
@@ -37,6 +37,7 @@
                           libdl \
                           libcutils \
                           libutils \
+                          liblog \
                           libandroid \
                           libjnigraphics \
                           libmedia
@@ -48,5 +49,3 @@
 LOCAL_PRELINK_MODULE := false
 
 include $(BUILD_SHARED_LIBRARY)
-
-
diff --git a/media/mca/filterpacks/Android.mk b/media/mca/filterpacks/Android.mk
index 6166b1e..6e54f60 100644
--- a/media/mca/filterpacks/Android.mk
+++ b/media/mca/filterpacks/Android.mk
@@ -46,10 +46,8 @@
                    native/imageproc/invert.c \
                    native/imageproc/to_rgba.c
 
-LOCAL_SHARED_LIBRARIES := libutils libfilterfw
+LOCAL_SHARED_LIBRARIES := liblog libutils libfilterfw
 
 LOCAL_PRELINK_MODULE := false
 
 include $(BUILD_SHARED_LIBRARY)
-
-
diff --git a/media/tests/omxjpegdecoder/Android.mk b/media/tests/omxjpegdecoder/Android.mk
index 9dcc7ba..ad874c8 100644
--- a/media/tests/omxjpegdecoder/Android.mk
+++ b/media/tests/omxjpegdecoder/Android.mk
@@ -29,6 +29,7 @@
     libstagefright_foundation \
     libbinder \
     libutils \
+    liblog \
     libjpeg
 
 LOCAL_C_INCLUDES := \
diff --git a/media/tests/players/Android.mk b/media/tests/players/Android.mk
index c655ae6..adf0d30 100644
--- a/media/tests/players/Android.mk
+++ b/media/tests/players/Android.mk
@@ -20,7 +20,8 @@
 
 LOCAL_SHARED_LIBRARIES:= \
     libbinder \
-    libutils
+    libutils \
+    liblog
 
 LOCAL_MODULE:= invoke_mock_media_player
 LOCAL_MODULE_TAGS := tests eng
diff --git a/native/android/Android.mk b/native/android/Android.mk
index 00d11da..207cc4b 100644
--- a/native/android/Android.mk
+++ b/native/android/Android.mk
@@ -17,6 +17,7 @@
     storage_manager.cpp
 
 LOCAL_SHARED_LIBRARIES := \
+    liblog \
     libcutils \
     libandroidfw \
     libutils \
diff --git a/opengl/java/android/opengl/GLSurfaceView.java b/opengl/java/android/opengl/GLSurfaceView.java
index 5a2e261..ab7ceb6 100644
--- a/opengl/java/android/opengl/GLSurfaceView.java
+++ b/opengl/java/android/opengl/GLSurfaceView.java
@@ -18,7 +18,6 @@
 
 import java.io.Writer;
 import java.lang.ref.WeakReference;
-import java.util.ArrayList;
 
 import javax.microedition.khronos.egl.EGL10;
 import javax.microedition.khronos.egl.EGL11;
@@ -30,10 +29,13 @@
 import javax.microedition.khronos.opengles.GL10;
 
 import android.content.Context;
-import android.content.pm.ConfigurationInfo;
-import android.os.SystemProperties;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Looper;
+import android.os.Trace;
 import android.util.AttributeSet;
 import android.util.Log;
+import android.view.Choreographer;
 import android.view.SurfaceHolder;
 import android.view.SurfaceView;
 
@@ -164,11 +166,26 @@
     private final static String TAG = "GLSurfaceView";
     private final static boolean LOG_ATTACH_DETACH = false;
     private final static boolean LOG_THREADS = false;
-    private final static boolean LOG_PAUSE_RESUME = false;
     private final static boolean LOG_SURFACE = false;
     private final static boolean LOG_RENDERER = false;
     private final static boolean LOG_RENDERER_DRAW_FRAME = false;
     private final static boolean LOG_EGL = false;
+    private final static boolean TRACE_ENABLED = false;
+
+    private final WeakReference<GLSurfaceView> mThisWeakRef =
+            new WeakReference<GLSurfaceView>(this);
+    private GLThread mGLThread;
+    private Renderer mRenderer;
+    private boolean mDetached;
+    private EGLConfigChooser mEGLConfigChooser;
+    private EGLContextFactory mEGLContextFactory;
+    private EGLWindowSurfaceFactory mEGLWindowSurfaceFactory;
+    private GLWrapper mGLWrapper;
+    private int mDebugFlags;
+    private int mEGLContextClientVersion;
+    private boolean mPreserveEGLContextOnPause;
+    private int mUserRenderMode;
+
     /**
      * The renderer only renders
      * when the surface is created, or when {@link #requestRender} is called.
@@ -241,13 +258,7 @@
         // underlying surface is created and destroyed
         SurfaceHolder holder = getHolder();
         holder.addCallback(this);
-        // setFormat is done by SurfaceView in SDK 2.3 and newer. Uncomment
-        // this statement if back-porting to 2.2 or older:
-        // holder.setFormat(PixelFormat.RGB_565);
-        //
-        // setType is not needed for SDK 2.0 or newer. Uncomment this
-        // statement if back-porting this code to older SDKs.
-        // holder.setType(SurfaceHolder.SURFACE_TYPE_GPU);
+        mUserRenderMode = RENDERMODE_CONTINUOUSLY;
     }
 
     /**
@@ -346,15 +357,16 @@
     public void setRenderer(Renderer renderer) {
         checkRenderThreadState();
         if (mEGLConfigChooser == null) {
-            mEGLConfigChooser = new SimpleEGLConfigChooser(true);
+            mEGLConfigChooser = new SimpleEGLConfigChooser(true, mEGLContextClientVersion);
         }
         if (mEGLContextFactory == null) {
-            mEGLContextFactory = new DefaultContextFactory();
+            mEGLContextFactory = new DefaultContextFactory(mEGLContextClientVersion);
         }
         if (mEGLWindowSurfaceFactory == null) {
             mEGLWindowSurfaceFactory = new DefaultWindowSurfaceFactory();
         }
         mRenderer = renderer;
+
         mGLThread = new GLThread(mThisWeakRef);
         mGLThread.start();
     }
@@ -420,7 +432,7 @@
      * @param needDepth
      */
     public void setEGLConfigChooser(boolean needDepth) {
-        setEGLConfigChooser(new SimpleEGLConfigChooser(needDepth));
+        setEGLConfigChooser(new SimpleEGLConfigChooser(needDepth, mEGLContextClientVersion));
     }
 
     /**
@@ -439,7 +451,7 @@
     public void setEGLConfigChooser(int redSize, int greenSize, int blueSize,
             int alphaSize, int depthSize, int stencilSize) {
         setEGLConfigChooser(new ComponentSizeChooser(redSize, greenSize,
-                blueSize, alphaSize, depthSize, stencilSize));
+                blueSize, alphaSize, depthSize, stencilSize, mEGLContextClientVersion));
     }
 
     /**
@@ -466,6 +478,13 @@
      * If
      * {@link #setEGLConfigChooser(EGLConfigChooser)} has been called, then the supplied
      * EGLConfigChooser is responsible for choosing an OpenGL ES 2.0-compatible config.
+     *
+     * This method must be called before:
+     * <ul>
+     * <li>{@link #setEGLConfigChooser(boolean)}
+     * <li>{@link #setEGLConfigChooser(int, int, int, int, int, int)}
+     * </ul>
+     *
      * @param version The EGLContext client version to choose. Use 2 for OpenGL ES 2.0
      */
     public void setEGLContextClientVersion(int version) {
@@ -490,6 +509,14 @@
      * @see #RENDERMODE_WHEN_DIRTY
      */
     public void setRenderMode(int renderMode) {
+        switch (renderMode) {
+            case RENDERMODE_WHEN_DIRTY:
+            case RENDERMODE_CONTINUOUSLY:
+                break;
+            default:
+                throw new IllegalArgumentException("renderMode");
+        }
+        mUserRenderMode = renderMode;
         mGLThread.setRenderMode(renderMode);
     }
 
@@ -501,7 +528,7 @@
      * @see #RENDERMODE_WHEN_DIRTY
      */
     public int getRenderMode() {
-        return mGLThread.getRenderMode();
+        return mUserRenderMode;
     }
 
     /**
@@ -582,14 +609,8 @@
             Log.d(TAG, "onAttachedToWindow reattach =" + mDetached);
         }
         if (mDetached && (mRenderer != null)) {
-            int renderMode = RENDERMODE_CONTINUOUSLY;
-            if (mGLThread != null) {
-                renderMode = mGLThread.getRenderMode();
-            }
             mGLThread = new GLThread(mThisWeakRef);
-            if (renderMode != RENDERMODE_CONTINUOUSLY) {
-                mGLThread.setRenderMode(renderMode);
-            }
+            mGLThread.setRenderMode(mUserRenderMode);
             mGLThread.start();
         }
         mDetached = false;
@@ -761,11 +782,15 @@
         void destroyContext(EGL10 egl, EGLDisplay display, EGLContext context);
     }
 
-    private class DefaultContextFactory implements EGLContextFactory {
-        private int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
+    private static class DefaultContextFactory implements EGLContextFactory {
+        private final int mEGLContextClientVersion;
+
+        public DefaultContextFactory(int version) {
+            mEGLContextClientVersion = version;
+        }
 
         public EGLContext createContext(EGL10 egl, EGLDisplay display, EGLConfig config) {
-            int[] attrib_list = {EGL_CONTEXT_CLIENT_VERSION, mEGLContextClientVersion,
+            int[] attrib_list = {EGL14.EGL_CONTEXT_CLIENT_VERSION, mEGLContextClientVersion,
                     EGL10.EGL_NONE };
 
             return egl.eglCreateContext(display, config, EGL10.EGL_NO_CONTEXT,
@@ -775,9 +800,9 @@
         public void destroyContext(EGL10 egl, EGLDisplay display,
                 EGLContext context) {
             if (!egl.eglDestroyContext(display, context)) {
-                Log.e("DefaultContextFactory", "display:" + display + " context: " + context);
+                Log.e(TAG, "display:" + display + " context: " + context);
                 if (LOG_THREADS) {
-                    Log.i("DefaultContextFactory", "tid=" + Thread.currentThread().getId());
+                    Log.d(TAG, "tid=" + Thread.currentThread().getId());
                 }
                 EglHelper.throwEglException("eglDestroyContex", egl.eglGetError());
             }
@@ -807,8 +832,8 @@
             try {
                 result = egl.eglCreateWindowSurface(display, config, nativeWindow, null);
             } catch (IllegalArgumentException e) {
-                // This exception indicates that the surface flinger surface
-                // is not valid. This can happen if the surface flinger surface has
+                // This exception indicates that the surfaceflinger surface
+                // is not valid. This can happen if the surfaceflinger surface has
                 // been torn down, but the application has not yet been
                 // notified via SurfaceHolder.Callback.surfaceDestroyed.
                 // In theory the application should be notified first,
@@ -844,10 +869,11 @@
         EGLConfig chooseConfig(EGL10 egl, EGLDisplay display);
     }
 
-    private abstract class BaseConfigChooser
+    private static abstract class BaseConfigChooser
             implements EGLConfigChooser {
-        public BaseConfigChooser(int[] configSpec) {
-            mConfigSpec = filterConfigSpec(configSpec);
+
+        public BaseConfigChooser(int[] configSpec, int version) {
+            mConfigSpec = filterConfigSpec(configSpec, version);
         }
 
         public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) {
@@ -881,8 +907,8 @@
 
         protected int[] mConfigSpec;
 
-        private int[] filterConfigSpec(int[] configSpec) {
-            if (mEGLContextClientVersion != 2) {
+        private int[] filterConfigSpec(int[] configSpec, int version) {
+            if (version != 2) {
                 return configSpec;
             }
             /* We know none of the subclasses define EGL_RENDERABLE_TYPE.
@@ -892,7 +918,7 @@
             int[] newConfigSpec = new int[len + 2];
             System.arraycopy(configSpec, 0, newConfigSpec, 0, len-1);
             newConfigSpec[len-1] = EGL10.EGL_RENDERABLE_TYPE;
-            newConfigSpec[len] = 4; /* EGL_OPENGL_ES2_BIT */
+            newConfigSpec[len] = EGL14.EGL_OPENGL_ES2_BIT;
             newConfigSpec[len+1] = EGL10.EGL_NONE;
             return newConfigSpec;
         }
@@ -902,9 +928,9 @@
      * Choose a configuration with exactly the specified r,g,b,a sizes,
      * and at least the specified depth and stencil sizes.
      */
-    private class ComponentSizeChooser extends BaseConfigChooser {
+    private static class ComponentSizeChooser extends BaseConfigChooser {
         public ComponentSizeChooser(int redSize, int greenSize, int blueSize,
-                int alphaSize, int depthSize, int stencilSize) {
+                int alphaSize, int depthSize, int stencilSize, int version) {
             super(new int[] {
                     EGL10.EGL_RED_SIZE, redSize,
                     EGL10.EGL_GREEN_SIZE, greenSize,
@@ -912,7 +938,7 @@
                     EGL10.EGL_ALPHA_SIZE, alphaSize,
                     EGL10.EGL_DEPTH_SIZE, depthSize,
                     EGL10.EGL_STENCIL_SIZE, stencilSize,
-                    EGL10.EGL_NONE});
+                    EGL10.EGL_NONE}, version);
             mValue = new int[1];
             mRedSize = redSize;
             mGreenSize = greenSize;
@@ -920,7 +946,7 @@
             mAlphaSize = alphaSize;
             mDepthSize = depthSize;
             mStencilSize = stencilSize;
-       }
+        }
 
         @Override
         public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display,
@@ -931,14 +957,10 @@
                 int s = findConfigAttrib(egl, display, config,
                         EGL10.EGL_STENCIL_SIZE, 0);
                 if ((d >= mDepthSize) && (s >= mStencilSize)) {
-                    int r = findConfigAttrib(egl, display, config,
-                            EGL10.EGL_RED_SIZE, 0);
-                    int g = findConfigAttrib(egl, display, config,
-                             EGL10.EGL_GREEN_SIZE, 0);
-                    int b = findConfigAttrib(egl, display, config,
-                              EGL10.EGL_BLUE_SIZE, 0);
-                    int a = findConfigAttrib(egl, display, config,
-                            EGL10.EGL_ALPHA_SIZE, 0);
+                    int r = findConfigAttrib(egl, display, config, EGL10.EGL_RED_SIZE, 0);
+                    int g = findConfigAttrib(egl, display, config, EGL10.EGL_GREEN_SIZE, 0);
+                    int b = findConfigAttrib(egl, display, config, EGL10.EGL_BLUE_SIZE, 0);
+                    int a = findConfigAttrib(egl, display, config, EGL10.EGL_ALPHA_SIZE, 0);
                     if ((r == mRedSize) && (g == mGreenSize)
                             && (b == mBlueSize) && (a == mAlphaSize)) {
                         return config;
@@ -965,16 +987,16 @@
         protected int mAlphaSize;
         protected int mDepthSize;
         protected int mStencilSize;
-        }
+    }
 
     /**
      * This class will choose a RGB_888 surface with
      * or without a depth buffer.
      *
      */
-    private class SimpleEGLConfigChooser extends ComponentSizeChooser {
-        public SimpleEGLConfigChooser(boolean withDepthBuffer) {
-            super(8, 8, 8, 0, withDepthBuffer ? 16 : 0, 0);
+    private static class SimpleEGLConfigChooser extends ComponentSizeChooser {
+        public SimpleEGLConfigChooser(boolean withDepthBuffer, int version) {
+            super(8, 8, 8, 0, withDepthBuffer ? 16 : 0, 0, version);
         }
     }
 
@@ -991,9 +1013,9 @@
          * Initialize EGL for a given configuration spec.
          * @param configSpec
          */
-        public void start() {
+        public void initialize() {
             if (LOG_EGL) {
-                Log.w("EglHelper", "start() tid=" + Thread.currentThread().getId());
+                Log.d(TAG, "initialize() tid=" + Thread.currentThread().getId());
             }
             /*
              * Get an EGL instance
@@ -1034,7 +1056,7 @@
                 throwEglException("createContext");
             }
             if (LOG_EGL) {
-                Log.w("EglHelper", "createContext " + mEglContext + " tid=" + Thread.currentThread().getId());
+                Log.d(TAG, "createContext " + mEglContext + " tid=" + Thread.currentThread().getId());
             }
 
             mEglSurface = null;
@@ -1048,7 +1070,7 @@
          */
         public boolean createSurface() {
             if (LOG_EGL) {
-                Log.w("EglHelper", "createSurface()  tid=" + Thread.currentThread().getId());
+                Log.d(TAG, "createSurface()  tid=" + Thread.currentThread().getId());
             }
             /*
              * Check preconditions.
@@ -1083,7 +1105,7 @@
             if (mEglSurface == null || mEglSurface == EGL10.EGL_NO_SURFACE) {
                 int error = mEgl.eglGetError();
                 if (error == EGL10.EGL_BAD_NATIVE_WINDOW) {
-                    Log.e("EglHelper", "createWindowSurface returned EGL_BAD_NATIVE_WINDOW.");
+                    Log.e(TAG, "createWindowSurface returned EGL_BAD_NATIVE_WINDOW.");
                 }
                 return false;
             }
@@ -1097,8 +1119,9 @@
                  * Could not make the context current, probably because the underlying
                  * SurfaceView surface has been destroyed.
                  */
-                logEglErrorAsWarning("EGLHelper", "eglMakeCurrent", mEgl.eglGetError());
-                return false;
+                logEglErrorAsWarning(TAG, "eglMakeCurrent", mEgl.eglGetError());
+                // we fall-through to "true" here because we do have a
+                // valid EGLSurface at this point.
             }
 
             return true;
@@ -1108,8 +1131,7 @@
          * Create a GL object for the current EGL context.
          * @return
          */
-        GL createGL() {
-
+        public GL createGL() {
             GL gl = mEglContext.getGL();
             GLSurfaceView view = mGLSurfaceViewWeakRef.get();
             if (view != null) {
@@ -1145,7 +1167,7 @@
 
         public void destroySurface() {
             if (LOG_EGL) {
-                Log.w("EglHelper", "destroySurface()  tid=" + Thread.currentThread().getId());
+                Log.d(TAG, "destroySurface()  tid=" + Thread.currentThread().getId());
             }
             destroySurfaceImp();
         }
@@ -1163,9 +1185,9 @@
             }
         }
 
-        public void finish() {
+        public void terminate() {
             if (LOG_EGL) {
-                Log.w("EglHelper", "finish() tid=" + Thread.currentThread().getId());
+                Log.d(TAG, "terminate() tid=" + Thread.currentThread().getId());
             }
             if (mEglContext != null) {
                 GLSurfaceView view = mGLSurfaceViewWeakRef.get();
@@ -1187,7 +1209,7 @@
         public static void throwEglException(String function, int error) {
             String message = formatEglError(function, error);
             if (LOG_THREADS) {
-                Log.e("EglHelper", "throwEglException tid=" + Thread.currentThread().getId() + " "
+                Log.e(TAG, "throwEglException tid=" + Thread.currentThread().getId() + " "
                         + message);
             }
             throw new RuntimeException(message);
@@ -1207,584 +1229,411 @@
         EGLSurface mEglSurface;
         EGLConfig mEglConfig;
         EGLContext mEglContext;
-
     }
 
     /**
      * A generic GL Thread. Takes care of initializing EGL and GL. Delegates
      * to a Renderer instance to do the actual drawing. Can be configured to
      * render continuously or on request.
-     *
-     * All potentially blocking synchronization is done through the
-     * sGLThreadManager object. This avoids multiple-lock ordering issues.
-     *
      */
-    static class GLThread extends Thread {
-        GLThread(WeakReference<GLSurfaceView> glSurfaceViewWeakRef) {
-            super();
+
+    static class GLThread extends HandlerThread {
+        // only accessed from GLThread
+        private GL10 mGLContext;
+        private int mWidth;
+        private int mHeight;
+        private boolean mSizeChanged;
+        // current render mode
+        private int mRenderMode;
+        // the EGLSurface exists but isn't working for some reason
+        private boolean mEglSurfaceIsBad;
+        // we have an EGLContext
+        private boolean mHaveEglContext;
+        // we have an EGLSurface
+        private boolean mHaveEglSurface;
+        // we have a Surface (i.e.: EGLNativeWindowType)
+        private boolean mHasSurface;
+        // activity is paused
+        private boolean mPaused;
+
+        // constants
+        private EglHelper mEglHelper;
+        private Handler mGLHandler;
+        private Choreographer mChoreographer;
+
+        /*
+         * Set once at thread construction time, nulled out when the parent view is garbage
+         * called. This weak reference allows the GLSurfaceView to be garbage collected while
+         * the GLThread is still alive.
+         */
+        private final WeakReference<GLSurfaceView> mGLSurfaceViewWeakRef;
+
+        private final Runnable mExecuteDrawAction = new Runnable() {
+            private int mTraceVsyncCounter = 0;
+            @Override
+            public void run() {
+                if (TRACE_ENABLED) {
+                    Trace.traceCounter(Trace.TRACE_TAG_GRAPHICS,
+                            "GLSurfaceView VSYNC counter", (mTraceVsyncCounter++) & 0xf);
+                }
+                executeDraw();
+            }
+        };
+
+        public GLThread(WeakReference<GLSurfaceView> glSurfaceViewWeakRef) {
+            super("GLThread", android.os.Process.THREAD_PRIORITY_DISPLAY);
+            if (LOG_THREADS) {
+                Log.d(TAG, "*** Starting GLThread ***");
+            }
             mWidth = 0;
             mHeight = 0;
-            mRequestRender = true;
             mRenderMode = RENDERMODE_CONTINUOUSLY;
             mGLSurfaceViewWeakRef = glSurfaceViewWeakRef;
         }
 
+        private void readyToRun() {
+            mChoreographer = Choreographer.getInstance();
+            mEglHelper = new EglHelper(mGLSurfaceViewWeakRef);
+        }
+
+        @Override
+        public void start() {
+            super.start();
+            // getLooper() blocks until the thread is running
+            Looper looper = getLooper();
+            mGLHandler = new Handler(looper);
+            // don't return until the GLThread state has been initialized
+            mGLHandler.runWithScissors(new Runnable() {
+                @Override
+                public void run() {
+                    readyToRun();
+                }
+            }, 0);
+        }
+
         @Override
         public void run() {
-            setName("GLThread " + getId());
-            if (LOG_THREADS) {
-                Log.i("GLThread", "starting tid=" + getId());
-            }
-
             try {
-                guardedRun();
-            } catch (InterruptedException e) {
-                // fall thru and exit normally
+                super.run();
             } finally {
-                sGLThreadManager.threadExiting(this);
+                // by definition the GLThread is not running anymore here
+                stopEglContext();
+                stopEglSurface();
             }
         }
 
-        /*
-         * This private method should only be called inside a
-         * synchronized(sGLThreadManager) block.
-         */
-        private void stopEglSurfaceLocked() {
+        // only call from the GLThread
+        private void stopEglSurface() {
             if (mHaveEglSurface) {
+                if (LOG_SURFACE) {
+                    Log.d(TAG, "releasing EGL surface because paused tid=" + getId());
+                }
                 mHaveEglSurface = false;
                 mEglHelper.destroySurface();
             }
         }
 
-        /*
-         * This private method should only be called inside a
-         * synchronized(sGLThreadManager) block.
-         */
-        private void stopEglContextLocked() {
+        // only call from the GLThread
+        private void stopEglContext() {
             if (mHaveEglContext) {
-                mEglHelper.finish();
+                mEglHelper.terminate();
                 mHaveEglContext = false;
-                sGLThreadManager.releaseEglContextLocked(this);
+                if (LOG_SURFACE) {
+                    Log.d(TAG, "releasing EGL context because paused tid=" + getId());
+                }
             }
         }
-        private void guardedRun() throws InterruptedException {
-            mEglHelper = new EglHelper(mGLSurfaceViewWeakRef);
-            mHaveEglContext = false;
-            mHaveEglSurface = false;
-            try {
-                GL10 gl = null;
-                boolean createEglContext = false;
-                boolean createEglSurface = false;
-                boolean createGlInterface = false;
-                boolean lostEglContext = false;
-                boolean sizeChanged = false;
-                boolean wantRenderNotification = false;
-                boolean doRenderNotification = false;
-                boolean askedToReleaseEglContext = false;
-                int w = 0;
-                int h = 0;
-                Runnable event = null;
 
-                while (true) {
-                    synchronized (sGLThreadManager) {
-                        while (true) {
-                            if (mShouldExit) {
-                                return;
-                            }
+        private void updateState() {
+            final boolean wasAbleToDraw = isAbleToDraw();
+            if (!isReadyToDraw()) {
+                return;
+            }
 
-                            if (! mEventQueue.isEmpty()) {
-                                event = mEventQueue.remove(0);
-                                break;
-                            }
+            if (!mHaveEglSurface || mSizeChanged) {
+                // create EGL context if needed
+                boolean reportSurfaceCreated = false;
+                if (!mHaveEglContext) {
+                    mEglHelper.initialize();
+                    mHaveEglContext = true;
+                    reportSurfaceCreated = true;
+                }
 
-                            // Update the pause state.
-                            boolean pausing = false;
-                            if (mPaused != mRequestPaused) {
-                                pausing = mRequestPaused;
-                                mPaused = mRequestPaused;
-                                sGLThreadManager.notifyAll();
-                                if (LOG_PAUSE_RESUME) {
-                                    Log.i("GLThread", "mPaused is now " + mPaused + " tid=" + getId());
-                                }
-                            }
+                // get the GL interface for the active EGLContext
+                mGLContext = (GL10)mEglHelper.createGL();
 
-                            // Do we need to give up the EGL context?
-                            if (mShouldReleaseEglContext) {
-                                if (LOG_SURFACE) {
-                                    Log.i("GLThread", "releasing EGL context because asked to tid=" + getId());
-                                }
-                                stopEglSurfaceLocked();
-                                stopEglContextLocked();
-                                mShouldReleaseEglContext = false;
-                                askedToReleaseEglContext = true;
-                            }
+                // create EGL Surface
+                mHaveEglSurface = mEglHelper.createSurface();
+                mEglSurfaceIsBad = !mHaveEglSurface;
+                mSizeChanged = false;
 
-                            // Have we lost the EGL context?
-                            if (lostEglContext) {
-                                stopEglSurfaceLocked();
-                                stopEglContextLocked();
-                                lostEglContext = false;
-                            }
-
-                            // When pausing, release the EGL surface:
-                            if (pausing && mHaveEglSurface) {
-                                if (LOG_SURFACE) {
-                                    Log.i("GLThread", "releasing EGL surface because paused tid=" + getId());
-                                }
-                                stopEglSurfaceLocked();
-                            }
-
-                            // When pausing, optionally release the EGL Context:
-                            if (pausing && mHaveEglContext) {
-                                GLSurfaceView view = mGLSurfaceViewWeakRef.get();
-                                boolean preserveEglContextOnPause = view == null ?
-                                        false : view.mPreserveEGLContextOnPause;
-                                if (!preserveEglContextOnPause || sGLThreadManager.shouldReleaseEGLContextWhenPausing()) {
-                                    stopEglContextLocked();
-                                    if (LOG_SURFACE) {
-                                        Log.i("GLThread", "releasing EGL context because paused tid=" + getId());
-                                    }
-                                }
-                            }
-
-                            // When pausing, optionally terminate EGL:
-                            if (pausing) {
-                                if (sGLThreadManager.shouldTerminateEGLWhenPausing()) {
-                                    mEglHelper.finish();
-                                    if (LOG_SURFACE) {
-                                        Log.i("GLThread", "terminating EGL because paused tid=" + getId());
-                                    }
-                                }
-                            }
-
-                            // Have we lost the SurfaceView surface?
-                            if ((! mHasSurface) && (! mWaitingForSurface)) {
-                                if (LOG_SURFACE) {
-                                    Log.i("GLThread", "noticed surfaceView surface lost tid=" + getId());
-                                }
-                                if (mHaveEglSurface) {
-                                    stopEglSurfaceLocked();
-                                }
-                                mWaitingForSurface = true;
-                                mSurfaceIsBad = false;
-                                sGLThreadManager.notifyAll();
-                            }
-
-                            // Have we acquired the surface view surface?
-                            if (mHasSurface && mWaitingForSurface) {
-                                if (LOG_SURFACE) {
-                                    Log.i("GLThread", "noticed surfaceView surface acquired tid=" + getId());
-                                }
-                                mWaitingForSurface = false;
-                                sGLThreadManager.notifyAll();
-                            }
-
-                            if (doRenderNotification) {
-                                if (LOG_SURFACE) {
-                                    Log.i("GLThread", "sending render notification tid=" + getId());
-                                }
-                                wantRenderNotification = false;
-                                doRenderNotification = false;
-                                mRenderComplete = true;
-                                sGLThreadManager.notifyAll();
-                            }
-
-                            // Ready to draw?
-                            if (readyToDraw()) {
-
-                                // If we don't have an EGL context, try to acquire one.
-                                if (! mHaveEglContext) {
-                                    if (askedToReleaseEglContext) {
-                                        askedToReleaseEglContext = false;
-                                    } else if (sGLThreadManager.tryAcquireEglContextLocked(this)) {
-                                        try {
-                                            mEglHelper.start();
-                                        } catch (RuntimeException t) {
-                                            sGLThreadManager.releaseEglContextLocked(this);
-                                            throw t;
-                                        }
-                                        mHaveEglContext = true;
-                                        createEglContext = true;
-
-                                        sGLThreadManager.notifyAll();
-                                    }
-                                }
-
-                                if (mHaveEglContext && !mHaveEglSurface) {
-                                    mHaveEglSurface = true;
-                                    createEglSurface = true;
-                                    createGlInterface = true;
-                                    sizeChanged = true;
-                                }
-
-                                if (mHaveEglSurface) {
-                                    if (mSizeChanged) {
-                                        sizeChanged = true;
-                                        w = mWidth;
-                                        h = mHeight;
-                                        wantRenderNotification = true;
-                                        if (LOG_SURFACE) {
-                                            Log.i("GLThread",
-                                                    "noticing that we want render notification tid="
-                                                    + getId());
-                                        }
-
-                                        // Destroy and recreate the EGL surface.
-                                        createEglSurface = true;
-
-                                        mSizeChanged = false;
-                                    }
-                                    mRequestRender = false;
-                                    sGLThreadManager.notifyAll();
-                                    break;
-                                }
-                            }
-
-                            // By design, this is the only place in a GLThread thread where we wait().
-                            if (LOG_THREADS) {
-                                Log.i("GLThread", "waiting tid=" + getId()
-                                    + " mHaveEglContext: " + mHaveEglContext
-                                    + " mHaveEglSurface: " + mHaveEglSurface
-                                    + " mFinishedCreatingEglSurface: " + mFinishedCreatingEglSurface
-                                    + " mPaused: " + mPaused
-                                    + " mHasSurface: " + mHasSurface
-                                    + " mSurfaceIsBad: " + mSurfaceIsBad
-                                    + " mWaitingForSurface: " + mWaitingForSurface
-                                    + " mWidth: " + mWidth
-                                    + " mHeight: " + mHeight
-                                    + " mRequestRender: " + mRequestRender
-                                    + " mRenderMode: " + mRenderMode);
-                            }
-                            sGLThreadManager.wait();
-                        }
-                    } // end of synchronized(sGLThreadManager)
-
-                    if (event != null) {
-                        event.run();
-                        event = null;
-                        continue;
-                    }
-
-                    if (createEglSurface) {
-                        if (LOG_SURFACE) {
-                            Log.w("GLThread", "egl createSurface");
-                        }
-                        if (mEglHelper.createSurface()) {
-                            synchronized(sGLThreadManager) {
-                                mFinishedCreatingEglSurface = true;
-                                sGLThreadManager.notifyAll();
-                            }
-                        } else {
-                            synchronized(sGLThreadManager) {
-                                mFinishedCreatingEglSurface = true;
-                                mSurfaceIsBad = true;
-                                sGLThreadManager.notifyAll();
-                            }
-                            continue;
-                        }
-                        createEglSurface = false;
-                    }
-
-                    if (createGlInterface) {
-                        gl = (GL10) mEglHelper.createGL();
-
-                        sGLThreadManager.checkGLDriver(gl);
-                        createGlInterface = false;
-                    }
-
-                    if (createEglContext) {
+                // notify use of surface size change
+                GLSurfaceView view = mGLSurfaceViewWeakRef.get();
+                if (view != null) {
+                    if (reportSurfaceCreated) {
                         if (LOG_RENDERER) {
-                            Log.w("GLThread", "onSurfaceCreated");
+                            Log.d(TAG, "onSurfaceCreated");
                         }
-                        GLSurfaceView view = mGLSurfaceViewWeakRef.get();
-                        if (view != null) {
-                            view.mRenderer.onSurfaceCreated(gl, mEglHelper.mEglConfig);
-                        }
-                        createEglContext = false;
+                        view.mRenderer.onSurfaceCreated(mGLContext, mEglHelper.mEglConfig);
                     }
 
-                    if (sizeChanged) {
-                        if (LOG_RENDERER) {
-                            Log.w("GLThread", "onSurfaceChanged(" + w + ", " + h + ")");
-                        }
-                        GLSurfaceView view = mGLSurfaceViewWeakRef.get();
-                        if (view != null) {
-                            view.mRenderer.onSurfaceChanged(gl, w, h);
-                        }
-                        sizeChanged = false;
+                    if (LOG_RENDERER) {
+                        Log.d(TAG, "onSurfaceChanged(" + mWidth + ", " + mHeight + ")");
                     }
+                    view.mRenderer.onSurfaceChanged(mGLContext, mWidth, mHeight);
+                }
+            }
 
-                    if (LOG_RENDERER_DRAW_FRAME) {
-                        Log.w("GLThread", "onDrawFrame tid=" + getId());
-                    }
-                    {
-                        GLSurfaceView view = mGLSurfaceViewWeakRef.get();
-                        if (view != null) {
-                            view.mRenderer.onDrawFrame(gl);
-                        }
-                    }
+            // see if we should kick the rendering loop
+            if (!wasAbleToDraw && isAbleToDraw()) {
+                // we're now able to draw
+                if (mRenderMode == RENDERMODE_CONTINUOUSLY) {
+                    requestRender();
+                }
+            }
+
+            // By design, this is the only place in a GLThread thread where we wait().
+            if (LOG_THREADS) {
+                Log.d(TAG, "waiting tid=" + getId()
+                        + " mHaveEglContext: " + mHaveEglContext
+                        + " mHaveEglSurface: " + mHaveEglSurface
+                        + " mPaused: " + mPaused
+                        + " mHasSurface: " + mHasSurface
+                        + " mSurfaceIsBad: " + mEglSurfaceIsBad
+                        + " mWidth: " + mWidth
+                        + " mHeight: " + mHeight
+                        + " mRenderMode: " + mRenderMode);
+            }
+        }
+
+        private void executeDraw() {
+            if (TRACE_ENABLED) {
+                Trace.traceBegin(Trace.TRACE_TAG_GRAPHICS, "executeDraw");
+            }
+
+            if (isAbleToDraw()) {
+                if (mRenderMode == RENDERMODE_CONTINUOUSLY) {
+                    requestRender();
+                }
+
+                if (LOG_RENDERER_DRAW_FRAME) {
+                    Log.d(TAG, "onDrawFrame tid=" + getId());
+                }
+
+                GLSurfaceView view = mGLSurfaceViewWeakRef.get();
+                if (view != null) {
+                    view.mRenderer.onDrawFrame(mGLContext);
                     int swapError = mEglHelper.swap();
                     switch (swapError) {
                         case EGL10.EGL_SUCCESS:
                             break;
                         case EGL11.EGL_CONTEXT_LOST:
                             if (LOG_SURFACE) {
-                                Log.i("GLThread", "egl context lost tid=" + getId());
+                                Log.d(TAG, "egl context lost tid=" + getId());
                             }
-                            lostEglContext = true;
+                            stopEglSurface();
+                            stopEglContext();
                             break;
                         default:
                             // Other errors typically mean that the current surface is bad,
                             // probably because the SurfaceView surface has been destroyed,
                             // but we haven't been notified yet.
                             // Log the error to help developers understand why rendering stopped.
-                            EglHelper.logEglErrorAsWarning("GLThread", "eglSwapBuffers", swapError);
-
-                            synchronized(sGLThreadManager) {
-                                mSurfaceIsBad = true;
-                                sGLThreadManager.notifyAll();
-                            }
+                            EglHelper.logEglErrorAsWarning(TAG, "eglSwapBuffers", swapError);
+                            mEglSurfaceIsBad = true;
                             break;
                     }
-
-                    if (wantRenderNotification) {
-                        doRenderNotification = true;
-                    }
                 }
+            }
 
-            } finally {
-                /*
-                 * clean-up everything...
-                 */
-                synchronized (sGLThreadManager) {
-                    stopEglSurfaceLocked();
-                    stopEglContextLocked();
+            if (TRACE_ENABLED) {
+                Trace.traceEnd(Trace.TRACE_TAG_GRAPHICS);
+            }
+        }
+
+        private boolean isAbleToDraw() {
+            return mHaveEglContext && mHaveEglSurface && isReadyToDraw();
+        }
+
+        private boolean isReadyToDraw() {
+            return (!mPaused) && mHasSurface && (!mEglSurfaceIsBad)
+                && (mWidth > 0) && (mHeight > 0);
+        }
+
+        private boolean isEglContextReleasedWhenPausing() {
+            GLSurfaceView view = mGLSurfaceViewWeakRef.get();
+            return (view != null) ? !view.mPreserveEGLContextOnPause : false;
+        }
+
+        public void queueEvent(Runnable r) {
+            if (r == null) {
+                throw new IllegalArgumentException("Runnable r must not be null");
+            }
+            mGLHandler.post(r);
+        }
+
+        /*
+         * the call-backs below all run on the GLThread and implement state
+         * changes of the GLSurfaceView and Activity life cycle.
+         */
+
+        private void doSurfaceCreated() {
+            mHasSurface = true;
+            updateState();
+        }
+
+        private void doSurfaceDestroyed() {
+            if (mHasSurface) {
+                if (LOG_SURFACE) {
+                    Log.d(TAG, "noticed surfaceView surface lost tid=" + getId());
+                }
+                stopEglSurface();
+            }
+            mHasSurface = false;
+        }
+
+        private void doPause() {
+            if (mPaused == false) {
+                mPaused = true;
+                stopEglSurface();
+                // When pausing, optionally release the EGL Context:
+                if (mHaveEglContext && isEglContextReleasedWhenPausing()) {
+                    stopEglContext();
                 }
             }
         }
 
-        public boolean ableToDraw() {
-            return mHaveEglContext && mHaveEglSurface && readyToDraw();
-        }
-
-        private boolean readyToDraw() {
-            return (!mPaused) && mHasSurface && (!mSurfaceIsBad)
-                && (mWidth > 0) && (mHeight > 0)
-                && (mRequestRender || (mRenderMode == RENDERMODE_CONTINUOUSLY));
-        }
-
-        public void setRenderMode(int renderMode) {
-            if ( !((RENDERMODE_WHEN_DIRTY <= renderMode) && (renderMode <= RENDERMODE_CONTINUOUSLY)) ) {
-                throw new IllegalArgumentException("renderMode");
-            }
-            synchronized(sGLThreadManager) {
-                mRenderMode = renderMode;
-                sGLThreadManager.notifyAll();
+        private void doResume() {
+            mPaused = false;
+            updateState();
+            if (mRenderMode == RENDERMODE_WHEN_DIRTY) {
+                requestRender();
             }
         }
 
-        public int getRenderMode() {
-            synchronized(sGLThreadManager) {
-                return mRenderMode;
-            }
+        private void doWindowResize(final int width, final int height) {
+            // we were not drawing yet. Update the window size and
+            // state and attempt to draw a frame.
+            mSizeChanged = (mWidth != width || mHeight != height);
+            mWidth = width;
+            mHeight = height;
+            updateState();
+            // we always (attempt to) draw a frame before returning
+            executeDraw();
         }
 
-        public void requestRender() {
-            synchronized(sGLThreadManager) {
-                mRequestRender = true;
-                sGLThreadManager.notifyAll();
-            }
+        private void doSetRenderMode(final int renderMode) {
+            mRenderMode = renderMode;
+            requestRender();
         }
 
+        /*
+         * the call-backs below run on the main UI thread, they just
+         * wait while executing work on the GLThread.
+         */
+
         public void surfaceCreated() {
-            synchronized(sGLThreadManager) {
-                if (LOG_THREADS) {
-                    Log.i("GLThread", "surfaceCreated tid=" + getId());
+            mGLHandler.runWithScissors(new Runnable() {
+                @Override
+                public void run() {
+                    doSurfaceCreated();
                 }
-                mHasSurface = true;
-                mFinishedCreatingEglSurface = false;
-                sGLThreadManager.notifyAll();
-                while (mWaitingForSurface
-                       && !mFinishedCreatingEglSurface
-                       && !mExited) {
-                    try {
-                        sGLThreadManager.wait();
-                    } catch (InterruptedException e) {
-                        Thread.currentThread().interrupt();
-                    }
-                }
-            }
+            }, 0);
         }
 
         public void surfaceDestroyed() {
-            synchronized(sGLThreadManager) {
-                if (LOG_THREADS) {
-                    Log.i("GLThread", "surfaceDestroyed tid=" + getId());
+            mGLHandler.runWithScissors(new Runnable() {
+                @Override
+                public void run() {
+                    doSurfaceDestroyed();
                 }
-                mHasSurface = false;
-                sGLThreadManager.notifyAll();
-                while((!mWaitingForSurface) && (!mExited)) {
-                    try {
-                        sGLThreadManager.wait();
-                    } catch (InterruptedException e) {
-                        Thread.currentThread().interrupt();
-                    }
-                }
-            }
+            }, 0);
         }
 
         public void onPause() {
-            synchronized (sGLThreadManager) {
-                if (LOG_PAUSE_RESUME) {
-                    Log.i("GLThread", "onPause tid=" + getId());
+            mGLHandler.runWithScissors(new Runnable() {
+                @Override
+                public void run() {
+                    doPause();
                 }
-                mRequestPaused = true;
-                sGLThreadManager.notifyAll();
-                while ((! mExited) && (! mPaused)) {
-                    if (LOG_PAUSE_RESUME) {
-                        Log.i("Main thread", "onPause waiting for mPaused.");
-                    }
-                    try {
-                        sGLThreadManager.wait();
-                    } catch (InterruptedException ex) {
-                        Thread.currentThread().interrupt();
-                    }
-                }
-            }
+            }, 0);
         }
 
         public void onResume() {
-            synchronized (sGLThreadManager) {
-                if (LOG_PAUSE_RESUME) {
-                    Log.i("GLThread", "onResume tid=" + getId());
+            mGLHandler.runWithScissors(new Runnable() {
+                @Override
+                public void run() {
+                    doResume();
                 }
-                mRequestPaused = false;
-                mRequestRender = true;
-                mRenderComplete = false;
-                sGLThreadManager.notifyAll();
-                while ((! mExited) && mPaused && (!mRenderComplete)) {
-                    if (LOG_PAUSE_RESUME) {
-                        Log.i("Main thread", "onResume waiting for !mPaused.");
-                    }
-                    try {
-                        sGLThreadManager.wait();
-                    } catch (InterruptedException ex) {
-                        Thread.currentThread().interrupt();
-                    }
-                }
-            }
+            }, 0);
         }
 
         public void onWindowResize(int w, int h) {
-            synchronized (sGLThreadManager) {
-                mWidth = w;
-                mHeight = h;
-                mSizeChanged = true;
-                mRequestRender = true;
-                mRenderComplete = false;
-                sGLThreadManager.notifyAll();
-
-                // Wait for thread to react to resize and render a frame
-                while (! mExited && !mPaused && !mRenderComplete
-                        && ableToDraw()) {
-                    if (LOG_SURFACE) {
-                        Log.i("Main thread", "onWindowResize waiting for render complete from tid=" + getId());
-                    }
-                    try {
-                        sGLThreadManager.wait();
-                    } catch (InterruptedException ex) {
-                        Thread.currentThread().interrupt();
-                    }
+            final int width = w;
+            final int height = h;
+            mGLHandler.runWithScissors(new Runnable() {
+                @Override
+                public void run() {
+                    doWindowResize(width, height);
                 }
+            }, 0);
+        }
+
+        /*
+         * the methods below can be called from any thread
+         */
+
+        public void requestRender() {
+            if (mRenderMode == RENDERMODE_CONTINUOUSLY) {
+                mChoreographer.postCallback(Choreographer.CALLBACK_ANIMATION,
+                        mExecuteDrawAction, null);
+            } else {
+                /*
+                 * in RENDERMODE_WHEN_DIRTY we schedule the draw callback
+                 * immediately because the developer is manager her
+                 * timing loop manually -- in particular she could be
+                 * using the Choreographer already.
+                 */
+                mGLHandler.post(mExecuteDrawAction);
             }
         }
 
+        public void setRenderMode(final int renderMode) {
+            mGLHandler.runWithScissors(new Runnable() {
+                @Override
+                public void run() {
+                    doSetRenderMode(renderMode);
+                }
+            }, 0);
+        }
+
         public void requestExitAndWait() {
-            // don't call this from GLThread thread or it is a guaranteed
-            // deadlock!
-            synchronized(sGLThreadManager) {
-                mShouldExit = true;
-                sGLThreadManager.notifyAll();
-                while (! mExited) {
-                    try {
-                        sGLThreadManager.wait();
-                    } catch (InterruptedException ex) {
-                        Thread.currentThread().interrupt();
-                    }
-                }
+            getLooper().quit();
+            try {
+                this.join();
+            } catch (InterruptedException e) {
             }
         }
-
-        public void requestReleaseEglContextLocked() {
-            mShouldReleaseEglContext = true;
-            sGLThreadManager.notifyAll();
-        }
-
-        /**
-         * Queue an "event" to be run on the GL rendering thread.
-         * @param r the runnable to be run on the GL rendering thread.
-         */
-        public void queueEvent(Runnable r) {
-            if (r == null) {
-                throw new IllegalArgumentException("r must not be null");
-            }
-            synchronized(sGLThreadManager) {
-                mEventQueue.add(r);
-                sGLThreadManager.notifyAll();
-            }
-        }
-
-        // Once the thread is started, all accesses to the following member
-        // variables are protected by the sGLThreadManager monitor
-        private boolean mShouldExit;
-        private boolean mExited;
-        private boolean mRequestPaused;
-        private boolean mPaused;
-        private boolean mHasSurface;
-        private boolean mSurfaceIsBad;
-        private boolean mWaitingForSurface;
-        private boolean mHaveEglContext;
-        private boolean mHaveEglSurface;
-        private boolean mFinishedCreatingEglSurface;
-        private boolean mShouldReleaseEglContext;
-        private int mWidth;
-        private int mHeight;
-        private int mRenderMode;
-        private boolean mRequestRender;
-        private boolean mRenderComplete;
-        private ArrayList<Runnable> mEventQueue = new ArrayList<Runnable>();
-        private boolean mSizeChanged = true;
-
-        // End of member variables protected by the sGLThreadManager monitor.
-
-        private EglHelper mEglHelper;
-
-        /**
-         * Set once at thread construction time, nulled out when the parent view is garbage
-         * called. This weak reference allows the GLSurfaceView to be garbage collected while
-         * the GLThread is still alive.
-         */
-        private WeakReference<GLSurfaceView> mGLSurfaceViewWeakRef;
-
-    }
+    } // class GLThread
 
     static class LogWriter extends Writer {
-
-        @Override public void close() {
+        @Override
+        public void close() {
             flushBuilder();
         }
 
-        @Override public void flush() {
+        @Override
+        public void flush() {
             flushBuilder();
         }
 
-        @Override public void write(char[] buf, int offset, int count) {
-            for(int i = 0; i < count; i++) {
+        @Override
+        public void write(char[] buf, int offset, int count) {
+            for (int i = 0; i < count; i++) {
                 char c = buf[offset + i];
-                if ( c == '\n') {
+                if (c == '\n') {
                     flushBuilder();
-                }
-                else {
+                } else {
                     mBuilder.append(c);
                 }
             }
@@ -1792,7 +1641,7 @@
 
         private void flushBuilder() {
             if (mBuilder.length() > 0) {
-                Log.v("GLSurfaceView", mBuilder.toString());
+                Log.v(TAG, mBuilder.toString());
                 mBuilder.delete(0, mBuilder.length());
             }
         }
@@ -1800,141 +1649,10 @@
         private StringBuilder mBuilder = new StringBuilder();
     }
 
-
     private void checkRenderThreadState() {
         if (mGLThread != null) {
             throw new IllegalStateException(
                     "setRenderer has already been called for this instance.");
         }
     }
-
-    private static class GLThreadManager {
-        private static String TAG = "GLThreadManager";
-
-        public synchronized void threadExiting(GLThread thread) {
-            if (LOG_THREADS) {
-                Log.i("GLThread", "exiting tid=" +  thread.getId());
-            }
-            thread.mExited = true;
-            if (mEglOwner == thread) {
-                mEglOwner = null;
-            }
-            notifyAll();
-        }
-
-        /*
-         * Tries once to acquire the right to use an EGL
-         * context. Does not block. Requires that we are already
-         * in the sGLThreadManager monitor when this is called.
-         *
-         * @return true if the right to use an EGL context was acquired.
-         */
-        public boolean tryAcquireEglContextLocked(GLThread thread) {
-            if (mEglOwner == thread || mEglOwner == null) {
-                mEglOwner = thread;
-                notifyAll();
-                return true;
-            }
-            checkGLESVersion();
-            if (mMultipleGLESContextsAllowed) {
-                return true;
-            }
-            // Notify the owning thread that it should release the context.
-            // TODO: implement a fairness policy. Currently
-            // if the owning thread is drawing continuously it will just
-            // reacquire the EGL context.
-            if (mEglOwner != null) {
-                mEglOwner.requestReleaseEglContextLocked();
-            }
-            return false;
-        }
-
-        /*
-         * Releases the EGL context. Requires that we are already in the
-         * sGLThreadManager monitor when this is called.
-         */
-        public void releaseEglContextLocked(GLThread thread) {
-            if (mEglOwner == thread) {
-                mEglOwner = null;
-            }
-            notifyAll();
-        }
-
-        public synchronized boolean shouldReleaseEGLContextWhenPausing() {
-            // Release the EGL context when pausing even if
-            // the hardware supports multiple EGL contexts.
-            // Otherwise the device could run out of EGL contexts.
-            return mLimitedGLESContexts;
-        }
-
-        public synchronized boolean shouldTerminateEGLWhenPausing() {
-            checkGLESVersion();
-            return !mMultipleGLESContextsAllowed;
-        }
-
-        public synchronized void checkGLDriver(GL10 gl) {
-            if (! mGLESDriverCheckComplete) {
-                checkGLESVersion();
-                String renderer = gl.glGetString(GL10.GL_RENDERER);
-                if (mGLESVersion < kGLES_20) {
-                    mMultipleGLESContextsAllowed =
-                        ! renderer.startsWith(kMSM7K_RENDERER_PREFIX);
-                    notifyAll();
-                }
-                mLimitedGLESContexts = !mMultipleGLESContextsAllowed;
-                if (LOG_SURFACE) {
-                    Log.w(TAG, "checkGLDriver renderer = \"" + renderer + "\" multipleContextsAllowed = "
-                        + mMultipleGLESContextsAllowed
-                        + " mLimitedGLESContexts = " + mLimitedGLESContexts);
-                }
-                mGLESDriverCheckComplete = true;
-            }
-        }
-
-        private void checkGLESVersion() {
-            if (! mGLESVersionCheckComplete) {
-                mGLESVersion = SystemProperties.getInt(
-                        "ro.opengles.version",
-                        ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
-                if (mGLESVersion >= kGLES_20) {
-                    mMultipleGLESContextsAllowed = true;
-                }
-                if (LOG_SURFACE) {
-                    Log.w(TAG, "checkGLESVersion mGLESVersion =" +
-                            " " + mGLESVersion + " mMultipleGLESContextsAllowed = " + mMultipleGLESContextsAllowed);
-                }
-                mGLESVersionCheckComplete = true;
-            }
-        }
-
-        /**
-         * This check was required for some pre-Android-3.0 hardware. Android 3.0 provides
-         * support for hardware-accelerated views, therefore multiple EGL contexts are
-         * supported on all Android 3.0+ EGL drivers.
-         */
-        private boolean mGLESVersionCheckComplete;
-        private int mGLESVersion;
-        private boolean mGLESDriverCheckComplete;
-        private boolean mMultipleGLESContextsAllowed;
-        private boolean mLimitedGLESContexts;
-        private static final int kGLES_20 = 0x20000;
-        private static final String kMSM7K_RENDERER_PREFIX =
-            "Q3Dimension MSM7500 ";
-        private GLThread mEglOwner;
-    }
-
-    private static final GLThreadManager sGLThreadManager = new GLThreadManager();
-
-    private final WeakReference<GLSurfaceView> mThisWeakRef =
-            new WeakReference<GLSurfaceView>(this);
-    private GLThread mGLThread;
-    private Renderer mRenderer;
-    private boolean mDetached;
-    private EGLConfigChooser mEGLConfigChooser;
-    private EGLContextFactory mEGLContextFactory;
-    private EGLWindowSurfaceFactory mEGLWindowSurfaceFactory;
-    private GLWrapper mGLWrapper;
-    private int mDebugFlags;
-    private int mEGLContextClientVersion;
-    private boolean mPreserveEGLContextOnPause;
 }
diff --git a/packages/DefaultContainerService/jni/Android.mk b/packages/DefaultContainerService/jni/Android.mk
index 79ff451..ef4f699 100644
--- a/packages/DefaultContainerService/jni/Android.mk
+++ b/packages/DefaultContainerService/jni/Android.mk
@@ -28,7 +28,8 @@
 
 LOCAL_SHARED_LIBRARIES := \
     libnativehelper \
-    libutils
+    libutils \
+    liblog
 
 LOCAL_STATIC_LIBRARIES := \
     libdiskusage
@@ -36,4 +37,4 @@
 LOCAL_MODULE := libdefcontainer_jni
 LOCAL_MODULE_TAGS := optional
 
-include $(BUILD_SHARED_LIBRARY)
\ No newline at end of file
+include $(BUILD_SHARED_LIBRARY)
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetPager.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetPager.java
index ad5e257..1bcee4e 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetPager.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetPager.java
@@ -594,13 +594,12 @@
         animateOutlinesAndSidePages(false);
     }
 
-    public void showInitialPageHints() {
-        mShowingInitialHints = true;
+    void updateChildrenContentAlpha(float sidePageAlpha) {
         int count = getChildCount();
         for (int i = 0; i < count; i++) {
             KeyguardWidgetFrame child = getWidgetPageAt(i);
             if (i != mCurrentPage) {
-                child.setBackgroundAlpha(KeyguardWidgetFrame.OUTLINE_ALPHA_MULTIPLIER);
+                child.setBackgroundAlpha(sidePageAlpha);
                 child.setContentAlpha(0f);
             } else {
                 child.setBackgroundAlpha(0f);
@@ -609,9 +608,15 @@
         }
     }
 
+    public void showInitialPageHints() {
+        mShowingInitialHints = true;
+        updateChildrenContentAlpha(KeyguardWidgetFrame.OUTLINE_ALPHA_MULTIPLIER);
+    }
+
     @Override
     void setCurrentPage(int currentPage) {
         super.setCurrentPage(currentPage);
+        updateChildrenContentAlpha(0.0f);
         updateWidgetFramesImportantForAccessibility();
     }
 
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/PagedView.java b/policy/src/com/android/internal/policy/impl/keyguard/PagedView.java
index 539ec1a..186a013 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/PagedView.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/PagedView.java
@@ -756,6 +756,8 @@
     @Override
     public void onChildViewRemoved(View parent, View child) {
         mForceScreenScrolled = true;
+        invalidate();
+        invalidateCachedOffsets();
     }
 
     protected void invalidateCachedOffsets() {
diff --git a/services/common_time/Android.mk b/services/common_time/Android.mk
index 0606ab4..75eb528 100644
--- a/services/common_time/Android.mk
+++ b/services/common_time/Android.mk
@@ -27,7 +27,8 @@
 LOCAL_SHARED_LIBRARIES := \
     libbinder \
     libcommon_time_client \
-    libutils
+    libutils \
+    liblog
 
 LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE := common_time
diff --git a/services/input/Android.mk b/services/input/Android.mk
index 159800f..5d913f3 100644
--- a/services/input/Android.mk
+++ b/services/input/Android.mk
@@ -29,6 +29,7 @@
 
 LOCAL_SHARED_LIBRARIES := \
     libcutils \
+    liblog \
     libandroidfw \
     libutils \
     libhardware \
diff --git a/services/input/EventHub.cpp b/services/input/EventHub.cpp
index 0773afb..376de96 100644
--- a/services/input/EventHub.cpp
+++ b/services/input/EventHub.cpp
@@ -40,7 +40,6 @@
 #include <androidfw/KeyCharacterMap.h>
 #include <androidfw/VirtualKeyMap.h>
 
-#include <sha1.h>
 #include <string.h>
 #include <stdint.h>
 #include <dirent.h>
@@ -49,6 +48,7 @@
 #include <sys/epoll.h>
 #include <sys/ioctl.h>
 #include <sys/limits.h>
+#include <sys/sha1.h>
 
 /* this macro is used to tell if "bit" is set in "array"
  * it selects a byte from the array, and does a boolean AND
@@ -162,7 +162,8 @@
         next(NULL),
         fd(fd), id(id), path(path), identifier(identifier),
         classes(0), configuration(NULL), virtualKeyMap(NULL),
-        ffEffectPlaying(false), ffEffectId(-1) {
+        ffEffectPlaying(false), ffEffectId(-1),
+        timestampOverrideSec(0), timestampOverrideUsec(0) {
     memset(keyBitmask, 0, sizeof(keyBitmask));
     memset(absBitmask, 0, sizeof(absBitmask));
     memset(relBitmask, 0, sizeof(relBitmask));
@@ -766,12 +767,37 @@
 
                     size_t count = size_t(readSize) / sizeof(struct input_event);
                     for (size_t i = 0; i < count; i++) {
-                        const struct input_event& iev = readBuffer[i];
-                        ALOGV("%s got: t0=%d, t1=%d, type=%d, code=%d, value=%d",
+                        struct input_event& iev = readBuffer[i];
+                        ALOGV("%s got: time=%d.%06d, type=%d, code=%d, value=%d",
                                 device->path.string(),
                                 (int) iev.time.tv_sec, (int) iev.time.tv_usec,
                                 iev.type, iev.code, iev.value);
 
+                        // Some input devices may have a better concept of the time
+                        // when an input event was actually generated than the kernel
+                        // which simply timestamps all events on entry to evdev.
+                        // This is a custom Android extension of the input protocol
+                        // mainly intended for use with uinput based device drivers.
+                        if (iev.type == EV_MSC) {
+                            if (iev.code == MSC_ANDROID_TIME_SEC) {
+                                device->timestampOverrideSec = iev.value;
+                                continue;
+                            } else if (iev.code == MSC_ANDROID_TIME_USEC) {
+                                device->timestampOverrideUsec = iev.value;
+                                continue;
+                            }
+                        }
+                        if (device->timestampOverrideSec || device->timestampOverrideUsec) {
+                            iev.time.tv_sec = device->timestampOverrideSec;
+                            iev.time.tv_usec = device->timestampOverrideUsec;
+                            if (iev.type == EV_SYN && iev.code == SYN_REPORT) {
+                                device->timestampOverrideSec = 0;
+                                device->timestampOverrideUsec = 0;
+                            }
+                            ALOGV("applied override time %d.%06d",
+                                    int(iev.time.tv_sec), int(iev.time.tv_usec));
+                        }
+
 #ifdef HAVE_POSIX_CLOCKS
                         // Use the time specified in the event instead of the current time
                         // so that downstream code can get more accurate estimates of
@@ -829,8 +855,8 @@
                         event->code = iev.code;
                         event->value = iev.value;
                         event += 1;
+                        capacity -= 1;
                     }
-                    capacity -= count;
                     if (capacity == 0) {
                         // The result buffer is full.  Reset the pending event index
                         // so we will try to read the device again on the next iteration.
@@ -1162,11 +1188,6 @@
             mBuiltInKeyboardId = device->id;
         }
 
-        // 'Q' key support = cheap test of whether this is an alpha-capable kbd
-        if (hasKeycodeLocked(device, AKEYCODE_Q)) {
-            device->classes |= INPUT_DEVICE_CLASS_ALPHAKEY;
-        }
-
         // See if this device has a DPAD.
         if (hasKeycodeLocked(device, AKEYCODE_DPAD_UP) &&
                 hasKeycodeLocked(device, AKEYCODE_DPAD_DOWN) &&
@@ -1184,6 +1205,14 @@
             }
         }
 
+        // 'Q' key support = cheap test of whether this is an alpha-capable kbd. Many gamepads will
+        // report a broader set of HID usages than they need, however, so we only want to mark this
+        // device as a keyboard if it is not a gamepad.
+        if (hasKeycodeLocked(device, AKEYCODE_Q) &&
+                !(device->classes & INPUT_DEVICE_CLASS_GAMEPAD)) {
+            device->classes |= INPUT_DEVICE_CLASS_ALPHAKEY;
+        }
+
         // Disable kernel key repeat since we handle it ourselves
         unsigned int repeatRate[] = {0,0};
         if (ioctl(fd, EVIOCSREP, repeatRate)) {
diff --git a/services/input/EventHub.h b/services/input/EventHub.h
index afc12ef..c93fc7a 100644
--- a/services/input/EventHub.h
+++ b/services/input/EventHub.h
@@ -42,6 +42,20 @@
 #define BTN_FIRST 0x100  // first button code
 #define BTN_LAST 0x15f   // last button code
 
+/*
+ * These constants are used privately in Android to pass raw timestamps
+ * through evdev from uinput device drivers because there is currently no
+ * other way to transfer this information.  The evdev driver automatically
+ * timestamps all input events with the time they were posted and clobbers
+ * whatever information was passed in.
+ *
+ * For the purposes of this hack, the timestamp is specified in the
+ * CLOCK_MONOTONIC timebase and is split into two EV_MSC events specifying
+ * seconds and microseconds.
+ */
+#define MSC_ANDROID_TIME_SEC 0x6
+#define MSC_ANDROID_TIME_USEC 0x7
+
 namespace android {
 
 enum {
@@ -329,6 +343,9 @@
         bool ffEffectPlaying;
         int16_t ffEffectId; // initially -1
 
+        int32_t timestampOverrideSec;
+        int32_t timestampOverrideUsec;
+
         Device(int fd, int32_t id, const String8& path, const InputDeviceIdentifier& identifier);
         ~Device();
 
diff --git a/services/input/InputReader.cpp b/services/input/InputReader.cpp
index 602afd4..ab38ed2 100644
--- a/services/input/InputReader.cpp
+++ b/services/input/InputReader.cpp
@@ -2701,6 +2701,12 @@
                 mPointerYZoomScale);
         dump.appendFormat(INDENT4 "MaxSwipeWidth: %f\n",
                 mPointerGestureMaxSwipeWidth);
+    } else if (mDeviceMode == DEVICE_MODE_NAVIGATION) {
+        dump.appendFormat(INDENT3 "Navigation Gesture Detector:\n");
+        dump.appendFormat(INDENT4 "AssistStartY: %0.3f\n",
+                mNavigationAssistStartY);
+        dump.appendFormat(INDENT4 "AssistEndY: %0.3f\n",
+                mNavigationAssistEndY);
     }
 }
 
@@ -2895,7 +2901,7 @@
         }
     } else if (mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_NAVIGATION) {
         mSource = AINPUT_SOURCE_TOUCH_NAVIGATION;
-        mDeviceMode = DEVICE_MODE_UNSCALED;
+        mDeviceMode = DEVICE_MODE_NAVIGATION;
     } else {
         mSource = AINPUT_SOURCE_TOUCHPAD;
         mDeviceMode = DEVICE_MODE_UNSCALED;
@@ -3243,8 +3249,8 @@
             break;
         }
 
-        // Compute pointer gesture detection parameters.
         if (mDeviceMode == DEVICE_MODE_POINTER) {
+            // Compute pointer gesture detection parameters.
             float rawDiagonal = hypotf(rawWidth, rawHeight);
             float displayDiagonal = hypotf(mSurfaceWidth, mSurfaceHeight);
 
@@ -3269,10 +3275,14 @@
             // translated into freeform gestures.
             mPointerGestureMaxSwipeWidth =
                     mConfig.pointerGestureSwipeMaxWidthRatio * rawDiagonal;
-        }
 
-        // Abort current pointer usages because the state has changed.
-        abortPointerUsage(when, 0 /*policyFlags*/);
+            // Abort current pointer usages because the state has changed.
+            abortPointerUsage(when, 0 /*policyFlags*/);
+        } else if (mDeviceMode == DEVICE_MODE_NAVIGATION) {
+            // Compute navigation parameters.
+            mNavigationAssistStartY = mSurfaceHeight * 0.9f;
+            mNavigationAssistEndY = mSurfaceHeight * 0.5f;
+        }
 
         // Inform the dispatcher about the changes.
         *outResetNeeded = true;
@@ -3611,6 +3621,7 @@
 
     mPointerGesture.reset();
     mPointerSimple.reset();
+    mNavigation.reset();
 
     if (mPointerController != NULL) {
         mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
@@ -3761,6 +3772,8 @@
                 mPointerController->setSpots(mCurrentCookedPointerData.pointerCoords,
                         mCurrentCookedPointerData.idToIndex,
                         mCurrentCookedPointerData.touchingIdBits);
+            } else if (mDeviceMode == DEVICE_MODE_NAVIGATION) {
+                dispatchNavigationAssist(when, policyFlags);
             }
 
             dispatchHoverExit(when, policyFlags);
@@ -5482,6 +5495,44 @@
     dispatchPointerSimple(when, policyFlags, false, false);
 }
 
+void TouchInputMapper::dispatchNavigationAssist(nsecs_t when, uint32_t policyFlags) {
+    if (mCurrentCookedPointerData.touchingIdBits.count() == 1) {
+        if (mLastCookedPointerData.touchingIdBits.isEmpty()) {
+            // First pointer down.
+            uint32_t id = mCurrentCookedPointerData.touchingIdBits.firstMarkedBit();
+            const PointerCoords& coords = mCurrentCookedPointerData.pointerCoordsForId(id);
+            if (coords.getY() >= mNavigationAssistStartY) {
+                // Start tracking the possible assist swipe.
+                mNavigation.activeAssistId = id;
+                return;
+            }
+        } else if (mNavigation.activeAssistId >= 0
+                && mCurrentCookedPointerData.touchingIdBits.hasBit(mNavigation.activeAssistId)) {
+            const PointerCoords& coords = mCurrentCookedPointerData.pointerCoordsForId(
+                    mNavigation.activeAssistId);
+            if (coords.getY() > mNavigationAssistEndY) {
+                // Swipe is still in progress.
+                return;
+            }
+
+            // Detected assist swipe.
+            int32_t metaState = mContext->getGlobalMetaState();
+            NotifyKeyArgs downArgs(when, getDeviceId(), AINPUT_SOURCE_KEYBOARD,
+                    policyFlags | POLICY_FLAG_VIRTUAL,
+                    AKEY_EVENT_ACTION_DOWN, 0, AKEYCODE_ASSIST, 0, metaState, when);
+            getListener()->notifyKey(&downArgs);
+
+            NotifyKeyArgs upArgs(when, getDeviceId(), AINPUT_SOURCE_KEYBOARD,
+                    policyFlags | POLICY_FLAG_VIRTUAL,
+                    AKEY_EVENT_ACTION_UP, 0, AKEYCODE_ASSIST, 0, metaState, when);
+            getListener()->notifyKey(&upArgs);
+        }
+    }
+
+    // Cancel the assist swipe.
+    mNavigation.activeAssistId = -1;
+}
+
 void TouchInputMapper::dispatchMotion(nsecs_t when, uint32_t policyFlags, uint32_t source,
         int32_t action, int32_t flags, int32_t metaState, int32_t buttonState, int32_t edgeFlags,
         const PointerProperties* properties, const PointerCoords* coords,
diff --git a/services/input/InputReader.h b/services/input/InputReader.h
index 8a52c06..312f19b 100644
--- a/services/input/InputReader.h
+++ b/services/input/InputReader.h
@@ -791,6 +791,10 @@
     void clear();
     void copyFrom(const CookedPointerData& other);
 
+    inline const PointerCoords& pointerCoordsForId(uint32_t id) const {
+        return pointerCoords[idToIndex[id]];
+    }
+
     inline bool isHovering(uint32_t pointerIndex) {
         return hoveringIdBits.hasBit(pointerProperties[pointerIndex].id);
     }
@@ -1180,6 +1184,7 @@
         DEVICE_MODE_DISABLED, // input is disabled
         DEVICE_MODE_DIRECT, // direct mapping (touchscreen)
         DEVICE_MODE_UNSCALED, // unscaled mapping (touchpad)
+        DEVICE_MODE_NAVIGATION, // unscaled mapping with assist gesture (touch navigation)
         DEVICE_MODE_POINTER, // pointer mapping (pointer)
     };
     DeviceMode mDeviceMode;
@@ -1432,6 +1437,10 @@
     // The maximum swipe width.
     float mPointerGestureMaxSwipeWidth;
 
+    // The start and end Y thresholds for invoking the assist navigation swipe.
+    float mNavigationAssistStartY;
+    float mNavigationAssistEndY;
+
     struct PointerDistanceHeapElement {
         uint32_t currentPointerIndex : 8;
         uint32_t lastPointerIndex : 8;
@@ -1606,6 +1615,15 @@
         }
     } mPointerSimple;
 
+    struct Navigation {
+        // The id of a pointer that is tracking a possible assist swipe.
+        int32_t activeAssistId; // -1 if none
+
+        void reset() {
+            activeAssistId = -1;
+        }
+    } mNavigation;
+
     // The pointer and scroll velocity controls.
     VelocityControl mPointerVelocityControl;
     VelocityControl mWheelXVelocityControl;
@@ -1641,6 +1659,8 @@
             bool down, bool hovering);
     void abortPointerSimple(nsecs_t when, uint32_t policyFlags);
 
+    void dispatchNavigationAssist(nsecs_t when, uint32_t policyFlags);
+
     // Dispatches a motion event.
     // If the changedId is >= 0 and the action is POINTER_DOWN or POINTER_UP, the
     // method will take care of setting the index and transmuting the action to DOWN or UP
diff --git a/services/input/tests/Android.mk b/services/input/tests/Android.mk
index 8f8c34b..211e64b 100644
--- a/services/input/tests/Android.mk
+++ b/services/input/tests/Android.mk
@@ -9,6 +9,7 @@
 
 shared_libraries := \
     libcutils \
+    liblog \
     libandroidfw \
     libutils \
     libhardware \
diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java
index 9e06db8..ffc3672 100644
--- a/services/java/com/android/server/ConnectivityService.java
+++ b/services/java/com/android/server/ConnectivityService.java
@@ -321,12 +321,11 @@
 
     // track the current default http proxy - tell the world if we get a new one (real change)
     private ProxyProperties mDefaultProxy = null;
-    private Object mDefaultProxyLock = new Object();
+    private Object mProxyLock = new Object();
     private boolean mDefaultProxyDisabled = false;
 
     // track the global proxy.
     private ProxyProperties mGlobalProxy = null;
-    private final Object mGlobalProxyLock = new Object();
 
     private SettingsObserver mSettingsObserver;
 
@@ -3039,14 +3038,15 @@
         // so this API change wouldn't have a benifit.  It also breaks the passing
         // of proxy info to all the JVMs.
         // enforceAccessPermission();
-        synchronized (mDefaultProxyLock) {
-            return mDefaultProxyDisabled ? null : mDefaultProxy;
+        synchronized (mProxyLock) {
+            if (mGlobalProxy != null) return mGlobalProxy;
+            return (mDefaultProxyDisabled ? null : mDefaultProxy);
         }
     }
 
     public void setGlobalProxy(ProxyProperties proxyProperties) {
         enforceChangePermission();
-        synchronized (mGlobalProxyLock) {
+        synchronized (mProxyLock) {
             if (proxyProperties == mGlobalProxy) return;
             if (proxyProperties != null && proxyProperties.equals(mGlobalProxy)) return;
             if (mGlobalProxy != null && mGlobalProxy.equals(proxyProperties)) return;
@@ -3072,7 +3072,7 @@
         if (mGlobalProxy == null) {
             proxyProperties = mDefaultProxy;
         }
-        //sendProxyBroadcast(proxyProperties);
+        sendProxyBroadcast(proxyProperties);
     }
 
     private void loadGlobalProxy() {
@@ -3083,7 +3083,7 @@
                 Settings.Global.GLOBAL_HTTP_PROXY_EXCLUSION_LIST);
         if (!TextUtils.isEmpty(host)) {
             ProxyProperties proxyProperties = new ProxyProperties(host, port, exclList);
-            synchronized (mGlobalProxyLock) {
+            synchronized (mProxyLock) {
                 mGlobalProxy = proxyProperties;
             }
         }
@@ -3094,7 +3094,7 @@
         // so this API change wouldn't have a benifit.  It also breaks the passing
         // of proxy info to all the JVMs.
         // enforceAccessPermission();
-        synchronized (mGlobalProxyLock) {
+        synchronized (mProxyLock) {
             return mGlobalProxy;
         }
     }
@@ -3103,11 +3103,12 @@
         if (proxy != null && TextUtils.isEmpty(proxy.getHost())) {
             proxy = null;
         }
-        synchronized (mDefaultProxyLock) {
+        synchronized (mProxyLock) {
             if (mDefaultProxy != null && mDefaultProxy.equals(proxy)) return;
-            if (mDefaultProxy == proxy) return;
+            if (mDefaultProxy == proxy) return; // catches repeated nulls
             mDefaultProxy = proxy;
 
+            if (mGlobalProxy != null) return;
             if (!mDefaultProxyDisabled) {
                 sendProxyBroadcast(proxy);
             }
@@ -3350,10 +3351,10 @@
                 mDnsOverridden = true;
             }
 
-            // Temporarily disable the default proxy.
-            synchronized (mDefaultProxyLock) {
+            // Temporarily disable the default proxy (not global).
+            synchronized (mProxyLock) {
                 mDefaultProxyDisabled = true;
-                if (mDefaultProxy != null) {
+                if (mGlobalProxy == null && mDefaultProxy != null) {
                     sendProxyBroadcast(null);
                 }
             }
@@ -3368,9 +3369,9 @@
                     mHandler.sendEmptyMessage(EVENT_RESTORE_DNS);
                 }
             }
-            synchronized (mDefaultProxyLock) {
+            synchronized (mProxyLock) {
                 mDefaultProxyDisabled = false;
-                if (mDefaultProxy != null) {
+                if (mGlobalProxy == null && mDefaultProxy != null) {
                     sendProxyBroadcast(mDefaultProxy);
                 }
             }
diff --git a/services/java/com/android/server/LocationManagerService.java b/services/java/com/android/server/LocationManagerService.java
index bcb7cb7..1e1cf5a 100644
--- a/services/java/com/android/server/LocationManagerService.java
+++ b/services/java/com/android/server/LocationManagerService.java
@@ -54,19 +54,17 @@
 import android.os.PowerManager;
 import android.os.Process;
 import android.os.RemoteException;
-import android.os.ServiceManager;
 import android.os.SystemClock;
 import android.os.UserHandle;
 import android.os.WorkSource;
 import android.provider.Settings;
 import android.util.Log;
 import android.util.Slog;
-
-import com.android.internal.app.IAppOpsService;
 import com.android.internal.content.PackageMonitor;
 import com.android.internal.location.ProviderProperties;
 import com.android.internal.location.ProviderRequest;
 import com.android.server.location.GeocoderProxy;
+import com.android.server.location.GeofenceProxy;
 import com.android.server.location.GeofenceManager;
 import com.android.server.location.GpsLocationProvider;
 import com.android.server.location.LocationBlacklist;
@@ -338,11 +336,11 @@
         addProviderLocked(passiveProvider);
         mEnabledProviders.add(passiveProvider.getName());
         mPassiveProvider = passiveProvider;
+        // Create a gps location provider
+        GpsLocationProvider gpsProvider = new GpsLocationProvider(mContext, this,
+                mLocationHandler.getLooper());
 
         if (GpsLocationProvider.isSupported()) {
-            // Create a gps location provider
-            GpsLocationProvider gpsProvider = new GpsLocationProvider(mContext, this,
-                    mLocationHandler.getLooper());
             mGpsStatusProvider = gpsProvider.getGpsStatusProvider();
             mNetInitiatedListener = gpsProvider.getNetInitiatedListener();
             addProviderLocked(gpsProvider);
@@ -406,6 +404,14 @@
         if (mGeocodeProvider == null) {
             Slog.e(TAG,  "no geocoder provider found");
         }
+
+        // bind to geofence provider
+        GeofenceProxy provider = GeofenceProxy.createAndBind(mContext, providerPackageNames,
+                mLocationHandler, gpsProvider.getGpsGeofenceProxy());
+        if (provider == null) {
+            Slog.e(TAG,  "no geofence provider found");
+        }
+
     }
 
     /**
diff --git a/services/java/com/android/server/accounts/AccountManagerService.java b/services/java/com/android/server/accounts/AccountManagerService.java
index 14d808f..fd7cd78 100644
--- a/services/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/java/com/android/server/accounts/AccountManagerService.java
@@ -22,6 +22,7 @@
 import android.accounts.AccountAuthenticatorResponse;
 import android.accounts.AccountManager;
 import android.accounts.AuthenticatorDescription;
+import android.accounts.CantAddAccountActivity;
 import android.accounts.GrantCredentialsPermissionActivity;
 import android.accounts.IAccountAuthenticator;
 import android.accounts.IAccountAuthenticatorResponse;
@@ -1456,6 +1457,14 @@
                         "User is not allowed to add an account!");
             } catch (RemoteException re) {
             }
+            Intent cantAddAccount = new Intent(mContext, CantAddAccountActivity.class);
+            cantAddAccount.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+            long identityToken = clearCallingIdentity();
+            try {
+                mContext.startActivityAsUser(cantAddAccount, UserHandle.CURRENT);
+            } finally {
+                restoreCallingIdentity(identityToken);
+            }
             return;
         }
 
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 26a20b9..cc7905c 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -3858,6 +3858,9 @@
                     if (app.userId != userId) {
                         continue;
                     }
+                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
+                        continue;
+                    }
                 // Package has been specified, we want to hit all processes
                 // that match it.  We need to qualify this by the processes
                 // that are running under the specified app and user ID.
@@ -7733,6 +7736,18 @@
     }
 
     @Override
+    public void killUid(int uid, String reason) {
+        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
+            throw new SecurityException("killUid only available to the system");
+        }
+        synchronized (this) {
+            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
+                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
+                    reason != null ? reason : "kill uid");
+        }
+    }
+
+    @Override
     public boolean killProcessesBelowForeground(String reason) {
         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
             throw new SecurityException("killProcessesBelowForeground() only available to system");
diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java
index 3d2e912..0f1700d 100644
--- a/services/java/com/android/server/am/ActivityStack.java
+++ b/services/java/com/android/server/am/ActivityStack.java
@@ -47,6 +47,7 @@
 import android.content.res.Resources;
 import android.graphics.Bitmap;
 import android.graphics.Bitmap.Config;
+import android.net.Uri;
 import android.os.Binder;
 import android.os.Bundle;
 import android.os.Handler;
@@ -4600,11 +4601,13 @@
 
     private final void logStartActivity(int tag, ActivityRecord r,
             TaskRecord task) {
+        final Uri data = r.intent.getData();
+        final String strData = data != null ? data.toSafeString() : null;
+
         EventLog.writeEvent(tag,
                 r.userId, System.identityHashCode(r), task.taskId,
                 r.shortComponentName, r.intent.getAction(),
-                r.intent.getType(), r.intent.getDataString(),
-                r.intent.getFlags());
+                r.intent.getType(), strData, r.intent.getFlags());
     }
 
     /**
diff --git a/services/java/com/android/server/location/GeofenceProxy.java b/services/java/com/android/server/location/GeofenceProxy.java
new file mode 100644
index 0000000..36e9fcc
--- /dev/null
+++ b/services/java/com/android/server/location/GeofenceProxy.java
@@ -0,0 +1,154 @@
+/*
+ * 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.location;
+
+import android.content.ComponentName;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.hardware.location.GeofenceHardwareService;
+import android.hardware.location.IGeofenceHardware;
+import android.location.IGeofenceProvider;
+import android.location.IGpsGeofenceHardware;
+import android.content.Context;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Message;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.util.Log;
+import com.android.server.ServiceWatcher;
+
+import java.util.List;
+
+/**
+ * @hide
+ */
+public final class GeofenceProxy {
+    private static final String TAG = "GeofenceProxy";
+    private static final String SERVICE_ACTION =
+            "com.android.location.service.GeofenceProvider";
+    private ServiceWatcher mServiceWatcher;
+    private Context mContext;
+    private IGeofenceHardware mGeofenceHardware;
+    private IGpsGeofenceHardware mGpsGeofenceHardware;
+
+    private static final int GEOFENCE_PROVIDER_CONNECTED = 1;
+    private static final int GEOFENCE_HARDWARE_CONNECTED = 2;
+    private static final int GEOFENCE_HARDWARE_DISCONNECTED = 3;
+    private static final int GEOFENCE_GPS_HARDWARE_CONNECTED = 4;
+    private static final int GEOFENCE_GPS_HARDWARE_DISCONNECTED = 5;
+
+    private Runnable mRunnable = new Runnable() {
+        @Override
+        public void run() {
+            mHandler.sendEmptyMessage(GEOFENCE_PROVIDER_CONNECTED);
+        }
+    };
+
+    public static GeofenceProxy createAndBind(Context context,
+            List<String> initialPackageNames, Handler handler, IGpsGeofenceHardware gpsGeofence) {
+        GeofenceProxy proxy = new GeofenceProxy(context, initialPackageNames, handler, gpsGeofence);
+        if (proxy.bindGeofenceProvider()) {
+            return proxy;
+        } else {
+            return null;
+        }
+    }
+
+    private GeofenceProxy(Context context, List<String> initialPackageName, Handler handler,
+            IGpsGeofenceHardware gpsGeofence) {
+        mContext = context;
+        mServiceWatcher = new ServiceWatcher(context, TAG, SERVICE_ACTION, initialPackageName,
+                mRunnable, handler);
+        mGpsGeofenceHardware = gpsGeofence;
+        bindHardwareGeofence();
+    }
+
+    private boolean bindGeofenceProvider() {
+        return mServiceWatcher.start();
+    }
+
+    private IGeofenceProvider getGeofenceProviderService() {
+        return IGeofenceProvider.Stub.asInterface(mServiceWatcher.getBinder());
+    }
+
+    private void bindHardwareGeofence() {
+        mContext.bindServiceAsUser(new Intent(mContext, GeofenceHardwareService.class),
+                mServiceConnection, Context.BIND_AUTO_CREATE, UserHandle.OWNER);
+    }
+
+    private ServiceConnection mServiceConnection = new ServiceConnection() {
+        @Override
+        public void onServiceConnected(ComponentName name, IBinder service) {
+            mGeofenceHardware = IGeofenceHardware.Stub.asInterface(service);
+            mHandler.sendEmptyMessage(GEOFENCE_HARDWARE_CONNECTED);
+        }
+
+        @Override
+        public void onServiceDisconnected(ComponentName name) {
+            mGeofenceHardware = null;
+            mHandler.sendEmptyMessage(GEOFENCE_HARDWARE_DISCONNECTED);
+        }
+    };
+
+    private void setGeofenceHardwareInProvider() {
+        try {
+            getGeofenceProviderService().setGeofenceHardware(mGeofenceHardware);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Remote Exception: setGeofenceHardwareInProvider: " + e);
+        }
+    }
+
+    private void setGpsGeofence() {
+        try {
+            mGeofenceHardware.setGpsGeofenceHardware(mGpsGeofenceHardware);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Error while connecting to GeofenceHardwareService");
+        }
+    }
+
+
+    // This needs to be reworked, when more services get added,
+    // Might need a state machine or add a framework utility class,
+    private Handler mHandler = new Handler() {
+        private boolean mGeofenceHardwareConnected = false;
+        private boolean mGeofenceProviderConnected = false;
+
+
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case GEOFENCE_PROVIDER_CONNECTED:
+                    mGeofenceProviderConnected = true;
+                    if (mGeofenceHardwareConnected) {
+                        setGeofenceHardwareInProvider();
+                    }
+                    break;
+                case GEOFENCE_HARDWARE_CONNECTED:
+                    setGpsGeofence();
+                    mGeofenceHardwareConnected = true;
+                    if (mGeofenceProviderConnected) {
+                        setGeofenceHardwareInProvider();
+                    }
+                    break;
+                case GEOFENCE_HARDWARE_DISCONNECTED:
+                    mGeofenceHardwareConnected = false;
+                    setGeofenceHardwareInProvider();
+                    break;
+            }
+        }
+    };
+}
diff --git a/services/java/com/android/server/location/GpsLocationProvider.java b/services/java/com/android/server/location/GpsLocationProvider.java
index 3552b6a..1ebff67 100644
--- a/services/java/com/android/server/location/GpsLocationProvider.java
+++ b/services/java/com/android/server/location/GpsLocationProvider.java
@@ -24,7 +24,10 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.database.Cursor;
+import android.hardware.location.GeofenceHardwareImpl;
+import android.hardware.location.IGeofenceHardware;
 import android.location.Criteria;
+import android.location.IGpsGeofenceHardware;
 import android.location.IGpsStatusListener;
 import android.location.IGpsStatusProvider;
 import android.location.ILocationManager;
@@ -314,6 +317,8 @@
     // only modified on handler thread
     private WorkSource mClientSource = new WorkSource();
 
+    private GeofenceHardwareImpl mGeofenceHardwareImpl;
+
     private final IGpsStatusProvider mGpsStatusProvider = new IGpsStatusProvider.Stub() {
         @Override
         public void addGpsStatusListener(IGpsStatusListener listener) throws RemoteException {
@@ -367,6 +372,10 @@
         return mGpsStatusProvider;
     }
 
+    public IGpsGeofenceHardware getGpsGeofenceProxy() {
+        return mGpsGeofenceBinder;
+    }
+
     private final BroadcastReceiver mBroadcastReciever = new BroadcastReceiver() {
         @Override public void onReceive(Context context, Intent intent) {
             String action = intent.getAction();
@@ -918,6 +927,31 @@
         return result;
     }
 
+    private IGpsGeofenceHardware mGpsGeofenceBinder = new IGpsGeofenceHardware.Stub() {
+        public boolean isHardwareGeofenceSupported() {
+            return native_is_geofence_supported();
+        }
+
+        public boolean addCircularHardwareGeofence(int geofenceId, double latitude,
+                double longitude, double radius, int lastTransition, int monitorTransitions,
+                int notificationResponsiveness, int unknownTimer) {
+            return native_add_geofence(geofenceId, latitude, longitude, radius,
+                    lastTransition, monitorTransitions, notificationResponsiveness, unknownTimer);
+        }
+
+        public boolean removeHardwareGeofence(int geofenceId) {
+            return native_remove_geofence(geofenceId);
+        }
+
+        public boolean pauseHardwareGeofence(int geofenceId) {
+            return native_pause_geofence(geofenceId);
+        }
+
+        public boolean resumeHardwareGeofence(int geofenceId, int monitorTransition) {
+            return native_resume_geofence(geofenceId, monitorTransition);
+        }
+    };
+
     private boolean deleteAidingData(Bundle extras) {
         int flags;
 
@@ -1017,6 +1051,7 @@
         return ((mEngineCapabilities & capability) != 0);
     }
 
+
     /**
      * called from native code to update our position.
      */
@@ -1320,6 +1355,73 @@
         sendMessage(DOWNLOAD_XTRA_DATA, 0, null);
     }
 
+    /**
+     * Called from native to report GPS Geofence transition
+     * All geofence callbacks are called on the same thread
+     */
+    private void reportGeofenceTransition(int geofenceId, int flags, double latitude,
+            double longitude, double altitude, float speed, float bearing, float accuracy,
+            long timestamp, int transition, long transitionTimestamp) {
+        if (mGeofenceHardwareImpl == null) {
+            mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
+        }
+        mGeofenceHardwareImpl.reportGpsGeofenceTransition(geofenceId, flags, latitude, longitude,
+           altitude, speed, bearing, accuracy, timestamp, transition, transitionTimestamp);
+    }
+
+    /**
+     * called from native code to report GPS status change.
+     */
+    private void reportGeofenceStatus(int status, int flags, double latitude,
+            double longitude, double altitude, float speed, float bearing, float accuracy,
+            long timestamp) {
+        if (mGeofenceHardwareImpl == null) {
+            mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
+        }
+        mGeofenceHardwareImpl.reportGpsGeofenceStatus(status, flags, latitude, longitude, altitude,
+            speed, bearing, accuracy, timestamp);
+    }
+
+    /**
+     * called from native code - Geofence Add callback
+     */
+    private void reportGeofenceAddStatus(int geofenceId, int status) {
+        if (mGeofenceHardwareImpl == null) {
+            mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
+        }
+        mGeofenceHardwareImpl.reportGpsGeofenceAddStatus(geofenceId, status);
+    }
+
+    /**
+     * called from native code - Geofence Remove callback
+     */
+    private void reportGeofenceRemoveStatus(int geofenceId, int status) {
+        if (mGeofenceHardwareImpl == null) {
+            mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
+        }
+        mGeofenceHardwareImpl.reportGpsGeofenceRemoveStatus(geofenceId, status);
+    }
+
+    /**
+     * called from native code - Geofence Pause callback
+     */
+    private void reportGeofencePauseStatus(int geofenceId, int status) {
+        if (mGeofenceHardwareImpl == null) {
+            mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
+        }
+        mGeofenceHardwareImpl.reportGpsGeofencePauseStatus(geofenceId, status);
+    }
+
+    /**
+     * called from native code - Geofence Resume callback
+     */
+    private void reportGeofenceResumeStatus(int geofenceId, int status) {
+        if (mGeofenceHardwareImpl == null) {
+            mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
+        }
+        mGeofenceHardwareImpl.reportGpsGeofenceResumeStatus(geofenceId, status);
+    }
+
     //=============================================================
     // NI Client support
     //=============================================================
@@ -1650,4 +1752,13 @@
 
     private native void native_update_network_state(boolean connected, int type,
             boolean roaming, boolean available, String extraInfo, String defaultAPN);
+
+    // Hardware Geofence support.
+    private static native boolean native_is_geofence_supported();
+    private static native boolean native_add_geofence(int geofenceId, double latitude,
+            double longitude, double radius, int lastTransition,int monitorTransitions,
+            int notificationResponsivenes, int unknownTimer);
+    private static native boolean native_remove_geofence(int geofenceId);
+    private static native boolean native_resume_geofence(int geofenceId, int transitions);
+    private static native boolean native_pause_geofence(int geofenceId);
 }
diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java
index 3d7dd63..154c4e8 100644
--- a/services/java/com/android/server/pm/PackageManagerService.java
+++ b/services/java/com/android/server/pm/PackageManagerService.java
@@ -2308,6 +2308,8 @@
     }
 
     public void revokePermission(String packageName, String permissionName) {
+        int changedAppId = -1;
+
         synchronized (mPackages) {
             final PackageParser.Package pkg = mPackages.get(packageName);
             if (pkg == null) {
@@ -2335,6 +2337,30 @@
                     gp.gids = removeInts(gp.gids, bp.gids);
                 }
                 mSettings.writeLPr();
+                changedAppId = ps.appId;
+            }
+        }
+
+        if (changedAppId >= 0) {
+            // We changed the perm on someone, kill its processes.
+            IActivityManager am = ActivityManagerNative.getDefault();
+            if (am != null) {
+                final int callingUserId = UserHandle.getCallingUserId();
+                final long ident = Binder.clearCallingIdentity();
+                try {
+                    //XXX we should only revoke for the calling user's app permissions,
+                    // but for now we impact all users.
+                    //am.killUid(UserHandle.getUid(callingUserId, changedAppId),
+                    //        "revoke " + permissionName);
+                    int[] users = sUserManager.getUserIds();
+                    for (int user : users) {
+                        am.killUid(UserHandle.getUid(user, changedAppId),
+                                "revoke " + permissionName);
+                    }
+                } catch (RemoteException e) {
+                } finally {
+                    Binder.restoreCallingIdentity(ident);
+                }
             }
         }
     }
@@ -8223,6 +8249,24 @@
             updatePermissionsLPw(newPackage.packageName, newPackage,
                     UPDATE_PERMISSIONS_REPLACE_PKG | (newPackage.permissions.size() > 0
                             ? UPDATE_PERMISSIONS_ALL : 0));
+            // For system-bundled packages, we assume that installing an upgraded version
+            // of the package implies that the user actually wants to run that new code,
+            // so we enable the package.
+            if (isSystemApp(newPackage)) {
+                // NB: implicit assumption that system package upgrades apply to all users
+                if (DEBUG_INSTALL) {
+                    Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName);
+                }
+                PackageSetting ps = mSettings.mPackages.get(pkgName);
+                if (ps != null) {
+                    if (res.origUsers != null) {
+                        for (int userHandle : res.origUsers) {
+                            ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT,
+                                    userHandle, installerPackageName);
+                        }
+                    }
+                }
+            }
             res.name = pkgName;
             res.uid = newPackage.applicationInfo.uid;
             res.pkg = newPackage;
@@ -10657,19 +10701,18 @@
                         || mSettings.mReadExternalStorageEnforced != enforced) {
                     mSettings.mReadExternalStorageEnforced = enforced;
                     mSettings.writeLPr();
-
-                    // kill any non-foreground processes so we restart them and
-                    // grant/revoke the GID.
-                    final IActivityManager am = ActivityManagerNative.getDefault();
-                    if (am != null) {
-                        final long token = Binder.clearCallingIdentity();
-                        try {
-                            am.killProcessesBelowForeground("setPermissionEnforcement");
-                        } catch (RemoteException e) {
-                        } finally {
-                            Binder.restoreCallingIdentity(token);
-                        }
-                    }
+                }
+            }
+            // kill any non-foreground processes so we restart them and
+            // grant/revoke the GID.
+            final IActivityManager am = ActivityManagerNative.getDefault();
+            if (am != null) {
+                final long token = Binder.clearCallingIdentity();
+                try {
+                    am.killProcessesBelowForeground("setPermissionEnforcement");
+                } catch (RemoteException e) {
+                } finally {
+                    Binder.restoreCallingIdentity(token);
                 }
             }
         } else {
diff --git a/services/java/com/android/server/pm/UserManagerService.java b/services/java/com/android/server/pm/UserManagerService.java
index aa1b2ff..3ef9370 100644
--- a/services/java/com/android/server/pm/UserManagerService.java
+++ b/services/java/com/android/server/pm/UserManagerService.java
@@ -963,7 +963,7 @@
     @Override
     public List<RestrictionEntry> getApplicationRestrictions(String packageName, int userId) {
         if (UserHandle.getCallingUserId() != userId
-                || Binder.getCallingUid() != getUidForPackage(packageName)) {
+                || !UserHandle.isSameApp(Binder.getCallingUid(), getUidForPackage(packageName))) {
             checkManageUsersPermission("Only system can get restrictions for other users/apps");
         }
         synchronized (mPackagesLock) {
@@ -976,7 +976,7 @@
     public void setApplicationRestrictions(String packageName, List<RestrictionEntry> entries,
             int userId) {
         if (UserHandle.getCallingUserId() != userId
-                || Binder.getCallingUid() != getUidForPackage(packageName)) {
+                || !UserHandle.isSameApp(Binder.getCallingUid(), getUidForPackage(packageName))) {
             checkManageUsersPermission("Only system can set restrictions for other users/apps");
         }
         synchronized (mPackagesLock) {
@@ -986,11 +986,14 @@
     }
 
     private int getUidForPackage(String packageName) {
+        long ident = Binder.clearCallingIdentity();
         try {
             return mContext.getPackageManager().getApplicationInfo(packageName,
                     PackageManager.GET_UNINSTALLED_PACKAGES).uid;
         } catch (NameNotFoundException nnfe) {
             return -1;
+        } finally {
+            Binder.restoreCallingIdentity(ident);
         }
     }
 
diff --git a/services/java/com/android/server/wm/AppWindowAnimator.java b/services/java/com/android/server/wm/AppWindowAnimator.java
index 297324b..6293dc6 100644
--- a/services/java/com/android/server/wm/AppWindowAnimator.java
+++ b/services/java/com/android/server/wm/AppWindowAnimator.java
@@ -4,6 +4,7 @@
 
 import android.graphics.Matrix;
 import android.util.Slog;
+import android.util.TimeUtils;
 import android.view.Display;
 import android.view.Surface;
 import android.view.SurfaceControl;
@@ -30,6 +31,11 @@
     // Protect with mAnimator.
     boolean freezingScreen;
 
+    /**
+     * How long we last kept the screen frozen.
+     */
+    int lastFreezeDuration;
+
     // Offset to the window of all layers in the token, for use by
     // AppWindowToken animations.
     int animLayerAdjustment;
@@ -287,6 +293,10 @@
         pw.print(prefix); pw.print("freezingScreen="); pw.print(freezingScreen);
                 pw.print(" allDrawn="); pw.print(allDrawn);
                 pw.print(" animLayerAdjustment="); pw.println(animLayerAdjustment);
+        if (lastFreezeDuration != 0) {
+            pw.print(prefix); pw.print("lastFreezeDuration=");
+                    TimeUtils.formatDuration(lastFreezeDuration, pw); pw.println();
+        }
         if (animating || animation != null) {
             pw.print(prefix); pw.print("animating="); pw.println(animating);
             pw.print(prefix); pw.print("animation="); pw.println(animation);
diff --git a/services/java/com/android/server/wm/WindowAnimator.java b/services/java/com/android/server/wm/WindowAnimator.java
index 3964782..054a075 100644
--- a/services/java/com/android/server/wm/WindowAnimator.java
+++ b/services/java/com/android/server/wm/WindowAnimator.java
@@ -70,6 +70,7 @@
     int mAboveUniverseLayer = 0;
 
     int mBulkUpdateParams = 0;
+    Object mLastWindowFreezeSource;
 
     SparseArray<DisplayContentsAnimator> mDisplayContentsAnimators =
             new SparseArray<WindowAnimator.DisplayContentsAnimator>();
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index af603fd..1d1fda5 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -43,6 +43,7 @@
 import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
 
 import android.app.AppOpsManager;
+import android.util.TimeUtils;
 import android.view.IWindowId;
 import com.android.internal.app.IBatteryStats;
 import com.android.internal.policy.PolicyManager;
@@ -464,6 +465,9 @@
 
     boolean mTraversalScheduled = false;
     boolean mDisplayFrozen = false;
+    long mDisplayFreezeTime = 0;
+    int mLastDisplayFreezeDuration = 0;
+    Object mLastFinishedFreezeSource = null;
     boolean mWaitingForConfig = false;
     boolean mWindowsFreezingScreen = false;
     boolean mClientFreezingScreen = false;
@@ -582,6 +586,7 @@
         boolean mWallpaperForceHidingChanged = false;
         boolean mWallpaperMayChange = false;
         boolean mOrientationChangeComplete = true;
+        Object mLastWindowFreezeSource = null;
         private Session mHoldScreen = null;
         private boolean mObscured = false;
         boolean mDimming = false;
@@ -3590,7 +3595,10 @@
 
         synchronized(mWindowMap) {
             mCurConfiguration = new Configuration(config);
-            mWaitingForConfig = false;
+            if (mWaitingForConfig) {
+                mWaitingForConfig = false;
+                mLastFinishedFreezeSource = "new-config";
+            }
             performLayoutAndPlaceSurfacesLocked();
         }
     }
@@ -4209,6 +4217,7 @@
                         w.mOrientationChanging = true;
                         mInnerFields.mOrientationChangeComplete = false;
                     }
+                    w.mLastFreezeDuration = 0;
                     unfrozeWindows = true;
                     w.mDisplayContent.layoutNeeded = true;
                 }
@@ -4216,7 +4225,10 @@
             if (force || unfrozeWindows) {
                 if (DEBUG_ORIENTATION) Slog.v(TAG, "No longer freezing: " + wtoken);
                 wtoken.mAppAnimator.freezingScreen = false;
+                wtoken.mAppAnimator.lastFreezeDuration = (int)(SystemClock.elapsedRealtime()
+                        - mDisplayFreezeTime);
                 mAppsFreezingScreen--;
+                mLastFinishedFreezeSource = wtoken;
             }
             if (unfreezeSurfaceNow) {
                 if (unfrozeWindows) {
@@ -4242,6 +4254,7 @@
         if (!wtoken.hiddenRequested) {
             if (!wtoken.mAppAnimator.freezingScreen) {
                 wtoken.mAppAnimator.freezingScreen = true;
+                wtoken.mAppAnimator.lastFreezeDuration = 0;
                 mAppsFreezingScreen++;
                 if (mAppsFreezingScreen == 1) {
                     startFreezingDisplayLocked(false, 0, 0);
@@ -4750,6 +4763,7 @@
         synchronized(mWindowMap) {
             if (mClientFreezingScreen) {
                 mClientFreezingScreen = false;
+                mLastFinishedFreezeSource = "client";
                 final long origId = Binder.clearCallingIdentity();
                 try {
                     stopFreezingDisplayLocked();
@@ -5742,6 +5756,7 @@
                 w.mOrientationChanging = true;
                 mInnerFields.mOrientationChangeComplete = false;
             }
+            w.mLastFreezeDuration = 0;
         }
 
         for (int i=mRotationWatchers.size()-1; i>=0; i--) {
@@ -6240,6 +6255,7 @@
             if (config == null && mWaitingForConfig) {
                 // Nothing changed but we are waiting for something... stop that!
                 mWaitingForConfig = false;
+                mLastFinishedFreezeSource = "new-config";
                 performLayoutAndPlaceSurfacesLocked();
             }
             return config;
@@ -7036,6 +7052,8 @@
                             WindowState w = windows.get(i);
                             if (w.mOrientationChanging) {
                                 w.mOrientationChanging = false;
+                                w.mLastFreezeDuration = (int)(SystemClock.elapsedRealtime()
+                                        - mDisplayFreezeTime);
                                 Slog.w(TAG, "Force clearing orientation change: " + w);
                             }
                         }
@@ -7112,6 +7130,7 @@
                     synchronized (mWindowMap) {
                         if (mClientFreezingScreen) {
                             mClientFreezingScreen = false;
+                            mLastFinishedFreezeSource = "client-timeout";
                             stopFreezingDisplayLocked();
                         }
                     }
@@ -8029,6 +8048,7 @@
             if (DEBUG_ORIENTATION) Slog.v(TAG,
                     "Changing surface while display frozen: " + w);
             w.mOrientationChanging = true;
+            w.mLastFreezeDuration = 0;
             mInnerFields.mOrientationChangeComplete = false;
             if (!mWindowsFreezingScreen) {
                 mWindowsFreezingScreen = true;
@@ -8417,6 +8437,8 @@
                             "Orientation not waiting for draw in "
                             + w + ", surface " + winAnimator.mSurfaceControl);
                     w.mOrientationChanging = false;
+                    w.mLastFreezeDuration = (int)(SystemClock.elapsedRealtime()
+                            - mDisplayFreezeTime);
                 }
             }
         }
@@ -8930,6 +8952,8 @@
                 winAnimator.mSurfaceResized = false;
             } catch (RemoteException e) {
                 win.mOrientationChanging = false;
+                win.mLastFreezeDuration = (int)(SystemClock.elapsedRealtime()
+                        - mDisplayFreezeTime);
             }
             mResizingWindows.remove(i);
         }
@@ -8940,6 +8964,7 @@
         if (mInnerFields.mOrientationChangeComplete) {
             if (mWindowsFreezingScreen) {
                 mWindowsFreezingScreen = false;
+                mLastFinishedFreezeSource = mInnerFields.mLastWindowFreezeSource;
                 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
             }
             stopFreezingDisplayLocked();
@@ -9226,6 +9251,7 @@
             mInnerFields.mOrientationChangeComplete = false;
         } else {
             mInnerFields.mOrientationChangeComplete = true;
+            mInnerFields.mLastWindowFreezeSource = mAnimator.mLastWindowFreezeSource;
             if (mWindowsFreezingScreen) {
                 doRequest = true;
             }
@@ -9498,6 +9524,8 @@
         mScreenFrozenLock.acquire();
 
         mDisplayFrozen = true;
+        mDisplayFreezeTime = SystemClock.elapsedRealtime();
+        mLastFinishedFreezeSource = null;
 
         mInputMonitor.freezeInputDispatchingLw();
 
@@ -9552,6 +9580,15 @@
         }
 
         mDisplayFrozen = false;
+        mLastDisplayFreezeDuration = (int)(SystemClock.elapsedRealtime() - mDisplayFreezeTime);
+        StringBuilder sb = new StringBuilder(128);
+        sb.append("Screen frozen for ");
+        TimeUtils.formatDuration(mLastDisplayFreezeDuration, sb);
+        if (mLastFinishedFreezeSource != null) {
+            sb.append(" due to ");
+            sb.append(mLastFinishedFreezeSource);
+        }
+        Slog.i(TAG, sb.toString());
         mH.removeMessages(H.APP_FREEZE_TIMEOUT);
         mH.removeMessages(H.CLIENT_FREEZE_TIMEOUT);
         if (PROFILE_ORIENTATION) {
@@ -10076,6 +10113,13 @@
         }
         pw.print("  mInTouchMode="); pw.print(mInTouchMode);
                 pw.print(" mLayoutSeq="); pw.println(mLayoutSeq);
+        pw.print("  mLastDisplayFreezeDuration=");
+                TimeUtils.formatDuration(mLastDisplayFreezeDuration, pw);
+                if ( mLastFinishedFreezeSource != null) {
+                    pw.print(" due to ");
+                    pw.print(mLastFinishedFreezeSource);
+                }
+                pw.println();
         if (dumpAll) {
             pw.print("  mSystemDecorRect="); pw.print(mSystemDecorRect.toShortString());
                     pw.print(" mSystemDecorLayer="); pw.print(mSystemDecorLayer);
diff --git a/services/java/com/android/server/wm/WindowState.java b/services/java/com/android/server/wm/WindowState.java
index 506fcec..ca060f4 100644
--- a/services/java/com/android/server/wm/WindowState.java
+++ b/services/java/com/android/server/wm/WindowState.java
@@ -26,6 +26,7 @@
 
 import android.app.AppOpsManager;
 import android.os.RemoteCallbackList;
+import android.util.TimeUtils;
 import android.view.IWindowFocusObserver;
 import android.view.IWindowId;
 import com.android.server.input.InputWindowHandle;
@@ -266,6 +267,11 @@
      */
     boolean mOrientationChanging;
 
+    /**
+     * How long we last kept the screen frozen.
+     */
+    int mLastFreezeDuration;
+
     /** Is this window now (or just being) removed? */
     boolean mRemoved;
 
@@ -1387,6 +1393,10 @@
                     pw.print(" mAppFreezing="); pw.print(mAppFreezing);
                     pw.print(" mTurnOnScreen="); pw.println(mTurnOnScreen);
         }
+        if (mLastFreezeDuration != 0) {
+            pw.print(prefix); pw.print("mLastFreezeDuration=");
+                    TimeUtils.formatDuration(mLastFreezeDuration, pw); pw.println();
+        }
         if (mHScale != 1 || mVScale != 1) {
             pw.print(prefix); pw.print("mHScale="); pw.print(mHScale);
                     pw.print(" mVScale="); pw.println(mVScale);
diff --git a/services/java/com/android/server/wm/WindowStateAnimator.java b/services/java/com/android/server/wm/WindowStateAnimator.java
index 3a9f7cb..c07174b 100644
--- a/services/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/java/com/android/server/wm/WindowStateAnimator.java
@@ -505,20 +505,20 @@
         public void setAlpha(float alpha) {
             super.setAlpha(alpha);
             if (alpha != mSurfaceTraceAlpha) {
+                mSurfaceTraceAlpha = alpha;
                 Slog.v(SURFACE_TAG, "setAlpha: " + this + ". Called by "
                         + Debug.getCallers(3));
             }
-            mSurfaceTraceAlpha = alpha;
         }
 
         @Override
         public void setLayer(int zorder) {
             super.setLayer(zorder);
             if (zorder != mLayer) {
+                mLayer = zorder;
                 Slog.v(SURFACE_TAG, "setLayer: " + this + ". Called by "
                         + Debug.getCallers(3));
             }
-            mLayer = zorder;
 
             sSurfaces.remove(this);
             int i;
@@ -535,20 +535,20 @@
         public void setPosition(float x, float y) {
             super.setPosition(x, y);
             if (x != mPosition.x || y != mPosition.y) {
+                mPosition.set(x, y);
                 Slog.v(SURFACE_TAG, "setPosition: " + this + ". Called by "
                         + Debug.getCallers(3));
             }
-            mPosition.set(x, y);
         }
 
         @Override
         public void setSize(int w, int h) {
             super.setSize(w, h);
             if (w != mSize.x || h != mSize.y) {
+                mSize.set(w, h);
                 Slog.v(SURFACE_TAG, "setSize: " + this + ". Called by "
                         + Debug.getCallers(3));
             }
-            mSize.set(w, h);
         }
 
         @Override
@@ -556,10 +556,10 @@
             super.setWindowCrop(crop);
             if (crop != null) {
                 if (!crop.equals(mWindowCrop)) {
+                    mWindowCrop.set(crop);
                     Slog.v(SURFACE_TAG, "setWindowCrop: " + this + ". Called by "
                             + Debug.getCallers(3));
                 }
-                mWindowCrop.set(crop);
             }
         }
 
@@ -567,28 +567,28 @@
         public void setLayerStack(int layerStack) {
             super.setLayerStack(layerStack);
             if (layerStack != mLayerStack) {
+                mLayerStack = layerStack;
                 Slog.v(SURFACE_TAG, "setLayerStack: " + this + ". Called by " + Debug.getCallers(3));
             }
-            mLayerStack = layerStack;
         }
 
         @Override
         public void hide() {
             super.hide();
             if (mShown) {
+                mShown = false;
                 Slog.v(SURFACE_TAG, "hide: " + this + ". Called by "
                         + Debug.getCallers(3));
             }
-            mShown = false;
         }
         @Override
         public void show() {
             super.show();
             if (!mShown) {
+                mShown = true;
                 Slog.v(SURFACE_TAG, "show: " + this + ". Called by "
                         + Debug.getCallers(3));
             }
-            mShown = true;
         }
 
         @Override
@@ -1307,6 +1307,7 @@
             if (w.mOrientationChanging) {
                 if (!w.isDrawnLw()) {
                     mAnimator.mBulkUpdateParams &= ~SET_ORIENTATION_CHANGE_COMPLETE;
+                    mAnimator.mLastWindowFreezeSource = w;
                     if (DEBUG_ORIENTATION) Slog.v(TAG,
                             "Orientation continue waiting for draw in " + w);
                 } else {
diff --git a/services/jni/Android.mk b/services/jni/Android.mk
index d097a93..b313d48 100644
--- a/services/jni/Android.mk
+++ b/services/jni/Android.mk
@@ -32,6 +32,7 @@
     libandroid_runtime \
     libandroidfw \
     libcutils \
+    liblog \
     libhardware \
     libhardware_legacy \
     libnativehelper \
diff --git a/services/jni/com_android_server_location_GpsLocationProvider.cpp b/services/jni/com_android_server_location_GpsLocationProvider.cpp
index 036fc43..98de12a 100644
--- a/services/jni/com_android_server_location_GpsLocationProvider.cpp
+++ b/services/jni/com_android_server_location_GpsLocationProvider.cpp
@@ -43,6 +43,12 @@
 static jmethodID method_requestRefLocation;
 static jmethodID method_requestSetID;
 static jmethodID method_requestUtcTime;
+static jmethodID method_reportGeofenceTransition;
+static jmethodID method_reportGeofenceStatus;
+static jmethodID method_reportGeofenceAddStatus;
+static jmethodID method_reportGeofenceRemoveStatus;
+static jmethodID method_reportGeofencePauseStatus;
+static jmethodID method_reportGeofenceResumeStatus;
 
 static const GpsInterface* sGpsInterface = NULL;
 static const GpsXtraInterface* sGpsXtraInterface = NULL;
@@ -50,6 +56,7 @@
 static const GpsNiInterface* sGpsNiInterface = NULL;
 static const GpsDebugInterface* sGpsDebugInterface = NULL;
 static const AGpsRilInterface* sAGpsRilInterface = NULL;
+static const GpsGeofencingInterface* sGpsGeofencingInterface = NULL;
 
 // temporary storage for GPS callbacks
 static GpsSvStatus  sGpsSvStatus;
@@ -107,7 +114,7 @@
 
 static void set_capabilities_callback(uint32_t capabilities)
 {
-    ALOGD("set_capabilities_callback: %ld\n", capabilities);
+    ALOGD("set_capabilities_callback: %du\n", capabilities);
     JNIEnv* env = AndroidRuntime::getJNIEnv();
     env->CallVoidMethod(mCallbacksObj, method_setEngineCapabilities, capabilities);
     checkAndClearExceptionFromCallback(env, __FUNCTION__);
@@ -233,6 +240,97 @@
     create_thread_callback,
 };
 
+static void gps_geofence_transition_callback(int32_t geofence_id,  GpsLocation* location,
+        int32_t transition, GpsUtcTime timestamp)
+{
+    JNIEnv* env = AndroidRuntime::getJNIEnv();
+
+    env->CallVoidMethod(mCallbacksObj, method_reportGeofenceTransition, geofence_id,
+            location->flags, (jdouble)location->latitude, (jdouble)location->longitude,
+            (jdouble)location->altitude,
+            (jfloat)location->speed, (jfloat)location->bearing,
+            (jfloat)location->accuracy, (jlong)location->timestamp,
+            transition, timestamp);
+    checkAndClearExceptionFromCallback(env, __FUNCTION__);
+};
+
+static void gps_geofence_status_callback(int32_t status, GpsLocation* location)
+{
+    JNIEnv* env = AndroidRuntime::getJNIEnv();
+    jint flags = 0;
+    jdouble latitude = 0;
+    jdouble longitude = 0;
+    jdouble altitude = 0;
+    jfloat speed = 0;
+    jfloat bearing = 0;
+    jfloat accuracy = 0;
+    jlong timestamp = 0;
+    if (location != NULL) {
+        flags = location->flags;
+        latitude = location->latitude;
+        longitude = location->longitude;
+        altitude = location->altitude;
+        speed = location->speed;
+        bearing = location->bearing;
+        accuracy = location->accuracy;
+        timestamp = location->timestamp;
+    }
+
+    env->CallVoidMethod(mCallbacksObj, method_reportGeofenceStatus, status,
+            flags, latitude, longitude, altitude, speed, bearing, accuracy, timestamp);
+    checkAndClearExceptionFromCallback(env, __FUNCTION__);
+};
+
+static void gps_geofence_add_callback(int32_t geofence_id, int32_t status)
+{
+    JNIEnv* env = AndroidRuntime::getJNIEnv();
+    if (status != GPS_GEOFENCE_OPERATION_SUCCESS) {
+        ALOGE("Error in geofence_add_callback: %d\n", status);
+    }
+    env->CallVoidMethod(mCallbacksObj, method_reportGeofenceAddStatus, geofence_id, status);
+    checkAndClearExceptionFromCallback(env, __FUNCTION__);
+};
+
+static void gps_geofence_remove_callback(int32_t geofence_id, int32_t status)
+{
+    JNIEnv* env = AndroidRuntime::getJNIEnv();
+    if (status != GPS_GEOFENCE_OPERATION_SUCCESS) {
+        ALOGE("Error in geofence_remove_callback: %d\n", status);
+    }
+    env->CallVoidMethod(mCallbacksObj, method_reportGeofenceRemoveStatus, geofence_id, status);
+    checkAndClearExceptionFromCallback(env, __FUNCTION__);
+};
+
+static void gps_geofence_resume_callback(int32_t geofence_id, int32_t status)
+{
+    JNIEnv* env = AndroidRuntime::getJNIEnv();
+    if (status != GPS_GEOFENCE_OPERATION_SUCCESS) {
+        ALOGE("Error in geofence_resume_callback: %d\n", status);
+    }
+    env->CallVoidMethod(mCallbacksObj, method_reportGeofenceResumeStatus, geofence_id, status);
+    checkAndClearExceptionFromCallback(env, __FUNCTION__);
+};
+
+static void gps_geofence_pause_callback(int32_t geofence_id, int32_t status)
+{
+    JNIEnv* env = AndroidRuntime::getJNIEnv();
+    if (status != GPS_GEOFENCE_OPERATION_SUCCESS) {
+        ALOGE("Error in geofence_pause_callback: %d\n", status);
+    }
+    env->CallVoidMethod(mCallbacksObj, method_reportGeofencePauseStatus, geofence_id, status);
+    checkAndClearExceptionFromCallback(env, __FUNCTION__);
+};
+
+GpsGeofenceCallbacks sGpsGeofenceCallbacks = {
+    gps_geofence_transition_callback,
+    gps_geofence_status_callback,
+    gps_geofence_add_callback,
+    gps_geofence_remove_callback,
+    gps_geofence_pause_callback,
+    gps_geofence_resume_callback,
+    create_thread_callback,
+};
+
 static void android_location_GpsLocationProvider_class_init_native(JNIEnv* env, jclass clazz) {
     int err;
     hw_module_t* module;
@@ -249,6 +347,18 @@
     method_requestRefLocation = env->GetMethodID(clazz,"requestRefLocation","(I)V");
     method_requestSetID = env->GetMethodID(clazz,"requestSetID","(I)V");
     method_requestUtcTime = env->GetMethodID(clazz,"requestUtcTime","()V");
+    method_reportGeofenceTransition = env->GetMethodID(clazz,"reportGeofenceTransition",
+            "(IIDDDFFFJIJ)V");
+    method_reportGeofenceStatus = env->GetMethodID(clazz,"reportGeofenceStatus",
+            "(IIDDDFFFJ)V");
+    method_reportGeofenceAddStatus = env->GetMethodID(clazz,"reportGeofenceAddStatus",
+            "(II)V");
+    method_reportGeofenceRemoveStatus = env->GetMethodID(clazz,"reportGeofenceRemoveStatus",
+            "(II)V");
+    method_reportGeofenceResumeStatus = env->GetMethodID(clazz,"reportGeofenceResumeStatus",
+            "(II)V");
+    method_reportGeofencePauseStatus = env->GetMethodID(clazz,"reportGeofencePauseStatus",
+            "(II)V");
 
     err = hw_get_module(GPS_HARDWARE_MODULE_ID, (hw_module_t const**)&module);
     if (err == 0) {
@@ -270,6 +380,8 @@
             (const GpsDebugInterface*)sGpsInterface->get_extension(GPS_DEBUG_INTERFACE);
         sAGpsRilInterface =
             (const AGpsRilInterface*)sGpsInterface->get_extension(AGPS_RIL_INTERFACE);
+        sGpsGeofencingInterface =
+            (const GpsGeofencingInterface*)sGpsInterface->get_extension(GPS_GEOFENCING_INTERFACE);
     }
 }
 
@@ -287,7 +399,7 @@
     if (!sGpsInterface || sGpsInterface->init(&sGpsCallbacks) != 0)
         return false;
 
-    // if XTRA initialization fails we will disable it by sGpsXtraInterface to null,
+    // if XTRA initialization fails we will disable it by sGpsXtraInterface to NULL,
     // but continue to allow the rest of the GPS interface to work.
     if (sGpsXtraInterface && sGpsXtraInterface->init(&sGpsXtraCallbacks) != 0)
         sGpsXtraInterface = NULL;
@@ -297,6 +409,8 @@
         sGpsNiInterface->init(&sGpsNiCallbacks);
     if (sAGpsRilInterface)
         sAGpsRilInterface->init(&sAGpsRilCallbacks);
+    if (sGpsGeofencingInterface)
+        sGpsGeofencingInterface->init(&sGpsGeofenceCallbacks);
 
     return true;
 }
@@ -565,6 +679,62 @@
     }
 }
 
+static jboolean android_location_GpsLocationProvider_is_geofence_supported(JNIEnv* env,
+          jobject obj) {
+    if (sGpsGeofencingInterface != NULL) {
+        return JNI_TRUE;
+    }
+    return JNI_FALSE;
+}
+
+static jboolean android_location_GpsLocationProvider_add_geofence(JNIEnv* env, jobject obj,
+        jint geofence_id, jdouble latitude, jdouble longitude, jdouble radius,
+        jint last_transition, jint monitor_transition, jint notification_responsiveness,
+        jint unknown_timer) {
+    if (sGpsGeofencingInterface != NULL) {
+        sGpsGeofencingInterface->add_geofence_area(geofence_id, latitude, longitude,
+                radius, last_transition, monitor_transition, notification_responsiveness,
+                unknown_timer);
+        return JNI_TRUE;
+    } else {
+        ALOGE("Geofence interface not available");
+    }
+    return JNI_FALSE;
+}
+
+static jboolean android_location_GpsLocationProvider_remove_geofence(JNIEnv* env, jobject obj,
+        jint geofence_id) {
+    if (sGpsGeofencingInterface != NULL) {
+        sGpsGeofencingInterface->remove_geofence_area(geofence_id);
+        return JNI_TRUE;
+    } else {
+        ALOGE("Geofence interface not available");
+    }
+    return JNI_FALSE;
+}
+
+static jboolean android_location_GpsLocationProvider_pause_geofence(JNIEnv* env, jobject obj,
+        jint geofence_id) {
+    if (sGpsGeofencingInterface != NULL) {
+        sGpsGeofencingInterface->pause_geofence(geofence_id);
+        return JNI_TRUE;
+    } else {
+        ALOGE("Geofence interface not available");
+    }
+    return JNI_FALSE;
+}
+
+static jboolean android_location_GpsLocationProvider_resume_geofence(JNIEnv* env, jobject obj,
+        jint geofence_id, jint monitor_transition) {
+    if (sGpsGeofencingInterface != NULL) {
+        sGpsGeofencingInterface->resume_geofence(geofence_id, monitor_transition);
+        return JNI_TRUE;
+    } else {
+        ALOGE("Geofence interface not available");
+    }
+    return JNI_FALSE;
+}
+
 static JNINativeMethod sMethods[] = {
      /* name, signature, funcPtr */
     {"class_init_native", "()V", (void *)android_location_GpsLocationProvider_class_init_native},
@@ -591,6 +761,11 @@
     {"native_agps_ni_message", "([BI)V", (void *)android_location_GpsLocationProvider_agps_send_ni_message},
     {"native_get_internal_state", "()Ljava/lang/String;", (void*)android_location_GpsLocationProvider_get_internal_state},
     {"native_update_network_state", "(ZIZZLjava/lang/String;Ljava/lang/String;)V", (void*)android_location_GpsLocationProvider_update_network_state },
+    {"native_is_geofence_supported", "()Z", (void*) android_location_GpsLocationProvider_is_geofence_supported},
+    {"native_add_geofence", "(IDDDIIII)Z", (void *)android_location_GpsLocationProvider_add_geofence},
+    {"native_remove_geofence", "(I)Z", (void *)android_location_GpsLocationProvider_remove_geofence},
+    {"native_pause_geofence", "(I)Z", (void *)android_location_GpsLocationProvider_pause_geofence},
+    {"native_resume_geofence", "(II)Z", (void *)android_location_GpsLocationProvider_resume_geofence}
 };
 
 int register_android_server_location_GpsLocationProvider(JNIEnv* env)
diff --git a/telephony/java/android/telephony/CellIdentityCdma.java b/telephony/java/android/telephony/CellIdentityCdma.java
index 6e2a70d..31e01c0 100644
--- a/telephony/java/android/telephony/CellIdentityCdma.java
+++ b/telephony/java/android/telephony/CellIdentityCdma.java
@@ -162,13 +162,13 @@
 
     @Override
     public String toString() {
-        StringBuilder sb = new StringBuilder("CdmaCellIdentitiy:");
-        sb.append(super.toString());
+        StringBuilder sb = new StringBuilder("CellIdentitiyCdma:{");
         sb.append(" mNetworkId="); sb.append(mNetworkId);
         sb.append(" mSystemId="); sb.append(mSystemId);
         sb.append(" mBasestationId="); sb.append(mBasestationId);
         sb.append(" mLongitude="); sb.append(mLongitude);
         sb.append(" mLatitude="); sb.append(mLatitude);
+        sb.append("}");
 
         return sb.toString();
     }
diff --git a/telephony/java/android/telephony/CellIdentityGsm.java b/telephony/java/android/telephony/CellIdentityGsm.java
index bda96be..98113e7 100644
--- a/telephony/java/android/telephony/CellIdentityGsm.java
+++ b/telephony/java/android/telephony/CellIdentityGsm.java
@@ -147,13 +147,13 @@
 
     @Override
     public String toString() {
-        StringBuilder sb = new StringBuilder("GsmCellIdentitiy:");
-        sb.append(super.toString());
+        StringBuilder sb = new StringBuilder("CellIdentitiyGsm:{");
         sb.append(" mMcc=").append(mMcc);
-        sb.append(" mMnc=").append(mMcc);
+        sb.append(" mMnc=").append(mMnc);
         sb.append(" mLac=").append(mLac);
         sb.append(" mCid=").append(mCid);
         sb.append(" mPsc=").append(mPsc);
+        sb.append("}");
 
         return sb.toString();
     }
diff --git a/telephony/java/android/telephony/CellIdentityLte.java b/telephony/java/android/telephony/CellIdentityLte.java
index f72d583..86924bd 100644
--- a/telephony/java/android/telephony/CellIdentityLte.java
+++ b/telephony/java/android/telephony/CellIdentityLte.java
@@ -142,13 +142,13 @@
 
     @Override
     public String toString() {
-        StringBuilder sb = new StringBuilder("LteCellIdentitiy:");
-        sb.append(super.toString());
+        StringBuilder sb = new StringBuilder("CellIdentitiyLte:{");
         sb.append(" mMcc="); sb.append(mMcc);
         sb.append(" mMnc="); sb.append(mMnc);
         sb.append(" mCi="); sb.append(mCi);
         sb.append(" mPci="); sb.append(mPci);
         sb.append(" mTac="); sb.append(mTac);
+        sb.append("}");
 
         return sb.toString();
     }
diff --git a/telephony/java/android/telephony/CellInfo.java b/telephony/java/android/telephony/CellInfo.java
index f367f99..fe3c68b 100644
--- a/telephony/java/android/telephony/CellInfo.java
+++ b/telephony/java/android/telephony/CellInfo.java
@@ -149,7 +149,7 @@
         StringBuffer sb = new StringBuffer();
         String timeStampType;
 
-        sb.append(" mRegistered=").append(mRegistered ? "YES" : "NO");
+        sb.append("mRegistered=").append(mRegistered ? "YES" : "NO");
         timeStampType = timeStampTypeToString(mTimeStampType);
         sb.append(" mTimeStampType=").append(timeStampType);
         sb.append(" mTimeStamp=").append(mTimeStamp).append("ns");
diff --git a/telephony/java/android/telephony/CellInfoCdma.java b/telephony/java/android/telephony/CellInfoCdma.java
index a5d6e9c..6f2f1f6 100644
--- a/telephony/java/android/telephony/CellInfoCdma.java
+++ b/telephony/java/android/telephony/CellInfoCdma.java
@@ -87,10 +87,11 @@
     public String toString() {
         StringBuffer sb = new StringBuffer();
 
-        sb.append("CellInfoCdma:");
+        sb.append("CellInfoCdma:{");
         sb.append(super.toString());
-        sb.append(", ").append(mCellIdentityCdma);
-        sb.append(", ").append(mCellSignalStrengthCdma);
+        sb.append(" ").append(mCellIdentityCdma);
+        sb.append(" ").append(mCellSignalStrengthCdma);
+        sb.append("}");
 
         return sb.toString();
     }
diff --git a/telephony/java/android/telephony/CellInfoGsm.java b/telephony/java/android/telephony/CellInfoGsm.java
index bf0eca8..1bedddb 100644
--- a/telephony/java/android/telephony/CellInfoGsm.java
+++ b/telephony/java/android/telephony/CellInfoGsm.java
@@ -87,10 +87,11 @@
     public String toString() {
         StringBuffer sb = new StringBuffer();
 
-        sb.append("CellInfoGsm:");
+        sb.append("CellInfoGsm:{");
         sb.append(super.toString());
-        sb.append(", ").append(mCellIdentityGsm);
-        sb.append(", ").append(mCellSignalStrengthGsm);
+        sb.append(" ").append(mCellIdentityGsm);
+        sb.append(" ").append(mCellSignalStrengthGsm);
+        sb.append("}");
 
         return sb.toString();
     }
diff --git a/telephony/java/android/telephony/CellInfoLte.java b/telephony/java/android/telephony/CellInfoLte.java
index d7a58b6..287c9f0 100644
--- a/telephony/java/android/telephony/CellInfoLte.java
+++ b/telephony/java/android/telephony/CellInfoLte.java
@@ -91,10 +91,11 @@
     public String toString() {
         StringBuffer sb = new StringBuffer();
 
-        sb.append("CellInfoLte:");
+        sb.append("CellInfoLte:{");
         sb.append(super.toString());
-        sb.append(", ").append(mCellIdentityLte);
-        sb.append(", ").append(mCellSignalStrengthLte);
+        sb.append(" ").append(mCellIdentityLte);
+        sb.append(" ").append(mCellSignalStrengthLte);
+        sb.append("}");
 
         return sb.toString();
     }
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 4aee902..6400e68 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -1341,7 +1341,8 @@
     }
 
     /**
-     * Returns all observed cell information of the device.
+     * Returns all observed cell information of the device. This does
+     * not cause or change the rate of PhoneStateListner#onCellInfoChanged.
      *
      * @return List of CellInfo or null if info unavailable.
      *
@@ -1357,4 +1358,24 @@
             return null;
         }
     }
+
+    /**
+     * Sets the minimum time in milli-seconds between {@link PhoneStateListener#onCellInfoChanged
+     * PhoneStateListener.onCellInfoChanged} will be invoked.
+     *
+     * The default, 0, means invoke onCellInfoChanged when any of the reported
+     * information changes. Setting the value to INT_MAX(0x7fffffff) means never issue
+     * A onCellInfoChanged.
+     *
+     * @param rateInMillis the rate
+     *
+     * @hide
+     */
+    public void setCellInfoListRate(int rateInMillis) {
+        try {
+            getITelephony().setCellInfoListRate(rateInMillis);
+        } catch (RemoteException ex) {
+        } catch (NullPointerException ex) {
+        }
+    }
 }
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index 1449ab1..b78f589 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -294,5 +294,10 @@
      * Returns the all observed cell information of the device.
      */
     List<CellInfo> getAllCellInfo();
+
+    /**
+     * Sets minimum time in milli-seconds between onCellInfoChanged
+     */
+    void setCellInfoListRate(int rateInMillis);
 }
 
diff --git a/telephony/java/com/android/internal/telephony/RILConstants.java b/telephony/java/com/android/internal/telephony/RILConstants.java
index 077ad68..9650b99 100644
--- a/telephony/java/com/android/internal/telephony/RILConstants.java
+++ b/telephony/java/com/android/internal/telephony/RILConstants.java
@@ -260,6 +260,8 @@
     int RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU = 106;
     int RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS = 107;
     int RIL_REQUEST_VOICE_RADIO_TECH = 108;
+    int RIL_REQUEST_GET_CELL_INFO_LIST = 109;
+    int RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE = 110;
     int RIL_UNSOL_RESPONSE_BASE = 1000;
     int RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED = 1000;
     int RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED = 1001;
@@ -297,4 +299,5 @@
     int RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE = 1033;
     int RIL_UNSOL_RIL_CONNECTED = 1034;
     int RIL_UNSOL_VOICE_RADIO_TECH_CHANGED = 1035;
+    int RIL_UNSOL_CELL_INFO_LIST = 1036;
 }
diff --git a/tests/Compatibility/src/com/android/compatibilitytest/AppCompatibility.java b/tests/Compatibility/src/com/android/compatibilitytest/AppCompatibility.java
index 4d60c83..7ae0fb8 100644
--- a/tests/Compatibility/src/com/android/compatibilitytest/AppCompatibility.java
+++ b/tests/Compatibility/src/com/android/compatibilitytest/AppCompatibility.java
@@ -127,6 +127,10 @@
         homeIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
 
         Intent intent = mPackageManager.getLaunchIntentForPackage(packageName);
+        // Skip if the apk does not have a launch intent.
+        if (intent == null) {
+            return null;
+        }
 
         // We check for any Crash or ANR dialogs that are already up, and we ignore them.  This is
         // so that we don't report crashes that were caused by prior apps (which those particular
diff --git a/tools/aapt/Android.mk b/tools/aapt/Android.mk
index 5b88669..9b1658a 100644
--- a/tools/aapt/Android.mk
+++ b/tools/aapt/Android.mk
@@ -39,14 +39,14 @@
 LOCAL_C_INCLUDES += external/zlib
 LOCAL_C_INCLUDES += build/libs/host/include
 
-#LOCAL_WHOLE_STATIC_LIBRARIES := 
 LOCAL_STATIC_LIBRARIES := \
 	libhost \
 	libandroidfw \
 	libutils \
 	libcutils \
 	libexpat \
-	libpng
+	libpng \
+	liblog
 
 ifeq ($(HOST_OS),linux)
 LOCAL_LDLIBS += -lrt -ldl -lpthread
diff --git a/tools/obbtool/Android.mk b/tools/obbtool/Android.mk
index dd57ae6..ad8de69 100644
--- a/tools/obbtool/Android.mk
+++ b/tools/obbtool/Android.mk
@@ -20,7 +20,8 @@
 LOCAL_STATIC_LIBRARIES := \
 	libutils \
 	libandroidfw \
-	libcutils
+	libcutils \
+	liblog
 
 ifeq ($(HOST_OS),linux)
 LOCAL_LDLIBS += -ldl -lpthread
diff --git a/tools/validatekeymaps/Android.mk b/tools/validatekeymaps/Android.mk
index fce2e93..90fbc08 100644
--- a/tools/validatekeymaps/Android.mk
+++ b/tools/validatekeymaps/Android.mk
@@ -20,7 +20,8 @@
 LOCAL_STATIC_LIBRARIES := \
 	libandroidfw \
 	libutils \
-	libcutils
+	libcutils \
+	liblog
 
 ifeq ($(HOST_OS),linux)
 LOCAL_LDLIBS += -ldl -lpthread
diff --git a/wifi/java/android/net/wifi/WifiConfigStore.java b/wifi/java/android/net/wifi/WifiConfigStore.java
index 47f1fbf..7b1a71f 100644
--- a/wifi/java/android/net/wifi/WifiConfigStore.java
+++ b/wifi/java/android/net/wifi/WifiConfigStore.java
@@ -1196,7 +1196,7 @@
             WifiConfiguration newConfig) {
         boolean ipChanged = false;
         boolean proxyChanged = false;
-        LinkProperties linkProperties = new LinkProperties();
+        LinkProperties linkProperties = null;
 
         switch (newConfig.ipAssignment) {
             case STATIC:
@@ -1262,10 +1262,10 @@
         }
 
         if (!ipChanged) {
-            addIpSettingsFromConfig(linkProperties, currentConfig);
+            linkProperties = copyIpSettingsFromConfig(currentConfig);
         } else {
             currentConfig.ipAssignment = newConfig.ipAssignment;
-            addIpSettingsFromConfig(linkProperties, newConfig);
+            linkProperties = copyIpSettingsFromConfig(newConfig);
             log("IP config changed SSID = " + currentConfig.SSID + " linkProperties: " +
                     linkProperties.toString());
         }
@@ -1291,8 +1291,9 @@
         return new NetworkUpdateResult(ipChanged, proxyChanged);
     }
 
-    private void addIpSettingsFromConfig(LinkProperties linkProperties,
-            WifiConfiguration config) {
+    private LinkProperties copyIpSettingsFromConfig(WifiConfiguration config) {
+        LinkProperties linkProperties = new LinkProperties();
+        linkProperties.setInterfaceName(config.linkProperties.getInterfaceName());
         for (LinkAddress linkAddr : config.linkProperties.getLinkAddresses()) {
             linkProperties.addLinkAddress(linkAddr);
         }
@@ -1302,6 +1303,7 @@
         for (InetAddress dns : config.linkProperties.getDnses()) {
             linkProperties.addDns(dns);
         }
+        return linkProperties;
     }
 
     /**