Merge "Use clock's widget as the default keyguard widget" into jb-mr1-lockscreen-dev
diff --git a/api/17.txt b/api/17.txt
index bdc7b19..6b893d5 100644
--- a/api/17.txt
+++ b/api/17.txt
@@ -10582,7 +10582,7 @@
     field public static final android.os.Parcelable.Creator CREATOR;
   }
 
-  public deprecated class Criteria implements android.os.Parcelable {
+  public class Criteria implements android.os.Parcelable {
     ctor public Criteria();
     ctor public Criteria(android.location.Criteria);
     method public int describeContents();
@@ -10628,13 +10628,6 @@
     method public static boolean isPresent();
   }
 
-  public final class Geofence implements android.os.Parcelable {
-    method public static android.location.Geofence createCircle(double, double, float);
-    method public int describeContents();
-    method public void writeToParcel(android.os.Parcel, int);
-    field public static final android.os.Parcelable.Creator CREATOR;
-  }
-
   public final class GpsSatellite {
     method public float getAzimuth();
     method public float getElevation();
@@ -10680,7 +10673,7 @@
     method public android.os.Bundle getExtras();
     method public double getLatitude();
     method public double getLongitude();
-    method public deprecated java.lang.String getProvider();
+    method public java.lang.String getProvider();
     method public float getSpeed();
     method public long getTime();
     method public boolean hasAccuracy();
@@ -10718,57 +10711,51 @@
   }
 
   public class LocationManager {
-    method public void addGeofence(android.location.LocationRequest, android.location.Geofence, android.app.PendingIntent);
     method public boolean addGpsStatusListener(android.location.GpsStatus.Listener);
     method public boolean addNmeaListener(android.location.GpsStatus.NmeaListener);
-    method public deprecated void addProximityAlert(double, double, float, long, android.app.PendingIntent);
-    method public deprecated void addTestProvider(java.lang.String, boolean, boolean, boolean, boolean, boolean, boolean, boolean, int, int);
-    method public deprecated void clearTestProviderEnabled(java.lang.String);
-    method public deprecated void clearTestProviderLocation(java.lang.String);
-    method public deprecated void clearTestProviderStatus(java.lang.String);
-    method public deprecated java.util.List<java.lang.String> getAllProviders();
-    method public deprecated java.lang.String getBestProvider(android.location.Criteria, boolean);
+    method public void addProximityAlert(double, double, float, long, android.app.PendingIntent);
+    method public void addTestProvider(java.lang.String, boolean, boolean, boolean, boolean, boolean, boolean, boolean, int, int);
+    method public void clearTestProviderEnabled(java.lang.String);
+    method public void clearTestProviderLocation(java.lang.String);
+    method public void clearTestProviderStatus(java.lang.String);
+    method public java.util.List<java.lang.String> getAllProviders();
+    method public java.lang.String getBestProvider(android.location.Criteria, boolean);
     method public android.location.GpsStatus getGpsStatus(android.location.GpsStatus);
-    method public deprecated android.location.Location getLastKnownLocation(java.lang.String);
-    method public android.location.Location getLastLocation();
-    method public deprecated android.location.LocationProvider getProvider(java.lang.String);
-    method public deprecated java.util.List<java.lang.String> getProviders(boolean);
-    method public deprecated java.util.List<java.lang.String> getProviders(android.location.Criteria, boolean);
-    method public deprecated boolean isProviderEnabled(java.lang.String);
-    method public void removeAllGeofences(android.app.PendingIntent);
-    method public void removeGeofence(android.location.Geofence, android.app.PendingIntent);
+    method public android.location.Location getLastKnownLocation(java.lang.String);
+    method public android.location.LocationProvider getProvider(java.lang.String);
+    method public java.util.List<java.lang.String> getProviders(boolean);
+    method public java.util.List<java.lang.String> getProviders(android.location.Criteria, boolean);
+    method public boolean isProviderEnabled(java.lang.String);
     method public void removeGpsStatusListener(android.location.GpsStatus.Listener);
     method public void removeNmeaListener(android.location.GpsStatus.NmeaListener);
-    method public deprecated void removeProximityAlert(android.app.PendingIntent);
-    method public deprecated void removeTestProvider(java.lang.String);
+    method public void removeProximityAlert(android.app.PendingIntent);
+    method public void removeTestProvider(java.lang.String);
     method public void removeUpdates(android.location.LocationListener);
     method public void removeUpdates(android.app.PendingIntent);
-    method public deprecated void requestLocationUpdates(java.lang.String, long, float, android.location.LocationListener);
-    method public deprecated void requestLocationUpdates(java.lang.String, long, float, android.location.LocationListener, android.os.Looper);
-    method public deprecated void requestLocationUpdates(long, float, android.location.Criteria, android.location.LocationListener, android.os.Looper);
-    method public deprecated void requestLocationUpdates(java.lang.String, long, float, android.app.PendingIntent);
-    method public deprecated void requestLocationUpdates(long, float, android.location.Criteria, android.app.PendingIntent);
-    method public void requestLocationUpdates(android.location.LocationRequest, android.location.LocationListener, android.os.Looper);
-    method public void requestLocationUpdates(android.location.LocationRequest, android.app.PendingIntent);
-    method public deprecated void requestSingleUpdate(java.lang.String, android.location.LocationListener, android.os.Looper);
-    method public deprecated void requestSingleUpdate(android.location.Criteria, android.location.LocationListener, android.os.Looper);
-    method public deprecated void requestSingleUpdate(java.lang.String, android.app.PendingIntent);
-    method public deprecated void requestSingleUpdate(android.location.Criteria, android.app.PendingIntent);
-    method public deprecated boolean sendExtraCommand(java.lang.String, java.lang.String, android.os.Bundle);
-    method public deprecated void setTestProviderEnabled(java.lang.String, boolean);
-    method public deprecated void setTestProviderLocation(java.lang.String, android.location.Location);
-    method public deprecated void setTestProviderStatus(java.lang.String, int, android.os.Bundle, long);
-    field public static final deprecated java.lang.String GPS_PROVIDER = "gps";
+    method public void requestLocationUpdates(java.lang.String, long, float, android.location.LocationListener);
+    method public void requestLocationUpdates(java.lang.String, long, float, android.location.LocationListener, android.os.Looper);
+    method public void requestLocationUpdates(long, float, android.location.Criteria, android.location.LocationListener, android.os.Looper);
+    method public void requestLocationUpdates(java.lang.String, long, float, android.app.PendingIntent);
+    method public void requestLocationUpdates(long, float, android.location.Criteria, android.app.PendingIntent);
+    method public void requestSingleUpdate(java.lang.String, android.location.LocationListener, android.os.Looper);
+    method public void requestSingleUpdate(android.location.Criteria, android.location.LocationListener, android.os.Looper);
+    method public void requestSingleUpdate(java.lang.String, android.app.PendingIntent);
+    method public void requestSingleUpdate(android.location.Criteria, android.app.PendingIntent);
+    method public boolean sendExtraCommand(java.lang.String, java.lang.String, android.os.Bundle);
+    method public void setTestProviderEnabled(java.lang.String, boolean);
+    method public void setTestProviderLocation(java.lang.String, android.location.Location);
+    method public void setTestProviderStatus(java.lang.String, int, android.os.Bundle, long);
+    field public static final java.lang.String GPS_PROVIDER = "gps";
     field public static final java.lang.String KEY_LOCATION_CHANGED = "location";
-    field public static final deprecated java.lang.String KEY_PROVIDER_ENABLED = "providerEnabled";
+    field public static final java.lang.String KEY_PROVIDER_ENABLED = "providerEnabled";
     field public static final java.lang.String KEY_PROXIMITY_ENTERING = "entering";
-    field public static final deprecated java.lang.String KEY_STATUS_CHANGED = "status";
-    field public static final deprecated java.lang.String NETWORK_PROVIDER = "network";
-    field public static final deprecated java.lang.String PASSIVE_PROVIDER = "passive";
-    field public static final deprecated java.lang.String PROVIDERS_CHANGED_ACTION = "android.location.PROVIDERS_CHANGED";
+    field public static final java.lang.String KEY_STATUS_CHANGED = "status";
+    field public static final java.lang.String NETWORK_PROVIDER = "network";
+    field public static final java.lang.String PASSIVE_PROVIDER = "passive";
+    field public static final java.lang.String PROVIDERS_CHANGED_ACTION = "android.location.PROVIDERS_CHANGED";
   }
 
-  public deprecated class LocationProvider {
+  public class LocationProvider {
     method public int getAccuracy();
     method public java.lang.String getName();
     method public int getPowerRequirement();
@@ -10785,30 +10772,6 @@
     field public static final int TEMPORARILY_UNAVAILABLE = 1; // 0x1
   }
 
-  public final class LocationRequest implements android.os.Parcelable {
-    method public static android.location.LocationRequest create();
-    method public int describeContents();
-    method public long getExpireAt();
-    method public long getFastestInterval();
-    method public long getInterval();
-    method public int getNumUpdates();
-    method public int getQuality();
-    method public android.location.LocationRequest setExpireAt(long);
-    method public android.location.LocationRequest setExpireIn(long);
-    method public android.location.LocationRequest setFastestInterval(long);
-    method public android.location.LocationRequest setInterval(long);
-    method public android.location.LocationRequest setNumUpdates(int);
-    method public android.location.LocationRequest setQuality(int);
-    method public void writeToParcel(android.os.Parcel, int);
-    field public static final int ACCURACY_BLOCK = 102; // 0x66
-    field public static final int ACCURACY_CITY = 104; // 0x68
-    field public static final int ACCURACY_FINE = 100; // 0x64
-    field public static final android.os.Parcelable.Creator CREATOR;
-    field public static final int POWER_HIGH = 203; // 0xcb
-    field public static final int POWER_LOW = 201; // 0xc9
-    field public static final int POWER_NONE = 200; // 0xc8
-  }
-
 }
 
 package android.media {
diff --git a/api/current.txt b/api/current.txt
index bdc7b19..6b893d5 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -10582,7 +10582,7 @@
     field public static final android.os.Parcelable.Creator CREATOR;
   }
 
-  public deprecated class Criteria implements android.os.Parcelable {
+  public class Criteria implements android.os.Parcelable {
     ctor public Criteria();
     ctor public Criteria(android.location.Criteria);
     method public int describeContents();
@@ -10628,13 +10628,6 @@
     method public static boolean isPresent();
   }
 
-  public final class Geofence implements android.os.Parcelable {
-    method public static android.location.Geofence createCircle(double, double, float);
-    method public int describeContents();
-    method public void writeToParcel(android.os.Parcel, int);
-    field public static final android.os.Parcelable.Creator CREATOR;
-  }
-
   public final class GpsSatellite {
     method public float getAzimuth();
     method public float getElevation();
@@ -10680,7 +10673,7 @@
     method public android.os.Bundle getExtras();
     method public double getLatitude();
     method public double getLongitude();
-    method public deprecated java.lang.String getProvider();
+    method public java.lang.String getProvider();
     method public float getSpeed();
     method public long getTime();
     method public boolean hasAccuracy();
@@ -10718,57 +10711,51 @@
   }
 
   public class LocationManager {
-    method public void addGeofence(android.location.LocationRequest, android.location.Geofence, android.app.PendingIntent);
     method public boolean addGpsStatusListener(android.location.GpsStatus.Listener);
     method public boolean addNmeaListener(android.location.GpsStatus.NmeaListener);
-    method public deprecated void addProximityAlert(double, double, float, long, android.app.PendingIntent);
-    method public deprecated void addTestProvider(java.lang.String, boolean, boolean, boolean, boolean, boolean, boolean, boolean, int, int);
-    method public deprecated void clearTestProviderEnabled(java.lang.String);
-    method public deprecated void clearTestProviderLocation(java.lang.String);
-    method public deprecated void clearTestProviderStatus(java.lang.String);
-    method public deprecated java.util.List<java.lang.String> getAllProviders();
-    method public deprecated java.lang.String getBestProvider(android.location.Criteria, boolean);
+    method public void addProximityAlert(double, double, float, long, android.app.PendingIntent);
+    method public void addTestProvider(java.lang.String, boolean, boolean, boolean, boolean, boolean, boolean, boolean, int, int);
+    method public void clearTestProviderEnabled(java.lang.String);
+    method public void clearTestProviderLocation(java.lang.String);
+    method public void clearTestProviderStatus(java.lang.String);
+    method public java.util.List<java.lang.String> getAllProviders();
+    method public java.lang.String getBestProvider(android.location.Criteria, boolean);
     method public android.location.GpsStatus getGpsStatus(android.location.GpsStatus);
-    method public deprecated android.location.Location getLastKnownLocation(java.lang.String);
-    method public android.location.Location getLastLocation();
-    method public deprecated android.location.LocationProvider getProvider(java.lang.String);
-    method public deprecated java.util.List<java.lang.String> getProviders(boolean);
-    method public deprecated java.util.List<java.lang.String> getProviders(android.location.Criteria, boolean);
-    method public deprecated boolean isProviderEnabled(java.lang.String);
-    method public void removeAllGeofences(android.app.PendingIntent);
-    method public void removeGeofence(android.location.Geofence, android.app.PendingIntent);
+    method public android.location.Location getLastKnownLocation(java.lang.String);
+    method public android.location.LocationProvider getProvider(java.lang.String);
+    method public java.util.List<java.lang.String> getProviders(boolean);
+    method public java.util.List<java.lang.String> getProviders(android.location.Criteria, boolean);
+    method public boolean isProviderEnabled(java.lang.String);
     method public void removeGpsStatusListener(android.location.GpsStatus.Listener);
     method public void removeNmeaListener(android.location.GpsStatus.NmeaListener);
-    method public deprecated void removeProximityAlert(android.app.PendingIntent);
-    method public deprecated void removeTestProvider(java.lang.String);
+    method public void removeProximityAlert(android.app.PendingIntent);
+    method public void removeTestProvider(java.lang.String);
     method public void removeUpdates(android.location.LocationListener);
     method public void removeUpdates(android.app.PendingIntent);
-    method public deprecated void requestLocationUpdates(java.lang.String, long, float, android.location.LocationListener);
-    method public deprecated void requestLocationUpdates(java.lang.String, long, float, android.location.LocationListener, android.os.Looper);
-    method public deprecated void requestLocationUpdates(long, float, android.location.Criteria, android.location.LocationListener, android.os.Looper);
-    method public deprecated void requestLocationUpdates(java.lang.String, long, float, android.app.PendingIntent);
-    method public deprecated void requestLocationUpdates(long, float, android.location.Criteria, android.app.PendingIntent);
-    method public void requestLocationUpdates(android.location.LocationRequest, android.location.LocationListener, android.os.Looper);
-    method public void requestLocationUpdates(android.location.LocationRequest, android.app.PendingIntent);
-    method public deprecated void requestSingleUpdate(java.lang.String, android.location.LocationListener, android.os.Looper);
-    method public deprecated void requestSingleUpdate(android.location.Criteria, android.location.LocationListener, android.os.Looper);
-    method public deprecated void requestSingleUpdate(java.lang.String, android.app.PendingIntent);
-    method public deprecated void requestSingleUpdate(android.location.Criteria, android.app.PendingIntent);
-    method public deprecated boolean sendExtraCommand(java.lang.String, java.lang.String, android.os.Bundle);
-    method public deprecated void setTestProviderEnabled(java.lang.String, boolean);
-    method public deprecated void setTestProviderLocation(java.lang.String, android.location.Location);
-    method public deprecated void setTestProviderStatus(java.lang.String, int, android.os.Bundle, long);
-    field public static final deprecated java.lang.String GPS_PROVIDER = "gps";
+    method public void requestLocationUpdates(java.lang.String, long, float, android.location.LocationListener);
+    method public void requestLocationUpdates(java.lang.String, long, float, android.location.LocationListener, android.os.Looper);
+    method public void requestLocationUpdates(long, float, android.location.Criteria, android.location.LocationListener, android.os.Looper);
+    method public void requestLocationUpdates(java.lang.String, long, float, android.app.PendingIntent);
+    method public void requestLocationUpdates(long, float, android.location.Criteria, android.app.PendingIntent);
+    method public void requestSingleUpdate(java.lang.String, android.location.LocationListener, android.os.Looper);
+    method public void requestSingleUpdate(android.location.Criteria, android.location.LocationListener, android.os.Looper);
+    method public void requestSingleUpdate(java.lang.String, android.app.PendingIntent);
+    method public void requestSingleUpdate(android.location.Criteria, android.app.PendingIntent);
+    method public boolean sendExtraCommand(java.lang.String, java.lang.String, android.os.Bundle);
+    method public void setTestProviderEnabled(java.lang.String, boolean);
+    method public void setTestProviderLocation(java.lang.String, android.location.Location);
+    method public void setTestProviderStatus(java.lang.String, int, android.os.Bundle, long);
+    field public static final java.lang.String GPS_PROVIDER = "gps";
     field public static final java.lang.String KEY_LOCATION_CHANGED = "location";
-    field public static final deprecated java.lang.String KEY_PROVIDER_ENABLED = "providerEnabled";
+    field public static final java.lang.String KEY_PROVIDER_ENABLED = "providerEnabled";
     field public static final java.lang.String KEY_PROXIMITY_ENTERING = "entering";
-    field public static final deprecated java.lang.String KEY_STATUS_CHANGED = "status";
-    field public static final deprecated java.lang.String NETWORK_PROVIDER = "network";
-    field public static final deprecated java.lang.String PASSIVE_PROVIDER = "passive";
-    field public static final deprecated java.lang.String PROVIDERS_CHANGED_ACTION = "android.location.PROVIDERS_CHANGED";
+    field public static final java.lang.String KEY_STATUS_CHANGED = "status";
+    field public static final java.lang.String NETWORK_PROVIDER = "network";
+    field public static final java.lang.String PASSIVE_PROVIDER = "passive";
+    field public static final java.lang.String PROVIDERS_CHANGED_ACTION = "android.location.PROVIDERS_CHANGED";
   }
 
-  public deprecated class LocationProvider {
+  public class LocationProvider {
     method public int getAccuracy();
     method public java.lang.String getName();
     method public int getPowerRequirement();
@@ -10785,30 +10772,6 @@
     field public static final int TEMPORARILY_UNAVAILABLE = 1; // 0x1
   }
 
-  public final class LocationRequest implements android.os.Parcelable {
-    method public static android.location.LocationRequest create();
-    method public int describeContents();
-    method public long getExpireAt();
-    method public long getFastestInterval();
-    method public long getInterval();
-    method public int getNumUpdates();
-    method public int getQuality();
-    method public android.location.LocationRequest setExpireAt(long);
-    method public android.location.LocationRequest setExpireIn(long);
-    method public android.location.LocationRequest setFastestInterval(long);
-    method public android.location.LocationRequest setInterval(long);
-    method public android.location.LocationRequest setNumUpdates(int);
-    method public android.location.LocationRequest setQuality(int);
-    method public void writeToParcel(android.os.Parcel, int);
-    field public static final int ACCURACY_BLOCK = 102; // 0x66
-    field public static final int ACCURACY_CITY = 104; // 0x68
-    field public static final int ACCURACY_FINE = 100; // 0x64
-    field public static final android.os.Parcelable.Creator CREATOR;
-    field public static final int POWER_HIGH = 203; // 0xcb
-    field public static final int POWER_LOW = 201; // 0xc9
-    field public static final int POWER_NONE = 200; // 0xc8
-  }
-
 }
 
 package android.media {
diff --git a/core/java/android/webkit/AccessibilityInjector.java b/core/java/android/webkit/AccessibilityInjector.java
index 95a0416..008a615 100644
--- a/core/java/android/webkit/AccessibilityInjector.java
+++ b/core/java/android/webkit/AccessibilityInjector.java
@@ -18,6 +18,7 @@
 
 import android.content.Context;
 import android.os.Bundle;
+import android.os.Handler;
 import android.os.SystemClock;
 import android.provider.Settings;
 import android.speech.tts.TextToSpeech;
@@ -159,7 +160,7 @@
      * <p>
      * This should only be called before a page loads.
      */
-    private void addAccessibilityApisIfNecessary() {
+    public void addAccessibilityApisIfNecessary() {
         if (!isAccessibilityEnabled() || !isJavaScriptEnabled()) {
             return;
         }
@@ -333,8 +334,9 @@
      */
     public void onPageStarted(String url) {
         mAccessibilityScriptInjected = false;
-        if (DEBUG)
+        if (DEBUG) {
             Log.w(TAG, "[" + mWebView.hashCode() + "] Started loading new page");
+        }
         addAccessibilityApisIfNecessary();
     }
 
@@ -348,30 +350,57 @@
      */
     public void onPageFinished(String url) {
         if (!isAccessibilityEnabled()) {
-            mAccessibilityScriptInjected = false;
             toggleFallbackAccessibilityInjector(false);
             return;
         }
 
-        if (!shouldInjectJavaScript(url)) {
-            mAccessibilityScriptInjected = false;
-            toggleFallbackAccessibilityInjector(true);
-            if (DEBUG)
-                Log.d(TAG, "[" + mWebView.hashCode() + "] Using fallback accessibility support");
-            return;
-        }
+        toggleFallbackAccessibilityInjector(true);
 
+        if (shouldInjectJavaScript(url)) {
+            // If we're supposed to use the JS screen reader, request a
+            // callback to confirm that CallbackHandler is working.
+            if (DEBUG) {
+                Log.d(TAG, "[" + mWebView.hashCode() + "] Request callback ");
+            }
+
+            mCallback.requestCallback(mWebView, mInjectScriptRunnable);
+        }
+    }
+
+    /**
+     * Runnable used to inject the JavaScript-based screen reader if the
+     * {@link CallbackHandler} API was successfully exposed to JavaScript.
+     */
+    private Runnable mInjectScriptRunnable = new Runnable() {
+        @Override
+        public void run() {
+            if (DEBUG) {
+                Log.d(TAG, "[" + mWebView.hashCode() + "] Received callback");
+            }
+
+            injectJavaScript();
+        }
+    };
+
+    /**
+     * Called by {@link #mInjectScriptRunnable} to inject the JavaScript-based
+     * screen reader after confirming that the {@link CallbackHandler} API is
+     * functional.
+     */
+    private void injectJavaScript() {
         toggleFallbackAccessibilityInjector(false);
 
         if (!mAccessibilityScriptInjected) {
             mAccessibilityScriptInjected = true;
             final String injectionUrl = getScreenReaderInjectionUrl();
             mWebView.loadUrl(injectionUrl);
-            if (DEBUG)
+            if (DEBUG) {
                 Log.d(TAG, "[" + mWebView.hashCode() + "] Loading screen reader into WebView");
+            }
         } else {
-            if (DEBUG)
+            if (DEBUG) {
                 Log.w(TAG, "[" + mWebView.hashCode() + "] Attempted to inject screen reader twice");
+            }
         }
     }
 
@@ -447,12 +476,10 @@
      * been done.
      */
     private void addTtsApis() {
-        if (mTextToSpeech != null) {
-            return;
+        if (mTextToSpeech == null) {
+            mTextToSpeech = new TextToSpeechWrapper(mContext);
         }
-        if (DEBUG)
-            Log.d(TAG, "[" + mWebView.hashCode() + "] Adding TTS APIs into WebView");
-        mTextToSpeech = new TextToSpeechWrapper(mContext);
+
         mWebView.addJavascriptInterface(mTextToSpeech, ALIAS_TTS_JS_INTERFACE);
     }
 
@@ -461,34 +488,29 @@
      * already been done.
      */
     private void removeTtsApis() {
-        if (mTextToSpeech == null) {
-            return;
+        if (mTextToSpeech != null) {
+            mTextToSpeech.stop();
+            mTextToSpeech.shutdown();
+            mTextToSpeech = null;
         }
 
-        if (DEBUG)
-            Log.d(TAG, "[" + mWebView.hashCode() + "] Removing TTS APIs from WebView");
         mWebView.removeJavascriptInterface(ALIAS_TTS_JS_INTERFACE);
-        mTextToSpeech.stop();
-        mTextToSpeech.shutdown();
-        mTextToSpeech = null;
     }
 
     private void addCallbackApis() {
-        if (mCallback != null) {
-            return;
+        if (mCallback == null) {
+            mCallback = new CallbackHandler(ALIAS_TRAVERSAL_JS_INTERFACE);
         }
 
-        mCallback = new CallbackHandler(ALIAS_TRAVERSAL_JS_INTERFACE);
         mWebView.addJavascriptInterface(mCallback, ALIAS_TRAVERSAL_JS_INTERFACE);
     }
 
     private void removeCallbackApis() {
-        if (mCallback == null) {
-            return;
+        if (mCallback != null) {
+            mCallback = null;
         }
 
         mWebView.removeJavascriptInterface(ALIAS_TRAVERSAL_JS_INTERFACE);
-        mCallback = null;
     }
 
     /**
@@ -638,9 +660,10 @@
         private volatile boolean mShutdown;
 
         public TextToSpeechWrapper(Context context) {
-            if (DEBUG)
+            if (DEBUG) {
                 Log.d(WRAP_TAG, "[" + hashCode() + "] Initializing text-to-speech on thread "
                         + Thread.currentThread().getId() + "...");
+            }
 
             final String pkgName = context.getPackageName();
 
@@ -672,12 +695,14 @@
         public int speak(String text, int queueMode, HashMap<String, String> params) {
             synchronized (mTextToSpeech) {
                 if (!mReady) {
-                    if (DEBUG)
+                    if (DEBUG) {
                         Log.w(WRAP_TAG, "[" + hashCode() + "] Attempted to speak before TTS init");
+                    }
                     return TextToSpeech.ERROR;
                 } else {
-                    if (DEBUG)
+                    if (DEBUG) {
                         Log.i(WRAP_TAG, "[" + hashCode() + "] Speak called from JS binder");
+                    }
                 }
 
                 return mTextToSpeech.speak(text, queueMode, params);
@@ -689,12 +714,14 @@
         public int stop() {
             synchronized (mTextToSpeech) {
                 if (!mReady) {
-                    if (DEBUG)
+                    if (DEBUG) {
                         Log.w(WRAP_TAG, "[" + hashCode() + "] Attempted to stop before initialize");
+                    }
                     return TextToSpeech.ERROR;
                 } else {
-                    if (DEBUG)
+                    if (DEBUG) {
                         Log.i(WRAP_TAG, "[" + hashCode() + "] Stop called from JS binder");
+                    }
                 }
 
                 return mTextToSpeech.stop();
@@ -705,12 +732,14 @@
         protected void shutdown() {
             synchronized (mTextToSpeech) {
                 if (!mReady) {
-                    if (DEBUG)
+                    if (DEBUG) {
                         Log.w(WRAP_TAG, "[" + hashCode() + "] Called shutdown before initialize");
+                    }
                 } else {
-                    if (DEBUG)
+                    if (DEBUG) {
                         Log.i(WRAP_TAG, "[" + hashCode() + "] Shutting down text-to-speech from "
                                 + "thread " + Thread.currentThread().getId() + "...");
+                    }
                 }
                 mShutdown = true;
                 mReady = false;
@@ -723,14 +752,16 @@
             public void onInit(int status) {
                 synchronized (mTextToSpeech) {
                     if (!mShutdown && (status == TextToSpeech.SUCCESS)) {
-                        if (DEBUG)
+                        if (DEBUG) {
                             Log.d(WRAP_TAG, "[" + TextToSpeechWrapper.this.hashCode()
                                     + "] Initialized successfully");
+                        }
                         mReady = true;
                     } else {
-                        if (DEBUG)
+                        if (DEBUG) {
                             Log.w(WRAP_TAG, "[" + TextToSpeechWrapper.this.hashCode()
                                     + "] Failed to initialize");
+                        }
                         mReady = false;
                     }
                 }
@@ -745,9 +776,10 @@
 
             @Override
             public void onError(String utteranceId) {
-                if (DEBUG)
+                if (DEBUG) {
                     Log.w(WRAP_TAG, "[" + TextToSpeechWrapper.this.hashCode()
                             + "] Failed to speak utterance");
+                }
             }
 
             @Override
@@ -770,12 +802,16 @@
         private final AtomicInteger mResultIdCounter = new AtomicInteger();
         private final Object mResultLock = new Object();
         private final String mInterfaceName;
+        private final Handler mMainHandler;
+
+        private Runnable mCallbackRunnable;
 
         private boolean mResult = false;
         private int mResultId = -1;
 
         private CallbackHandler(String interfaceName) {
             mInterfaceName = interfaceName;
+            mMainHandler = new Handler();
         }
 
         /**
@@ -826,25 +862,29 @@
         private boolean waitForResultTimedLocked(int resultId) {
             final long startTimeMillis = SystemClock.uptimeMillis();
 
-            if (DEBUG)
+            if (DEBUG) {
                 Log.d(TAG, "Waiting for CVOX result with ID " + resultId + "...");
+            }
 
             while (true) {
                 // Fail if we received a callback from the future.
                 if (mResultId > resultId) {
-                    if (DEBUG)
+                    if (DEBUG) {
                         Log.w(TAG, "Aborted CVOX result");
+                    }
                     return false;
                 }
 
                 final long elapsedTimeMillis = (SystemClock.uptimeMillis() - startTimeMillis);
 
                 // Succeed if we received the callback we were expecting.
-                if (DEBUG)
+                if (DEBUG) {
                     Log.w(TAG, "Check " + mResultId + " versus expected " + resultId);
+                }
                 if (mResultId == resultId) {
-                    if (DEBUG)
+                    if (DEBUG) {
                         Log.w(TAG, "Received CVOX result after " + elapsedTimeMillis + " ms");
+                    }
                     return true;
                 }
 
@@ -852,18 +892,21 @@
 
                 // Fail if we've already exceeded the timeout.
                 if (waitTimeMillis <= 0) {
-                    if (DEBUG)
+                    if (DEBUG) {
                         Log.w(TAG, "Timed out while waiting for CVOX result");
+                    }
                     return false;
                 }
 
                 try {
-                    if (DEBUG)
+                    if (DEBUG) {
                         Log.w(TAG, "Start waiting...");
+                    }
                     mResultLock.wait(waitTimeMillis);
                 } catch (InterruptedException ie) {
-                    if (DEBUG)
+                    if (DEBUG) {
                         Log.w(TAG, "Interrupted while waiting for CVOX result");
+                    }
                 }
             }
         }
@@ -878,8 +921,9 @@
         @JavascriptInterface
         @SuppressWarnings("unused")
         public void onResult(String id, String result) {
-            if (DEBUG)
+            if (DEBUG) {
                 Log.w(TAG, "Saw CVOX result of '" + result + "' for ID " + id);
+            }
             final int resultId;
 
             try {
@@ -893,11 +937,34 @@
                     mResult = Boolean.parseBoolean(result);
                     mResultId = resultId;
                 } else {
-                    if (DEBUG)
+                    if (DEBUG) {
                         Log.w(TAG, "Result with ID " + resultId + " was stale vesus " + mResultId);
+                    }
                 }
                 mResultLock.notifyAll();
             }
         }
+
+        /**
+         * Requests a callback to ensure that the JavaScript interface for this
+         * object has been added successfully.
+         *
+         * @param webView The web view to request a callback from.
+         * @param callbackRunnable Runnable to execute if a callback is received.
+         */
+        public void requestCallback(WebView webView, Runnable callbackRunnable) {
+            mCallbackRunnable = callbackRunnable;
+
+            webView.loadUrl("javascript:(function() { " + mInterfaceName + ".callback(); })();");
+        }
+
+        @JavascriptInterface
+        @SuppressWarnings("unused")
+        public void callback() {
+            if (mCallbackRunnable != null) {
+                mMainHandler.post(mCallbackRunnable);
+                mCallbackRunnable = null;
+            }
+        }
     }
 }
diff --git a/core/java/android/webkit/WebViewClassic.java b/core/java/android/webkit/WebViewClassic.java
index 0f8966e..ae56e6b 100644
--- a/core/java/android/webkit/WebViewClassic.java
+++ b/core/java/android/webkit/WebViewClassic.java
@@ -2500,6 +2500,9 @@
             // Remove all pending messages because we are restoring previous
             // state.
             mWebViewCore.removeMessages();
+            if (isAccessibilityInjectionEnabled()) {
+                getAccessibilityInjector().addAccessibilityApisIfNecessary();
+            }
             // Send a restore state message.
             mWebViewCore.sendMessage(EventHub.RESTORE_STATE, index);
         }
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index a5aa713..3f20ed1 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -503,14 +503,16 @@
         android:permissionGroupFlags="personalInfo"
         android:priority="330" />
 
-    <!-- Allows an application to access fine (e.g., GPS) location -->
+    <!-- Allows an app to access precise location from location sources such
+         as GPS, cell towers, and Wi-Fi. -->
     <permission android:name="android.permission.ACCESS_FINE_LOCATION"
         android:permissionGroup="android.permission-group.LOCATION"
         android:protectionLevel="dangerous"
         android:label="@string/permlab_accessFineLocation"
         android:description="@string/permdesc_accessFineLocation" />
 
-    <!-- Allows an application to access coarse (e.g., Cell-ID, WiFi) location -->
+    <!-- Allows an app to access approximate location derived from network location
+         sources such as cell towers and Wi-Fi. -->
     <permission android:name="android.permission.ACCESS_COARSE_LOCATION"
         android:permissionGroup="android.permission-group.LOCATION"
         android:protectionLevel="dangerous"
diff --git a/core/res/res/layout-port/keyguard_host_view.xml b/core/res/res/layout-port/keyguard_host_view.xml
index bba1b04..b3270e0 100644
--- a/core/res/res/layout-port/keyguard_host_view.xml
+++ b/core/res/res/layout-port/keyguard_host_view.xml
@@ -69,8 +69,8 @@
         </com.android.internal.policy.impl.keyguard.KeyguardSecurityContainer>
 
         <ImageButton
-              android:layout_width="wrap_content"
-              android:layout_height="wrap_content"
+              android:layout_width="match_parent"
+              android:layout_height="@dimen/kg_widget_pager_bottom_padding"
               androidprv:layout_childType="expandChallengeHandle"
               android:focusable="true"
               android:background="@null"
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 4861c57..3b7d73a 100755
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -656,9 +656,9 @@
          speech -->
     <bool name="config_bluetooth_wide_band_speech">true</bool>
 
-    <!-- Boolean indicating if current platform supports quick switch-on/off of
-         Bluetooth Module -->
-    <bool name="config_bluetooth_adapter_quick_switch">true</bool>
+    <!-- Boolean indicating if current platform need do one-time bluetooth address
+         re-validation -->
+    <bool name="config_bluetooth_address_validation">false</bool>
 
     <!-- The default data-use polling period. -->
     <integer name="config_datause_polling_period_sec">600</integer>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 4a4f1c4..06e927b 100755
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -3967,6 +3967,9 @@
        you will be asked to unlock your phone using an email account.\n\n
        Try again in <xliff:g id="number">%d</xliff:g> seconds.
     </string>
+    <!-- Sequence of characters used to separate message strings in keyguard. Typically just em-dash
+         with spaces on either side. [CHAR LIMIT=3] -->
+    <string name="kg_text_message_separator" product="default"> \u2014 </string>
 
     <!-- Message shown in dialog when user is attempting to set the music volume above the
     recommended maximum level for headphones -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index d28f139..3bdf4c6 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -245,7 +245,7 @@
   <java-symbol type="bool" name="action_bar_embed_tabs_pre_jb" />
   <java-symbol type="bool" name="action_bar_expanded_action_views_exclusive" />
   <java-symbol type="bool" name="config_allowActionMenuItemTextWithIcon" />
-  <java-symbol type="bool" name="config_bluetooth_adapter_quick_switch" />
+  <java-symbol type="bool" name="config_bluetooth_address_validation" />
   <java-symbol type="bool" name="config_bluetooth_sco_off_call" />
   <java-symbol type="bool" name="config_cellBroadcastAppLinks" />
   <java-symbol type="bool" name="config_duplicate_port_omadm_wappush" />
@@ -1477,6 +1477,7 @@
   <java-symbol type="string" name="kg_failed_attempts_almost_at_login" />
   <java-symbol type="string" name="kg_enter_confirm_pin_hint" />
   <java-symbol type="string" name="kg_invalid_confirm_pin_hint" />
+  <java-symbol type="string" name="kg_text_message_separator" />
 
   <!-- From services -->
   <java-symbol type="anim" name="screen_rotate_0_enter" />
diff --git a/docs/html/about/dashboards/index.jd b/docs/html/about/dashboards/index.jd
index 6555733..edf1f41 100644
--- a/docs/html/about/dashboards/index.jd
+++ b/docs/html/about/dashboards/index.jd
@@ -31,30 +31,30 @@
   <th>Distribution</th>
 </tr>
 <tr><td><a href="/about/versions/android-1.5.html">1.5</a></td><td>Cupcake</td>  <td>3</td><td>0.1%</td></tr>
-<tr><td><a href="/about/versions/android-1.6.html">1.6</a></td><td>Donut</td>    <td>4</td><td>0.4%</td></tr>
-<tr><td><a href="/about/versions/android-2.1.html">2.1</a></td><td>Eclair</td>   <td>7</td><td>3.4%</td></tr>
-<tr><td><a href="/about/versions/android-2.2.html">2.2</a></td><td>Froyo</td>    <td>8</td><td>12.9%</td></tr>
+<tr><td><a href="/about/versions/android-1.6.html">1.6</a></td><td>Donut</td>    <td>4</td><td>0.3%</td></tr>
+<tr><td><a href="/about/versions/android-2.1.html">2.1</a></td><td>Eclair</td>   <td>7</td><td>3.1%</td></tr>
+<tr><td><a href="/about/versions/android-2.2.html">2.2</a></td><td>Froyo</td>    <td>8</td><td>12%</td></tr>
 <tr><td><a href="/about/versions/android-2.3.html">2.3 - 2.3.2</a>
                                    </td><td rowspan="2">Gingerbread</td>    <td>9</td><td>0.3%</td></tr>
 <tr><td><a href="/about/versions/android-2.3.3.html">2.3.3 - 2.3.7
-        </a></td><!-- Gingerbread -->                                       <td>10</td><td>55.5%</td></tr>
+        </a></td><!-- Gingerbread -->                                       <td>10</td><td>53.9%</td></tr>
 <tr><td><a href="/about/versions/android-3.1.html">3.1</a></td>
                                                    <td rowspan="2">Honeycomb</td>      <td>12</td><td>0.4%</td></tr>
-<tr><td><a href="/about/versions/android-3.2.html">3.2</a></td>      <!-- Honeycomb --><td>13</td><td>1.5%</td></tr>
+<tr><td><a href="/about/versions/android-3.2.html">3.2</a></td>      <!-- Honeycomb --><td>13</td><td>1.4%</td></tr>
 <tr><td><a href="/about/versions/android-4.0.3.html">4.0.3 - 4.0.4</a></td>
-                                                            <td>Ice Cream Sandwich</td><td>15</td><td>23.7%</td></tr> 
-<tr><td><a href="/about/versions/android-4.1.html">4.1</a></td>   <td>Jelly Bean</td><td>16</td><td>1.8%</td></tr> 
+                                                            <td>Ice Cream Sandwich</td><td>15</td><td>25.8%</td></tr> 
+<tr><td><a href="/about/versions/android-4.1.html">4.1</a></td>   <td>Jelly Bean</td><td>16</td><td>2.7%</td></tr> 
 </table>
 
 </div>
 
 <div class="col-8" style="margin-right:0">
 <img alt=""
-src="http://chart.apis.google.com/chart?&cht=p&chs=460x245&chd=t:3.9,12.9,55.8,1.9,23.7,1.8&chl=Eclair%20%26%20older|Froyo|Gingerbread|Honeycomb|Ice%20Cream%20Sandwich|Jelly%20Bean&chco=c4df9b,6fad0c&chf=bg,s,00000000" />
+src="http://chart.apis.google.com/chart?&cht=p&chs=460x245&chd=t:3.5,12,54.2,1.8,25.8,2.7&chl=Eclair%20%26%20older|Froyo|Gingerbread|Honeycomb|Ice%20Cream%20Sandwich|Jelly%20Bean&chco=c4df9b,6fad0c&chf=bg,s,00000000" />
 
 </div><!-- end dashboard-panel -->
 
-<p style="clear:both"><em>Data collected during a 14-day period ending on October 1, 2012</em></p>
+<p style="clear:both"><em>Data collected during a 14-day period ending on November 1, 2012</em></p>
 <!--
 <p style="font-size:.9em">* <em>Other: 0.1% of devices running obsolete versions</em></p>
 -->
@@ -79,9 +79,9 @@
 Google Play within a 14-day period ending on the date indicated on the x-axis.</p>
 
 <img alt="" height="250" width="660"
-src="http://chart.apis.google.com/chart?&cht=lc&chs=660x250&chxt=x,x,y,r&chf=bg,s,00000000&chxr=0,0,12|1,0,12|2,0,100|3,0,100&chxl=0%3A%7C04/01%7C04/15%7C05/01%7C05/15%7C06/01%7C06/15%7C07/01%7C07/15%7C08/01%7C08/15%7C09/01%7C09/15%7C10/01%7C1%3A%7C2012%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C2012%7C2%3A%7C0%25%7C25%25%7C50%25%7C75%25%7C100%25%7C3%3A%7C0%25%7C25%25%7C50%25%7C75%25%7C100%25&chxp=0,0,1,2,3,4,5,6,7,8,9,10,11,12&chxtc=0,5&chd=t:97.8,97.9,98.1,98.1,98.3,98.5,98.6,98.7,98.9,98.9,99.0,99.1,99.2|91.8,92.1,92.5,92.7,93.1,93.5,93.9,94.2,94.7,94.9,95.3,95.5,95.8|68.6,69.9,71.5,72.6,74.0,75.2,76.5,77.8,79.2,80.1,81.1,82.0,82.9|5.5,6.5,7.6,8.2,9.4,11.0,12.8,15.6,18.9,21.2,23.7,25.5,27.4|4.5,5.5,6.6,7.4,8.7,10.4,12.3,15.1,18.4,20.7,23.2,25.1,27.0|2.3,3.3,4.4,5.3,6.7,8.4,10.4,13.2,16.6,19.0,21.5,23.5,25.5|0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.8,0.9,1.1,1.4,1.8&chm=b,c3df9b,0,1,0|tAndroid%202.2,6c9729,1,0,15,,t::-5|b,b6dc7d,1,2,0|tAndroid%202.3.3,5b831d,2,0,15,,t::-5|b,aadb5e,2,3,0|b,9ddb3d,3,4,0|b,91da1e,4,5,0|tAndroid%204.0.3,253a06,5,6,15,,t::-5|b,80c414,5,6,0|B,6fad0c,6,7,0&chg=7,25&chdl=Android%202.1|Android%202.2|Android%202.3.3|Android%203.1|Android%203.2|Android%204.0.3|Android%204.1&chco=add274,a0d155,94d134,84c323,73ad18,62960f,507d08" />
+src="http://chart.apis.google.com/chart?&cht=lc&chs=660x250&chxt=x,x,y,r&chf=bg,s,00000000&chxr=0,0,12|1,0,12|2,0,100|3,0,100&chxl=0%3A%7C05/01%7C05/15%7C06/01%7C06/15%7C07/01%7C07/15%7C08/01%7C08/15%7C09/01%7C09/15%7C10/01%7C10/15%7C11/01%7C1%3A%7C2012%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C2012%7C2%3A%7C0%25%7C25%25%7C50%25%7C75%25%7C100%25%7C3%3A%7C0%25%7C25%25%7C50%25%7C75%25%7C100%25&chxp=0,0,1,2,3,4,5,6,7,8,9,10,11,12&chxtc=0,5&chd=t:98.1,98.1,98.3,98.5,98.6,98.7,98.9,98.9,99.0,99.1,99.2,99.2,99.2|92.5,92.7,93.1,93.5,93.9,94.2,94.7,94.9,95.3,95.5,95.8,96.0,96.1|71.5,72.6,74.0,75.2,76.5,77.8,79.2,80.1,81.1,82.0,82.9,83.5,84.4|7.6,8.2,9.4,11.0,12.8,15.6,18.9,21.2,23.7,25.5,27.4,28.7,31.1|6.6,7.4,8.7,10.4,12.3,15.1,18.4,20.7,23.2,25.1,27.0,28.3,30.7|4.4,5.3,6.7,8.4,10.4,13.2,16.6,19.0,21.5,23.5,25.5,26.8,29.4|0.0,0.0,0.0,0.0,0.0,0.0,0.8,0.9,1.1,1.4,1.8,2.1,3.2&chm=b,c3df9b,0,1,0|tAndroid%202.2,6c9729,1,0,15,,t::-5|b,b6dc7d,1,2,0|tAndroid%202.3.3,5b831d,2,0,15,,t::-5|b,aadb5e,2,3,0|b,9ddb3d,3,4,0|b,91da1e,4,5,0|tAndroid%204.0.3,253a06,5,4,15,,t::-5|b,80c414,5,6,0|B,6fad0c,6,7,0&chg=7,25&chdl=Android%202.1|Android%202.2|Android%202.3.3|Android%203.1|Android%203.2|Android%204.0.3|Android%204.1&chco=add274,a0d155,94d134,84c323,73ad18,62960f,507d08"/>
 
-<p><em>Last historical dataset collected during a 14-day period ending on October 1, 2012</em></p>
+<p><em>Last historical dataset collected during a 14-day period ending on November 1, 2012</em></p>
 
 
 
diff --git a/docs/html/guide/google/play/expansion-files.jd b/docs/html/guide/google/play/expansion-files.jd
index 750e958..f5cda06 100644
--- a/docs/html/guide/google/play/expansion-files.jd
+++ b/docs/html/guide/google/play/expansion-files.jd
@@ -421,7 +421,7 @@
 
 <p>To use APK expansion files with your application and provide the best user experience with
 minimal effort on your behalf, we recommend you use the Downloader Library that's included in the
-Google Market Apk Expansion package. This library downloads your expansion files in a
+Google Play APK Expansion Library package. This library downloads your expansion files in a
 background service, shows a user notification with the download status, handles network
 connectivity loss, resumes the download when possible, and more.</p>
 
@@ -450,8 +450,8 @@
 <p>First, open the <a href="{@docRoot}sdk/exploring.html">Android SDK Manager</a>, expand
 <em>Extras</em> and download:</p>
 <ul>
-  <li><em>Google Market Licensing package</em></li>
-  <li><em>Google Market Apk Expansion package</em></li>
+  <li><em>Google Play Licensing Library package</em></li>
+  <li><em>Google Play APK Expansion Library package</em></li>
 </ul>
 
 <p>If you're using Eclipse, create a project for each library and add it to your app:</p>
diff --git a/docs/html/guide/topics/manifest/activity-element.jd b/docs/html/guide/topics/manifest/activity-element.jd
index 844be11..2aedaec 100644
--- a/docs/html/guide/topics/manifest/activity-element.jd
+++ b/docs/html/guide/topics/manifest/activity-element.jd
@@ -218,7 +218,8 @@
   <td>"{@code uiMode}"</td>
    <td>The user interface mode has changed &mdash; this can be caused when the user places the
 device into a desk/car dock or when the the night mode changes. See {@link
-android.app.UiModeManager}. <em>Introduced in API Level 8</em>.</td>
+android.app.UiModeManager}. 
+    <em>Added in API level 8</em>.</td>
   </tr><tr>
    <td>"{@code orientation}"</td>
    <td>The screen orientation has changed &mdash; the user has rotated the device. 
@@ -246,7 +247,12 @@
 your activity always handles this configuration change itself (this configuration change does not
 restart your activity, even when running on an Android 3.2 or higher device).
   <p><em>Added in API level 13.</em></p></td>
- </tr>
+ </tr><tr>
+  <td>"{@code layoutDirection}"</td>
+   <td>The layout direction has changed. For example, changing from left-to-right (LTR)
+    to right-to-left (RTL).
+   <em>Added in API level 17.</em></td>
+  </tr>
 </table>
 
 <p>
diff --git a/docs/html/guide/topics/manifest/application-element.jd b/docs/html/guide/topics/manifest/application-element.jd
index 2105a50..42cfdd5 100644
--- a/docs/html/guide/topics/manifest/application-element.jd
+++ b/docs/html/guide/topics/manifest/application-element.jd
@@ -23,6 +23,7 @@
              android:<a href="#persistent">persistent</a>=["true" | "false"]
              android:<a href="#proc">process</a>="<i>string</i>"
              android:<a href="#restoreany">restoreAnyVersion</a>=["true" | "false"]
+             android:<a href="#supportsrtl">supportsRtl</a>=["true" | "false"]
              android:<a href="#aff">taskAffinity</a>="<i>string</i>"
              android:<a href="#theme">theme</a>="<i>resource or theme</i>"
              android:<a href="#uioptions">uiOptions</a>=["none" | "splitActionBarWhenNarrow"] &gt;
@@ -271,7 +272,7 @@
 </p></dd>
 
 <dt><a name="restoreany"></a>{@code android:restoreAnyVersion}</dt>
-<dd>Indicate that the application is prepared to attempt a restore of any
+<dd>Indicates that the application is prepared to attempt a restore of any
 backed-up data set, even if the backup was stored by a newer version
 of the application than is currently installed on the device.  Setting
 this attribute to {@code true} will permit the Backup Manager to
@@ -281,6 +282,21 @@
 <p>The default value of this attribute is {@code false}.
 </p></dd>
 
+<dt><a name="supportsrtl"></a>{@code android:supportsRtl}</dt>
+<dd>Declares whether your application is willing to support right-to-left (RTL) layouts.
+<p>If set to {@code true} and <a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target"
+>{@code targetSdkVersion}</a> is set to 17 or higher, various RTL APIs will be
+activated and used by the system so your app can display RTL layouts.
+If set to {@code false} or if <a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target"
+>{@code targetSdkVersion}</a> is set to 16 or lower, the RTL APIs will be ignored
+or will have no effect and your app will behave the same regardless of the layout
+direction associated to the user's Locale choice (your layouts will always be left-to-right).
+
+<p>The default value of this attribute is {@code false}.</p>
+
+<p>This attribute was added in API level 17.</p>
+</dd>
+
 <dt><a name="aff"></a>{@code android:taskAffinity}</dt>
 <dd>An affinity name that applies to all activities within the application,
 except for those that set a different affinity with their own
diff --git a/docs/html/guide/topics/manifest/permission-element.jd b/docs/html/guide/topics/manifest/permission-element.jd
index c256fb1..a23fb4b 100644
--- a/docs/html/guide/topics/manifest/permission-element.jd
+++ b/docs/html/guide/topics/manifest/permission-element.jd
@@ -111,7 +111,7 @@
    <td>"{@code signatureOrSystem}"</td>
    <td>A permission that the system grants only to applications that are 
        in the Android system image <em>or</em> that are signed with the same
-       certificates as those in the system image.  Please avoid using this 
+       certificate as the application that declared the permission. Please avoid using this 
        option, as the {@code signature} protection level should be sufficient 
        for most needs and works regardless of exactly where applications are 
        installed.  The "{@code signatureOrSystem}"
diff --git a/docs/html/guide/topics/resources/providing-resources.jd b/docs/html/guide/topics/resources/providing-resources.jd
index 749e458..b311b7f 100644
--- a/docs/html/guide/topics/resources/providing-resources.jd
+++ b/docs/html/guide/topics/resources/providing-resources.jd
@@ -331,14 +331,13 @@
     </tr>
     <tr id="LayoutDirectionQualifier">
       <td>Layout Direction</td>
-      <td>Examples:<br/>
-        <code>ldrtl</code><br/>
+      <td><code>ldrtl</code><br/>
         <code>ldltr</code><br/>
       </td>
       <td><p>The layout direction of your application. {@code ldrtl} means "layout-direction-right-to-left".
       {@code ldltr} means "layout-direction-left-to-right" and is the default implicit value.
       </p>
-      <p>This can apply to any resource like layouts or values or drawables.
+      <p>This can apply to any resource such as layouts, drawables, or values.
       </p>
       <p>For example, if you want to provide some specific layout for the Arabic language and some
       generic layout for any other "right-to-left" language (like Persian or Hebrew) then you would have:
@@ -346,12 +345,21 @@
 <pre class="classic no-pretty-print">
 res/
     layout/   <span style="color:black">
-        main.xml  </span>(This is the default layout)
+        main.xml  </span>(Default layout)
     layout-ar/  <span style="color:black">
-        main.xml  </span>(This is the specific layout for Arabic)
+        main.xml  </span>(Specific layout for Arabic)
     layout-ldrtl/  <span style="color:black">
-        main.xml  </span>(This applies to any "right-to-left" language, except for Arabic, because the ar language qualifier has a higher precedence.)
+        main.xml  </span>(Any "right-to-left" language, except
+                  for Arabic, because the "ar" language qualifier
+                  has a higher precedence.)
 </pre>
+        <p class="note"><strong>Note:</strong> To enable right-to-left layout features
+        for your app, you must set <a
+        href="{@docRoot}guide/topics/manifest/application-element.html#supportsrtl">{@code
+        supportsRtl}</a> to {@code "true"} and set <a
+        href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target"
+        >{@code targetSdkVersion}</a> to 17 or higher.</p>
+        <p><em>Added in API level 17.</em></p>
       </td>
     </tr>
     <tr id="SmallestScreenWidthQualifier">
diff --git a/docs/html/guide/topics/ui/notifiers/notifications.jd b/docs/html/guide/topics/ui/notifiers/notifications.jd
index 2de6260..8026b7d 100644
--- a/docs/html/guide/topics/ui/notifiers/notifications.jd
+++ b/docs/html/guide/topics/ui/notifiers/notifications.jd
@@ -18,6 +18,7 @@
       <li><a href="#Actions">Notification actions</a></li>
       <li><a href="#SimpleNotification">Creating a simple notification</a></li>
       <li><a href="#ApplyStyle">Applying a big view style to a notification</a></li>
+      <li><a href="#Compatibility">Handling compatibility</a></li>
     </ol>
   </li>
   <li><a href="#Managing">Managing Notifications</a>
@@ -91,18 +92,36 @@
     </p>
 </div>
 <p class="note">
-    <strong>Note:</strong> This guide refers to the
+    <strong>Note:</strong> Except where noted, this guide refers to the
     {@link android.support.v4.app.NotificationCompat.Builder NotificationCompat.Builder} class
     in the version 4 <a href="{@docRoot}tools/extras/support-library.html">Support Library</a>.
-    The class {@link android.app.Notification.Builder Notification.Builder} was added in API
-    level 11.
+    The class {@link android.app.Notification.Builder Notification.Builder} was added in Android
+    3.0.
 </p>
 <!-- ------------------------------------------------------------------------------------------ -->
 <!-- ------------------------------------------------------------------------------------------ -->
 <h2 id="NotificationUI">Notification Display Elements</h2>
 <p>
-    Notifications in the notification drawer appear in two main visual styles, normal view and
-    big view.
+    Notifications in the notification drawer can appear in one of two visual styles, depending on
+    the version and the state of the drawer:
+</p>
+<dl>
+    <dt>
+        Normal view
+    </dt>
+    <dd>
+        The standard view of the notifications in the notification drawer.
+    </dd>
+    <dt>
+        Big view
+    </dt>
+    <dd>
+        A large view that's visible when the notification is expanded. Big view is part of the
+        expanded notification feature available as of Android 4.1.
+    </dd>
+</dl>
+<p>
+    These styles are described in the following sections.
 </p>
 <!-- ------------------------------------------------------------------------------------------ -->
 <h3 id="NormalNotify">Normal view</h3>
@@ -139,7 +158,7 @@
 <p>
     A notification's big view appears only when the notification is expanded, which happens when the
     notification is at the top of the notification drawer, or when the user expands the
-    notification with a gesture.
+    notification with a gesture. Expanded notifications are available starting with Android 4.1.
 </p>
 <p>
     The following screenshot shows an inbox-style notification:
@@ -246,10 +265,12 @@
 </p>
 <p>
     A notification can provide multiple actions. You should always define the action that's
-    triggered when the user touches the notification; usually this action opens an
+    triggered when the user clicks the notification; usually this action opens an
     {@link android.app.Activity} in your application. You can also add buttons to the notification
     that perform additional actions such as snoozing an alarm or responding immediately to a text
-    message.
+    message; this feature is available as of Android 4.1. If you use additional action buttons, you
+    must also make their functionality available in an {@link android.app.Activity} in your app; see
+    the section <a href="#Compatibility">Handling compatibility</a> for more details.
 </p>
 <p>
     Inside a {@link android.app.Notification}, the action itself is defined by a
@@ -257,22 +278,22 @@
     an {@link android.app.Activity} in your application. To associate the
     {@link android.app.PendingIntent} with a gesture, call the appropriate method of
     {@link android.support.v4.app.NotificationCompat.Builder}. For example, if you want to start
-    {@link android.app.Activity} when the user touches the notification text in
+    {@link android.app.Activity} when the user clicks the notification text in
     the notification drawer, you add the {@link android.app.PendingIntent} by calling
     {@link android.support.v4.app.NotificationCompat.Builder#setContentIntent setContentIntent()}.
 </p>
 <p>
-    Starting an {@link android.app.Activity} when the user touches the notification is the most
+    Starting an {@link android.app.Activity} when the user clicks the notification is the most
     common action scenario. You can also start an {@link android.app.Activity} when the user
-    dismisses an {@link android.app.Activity}, and you can start an {@link android.app.Activity}
-    from an action button. To learn more, read the reference guide for
+    dismisses an {@link android.app.Activity}. In Android 4.1 and later, you can start an
+    {@link android.app.Activity} from an action button. To learn more, read the reference guide for
     {@link android.support.v4.app.NotificationCompat.Builder}.
 </p>
 <!-- ------------------------------------------------------------------------------------------ -->
 <h3 id="SimpleNotification">Creating a simple notification</h3>
 <p>
     The following snippet illustrates a simple notification that specifies an activity to open when
-    the user touches the notification. Notice that the code creates a
+    the user clicks the notification. Notice that the code creates a
     {@link android.support.v4.app.TaskStackBuilder} object and uses it to create the
     {@link android.app.PendingIntent} for the action. This pattern is explained in more detail
     in the section <a href="#NotificationResponse">
@@ -317,6 +338,11 @@
     Builder.setStyle()} with a big view style object as its argument.
 </p>
 <p>
+    Remember that expanded notifications are not available on platforms prior to Android 4.1. To
+    learn how to handle notifications for Android 4.1 and for earlier platforms, read the
+    section <a href="#Compatibility">Handling compatibility</a>.
+</p>
+<p>
     For example, the following code snippet demonstrates how to alter the notification created
     in the previous snippet to use the Inbox big view style:
 </p>
@@ -341,6 +367,47 @@
 ...
 // Issue the notification here.
 </pre>
+<h3 id="Compatibility">Handling compatibility</h3>
+<p>
+    Not all notification features are available for a particular version, even though
+    the methods to set them are in the support library class
+    {@link android.support.v4.app.NotificationCompat.Builder NotificationCompat.Builder}.
+    For example, action buttons, which depend on expanded notifications, only appear on Android
+    4.1 and higher, because expanded notifications themselves are only available on
+    Android 4.1 and higher.
+</p>
+<p>
+    To ensure the best compatibility, create notifications with
+    {@link android.support.v4.app.NotificationCompat NotificationCompat} and its subclasses,
+    particularly {@link android.support.v4.app.NotificationCompat.Builder
+    NotificationCompat.Builder}. In addition, follow this process when you implement a notification:
+</p>
+<ol>
+    <li>
+        Provide all of the notification's functionality to all users, regardless of the version
+        they're using. To do this, verify that all of the functionality is available from an
+        {@link android.app.Activity} in your app. You may want to add a new
+        {@link android.app.Activity} to do this.
+        <p>
+            For example, if you want to use
+            {@link android.support.v4.app.NotificationCompat.Builder#addAction addAction()} to
+            provide a control that stops and starts media playback, first implement this
+            control in an {@link android.app.Activity} in your app.
+        </p>
+    </li>
+    <li>
+        Ensure that all users can get to the functionality in the {@link android.app.Activity},
+        by having it start when users click the notification. To do this,
+        create a {@link android.app.PendingIntent} for the {@link android.app.Activity}. Call
+        {@link android.support.v4.app.NotificationCompat.Builder#setContentIntent
+        setContentIntent()} to add the {@link android.app.PendingIntent} to the notification.
+    </li>
+    <li>
+        Now add the expanded notification features you want to use to the notification. Remember
+        that any functionality you add also has to be available in the {@link android.app.Activity}
+        that starts when users click the notification.
+    </li>
+</ol>
 <!-- ------------------------------------------------------------------------------------------ -->
 <!-- ------------------------------------------------------------------------------------------ -->
 <h2 id="Managing">Managing Notifications</h2>
@@ -355,6 +422,10 @@
     "stacking" the notification; it's described in more detail in the
     <a href="{@docRoot}design/patterns/notifications.html">Notifications</a> Design guide.
 </p>
+<p class="note">
+    <strong>Note:</strong> This Gmail feature requires the "inbox" big view style, which is
+    part of the expanded notification feature available starting in Android 4.1.
+</p>
 <p>
     The following section describes how to update notifications and also how to remove them.
 </p>
@@ -417,7 +488,7 @@
         the notification can be cleared).
     </li>
     <li>
-        The user touches the notification, and you called
+        The user clicks the notification, and you called
         {@link android.support.v4.app.NotificationCompat.Builder#setAutoCancel setAutoCancel()} when
         you created the notification.
     </li>
@@ -452,7 +523,7 @@
         start a fresh task, and provide the {@link android.app.PendingIntent} with a back stack
         that reproduces the application's normal <i>Back</i> behavior.
         <p>
-            Notifications from the Gmail app demonstrate this. When you touch a notification for
+            Notifications from the Gmail app demonstrate this. When you click a notification for
             a single email message, you see the message itself. Touching <b>Back</b> takes you
             backwards through Gmail to the Home screen, just as if you had entered Gmail from the
             Home screen rather than entering it from a notification.
@@ -489,7 +560,7 @@
         Define your application's {@link android.app.Activity} hierarchy in the manifest.
         <ol style="list-style-type: lower-alpha;">
             <li>
-                Add support for API versions 15 and earlier. To do this, specify the parent of the
+                Add support for Android 4.0.3 and earlier. To do this, specify the parent of the
                 {@link android.app.Activity} you're starting by adding a
 <code><a href="{@docRoot}guide/topics/manifest/meta-data-element.html">&lt;meta-data&gt;</a></code>
                 element as the child of the
@@ -507,7 +578,7 @@
                 </p>
             </li>
             <li>
-                Also add support for API versions 16 and later. To do this, add the
+                Also add support for Android 4.1 and later. To do this, add the
 <code><a href="{@docRoot}guide/topics/manifest/activity-element.html#parent">android:parentActivityName</a></code>
                 attribute to the
 <code><a href="{@docRoot}guide/topics/manifest/activity-element.html">&lt;activity&gt;</a></code>
@@ -738,9 +809,14 @@
     {@link android.widget.ProgressBar} class.
 </p>
 <p>
-    To use a progress indicator, call
-    {@link android.support.v4.app.NotificationCompat.Builder#setProgress setProgress()}. The
-    determinate and indeterminate forms are described in the following sections.
+    To use a progress indicator on platforms starting with Android 4.0, call
+    {@link android.support.v4.app.NotificationCompat.Builder#setProgress setProgress()}. For
+    previous versions, you must create your own custom notification layout that
+    includes a {@link android.widget.ProgressBar} view.
+</p>
+<p>
+    The following sections describe how to display progress in a notification using
+    {@link android.support.v4.app.NotificationCompat.Builder#setProgress setProgress()}.
 </p>
 <!-- ------------------------------------------------------------------------------------------ -->
 <h3 id="FixedProgress">Displaying a fixed-duration progress indicator</h3>
@@ -872,6 +948,10 @@
     {@link android.widget.RemoteViews} defined in a XML layout file.
 </p>
 <p>
+    The height available for a custom notification layout depends on the notification view. Normal
+    view layouts are limited to 64 dp, and expanded view layouts are limited to 256 dp.
+</p>
+<p>
     To define a custom notification layout, start by instantiating a
     {@link android.widget.RemoteViews} object that inflates an XML layout file. Then,
     instead of calling methods such as
@@ -911,8 +991,8 @@
 <h4>Using style resources for custom notification text</h4>
 <p>
     Always use style resources for the text of a custom notification. The background color of the
-    notification can vary across different devices and platform versions, and using style resources
-    helps you account for this. Starting in API level 9, the system defined a style for the
-    standard notification layout text. If you use the same style in applications that target API
-    level 9 or higher, you'll ensure that your text is visible against the display background.
+    notification can vary across different devices and versions, and using style resources
+    helps you account for this. Starting in Android 2.3, the system defined a style for the
+    standard notification layout text. If you use the same style in applications that target Android
+    2.3 or higher, you'll ensure that your text is visible against the display background.
 </p>
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index e2d7156..6787705 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -2433,7 +2433,7 @@
     }
 
     // TODO: support fills (accounting for concavity if useCenter && sweepAngle > 180)
-    if (p->getStyle() != SkPaint::kStroke_Style || p->getPathEffect() != 0 || p->getStrokeCap() != SkPaint::kButt_Cap) {
+    if (p->getStyle() != SkPaint::kStroke_Style || p->getPathEffect() != 0 || p->getStrokeCap() != SkPaint::kButt_Cap || useCenter) {
         mCaches.activeTexture(0);
         const PathTexture* texture = mCaches.arcShapeCache.getArc(right - left, bottom - top,
                 startAngle, sweepAngle, useCenter, p);
diff --git a/location/java/android/location/Criteria.java b/location/java/android/location/Criteria.java
index 68fb4a0..a6099be 100644
--- a/location/java/android/location/Criteria.java
+++ b/location/java/android/location/Criteria.java
@@ -24,11 +24,7 @@
  * location provider.  Providers maybe ordered according to accuracy,
  * power usage, ability to report altitude, speed,
  * and bearing, and monetary cost.
- *
- * @deprecated use {@link LocationRequest} instead, and also see notes
- * at {@link LocationManager}
  */
-@Deprecated
 public class Criteria implements Parcelable {
     /**
      * A constant indicating that the application does not choose to
diff --git a/location/java/android/location/Geofence.java b/location/java/android/location/Geofence.java
index 791d3d0..5fef626 100644
--- a/location/java/android/location/Geofence.java
+++ b/location/java/android/location/Geofence.java
@@ -23,6 +23,8 @@
  * Represents a geographical boundary, also known as a geofence.
  *
  * <p>Currently only circular geofences are supported and they do not support altitude changes.
+ *
+ * @hide
  */
 public final class Geofence implements Parcelable {
     /** @hide */
diff --git a/location/java/android/location/Location.java b/location/java/android/location/Location.java
index f057ebc..9b32667 100644
--- a/location/java/android/location/Location.java
+++ b/location/java/android/location/Location.java
@@ -60,11 +60,19 @@
     public static final int FORMAT_SECONDS = 2;
 
     /**
+     * Bundle key for a version of the location that has been fed through
+     * LocationFudger. Allows location providers to flag locations as being
+     * safe for use with ACCESS_COARSE_LOCATION permission.
+     *
      * @hide
      */
     public static final String EXTRA_COARSE_LOCATION = "coarseLocation";
 
     /**
+     * Bundle key for a version of the location containing no GPS data.
+     * Allows location providers to flag locations as being safe to
+     * feed to LocationFudger.
+     *
      * @hide
      */
     public static final String EXTRA_NO_GPS_LOCATION = "noGPSLocation";
@@ -458,17 +466,8 @@
     /**
      * Returns the name of the provider that generated this fix.
      *
-     * <p class="note">At API version 17 we deprecated {@link LocationProvider}
-     * and all API methods that request a provider by name. The new API methods
-     * will produce locations that could come from different sources, and even
-     * locations that are fused from several sources. So you should generally
-     * not care what provider is associated with a location object.
-     *
      * @return the provider, or null if it has not been set
-     *
-     * @deprecated locations can now be sourced from many providers, or even fused
      */
-    @Deprecated
     public String getProvider() {
         return mProvider;
     }
diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java
index 653e8d1..5a2f71b 100644
--- a/location/java/android/location/LocationManager.java
+++ b/location/java/android/location/LocationManager.java
@@ -46,29 +46,6 @@
  * {@link android.content.Context#getSystemService
  * Context.getSystemService(Context.LOCATION_SERVICE)}.
  *
- * <p>At API version 17 the Location API's were simplified.
- * Previously applications would need to explicitly enumerate, select, and
- * track Location Providers (such as GPS or Network).
- * This has been replaced by the concept of
- * <em>Fused Location</em>. Now applications just specify the quality of service
- * required for location updates (using the new {@link LocationRequest} class),
- * and the system will fuse results from individual location providers
- * as necessary before returning the result to the application.
- *
- * <p>As a result of this change, the {@link LocationProvider} and
- * {@link Criteria} classes have been deprecated, in favor of
- * {@link LocationRequest}. Furthermore, all Location Manager
- * methods involving Criteria or explicitly named Providers have
- * been deprecated, in favor of new variants that use
- * {@link LocationRequest}.
- *
- * <p>A single {@link LocationRequest} object can trigger the use
- * of all providers (including GPS, Network, and the passive) provider
- * as necessary. This should result in a lot less work for your application. You
- * no longer need to track the status and availability of each
- * location provider. Just set the quality of locations required
- * in {@link LocationRequest}, and let the system manage the rest.
- *
  * <p class="note">Unless noted, all Location API methods require
  * the {@link android.Manifest.permission#ACCESS_COARSE_LOCATION} or
  * {@link android.Manifest.permission#ACCESS_FINE_LOCATION} permissions.
@@ -93,10 +70,7 @@
      * <p>This provider determines location based on
      * availability of cell tower and WiFi access points. Results are retrieved
      * by means of a network lookup.
-     *
-     * @deprecated Use {@link LocationRequest} instead, see notes on {@link LocationManager}
      */
-    @Deprecated
     public static final String NETWORK_PROVIDER = "network";
 
     /**
@@ -112,10 +86,7 @@
      * <ul>
      * <li> satellites - the number of satellites used to derive the fix
      * </ul>
-     *
-     * @deprecated Use {@link LocationRequest} instead, see notes on {@link LocationManager}
      */
-    @Deprecated
     public static final String GPS_PROVIDER = "gps";
 
     /**
@@ -129,10 +100,7 @@
      * the origin of the location update. Requires the permission
      * {@link android.Manifest.permission#ACCESS_FINE_LOCATION}, although if the GPS is
      * not enabled this provider might only return coarse fixes.
-     *
-     * @deprecated Use {@link LocationRequest} instead, see notes on {@link LocationManager}
      */
-    @Deprecated
     public static final String PASSIVE_PROVIDER = "passive";
 
     /**
@@ -156,19 +124,13 @@
     /**
      * Key used for a Bundle extra holding an Integer status value
      * when a status change is broadcast using a PendingIntent.
-     *
-     * @deprecated Use {@link LocationRequest} instead, see notes on {@link LocationManager}
      */
-    @Deprecated
     public static final String KEY_STATUS_CHANGED = "status";
 
     /**
      * Key used for a Bundle extra holding an Boolean status value
      * when a provider enabled/disabled event is broadcast using a PendingIntent.
-     *
-     * @deprecated Use {@link LocationRequest} instead, see notes on {@link LocationManager}
      */
-    @Deprecated
     public static final String KEY_PROVIDER_ENABLED = "providerEnabled";
 
     /**
@@ -191,10 +153,7 @@
     /**
      * Broadcast intent action when the configured location providers
      * change.
-     *
-     * @deprecated Use {@link LocationRequest} instead, see notes on {@link LocationManager}
      */
-    @Deprecated
     public static final String PROVIDERS_CHANGED_ACTION =
         "android.location.PROVIDERS_CHANGED";
 
@@ -338,10 +297,7 @@
      * be accessed by the calling activity or are currently disabled.
      *
      * @return list of Strings containing names of the provider
-     *
-     * @deprecated Use {@link LocationRequest} instead, see notes on {@link LocationManager}
      */
-    @Deprecated
     public List<String> getAllProviders() {
         try {
             return mService.getAllProviders();
@@ -357,10 +313,7 @@
      * @param enabledOnly if true then only the providers which are currently
      * enabled are returned.
      * @return list of Strings containing names of the providers
-     *
-     * @deprecated Use {@link LocationRequest} instead, see notes on {@link LocationManager}
      */
-    @Deprecated
     public List<String> getProviders(boolean enabledOnly) {
         try {
             return mService.getProviders(null, enabledOnly);
@@ -380,10 +333,7 @@
      * @throws IllegalArgumentException if name is null or does not exist
      * @throws SecurityException if the caller is not permitted to access the
      * given provider.
-     *
-     * @deprecated Use {@link LocationRequest} instead, see notes on {@link LocationManager}
      */
-    @Deprecated
     public LocationProvider getProvider(String name) {
         checkProvider(name);
         try {
@@ -407,10 +357,7 @@
      * @param enabledOnly if true then only the providers which are currently
      * enabled are returned.
      * @return list of Strings containing names of the providers
-     *
-     * @deprecated Use {@link LocationRequest} instead, see notes on {@link LocationManager}
      */
-    @Deprecated
     public List<String> getProviders(Criteria criteria, boolean enabledOnly) {
         checkCriteria(criteria);
         try {
@@ -442,10 +389,7 @@
      * @param criteria the criteria that need to be matched
      * @param enabledOnly if true then only a provider that is currently enabled is returned
      * @return name of the provider that best matches the requirements
-     *
-     * @deprecated Use {@link LocationRequest} instead, see notes on {@link LocationManager}
      */
-    @Deprecated
     public String getBestProvider(Criteria criteria, boolean enabledOnly) {
         checkCriteria(criteria);
         try {
@@ -461,7 +405,7 @@
      * pending intent.
      *
      * <p>See {@link #requestLocationUpdates(long, float, Criteria, PendingIntent)}
-     * for more detail on how to use this (deprecated) method.
+     * for more detail on how to use this method.
      *
      * @param provider the name of the provider with which to register
      * @param minTime minimum time interval between location updates, in milliseconds
@@ -475,9 +419,7 @@
      * @throws IllegalArgumentException if listener is null
      * @throws RuntimeException if the calling thread has no Looper
      * @throws SecurityException if no suitable permission is present
-     * @deprecated Use {@link LocationRequest} instead, see notes on {@link LocationManager}
      */
-    @Deprecated
     public void requestLocationUpdates(String provider, long minTime, float minDistance,
             LocationListener listener) {
         checkProvider(provider);
@@ -493,7 +435,7 @@
      * the specified looper thread.
      *
      * <p>See {@link #requestLocationUpdates(long, float, Criteria, PendingIntent)}
-     * for more detail on how to use this (deprecated) method.
+     * for more detail on how to use this method.
      *
      * @param provider the name of the provider with which to register
      * @param minTime minimum time interval between location updates, in milliseconds
@@ -508,10 +450,7 @@
      * @throws IllegalArgumentException if provider is null or doesn't exist
      * @throws IllegalArgumentException if listener is null
      * @throws SecurityException if no suitable permission is present
-     *
-     * @deprecated Use {@link LocationRequest} instead, see notes on {@link LocationManager}
      */
-    @Deprecated
     public void requestLocationUpdates(String provider, long minTime, float minDistance,
             LocationListener listener, Looper looper) {
         checkProvider(provider);
@@ -527,7 +466,7 @@
      * on the specified looper thread.
      *
      * <p>See {@link #requestLocationUpdates(long, float, Criteria, PendingIntent)}
-     * for more detail on how to use this (deprecated) method.
+     * for more detail on how to use this method.
      *
      * @param minTime minimum time interval between location updates, in milliseconds
      * @param minDistance minimum distance between location updates, in meters
@@ -543,10 +482,7 @@
      * @throws IllegalArgumentException if criteria is null
      * @throws IllegalArgumentException if listener is null
      * @throws SecurityException if no suitable permission is present
-     *
-     * @deprecated Use {@link LocationRequest} instead, see notes on {@link LocationManager}
      */
-    @Deprecated
     public void requestLocationUpdates(long minTime, float minDistance, Criteria criteria,
             LocationListener listener, Looper looper) {
         checkCriteria(criteria);
@@ -562,7 +498,7 @@
      * pending intent.
      *
      * <p>See {@link #requestLocationUpdates(long, float, Criteria, PendingIntent)}
-     * for more detail on how to use this (deprecated) method.
+     * for more detail on how to use this method.
      *
      * @param provider the name of the provider with which to register
      * @param minTime minimum time interval between location updates, in milliseconds
@@ -573,10 +509,7 @@
      * on this device
      * @throws IllegalArgumentException if intent is null
      * @throws SecurityException if no suitable permission is present
-     *
-     * @deprecated Use {@link LocationRequest} instead, see notes on {@link LocationManager}
      */
-    @Deprecated
     public void requestLocationUpdates(String provider, long minTime, float minDistance,
             PendingIntent intent) {
         checkProvider(provider);
@@ -591,11 +524,8 @@
      * Register for location updates using a Criteria and pending intent.
      *
      * <p>The <code>requestLocationUpdates()</code> and
-     * <code>requestSingleUpdate()</code> methods involving
-     * an explicit String provider or {@link Criteria} are deprecated.
-     *
-     * <p>They register the current activity to be updated
-     * periodically by the named provider, or by the provider matching
+     * <code>requestSingleUpdate()</code> register the current activity to be
+     * updated periodically by the named provider, or by the provider matching
      * the specified {@link Criteria}, with location and status updates.
      *
      * <p> It may take a while to receive the first location update. If
@@ -680,10 +610,7 @@
      * @throws IllegalArgumentException if criteria is null
      * @throws IllegalArgumentException if intent is null
      * @throws SecurityException if no suitable permission is present
-     *
-     * @deprecated Use {@link LocationRequest} instead, see notes on {@link LocationManager}
      */
-    @Deprecated
     public void requestLocationUpdates(long minTime, float minDistance, Criteria criteria,
             PendingIntent intent) {
         checkCriteria(criteria);
@@ -699,7 +626,7 @@
      * a callback.
      *
      * <p>See {@link #requestLocationUpdates(long, float, Criteria, PendingIntent)}
-     * for more detail on how to use this (deprecated) method.
+     * for more detail on how to use this method.
      *
      * @param provider the name of the provider with which to register
      * @param listener a {@link LocationListener} whose
@@ -712,10 +639,7 @@
      * @throws IllegalArgumentException if provider is null or doesn't exist
      * @throws IllegalArgumentException if listener is null
      * @throws SecurityException if no suitable permission is present
-     *
-     * @deprecated Use {@link LocationRequest#setNumUpdates} instead
      */
-    @Deprecated
     public void requestSingleUpdate(String provider, LocationListener listener, Looper looper) {
         checkProvider(provider);
         checkListener(listener);
@@ -730,7 +654,7 @@
      * a callback.
      *
      * <p>See {@link #requestLocationUpdates(long, float, Criteria, PendingIntent)}
-     * for more detail on how to use this (deprecated) method.
+     * for more detail on how to use this method.
      *
      * @param criteria contains parameters for the location manager to choose the
      * appropriate provider and parameters to compute the location
@@ -744,10 +668,7 @@
      * @throws IllegalArgumentException if criteria is null
      * @throws IllegalArgumentException if listener is null
      * @throws SecurityException if no suitable permission is present
-     *
-     * @deprecated Use {@link LocationRequest#setNumUpdates} instead
      */
-    @Deprecated
     public void requestSingleUpdate(Criteria criteria, LocationListener listener, Looper looper) {
         checkCriteria(criteria);
         checkListener(listener);
@@ -761,7 +682,7 @@
      * Register for a single location update using a named provider and pending intent.
      *
      * <p>See {@link #requestLocationUpdates(long, float, Criteria, PendingIntent)}
-     * for more detail on how to use this (deprecated) method.
+     * for more detail on how to use this method.
      *
      * @param provider the name of the provider with which to register
      * @param intent a {@link PendingIntent} to be sent for the location update
@@ -769,10 +690,7 @@
      * @throws IllegalArgumentException if provider is null or doesn't exist
      * @throws IllegalArgumentException if intent is null
      * @throws SecurityException if no suitable permission is present
-     *
-     * @deprecated Use {@link LocationRequest#setNumUpdates} instead
      */
-    @Deprecated
     public void requestSingleUpdate(String provider, PendingIntent intent) {
         checkProvider(provider);
         checkPendingIntent(intent);
@@ -786,7 +704,7 @@
      * Register for a single location update using a Criteria and pending intent.
      *
      * <p>See {@link #requestLocationUpdates(long, float, Criteria, PendingIntent)}
-     * for more detail on how to use this (deprecated) method.
+     * for more detail on how to use this method.
      *
      * @param criteria contains parameters for the location manager to choose the
      * appropriate provider and parameters to compute the location
@@ -795,10 +713,7 @@
      * @throws IllegalArgumentException if provider is null or doesn't exist
      * @throws IllegalArgumentException if intent is null
      * @throws SecurityException if no suitable permission is present
-     *
-     * @deprecated Use {@link LocationRequest#setNumUpdates} instead
      */
-    @Deprecated
     public void requestSingleUpdate(Criteria criteria, PendingIntent intent) {
         checkCriteria(criteria);
         checkPendingIntent(intent);
@@ -862,6 +777,8 @@
      *
      * @throws IllegalArgumentException if listener is null
      * @throws SecurityException if no suitable permission is present
+     *
+     * @hide
      */
     public void requestLocationUpdates(LocationRequest request, LocationListener listener,
             Looper looper) {
@@ -887,6 +804,8 @@
      *
      * @throws IllegalArgumentException if intent is null
      * @throws SecurityException if no suitable permission is present
+     *
+     * @hide
      */
     public void requestLocationUpdates(LocationRequest request, PendingIntent intent) {
         checkPendingIntent(intent);
@@ -1011,10 +930,7 @@
      *
      * @throws SecurityException if {@link android.Manifest.permission#ACCESS_FINE_LOCATION}
      * permission is not present
-     *
-     * @deprecated Use {@link LocationRequest} and {@link Geofence} instead
      */
-    @Deprecated
     public void addProximityAlert(double latitude, double longitude, float radius, long expiration,
             PendingIntent intent) {
         checkPendingIntent(intent);
@@ -1062,6 +978,8 @@
      * @throws IllegalArgumentException if intent is null
      * @throws SecurityException if {@link android.Manifest.permission#ACCESS_FINE_LOCATION}
      * permission is not present
+     *
+     * @hide
      */
     public void addGeofence(LocationRequest request, Geofence fence, PendingIntent intent) {
         checkPendingIntent(intent);
@@ -1089,10 +1007,7 @@
      * @throws IllegalArgumentException if intent is null
      * @throws SecurityException if {@link android.Manifest.permission#ACCESS_FINE_LOCATION}
      * permission is not present
-     *
-     * @deprecated Use {@link LocationRequest} and {@link Geofence} instead
      */
-    @Deprecated
     public void removeProximityAlert(PendingIntent intent) {
         checkPendingIntent(intent);
         String packageName = mContext.getPackageName();
@@ -1117,6 +1032,8 @@
      * @throws IllegalArgumentException if intent is null
      * @throws SecurityException if {@link android.Manifest.permission#ACCESS_FINE_LOCATION}
      * permission is not present
+     *
+     * @hide
      */
     public void removeGeofence(Geofence fence, PendingIntent intent) {
         checkPendingIntent(intent);
@@ -1138,6 +1055,8 @@
      * @throws IllegalArgumentException if intent is null
      * @throws SecurityException if {@link android.Manifest.permission#ACCESS_FINE_LOCATION}
      * permission is not present
+     *
+     * @hide
      */
     public void removeAllGeofences(PendingIntent intent) {
         checkPendingIntent(intent);
@@ -1161,10 +1080,7 @@
      *
      * @throws IllegalArgumentException if provider is null
      * @throws SecurityException if no suitable permission is present
-     *
-     * @deprecated Use {@link LocationRequest} instead, see notes on {@link LocationManager}
      */
-    @Deprecated
     public boolean isProviderEnabled(String provider) {
         checkProvider(provider);
 
@@ -1187,6 +1103,8 @@
      *
      * @return The last known location, or null if not available
      * @throws SecurityException if no suitable permission is present
+     *
+     * @hide
      */
     public Location getLastLocation() {
         String packageName = mContext.getPackageName();
@@ -1215,10 +1133,7 @@
      *
      * @throws SecurityException if no suitable permission is present
      * @throws IllegalArgumentException if provider is null or doesn't exist
-     *
-     * @deprecated Use {@link #getLastLocation} instead
      */
-    @Deprecated
     public Location getLastKnownLocation(String provider) {
         checkProvider(provider);
         String packageName = mContext.getPackageName();
@@ -1246,10 +1161,7 @@
      * or the {@link android.provider.Settings.Secure#ALLOW_MOCK_LOCATION
      * Settings.Secure.ALLOW_MOCK_LOCATION} system setting is not enabled
      * @throws IllegalArgumentException if a provider with the given name already exists
-     *
-     * @deprecated requesting location providers by name is deprecated
      */
-    @Deprecated
     public void addTestProvider(String name, boolean requiresNetwork, boolean requiresSatellite,
             boolean requiresCell, boolean hasMonetaryCost, boolean supportsAltitude,
             boolean supportsSpeed, boolean supportsBearing, int powerRequirement, int accuracy) {
@@ -1276,10 +1188,7 @@
      * or the {@link android.provider.Settings.Secure#ALLOW_MOCK_LOCATION
      * Settings.Secure.ALLOW_MOCK_LOCATION}} system setting is not enabled
      * @throws IllegalArgumentException if no provider with the given name exists
-     *
-     * @deprecated requesting location providers by name is deprecated
      */
-    @Deprecated
     public void removeTestProvider(String provider) {
         try {
             mService.removeTestProvider(provider);
@@ -1303,10 +1212,7 @@
      * Settings.Secure.ALLOW_MOCK_LOCATION}} system setting is not enabled
      * @throws IllegalArgumentException if no provider with the given name exists
      * @throws IllegalArgumentException if the location is incomplete
-     *
-     * @deprecated requesting location providers by name is deprecated
      */
-    @Deprecated
     public void setTestProviderLocation(String provider, Location loc) {
         if (!loc.isComplete()) {
             IllegalArgumentException e = new IllegalArgumentException(
@@ -1337,10 +1243,7 @@
      * or the {@link android.provider.Settings.Secure#ALLOW_MOCK_LOCATION
      * Settings.Secure.ALLOW_MOCK_LOCATION}} system setting is not enabled
      * @throws IllegalArgumentException if no provider with the given name exists
-     *
-     * @deprecated requesting location providers by name is deprecated
      */
-    @Deprecated
     public void clearTestProviderLocation(String provider) {
         try {
             mService.clearTestProviderLocation(provider);
@@ -1360,10 +1263,7 @@
      * or the {@link android.provider.Settings.Secure#ALLOW_MOCK_LOCATION
      * Settings.Secure.ALLOW_MOCK_LOCATION}} system setting is not enabled
      * @throws IllegalArgumentException if no provider with the given name exists
-     *
-     * @deprecated requesting location providers by name is deprecated
      */
-    @Deprecated
     public void setTestProviderEnabled(String provider, boolean enabled) {
         try {
             mService.setTestProviderEnabled(provider, enabled);
@@ -1381,10 +1281,7 @@
      * or the {@link android.provider.Settings.Secure#ALLOW_MOCK_LOCATION
      * Settings.Secure.ALLOW_MOCK_LOCATION}} system setting is not enabled
      * @throws IllegalArgumentException if no provider with the given name exists
-     *
-     * @deprecated requesting location providers by name is deprecated
      */
-    @Deprecated
     public void clearTestProviderEnabled(String provider) {
         try {
             mService.clearTestProviderEnabled(provider);
@@ -1406,10 +1303,7 @@
      * or the {@link android.provider.Settings.Secure#ALLOW_MOCK_LOCATION
      * Settings.Secure.ALLOW_MOCK_LOCATION}} system setting is not enabled
      * @throws IllegalArgumentException if no provider with the given name exists
-     *
-     * @deprecated requesting location providers by name is deprecated
      */
-    @Deprecated
     public void setTestProviderStatus(String provider, int status, Bundle extras, long updateTime) {
         try {
             mService.setTestProviderStatus(provider, status, extras, updateTime);
@@ -1427,10 +1321,7 @@
      * or the {@link android.provider.Settings.Secure#ALLOW_MOCK_LOCATION
      * Settings.Secure.ALLOW_MOCK_LOCATION}} system setting is not enabled
      * @throws IllegalArgumentException if no provider with the given name exists
-     *
-     * @deprecated requesting location providers by name is deprecated
      */
-    @Deprecated
     public void clearTestProviderStatus(String provider) {
         try {
             mService.clearTestProviderStatus(provider);
@@ -1673,10 +1564,7 @@
      * The provider may optionally fill the extras Bundle with results from the command.
      *
      * @return true if the command succeeds.
-     *
-     * @deprecated Use {@link LocationRequest} instead, see notes on {@link LocationManager}
      */
-    @Deprecated
     public boolean sendExtraCommand(String provider, String command, Bundle extras) {
         try {
             return mService.sendExtraCommand(provider, command, extras);
diff --git a/location/java/android/location/LocationProvider.java b/location/java/android/location/LocationProvider.java
index 737e17f..c4fd097 100644
--- a/location/java/android/location/LocationProvider.java
+++ b/location/java/android/location/LocationProvider.java
@@ -32,11 +32,7 @@
  * characteristics or monetary costs to the user.  The {@link
  * Criteria} class allows providers to be selected based on
  * user-specified criteria.
- *
- * @deprecated Use the {@link Criteria} class to request location instead of
- * enumerating providers.
  */
-@Deprecated
 public class LocationProvider {
     public static final int OUT_OF_SERVICE = 0;
     public static final int TEMPORARILY_UNAVAILABLE = 1;
diff --git a/location/java/android/location/LocationRequest.java b/location/java/android/location/LocationRequest.java
index 6871ee2..68f540b 100644
--- a/location/java/android/location/LocationRequest.java
+++ b/location/java/android/location/LocationRequest.java
@@ -80,6 +80,8 @@
  * <p>All location requests are considered hints, and you may receive
  * locations that are more accurate, less accurate, and slower
  * than requested.
+ *
+ * @hide
  */
 public final class LocationRequest implements Parcelable {
     /**
diff --git a/location/lib/java/com/android/location/provider/LocationProviderBase.java b/location/lib/java/com/android/location/provider/LocationProviderBase.java
index b0e5d2c..8a5a739 100644
--- a/location/lib/java/com/android/location/provider/LocationProviderBase.java
+++ b/location/lib/java/com/android/location/provider/LocationProviderBase.java
@@ -23,6 +23,8 @@
 import android.content.Context;
 import android.location.ILocationManager;
 import android.location.Location;
+import android.location.LocationManager;
+import android.location.LocationRequest;
 import android.os.Bundle;
 import android.os.IBinder;
 import android.os.RemoteException;
@@ -58,6 +60,21 @@
     private final ProviderProperties mProperties;
     private final IBinder mBinder;
 
+    /**
+     * Bundle key for a version of the location containing no GPS data.
+     * Allows location providers to flag locations as being safe to
+     * feed to LocationFudger.
+     */
+    public static final String EXTRA_NO_GPS_LOCATION = Location.EXTRA_NO_GPS_LOCATION;
+
+    /**
+     * Name of the Fused location provider.
+     *
+     * <p>This provider combines inputs for all possible location sources
+     * to provide the best possible Location fix.
+     */
+    public static final String FUSED_PROVIDER = LocationManager.FUSED_PROVIDER;
+
     private final class Service extends ILocationProvider.Stub {
         @Override
         public void enable() {
diff --git a/location/lib/java/com/android/location/provider/LocationRequestUnbundled.java b/location/lib/java/com/android/location/provider/LocationRequestUnbundled.java
new file mode 100644
index 0000000..41fd769
--- /dev/null
+++ b/location/lib/java/com/android/location/provider/LocationRequestUnbundled.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.location.provider;
+
+import android.location.LocationRequest;
+
+/**
+ * This class is an interface to LocationRequests for unbundled applications.
+ *
+ * <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 final class LocationRequestUnbundled {
+    /**
+     * Returned by {@link #getQuality} when requesting the most accurate locations available.
+     *
+     * <p>This may be up to 1 meter accuracy, although this is implementation dependent.
+     */
+    public static final int ACCURACY_FINE = LocationRequest.ACCURACY_FINE;
+
+    /**
+     * Returned by {@link #getQuality} when requesting "block" level accuracy.
+     *
+     * <p>Block level accuracy is considered to be about 100 meter accuracy,
+     * although this is implementation dependent. Using a coarse accuracy
+     * such as this often consumes less power.
+     */
+    public static final int ACCURACY_BLOCK = LocationRequest.ACCURACY_BLOCK;
+
+    /**
+     * Returned by {@link #getQuality} when requesting "city" level accuracy.
+     *
+     * <p>City level accuracy is considered to be about 10km accuracy,
+     * although this is implementation dependent. Using a coarse accuracy
+     * such as this often consumes less power.
+     */
+    public static final int ACCURACY_CITY = LocationRequest.ACCURACY_CITY;
+
+    /**
+     * Returned by {@link #getQuality} when requiring no direct power impact (passive locations).
+     *
+     * <p>This location request will not trigger any active location requests,
+     * but will receive locations triggered by other applications. Your application
+     * will not receive any direct power blame for location work.
+     */
+    public static final int POWER_NONE = LocationRequest.POWER_NONE;
+
+    /**
+     * Returned by {@link #getQuality} when requesting low power impact.
+     *
+     * <p>This location request will avoid high power location work where
+     * possible.
+     */
+    public static final int POWER_LOW = LocationRequest.POWER_LOW;
+
+    /**
+     * Returned by {@link #getQuality} when allowing high power consumption for location.
+     *
+     * <p>This location request will allow high power location work.
+     */
+    public static final int POWER_HIGH = LocationRequest.POWER_HIGH;
+
+    private final LocationRequest delegate;
+
+    LocationRequestUnbundled(LocationRequest delegate) {
+        this.delegate = delegate;
+    }
+
+    /**
+     * Get the desired interval of this request, in milliseconds.
+     *
+     * @return desired interval in milliseconds, inexact
+     */
+    public long getInterval() {
+        return delegate.getInterval();
+    }
+
+    /**
+     * Get the fastest interval of this request, in milliseconds.
+     *
+     * <p>The system will never provide location updates faster
+     * than the minimum of {@link #getFastestInterval} and
+     * {@link #getInterval}.
+     *
+     * @return fastest interval in milliseconds, exact
+     */
+    public long getFastestInterval() {
+        return delegate.getFastestInterval();
+    }
+
+    /**
+     * Get the quality of the request.
+     *
+     * @return an accuracy or power constant
+     */
+    public int getQuality() {
+        return delegate.getQuality();
+    }
+
+    /**
+     * Get the minimum distance between location updates, in meters.
+     *
+     * @return minimum distance between location updates in meters
+     */
+    public float getSmallestDisplacement() {
+        return delegate.getSmallestDisplacement();
+    }
+
+    @Override
+    public String toString() {
+      return delegate.toString();
+    }
+}
diff --git a/location/lib/java/com/android/location/provider/ProviderRequestUnbundled.java b/location/lib/java/com/android/location/provider/ProviderRequestUnbundled.java
index 3605381..ad3d1df 100644
--- a/location/lib/java/com/android/location/provider/ProviderRequestUnbundled.java
+++ b/location/lib/java/com/android/location/provider/ProviderRequestUnbundled.java
@@ -16,6 +16,7 @@
 
 package com.android.location.provider;
 
+import java.util.ArrayList;
 import java.util.List;
 
 import android.location.LocationRequest;
@@ -47,8 +48,13 @@
     /**
      * Never null.
      */
-    public List<LocationRequest> getLocationRequests() {
-        return mRequest.locationRequests;
+    public List<LocationRequestUnbundled> getLocationRequests() {
+        List<LocationRequestUnbundled> result = new ArrayList<LocationRequestUnbundled>(
+                mRequest.locationRequests.size());
+        for (LocationRequest r : mRequest.locationRequests) {
+          result.add(new LocationRequestUnbundled(r));
+        }
+        return result;
     }
 
     @Override
diff --git a/packages/FusedLocation/Android.mk b/packages/FusedLocation/Android.mk
index 318782f..a81b9f1 100644
--- a/packages/FusedLocation/Android.mk
+++ b/packages/FusedLocation/Android.mk
@@ -23,5 +23,6 @@
 
 LOCAL_PACKAGE_NAME := FusedLocation
 LOCAL_CERTIFICATE := platform
+LOCAL_SDK_VERSION := current
 
 include $(BUILD_PACKAGE)
diff --git a/packages/FusedLocation/src/com/android/location/fused/FusionEngine.java b/packages/FusedLocation/src/com/android/location/fused/FusionEngine.java
index 87d56fd..f137373 100644
--- a/packages/FusedLocation/src/com/android/location/fused/FusionEngine.java
+++ b/packages/FusedLocation/src/com/android/location/fused/FusionEngine.java
@@ -20,15 +20,17 @@
 import java.io.PrintWriter;
 import java.util.HashMap;
 
+import com.android.location.provider.LocationProviderBase;
+import com.android.location.provider.LocationRequestUnbundled;
 import com.android.location.provider.ProviderRequestUnbundled;
 
 import android.content.Context;
 import android.location.Location;
 import android.location.LocationListener;
 import android.location.LocationManager;
-import android.location.LocationRequest;
 import android.os.Bundle;
 import android.os.Looper;
+import android.os.Parcelable;
 import android.os.SystemClock;
 import android.os.WorkSource;
 import android.util.Log;
@@ -41,6 +43,7 @@
     private static final String TAG = "FusedLocation";
     private static final String NETWORK = LocationManager.NETWORK_PROVIDER;
     private static final String GPS = LocationManager.GPS_PROVIDER;
+    private static final String FUSED = LocationProviderBase.FUSED_PROVIDER;
 
     public static final long SWITCH_ON_FRESHNESS_CLIFF_NS = 11 * 1000000000; // 11 seconds
 
@@ -72,6 +75,7 @@
         mStats.get(GPS).available = mLocationManager.isProviderEnabled(GPS);
         mStats.put(NETWORK, new ProviderStats());
         mStats.get(NETWORK).available = mLocationManager.isProviderEnabled(NETWORK);
+
     }
 
     public void init(Callback callback) {
@@ -157,10 +161,10 @@
 
         long networkInterval = Long.MAX_VALUE;
         long gpsInterval = Long.MAX_VALUE;
-        for (LocationRequest request : mRequest.getLocationRequests()) {
+        for (LocationRequestUnbundled request : mRequest.getLocationRequests()) {
             switch (request.getQuality()) {
-                case LocationRequest.ACCURACY_FINE:
-                case LocationRequest.POWER_HIGH:
+                case LocationRequestUnbundled.ACCURACY_FINE:
+                case LocationRequestUnbundled.POWER_HIGH:
                     if (request.getInterval() < gpsInterval) {
                         gpsInterval = request.getInterval();
                     }
@@ -168,9 +172,9 @@
                         networkInterval = request.getInterval();
                     }
                     break;
-                case LocationRequest.ACCURACY_BLOCK:
-                case LocationRequest.ACCURACY_CITY:
-                case LocationRequest.POWER_LOW:
+                case LocationRequestUnbundled.ACCURACY_BLOCK:
+                case LocationRequestUnbundled.ACCURACY_CITY:
+                case LocationRequestUnbundled.POWER_LOW:
                     if (request.getInterval() < networkInterval) {
                         networkInterval = request.getInterval();
                     }
@@ -226,10 +230,24 @@
         } else {
             mFusedLocation = new Location(mNetworkLocation);
         }
+        mFusedLocation.setProvider(FUSED);
         if (mNetworkLocation != null) {
-            mFusedLocation.setExtraLocation(Location.EXTRA_NO_GPS_LOCATION, mNetworkLocation);
+            // copy NO_GPS_LOCATION extra from mNetworkLocation into mFusedLocation
+            Bundle srcExtras = mNetworkLocation.getExtras();
+            if (srcExtras != null) {
+                Parcelable srcParcelable =
+                        srcExtras.getParcelable(LocationProviderBase.EXTRA_NO_GPS_LOCATION);
+                if (srcParcelable instanceof Location) {
+                    Bundle dstExtras = mFusedLocation.getExtras();
+                    if (dstExtras == null) {
+                        dstExtras = new Bundle();
+                        mFusedLocation.setExtras(dstExtras);
+                    }
+                    dstExtras.putParcelable(LocationProviderBase.EXTRA_NO_GPS_LOCATION,
+                            (Location) srcParcelable);
+                }
+            }
         }
-        mFusedLocation.setProvider(LocationManager.FUSED_PROVIDER);
 
         mCallback.reportLocation(mFusedLocation);
     }
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/CarrierText.java b/policy/src/com/android/internal/policy/impl/keyguard/CarrierText.java
index b031baf..f3ea992 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/CarrierText.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/CarrierText.java
@@ -27,6 +27,8 @@
 import com.android.internal.widget.LockPatternUtils;
 
 public class CarrierText extends TextView {
+    private static CharSequence mSeparator;
+
     private LockPatternUtils mLockPatternUtils;
 
     private KeyguardUpdateMonitorCallback mCallback = new KeyguardUpdateMonitorCallback() {
@@ -82,6 +84,7 @@
     @Override
     protected void onFinishInflate() {
         super.onFinishInflate();
+        mSeparator = getResources().getString(R.string.kg_text_message_separator);
         KeyguardUpdateMonitor.getInstance(mContext).registerCallback(mCallback);
         setSelected(true); // Allow marquee to work.
     }
@@ -202,7 +205,7 @@
         final boolean plmnValid = !TextUtils.isEmpty(plmn);
         final boolean spnValid = !TextUtils.isEmpty(spn);
         if (plmnValid && spnValid) {
-            return plmn + "|" + spn;
+            return new StringBuilder().append(plmn).append(mSeparator).append(spn).toString();
         } else if (plmnValid) {
             return plmn;
         } else if (spnValid) {
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardAbsKeyInputView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardAbsKeyInputView.java
index db36bcc..f630589 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardAbsKeyInputView.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardAbsKeyInputView.java
@@ -88,6 +88,7 @@
     }
 
     protected abstract int getPasswordTextViewId();
+    protected abstract int getWrongPasswordStringId();
     protected abstract void resetState();
 
     @Override
@@ -144,7 +145,7 @@
                 long deadline = mLockPatternUtils.setLockoutAttemptDeadline();
                 handleAttemptLockout(deadline);
             }
-            mSecurityMessageDisplay.setMessage(R.string.kg_wrong_pin, true);
+            mSecurityMessageDisplay.setMessage(getWrongPasswordStringId(), true);
         }
         mPasswordEntry.setText("");
     }
@@ -164,6 +165,7 @@
 
             @Override
             public void onFinish() {
+                mSecurityMessageDisplay.setMessage("", false);
                 resetState();
             }
         }.start();
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardMessageArea.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardMessageArea.java
index 5e331e1..f6f3fab 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardMessageArea.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardMessageArea.java
@@ -43,7 +43,6 @@
 
     static final int SECURITY_MESSAGE_DURATION = 5000;
     protected static final int FADE_DURATION = 750;
-    static final String SEPARATOR = "  ";
 
     // are we showing battery information?
     boolean mShowingBatteryInfo = false;
@@ -143,6 +142,8 @@
         }
     };
 
+    private CharSequence mSeparator;
+
     public KeyguardMessageArea(Context context) {
         this(context, null);
     }
@@ -158,6 +159,8 @@
         mUpdateMonitor.registerCallback(mInfoCallback);
         mHandler = new Handler(Looper.myLooper());
 
+        mSeparator = getResources().getString(R.string.kg_text_message_separator);
+
         update();
     }
 
@@ -186,23 +189,23 @@
         setText(status);
     }
 
-
-    private CharSequence concat(Object... args) {
+    private CharSequence concat(CharSequence... args) {
         StringBuilder b = new StringBuilder();
-        for (int i = 0; i < args.length; i++) {
-            final Object arg = args[i];
-            if (arg instanceof CharSequence) {
-                b.append((CharSequence)args[i]);
-                b.append(SEPARATOR);
-            } else if (arg instanceof String) {
-                b.append((String)args[i]);
-                b.append(SEPARATOR);
+        if (!TextUtils.isEmpty(args[0])) {
+            b.append(args[0]);
+        }
+        for (int i = 1; i < args.length; i++) {
+            CharSequence text = args[i];
+            if (!TextUtils.isEmpty(text)) {
+                if (b.length() > 0) {
+                    b.append(mSeparator);
+                }
+                b.append(text);
             }
         }
         return b.toString();
     }
 
-
     CharSequence getCurrentMessage() {
         return mShowingMessage ? mMessage : null;
     }
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardPINView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardPINView.java
index 1255712..cea3fb0 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardPINView.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardPINView.java
@@ -42,7 +42,11 @@
     }
 
     protected void resetState() {
-        mSecurityMessageDisplay.setMessage(R.string.kg_pin_instructions, false);
+        if (KeyguardUpdateMonitor.getInstance(mContext).getMaxBiometricUnlockAttemptsReached()) {
+            mSecurityMessageDisplay.setMessage(R.string.faceunlock_multiple_failures, true);
+        } else {
+            mSecurityMessageDisplay.setMessage(R.string.kg_pin_instructions, false);
+        }
         mPasswordEntry.setEnabled(true);
     }
 
@@ -61,7 +65,9 @@
                 @Override
                 public void onClick(View v) {
                     doHapticKeyClick();
-                    verifyPasswordAndUnlock();
+                    if (mPasswordEntry.isEnabled()) {
+                        verifyPasswordAndUnlock();
+                    }
                 }
             });
             ok.setOnHoverListener(new NumPadKey.LiftToActivateListener(getContext()));
@@ -74,16 +80,22 @@
             pinDelete.setVisibility(View.VISIBLE);
             pinDelete.setOnClickListener(new OnClickListener() {
                 public void onClick(View v) {
-                    CharSequence str = mPasswordEntry.getText();
-                    if (str.length() > 0) {
-                        mPasswordEntry.setText(str.subSequence(0, str.length()-1));
+                    // check for time-based lockouts
+                    if (mPasswordEntry.isEnabled()) {
+                        CharSequence str = mPasswordEntry.getText();
+                        if (str.length() > 0) {
+                            mPasswordEntry.setText(str.subSequence(0, str.length()-1));
+                        }
                     }
                     doHapticKeyClick();
                 }
             });
             pinDelete.setOnLongClickListener(new View.OnLongClickListener() {
                 public boolean onLongClick(View v) {
-                    mPasswordEntry.setText("");
+                    // check for time-based lockouts
+                    if (mPasswordEntry.isEnabled()) {
+                        mPasswordEntry.setText("");
+                    }
                     doHapticKeyClick();
                     return true;
                 }
@@ -100,4 +112,9 @@
     @Override
     public void showUsabilityHint() {
     }
+
+    @Override
+    public int getWrongPasswordStringId() {
+        return R.string.kg_wrong_pin;
+    }
 }
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardPasswordView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardPasswordView.java
index 64bbdd3..23ea2e9 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardPasswordView.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardPasswordView.java
@@ -195,4 +195,9 @@
     @Override
     public void showUsabilityHint() {
     }
+
+    @Override
+    public int getWrongPasswordStringId() {
+        return R.string.kg_wrong_password;
+    }
 }
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardPatternView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardPatternView.java
index 6b3446a..82cb44b 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardPatternView.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardPatternView.java
@@ -182,7 +182,7 @@
         if (deadline != 0) {
             handleAttemptLockout(deadline);
         } else {
-            mSecurityMessageDisplay.setMessage(R.string.kg_pattern_instructions, false);
+            displayDefaultSecurityMessage();
         }
 
         // the footer depends on how many total attempts the user has failed
@@ -197,6 +197,14 @@
 
     }
 
+    private void displayDefaultSecurityMessage() {
+        if (KeyguardUpdateMonitor.getInstance(mContext).getMaxBiometricUnlockAttemptsReached()) {
+            mSecurityMessageDisplay.setMessage(R.string.faceunlock_multiple_failures, true);
+        } else {
+            mSecurityMessageDisplay.setMessage(R.string.kg_pattern_instructions, false);
+        }
+    }
+
     @Override
     public void showUsabilityHint() {
     }
@@ -338,7 +346,7 @@
             @Override
             public void onFinish() {
                 mLockPatternView.setEnabled(true);
-                mSecurityMessageDisplay.setMessage(R.string.kg_pattern_instructions, false);
+                displayDefaultSecurityMessage();
                 // TODO mUnlockIcon.setVisibility(View.VISIBLE);
                 mFailedPatternAttemptsSinceLastTimeout = 0;
                 if (mEnableFallback) {
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetPager.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetPager.java
index b023573..f04c4df 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetPager.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetPager.java
@@ -98,6 +98,16 @@
         mBgPersistenceWorkerHandler = new Handler(mBgPersistenceWorkerThread.getLooper());
     }
 
+    @Override
+    protected void onDetachedFromWindow() {
+        super.onDetachedFromWindow();
+
+        // Clean up the persistence worker thread
+        if (mBgPersistenceWorkerThread != null) {
+            mBgPersistenceWorkerThread.quit();
+        }
+    }
+
     public void setViewStateManager(KeyguardViewStateManager viewStateManager) {
         mViewStateManager = viewStateManager;
     }
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/NumPadKey.java b/policy/src/com/android/internal/policy/impl/keyguard/NumPadKey.java
index ca36007..7f51a84 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/NumPadKey.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/NumPadKey.java
@@ -51,7 +51,8 @@
                     }
                 }
             }
-            if (mTextView != null) {
+            // check for time-based lockouts
+            if (mTextView != null && mTextView.isEnabled()) {
                 mTextView.append(String.valueOf(mDigit));
             }
             doHapticKeyClick();
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/SlidingChallengeLayout.java b/policy/src/com/android/internal/policy/impl/keyguard/SlidingChallengeLayout.java
index af7dc15..fd87646 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/SlidingChallengeLayout.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/SlidingChallengeLayout.java
@@ -16,6 +16,8 @@
 
 package com.android.internal.policy.impl.keyguard;
 
+import com.android.internal.R;
+
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.ObjectAnimator;
@@ -29,7 +31,6 @@
 import android.util.AttributeSet;
 import android.util.FloatProperty;
 import android.util.Log;
-import android.util.MathUtils;
 import android.util.Property;
 import android.view.MotionEvent;
 import android.view.VelocityTracker;
@@ -40,8 +41,6 @@
 import android.view.animation.Interpolator;
 import android.widget.Scroller;
 
-import com.android.internal.R;
-
 /**
  * This layout handles interaction with the sliding security challenge views
  * that overlay/resize other keyguard contents.
@@ -53,7 +52,7 @@
     // The drag handle is measured in dp above & below the top edge of the
     // challenge view; these parameters change based on whether the challenge 
     // is open or closed.
-    private static final int DRAG_HANDLE_CLOSED_ABOVE = 64; // dp
+    private static final int DRAG_HANDLE_CLOSED_ABOVE = 8; // dp
     private static final int DRAG_HANDLE_CLOSED_BELOW = 0; // dp
     private static final int DRAG_HANDLE_OPEN_ABOVE = 8; // dp
     private static final int DRAG_HANDLE_OPEN_BELOW = 0; // dp
@@ -581,18 +580,16 @@
                     final float x = ev.getX(i);
                     final float y = ev.getY(i);
                     if (!mIsBouncing && mActivePointerId == INVALID_POINTER
-                            && ((isInDragHandle(x, y) && MathUtils.sq(x - mGestureStartX)
-                                    + MathUtils.sq(y - mGestureStartY) > mTouchSlopSquare)
-                               || crossedDragHandle(x, y, mGestureStartY)
-                               || (isInChallengeView(x, y) && (mScrollState == SCROLL_STATE_SETTLING
-                                       || !mChallengeShowing)))) {
+                                && (crossedDragHandle(x, y, mGestureStartY)
+                                || (isInChallengeView(x, y) &&
+                                        mScrollState == SCROLL_STATE_SETTLING))) {
                         mActivePointerId = ev.getPointerId(i);
                         mGestureStartX = x;
                         mGestureStartY = y;
                         mGestureStartChallengeBottom = getChallengeBottom();
                         mDragging = true;
                         mChallengeView.setLayerType(LAYER_TYPE_HARDWARE, null);
-                    } else if (isInChallengeView(x, y)) {
+                    } else if (mChallengeShowing && isInChallengeView(x, y)) {
                         mBlockDrag = true;
                     }
                 }
@@ -767,11 +764,19 @@
     }
 
     private boolean crossedDragHandle(float x, float y, float initialY) {
+
         final int challengeTop = mChallengeView.getTop();
-        return  x >= 0 &&
-                x < getWidth() &&
-                initialY < (challengeTop - getDragHandleSizeAbove()) &&
-                y > challengeTop + getDragHandleSizeBelow();
+        final boolean horizOk = x >= 0 && x < getWidth();
+
+        final boolean vertOk;
+        if (mChallengeShowing) {
+            vertOk = initialY < (challengeTop - getDragHandleSizeAbove()) &&
+                    y > challengeTop + getDragHandleSizeBelow();
+        } else {
+            vertOk = initialY > challengeTop + getDragHandleSizeBelow() &&
+                    y < challengeTop - getDragHandleSizeAbove();
+        }
+        return horizOk && vertOk;
     }
 
     @Override
@@ -884,7 +889,12 @@
                 child.setAlpha(getChallengeAlpha());
                 child.layout(left, bottom - childHeight, left + childWidth, bottom);
             } else if (lp.childType == LayoutParams.CHILD_TYPE_EXPAND_CHALLENGE_HANDLE) {
-                child.layout(0, b - mChallengeBottomBound, width, b);
+                final int center = (paddingLeft + width - paddingRight) / 2;
+                final int left = center - child.getMeasuredWidth() / 2;
+                final int right = left + child.getMeasuredWidth();
+                final int bottom = height - paddingBottom - lp.bottomMargin;
+                final int top = bottom - child.getMeasuredHeight();
+                child.layout(left, top, right, bottom);
             } else {
                 // Non-challenge views lay out from the upper left, layered.
                 child.layout(paddingLeft + lp.leftMargin,
diff --git a/services/input/InputDispatcher.cpp b/services/input/InputDispatcher.cpp
index 7862e17..0465215 100644
--- a/services/input/InputDispatcher.cpp
+++ b/services/input/InputDispatcher.cpp
@@ -224,10 +224,16 @@
         AutoMutex _l(mLock);
         mDispatcherIsAliveCondition.broadcast();
 
-        dispatchOnceInnerLocked(&nextWakeupTime);
+        // Run a dispatch loop if there are no pending commands.
+        // The dispatch loop might enqueue commands to run afterwards.
+        if (!haveCommandsLocked()) {
+            dispatchOnceInnerLocked(&nextWakeupTime);
+        }
 
+        // Run all pending commands if there are any.
+        // If any commands were run then force the next poll to wake up immediately.
         if (runCommandsLockedInterruptible()) {
-            nextWakeupTime = LONG_LONG_MIN;  // force next poll to wake up immediately
+            nextWakeupTime = LONG_LONG_MIN;
         }
     } // release lock
 
@@ -562,6 +568,10 @@
     return currentTime - entry->eventTime >= STALE_EVENT_TIMEOUT;
 }
 
+bool InputDispatcher::haveCommandsLocked() const {
+    return !mCommandQueue.isEmpty();
+}
+
 bool InputDispatcher::runCommandsLockedInterruptible() {
     if (mCommandQueue.isEmpty()) {
         return false;
@@ -3247,9 +3257,10 @@
         }
 
         mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
-
-        runCommandsLockedInterruptible();
     } // release lock
+
+    // Wake the looper because some connections have changed.
+    mLooper->wake();
     return OK;
 }
 
@@ -3294,8 +3305,6 @@
     nsecs_t currentTime = now();
     abortBrokenDispatchCycleLocked(currentTime, connection, notify);
 
-    runCommandsLockedInterruptible();
-
     connection->status = Connection::STATUS_ZOMBIE;
     return OK;
 }
diff --git a/services/input/InputDispatcher.h b/services/input/InputDispatcher.h
index 6099c43..d4f932e 100644
--- a/services/input/InputDispatcher.h
+++ b/services/input/InputDispatcher.h
@@ -899,6 +899,7 @@
     KeyEntry* synthesizeKeyRepeatLocked(nsecs_t currentTime);
 
     // Deferred command processing.
+    bool haveCommandsLocked() const;
     bool runCommandsLockedInterruptible();
     CommandEntry* postCommandLocked(Command command);
 
diff --git a/services/java/com/android/server/BluetoothManagerService.java b/services/java/com/android/server/BluetoothManagerService.java
index 6ff33d7..69ccbc7 100755
--- a/services/java/com/android/server/BluetoothManagerService.java
+++ b/services/java/com/android/server/BluetoothManagerService.java
@@ -53,6 +53,7 @@
     private static final String BLUETOOTH_PERM = android.Manifest.permission.BLUETOOTH;
     private static final String ACTION_SERVICE_STATE_CHANGED="com.android.bluetooth.btservice.action.STATE_CHANGED";
     private static final String EXTRA_ACTION="action";
+    private static final String SECURE_SETTINGS_BLUETOOTH_ADDR_VALID="bluetooth_addr_valid";
     private static final String SECURE_SETTINGS_BLUETOOTH_ADDRESS="bluetooth_address";
     private static final String SECURE_SETTINGS_BLUETOOTH_NAME="bluetooth_name";
     private static final int TIMEOUT_BIND_MS = 3000; //Maximum msec to wait for a bind
@@ -174,7 +175,9 @@
             //Enable
             if (DBG) Log.d(TAG, "Auto-enabling Bluetooth.");
             enableHelper();
-        } else if (!isNameAndAddressSet()) {
+        }
+
+        if (!isNameAndAddressSet()) {
             //Sync the Bluetooth name and address from the Bluetooth Adapter
             if (DBG) Log.d(TAG,"Retrieving Bluetooth Adapter name and address...");
             getNameAndAddress();
@@ -222,11 +225,16 @@
      */
     private void loadStoredNameAndAddress() {
         if (DBG) Log.d(TAG, "Loading stored name and address");
+        if (mContext.getResources().getBoolean
+            (com.android.internal.R.bool.config_bluetooth_address_validation) &&
+             Settings.Secure.getInt(mContentResolver, SECURE_SETTINGS_BLUETOOTH_ADDR_VALID, 0) == 0) {
+            // if the valid flag is not set, don't load the address and name
+            if (DBG) Log.d(TAG, "invalid bluetooth name and address stored");
+            return;
+        }
         mName = Settings.Secure.getString(mContentResolver, SECURE_SETTINGS_BLUETOOTH_NAME);
         mAddress = Settings.Secure.getString(mContentResolver, SECURE_SETTINGS_BLUETOOTH_ADDRESS);
-        if (mName == null || mAddress == null) {
-            if (DBG) Log.d(TAG, "Name or address not cached...");
-        }
+        if (DBG) Log.d(TAG, "Stored bluetooth Name=" + mName + ",Address=" + mAddress);
     }
 
     /**
@@ -249,6 +257,10 @@
             if (DBG)  Log.d(TAG,"Stored Bluetoothaddress: " +
                 Settings.Secure.getString(mContentResolver,SECURE_SETTINGS_BLUETOOTH_ADDRESS));
         }
+
+        if ((name != null) && (address != null)) {
+            Settings.Secure.putInt(mContentResolver, SECURE_SETTINGS_BLUETOOTH_ADDR_VALID, 1);
+        }
     }
 
     public IBluetooth registerAdapter(IBluetoothManagerCallback callback){
@@ -560,8 +572,19 @@
                     break;
                 }
                 case MESSAGE_SAVE_NAME_AND_ADDRESS: {
+                    boolean unbind = false;
                     if (DBG) Log.d(TAG,"MESSAGE_SAVE_NAME_AND_ADDRESS");
                     synchronized(mConnection) {
+                        if (!mEnable && mBluetooth != null) {
+                            try {
+                                mBluetooth.enable();
+                            } catch (RemoteException e) {
+                                Log.e(TAG,"Unable to call enable()",e);
+                            }
+                        }
+                    }
+                    if (mBluetooth != null) waitForOnOff(true, false);
+                    synchronized(mConnection) {
                         if (mBluetooth != null) {
                             String name =  null;
                             String address = null;
@@ -575,7 +598,7 @@
                             if (name != null && address != null) {
                                 storeNameAndAddress(name,address);
                                 if (mConnection.isGetNameAddressOnly()) {
-                                    unbindAndFinish();
+                                    unbind = true;
                                 }
                             } else {
                                 if (msg.arg1 < MAX_SAVE_RETRIES) {
@@ -586,10 +609,17 @@
                                 } else {
                                     Log.w(TAG,"Maximum name/address remote retrieval retry exceeded");
                                     if (mConnection.isGetNameAddressOnly()) {
-                                        unbindAndFinish();
+                                        unbind = true;
                                     }
                                 }
                             }
+                            if (!mEnable) {
+                                try {
+                                    mBluetooth.disable();
+                                } catch (RemoteException e) {
+                                    Log.e(TAG,"Unable to call disable()",e);
+                                }
+                            }
                         } else {
                             // rebind service by Request GET NAME AND ADDRESS
                             // if service is unbinded by disable or
@@ -598,6 +628,10 @@
                             mHandler.sendMessage(getMsg);
                         }
                     }
+                    if (!mEnable && mBluetooth != null) waitForOnOff(false, true);
+                    if (unbind) {
+                        unbindAndFinish();
+                    }
                     break;
                 }
                 case MESSAGE_ENABLE:
@@ -677,14 +711,6 @@
                         //Inform BluetoothAdapter instances that service is up
                         sendBluetoothServiceUpCallback();
 
-                        //Check if name and address is loaded if not get it first.
-                        if (!isNameAndAddressSet()) {
-                            try {
-                                storeNameAndAddress(mBluetooth.getName(),
-                                                    mBluetooth.getAddress());
-                            } catch (RemoteException e) {Log.e(TAG, "", e);};
-                        }
-
                         //Do enable request
                         try {
                             if (mQuietEnable == false) {
@@ -873,14 +899,6 @@
                     sendBluetoothServiceUpCallback();
                 }
 
-                //Check if name and address is loaded if not get it first.
-                if (!isNameAndAddressSet()) {
-                    try {
-                        if (DBG) Log.d(TAG,"Getting and storing Bluetooth name and address prior to enable.");
-                        storeNameAndAddress(mBluetooth.getName(),mBluetooth.getAddress());
-                    } catch (RemoteException e) {Log.e(TAG, "", e);};
-                }
-
                 //Enable bluetooth
                 try {
                     if (!mQuietEnable) {
diff --git a/services/java/com/android/server/wm/AppWindowAnimator.java b/services/java/com/android/server/wm/AppWindowAnimator.java
index 2445b98..ca94d04 100644
--- a/services/java/com/android/server/wm/AppWindowAnimator.java
+++ b/services/java/com/android/server/wm/AppWindowAnimator.java
@@ -279,22 +279,22 @@
         return isAnimating;
     }
 
-    void dump(PrintWriter pw, String prefix) {
-        if (freezingScreen) {
-            pw.print(prefix); pw.print(" freezingScreen="); pw.println(freezingScreen);
-        }
+    void dump(PrintWriter pw, String prefix, boolean dumpAll) {
+        pw.print(prefix); pw.print("mAppToken="); pw.println(mAppToken);
+        pw.print(prefix); pw.print("mAnimator="); pw.println(mAnimator);
+        pw.print(prefix); pw.print("freezingScreen="); pw.print(freezingScreen);
+                pw.print(" allDrawn="); pw.print(allDrawn);
+                pw.print(" animLayerAdjustment="); pw.println(animLayerAdjustment);
         if (animating || animation != null) {
             pw.print(prefix); pw.print("animating="); pw.print(animating);
-                    pw.print(" animation="); pw.println(animation);
+                    pw.print(" animInitialized="); pw.println(animInitialized);
+            pw.print(prefix); pw.print("animation="); pw.println(animation);
         }
         if (hasTransformation) {
             pw.print(prefix); pw.print("XForm: ");
                     transformation.printShortString(pw);
                     pw.println();
         }
-        if (animLayerAdjustment != 0) {
-            pw.print(prefix); pw.print("animLayerAdjustment="); pw.println(animLayerAdjustment);
-        }
         if (thumbnail != null) {
             pw.print(prefix); pw.print("thumbnail="); pw.print(thumbnail);
                     pw.print(" x="); pw.print(thumbnailX);
@@ -304,6 +304,11 @@
             pw.print(prefix); pw.print("thumbnailTransformation=");
                     pw.println(thumbnailTransformation.toShortString());
         }
+        for (int i=0; i<mAllAppWinAnimators.size(); i++) {
+            WindowStateAnimator wanim = mAllAppWinAnimators.get(i);
+            pw.print(prefix); pw.print("App Win Anim #"); pw.print(i);
+                    pw.print(": "); pw.println(wanim);
+        }
     }
 
     // This is an animation that does nothing: it just immediately finishes
diff --git a/services/java/com/android/server/wm/WindowAnimator.java b/services/java/com/android/server/wm/WindowAnimator.java
index 9a62482..c8d9cc3 100644
--- a/services/java/com/android/server/wm/WindowAnimator.java
+++ b/services/java/com/android/server/wm/WindowAnimator.java
@@ -18,12 +18,14 @@
 import android.util.Slog;
 import android.util.SparseArray;
 import android.util.SparseIntArray;
+import android.util.TimeUtils;
 import android.view.Display;
 import android.view.Surface;
 import android.view.WindowManagerPolicy;
 import android.view.animation.Animation;
 
 import com.android.server.wm.WindowManagerService.AppWindowAnimParams;
+import com.android.server.wm.WindowManagerService.LayoutFields;
 import com.android.server.wm.WindowManagerService.LayoutToAnimatorParams;
 
 import java.io.PrintWriter;
@@ -197,6 +199,15 @@
                 mWallpaperTokens = new ArrayList<WindowToken>(layoutToAnim.mWallpaperTokens);
             }
 
+            if (WindowManagerService.DEBUG_WALLPAPER_LIGHT) {
+                if (mWallpaperTarget != layoutToAnim.mWallpaperTarget
+                        || mLowerWallpaperTarget != layoutToAnim.mLowerWallpaperTarget
+                        || mUpperWallpaperTarget != layoutToAnim.mUpperWallpaperTarget) {
+                    Slog.d(TAG, "Updating anim wallpaper: target=" + mWallpaperTarget
+                            + " lower=" + mLowerWallpaperTarget + " upper="
+                            + mUpperWallpaperTarget);
+                }
+            }
             mWallpaperTarget = layoutToAnim.mWallpaperTarget;
             mWpAppAnimator = mWallpaperTarget == null
                     ? null : mWallpaperTarget.mAppToken == null
@@ -735,45 +746,143 @@
         return dimParams != null && dimParams.mDimWinAnimator == winAnimator;
     }
 
+    static String bulkUpdateParamsToString(int bulkUpdateParams) {
+        StringBuilder builder = new StringBuilder(128);
+        if ((bulkUpdateParams & LayoutFields.SET_UPDATE_ROTATION) != 0) {
+            builder.append(" UPDATE_ROTATION");
+        }
+        if ((bulkUpdateParams & LayoutFields.SET_WALLPAPER_MAY_CHANGE) != 0) {
+            builder.append(" WALLPAPER_MAY_CHANGE");
+        }
+        if ((bulkUpdateParams & LayoutFields.SET_FORCE_HIDING_CHANGED) != 0) {
+            builder.append(" FORCE_HIDING_CHANGED");
+        }
+        if ((bulkUpdateParams & LayoutFields.SET_ORIENTATION_CHANGE_COMPLETE) != 0) {
+            builder.append(" ORIENTATION_CHANGE_COMPLETE");
+        }
+        if ((bulkUpdateParams & LayoutFields.SET_TURN_ON_SCREEN) != 0) {
+            builder.append(" TURN_ON_SCREEN");
+        }
+        return builder.toString();
+    }
+
     public void dumpLocked(PrintWriter pw, String prefix, boolean dumpAll) {
-        if (dumpAll) {
-            if (mWindowDetachedWallpaper != null) {
-                pw.print(prefix); pw.print("mWindowDetachedWallpaper=");
-                    pw.println(mWindowDetachedWallpaper);
+        final String subPrefix = "  " + prefix;
+        final String subSubPrefix = "  " + subPrefix;
+
+        boolean needSep = false;
+        if (mAppAnimators.size() > 0) {
+            needSep = true;
+            pw.println("  App Animators:");
+            for (int i=mAppAnimators.size()-1; i>=0; i--) {
+                AppWindowAnimator anim = mAppAnimators.get(i);
+                pw.print(prefix); pw.print("App Animator #"); pw.print(i);
+                        pw.print(' '); pw.print(anim);
+                if (dumpAll) {
+                    pw.println(':');
+                    anim.dump(pw, subPrefix, dumpAll);
+                } else {
+                    pw.println();
+                }
             }
-            pw.print(prefix); pw.print("mAnimTransactionSequence=");
-                pw.print(mAnimTransactionSequence);
-                pw.println(" mForceHiding=" + forceHidingToString());
-            for (int i = 0; i < mDisplayContentsAnimators.size(); i++) {
-                pw.print(prefix); pw.print("DisplayContentsAnimator #");
-                    pw.println(mDisplayContentsAnimators.keyAt(i));
-                DisplayContentsAnimator displayAnimator = mDisplayContentsAnimators.valueAt(i);
-                final String subPrefix = "  " + prefix;
-                final String subSubPrefix = "  " + subPrefix;
-                if (displayAnimator.mWindowAnimationBackgroundSurface != null) {
-                    pw.println(subPrefix + "mWindowAnimationBackgroundSurface:");
+        }
+        if (mWallpaperTokens.size() > 0) {
+            if (needSep) {
+                pw.println();
+            }
+            needSep = true;
+            pw.print(prefix); pw.println("Wallpaper tokens:");
+            for (int i=mWallpaperTokens.size()-1; i>=0; i--) {
+                WindowToken token = mWallpaperTokens.get(i);
+                pw.print(prefix); pw.print("Wallpaper #"); pw.print(i);
+                        pw.print(' '); pw.print(token);
+                if (dumpAll) {
+                    pw.println(':');
+                    token.dump(pw, subPrefix);
+                } else {
+                    pw.println();
+                }
+            }
+        }
+
+        if (needSep) {
+            pw.println();
+        }
+        for (int i = 0; i < mDisplayContentsAnimators.size(); i++) {
+            pw.print(prefix); pw.print("DisplayContentsAnimator #");
+                    pw.print(mDisplayContentsAnimators.keyAt(i));
+                    pw.println(":");
+            DisplayContentsAnimator displayAnimator = mDisplayContentsAnimators.valueAt(i);
+            for (int j=0; j<displayAnimator.mWinAnimators.size(); j++) {
+                WindowStateAnimator wanim = displayAnimator.mWinAnimators.get(j);
+                pw.print(subPrefix); pw.print("Window #"); pw.print(j);
+                        pw.print(": "); pw.println(wanim);
+            }
+            if (displayAnimator.mWindowAnimationBackgroundSurface != null) {
+                if (dumpAll || displayAnimator.mWindowAnimationBackgroundSurface.mDimShown) {
+                    pw.print(subPrefix); pw.println("mWindowAnimationBackgroundSurface:");
                     displayAnimator.mWindowAnimationBackgroundSurface.printTo(subSubPrefix, pw);
                 }
-                if (displayAnimator.mDimAnimator != null) {
-                    pw.println(subPrefix + "mDimAnimator:");
-                    displayAnimator.mDimAnimator.printTo(subSubPrefix, pw);
-                } else {
-                    pw.println(subPrefix + "no DimAnimator ");
-                }
-                if (displayAnimator.mDimParams != null) {
-                    pw.println(subPrefix + "mDimParams:");
-                    displayAnimator.mDimParams.printTo(subSubPrefix, pw);
-                } else {
-                    pw.println(subPrefix + "no DimParams ");
-                }
-                if (displayAnimator.mScreenRotationAnimation != null) {
-                    pw.println(subPrefix + "mScreenRotationAnimation:");
-                    displayAnimator.mScreenRotationAnimation.printTo(subSubPrefix, pw);
-                } else {
-                    pw.print(subPrefix + "no ScreenRotationAnimation ");
-                }
             }
-            pw.println();
+            if (displayAnimator.mDimAnimator != null) {
+                if (dumpAll || displayAnimator.mDimAnimator.mDimShown) {
+                    pw.print(subPrefix); pw.println("mDimAnimator:");
+                    displayAnimator.mDimAnimator.printTo(subSubPrefix, pw);
+                }
+            } else if (dumpAll) {
+                pw.print(subPrefix); pw.println("no DimAnimator ");
+            }
+            if (displayAnimator.mDimParams != null) {
+                pw.print(subPrefix); pw.println("mDimParams:");
+                displayAnimator.mDimParams.printTo(subSubPrefix, pw);
+            } else if (dumpAll) {
+                pw.print(subPrefix); pw.println("no DimParams ");
+            }
+            if (displayAnimator.mScreenRotationAnimation != null) {
+                pw.print(subPrefix); pw.println("mScreenRotationAnimation:");
+                displayAnimator.mScreenRotationAnimation.printTo(subSubPrefix, pw);
+            } else if (dumpAll) {
+                pw.print(subPrefix); pw.println("no ScreenRotationAnimation ");
+            }
+        }
+
+        pw.println();
+
+        if (dumpAll) {
+            pw.print(prefix); pw.print("mAnimTransactionSequence=");
+                    pw.print(mAnimTransactionSequence);
+                    pw.print(" mForceHiding="); pw.println(forceHidingToString());
+            pw.print(prefix); pw.print("mCurrentTime=");
+                    pw.println(TimeUtils.formatUptime(mCurrentTime));
+            pw.print(prefix); pw.print("mDw=");
+                    pw.print(mDw); pw.print(" mDh="); pw.print(mDh);
+                    pw.print(" mInnerDw="); pw.print(mInnerDw);
+                    pw.print(" mInnerDh="); pw.println(mInnerDh);
+        }
+        if (mBulkUpdateParams != 0) {
+            pw.print(prefix); pw.print("mBulkUpdateParams=0x");
+                    pw.print(Integer.toHexString(mBulkUpdateParams));
+                    pw.println(bulkUpdateParamsToString(mBulkUpdateParams));
+        }
+        if (mPendingActions != 0) {
+            pw.print(prefix); pw.print("mPendingActions=0x");
+                    pw.println(Integer.toHexString(mPendingActions));
+        }
+        if (mWindowDetachedWallpaper != null) {
+            pw.print(prefix); pw.print("mWindowDetachedWallpaper=");
+                pw.println(mWindowDetachedWallpaper);
+        }
+        pw.print(prefix); pw.print("mWallpaperTarget="); pw.println(mWallpaperTarget);
+        pw.print(prefix); pw.print("mWpAppAnimator="); pw.println(mWpAppAnimator);
+        if (mLowerWallpaperTarget != null || mUpperWallpaperTarget != null) {
+            pw.print(prefix); pw.print("mLowerWallpaperTarget=");
+                    pw.println(mLowerWallpaperTarget);
+            pw.print(prefix); pw.print("mUpperWallpaperTarget=");
+                    pw.println(mUpperWallpaperTarget);
+        }
+        if (mUniverseBackground != null) {
+            pw.print(prefix); pw.print("mUniverseBackground="); pw.print(mUniverseBackground);
+                    pw.print(" mAboveUniverseLayer="); pw.println(mAboveUniverseLayer);
         }
     }
 
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 7958f9a..137c8ee 100755
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -10329,6 +10329,11 @@
         mPolicy.dump("    ", pw, args);
     }
 
+    void dumpAnimatorLocked(PrintWriter pw, String[] args, boolean dumpAll) {
+        pw.println("WINDOW MANAGER ANIMATOR STATE (dumpsys window animator)");
+        mAnimator.dumpLocked(pw, "    ", dumpAll);
+    }
+
     void dumpTokensLocked(PrintWriter pw, boolean dumpAll) {
         pw.println("WINDOW MANAGER TOKENS (dumpsys window tokens)");
         if (mTokenMap.size() > 0) {
@@ -10605,7 +10610,7 @@
                 pw.print("  mInputMethodWindow="); pw.println(mInputMethodWindow);
             }
             pw.print("  mWallpaperTarget="); pw.println(mWallpaperTarget);
-            if (mLowerWallpaperTarget != null && mUpperWallpaperTarget != null) {
+            if (mLowerWallpaperTarget != null || mUpperWallpaperTarget != null) {
                 pw.print("  mLowerWallpaperTarget="); pw.println(mLowerWallpaperTarget);
                 pw.print("  mUpperWallpaperTarget="); pw.println(mUpperWallpaperTarget);
             }
@@ -10689,8 +10694,32 @@
             }
             pw.print("  mStartingIconInTransition="); pw.print(mStartingIconInTransition);
                     pw.print(" mSkipAppTransitionAnimation="); pw.println(mSkipAppTransitionAnimation);
-            pw.println("  Window Animator:");
-            mAnimator.dumpLocked(pw, "    ", dumpAll);
+            pw.println("  mLayoutToAnim:");
+            pw.print("    mParamsModified="); pw.print(mLayoutToAnim.mParamsModified);
+                    pw.print(" mAnimationScheduled="); pw.print(mLayoutToAnim.mAnimationScheduled);
+                    pw.print(" mChanges=0x");
+                    pw.println(Long.toHexString(mLayoutToAnim.mChanges));
+            pw.print("    mWallpaperTarget="); pw.println(mLayoutToAnim.mWallpaperTarget);
+            if (mLayoutToAnim.mLowerWallpaperTarget != null
+                    || mLayoutToAnim.mUpperWallpaperTarget != null) {
+                pw.print("    mLowerWallpaperTarget=");
+                        pw.println(mLayoutToAnim.mLowerWallpaperTarget);
+                pw.print("    mUpperWallpaperTarget=");
+                        pw.println(mLayoutToAnim.mUpperWallpaperTarget);
+            }
+            for (int i=0; i<mLayoutToAnim.mWinAnimatorLists.size(); i++) {
+                pw.print("    Win Animator List #");
+                        pw.print(mLayoutToAnim.mWinAnimatorLists.keyAt(i)); pw.println(":");
+                WinAnimatorList wanim = mLayoutToAnim.mWinAnimatorLists.valueAt(i);
+                for (int wi=0; wi<wanim.size(); wi++) {
+                    pw.print("      "); pw.println(wanim.get(wi));
+                }
+            }
+            for (int i=0; i<mLayoutToAnim.mWallpaperTokens.size(); i++) {
+                pw.print("    Wallpaper Token #"); pw.print(i); pw.print(": ");
+                        pw.println(mLayoutToAnim.mWallpaperTokens.get(i));
+            }
+            // XXX also need to print mDimParams and mAppWindowAnimParams.  I am lazy.
         }
     }
 
@@ -10800,6 +10829,7 @@
                 pw.println("  cmd may be one of:");
                 pw.println("    l[astanr]: last ANR information");
                 pw.println("    p[policy]: policy state");
+                pw.println("    a[animator]: animator state");
                 pw.println("    s[essions]: active sessions");
                 pw.println("    t[okens]: token list");
                 pw.println("    w[indows]: window list");
@@ -10829,6 +10859,11 @@
                     dumpPolicyLocked(pw, args, true);
                 }
                 return;
+            } else if ("animator".equals(cmd) || "a".equals(cmd)) {
+                synchronized(mWindowMap) {
+                    dumpAnimatorLocked(pw, args, true);
+                }
+                return;
             } else if ("sessions".equals(cmd) || "s".equals(cmd)) {
                 synchronized(mWindowMap) {
                     dumpSessionsLocked(pw, true);
@@ -10874,6 +10909,11 @@
             if (dumpAll) {
                 pw.println("-------------------------------------------------------------------------------");
             }
+            dumpAnimatorLocked(pw, args, dumpAll);
+            pw.println();
+            if (dumpAll) {
+                pw.println("-------------------------------------------------------------------------------");
+            }
             dumpSessionsLocked(pw, dumpAll);
             pw.println();
             if (dumpAll) {
diff --git a/services/java/com/android/server/wm/WindowState.java b/services/java/com/android/server/wm/WindowState.java
index 0a9c3e5..e1cc58f 100644
--- a/services/java/com/android/server/wm/WindowState.java
+++ b/services/java/com/android/server/wm/WindowState.java
@@ -250,7 +250,7 @@
     // Used to improve performance of toString()
     String mStringNameCache;
     CharSequence mLastTitle;
-    boolean mWasPaused;
+    boolean mWasExiting;
 
     final WindowStateAnimator mWinAnimator;
 
@@ -1206,7 +1206,8 @@
                     pw.print(" visible="); mLastVisibleInsets.printShortString(pw);
                     pw.println();
         }
-        mWinAnimator.dump(pw, prefix, dumpAll);
+        pw.print(prefix); pw.print(mWinAnimator); pw.println(":");
+        mWinAnimator.dump(pw, prefix + "  ", dumpAll);
         if (mExiting || mRemoveOnExit || mDestroying || mRemoved) {
             pw.print(prefix); pw.print("mExiting="); pw.print(mExiting);
                     pw.print(" mRemoveOnExit="); pw.print(mRemoveOnExit);
@@ -1241,9 +1242,9 @@
     @Override
     public String toString() {
         if (mStringNameCache == null || mLastTitle != mAttrs.getTitle()
-                || mWasPaused != mToken.paused) {
+                || mWasExiting != mExiting) {
             mLastTitle = mAttrs.getTitle();
-            mWasPaused = mToken.paused;
+            mWasExiting = mExiting;
             mStringNameCache = "Window{" + Integer.toHexString(System.identityHashCode(this))
                     + " u" + UserHandle.getUserId(mSession.mUid)
                     + " " + mLastTitle + (mExiting ? " EXITING}" : "}");
diff --git a/services/java/com/android/server/wm/WindowStateAnimator.java b/services/java/com/android/server/wm/WindowStateAnimator.java
index 2bfefe1..85f087f 100644
--- a/services/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/java/com/android/server/wm/WindowStateAnimator.java
@@ -1604,10 +1604,11 @@
 
     @Override
     public String toString() {
-        StringBuffer sb = new StringBuffer("WindowStateAnimator (");
-        sb.append(mWin.mLastTitle + "): ");
-        sb.append("mSurface " + mSurface);
-        sb.append(", mAnimation " + mAnimation);
+        StringBuffer sb = new StringBuffer("WindowStateAnimator{");
+        sb.append(Integer.toHexString(System.identityHashCode(this)));
+        sb.append(' ');
+        sb.append(mWin.mAttrs.getTitle());
+        sb.append('}');
         return sb.toString();
     }
 }