Merge change I729c3938 into eclair-mr2

* changes:
  Insert a small delay after submitting to surface flinger and before returning the buffer to the decoder.
diff --git a/Android.mk b/Android.mk
index 1428454..2e2fec1 100644
--- a/Android.mk
+++ b/Android.mk
@@ -90,6 +90,7 @@
 	core/java/android/backup/IRestoreSession.aidl \
 	core/java/android/bluetooth/IBluetooth.aidl \
 	core/java/android/bluetooth/IBluetoothA2dp.aidl \
+	core/java/android/bluetooth/IBluetoothCallback.aidl \
 	core/java/android/bluetooth/IBluetoothHeadset.aidl \
 	core/java/android/bluetooth/IBluetoothPbap.aidl \
 	core/java/android/content/IContentService.aidl \
diff --git a/api/current.xml b/api/current.xml
index ae9d0bf..b269c82 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -25550,6 +25550,17 @@
  visibility="public"
 >
 </method>
+<method name="getDefaultAdapter"
+ return="android.bluetooth.BluetoothAdapter"
+ abstract="false"
+ native="false"
+ synchronized="true"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
 <method name="getName"
  return="java.lang.String"
  abstract="false"
@@ -25618,7 +25629,7 @@
  visibility="public"
 >
 </method>
-<method name="listenUsingRfcomm"
+<method name="listenUsingRfcommWithServiceRecord"
  return="android.bluetooth.BluetoothServerSocket"
  abstract="false"
  native="false"
@@ -25630,7 +25641,7 @@
 >
 <parameter name="name" type="java.lang.String">
 </parameter>
-<parameter name="uuid" type="android.os.ParcelUuid">
+<parameter name="uuid" type="java.util.UUID">
 </parameter>
 <exception name="IOException" type="java.io.IOException">
 </exception>
@@ -26804,7 +26815,7 @@
 >
 <implements name="android.os.Parcelable">
 </implements>
-<method name="createRfcommSocket"
+<method name="createRfcommSocketToServiceRecord"
  return="android.bluetooth.BluetoothSocket"
  abstract="false"
  native="false"
@@ -26814,7 +26825,7 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="channel" type="int">
+<parameter name="uuid" type="java.util.UUID">
 </parameter>
 <exception name="IOException" type="java.io.IOException">
 </exception>
@@ -31505,17 +31516,6 @@
  visibility="public"
 >
 </field>
-<field name="BLUETOOTH_SERVICE"
- type="java.lang.String"
- transient="false"
- volatile="false"
- value="&quot;bluetooth&quot;"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
 <field name="CLIPBOARD_SERVICE"
  type="java.lang.String"
  transient="false"
diff --git a/camera/libcameraservice/CameraService.cpp b/camera/libcameraservice/CameraService.cpp
index 8279914..b63e97f 100644
--- a/camera/libcameraservice/CameraService.cpp
+++ b/camera/libcameraservice/CameraService.cpp
@@ -563,7 +563,19 @@
     status_t ret = NO_ERROR;
     if (mSurface != 0) {
         if (mOverlayRef.get() == NULL) {
-            mOverlayRef = mSurface->createOverlay(w, h, OVERLAY_FORMAT_DEFAULT);
+
+            // FIXME:
+            // Surfaceflinger may hold onto the previous overlay reference for some
+            // time after we try to destroy it. retry a few times. In the future, we
+            // should make the destroy call block, or possibly specify that we can
+            // wait in the createOverlay call if the previous overlay is in the 
+            // process of being destroyed.
+            for (int retry = 0; retry < 50; ++retry) {
+                mOverlayRef = mSurface->createOverlay(w, h, OVERLAY_FORMAT_DEFAULT);
+                if (mOverlayRef != NULL) break;
+                LOGD("Overlay create failed - retrying");
+                usleep(20000);
+            }
             if ( mOverlayRef.get() == NULL )
             {
                 LOGE("Overlay Creation Failed!");
diff --git a/cmds/dumpstate/dumpstate.c b/cmds/dumpstate/dumpstate.c
index 4a71dc6..9c2becf 100644
--- a/cmds/dumpstate/dumpstate.c
+++ b/cmds/dumpstate/dumpstate.c
@@ -110,7 +110,7 @@
         PRINT("------ PACKAGE UID ERRORS ------");
         DUMP("/data/system/uiderrors.txt");
 
-        dump_kernel_log("/data/dontpanic/last_kmsg", "RAMCONSOLE");
+        dump_kernel_log("/data/dontpanic/last_kmsg", "LAST KMSG");
         dump_kernel_log("/data/dontpanic/apanic_console",
                         "PANIC CONSOLE");
         dump_kernel_log("/data/dontpanic/apanic_threads",
diff --git a/core/java/android/accounts/AuthenticatorBindHelper.java b/core/java/android/accounts/AuthenticatorBindHelper.java
index 91e23ab..2ca1f0e 100644
--- a/core/java/android/accounts/AuthenticatorBindHelper.java
+++ b/core/java/android/accounts/AuthenticatorBindHelper.java
@@ -146,7 +146,7 @@
                                 Log.v(TAG, "there are no more callbacks for service "
                                         + authenticatorType + ", unbinding service");
                             }
-                            unbindFromService(authenticatorType);
+                            unbindFromServiceLocked(authenticatorType);
                         } else {
                             if (Log.isLoggable(TAG, Log.VERBOSE)) {
                                 Log.v(TAG, "leaving service " + authenticatorType
@@ -161,7 +161,10 @@
         }
     }
 
-    private void unbindFromService(String authenticatorType) {
+    /**
+     * You must synchronized on mServiceConnections before calling this
+     */
+    private void unbindFromServiceLocked(String authenticatorType) {
         if (Log.isLoggable(TAG, Log.VERBOSE)) {
             Log.v(TAG, "unbindService from " + authenticatorType);
         }
@@ -217,15 +220,18 @@
             // post a message for each service user to tell them that the service is disconnected,
             // and unbind from the service.
             synchronized (mServiceConnections) {
-                for (Callback callback : mServiceUsers.get(mAuthenticatorType)) {
-                    if (Log.isLoggable(TAG, Log.VERBOSE)) {
-                        Log.v(TAG, "the service became disconnected, scheduling a "
-                                + "disconnected message for "
-                                + mAuthenticatorType);
+                final ArrayList<Callback> callbackList = mServiceUsers.get(mAuthenticatorType);
+                if (callbackList != null) {
+                    for (Callback callback : callbackList) {
+                        if (Log.isLoggable(TAG, Log.VERBOSE)) {
+                            Log.v(TAG, "the service became disconnected, scheduling a "
+                                    + "disconnected message for "
+                                    + mAuthenticatorType);
+                        }
+                        mHandler.obtainMessage(mMessageWhatDisconnected, callback).sendToTarget();
                     }
-                    mHandler.obtainMessage(mMessageWhatDisconnected, callback).sendToTarget();
+                    unbindFromServiceLocked(mAuthenticatorType);
                 }
-                unbindFromService(mAuthenticatorType);
             }
         }
     }
diff --git a/core/java/android/app/ApplicationContext.java b/core/java/android/app/ApplicationContext.java
index 8ba7c01..f48f150 100644
--- a/core/java/android/app/ApplicationContext.java
+++ b/core/java/android/app/ApplicationContext.java
@@ -22,8 +22,6 @@
 
 import org.xmlpull.v1.XmlPullParserException;
 
-import android.bluetooth.BluetoothAdapter;
-import android.bluetooth.IBluetooth;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.ContentResolver;
@@ -182,8 +180,6 @@
     private StatusBarManager mStatusBarManager = null;
     private TelephonyManager mTelephonyManager = null;
     private ClipboardManager mClipboardManager = null;
-    private boolean mIsBluetoothAdapterCached = false;
-    private BluetoothAdapter mBluetoothAdapter;
     private boolean mRestricted;
     private AccountManager mAccountManager; // protected by mSync
 
@@ -883,8 +879,6 @@
             return getSearchManager();
         } else if (SENSOR_SERVICE.equals(name)) {
             return getSensorManager();
-        } else if (BLUETOOTH_SERVICE.equals(name)) {
-            return getBluetoothAdapter();
         } else if (VIBRATOR_SERVICE.equals(name)) {
             return getVibrator();
         } else if (STATUS_BAR_SERVICE.equals(name)) {
@@ -1034,18 +1028,6 @@
         return mSearchManager;
     }
 
-    private synchronized BluetoothAdapter getBluetoothAdapter() {
-        if (!mIsBluetoothAdapterCached) {
-            mIsBluetoothAdapterCached = true;
-            IBinder b = ServiceManager.getService(BLUETOOTH_SERVICE);
-            if (b != null) {
-                IBluetooth service = IBluetooth.Stub.asInterface(b);
-                mBluetoothAdapter = new BluetoothAdapter(service);
-            }
-        }
-        return mBluetoothAdapter;
-    }
-
     private SensorManager getSensorManager() {
         synchronized (mSync) {
             if (mSensorManager == null) {
diff --git a/core/java/android/app/SearchDialog.java b/core/java/android/app/SearchDialog.java
index 933c2fc..697ac76 100644
--- a/core/java/android/app/SearchDialog.java
+++ b/core/java/android/app/SearchDialog.java
@@ -1314,13 +1314,13 @@
             // source. this is because GlobalSearch may not have permission to launch the
             // intent, and to avoid the extra step of going through GlobalSearch.
             if (mGlobalSearchMode) {
+                launchGlobalSearchIntent(intent);
                 if (mStoredComponentName != null) {
                     // If we're embedded in an application, dismiss the dialog.
                     // This ensures that if the intent is handled by the current
                     // activity, it's not obscured by the dialog.
                     dismiss();
                 }
-                launchGlobalSearchIntent(intent);
             } else {
                 // If the intent was created from a suggestion, it will always have an explicit
                 // component here.
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index c6a0619..cc35b7d 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -20,9 +20,11 @@
 import android.annotation.SdkConstant.SdkConstantType;
 import android.os.Binder;
 import android.os.Handler;
+import android.os.IBinder;
 import android.os.Message;
 import android.os.ParcelUuid;
 import android.os.RemoteException;
+import android.os.ServiceManager;
 import android.util.Log;
 
 import java.io.IOException;
@@ -31,14 +33,13 @@
 import java.util.LinkedList;
 import java.util.Random;
 import java.util.Set;
+import java.util.UUID;
 
 /**
  * Represents the local Bluetooth adapter.
  *
- * <p>Use {@link android.content.Context#getSystemService} with {@link
- * android.content.Context#BLUETOOTH_SERVICE} to get the default local
- * Bluetooth adapter. On most Android devices there is only one local
- * Bluetotoh adapter.
+ * <p>Use {@link #getDefaultAdapter} to get the default local Bluetooth
+ * adapter.
  *
  * <p>Use the {@link BluetoothDevice} class for operations on remote Bluetooth
  * devices.
@@ -256,12 +257,40 @@
      */
     public static final String EXTRA_LOCAL_NAME = "android.bluetooth.adapter.extra.LOCAL_NAME";
 
+    /** @hide */
+    public static final String BLUETOOTH_SERVICE = "bluetooth";
+
     private static final int ADDRESS_LENGTH = 17;
 
+    /**
+     * Lazyily initialized singleton. Guaranteed final after first object
+     * constructed.
+     */
+    private static BluetoothAdapter sAdapter;
+
     private final IBluetooth mService;
 
     /**
-     * Do not use this constructor. Use Context.getSystemService() instead.
+     * Get a handle to the default local Bluetooth adapter.
+     * <p>Currently Android only supports one Bluetooth adapter, but the API
+     * could be extended to support more. This will always return the default
+     * adapter.
+     * @return the default local adapter, or null if Bluetooth is not supported
+     *         on this hardware platform
+     */
+    public static synchronized BluetoothAdapter getDefaultAdapter() {
+        if (sAdapter == null) {
+            IBinder b = ServiceManager.getService(BluetoothAdapter.BLUETOOTH_SERVICE);
+            if (b != null) {
+                IBluetooth service = IBluetooth.Stub.asInterface(b);
+                sAdapter = new BluetoothAdapter(service);
+            }
+        }
+        return sAdapter;
+    }
+
+    /**
+     * Use {@link #getDefaultAdapter} to get the BluetoothAdapter instance.
      * @hide
      */
     public BluetoothAdapter(IBluetooth service) {
@@ -564,8 +593,16 @@
     }
 
     /**
-     * Randomly picks RFCOMM channels until none are left.
+     * Picks RFCOMM channels until none are left.
      * Avoids reserved channels.
+     * Ideally we would pick random channels, but in the current implementation
+     * we start with the channel that is the hash of the UUID, and try every
+     * available channel from there. This means that in most cases a given
+     * uuid will use the same channel. This is a workaround for a Bluez SDP
+     * bug where we are not updating the cache when the channel changes for a
+     * uuid.
+     * TODO: Fix the Bluez SDP caching bug, and go back to random channel
+     * selection
      */
     private static class RfcommChannelPicker {
         private static final int[] RESERVED_RFCOMM_CHANNELS =  new int[] {
@@ -579,7 +616,9 @@
 
         private final LinkedList<Integer> mChannels;  // local list of channels left to try
 
-        public RfcommChannelPicker() {
+        private final UUID mUuid;
+
+        public RfcommChannelPicker(UUID uuid) {
             synchronized (RfcommChannelPicker.class) {
                 if (sChannels == null) {
                     // lazy initialization of non-reserved rfcomm channels
@@ -594,13 +633,21 @@
                 }
                 mChannels = (LinkedList<Integer>)sChannels.clone();
             }
+            mUuid = uuid;
         }
-        /* Returns next random channel, or -1 if we're out */
+        /* Returns next channel, or -1 if we're out */
         public int nextChannel() {
-            if (mChannels.size() == 0) {
-                return -1;
+            int channel = mUuid.hashCode();  // always pick the same channel to try first
+            Integer channelInt;
+            while (mChannels.size() > 0) {
+                channelInt = new Integer(channel);
+                if (mChannels.remove(channelInt)) {
+                    return channel;
+                }
+                channel = (channel % BluetoothSocket.MAX_RFCOMM_CHANNEL) + 1;
             }
-            return mChannels.remove(sRandom.nextInt(mChannels.size()));
+
+            return -1;
         }
     }
 
@@ -644,6 +691,8 @@
      * can use the same UUID to query our SDP server and discover which channel
      * to connect to. This SDP record will be removed when this socket is
      * closed, or if this application closes unexpectedly.
+     * <p>Use {@link BluetoothDevice#createRfcommSocketToServiceRecord} to
+     * connect to this socket from another device using the same {@link UUID}.
      * <p>Requires {@link android.Manifest.permission#BLUETOOTH}
      * @param name service name for SDP record
      * @param uuid uuid for SDP record
@@ -651,9 +700,9 @@
      * @throws IOException on error, for example Bluetooth not available, or
      *                     insufficient permissions, or channel in use.
      */
-    public BluetoothServerSocket listenUsingRfcomm(String name, ParcelUuid uuid)
+    public BluetoothServerSocket listenUsingRfcommWithServiceRecord(String name, UUID uuid)
             throws IOException {
-        RfcommChannelPicker picker = new RfcommChannelPicker();
+        RfcommChannelPicker picker = new RfcommChannelPicker(uuid);
 
         BluetoothServerSocket socket;
         int channel;
@@ -687,7 +736,8 @@
 
         int handle = -1;
         try {
-            handle = mService.addRfcommServiceRecord(name, uuid, channel, new Binder());
+            handle = mService.addRfcommServiceRecord(name, new ParcelUuid(uuid), channel,
+                    new Binder());
         } catch (RemoteException e) {Log.e(TAG, "", e);}
         if (handle == -1) {
             try {
diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java
index d5393ed..9c23746 100644
--- a/core/java/android/bluetooth/BluetoothDevice.java
+++ b/core/java/android/bluetooth/BluetoothDevice.java
@@ -18,7 +18,6 @@
 
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
-import android.content.Context;
 import android.os.IBinder;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -316,11 +315,28 @@
      */
     public static final String EXTRA_UUID = "android.bluetooth.device.extra.UUID";
 
-
-    private static IBluetooth sService;  /* Guarenteed constant after first object constructed */
+    /**
+     * Lazy initialization. Guaranteed final after first object constructed, or
+     * getService() called.
+     * TODO: Unify implementation of sService amongst BluetoothFoo API's
+     */
+    private static IBluetooth sService;
 
     private final String mAddress;
 
+    /*package*/ static IBluetooth getService() {
+        synchronized (BluetoothDevice.class) {
+            if (sService == null) {
+                IBinder b = ServiceManager.getService(BluetoothAdapter.BLUETOOTH_SERVICE);
+                if (b == null) {
+                    throw new RuntimeException("Bluetooth service not available");
+                }
+                sService = IBluetooth.Stub.asInterface(b);
+            }
+        }
+        return sService;
+    }
+
     /**
      * Create a new BluetoothDevice
      * Bluetooth MAC address must be upper case, such as "00:11:22:33:AA:BB",
@@ -331,16 +347,7 @@
      * @hide
      */
     /*package*/ BluetoothDevice(String address) {
-        synchronized (BluetoothDevice.class) {
-            if (sService == null) {
-                IBinder b = ServiceManager.getService(Context.BLUETOOTH_SERVICE);
-                if (b == null) {
-                    throw new RuntimeException("Bluetooth service not available");
-                }
-                sService = IBluetooth.Stub.asInterface(b);
-            }
-        }
-
+        getService();  // ensures sService is initialized
         if (!BluetoothAdapter.checkBluetoothAddress(address)) {
             throw new IllegalArgumentException(address + " is not a valid Bluetooth address");
         }
@@ -551,7 +558,7 @@
       */
      public boolean fetchUuidsWithSdp() {
         try {
-            return sService.fetchRemoteUuidsWithSdp(mAddress);
+            return sService.fetchRemoteUuids(mAddress, null, null);
         } catch (RemoteException e) {Log.e(TAG, "", e);}
         return false;
     }
@@ -598,7 +605,7 @@
 
     /**
      * Create an RFCOMM {@link BluetoothSocket} ready to start a secure
-     * outgoing connection to this remote device.
+     * outgoing connection to this remote device on given channel.
      * <p>The remote device will be authenticated and communication on this
      * socket will be encrypted.
      * <p>Use {@link BluetoothSocket#connect} to intiate the outgoing
@@ -610,9 +617,34 @@
      * @return a RFCOMM BluetoothServerSocket ready for an outgoing connection
      * @throws IOException on error, for example Bluetooth not available, or
      *                     insufficient permissions
+     * @hide
      */
     public BluetoothSocket createRfcommSocket(int channel) throws IOException {
-        return new BluetoothSocket(BluetoothSocket.TYPE_RFCOMM, -1, true, true, this, channel);
+        return new BluetoothSocket(BluetoothSocket.TYPE_RFCOMM, -1, true, true, this, channel,
+                null);
+    }
+
+    /**
+     * Create an RFCOMM {@link BluetoothSocket} ready to start a secure
+     * outgoing connection to this remote device using SDP lookup of uuid.
+     * <p>This is designed to be used with {@link
+     * BluetoothAdapter#listenUsingRfcommWithServiceRecord} for peer-peer
+     * Bluetooth applications.
+     * <p>Use {@link BluetoothSocket#connect} to intiate the outgoing
+     * connection. This will also perform an SDP lookup of the given uuid to
+     * determine which channel to connect to.
+     * <p>The remote device will be authenticated and communication on this
+     * socket will be encrypted.
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH}
+     *
+     * @param uuid service record uuid to lookup RFCOMM channel
+     * @return a RFCOMM BluetoothServerSocket ready for an outgoing connection
+     * @throws IOException on error, for example Bluetooth not available, or
+     *                     insufficient permissions
+     */
+    public BluetoothSocket createRfcommSocketToServiceRecord(UUID uuid) throws IOException {
+        return new BluetoothSocket(BluetoothSocket.TYPE_RFCOMM, -1, true, true, this, -1,
+                new ParcelUuid(uuid));
     }
 
     /**
@@ -628,7 +660,8 @@
      * @hide
      */
     public BluetoothSocket createInsecureRfcommSocket(int port) throws IOException {
-        return new BluetoothSocket(BluetoothSocket.TYPE_RFCOMM, -1, false, false, this, port);
+        return new BluetoothSocket(BluetoothSocket.TYPE_RFCOMM, -1, false, false, this, port,
+                null);
     }
 
     /**
@@ -640,7 +673,7 @@
      * @hide
      */
     public BluetoothSocket createScoSocket() throws IOException {
-        return new BluetoothSocket(BluetoothSocket.TYPE_SCO, -1, true, true, this, -1);
+        return new BluetoothSocket(BluetoothSocket.TYPE_SCO, -1, true, true, this, -1, null);
     }
 
     /**
diff --git a/core/java/android/bluetooth/BluetoothServerSocket.java b/core/java/android/bluetooth/BluetoothServerSocket.java
index d126ea4..605bdc1 100644
--- a/core/java/android/bluetooth/BluetoothServerSocket.java
+++ b/core/java/android/bluetooth/BluetoothServerSocket.java
@@ -36,13 +36,13 @@
  * connection orientated, streaming transport over Bluetooth. It is also known
  * as the Serial Port Profile (SPP).
  *
- * <p>Use {@link BluetoothDevice#createRfcommSocket} to create a new {@link
- * BluetoothSocket} ready for an outgoing connection to a remote
+ * <p>Use {@link BluetoothDevice#createRfcommSocketToServiceRecord} to create
+ * a new {@link BluetoothSocket} ready for an outgoing connection to a remote
  * {@link BluetoothDevice}.
  *
- * <p>Use {@link BluetoothAdapter#listenUsingRfcomm} to create a listening
- * {@link BluetoothServerSocket} ready for incoming connections to the local
- * {@link BluetoothAdapter}.
+ * <p>Use {@link BluetoothAdapter#listenUsingRfcommWithServiceRecord} to
+ * create a listening {@link BluetoothServerSocket} ready for incoming
+ * connections to the local {@link BluetoothAdapter}.
  *
  * <p>{@link BluetoothSocket} and {@link BluetoothServerSocket} are thread
  * safe. In particular, {@link #close} will always immediately abort ongoing
@@ -68,7 +68,7 @@
      */
     /*package*/ BluetoothServerSocket(int type, boolean auth, boolean encrypt, int port)
             throws IOException {
-        mSocket = new BluetoothSocket(type, -1, auth, encrypt, null, port);
+        mSocket = new BluetoothSocket(type, -1, auth, encrypt, null, port, null);
     }
 
     /**
diff --git a/core/java/android/bluetooth/BluetoothSocket.java b/core/java/android/bluetooth/BluetoothSocket.java
index b9e33f3..7e72590 100644
--- a/core/java/android/bluetooth/BluetoothSocket.java
+++ b/core/java/android/bluetooth/BluetoothSocket.java
@@ -16,11 +16,15 @@
 
 package android.bluetooth;
 
+import android.bluetooth.IBluetoothCallback;
+import android.os.ParcelUuid;
+import android.os.RemoteException;
+import android.util.Log;
+
 import java.io.Closeable;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
-
 import java.util.concurrent.locks.ReentrantReadWriteLock;
 
 /**
@@ -38,13 +42,13 @@
  * connection orientated, streaming transport over Bluetooth. It is also known
  * as the Serial Port Profile (SPP).
  *
- * <p>Use {@link BluetoothDevice#createRfcommSocket} to create a new {@link
- * BluetoothSocket} ready for an outgoing connection to a remote
+ * <p>Use {@link BluetoothDevice#createRfcommSocketToServiceRecord} to create
+ * a new {@link BluetoothSocket} ready for an outgoing connection to a remote
  * {@link BluetoothDevice}.
  *
- * <p>Use {@link BluetoothAdapter#listenUsingRfcomm} to create a listening
- * {@link BluetoothServerSocket} ready for incoming connections to the local
- * {@link BluetoothAdapter}.
+ * <p>Use {@link BluetoothAdapter#listenUsingRfcommWithServiceRecord} to
+ * create a listening {@link BluetoothServerSocket} ready for incoming
+ * connections to the local {@link BluetoothAdapter}.
  *
  * <p>{@link BluetoothSocket} and {@link BluetoothServerSocket} are thread
  * safe. In particular, {@link #close} will always immediately abort ongoing
@@ -54,6 +58,8 @@
  * {@link android.Manifest.permission#BLUETOOTH}
  */
 public final class BluetoothSocket implements Closeable {
+    private static final String TAG = "BluetoothSocket";
+
     /** @hide */
     public static final int MAX_RFCOMM_CHANNEL = 30;
 
@@ -66,13 +72,15 @@
     /*package*/ static final int EADDRINUSE = 98;
 
     private final int mType;  /* one of TYPE_RFCOMM etc */
-    private final int mPort;  /* RFCOMM channel or L2CAP psm */
     private final BluetoothDevice mDevice;    /* remote device */
     private final String mAddress;    /* remote address */
     private final boolean mAuth;
     private final boolean mEncrypt;
     private final BluetoothInputStream mInputStream;
     private final BluetoothOutputStream mOutputStream;
+    private final SdpHelper mSdp;
+
+    private int mPort;  /* RFCOMM channel or L2CAP psm */
 
     /** prevents all native calls after destroyNative() */
     private boolean mClosed;
@@ -91,16 +99,24 @@
      * @param encrypt require the connection to be encrypted
      * @param device  remote device that this socket can connect to
      * @param port    remote port
+     * @param uuid    SDP uuid
      * @throws IOException On error, for example Bluetooth not available, or
      *                     insufficient priveleges
      */
     /*package*/ BluetoothSocket(int type, int fd, boolean auth, boolean encrypt,
-            BluetoothDevice device, int port) throws IOException {
-        if (type == BluetoothSocket.TYPE_RFCOMM) {
+            BluetoothDevice device, int port, ParcelUuid uuid) throws IOException {
+        if (type == BluetoothSocket.TYPE_RFCOMM && uuid == null && fd == -1) {
             if (port < 1 || port > MAX_RFCOMM_CHANNEL) {
                 throw new IOException("Invalid RFCOMM channel: " + port);
             }
         }
+        if (uuid == null) {
+            mPort = port;
+            mSdp = null;
+        } else {
+            mSdp = new SdpHelper(device, uuid);
+            mPort = -1;
+        }
         mType = type;
         mAuth = auth;
         mEncrypt = encrypt;
@@ -110,7 +126,6 @@
         } else {
             mAddress = device.getAddress();
         }
-        mPort = port;
         if (fd == -1) {
             initSocketNative();
         } else {
@@ -123,7 +138,7 @@
     }
 
     /**
-     * Construct a BluetoothSocket from address.
+     * Construct a BluetoothSocket from address. Used by native code.
      * @param type    type of socket
      * @param fd      fd to use for connected socket, or -1 for a new socket
      * @param auth    require the remote device to be authenticated
@@ -135,7 +150,7 @@
      */
     private BluetoothSocket(int type, int fd, boolean auth, boolean encrypt, String address,
             int port) throws IOException {
-        this(type, fd, auth, encrypt, new BluetoothDevice(address), port);
+        this(type, fd, auth, encrypt, new BluetoothDevice(address), port, null);
     }
 
     /** @hide */
@@ -160,7 +175,12 @@
         mLock.readLock().lock();
         try {
             if (mClosed) throw new IOException("socket closed");
-            connectNative();
+
+            if (mSdp != null) {
+                mPort = mSdp.doSdp();  // blocks
+            }
+
+            connectNative();  // blocks
         } finally {
             mLock.readLock().unlock();
         }
@@ -176,12 +196,15 @@
         mLock.readLock().lock();
         try {
             if (mClosed) return;
+            if (mSdp != null) {
+                mSdp.cancel();
+            }
             abortNative();
         } finally {
             mLock.readLock().unlock();
         }
 
-        // all native calls are guarenteed to immediately return after
+        // all native calls are guaranteed to immediately return after
         // abortNative(), so this lock should immediatley acquire
         mLock.writeLock().lock();
         try {
@@ -291,4 +314,62 @@
      * use strerr to convert to string error.
      */
     /*package*/ native void throwErrnoNative(int errno) throws IOException;
+
+    /**
+     * Helper to perform blocking SDP lookup.
+     */
+    private static class SdpHelper extends IBluetoothCallback.Stub {
+        private final IBluetooth service;
+        private final ParcelUuid uuid;
+        private final BluetoothDevice device;
+        private int channel;
+        private boolean canceled;
+        public SdpHelper(BluetoothDevice device, ParcelUuid uuid) {
+            service = BluetoothDevice.getService();
+            this.device = device;
+            this.uuid = uuid;
+            canceled = false;
+        }
+        /**
+         * Returns the RFCOMM channel for the UUID, or throws IOException
+         * on failure.
+         */
+        public synchronized int doSdp() throws IOException {
+            if (canceled) throw new IOException("Service discovery canceled");
+            channel = -1;
+
+            boolean inProgress = false;
+            try {
+                inProgress = service.fetchRemoteUuids(device.getAddress(), uuid, this);
+            } catch (RemoteException e) {Log.e(TAG, "", e);}
+
+            if (!inProgress) throw new IOException("Unable to start Service Discovery");
+
+            try {
+                /* 12 second timeout as a precaution - onRfcommChannelFound
+                 * should always occur before the timeout */
+                wait(12000);   // block
+
+            } catch (InterruptedException e) {}
+
+            if (canceled) throw new IOException("Service discovery canceled");
+            if (channel < 1) throw new IOException("Service discovery failed");
+
+            return channel;
+        }
+        /** Object cannot be re-used after calling cancel() */
+        public synchronized void cancel() {
+            if (!canceled) {
+                canceled = true;
+                channel = -1;
+                notifyAll();  // unblock
+            }
+        }
+        public synchronized void onRfcommChannelFound(int channel) {
+            if (!canceled) {
+                this.channel = channel;
+                notifyAll();  // unblock
+            }
+        }
+    }
 }
diff --git a/core/java/android/bluetooth/IBluetooth.aidl b/core/java/android/bluetooth/IBluetooth.aidl
index e54abec..7e752af 100644
--- a/core/java/android/bluetooth/IBluetooth.aidl
+++ b/core/java/android/bluetooth/IBluetooth.aidl
@@ -16,6 +16,7 @@
 
 package android.bluetooth;
 
+import android.bluetooth.IBluetoothCallback;
 import android.os.ParcelUuid;
 
 /**
@@ -53,8 +54,8 @@
     String getRemoteName(in String address);
     int getRemoteClass(in String address);
     ParcelUuid[] getRemoteUuids(in String address);
-    boolean fetchRemoteUuidsWithSdp(in String address);
-    int getRemoteServiceChannel(in String address,in ParcelUuid uuid);
+    boolean fetchRemoteUuids(in String address, in ParcelUuid uuid, in IBluetoothCallback callback);
+    int getRemoteServiceChannel(in String address, in ParcelUuid uuid);
 
     boolean setPin(in String address, in byte[] pin);
     boolean setPasskey(in String address, int passkey);
diff --git a/core/java/android/bluetooth/IBluetoothCallback.aidl b/core/java/android/bluetooth/IBluetoothCallback.aidl
new file mode 100644
index 0000000..8edb3f4
--- /dev/null
+++ b/core/java/android/bluetooth/IBluetoothCallback.aidl
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.bluetooth;
+
+/**
+ * System private API for Bluetooth service callbacks.
+ *
+ * {@hide}
+ */
+interface IBluetoothCallback
+{
+    void onRfcommChannelFound(int channel);
+}
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index fe4665e..8f1c671 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -1218,14 +1218,6 @@
      */
     public static final String SENSOR_SERVICE = "sensor";
     /**
-     * Use with {@link #getSystemService} to retrieve a {@link
-     * android.bluetooth.BluetoothAdapter} for using Bluetooth.
-     *
-     * @see #getSystemService
-     * @see android.bluetooth.BluetoothAdapter
-     */
-    public static final String BLUETOOTH_SERVICE = "bluetooth";
-    /**
      * Use with {@link #getSystemService} to retrieve a
      * com.android.server.WallpaperService for accessing wallpapers.
      *
diff --git a/core/java/android/server/BluetoothA2dpService.java b/core/java/android/server/BluetoothA2dpService.java
index d61b42f..b73e53f 100644
--- a/core/java/android/server/BluetoothA2dpService.java
+++ b/core/java/android/server/BluetoothA2dpService.java
@@ -137,7 +137,7 @@
             throw new RuntimeException("Could not init BluetoothA2dpService");
         }
 
-        mAdapter = (BluetoothAdapter) context.getSystemService(Context.BLUETOOTH_SERVICE);
+        mAdapter = BluetoothAdapter.getDefaultAdapter();
 
         mIntentFilter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
         mIntentFilter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
diff --git a/core/java/android/server/BluetoothEventLoop.java b/core/java/android/server/BluetoothEventLoop.java
index 0152223..da1918a 100644
--- a/core/java/android/server/BluetoothEventLoop.java
+++ b/core/java/android/server/BluetoothEventLoop.java
@@ -55,6 +55,10 @@
     private static final int EVENT_RESTART_BLUETOOTH = 2;
     private static final int EVENT_PAIRING_CONSENT_DELAYED_ACCEPT = 3;
 
+    private static final int CREATE_DEVICE_ALREADY_EXISTS = 1;
+    private static final int CREATE_DEVICE_SUCCESS = 0;
+    private static final int CREATE_DEVICE_FAILED = -1;
+
     // The time (in millisecs) to delay the pairing attempt after the first
     // auto pairing attempt fails. We use an exponential delay with
     // INIT_AUTO_PAIRING_FAILURE_ATTEMPT_DELAY as the initial value and
@@ -550,14 +554,27 @@
             mBluetoothService.updateRemoteDevicePropertiesCache(address);
         }
         mBluetoothService.sendUuidIntent(address);
+        mBluetoothService.makeServiceChannelCallbacks(address);
     }
 
-    private void onCreateDeviceResult(String address, boolean result) {
-        if (DBG) {
-            log("Result of onCreateDeviceResult:" + result);
-        }
-        if (!result) {
+    private void onCreateDeviceResult(String address, int result) {
+        if (DBG) log("Result of onCreateDeviceResult:" + result);
+
+        switch (result) {
+        case CREATE_DEVICE_ALREADY_EXISTS:
+            String path = mBluetoothService.getObjectPathFromAddress(address);
+            if (path != null) {
+                mBluetoothService.discoverServicesNative(path, "");
+                break;
+            }
+            Log.w(TAG, "Device exists, but we dont have the bluez path, failing");
+            // fall-through
+        case CREATE_DEVICE_FAILED:
             mBluetoothService.sendUuidIntent(address);
+            mBluetoothService.makeServiceChannelCallbacks(address);
+            break;
+        case CREATE_DEVICE_SUCCESS:
+            // nothing to do, UUID intent's will be sent via property changed
         }
     }
 
diff --git a/core/java/android/server/BluetoothService.java b/core/java/android/server/BluetoothService.java
index 93133d7..6d4d152 100644
--- a/core/java/android/server/BluetoothService.java
+++ b/core/java/android/server/BluetoothService.java
@@ -31,6 +31,7 @@
 import android.bluetooth.BluetoothSocket;
 import android.bluetooth.BluetoothUuid;
 import android.bluetooth.IBluetooth;
+import android.bluetooth.IBluetoothCallback;
 import android.os.ParcelUuid;
 import android.content.BroadcastReceiver;
 import android.content.ContentResolver;
@@ -55,6 +56,7 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashMap;
+import java.util.Iterator;
 import java.util.Map;
 
 public class BluetoothService extends IBluetooth.Stub {
@@ -86,14 +88,39 @@
     // This timeout should be greater than the page timeout
     private static final int UUID_INTENT_DELAY = 6000;
 
-    private final Map<String, String> mAdapterProperties;
-    private final HashMap <String, Map<String, String>> mDeviceProperties;
+    /** Always retrieve RFCOMM channel for these SDP UUIDs */
+    private static final ParcelUuid[] RFCOMM_UUIDS = {
+            BluetoothUuid.Handsfree,
+            BluetoothUuid.HSP,
+            BluetoothUuid.ObexObjectPush };
 
-    private final HashMap <String, Map<ParcelUuid, Integer>> mDeviceServiceChannelCache;
-    private final ArrayList <String> mUuidIntentTracker;
+
+    private final Map<String, String> mAdapterProperties;
+    private final HashMap<String, Map<String, String>> mDeviceProperties;
+
+    private final HashMap<String, Map<ParcelUuid, Integer>> mDeviceServiceChannelCache;
+    private final ArrayList<String> mUuidIntentTracker;
+    private final HashMap<RemoteService, IBluetoothCallback> mUuidCallbackTracker;
 
     private final HashMap<Integer, Integer> mServiceRecordToPid;
 
+    private static class RemoteService {
+        public String address;
+        public ParcelUuid uuid;
+        public RemoteService(String address, ParcelUuid uuid) {
+            this.address = address;
+            this.uuid = uuid;
+        }
+        @Override
+        public boolean equals(Object o) {
+            if (o instanceof RemoteService) {
+                RemoteService service = (RemoteService)o;
+                return address.equals(service.address) && uuid.equals(service.uuid);
+            }
+            return false;
+        }
+    }
+
     static {
         classInitNative();
     }
@@ -121,12 +148,13 @@
 
         mDeviceServiceChannelCache = new HashMap<String, Map<ParcelUuid, Integer>>();
         mUuidIntentTracker = new ArrayList<String>();
+        mUuidCallbackTracker = new HashMap<RemoteService, IBluetoothCallback>();
         mServiceRecordToPid = new HashMap<Integer, Integer>();
         registerForAirplaneMode();
     }
 
     public synchronized void initAfterRegistration() {
-        mAdapter = (BluetoothAdapter) mContext.getSystemService(Context.BLUETOOTH_SERVICE);
+        mAdapter = BluetoothAdapter.getDefaultAdapter();
         mEventLoop = new BluetoothEventLoop(mContext, mAdapter, this);
     }
 
@@ -312,8 +340,10 @@
                 break;
             case MESSAGE_UUID_INTENT:
                 String address = (String)msg.obj;
-                if (address != null)
+                if (address != null) {
                     sendUuidIntent(address);
+                    makeServiceChannelCallbacks(address);
+                }
                 break;
             case MESSAGE_DISCOVERABLE_TIMEOUT:
                 int mode = msg.arg1;
@@ -1064,14 +1094,35 @@
         return uuids;
     }
 
-    public synchronized boolean fetchRemoteUuidsWithSdp(String address) {
+    /**
+     * Connect and fetch new UUID's using SDP.
+     * The UUID's found are broadcast as intents.
+     * Optionally takes a uuid and callback to fetch the RFCOMM channel for the
+     * a given uuid.
+     * TODO: Don't wait UUID_INTENT_DELAY to broadcast UUID intents on success
+     * TODO: Don't wait UUID_INTENT_DELAY to handle the failure case for
+     * callback and broadcast intents.
+     */
+    public synchronized boolean fetchRemoteUuids(String address, ParcelUuid uuid,
+            IBluetoothCallback callback) {
         mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
         if (!BluetoothAdapter.checkBluetoothAddress(address)) {
             return false;
         }
 
+        RemoteService service = new RemoteService(address, uuid);
+        if (uuid != null && mUuidCallbackTracker.get(service) != null) {
+            // An SDP query for this address & uuid is already in progress
+            // Do not add this callback for the uuid
+            return false;
+        }
+
         if (mUuidIntentTracker.contains(address)) {
             // An SDP query for this address is already in progress
+            // Add this uuid onto the in-progress SDP query
+            if (uuid != null) {
+                mUuidCallbackTracker.put(new RemoteService(address, uuid), callback);
+            }
             return true;
         }
 
@@ -1087,6 +1138,9 @@
         }
 
         mUuidIntentTracker.add(address);
+        if (uuid != null) {
+            mUuidCallbackTracker.put(new RemoteService(address, uuid), callback);
+        }
 
         Message message = mHandler.obtainMessage(MESSAGE_UUID_INTENT);
         message.obj = address;
@@ -1096,6 +1150,7 @@
 
     /**
      * Gets the rfcomm channel associated with the UUID.
+     * Pulls records from the cache only.
      *
      * @param address Address of the remote device
      * @param uuid ParcelUuid of the service attribute
@@ -1201,20 +1256,67 @@
         // We are storing the rfcomm channel numbers only for the uuids
         // we are interested in.
         int channel;
-        ParcelUuid[] interestedUuids = {BluetoothUuid.Handsfree,
-                                        BluetoothUuid.HSP,
-                                        BluetoothUuid.ObexObjectPush};
+        if (DBG) log("updateDeviceServiceChannelCache(" + address + ")");
+
+        ArrayList<ParcelUuid> applicationUuids = new ArrayList();
+
+        synchronized (this) {
+            for (RemoteService service : mUuidCallbackTracker.keySet()) {
+                if (service.address.equals(address)) {
+                    applicationUuids.add(service.uuid);
+                }
+            }
+        }
 
         Map <ParcelUuid, Integer> value = new HashMap<ParcelUuid, Integer>();
-        for (ParcelUuid uuid: interestedUuids) {
+
+        // Retrieve RFCOMM channel for default uuids
+        for (ParcelUuid uuid : RFCOMM_UUIDS) {
             if (BluetoothUuid.isUuidPresent(deviceUuids, uuid)) {
-                channel =
-                   getDeviceServiceChannelNative(getObjectPathFromAddress(address), uuid.toString(),
-                                                 0x0004);
+                channel = getDeviceServiceChannelNative(getObjectPathFromAddress(address),
+                        uuid.toString(), 0x0004);
+                if (DBG) log("\tuuid(system): " + uuid + " " + channel);
                 value.put(uuid, channel);
             }
         }
-        mDeviceServiceChannelCache.put(address, value);
+        // Retrieve RFCOMM channel for application requested uuids
+        for (ParcelUuid uuid : applicationUuids) {
+            if (BluetoothUuid.isUuidPresent(deviceUuids, uuid)) {
+                channel = getDeviceServiceChannelNative(getObjectPathFromAddress(address),
+                        uuid.toString(), 0x0004);
+                if (DBG) log("\tuuid(application): " + uuid + " " + channel);
+                value.put(uuid, channel);
+            }
+        }
+
+        synchronized (this) {
+            // Make application callbacks
+            for (Iterator<RemoteService> iter = mUuidCallbackTracker.keySet().iterator();
+                    iter.hasNext();) {
+                RemoteService service = iter.next();
+                if (service.address.equals(address)) {
+                    channel = -1;
+                    if (value.get(service.uuid) != null) {
+                        channel = value.get(service.uuid);
+                    }
+                    if (channel != -1) {
+                        if (DBG) log("Making callback for " + service.uuid + " with result " +
+                                channel);
+                        IBluetoothCallback callback = mUuidCallbackTracker.get(service);
+                        if (callback != null) {
+                            try {
+                                callback.onRfcommChannelFound(channel);
+                            } catch (RemoteException e) {Log.e(TAG, "", e);}
+                        }
+
+                        iter.remove();
+                    }
+                }
+            }
+
+            // Update cache
+            mDeviceServiceChannelCache.put(address, value);
+        }
     }
 
     /**
@@ -1330,6 +1432,26 @@
 
         if (mUuidIntentTracker.contains(address))
             mUuidIntentTracker.remove(address);
+
+    }
+
+    /*package*/ synchronized void makeServiceChannelCallbacks(String address) {
+        for (Iterator<RemoteService> iter = mUuidCallbackTracker.keySet().iterator();
+                iter.hasNext();) {
+            RemoteService service = iter.next();
+            if (service.address.equals(address)) {
+                if (DBG) log("Cleaning up failed UUID channel lookup: " + service.address +
+                        " " + service.uuid);
+                IBluetoothCallback callback = mUuidCallbackTracker.get(service);
+                if (callback != null) {
+                    try {
+                        callback.onRfcommChannelFound(-1);
+                    } catch (RemoteException e) {Log.e(TAG, "", e);}
+                }
+
+                iter.remove();
+            }
+        }
     }
 
     @Override
@@ -1377,6 +1499,11 @@
                     }
                 }
             }
+            for (RemoteService service : mUuidCallbackTracker.keySet()) {
+                if (service.address.equals(address)) {
+                    pw.println("\tPENDING CALLBACK: " + service.uuid);
+                }
+            }
         }
 
         String value = getProperty("Devices");
@@ -1508,7 +1635,7 @@
     private native boolean setDevicePropertyBooleanNative(String objectPath, String key,
             int value);
     private native boolean createDeviceNative(String address);
-    private native boolean discoverServicesNative(String objectPath, String pattern);
+    /*package*/ native boolean discoverServicesNative(String objectPath, String pattern);
 
     private native int addRfcommServiceRecordNative(String name, long uuidMsb, long uuidLsb,
             short channel);
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 7d821b5..4c91b6b 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -6188,11 +6188,12 @@
             }
 
             final int drawingCacheBackgroundColor = mDrawingCacheBackgroundColor;
-            final boolean opaque = drawingCacheBackgroundColor != 0 ||
-                (mBGDrawable != null && mBGDrawable.getOpacity() == PixelFormat.OPAQUE);
+            final boolean opaque = drawingCacheBackgroundColor != 0 || isOpaque();
+            final boolean translucentWindow = attachInfo.mTranslucentWindow;
 
             if (width <= 0 || height <= 0 ||
-                    (width * height * (opaque ? 2 : 4) > // Projected bitmap size in bytes
+                     // Projected bitmap size in bytes
+                    (width * height * (opaque && !translucentWindow ? 2 : 4) >
                             ViewConfiguration.get(mContext).getScaledMaximumDrawingCacheSize())) {
                 destroyDrawingCache();
                 return;
@@ -6203,7 +6204,6 @@
                     (mUnscaledDrawingCache == null ? null : mUnscaledDrawingCache.get());
 
             if (bitmap == null || bitmap.getWidth() != width || bitmap.getHeight() != height) {
-
                 Bitmap.Config quality;
                 if (!opaque) {
                     switch (mViewFlags & DRAWING_CACHE_QUALITY_MASK) {
@@ -6221,7 +6221,9 @@
                             break;
                     }
                 } else {
-                    quality = Bitmap.Config.RGB_565;
+                    // Optimization for translucent windows
+                    // If the window is translucent, use a 32 bits bitmap to benefit from memcpy()
+                    quality = translucentWindow ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565;
                 }
 
                 // Try to cleanup memory
@@ -6235,6 +6237,7 @@
                     } else {
                         mUnscaledDrawingCache = new SoftReference<Bitmap>(bitmap);
                     }
+                    if (opaque && translucentWindow) bitmap.setHasAlpha(false);
                 } catch (OutOfMemoryError e) {
                     // If there is not enough memory to create the bitmap cache, just
                     // ignore the issue as bitmap caches are not required to draw the
@@ -8821,6 +8824,11 @@
         int mWindowTop;
 
         /**
+         * Indicates whether the window is translucent/transparent
+         */
+        boolean mTranslucentWindow;        
+
+        /**
          * For windows that are full-screen but using insets to layout inside
          * of the screen decorations, these are the current insets for the
          * content of the window.
@@ -9033,8 +9041,8 @@
         public ScrollabilityCache(ViewConfiguration configuration, View host) {
             fadingEdgeLength = configuration.getScaledFadingEdgeLength();
             scrollBarSize = configuration.getScaledScrollBarSize();
-            scrollBarDefaultDelayBeforeFade = configuration.getScrollDefaultDelay();
-            scrollBarFadeDuration = configuration.getScrollBarFadeDuration();
+            scrollBarDefaultDelayBeforeFade = ViewConfiguration.getScrollDefaultDelay();
+            scrollBarFadeDuration = ViewConfiguration.getScrollBarFadeDuration();
 
             paint = new Paint();
             matrix = new Matrix();
diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java
index dba2e04..a6d644b 100644
--- a/core/java/android/view/ViewRoot.java
+++ b/core/java/android/view/ViewRoot.java
@@ -408,7 +408,7 @@
                 }
 
                 boolean restore = false;
-                if (attrs != null && mTranslator != null) {
+                if (mTranslator != null) {
                     restore = true;
                     attrs.backup();
                     mTranslator.translateWindowLayout(attrs);
@@ -422,7 +422,7 @@
                 mSoftInputMode = attrs.softInputMode;
                 mWindowAttributesChanged = true;
                 mAttachInfo.mRootView = view;
-                mAttachInfo.mScalingRequired = mTranslator == null ? false : true;
+                mAttachInfo.mScalingRequired = mTranslator != null;
                 mAttachInfo.mApplicationScale =
                         mTranslator == null ? 1.0f : mTranslator.applicationScale;
                 if (panelParentView != null) {
@@ -680,6 +680,7 @@
             // object is not initialized to its backing store, but soon it
             // will be (assuming the window is visible).
             attachInfo.mSurface = mSurface;
+            attachInfo.mTranslucentWindow = lp.format != PixelFormat.OPAQUE;
             attachInfo.mHasWindowFocus = false;
             attachInfo.mWindowVisibility = viewVisibility;
             attachInfo.mRecomputeGlobalAttributes = false;
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index 78999fa..916fc2d 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -263,6 +263,13 @@
         boolean isVisibleLw();
         
         /**
+         * Like {@link #isVisibleLw}, but also counts a window that is currently
+         * "hidden" behind the keyguard as visible.  This allows us to apply
+         * things like window flags that impact the keyguard.
+         */
+        boolean isVisibleOrBehindKeyguardLw();
+        
+        /**
          * Is this window currently visible to the user on-screen?  It is 
          * displayed either if it is visible or it is currently running an 
          * animation before no longer being visible.  Must be called with the
diff --git a/core/java/android/webkit/WebSettings.java b/core/java/android/webkit/WebSettings.java
index 4fedec9..79d8c03 100644
--- a/core/java/android/webkit/WebSettings.java
+++ b/core/java/android/webkit/WebSettings.java
@@ -1007,7 +1007,8 @@
      *     should never be null.
      */
     public synchronized void setGeolocationDatabasePath(String databasePath) {
-        if (databasePath != null && !databasePath.equals(mDatabasePath)) {
+        if (databasePath != null
+                && !databasePath.equals(mGeolocationDatabasePath)) {
             mGeolocationDatabasePath = databasePath;
             postSync();
         }
diff --git a/core/java/android/widget/QuickContactBadge.java b/core/java/android/widget/QuickContactBadge.java
index 8019f14..07c3e4b 100644
--- a/core/java/android/widget/QuickContactBadge.java
+++ b/core/java/android/widget/QuickContactBadge.java
@@ -25,9 +25,9 @@
 import android.graphics.drawable.Drawable;
 import android.net.Uri;
 import android.provider.ContactsContract.Contacts;
-import android.provider.ContactsContract.QuickContact;
 import android.provider.ContactsContract.Intents;
 import android.provider.ContactsContract.PhoneLookup;
+import android.provider.ContactsContract.QuickContact;
 import android.provider.ContactsContract.RawContacts;
 import android.provider.ContactsContract.CommonDataKinds.Email;
 import android.util.AttributeSet;
@@ -55,21 +55,28 @@
     static final private int TOKEN_PHONE_LOOKUP = 1;
     static final private int TOKEN_EMAIL_LOOKUP_AND_TRIGGER = 2;
     static final private int TOKEN_PHONE_LOOKUP_AND_TRIGGER = 3;
+    static final private int TOKEN_CONTACT_LOOKUP_AND_TRIGGER = 4;
 
     static final String[] EMAIL_LOOKUP_PROJECTION = new String[] {
         RawContacts.CONTACT_ID,
         Contacts.LOOKUP_KEY,
     };
-    static int EMAIL_ID_COLUMN_INDEX = 0;
-    static int EMAIL_LOOKUP_STRING_COLUMN_INDEX = 1;
+    static final int EMAIL_ID_COLUMN_INDEX = 0;
+    static final int EMAIL_LOOKUP_STRING_COLUMN_INDEX = 1;
 
     static final String[] PHONE_LOOKUP_PROJECTION = new String[] {
         PhoneLookup._ID,
         PhoneLookup.LOOKUP_KEY,
     };
-    static int PHONE_ID_COLUMN_INDEX = 0;
-    static int PHONE_LOOKUP_STRING_COLUMN_INDEX = 1;
+    static final int PHONE_ID_COLUMN_INDEX = 0;
+    static final int PHONE_LOOKUP_STRING_COLUMN_INDEX = 1;
 
+    static final String[] CONTACT_LOOKUP_PROJECTION = new String[] {
+        Contacts._ID,
+        Contacts.LOOKUP_KEY,
+    };
+    static final int CONTACT_ID_COLUMN_INDEX = 0;
+    static final int CONTACT_LOOKUPKEY_COLUMN_INDEX = 1;
 
 
     public QuickContactBadge(Context context) {
@@ -181,9 +188,9 @@
 
     public void onClick(View v) {
         if (mContactUri != null) {
-            final ContentResolver resolver = getContext().getContentResolver();
-            final Uri lookupUri = Contacts.getLookupUri(resolver, mContactUri);
-            trigger(lookupUri);
+            mQueryHandler.startQuery(TOKEN_CONTACT_LOOKUP_AND_TRIGGER, null,
+                    mContactUri,
+                    CONTACT_LOOKUP_PROJECTION, null, null, null);
         } else if (mContactEmail != null) {
             mQueryHandler.startQuery(TOKEN_EMAIL_LOOKUP_AND_TRIGGER, mContactEmail,
                     Uri.withAppendedPath(Email.CONTENT_LOOKUP_URI, Uri.encode(mContactEmail)),
@@ -249,6 +256,17 @@
                             lookupUri = Contacts.getLookupUri(contactId, lookupKey);
                         }
                     }
+
+                    case TOKEN_CONTACT_LOOKUP_AND_TRIGGER: {
+                        if (cursor != null && cursor.moveToFirst()) {
+                            long contactId = cursor.getLong(CONTACT_ID_COLUMN_INDEX);
+                            String lookupKey = cursor.getString(CONTACT_LOOKUPKEY_COLUMN_INDEX);
+                            lookupUri = Contacts.getLookupUri(contactId, lookupKey);
+                            trigger = true;
+                        }
+
+                        break;
+                    }
                 }
             } finally {
                 if (cursor != null) {
diff --git a/core/java/com/android/internal/app/ShutdownThread.java b/core/java/com/android/internal/app/ShutdownThread.java
index 9e1f325..2060cf8 100644
--- a/core/java/com/android/internal/app/ShutdownThread.java
+++ b/core/java/com/android/internal/app/ShutdownThread.java
@@ -32,6 +32,7 @@
 import android.os.Power;
 import android.os.ServiceManager;
 import android.os.SystemClock;
+
 import com.android.internal.telephony.ITelephony;
 import android.util.Log;
 import android.view.WindowManager;
@@ -91,7 +92,10 @@
                     .setNegativeButton(com.android.internal.R.string.no, null)
                     .create();
             dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
-            dialog.getWindow().addFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND);
+            if (!context.getResources().getBoolean(
+                    com.android.internal.R.bool.config_sf_slowBlur)) {
+                dialog.getWindow().addFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND);
+            }
             dialog.show();
         } else {
             beginShutdownSequence(context);
@@ -111,7 +115,10 @@
         pd.setIndeterminate(true);
         pd.setCancelable(false);
         pd.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
-        pd.getWindow().addFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND);
+        if (!context.getResources().getBoolean(
+                com.android.internal.R.bool.config_sf_slowBlur)) {
+            pd.getWindow().addFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND);
+        }
 
         pd.show();
 
@@ -181,7 +188,7 @@
                 ITelephony.Stub.asInterface(ServiceManager.checkService("phone"));
         final IBluetooth bluetooth =
                 IBluetooth.Stub.asInterface(ServiceManager.checkService(
-                        Context.BLUETOOTH_SERVICE));
+                        BluetoothAdapter.BLUETOOTH_SERVICE));
         
         try {
             bluetoothOff = bluetooth == null ||
diff --git a/core/jni/android_server_BluetoothEventLoop.cpp b/core/jni/android_server_BluetoothEventLoop.cpp
index e37e832..62a50e5 100644
--- a/core/jni/android_server_BluetoothEventLoop.cpp
+++ b/core/jni/android_server_BluetoothEventLoop.cpp
@@ -36,6 +36,10 @@
 
 namespace android {
 
+#define CREATE_DEVICE_ALREADY_EXISTS 1
+#define CREATE_DEVICE_SUCCESS 0
+#define CREATE_DEVICE_FAILED -1
+
 #ifdef HAVE_BLUETOOTH
 static jfieldID field_mNativeData;
 
@@ -95,7 +99,7 @@
     method_onCreatePairedDeviceResult = env->GetMethodID(clazz, "onCreatePairedDeviceResult",
                                                          "(Ljava/lang/String;I)V");
     method_onCreateDeviceResult = env->GetMethodID(clazz, "onCreateDeviceResult",
-                                                         "(Ljava/lang/String;Z)V");
+                                                         "(Ljava/lang/String;I)V");
     method_onDiscoverServicesResult = env->GetMethodID(clazz, "onDiscoverServicesResult",
                                                          "(Ljava/lang/String;Z)V");
 
@@ -1115,10 +1119,13 @@
 
     LOGV("... Address = %s", address);
 
-    bool result = JNI_TRUE;
+    jint result = CREATE_DEVICE_SUCCESS;
     if (dbus_set_error_from_message(&err, msg)) {
+        if (dbus_error_has_name(&err, "org.bluez.Error.AlreadyExists")) {
+            result = CREATE_DEVICE_ALREADY_EXISTS;
+        }
         LOG_AND_FREE_DBUS_ERROR(&err);
-        result = JNI_FALSE;
+        result = CREATE_DEVICE_FAILED;
     }
     env->CallVoidMethod(nat->me,
                         method_onCreateDeviceResult,
diff --git a/core/res/res/values-en-rUS/donottranslate-names.xml b/core/res/res/values-en-rUS/donottranslate-names.xml
index 82ba310..ae38ddf 100644
--- a/core/res/res/values-en-rUS/donottranslate-names.xml
+++ b/core/res/res/values-en-rUS/donottranslate-names.xml
@@ -4,31 +4,39 @@
     
     <!-- various string resources for Contacts -->
     <string-array name="common_nicknames">
+        <item>Abigail, Abbie, Gail, Gayle</item>
+        <item>Abe, Abraham</item>
+        <item>Aggie, Agatha, Agnes</item>
         <item>Albert, Al, Bert, Bertie</item>
-        <item>Alexander, Al, Alex, Lex, Sasha</item>
-        <item>Alexandra, Al, Alex, Allie, Ally, Lex, Lexie, Sandra, Sandy, Sasha</item>
+        <item>Alexander, Al, Alec, Alex, Lex, Sasha</item>
+        <item>Alexandra, Al, Allie, Ally, Lex, Lexie, Sandra, Sandy, Sasha</item>
+        <item>Alf, Alfred, Alfredo, Alfie</item>
         <item>Alice, Allie, Ally</item>
         <item>Alison, Allie, Ally</item>
         <item>Allison, Allie, Ally</item>
         <item>Amanda, Mandi, Mandy</item>
         <item>Andrea, Andie</item>
         <item>Andrew, Andy, Drew</item>
+        <item>Anne, Annie, Annette</item>
         <item>Anthony, Tony, Toni, Tone</item>
         <item>Arthur, Art, Arty</item>
         <item>Barbara, Babs, Barb, Barbie</item>
         <item>Benjamin, Ben, Benji, Benny</item>
-        <item>Bernard, Bern, Bernie</item>
+        <item>Bernard, Bern, Bernie, Barnie</item>
         <item>Bertram, Bert, Bertie</item>
         <item>Bradly, Brad</item>
+        <item>Calvin, Cal</item>
         <item>Catherine, Cat, Cate, Cath, Catie, Cathy, Kat, Kate, Katie, Kathy</item>
+        <item>Carrie, Caroline, Carolyn</item>
         <item>Charles, Chuck, Chaz, Charlie, Buck</item>
-        <item>Christine, Chris, Chrissy, Chrissie</item>
+        <item>Christine, Chrissy, Chrissie</item>
         <item>Christopher, Chris</item>
+        <item>Clinton, Clint</item>
         <item>Cynthia, Cindy, Cynth</item>
         <item>Daniel, Dan, Danny</item>
         <item>David, Dave</item>
         <item>Deborah, Deb, Debbie</item>
-        <item>Dennis, Den, Denny, Dean</item>
+        <item>Dennis, Den, Denny</item>
         <item>Dolores, Dolly</item>
         <item>Donald, Don, Donny</item>
         <item>Donnatella, Donna</item>
@@ -41,22 +49,21 @@
         <item>Elizabeth, Beth, Bess, Bessie, Betsy, Betty, Bette, Eliza, Lisa, Liza, Liz</item>
         <item>Emily, Em, Ems, Emmy</item>
         <item>Emma, Em, Ems, Emmy</item>
-        <item>Erica, Rikki, Rikkie, Ricky</item>
         <item>Eugene, Gene</item>
+        <item>Fannie, Fanny</item>
         <item>Florence, Flo</item>
         <item>Frances, Fran, Francie</item>
-        <item>Francis, Fran, Frank</item>
+        <item>Francis, Fran, Frank, Frankie</item>
         <item>Frederick, Fred, Freddy</item>
         <item>Gabriel, Gabe</item>
-        <item>Geoffrey, Jeff</item>
         <item>Gerald, Gerry</item>
         <item>Gerard, Gerry</item>
-        <item>Gregory, Greg</item>
-        <item>Harold, Hal, Hank, Harry</item>
+        <item>Gregory, Greg, Gregg</item>
+        <item>Harold, Hal, Harry</item>
         <item>Henry, Hal, Hank, Harry</item>
         <item>Herbert, Bert, Bertie</item>
         <item>Irving, Irv</item>
-        <item>Isabella, Isa, Izzy</item>
+        <item>Isabella, Isa, Izzy, Bella</item>
         <item>Jacob, Jake</item>
         <item>Jacqueline, Jackie</item>
         <item>James, Jim, Jimmy, Jamie, Jock</item>
@@ -68,8 +75,9 @@
         <item>Jennifer, Jen, Jenny</item>
         <item>Jerome, Jerry</item>
         <item>Jessica, Jessie</item>
-        <item>John, Jack, Jacky, Johnny, Jon</item>
-        <item>Jonathan, Jon, John</item>
+        <item>John, Johnny, Jon</item>
+        <item>Jack, Jacky</item>
+        <item>Jonathan, Jon</item>
         <item>Joseph, Joe, Joey</item>
         <item>Joshua, Josh</item>
         <item>Kaitlyn, Cat, Cate, Catie, Cath, Cathy, Kat, Kate, Katie, Kathy</item>
@@ -78,17 +86,20 @@
         <item>Katrina, Cat, Cate, Catie, Cath, Cathy, Kat, Kate, Katie, Kathy</item>
         <item>Kenneth, Ken</item>
         <item>Kevin, Kev</item>
+        <item>Kim, Kimberly</item>
         <item>Laura, Lauri, Laurie</item>
         <item>Lauren, Lauri, Laurie</item>
-        <item>Laurence, Larry, Lauri, Laurie</item>
-        <item>Lawrence, Larry, Lauri, Laurie</item>
+        <item>Lawrence, Larry</item>
         <item>Leonard, Leo, Len, Lenny</item>
         <item>Leopold, Leo, Len, Lenny</item>
         <item>Madeline, Maddie, Maddy</item>
-        <item>Margaret, Marge, Marg, Maggie, Mags, Meg, Peggy</item>
+        <item>Margaret, Marge, Marg, Maggie, Mags, Meg, Peggy, Greta, Gretchen</item>
+        <item>Martin, Martie, Marty</item>
         <item>Matthew, Matt, Mattie</item>
         <item>Maureen, Mo</item>
         <item>Maurice, Mo</item>
+        <item>Maxwell, Max</item>
+        <item>Maximilian, Maxim, Max</item>
         <item>Megan, Meg</item>
         <item>Michael, Mickey, Mick, Mike, Mikey</item>
         <item>Morris, Mo</item>
@@ -96,16 +107,17 @@
         <item>Nathan, Nat, Nate</item>
         <item>Nathaniel, Nat, Nate</item>
         <item>Nicholas, Nick</item>
+        <item>Nicole, Nicky, Nickie, Nikky</item>
         <item>Pamela, Pam</item>
         <item>Patricia, Pat, Patsy, Patty, Trish, Tricia</item>
-        <item>Patrick, Paddy, Pat, Patty, Patter, Rick, Ricky</item>
+        <item>Patrick, Pat, Patter</item>
+        <item>Penelope, Penny</item>
         <item>Peter, Pete</item>
         <item>Raymond, Ray</item>
         <item>Philip, Phil</item>
-        <item>Rebecca, Becca</item>
+        <item>Rebecca, Becca, Becky</item>
         <item>Richard, Rick, Rich, Dick</item>
         <item>Robert, Bob, Rob, Robbie, Bobby, Rab</item>
-        <item>Roberta, Bobbie</item>
         <item>Rodney. Rod</item>
         <item>Ronald, Ron, Ronnie</item>
         <item>Rosemary, Rosie, Rose</item>
@@ -120,7 +132,8 @@
         <item>Stuart, Stu</item>
         <item>Susan, Sue, Susie, Suzie</item>
         <item>Suzanne, Sue, Susie, Suzie</item>
-        <item>Teresa, Terrie, Terry</item>
+        <item>Tamara, Tammy</item>
+        <item>Theresa, Teresa</item>
         <item>Theodora, Teddie, Thea, Theo</item>
         <item>Theodore, Ted, Teddy, Theo</item>
         <item>Thomas, Tom, Thom, Tommy</item>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 9f4af83..9040edb 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -26,6 +26,11 @@
          strictly needed. -->
     <bool name="config_sf_limitedAlpha">false</bool>
     
+    <!-- Flag indicating whether the surface flinger is inefficient
+         at performing a blur.  Used by parts of the UI to turn off
+         the blur effect where it isn't worth the performance hit. -->
+    <bool name="config_sf_slowBlur">false</bool>
+    
     <!-- The duration (in milliseconds) of a short animation. -->
     <integer name="config_shortAnimTime">150</integer>
     
diff --git a/graphics/java/android/renderscript/SimpleMesh.java b/graphics/java/android/renderscript/SimpleMesh.java
index b422702..0ad093e 100644
--- a/graphics/java/android/renderscript/SimpleMesh.java
+++ b/graphics/java/android/renderscript/SimpleMesh.java
@@ -290,6 +290,11 @@
         }
 
         public void addTriangle(int idx1, int idx2, int idx3) {
+            if((idx1 >= mVtxCount) || (idx1 < 0) ||
+               (idx2 >= mVtxCount) || (idx2 < 0) ||
+               (idx3 >= mVtxCount) || (idx3 < 0)) {
+               throw new IllegalStateException("Index provided greater than vertex count.");
+            }
             if ((mIndexCount + 3) >= mIndexData.length) {
                 short t[] = new short[mIndexData.length * 2];
                 System.arraycopy(mIndexData, 0, t, 0, mIndexData.length);
diff --git a/include/media/stagefright/OMXCodec.h b/include/media/stagefright/OMXCodec.h
index e19830bb..ff7e34a 100644
--- a/include/media/stagefright/OMXCodec.h
+++ b/include/media/stagefright/OMXCodec.h
@@ -90,7 +90,6 @@
         kRequiresFlushCompleteEmulation      = 16,
         kRequiresAllocateBufferOnOutputPorts = 32,
         kRequiresFlushBeforeShutdown         = 64,
-        kAlwaysAllocateOutputWithPadding     = 128,
     };
 
     struct BufferInfo {
diff --git a/include/private/ui/SharedBufferStack.h b/include/private/ui/SharedBufferStack.h
index f6824d9..bbc1822 100644
--- a/include/private/ui/SharedBufferStack.h
+++ b/include/private/ui/SharedBufferStack.h
@@ -289,6 +289,7 @@
     void setStatus(status_t status);
     status_t reallocate();
     status_t assertReallocate(int buffer);
+    int32_t getQueuedCount() const;
     
     Region getDirtyRegion(int buffer) const;
 
diff --git a/include/private/ui/SurfaceFlingerSynchro.h b/include/private/ui/SurfaceFlingerSynchro.h
deleted file mode 100644
index 7386d33..0000000
--- a/include/private/ui/SurfaceFlingerSynchro.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-#ifndef ANDROID_SURFACE_FLINGER_SYNCHRO_H
-#define ANDROID_SURFACE_FLINGER_SYNCHRO_H
-
-#include <stdint.h>
-#include <sys/types.h>
-#include <utils/Errors.h>
-#include <ui/ISurfaceComposer.h>
-
-namespace android {
-
-class SurfaceFlinger;
-
-class SurfaceFlingerSynchro
-{
-public:
-                // client constructor
-                SurfaceFlingerSynchro(const sp<ISurfaceComposer>& flinger);
-                ~SurfaceFlingerSynchro();
-    
-                // signal surfaceflinger for some work
-    status_t    signal();
-    
-private:
-    friend class SurfaceFlinger;
-    sp<ISurfaceComposer> mSurfaceComposer;
-};
-
-}; // namespace android
-
-#endif // ANDROID_SURFACE_FLINGER_SYNCHRO_H
-
diff --git a/include/ui/SurfaceComposerClient.h b/include/ui/SurfaceComposerClient.h
index 8701928..777b878 100644
--- a/include/ui/SurfaceComposerClient.h
+++ b/include/ui/SurfaceComposerClient.h
@@ -153,7 +153,7 @@
                 SharedClient*               mControl;
                 sp<IMemoryHeap>             mControlMemory;
                 sp<ISurfaceFlingerClient>   mClient;
-                SurfaceFlingerSynchro*      mSignalServer;
+                sp<ISurfaceComposer>        mSignalServer;
 };
 
 }; // namespace android
diff --git a/libs/rs/rsContext.h b/libs/rs/rsContext.h
index b56e7d7..3570e10 100644
--- a/libs/rs/rsContext.h
+++ b/libs/rs/rsContext.h
@@ -99,6 +99,7 @@
 
     uint32_t getMessageToClient(void *data, size_t *receiveLen, size_t bufferLen, bool wait);
     bool sendMessageToClient(void *data, uint32_t cmdID, size_t len, bool waitForSpace);
+    bool runScript(Script *s, uint32_t launchID);
 
     void initToClient();
     void deinitToClient();
@@ -212,7 +213,6 @@
 
     void initEGL();
 
-    bool runScript(Script *s, uint32_t launchID);
     bool runRootScript();
 
     static void * threadProc(void *);
diff --git a/libs/rs/rsScriptC_Lib.cpp b/libs/rs/rsScriptC_Lib.cpp
index 9a96290..436f48b 100644
--- a/libs/rs/rsScriptC_Lib.cpp
+++ b/libs/rs/rsScriptC_Lib.cpp
@@ -1008,6 +1008,13 @@
     return rsc->sendMessageToClient(data, cmdID, len, waitForSpace != 0);
 }
 
+static void SC_scriptCall(int scriptID)
+{
+    GET_TLS();
+    rsc->runScript((Script *)scriptID, 0);
+}
+
+
 //////////////////////////////////////////////////////////////////////////////
 // Class implementation
 //////////////////////////////////////////////////////////////////////////////
@@ -1289,6 +1296,9 @@
     { "debugHexI32", (void *)&SC_debugHexI32,
         "void", "(void *, int)" },
 
+    { "scriptCall", (void *)&SC_scriptCall,
+        "void", "(int)" },
+
 
     { NULL, NULL, NULL, NULL }
 };
diff --git a/libs/surfaceflinger/Layer.cpp b/libs/surfaceflinger/Layer.cpp
index 0258cee..7fd5434d 100644
--- a/libs/surfaceflinger/Layer.cpp
+++ b/libs/surfaceflinger/Layer.cpp
@@ -454,14 +454,16 @@
 
             // recompute visible region
             recomputeVisibleRegions = true;
-
-            // we now have the correct size, unfreeze the screen
-            mFreezeLock.clear();
         }
+
+        // we now have the correct size, unfreeze the screen
+        mFreezeLock.clear();
     }
 
-    // FIXME: signal an event if we have more buffers waiting
-    // mFlinger->signalEvent();
+    if (lcblk->getQueuedCount()) {
+        // signal an event if we have more buffers waiting
+        mFlinger->signalEvent();
+    }
 
     if (!mPostedDirtyRegion.isEmpty()) {
         reloadTexture( mPostedDirtyRegion );
diff --git a/libs/ui/Android.mk b/libs/ui/Android.mk
index 73d86ea..84aec61 100644
--- a/libs/ui/Android.mk
+++ b/libs/ui/Android.mk
@@ -27,8 +27,7 @@
 	Region.cpp \
 	SharedBufferStack.cpp \
 	Surface.cpp \
-	SurfaceComposerClient.cpp \
-	SurfaceFlingerSynchro.cpp 
+	SurfaceComposerClient.cpp
 
 LOCAL_SHARED_LIBRARIES := \
 	libcutils \
diff --git a/libs/ui/SharedBufferStack.cpp b/libs/ui/SharedBufferStack.cpp
index b460757..46b6766 100644
--- a/libs/ui/SharedBufferStack.cpp
+++ b/libs/ui/SharedBufferStack.cpp
@@ -394,6 +394,12 @@
     return NO_ERROR;
 }
 
+int32_t SharedBufferServer::getQueuedCount() const
+{
+    SharedBufferStack& stack( *mSharedStack );
+    return stack.queued;
+}
+
 status_t SharedBufferServer::assertReallocate(int buffer)
 {
     ReallocateCondition condition(this, buffer);
diff --git a/libs/ui/Surface.cpp b/libs/ui/Surface.cpp
index 2d83a8c..f51ca7a 100644
--- a/libs/ui/Surface.cpp
+++ b/libs/ui/Surface.cpp
@@ -746,6 +746,8 @@
                 currentBuffer->setIndex(index);
                 mNeedFullUpdate = true;
             }
+        } else {
+            err = err<0 ? err : NO_MEMORY;
         }
     }
     return err; 
diff --git a/libs/ui/SurfaceComposerClient.cpp b/libs/ui/SurfaceComposerClient.cpp
index 3baa281..eda84ef 100644
--- a/libs/ui/SurfaceComposerClient.cpp
+++ b/libs/ui/SurfaceComposerClient.cpp
@@ -42,7 +42,6 @@
 
 #include <private/ui/LayerState.h>
 #include <private/ui/SharedBufferStack.h>
-#include <private/ui/SurfaceFlingerSynchro.h>
 
 #define VERBOSE(...)	((void)0)
 //#define VERBOSE			LOGD
@@ -155,7 +154,6 @@
 {
     VERBOSE("Creating client %p, conn %p", this, conn.get());
 
-    mSignalServer = 0;
     mPrebuiltLayerState = 0;
     mTransactionOpen = 0;
     mStatus = NO_ERROR;
@@ -168,7 +166,7 @@
     }
 
     mControlMemory = mClient->getControlBlock();
-    mSignalServer = new SurfaceFlingerSynchro(sm);
+    mSignalServer = sm;
     mControl = static_cast<SharedClient *>(mControlMemory->getBase());
 }
 
@@ -225,7 +223,6 @@
         Mutex::Autolock _lg(gLock);
         Mutex::Autolock _lm(mLock);
 
-        delete mSignalServer;
         mSignalServer = 0;
 
         if (mClient != 0) {
diff --git a/libs/ui/SurfaceFlingerSynchro.cpp b/libs/ui/SurfaceFlingerSynchro.cpp
deleted file mode 100644
index c81db71..0000000
--- a/libs/ui/SurfaceFlingerSynchro.cpp
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdint.h>
-
-#include <private/ui/SurfaceFlingerSynchro.h>
-
-namespace android {
-
-// ---------------------------------------------------------------------------
-
-SurfaceFlingerSynchro::SurfaceFlingerSynchro(const sp<ISurfaceComposer>& flinger)
-    : mSurfaceComposer(flinger)
-{
-}
-SurfaceFlingerSynchro::~SurfaceFlingerSynchro()
-{
-}
-
-status_t SurfaceFlingerSynchro::signal()
-{
-    mSurfaceComposer->signal();
-    return NO_ERROR;
-}
-
-// ---------------------------------------------------------------------------
-
-}; // namespace android
-
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index 26c6a9e..cd9c991 100644
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -219,11 +219,6 @@
     if (!strcmp(componentName, "OMX.TI.AAC.decode")) {
         quirks |= kNeedsFlushBeforeDisable;
         quirks |= kRequiresFlushCompleteEmulation;
-
-        // The following is currently necessary for proper shutdown
-        // behaviour, but NOT enabled by default in order to make the
-        // bug reproducible...
-        // quirks |= kRequiresFlushBeforeShutdown;
     }
     if (!strncmp(componentName, "OMX.qcom.video.encoder.", 23)) {
         quirks |= kRequiresLoadedToIdleAfterAllocation;
@@ -245,15 +240,6 @@
         quirks |= kRequiresAllocateBufferOnOutputPorts;
     }
 
-    if (!strcmp(componentName, "OMX.qcom.video.decoder.avc")) {
-        // This decoder misreports the required output buffer size if
-        // the content in question is not a multiple-16 width/height.
-
-        // XXX Not enabled by default to make the bug reproducible by
-        // the vendor.
-        // quirks |= kAlwaysAllocateOutputWithPadding;
-    }
-
     sp<OMXCodec> codec = new OMXCodec(
             omx, node, quirks, createEncoder, mime, componentName,
             source);
@@ -848,25 +834,6 @@
         return err;
     }
 
-    if ((portIndex == kPortIndexOutput)
-            && (mQuirks & kAlwaysAllocateOutputWithPadding)) {
-        CHECK_EQ(def.eDomain, OMX_PortDomainVideo);
-        const OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video;
-        CHECK_EQ(videoDef->eColorFormat, OMX_QCOM_COLOR_FormatYVU420SemiPlanar);
-
-        OMX_U32 width = (videoDef->nFrameWidth + 15) & ~0x0f;
-        OMX_U32 height = (videoDef->nFrameHeight + 15) & ~0x0f;
-
-        size_t newBufferSize = (width * height * 3) / 2;
-        CHECK(newBufferSize >= def.nBufferSize);
-        if (newBufferSize > def.nBufferSize) {
-            CODEC_LOGV("Rounding up output buffersize from %ld to %ld "
-                       "to accomodate multiple-of-16 alignment.",
-                       def.nBufferSize, newBufferSize);
-        }
-        def.nBufferSize = newBufferSize;
-    }
-
     size_t totalSize = def.nBufferCountActual * def.nBufferSize;
     mDealer[portIndex] = new MemoryDealer(totalSize);
 
diff --git a/services/java/com/android/server/DeviceStorageMonitorService.java b/services/java/com/android/server/DeviceStorageMonitorService.java
index 52e09ca..57af029 100644
--- a/services/java/com/android/server/DeviceStorageMonitorService.java
+++ b/services/java/com/android/server/DeviceStorageMonitorService.java
@@ -43,8 +43,8 @@
 /**
  * This class implements a service to monitor the amount of disk storage space
  * on the device. If the free storage on device is less than a tunable threshold value
- * (default is 10%. this value is a gservices parameter) a low memory notification is 
- * displayed to alert the user. If the user clicks on the low memory notification the 
+ * (default is 10%. this value is a gservices parameter) a low memory notification is
+ * displayed to alert the user. If the user clicks on the low memory notification the
  * Application Manager application gets launched to let the user free storage space.
  * Event log events:
  * A low memory event with the free storage on device in bytes  is logged to the event log
@@ -68,32 +68,35 @@
     private static final int EVENT_LOG_FREE_STORAGE_LEFT = 2746;
     private static final long DEFAULT_DISK_FREE_CHANGE_REPORTING_THRESHOLD = 2 * 1024 * 1024; // 2MB
     private static final long DEFAULT_CHECK_INTERVAL = MONITOR_INTERVAL*60*1000;
-    private long mFreeMem;
+    private long mFreeMem;  // on /data
     private long mLastReportedFreeMem;
     private long mLastReportedFreeMemTime;
     private boolean mLowMemFlag=false;
     private Context mContext;
     private ContentResolver mContentResolver;
-    long mBlkSize;
-    long mTotalMemory;
-    StatFs mFileStats;
-    private static final String DATA_PATH="/data";
-    long mThreadStartTime = -1;
-    boolean mClearSucceeded = false;
-    boolean mClearingCache;
+    private long mTotalMemory;  // on /data
+    private StatFs mDataFileStats;
+    private StatFs mSystemFileStats;
+    private StatFs mCacheFileStats;
+    private static final String DATA_PATH = "/data";
+    private static final String SYSTEM_PATH = "/system";
+    private static final String CACHE_PATH = "/cache";
+    private long mThreadStartTime = -1;
+    private boolean mClearSucceeded = false;
+    private boolean mClearingCache;
     private Intent mStorageLowIntent;
     private Intent mStorageOkIntent;
     private CachePackageDataObserver mClearCacheObserver;
     private static final int _TRUE = 1;
     private static final int _FALSE = 0;
-    
+
     /**
      * This string is used for ServiceManager access to this class.
      */
     static final String SERVICE = "devicestoragemonitor";
-    
+
     /**
-    * Handler that checks the amount of disk space on the device and sends a 
+    * Handler that checks the amount of disk space on the device and sends a
     * notification if the device runs low on disk space
     */
     Handler mHandler = new Handler() {
@@ -107,7 +110,7 @@
             checkMemory(msg.arg1 == _TRUE);
         }
     };
-    
+
     class CachePackageDataObserver extends IPackageDataObserver.Stub {
         public void onRemoveCompleted(String packageName, boolean succeeded) {
             mClearSucceeded = succeeded;
@@ -115,12 +118,17 @@
             if(localLOGV) Log.i(TAG, " Clear succeeded:"+mClearSucceeded
                     +", mClearingCache:"+mClearingCache+" Forcing memory check");
             postCheckMemoryMsg(false, 0);
-        }        
+        }
     }
-    
+
     private final void restatDataDir() {
-        mFileStats.restat(DATA_PATH);
-        mFreeMem = mFileStats.getAvailableBlocks()*mBlkSize;
+        try {
+            mDataFileStats.restat(DATA_PATH);
+            mFreeMem = (long) mDataFileStats.getAvailableBlocks() *
+                mDataFileStats.getBlockSize();
+        } catch (IllegalArgumentException e) {
+            // use the old value of mFreeMem
+        }
         // Allow freemem to be overridden by debug.freemem for testing
         String debugFreeMem = SystemProperties.get("debug.freemem");
         if (!"".equals(debugFreeMem)) {
@@ -132,10 +140,27 @@
                 DEFAULT_FREE_STORAGE_LOG_INTERVAL_IN_MINUTES)*60*1000;
         //log the amount of free memory in event log
         long currTime = SystemClock.elapsedRealtime();
-        if((mLastReportedFreeMemTime == 0) || 
-                (currTime-mLastReportedFreeMemTime) >= freeMemLogInterval) {
+        if((mLastReportedFreeMemTime == 0) ||
+           (currTime-mLastReportedFreeMemTime) >= freeMemLogInterval) {
             mLastReportedFreeMemTime = currTime;
-            EventLog.writeEvent(EVENT_LOG_FREE_STORAGE_LEFT, mFreeMem);
+            long mFreeSystem = -1, mFreeCache = -1;
+            try {
+                mSystemFileStats.restat(SYSTEM_PATH);
+                mFreeSystem = (long) mSystemFileStats.getAvailableBlocks() *
+                    mSystemFileStats.getBlockSize();
+            } catch (IllegalArgumentException e) {
+                // ignore; report -1
+            }
+            try {
+                mCacheFileStats.restat(CACHE_PATH);
+                mFreeCache = (long) mCacheFileStats.getAvailableBlocks() *
+                    mCacheFileStats.getBlockSize();
+            } catch (IllegalArgumentException e) {
+                // ignore; report -1
+            }
+            mCacheFileStats.restat(CACHE_PATH);
+            EventLog.writeEvent(EVENT_LOG_FREE_STORAGE_LEFT,
+                                mFreeMem, mFreeSystem, mFreeCache);
         }
         // Read the reporting threshold from Gservices
         long threshold = Gservices.getLong(mContentResolver,
@@ -148,7 +173,7 @@
             EventLog.writeEvent(EVENT_LOG_STORAGE_BELOW_THRESHOLD, mFreeMem);
         }
     }
-    
+
     private final void clearCache() {
         if (mClearCacheObserver == null) {
             // Lazy instantiation
@@ -165,10 +190,10 @@
             mClearSucceeded = false;
         }
     }
-    
+
     private final void checkMemory(boolean checkCache) {
-        //if the thread that was started to clear cache is still running do nothing till its 
-        //finished clearing cache. Ideally this flag could be modified by clearCache 
+        //if the thread that was started to clear cache is still running do nothing till its
+        //finished clearing cache. Ideally this flag could be modified by clearCache
         // and should be accessed via a lock but even if it does this test will fail now and
         //hopefully the next time this flag will be set to the correct value.
         if(mClearingCache) {
@@ -177,11 +202,11 @@
             long diffTime = System.currentTimeMillis() - mThreadStartTime;
             if(diffTime > (10*60*1000)) {
                 Log.w(TAG, "Thread that clears cache file seems to run for ever");
-            } 
+            }
         } else {
             restatDataDir();
             if (localLOGV)  Log.v(TAG, "freeMemory="+mFreeMem);
-            
+
             //post intent to NotificationManager to display icon if necessary
             long memThreshold = getMemThreshold();
             if (mFreeMem < memThreshold) {
@@ -214,7 +239,7 @@
         //keep posting messages to itself periodically
         postCheckMemoryMsg(true, DEFAULT_CHECK_INTERVAL);
     }
-    
+
     private void postCheckMemoryMsg(boolean clearCache, long delay) {
         // Remove queued messages
         mHandler.removeMessages(DEVICE_MEMORY_WHAT);
@@ -222,16 +247,16 @@
                 clearCache ?_TRUE : _FALSE, 0),
                 delay);
     }
-    
+
     /*
-     * just query settings to retrieve the memory threshold. 
+     * just query settings to retrieve the memory threshold.
      * Preferred this over using a ContentObserver since Settings.Gservices caches the value
      * any way
      */
     private long getMemThreshold() {
         int value = Settings.Gservices.getInt(
-                              mContentResolver, 
-                              Settings.Gservices.SYS_STORAGE_THRESHOLD_PERCENTAGE, 
+                              mContentResolver,
+                              Settings.Gservices.SYS_STORAGE_THRESHOLD_PERCENTAGE,
                               DEFAULT_THRESHOLD_PERCENTAGE);
         if(localLOGV) Log.v(TAG, "Threshold Percentage="+value);
         //evaluate threshold value
@@ -247,16 +272,17 @@
         mContext = context;
         mContentResolver = mContext.getContentResolver();
         //create StatFs object
-        mFileStats = new StatFs(DATA_PATH);
-        //initialize block size
-        mBlkSize = mFileStats.getBlockSize();
+        mDataFileStats = new StatFs(DATA_PATH);
+        mSystemFileStats = new StatFs(SYSTEM_PATH);
+        mCacheFileStats = new StatFs(CACHE_PATH);
         //initialize total storage on device
-        mTotalMemory = ((long)mFileStats.getBlockCount()*mBlkSize)/100L;
+        mTotalMemory = ((long)mDataFileStats.getBlockCount() *
+                        mDataFileStats.getBlockSize())/100L;
         mStorageLowIntent = new Intent(Intent.ACTION_DEVICE_STORAGE_LOW);
         mStorageOkIntent = new Intent(Intent.ACTION_DEVICE_STORAGE_OK);
         checkMemory(true);
     }
-    
+
 
     /**
     * This method sends a notification to NotificationManager to display
@@ -271,7 +297,7 @@
         Intent lowMemIntent = new Intent(Intent.ACTION_MANAGE_PACKAGE_STORAGE);
         lowMemIntent.putExtra("memory", mFreeMem);
         lowMemIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        NotificationManager mNotificationMgr = 
+        NotificationManager mNotificationMgr =
                 (NotificationManager)mContext.getSystemService(
                         Context.NOTIFICATION_SERVICE);
         CharSequence title = mContext.getText(
@@ -302,7 +328,7 @@
         mContext.removeStickyBroadcast(mStorageLowIntent);
         mContext.sendBroadcast(mStorageOkIntent);
     }
-    
+
     public void updateMemory() {
         int callingUid = getCallingUid();
         if(callingUid != Process.SYSTEM_UID) {
diff --git a/services/java/com/android/server/LocationManagerService.java b/services/java/com/android/server/LocationManagerService.java
index f6a1be7..c8fa4c3 100644
--- a/services/java/com/android/server/LocationManagerService.java
+++ b/services/java/com/android/server/LocationManagerService.java
@@ -382,7 +382,12 @@
     }
 
     public void locationCallbackFinished(ILocationListener listener) {
-        Receiver receiver = getReceiver(listener);
+        //Do not use getReceiver here as that will add the ILocationListener to
+        //the receiver list if it is not found.  If it is not found then the
+        //LocationListener was removed when it had a pending broadcast and should
+        //not be added back.
+        IBinder binder = listener.asBinder();
+        Receiver receiver = mReceivers.get(binder);
         if (receiver != null) {
             synchronized (receiver) {
                 // so wakelock calls will succeed
@@ -921,6 +926,12 @@
         try {
             if (mReceivers.remove(receiver.mKey) != null && receiver.isListener()) {
                 receiver.getListener().asBinder().unlinkToDeath(receiver, 0);
+                synchronized(receiver) {
+                    if(receiver.mPendingBroadcasts > 0) {
+                        decrementPendingBroadcasts();
+                        receiver.mPendingBroadcasts = 0;
+                    }
+                }
             }
 
             // Record which providers were associated with this listener
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index e5c6010..b8cf844 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -23,6 +23,7 @@
 import dalvik.system.VMRuntime;
 
 import android.app.ActivityManagerNative;
+import android.bluetooth.BluetoothAdapter;
 import android.content.ComponentName;
 import android.content.ContentResolver;
 import android.content.ContentService;
@@ -172,14 +173,14 @@
             // support Bluetooth - see bug 988521
             if (SystemProperties.get("ro.kernel.qemu").equals("1")) {
                 Log.i(TAG, "Registering null Bluetooth Service (emulator)");
-                ServiceManager.addService(Context.BLUETOOTH_SERVICE, null);
+                ServiceManager.addService(BluetoothAdapter.BLUETOOTH_SERVICE, null);
             } else if (factoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
                 Log.i(TAG, "Registering null Bluetooth Service (factory test)");
-                ServiceManager.addService(Context.BLUETOOTH_SERVICE, null);
+                ServiceManager.addService(BluetoothAdapter.BLUETOOTH_SERVICE, null);
             } else {
                 Log.i(TAG, "Bluetooth Service");
                 bluetooth = new BluetoothService(context);
-                ServiceManager.addService(Context.BLUETOOTH_SERVICE, bluetooth);
+                ServiceManager.addService(BluetoothAdapter.BLUETOOTH_SERVICE, bluetooth);
                 bluetooth.initAfterRegistration();
                 bluetoothA2dp = new BluetoothA2dpService(context, bluetooth);
                 ServiceManager.addService(BluetoothA2dpService.BLUETOOTH_A2DP_SERVICE,
diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java
index 67b8a85..00636c4 100644
--- a/services/java/com/android/server/WindowManagerService.java
+++ b/services/java/com/android/server/WindowManagerService.java
@@ -7574,6 +7574,21 @@
         }
 
         /**
+         * Like {@link #isVisibleLw}, but also counts a window that is currently
+         * "hidden" behind the keyguard as visible.  This allows us to apply
+         * things like window flags that impact the keyguard.
+         * XXX I am starting to think we need to have ANOTHER visibility flag
+         * for this "hidden behind keyguard" state rather than overloading
+         * mPolicyVisibility.  Ungh.
+         */
+        public boolean isVisibleOrBehindKeyguardLw() {
+            final AppWindowToken atoken = mAppToken;
+            return mSurface != null && !mAttachedHidden
+                    && (atoken == null ? mPolicyVisibility : !atoken.hiddenRequested)
+                    && !mExiting && !mDestroying;
+        }
+
+        /**
          * Is this window visible, ignoring its app token?  It is not visible
          * if there is no surface, or we are in the process of running an exit animation
          * that will remove the surface.
diff --git a/services/java/com/android/server/status/StatusBarPolicy.java b/services/java/com/android/server/status/StatusBarPolicy.java
index cf63d02..3d1fb83 100644
--- a/services/java/com/android/server/status/StatusBarPolicy.java
+++ b/services/java/com/android/server/status/StatusBarPolicy.java
@@ -448,8 +448,7 @@
         mBluetoothData = IconData.makeIcon("bluetooth",
                 null, com.android.internal.R.drawable.stat_sys_data_bluetooth, 0, 0);
         mBluetoothIcon = service.addIcon(mBluetoothData, null);
-        BluetoothAdapter adapter =
-                (BluetoothAdapter) mContext.getSystemService(Context.BLUETOOTH_SERVICE);
+        BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
         if (adapter != null) {
             mBluetoothEnabled = adapter.isEnabled();
         } else {
@@ -625,15 +624,20 @@
             pixelFormat = bg.getOpacity();
         }
 
+        int flags =  WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
+                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
+                | WindowManager.LayoutParams.FLAG_DIM_BEHIND;
+        
+        if (!mContext.getResources().getBoolean(
+                com.android.internal.R.bool.config_sf_slowBlur)) {
+            flags |= WindowManager.LayoutParams.FLAG_BLUR_BEHIND;
+        }
+        
         WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
                 ViewGroup.LayoutParams.WRAP_CONTENT,
                 ViewGroup.LayoutParams.WRAP_CONTENT,
                 WindowManager.LayoutParams.TYPE_TOAST,
-                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
-                    | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
-                    | WindowManager.LayoutParams.FLAG_BLUR_BEHIND
-                    | WindowManager.LayoutParams.FLAG_DIM_BEHIND,
-                pixelFormat);
+                flags, pixelFormat);
 
         // Get the dim amount from the theme
         TypedArray a = mContext.obtainStyledAttributes(