Merge "Debug logging improvement." 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 4236eae..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
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/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/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 98b7877..c1db4c6 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -4284,7 +4284,7 @@
                     enqueueInputEvent(e);
                     Message m = obtainMessage(MSG_ENQUEUE_X_AXIS_KEY_REPEAT, e);
                     m.setAsynchronous(true);
-                    mHandler.sendMessageDelayed(m, ViewConfiguration.getKeyRepeatTimeout());
+                    sendMessageDelayed(m, ViewConfiguration.getKeyRepeatTimeout());
                 }
             }
 
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/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 90e3b8d..8ebc88c 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 -->
     <!-- ======================================= -->
@@ -2350,6 +2358,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/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 65363da..ce76d40 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -1052,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>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 8ec00c3..132d4cc 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -1052,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>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 688f524..e13c0f2 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -1052,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>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index 4c88a71..6653ac1 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -1052,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>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 9ff9321..3d3e195 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -1052,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>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 6dff5d1..c96bef8 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -1052,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>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 7036fbe..4738834 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -1052,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>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 40dcfbd..6c16e56 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -1052,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>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 51a8504..ead4004 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -1052,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>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index a30b8cf..ac4ec2e 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -1052,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>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index 060322d..5285532 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -1052,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>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index f0786a9..20f0c33 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -1052,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>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index ec3308d..7dc03bec 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -1052,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>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index 8ec5525..e78e169 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -1052,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>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index d64265b..3ab64c0 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -1052,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>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 131d937..86a9fae 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -1052,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>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 9fe514d..3b539da8 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -1052,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>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 2fc5e2a..ac20919 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -1052,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>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 9c45b4b..9569a6c 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -1052,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>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 96380cd..61e3707 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -1052,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>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 40c466b..f4664e9 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -1052,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>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 79c1f51..592492a 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -1052,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>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 5430506..97c52c5 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -1052,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>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index a828c41..0abacb1 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -1052,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>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 9450a49..b07878c 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -1052,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>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index e20e1c9..1b7b68e 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -1052,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>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 3bf284f..9ae5381d 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -1052,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>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index 894352d..bbde90d 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -1052,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>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index c0f316f..3bb5022 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -1052,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>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 77e243e..4d71f08 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -1052,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>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index cae4008..f4fe466 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -1052,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>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 407ad6d..36751b1 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -1052,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>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index a14ebdd..61716fe 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -1052,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>
@@ -1425,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>
diff --git a/core/res/res/values-rm/strings.xml b/core/res/res/values-rm/strings.xml
index b850bfd..ba863cb 100644
--- a/core/res/res/values-rm/strings.xml
+++ b/core/res/res/values-rm/strings.xml
@@ -1638,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>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index f48e540..003f932 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -1052,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>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index eed5868..2c8dfe8 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -1052,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>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index a08262e..80a2c31 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -1052,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>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 0d09190..766b605 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -1052,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>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 5eff70b..15b9ec5 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -1052,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>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 4b831af..291681c 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -1052,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>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index b770143..c8f1343 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -1052,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>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index a8bb17b..66b3199 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -1052,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>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 323a673..bd5f99d 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -1052,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>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 414e9bd9..79c3706 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -1052,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>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index cb0b863..ad206d3 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -1052,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>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 1880369..4022f04 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -1052,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>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 7b52f15..5ebd3c7 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -1052,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>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 3faf789..a0c8c05 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -1052,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>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index afd183d..7f62603 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -1052,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>
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/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/graphics/java/android/renderscript/RenderScript.java b/graphics/java/android/renderscript/RenderScript.java
index 2438532..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 {
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 9221c7a..2f69775 100644
--- a/graphics/java/android/renderscript/ScriptC.java
+++ b/graphics/java/android/renderscript/ScriptC.java
@@ -64,6 +64,12 @@
         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;
@@ -96,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/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/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/opengl/java/android/opengl/GLSurfaceView.java b/opengl/java/android/opengl/GLSurfaceView.java
index daa5d13..ab7ceb6 100644
--- a/opengl/java/android/opengl/GLSurfaceView.java
+++ b/opengl/java/android/opengl/GLSurfaceView.java
@@ -1507,7 +1507,7 @@
             mPaused = false;
             updateState();
             if (mRenderMode == RENDERMODE_WHEN_DIRTY) {
-                executeDraw();
+                requestRender();
             }
         }
 
diff --git a/services/input/EventHub.cpp b/services/input/EventHub.cpp
index f4e1cec..376de96 100644
--- a/services/input/EventHub.cpp
+++ b/services/input/EventHub.cpp
@@ -1188,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) &&
@@ -1210,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/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/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/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 3991bdd..c07174b 100644
--- a/services/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/java/com/android/server/wm/WindowStateAnimator.java
@@ -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/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/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