auto import from //depot/cupcake/@136745
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index f11dbec..53e6f34 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -979,6 +979,17 @@
             return true;
         }
         
+        case PROFILE_CONTROL_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            String process = data.readString();
+            boolean start = data.readInt() != 0;
+            String path = data.readString();
+            boolean res = profileControl(process, start, path);
+            reply.writeNoException();
+            reply.writeInt(res ? 1 : 0);
+            return true;
+        }
+        
         case PEEK_SERVICE_TRANSACTION: {
             data.enforceInterface(IActivityManager.descriptor);
             Intent service = Intent.CREATOR.createFromParcel(data);
@@ -2131,5 +2142,23 @@
         data.recycle();
         return res;
     }
+    
+    public boolean profileControl(String process, boolean start,
+            String path) throws RemoteException
+    {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeString(process);
+        data.writeInt(start ? 1 : 0);
+        data.writeString(path);
+        mRemote.transact(PROFILE_CONTROL_TRANSACTION, data, reply, 0);
+        reply.readException();
+        boolean res = reply.readInt() != 0;
+        reply.recycle();
+        data.recycle();
+        return res;
+    }
+    
     private IBinder mRemote;
 }
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index bf5616e..f49005e 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -1449,6 +1449,10 @@
             }
         }
         
+        public void profilerControl(boolean start, String path) {
+            queueOrSendMessage(H.PROFILER_CONTROL, path, start ? 1 : 0);
+        }
+
         @Override
         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
             long nativeMax = Debug.getNativeHeapSize() / 1024;
@@ -1641,6 +1645,7 @@
         public static final int LOW_MEMORY              = 124;
         public static final int ACTIVITY_CONFIGURATION_CHANGED = 125;
         public static final int RELAUNCH_ACTIVITY       = 126;
+        public static final int PROFILER_CONTROL        = 127;
         String codeToString(int code) {
             if (localLOGV) {
                 switch (code) {
@@ -1671,6 +1676,7 @@
                     case LOW_MEMORY: return "LOW_MEMORY";
                     case ACTIVITY_CONFIGURATION_CHANGED: return "ACTIVITY_CONFIGURATION_CHANGED";
                     case RELAUNCH_ACTIVITY: return "RELAUNCH_ACTIVITY";
+                    case PROFILER_CONTROL: return "PROFILER_CONTROL";
                 }
             }
             return "(unknown)";
@@ -1770,6 +1776,9 @@
                 case ACTIVITY_CONFIGURATION_CHANGED:
                     handleActivityConfigurationChanged((IBinder)msg.obj);
                     break;
+                case PROFILER_CONTROL:
+                    handleProfilerControl(msg.arg1 != 0, (String)msg.obj);
+                    break;
             }
         }
     }
@@ -3432,6 +3441,21 @@
         performConfigurationChanged(r.activity, mConfiguration);
     }
 
+    final void handleProfilerControl(boolean start, String path) {
+        if (start) {
+            File file = new File(path);
+            file.getParentFile().mkdirs();
+            try {
+                Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024);
+            } catch (RuntimeException e) {
+                Log.w(TAG, "Profiling failed on path " + path
+                        + " -- can the process access this path?");
+            }
+        } else {
+            Debug.stopMethodTracing();
+        }
+    }
+    
     final void handleLowMemory() {
         ArrayList<ComponentCallbacks> callbacks
                 = new ArrayList<ComponentCallbacks>();
diff --git a/core/java/android/app/ApplicationThreadNative.java b/core/java/android/app/ApplicationThreadNative.java
index d2cf55a..bcc9302 100644
--- a/core/java/android/app/ApplicationThreadNative.java
+++ b/core/java/android/app/ApplicationThreadNative.java
@@ -322,6 +322,15 @@
             requestPss();
             return true;
         }
+        
+        case PROFILER_CONTROL_TRANSACTION:
+        {
+            data.enforceInterface(IApplicationThread.descriptor);
+            boolean start = data.readInt() != 0;
+            String path = data.readString();
+            profilerControl(start, path);
+            return true;
+        }
         }
 
         return super.onTransact(code, data, reply, flags);
@@ -654,5 +663,14 @@
         data.recycle();
     }
     
+    public void profilerControl(boolean start, String path) throws RemoteException {
+        Parcel data = Parcel.obtain();
+        data.writeInterfaceToken(IApplicationThread.descriptor);
+        data.writeInt(start ? 1 : 0);
+        data.writeString(path);
+        mRemote.transact(PROFILER_CONTROL_TRANSACTION, data, null,
+                IBinder.FLAG_ONEWAY);
+        data.recycle();
+    }
 }
 
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index cd3701f..2ac6160 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -221,6 +221,10 @@
     // Get device configuration
     public ConfigurationInfo getDeviceConfigurationInfo() throws RemoteException;
     
+    // Turn on/off profiling in a particular process.
+    public boolean profileControl(String process, boolean start,
+            String path) throws RemoteException;
+    
     /*
      * Private non-Binder interfaces
      */
@@ -365,4 +369,5 @@
     int GET_RUNNING_APP_PROCESSES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+82;
     int GET_DEVICE_CONFIGURATION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+83;
     int PEEK_SERVICE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+84;
+    int PROFILE_CONTROL_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+85;
 }
diff --git a/core/java/android/app/IApplicationThread.java b/core/java/android/app/IApplicationThread.java
index 47476b5..9f3534b 100644
--- a/core/java/android/app/IApplicationThread.java
+++ b/core/java/android/app/IApplicationThread.java
@@ -86,6 +86,7 @@
     void scheduleLowMemory() throws RemoteException;
     void scheduleActivityConfigurationChanged(IBinder token) throws RemoteException;
     void requestPss() throws RemoteException;
+    void profilerControl(boolean start, String path) throws RemoteException;
 
     String descriptor = "android.app.IApplicationThread";
 
@@ -115,4 +116,5 @@
     int SCHEDULE_ACTIVITY_CONFIGURATION_CHANGED_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+24;
     int SCHEDULE_RELAUNCH_ACTIVITY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+25;
     int REQUEST_PSS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+26;
+    int PROFILER_CONTROL_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+27;
 }
diff --git a/core/java/android/bluetooth/BluetoothA2dp.java b/core/java/android/bluetooth/BluetoothA2dp.java
index b0b0154..2ea45d5 100644
--- a/core/java/android/bluetooth/BluetoothA2dp.java
+++ b/core/java/android/bluetooth/BluetoothA2dp.java
@@ -49,6 +49,7 @@
  */
 public class BluetoothA2dp {
     private static final String TAG = "BluetoothA2dp";
+    private static final boolean DBG = false;
 
     /** int extra for SINK_STATE_CHANGED_ACTION */
     public static final String SINK_STATE =
@@ -103,6 +104,7 @@
      *  @hide
      */
     public int connectSink(String address) {
+        if (DBG) log("connectSink(" + address + ")");
         try {
             return mService.connectSink(address);
         } catch (RemoteException e) {
@@ -119,6 +121,7 @@
      *  @hide
      */
     public int disconnectSink(String address) {
+        if (DBG) log("disconnectSink(" + address + ")");
         try {
             return mService.disconnectSink(address);
         } catch (RemoteException e) {
@@ -133,6 +136,7 @@
      *  @hide
      */
     public boolean isSinkConnected(String address) {
+        if (DBG) log("isSinkConnected(" + address + ")");
         int state = getSinkState(address);
         return state == STATE_CONNECTED || state == STATE_PLAYING;
     }
@@ -142,6 +146,7 @@
      * @hide
      */
     public List<String> listConnectedSinks() {
+        if (DBG) log("listConnectedSinks()");
         try {
             return mService.listConnectedSinks();
         } catch (RemoteException e) {
@@ -156,6 +161,7 @@
      *  @hide
      */
     public int getSinkState(String address) {
+        if (DBG) log("getSinkState(" + address + ")");
         try {
             return mService.getSinkState(address);
         } catch (RemoteException e) {
@@ -177,6 +183,7 @@
      * @return Result code, negative indicates an error
      */
     public int setSinkPriority(String address, int priority) {
+        if (DBG) log("setSinkPriority(" + address + ", " + priority + ")");
         try {
             return mService.setSinkPriority(address, priority);
         } catch (RemoteException e) {
@@ -191,6 +198,7 @@
      * @return non-negative priority, or negative error code on error.
      */
     public int getSinkPriority(String address) {
+        if (DBG) log("getSinkPriority(" + address + ")");
         try {
             return mService.getSinkPriority(address);
         } catch (RemoteException e) {
@@ -244,4 +252,8 @@
             return "<unknown state " + state + ">";
         }
     }
+
+    private static void log(String msg) {
+        Log.d(TAG, msg);
+    }
 }
diff --git a/core/java/android/bluetooth/BluetoothHeadset.java b/core/java/android/bluetooth/BluetoothHeadset.java
index 34196bf..e23545b 100644
--- a/core/java/android/bluetooth/BluetoothHeadset.java
+++ b/core/java/android/bluetooth/BluetoothHeadset.java
@@ -126,6 +126,7 @@
      * are ok.
      */
     public synchronized void close() {
+        if (DBG) log("close()");
         if (mConnection != null) {
             mContext.unbindService(mConnection);
             mConnection = null;
@@ -138,6 +139,7 @@
      *         object is currently not connected to the Headset service.
      */
     public int getState() {
+        if (DBG) log("getState()");
         if (mService != null) {
             try {
                 return mService.getState();
@@ -156,6 +158,7 @@
      *         service.
      */
     public String getHeadsetAddress() {
+        if (DBG) log("getHeadsetAddress()");
         if (mService != null) {
             try {
                 return mService.getHeadsetAddress();
@@ -180,6 +183,7 @@
      *                will be expected.
      */
     public boolean connectHeadset(String address) {
+        if (DBG) log("connectHeadset(" + address + ")");
         if (mService != null) {
             try {
                 if (mService.connectHeadset(address)) {
@@ -199,6 +203,7 @@
      * if not currently connected to the headset service.
      */
     public boolean isConnected(String address) {
+        if (DBG) log("isConnected(" + address + ")");
         if (mService != null) {
             try {
                 return mService.isConnected(address);
@@ -216,6 +221,7 @@
      * not currently connected to the Headset service.
      */
     public boolean disconnectHeadset() {
+        if (DBG) log("disconnectHeadset()");
         if (mService != null) {
             try {
                 mService.disconnectHeadset();
@@ -235,6 +241,7 @@
      * error.
      */
     public boolean startVoiceRecognition() {
+        if (DBG) log("startVoiceRecognition()");
         if (mService != null) {
             try {
                 return mService.startVoiceRecognition();
@@ -252,6 +259,7 @@
      * headset is not in voice recognition mode, or on error.
      */
     public boolean stopVoiceRecognition() {
+        if (DBG) log("stopVoiceRecognition()");
         if (mService != null) {
             try {
                 return mService.stopVoiceRecognition();
@@ -282,6 +290,7 @@
      * @return True if successful, false if there was some error.
      */
     public boolean setPriority(String address, int priority) {
+        if (DBG) log("setPriority(" + address + ", " + priority + ")");
         if (mService != null) {
             try {
                 return mService.setPriority(address, priority);
@@ -299,6 +308,7 @@
      * @return non-negative priority, or negative error code on error.
      */
     public int getPriority(String address) {
+        if (DBG) log("getPriority(" + address + ")");
         if (mService != null) {
             try {
                 return mService.getPriority(address);
@@ -350,4 +360,8 @@
             }
         }
     };
+
+    private static void log(String msg) {
+        Log.d(TAG, msg);
+    }
 }
diff --git a/core/java/android/server/BluetoothDeviceService.java b/core/java/android/server/BluetoothDeviceService.java
index 950ff3a..87153cf 100644
--- a/core/java/android/server/BluetoothDeviceService.java
+++ b/core/java/android/server/BluetoothDeviceService.java
@@ -295,7 +295,8 @@
                 new ArrayList<String>(Arrays.asList(
                         "00:02:C7", "00:16:FE", "00:19:C1", "00:1B:FB", "00:1E:3D", //ALPS
                         "00:21:4F", "00:23:06", "00:24:33", "00:A0:79", // ALPS
-                        "00:0E:6D", "00:13:E0", "00:21:E8", "00:60:57"// Murata for Prius 2007
+                        "00:0E:6D", "00:13:E0", "00:21:E8", "00:60:57",// Murata for Prius 2007
+                        "00:0E:9F" // TEMIC SDS  for Porsche
                         ));
 
         public synchronized void loadBondState() {
diff --git a/core/java/android/view/GestureDetector.java b/core/java/android/view/GestureDetector.java
index e0231a7b..88ff3c5 100644
--- a/core/java/android/view/GestureDetector.java
+++ b/core/java/android/view/GestureDetector.java
@@ -499,13 +499,10 @@
                 // Finally, give the up event of the double-tap
                 handled |= mDoubleTapListener.onDoubleTapEvent(ev);
                 mIsDoubleTapping = false;
-                break;
             } else if (mInLongPress) {
                 mHandler.removeMessages(TAP);
                 mInLongPress = false;
-                break;
-            }
-            if (mAlwaysInTapRegion) {
+            } else if (mAlwaysInTapRegion) {
                 handled = mListener.onSingleTapUp(ev);
             } else {