diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 710e2ee..7b41af2 100755
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -52,5 +52,8 @@
             android:noHistory="true"
 
         />
+        <service android:name=".handover.HandoverService"
+            android:process=":handover"
+        />
     </application>
 </manifest>
diff --git a/nci/jni/NativeNfcManager.cpp b/nci/jni/NativeNfcManager.cpp
index f15c92f..61fc052 100755
--- a/nci/jni/NativeNfcManager.cpp
+++ b/nci/jni/NativeNfcManager.cpp
@@ -1276,6 +1276,7 @@
 {
     ALOGD ("%s: enter", __FUNCTION__);
     bool stat = false;
+    bool bRestartDiscovery = false;
 
     if (! sIsSecElemSelected)
     {
@@ -1290,6 +1291,12 @@
         goto TheEnd;
     }
 
+    if (sRfEnabled) {
+        // Stop RF Discovery if we were polling
+        startRfDiscovery (false);
+        bRestartDiscovery = true;
+    }
+
     stat = SecureElement::getInstance().routeToDefault ();
     sIsSecElemSelected = false;
 
@@ -1299,6 +1306,9 @@
         SecureElement::getInstance().deactivate (0xABCDEF);
 
 TheEnd:
+    if (bRestartDiscovery)
+        startRfDiscovery (true);
+
     //if nothing is active after this, then tell the controller to power down
     if (! PowerSwitch::getInstance ().setModeOff (PowerSwitch::SE_ROUTING))
         PowerSwitch::getInstance ().setLevel (PowerSwitch::LOW_POWER);
diff --git a/nci/jni/PeerToPeer.cpp b/nci/jni/PeerToPeer.cpp
index 7994e2a..b40e366 100644
--- a/nci/jni/PeerToPeer.cpp
+++ b/nci/jni/PeerToPeer.cpp
@@ -1431,9 +1431,9 @@
         if ((pConn = sP2p.findConnection(eventData->disc.handle)) == NULL)
         {
             // If no connection, may be a client that is trying to connect
-            if ((pClient = sP2p.findClientCon ((tNFA_HANDLE)NFA_HANDLE_INVALID)) == NULL)
+            if ((pClient = sP2p.findClient (eventData->disc.handle)) == NULL)
             {
-                ALOGE ("%s: NFA_P2P_DISC_EVT: can't find conn for NFA handle: 0x%04x", fn, eventData->disc.handle);
+                ALOGE ("%s: NFA_P2P_DISC_EVT: can't find client for NFA handle: 0x%04x", fn, eventData->disc.handle);
                 return;
             }
             // Unblock createDataLinkConn()
diff --git a/nci/jni/SecureElement.cpp b/nci/jni/SecureElement.cpp
index 3c9256b..a4c4d57 100755
--- a/nci/jni/SecureElement.cpp
+++ b/nci/jni/SecureElement.cpp
@@ -156,12 +156,12 @@
 
     if (GetNumValue("NFA_HCI_DEFAULT_DEST_GATE", &num, sizeof(num)))
         mDestinationGate = num;
-    ALOGD ("%s: Default destination gate: %d", fn, mDestinationGate);
+    ALOGD ("%s: Default destination gate: 0x%X", fn, mDestinationGate);
 
     // active SE, if not set active all SEs
     if (GetNumValue("ACTIVE_SE", &num, sizeof(num)))
         mActiveSeOverride = num;
-    ALOGD ("%s: Active SE override: %d", fn, mActiveSeOverride);
+    ALOGD ("%s: Active SE override: 0x%X", fn, mActiveSeOverride);
 
     if (GetNumValue("OBERTHUR_WARM_RESET_COMMAND", &num, sizeof(num)))
     {
@@ -442,7 +442,7 @@
 ** Function:        activate
 **
 ** Description:     Turn on the secure element.
-**                  seID: ID of secure element.
+**                  seID: ID of secure element; 0xF3 or 0xF4.
 **
 ** Returns:         True if ok.
 **
@@ -474,24 +474,16 @@
         return false;
     }
 
-    mActiveEeHandle = getDefaultEeHandle();
-    ALOGD ("%s: active ee h=0x%X, override se=0x%X", fn, mActiveEeHandle, mActiveSeOverride);
-    if (mActiveEeHandle == NFA_HANDLE_INVALID)
-    {
-        ALOGE ("%s: ee not found", fn);
-        return false;
-    }
-
-    UINT16 override_se = 0;
+    UINT16 overrideEeHandle = 0;
     if (mActiveSeOverride)
-        override_se = NFA_HANDLE_GROUP_EE | mActiveSeOverride;
+        overrideEeHandle = NFA_HANDLE_GROUP_EE | mActiveSeOverride;
 
     if (mRfFieldIsOn) {
         ALOGE("%s: RF field indication still on, resetting", fn);
         mRfFieldIsOn = false;
     }
 
-    ALOGD ("%s: override seid=0x%X", fn, override_se );
+    ALOGD ("%s: override ee h=0x%X", fn, overrideEeHandle );
     //activate every discovered secure element
     for (int index=0; index < mActualNumEe; index++)
     {
@@ -499,7 +491,7 @@
 
         if ((eeItem.ee_handle == EE_HANDLE_0xF3) || (eeItem.ee_handle == EE_HANDLE_0xF4))
         {
-            if (override_se && (override_se != eeItem.ee_handle) )
+            if (overrideEeHandle && (overrideEeHandle != eeItem.ee_handle) )
                 continue;   // do not enable all SEs; only the override one
 
             if (eeItem.ee_status != NFC_NFCEE_STATUS_INACTIVE)
@@ -524,18 +516,11 @@
         }
     } //for
 
-    for (UINT8 xx = 0; xx < mActualNumEe; xx++)
-    {
-        if ((mEeInfo[xx].num_interface != 0) && (mEeInfo[xx].ee_interface[0] != NCI_NFCEE_INTERFACE_HCI_ACCESS) &&
-            (mEeInfo[xx].ee_status != NFC_NFCEE_STATUS_INACTIVE))
-        {
-            mActiveEeHandle = mEeInfo[xx].ee_handle;
-            break;
-        }
-    }
-
-    ALOGD ("%s: exit; ok=%u", fn, numActivatedEe > 0);
-    return numActivatedEe > 0;
+    mActiveEeHandle = getDefaultEeHandle();
+    if (mActiveEeHandle == NFA_HANDLE_INVALID)
+        ALOGE ("%s: ee handle not found", fn);
+    ALOGD ("%s: exit; active ee h=0x%X", fn, mActiveEeHandle);
+    return mActiveEeHandle != NFA_HANDLE_INVALID;
 }
 
 
@@ -544,7 +529,7 @@
 ** Function:        deactivate
 **
 ** Description:     Turn off the secure element.
-**                  seID: ID of secure element.
+**                  seID: ID of secure element; 0xF3 or 0xF4.
 **
 ** Returns:         True if ok.
 **
@@ -1417,7 +1402,7 @@
     {
         tNFA_HANDLE eeHandle = NFA_EE_HANDLE_DH;
         if (routeSelection == SecElemRoute)
-            eeHandle = getDefaultEeHandle ();
+            eeHandle = mActiveEeHandle;
         ALOGD ("%s: route to default EE h=0x%X", fn, eeHandle);
         SyncEventGuard guard (mRoutingEvent);
         nfaStat = NFA_EeSetDefaultProtoRouting (eeHandle, protoMask, 0, 0);
@@ -1573,7 +1558,7 @@
     {
         tNFA_HANDLE eeHandle = NFA_EE_HANDLE_DH;
         if (routeSelection == SecElemRoute)
-            eeHandle = getDefaultEeHandle ();
+            eeHandle = mActiveEeHandle;
         ALOGD ("%s: route to default EE h=0x%X", fn, eeHandle);
         SyncEventGuard guard (mRoutingEvent);
         nfaStat = NFA_EeSetDefaultTechRouting (eeHandle, techMask, 0, 0);
@@ -1975,26 +1960,31 @@
 *******************************************************************************/
 tNFA_HANDLE SecureElement::getDefaultEeHandle ()
 {
+    UINT16 overrideEeHandle = NFA_HANDLE_GROUP_EE | mActiveSeOverride;
     // Find the first EE that is not the HCI Access i/f.
     for (UINT8 xx = 0; xx < mActualNumEe; xx++)
     {
-        if ((mEeInfo[xx].num_interface != 0) && (mEeInfo[xx].ee_interface[0] != NCI_NFCEE_INTERFACE_HCI_ACCESS) )
+        if (mActiveSeOverride && (overrideEeHandle != mEeInfo[xx].ee_handle))
+            continue; //skip all the EE's that are ignored
+        if ((mEeInfo[xx].num_interface != 0) &&
+            (mEeInfo[xx].ee_interface[0] != NCI_NFCEE_INTERFACE_HCI_ACCESS) &&
+            (mEeInfo[xx].ee_status != NFC_NFCEE_STATUS_INACTIVE))
             return (mEeInfo[xx].ee_handle);
     }
     return NFA_HANDLE_INVALID;
 }
 
 
-    /*******************************************************************************
-    **
-    ** Function:        findUiccByHandle
-    **
-    ** Description:     Find information about an execution environment.
-    **                  eeHandle: Handle of the execution environment.
-    **
-    ** Returns:         Information about the execution environment.
-    **
-    *******************************************************************************/
+/*******************************************************************************
+**
+** Function:        findUiccByHandle
+**
+** Description:     Find information about an execution environment.
+**                  eeHandle: Handle of the execution environment.
+**
+** Returns:         Information about the execution environment.
+**
+*******************************************************************************/
 tNFA_EE_DISCOVER_INFO *SecureElement::findUiccByHandle (tNFA_HANDLE eeHandle)
 {
     for (UINT8 index = 0; index < mUiccInfo.num_ee; index++)
diff --git a/src/com/android/nfc/NfcApplication.java b/src/com/android/nfc/NfcApplication.java
index 867b8bb..3e7194d 100644
--- a/src/com/android/nfc/NfcApplication.java
+++ b/src/com/android/nfc/NfcApplication.java
@@ -1,12 +1,18 @@
 package com.android.nfc;
 
+import android.app.ActivityManager;
+import android.app.ActivityManager.RunningAppProcessInfo;
 import android.app.Application;
+import android.os.Process;
 import android.os.UserHandle;
-import android.util.Log;
+import java.util.Iterator;
+import java.util.List;
 
 public class NfcApplication extends Application {
 
-    public static final String TAG = "NfcApplication";
+    static final String TAG = "NfcApplication";
+    static final String NFC_PROCESS = "com.android.nfc";
+
     NfcService mNfcService;
 
     public NfcApplication() {
@@ -17,7 +23,23 @@
     public void onCreate() {
         super.onCreate();
 
-        if (UserHandle.myUserId() == 0) {
+        boolean isMainProcess = false;
+        // We start a service in a separate process to do
+        // handover transfer. We don't want to instantiate an NfcService
+        // object in those cases, hence check the name of the process
+        // to determine whether we're the main NFC service, or the
+        // handover process
+        ActivityManager am = (ActivityManager)this.getSystemService(ACTIVITY_SERVICE);
+        List processes = am.getRunningAppProcesses();
+        Iterator i = processes.iterator();
+        while (i.hasNext()) {
+            RunningAppProcessInfo appInfo = (RunningAppProcessInfo)(i.next());
+            if (appInfo.pid == Process.myPid()) {
+                isMainProcess =  (NFC_PROCESS.equals(appInfo.processName));
+                break;
+            }
+        }
+        if (UserHandle.myUserId() == 0 && isMainProcess) {
             mNfcService = new NfcService(this);
         }
     }
diff --git a/src/com/android/nfc/RegisteredComponentCache.java b/src/com/android/nfc/RegisteredComponentCache.java
index 5da2cd4..8d73317 100644
--- a/src/com/android/nfc/RegisteredComponentCache.java
+++ b/src/com/android/nfc/RegisteredComponentCache.java
@@ -43,6 +43,7 @@
  */
 public class RegisteredComponentCache {
     private static final String TAG = "RegisteredComponentCache";
+    private static final boolean DEBUG = false;
 
     final Context mContext;
     final String mAction;
@@ -165,7 +166,9 @@
             }
         }
 
-        dump(components);
+        if (DEBUG) {
+            dump(components);
+        }
 
         synchronized (this) {
             mComponents = components;
diff --git a/src/com/android/nfc/handover/BluetoothHeadsetHandover.java b/src/com/android/nfc/handover/BluetoothHeadsetHandover.java
index 1377160..c845f89 100644
--- a/src/com/android/nfc/handover/BluetoothHeadsetHandover.java
+++ b/src/com/android/nfc/handover/BluetoothHeadsetHandover.java
@@ -16,7 +16,6 @@
 
 package com.android.nfc.handover;
 
-import android.app.ActivityManager;
 import android.bluetooth.BluetoothA2dp;
 import android.bluetooth.BluetoothAdapter;
 import android.bluetooth.BluetoothDevice;
@@ -29,12 +28,10 @@
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
-import android.os.UserHandle;
 import android.util.Log;
 import android.view.KeyEvent;
 import android.widget.Toast;
 
-import com.android.nfc.handover.HandoverManager.HandoverPowerManager;
 import com.android.nfc.R;
 
 /**
@@ -57,14 +54,13 @@
     static final int TIMEOUT_MS = 20000;
 
     static final int STATE_INIT = 0;
-    static final int STATE_TURNING_ON = 1;
-    static final int STATE_WAITING_FOR_PROXIES = 2;
-    static final int STATE_INIT_COMPLETE = 3;
-    static final int STATE_WAITING_FOR_BOND_CONFIRMATION = 4;
-    static final int STATE_BONDING = 5;
-    static final int STATE_CONNECTING = 6;
-    static final int STATE_DISCONNECTING = 7;
-    static final int STATE_COMPLETE = 8;
+    static final int STATE_WAITING_FOR_PROXIES = 1;
+    static final int STATE_INIT_COMPLETE = 2;
+    static final int STATE_WAITING_FOR_BOND_CONFIRMATION = 3;
+    static final int STATE_BONDING = 4;
+    static final int STATE_CONNECTING = 5;
+    static final int STATE_DISCONNECTING = 6;
+    static final int STATE_COMPLETE = 7;
 
     static final int RESULT_PENDING = 0;
     static final int RESULT_CONNECTED = 1;
@@ -80,7 +76,6 @@
     final Context mContext;
     final BluetoothDevice mDevice;
     final String mName;
-    final HandoverPowerManager mHandoverPowerManager;
     final Callback mCallback;
     final BluetoothAdapter mBluetoothAdapter;
 
@@ -101,18 +96,21 @@
     }
 
     public BluetoothHeadsetHandover(Context context, BluetoothDevice device, String name,
-            HandoverPowerManager powerManager, Callback callback) {
+            Callback callback) {
         checkMainThread();  // mHandler must get get constructed on Main Thread for toasts to work
         mContext = context;
         mDevice = device;
         mName = name;
-        mHandoverPowerManager = powerManager;
         mCallback = callback;
         mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
 
         mState = STATE_INIT;
     }
 
+    public boolean hasStarted() {
+        return mState != STATE_INIT;
+    }
+
     /**
      * Main entry point. This method is usually called after construction,
      * to begin the BT sequence. Must be called on Main thread.
@@ -156,18 +154,6 @@
     void nextStepInit() {
         switch (mState) {
             case STATE_INIT:
-                if (!mHandoverPowerManager.isBluetoothEnabled()) {
-                    if (mHandoverPowerManager.enableBluetooth()) {
-                        // Bluetooth is being enabled
-                        mState = STATE_TURNING_ON;
-                    } else {
-                        toast(mContext.getString(R.string.failed_to_enable_bt));
-                        complete(false);
-                    }
-                    break;
-                }
-                // fall-through
-            case STATE_TURNING_ON:
                 if (mA2dp == null || mHeadset == null) {
                     mState = STATE_WAITING_FOR_PROXIES;
                     if (!getProfileProxys()) {
@@ -310,18 +296,7 @@
 
     void handleIntent(Intent intent) {
         String action = intent.getAction();
-        if (BluetoothAdapter.ACTION_STATE_CHANGED.equals(action) && mState == STATE_TURNING_ON) {
-            int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
-            if (state == BluetoothAdapter.STATE_ON) {
-                nextStep();
-            } else if (state == BluetoothAdapter.STATE_OFF) {
-                toast(mContext.getString(R.string.failed_to_enable_bt));
-                complete(false);
-            }
-            return;
-        }
-
-        // Everything else requires the device to match...
+        // Everything requires the device to match...
         BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
         if (!mDevice.equals(device)) return;
 
@@ -387,19 +362,18 @@
         Intent intent = new Intent(Intent.ACTION_MEDIA_BUTTON);
         intent.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_DOWN,
                 KeyEvent.KEYCODE_MEDIA_PLAY));
-        mContext.sendOrderedBroadcastAsUser(intent, UserHandle.CURRENT, null, null, null, 0, null, null);
+        mContext.sendOrderedBroadcast(intent, null);
         intent.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_UP,
                 KeyEvent.KEYCODE_MEDIA_PLAY));
-        mContext.sendOrderedBroadcastAsUser(intent, UserHandle.CURRENT, null, null, null, 0, null, null);
+        mContext.sendOrderedBroadcast(intent, null);
     }
 
     void requestPairConfirmation() {
         Intent dialogIntent = new Intent(mContext, ConfirmConnectActivity.class);
         dialogIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-
         dialogIntent.putExtra(BluetoothDevice.EXTRA_DEVICE, mDevice);
 
-        mContext.startActivityAsUser(dialogIntent, new UserHandle(UserHandle.USER_CURRENT));
+        mContext.startActivity(dialogIntent);
     }
 
     final Handler mHandler = new Handler() {
diff --git a/src/com/android/nfc/handover/BluetoothOppHandover.java b/src/com/android/nfc/handover/BluetoothOppHandover.java
index ceb3c62..fdb5eff 100644
--- a/src/com/android/nfc/handover/BluetoothOppHandover.java
+++ b/src/com/android/nfc/handover/BluetoothOppHandover.java
@@ -16,25 +16,17 @@
 
 package com.android.nfc.handover;
 
-import android.bluetooth.BluetoothAdapter;
 import android.bluetooth.BluetoothDevice;
-import android.content.ActivityNotFoundException;
-import android.content.BroadcastReceiver;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
-import android.content.IntentFilter;
 import android.net.Uri;
 import android.os.Handler;
 import android.os.Message;
 import android.os.SystemClock;
+import android.os.UserHandle;
 import android.util.Log;
 import android.webkit.MimeTypeMap;
-import android.widget.Toast;
-
-import com.android.nfc.handover.HandoverManager.HandoverPowerManager;
-import com.android.nfc.R;
-
 import java.util.ArrayList;
 import java.util.Arrays;
 
@@ -61,20 +53,19 @@
     final BluetoothDevice mDevice;
 
     final Uri[] mUris;
-    final HandoverPowerManager mHandoverPowerManager;
     final boolean mRemoteActivating;
     final Handler mHandler;
+    final Long mCreateTime;
 
     int mState;
-    Long mStartTime;
 
     public BluetoothOppHandover(Context context, BluetoothDevice device, Uri[] uris,
-            HandoverPowerManager powerManager, boolean remoteActivating) {
+            boolean remoteActivating) {
         mContext = context;
         mDevice = device;
         mUris = uris;
-        mHandoverPowerManager = powerManager;
         mRemoteActivating = remoteActivating;
+        mCreateTime = SystemClock.elapsedRealtime();
 
         mHandler = new Handler(context.getMainLooper(),this);
         mState = STATE_INIT;
@@ -104,33 +95,24 @@
      * to begin the BT sequence. Must be called on Main thread.
      */
     public void start() {
-        mStartTime = SystemClock.elapsedRealtime();
-
-        IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
-        mContext.registerReceiver(mReceiver, filter);
-
-        if (!mHandoverPowerManager.isBluetoothEnabled()) {
-           if (mHandoverPowerManager.enableBluetooth()) {
-               mState = STATE_TURNING_ON;
-           } else {
-               Toast.makeText(mContext, mContext.getString(R.string.beam_failed),
-                       Toast.LENGTH_SHORT).show();
-               complete();
-           }
-        } else {
-            // BT already enabled
-            if (mRemoteActivating) {
-                mHandler.sendEmptyMessageDelayed(MSG_START_SEND, REMOTE_BT_ENABLE_DELAY_MS);
+        if (mRemoteActivating) {
+            Long timeElapsed = SystemClock.elapsedRealtime() - mCreateTime;
+            if (timeElapsed < REMOTE_BT_ENABLE_DELAY_MS) {
+                mHandler.sendEmptyMessageDelayed(MSG_START_SEND,
+                        REMOTE_BT_ENABLE_DELAY_MS - timeElapsed);
             } else {
-                // Remote BT enabled too, start send immediately
+                // Already waited long enough for BT to come up
+                // - start send.
                 sendIntent();
             }
+        } else {
+            // Remote BT enabled already, start send immediately
+            sendIntent();
         }
     }
 
     void complete() {
         mState = STATE_COMPLETE;
-        mContext.unregisterReceiver(mReceiver);
     }
 
     void sendIntent() {
@@ -153,32 +135,6 @@
         complete();
     }
 
-    void handleIntent(Intent intent) {
-        String action = intent.getAction();
-        if (BluetoothAdapter.ACTION_STATE_CHANGED.equals(action) && mState == STATE_TURNING_ON) {
-            int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
-            if (state == BluetoothAdapter.STATE_ON) {
-                // Add additional delay if needed
-                Long timeElapsed = SystemClock.elapsedRealtime() - mStartTime;
-                if (mRemoteActivating && timeElapsed < REMOTE_BT_ENABLE_DELAY_MS) {
-                    mHandler.sendEmptyMessageDelayed(MSG_START_SEND,
-                            REMOTE_BT_ENABLE_DELAY_MS - timeElapsed);
-                } else {
-                    sendIntent();
-                }
-            } else if (state == BluetoothAdapter.STATE_OFF) {
-                complete();
-            }
-            return;
-        }
-    }
-
-    final BroadcastReceiver mReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            handleIntent(intent);
-        }
-    };
 
     @Override
     public boolean handleMessage(Message msg) {
diff --git a/src/com/android/nfc/handover/HandoverManager.java b/src/com/android/nfc/handover/HandoverManager.java
index e7e807d..6d2271a 100644
--- a/src/com/android/nfc/handover/HandoverManager.java
+++ b/src/com/android/nfc/handover/HandoverManager.java
@@ -16,134 +16,71 @@
 
 package com.android.nfc.handover;
 
-import java.io.File;
 import java.nio.BufferUnderflowException;
 import java.nio.ByteBuffer;
 import java.nio.charset.Charset;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Date;
 import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
 import java.util.Random;
 
-import android.app.Notification;
-import android.app.NotificationManager;
-import android.app.PendingIntent;
-import android.app.Notification.Builder;
 import android.bluetooth.BluetoothAdapter;
 import android.bluetooth.BluetoothDevice;
 import android.content.BroadcastReceiver;
-import android.content.ContentResolver;
+import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.media.MediaScannerConnection;
+import android.content.ServiceConnection;
 import android.net.Uri;
 import android.nfc.FormatException;
 import android.nfc.NdefMessage;
 import android.nfc.NdefRecord;
-import android.os.Environment;
+import android.os.Bundle;
 import android.os.Handler;
+import android.os.IBinder;
 import android.os.Message;
-import android.os.SystemClock;
+import android.os.Messenger;
+import android.os.RemoteException;
 import android.os.UserHandle;
 import android.util.Log;
-import android.util.Pair;
-
-import com.android.nfc.NfcService;
-import com.android.nfc.R;
-
 
 /**
  * Manages handover of NFC to other technologies.
  */
-public class HandoverManager implements BluetoothHeadsetHandover.Callback {
+public class HandoverManager {
     static final String TAG = "NfcHandover";
     static final boolean DBG = true;
 
+    static final String ACTION_WHITELIST_DEVICE =
+            "android.btopp.intent.action.WHITELIST_DEVICE";
+
     static final byte[] TYPE_NOKIA = "nokia.com:bt".getBytes(Charset.forName("US_ASCII"));
     static final byte[] TYPE_BT_OOB = "application/vnd.bluetooth.ep.oob".
             getBytes(Charset.forName("US_ASCII"));
 
     static final byte[] RTD_COLLISION_RESOLUTION = {0x63, 0x72}; // "cr";
 
-    static final String ACTION_BT_OPP_TRANSFER_PROGRESS =
-            "android.btopp.intent.action.BT_OPP_TRANSFER_PROGRESS";
-
-    static final String ACTION_BT_OPP_TRANSFER_DONE =
-            "android.btopp.intent.action.BT_OPP_TRANSFER_DONE";
-
-    static final String EXTRA_BT_OPP_TRANSFER_STATUS =
-            "android.btopp.intent.extra.BT_OPP_TRANSFER_STATUS";
-
-    static final String EXTRA_BT_OPP_TRANSFER_MIMETYPE =
-            "android.btopp.intent.extra.BT_OPP_TRANSFER_MIMETYPE";
-
-    static final String EXTRA_BT_OPP_ADDRESS =
-            "android.btopp.intent.extra.BT_OPP_ADDRESS";
-
-    static final int HANDOVER_TRANSFER_STATUS_SUCCESS = 0;
-
-    static final int HANDOVER_TRANSFER_STATUS_FAILURE = 1;
-
-    static final String EXTRA_BT_OPP_TRANSFER_DIRECTION =
-            "android.btopp.intent.extra.BT_OPP_TRANSFER_DIRECTION";
-
-    static final int DIRECTION_BLUETOOTH_INCOMING = 0;
-
-    static final int DIRECTION_BLUETOOTH_OUTGOING = 1;
-
-    static final String EXTRA_BT_OPP_TRANSFER_ID =
-            "android.btopp.intent.extra.BT_OPP_TRANSFER_ID";
-
-    static final String EXTRA_BT_OPP_TRANSFER_PROGRESS =
-            "android.btopp.intent.extra.BT_OPP_TRANSFER_PROGRESS";
-
-    static final String EXTRA_BT_OPP_TRANSFER_URI =
-            "android.btopp.intent.extra.BT_OPP_TRANSFER_URI";
-
-    // permission needed to be able to receive handover status requests
-    static final String HANDOVER_STATUS_PERMISSION =
-            "com.android.permission.HANDOVER_STATUS";
-
-    static final int MSG_HANDOVER_POWER_CHECK = 0;
-
-    // We poll whether we can safely disable BT every POWER_CHECK_MS
-    static final int POWER_CHECK_MS = 20000;
-
-    static final String ACTION_WHITELIST_DEVICE =
-            "android.btopp.intent.action.WHITELIST_DEVICE";
-
-    static final String ACTION_CANCEL_HANDOVER_TRANSFER =
-            "com.android.nfc.handover.action.CANCEL_HANDOVER_TRANSFER";
-    static final String EXTRA_SOURCE_ADDRESS =
-            "com.android.nfc.handover.extra.SOURCE_ADDRESS";
-
-    static final int SOURCE_BLUETOOTH_INCOMING = 0;
-
-    static final int SOURCE_BLUETOOTH_OUTGOING = 1;
-
     static final int CARRIER_POWER_STATE_INACTIVE = 0;
     static final int CARRIER_POWER_STATE_ACTIVE = 1;
     static final int CARRIER_POWER_STATE_ACTIVATING = 2;
     static final int CARRIER_POWER_STATE_UNKNOWN = 3;
 
+    static final int MSG_HANDOVER_COMPLETE = 0;
+    static final int MSG_HEADSET_CONNECTED = 1;
+    static final int MSG_HEADSET_NOT_CONNECTED = 2;
+
     final Context mContext;
     final BluetoothAdapter mBluetoothAdapter;
-    final NotificationManager mNotificationManager;
-    final HandoverPowerManager mHandoverPowerManager;
+    final Messenger mMessenger = new Messenger (new MessageHandler());
 
-    // Variables below synchronized on HandoverManager.this
-    final HashMap<Pair<String, Boolean>, HandoverTransfer> mTransfers;
-
-    BluetoothHeadsetHandover mBluetoothHeadsetHandover;
+    final Object mLock = new Object();
+    // Variables below synchronized on mLock
+    HashMap<Integer, PendingHandoverTransfer> mPendingTransfers;
     boolean mBluetoothHeadsetConnected;
-
+    int mHandoverTransferId;
+    Messenger mService = null;
+    boolean mBound;
     String mLocalBluetoothAddress;
-    int mNotificationId;
 
     static class BluetoothHandoverData {
         public boolean valid = false;
@@ -152,487 +89,93 @@
         public boolean carrierActivating = false;
     }
 
-    class HandoverPowerManager implements Handler.Callback {
-        final Handler handler;
-        final Context context;
-
-        public HandoverPowerManager(Context context) {
-            this.handler = new Handler(this);
-            this.context = context;
-        }
-
-        /**
-         * Enables Bluetooth and will automatically disable it
-         * when there is no Bluetooth activity intitiated by NFC
-         * anymore.
-         */
-        synchronized boolean enableBluetooth() {
-            // Enable BT
-            boolean result = mBluetoothAdapter.enableNoAutoConnect();
-
-            if (result) {
-                // Start polling for BT activity to make sure we eventually disable
-                // it again.
-                handler.sendEmptyMessageDelayed(MSG_HANDOVER_POWER_CHECK, POWER_CHECK_MS);
-            }
-            return result;
-        }
-
-        synchronized boolean isBluetoothEnabled() {
-            return mBluetoothAdapter.isEnabled();
-        }
-
-        synchronized void resetTimer() {
-            if (handler.hasMessages(MSG_HANDOVER_POWER_CHECK)) {
-                handler.removeMessages(MSG_HANDOVER_POWER_CHECK);
-                handler.sendEmptyMessageDelayed(MSG_HANDOVER_POWER_CHECK, POWER_CHECK_MS);
+    class MessageHandler extends Handler {
+        @Override
+        public void handleMessage(Message msg) {
+            synchronized (mLock) {
+                switch (msg.what) {
+                    case MSG_HANDOVER_COMPLETE:
+                        int transferId = msg.arg1;
+                        Log.d(TAG, "Completed transfer id: " + Integer.toString(transferId));
+                        if (mPendingTransfers.containsKey(transferId)) {
+                            mPendingTransfers.remove(transferId);
+                        } else {
+                            Log.e(TAG, "Could not find completed transfer id: " + Integer.toString(transferId));
+                        }
+                        break;
+                    case MSG_HEADSET_CONNECTED:
+                        mBluetoothHeadsetConnected = true;
+                        break;
+                    case MSG_HEADSET_NOT_CONNECTED:
+                        mBluetoothHeadsetConnected = false;
+                        break;
+                    default:
+                        break;
+                }
             }
         }
+    };
 
-        void stopMonitoring() {
-            handler.removeMessages(MSG_HANDOVER_POWER_CHECK);
+    private ServiceConnection mConnection = new ServiceConnection() {
+        @Override
+        public void onServiceConnected(ComponentName name, IBinder service) {
+            synchronized (mLock) {
+                mService = new Messenger(service);
+                mBound = true;
+                // Register this client
+                Message msg = Message.obtain(null, HandoverService.MSG_REGISTER_CLIENT);
+                msg.replyTo = mMessenger;
+                try {
+                    mService.send(msg);
+                } catch (RemoteException e) {
+                    Log.e(TAG, "Failed to register client");
+                }
+            }
         }
 
         @Override
-        public boolean handleMessage(Message msg) {
-            switch (msg.what) {
-                case MSG_HANDOVER_POWER_CHECK:
-                    // Check for any alive transfers
-                    boolean transferAlive = false;
-                    synchronized (HandoverManager.this) {
-                        for (HandoverTransfer transfer : mTransfers.values()) {
-                            if (transfer.isRunning()) {
-                                transferAlive = true;
-                            }
-                        }
-
-                        if (!transferAlive && !mBluetoothHeadsetConnected) {
-                            mBluetoothAdapter.disable();
-                            handler.removeMessages(MSG_HANDOVER_POWER_CHECK);
-                        } else {
-                            handler.sendEmptyMessageDelayed(MSG_HANDOVER_POWER_CHECK, POWER_CHECK_MS);
-                        }
+        public void onServiceDisconnected(ComponentName name) {
+            synchronized (mLock) {
+                if (mBound) {
+                    try {
+                        Message msg = Message.obtain(null, HandoverService.MSG_DEREGISTER_CLIENT);
+                        msg.replyTo = mMessenger;
+                        mService.send(msg);
+                    } catch (RemoteException e) {
+                        // Service may have crashed - ignore
                     }
-                    return true;
-            }
-            return false;
-        }
-    }
-
-    /**
-     * A HandoverTransfer object represents a set of files
-     * that were received through NFC connection handover
-     * from the same source address.
-     *
-     * For Bluetooth, files are received through OPP, and
-     * we have no knowledge how many files will be transferred
-     * as part of a single transaction.
-     * Hence, a transfer has a notion of being "alive": if
-     * the last update to a transfer was within WAIT_FOR_NEXT_TRANSFER_MS
-     * milliseconds, we consider a new file transfer from the
-     * same source address as part of the same transfer.
-     * The corresponding URIs will be grouped in a single folder.
-     *
-     */
-    class HandoverTransfer implements Handler.Callback,
-            MediaScannerConnection.OnScanCompletedListener {
-        // In the states below we still accept new file transfer
-        static final int STATE_NEW = 0;
-        static final int STATE_IN_PROGRESS = 1;
-        static final int STATE_W4_NEXT_TRANSFER = 2;
-
-        // In the states below no new files are accepted.
-        static final int STATE_W4_MEDIA_SCANNER = 3;
-        static final int STATE_FAILED = 4;
-        static final int STATE_SUCCESS = 5;
-        static final int STATE_CANCELLED = 6;
-
-        static final int MSG_NEXT_TRANSFER_TIMER = 0;
-        static final int MSG_TRANSFER_TIMEOUT = 1;
-
-        // We need to receive an update within this time period
-        // to still consider this transfer to be "alive" (ie
-        // a reason to keep the handover transport enabled).
-        static final int ALIVE_CHECK_MS = 20000;
-
-        // The amount of time to wait for a new transfer
-        // once the current one completes.
-        static final int WAIT_FOR_NEXT_TRANSFER_MS = 4000;
-
-        static final String BEAM_DIR = "beam";
-
-        final BluetoothDevice device;
-        final String sourceAddress;
-        final boolean incoming;  // whether this is an incoming transfer
-        final int notificationId; // Unique ID of this transfer used for notifications
-        final Handler handler;
-        final PendingIntent cancelIntent;
-
-        int state;
-        Long lastUpdate; // Last time an event occurred for this transfer
-        float progress; // Progress in range [0..1]
-        ArrayList<Uri> btUris; // Received uris from Bluetooth OPP
-        ArrayList<String> btMimeTypes; // Mime-types received from Bluetooth OPP
-
-        ArrayList<String> paths; // Raw paths on the filesystem for Beam-stored files
-        HashMap<String, String> mimeTypes; // Mime-types associated with each path
-        HashMap<String, Uri> mediaUris; // URIs found by the media scanner for each path
-        int urisScanned;
-
-        public HandoverTransfer(String sourceAddress, boolean incoming) {
-            synchronized (HandoverManager.this) {
-                this.notificationId = mNotificationId++;
-            }
-            this.lastUpdate = SystemClock.elapsedRealtime();
-            this.progress = 0.0f;
-            this.state = STATE_NEW;
-            this.btUris = new ArrayList<Uri>();
-            this.btMimeTypes = new ArrayList<String>();
-            this.paths = new ArrayList<String>();
-            this.mimeTypes = new HashMap<String, String>();
-            this.mediaUris = new HashMap<String, Uri>();
-            this.sourceAddress = sourceAddress;
-            this.incoming = incoming;
-            this.handler = new Handler(mContext.getMainLooper(), this);
-            this.cancelIntent = buildCancelIntent();
-            this.urisScanned = 0;
-            this.device = mBluetoothAdapter.getRemoteDevice(sourceAddress);
-
-            handler.sendEmptyMessageDelayed(MSG_TRANSFER_TIMEOUT, ALIVE_CHECK_MS);
-        }
-
-        public synchronized void updateFileProgress(float progress) {
-            if (!isRunning()) return; // Ignore when we're no longer running
-
-            handler.removeMessages(MSG_NEXT_TRANSFER_TIMER);
-
-            this.progress = progress;
-
-            // We're still receiving data from this device - keep it in
-            // the whitelist for a while longer
-            if (incoming) whitelistOppDevice(device);
-
-            updateStateAndNotification(STATE_IN_PROGRESS);
-        }
-
-        public synchronized void finishTransfer(boolean success, Uri uri, String mimeType) {
-            if (!isRunning()) return; // Ignore when we're no longer running
-
-            if (success && uri != null) {
-                if (DBG) Log.d(TAG, "Transfer success, uri " + uri + " mimeType " + mimeType);
-                this.progress = 1.0f;
-                if (mimeType == null) {
-                    mimeType = BluetoothOppHandover.getMimeTypeForUri(mContext, uri);
                 }
-                if (mimeType != null) {
-                    btUris.add(uri);
-                    btMimeTypes.add(mimeType);
-                } else {
-                    if (DBG) Log.d(TAG, "Could not get mimeType for file.");
-                }
-            } else {
-                Log.e(TAG, "Handover transfer failed");
-                // Do wait to see if there's another file coming.
-            }
-            handler.removeMessages(MSG_NEXT_TRANSFER_TIMER);
-            handler.sendEmptyMessageDelayed(MSG_NEXT_TRANSFER_TIMER, WAIT_FOR_NEXT_TRANSFER_MS);
-            updateStateAndNotification(STATE_W4_NEXT_TRANSFER);
-        }
-
-        public synchronized boolean isRunning() {
-            if (state != STATE_NEW && state != STATE_IN_PROGRESS && state != STATE_W4_NEXT_TRANSFER) {
-                return false;
-            } else {
-                return true;
+                mService = null;
+                mBound = false;
             }
         }
-
-        synchronized void cancel() {
-            if (!isRunning()) return;
-
-            // Delete all files received so far
-            for (Uri uri : btUris) {
-                File file = new File(uri.getPath());
-                if (file.exists()) file.delete();
-            }
-
-            updateStateAndNotification(STATE_CANCELLED);
-        }
-
-        synchronized void updateNotification() {
-            if (!incoming) return; // No notifications for outgoing transfers
-
-            Builder notBuilder = new Notification.Builder(mContext);
-
-            if (state == STATE_NEW || state == STATE_IN_PROGRESS ||
-                    state == STATE_W4_NEXT_TRANSFER || state == STATE_W4_MEDIA_SCANNER) {
-                notBuilder.setAutoCancel(false);
-                notBuilder.setSmallIcon(android.R.drawable.stat_sys_download);
-                notBuilder.setTicker(mContext.getString(R.string.beam_progress));
-                notBuilder.setContentTitle(mContext.getString(R.string.beam_progress));
-                notBuilder.addAction(R.drawable.ic_menu_cancel_holo_dark,
-                        mContext.getString(R.string.cancel), cancelIntent);
-                notBuilder.setDeleteIntent(cancelIntent);
-                // We do have progress indication on a per-file basis, but in a multi-file
-                // transfer we don't know the total progress. So for now, just show an
-                // indeterminate progress bar.
-                notBuilder.setProgress(100, 0, true);
-            } else if (state == STATE_SUCCESS) {
-                notBuilder.setAutoCancel(true);
-                notBuilder.setSmallIcon(android.R.drawable.stat_sys_download_done);
-                notBuilder.setTicker(mContext.getString(R.string.beam_complete));
-                notBuilder.setContentTitle(mContext.getString(R.string.beam_complete));
-                notBuilder.setContentText(mContext.getString(R.string.beam_touch_to_view));
-
-                Intent viewIntent = buildViewIntent();
-                PendingIntent contentIntent = PendingIntent.getActivityAsUser(
-                        mContext, 0, viewIntent, 0, null, UserHandle.CURRENT);
-
-                notBuilder.setContentIntent(contentIntent);
-
-                // Play Beam success sound
-                NfcService.getInstance().playSound(NfcService.SOUND_END);
-            } else if (state == STATE_FAILED) {
-                notBuilder.setAutoCancel(false);
-                notBuilder.setSmallIcon(android.R.drawable.stat_sys_download_done);
-                notBuilder.setTicker(mContext.getString(R.string.beam_failed));
-                notBuilder.setContentTitle(mContext.getString(R.string.beam_failed));
-            } else if (state == STATE_CANCELLED) {
-                notBuilder.setAutoCancel(false);
-                notBuilder.setSmallIcon(android.R.drawable.stat_sys_download_done);
-                notBuilder.setTicker(mContext.getString(R.string.beam_canceled));
-                notBuilder.setContentTitle(mContext.getString(R.string.beam_canceled));
-            } else {
-                return;
-            }
-
-            mNotificationManager.notifyAsUser(null, mNotificationId, notBuilder.build(),
-                    UserHandle.CURRENT);
-        }
-
-        synchronized void updateStateAndNotification(int newState) {
-            this.state = newState;
-            this.lastUpdate = SystemClock.elapsedRealtime();
-
-            if (handler.hasMessages(MSG_TRANSFER_TIMEOUT)) {
-                // Update timeout timer
-                handler.removeMessages(MSG_TRANSFER_TIMEOUT);
-                handler.sendEmptyMessageDelayed(MSG_TRANSFER_TIMEOUT, ALIVE_CHECK_MS);
-            }
-            updateNotification();
-        }
-
-        synchronized void processFiles() {
-            // Check the amount of files we received in this transfer;
-            // If more than one, create a separate directory for it.
-            String extRoot = Environment.getExternalStorageDirectory().getPath();
-            File beamPath = new File(extRoot + "/" + BEAM_DIR);
-
-            if (!checkMediaStorage(beamPath) || btUris.size() == 0) {
-                Log.e(TAG, "Media storage not valid or no uris received.");
-                updateStateAndNotification(STATE_FAILED);
-                return;
-            }
-
-            if (btUris.size() > 1) {
-                beamPath = generateMultiplePath(extRoot + "/" + BEAM_DIR + "/");
-                if (!beamPath.isDirectory() && !beamPath.mkdir()) {
-                    Log.e(TAG, "Failed to create multiple path " + beamPath.toString());
-                    updateStateAndNotification(STATE_FAILED);
-                    return;
-                }
-            }
-
-            for (int i = 0; i < btUris.size(); i++) {
-                Uri uri = btUris.get(i);
-                String mimeType = btMimeTypes.get(i);
-
-                File srcFile = new File(uri.getPath());
-
-                File dstFile = generateUniqueDestination(beamPath.getAbsolutePath(),
-                        uri.getLastPathSegment());
-                if (!srcFile.renameTo(dstFile)) {
-                    if (DBG) Log.d(TAG, "Failed to rename from " + srcFile + " to " + dstFile);
-                    srcFile.delete();
-                    return;
-                } else {
-                    paths.add(dstFile.getAbsolutePath());
-                    mimeTypes.put(dstFile.getAbsolutePath(), mimeType);
-                    if (DBG) Log.d(TAG, "Did successful rename from " + srcFile + " to " + dstFile);
-                }
-            }
-
-            // We can either add files to the media provider, or provide an ACTION_VIEW
-            // intent to the file directly. We base this decision on the mime type
-            // of the first file; if it's media the platform can deal with,
-            // use the media provider, if it's something else, just launch an ACTION_VIEW
-            // on the file.
-            String mimeType = mimeTypes.get(paths.get(0));
-            if (mimeType.startsWith("image/") || mimeType.startsWith("video/") ||
-                    mimeType.startsWith("audio/")) {
-                String[] arrayPaths = new String[paths.size()];
-                MediaScannerConnection.scanFile(mContext, paths.toArray(arrayPaths), null, this);
-                updateStateAndNotification(STATE_W4_MEDIA_SCANNER);
-            } else {
-                // We're done.
-                updateStateAndNotification(STATE_SUCCESS);
-            }
-
-        }
-
-        public boolean handleMessage(Message msg) {
-            if (msg.what == MSG_NEXT_TRANSFER_TIMER) {
-                // We didn't receive a new transfer in time, finalize this one
-                if (incoming) {
-                    processFiles();
-                } else {
-                    updateStateAndNotification(STATE_SUCCESS);
-                }
-                return true;
-            } else if (msg.what == MSG_TRANSFER_TIMEOUT) {
-                // No update on this transfer for a while, check
-                // to see if it's still running, and fail it if it is.
-                if (isRunning()) {
-                    updateStateAndNotification(STATE_FAILED);
-                }
-            }
-            return false;
-        }
-
-        public synchronized void onScanCompleted(String path, Uri uri) {
-            if (DBG) Log.d(TAG, "Scan completed, path " + path + " uri " + uri);
-            if (uri != null) {
-                mediaUris.put(path, uri);
-            }
-            urisScanned++;
-            if (urisScanned == paths.size()) {
-                // We're done
-                updateStateAndNotification(STATE_SUCCESS);
-            }
-        }
-
-        boolean checkMediaStorage(File path) {
-            if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
-                if (!path.isDirectory() && !path.mkdir()) {
-                    Log.e(TAG, "Not dir or not mkdir " + path.getAbsolutePath());
-                    return false;
-                }
-                return true;
-            } else {
-                Log.e(TAG, "External storage not mounted, can't store file.");
-                return false;
-            }
-        }
-
-        synchronized Intent buildViewIntent() {
-            if (paths.size() == 0) return null;
-
-            Intent viewIntent = new Intent(Intent.ACTION_VIEW);
-
-            String filePath = paths.get(0);
-            Uri mediaUri = mediaUris.get(filePath);
-            Uri uri =  mediaUri != null ? mediaUri :
-                Uri.parse(ContentResolver.SCHEME_FILE + "://" + filePath);
-            viewIntent.setDataAndTypeAndNormalize(uri, mimeTypes.get(filePath));
-            viewIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-            return viewIntent;
-        }
-
-        PendingIntent buildCancelIntent() {
-            Intent intent = new Intent(ACTION_CANCEL_HANDOVER_TRANSFER);
-            intent.putExtra(EXTRA_SOURCE_ADDRESS, sourceAddress);
-            PendingIntent pi = PendingIntent.getBroadcast(mContext, 0, intent, 0);
-
-            return pi;
-        }
-
-        synchronized File generateUniqueDestination(String path, String fileName) {
-            int dotIndex = fileName.lastIndexOf(".");
-            String extension = null;
-            String fileNameWithoutExtension = null;
-            if (dotIndex < 0) {
-                extension = "";
-                fileNameWithoutExtension = fileName;
-            } else {
-                extension = fileName.substring(dotIndex);
-                fileNameWithoutExtension = fileName.substring(0, dotIndex);
-            }
-            File dstFile = new File(path + File.separator + fileName);
-            int count = 0;
-            while (dstFile.exists()) {
-                dstFile = new File(path + File.separator + fileNameWithoutExtension + "-" +
-                        Integer.toString(count) + extension);
-                count++;
-            }
-            return dstFile;
-        }
-
-        synchronized File generateMultiplePath(String beamRoot) {
-            // Generate a unique directory with the date
-            String format = "yyyy-MM-dd";
-            SimpleDateFormat sdf = new SimpleDateFormat(format);
-            String newPath = beamRoot + "beam-" + sdf.format(new Date());
-            File newFile = new File(newPath);
-            int count = 0;
-            while (newFile.exists()) {
-                newPath = beamRoot + "beam-" + sdf.format(new Date()) + "-" +
-                        Integer.toString(count);
-                newFile = new File(newPath);
-                count++;
-            }
-
-            return newFile;
-        }
-    }
-
-    synchronized HandoverTransfer getOrCreateHandoverTransfer(String sourceAddress, boolean incoming,
-            boolean create) {
-        Pair<String, Boolean> key = new Pair<String, Boolean>(sourceAddress, incoming);
-        if (mTransfers.containsKey(key)) {
-            HandoverTransfer transfer = mTransfers.get(key);
-            if (transfer.isRunning()) {
-                return transfer;
-            } else {
-                if (create) mTransfers.remove(key); // new one created below
-            }
-        }
-        if (create) {
-            HandoverTransfer transfer = new HandoverTransfer(sourceAddress, incoming);
-            mTransfers.put(key, transfer);
-
-            return transfer;
-        } else {
-            return null;
-        }
-    }
+    };
 
     public HandoverManager(Context context) {
         mContext = context;
         mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
 
-        mNotificationManager = (NotificationManager) mContext.getSystemService(
-                Context.NOTIFICATION_SERVICE);
+        mPendingTransfers = new HashMap<Integer, PendingHandoverTransfer>();
 
-        mTransfers = new HashMap<Pair<String, Boolean>, HandoverTransfer>();
-        mHandoverPowerManager = new HandoverPowerManager(context);
+        IntentFilter filter = new IntentFilter(Intent.ACTION_USER_SWITCHED);
+        mContext.registerReceiver(mReceiver, filter, null, null);
 
-        IntentFilter filter = new IntentFilter(ACTION_BT_OPP_TRANSFER_DONE);
-        filter.addAction(ACTION_BT_OPP_TRANSFER_PROGRESS);
-        filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
-        filter.addAction(ACTION_CANCEL_HANDOVER_TRANSFER);
-        mContext.registerReceiver(mReceiver, filter, HANDOVER_STATUS_PERMISSION, null);
+        mContext.bindService(new Intent(mContext, HandoverService.class), mConnection,
+                Context.BIND_AUTO_CREATE, UserHandle.USER_CURRENT);
     }
 
-    synchronized void cleanupTransfers() {
-        Iterator<Map.Entry<Pair<String, Boolean>, HandoverTransfer>> it = mTransfers.entrySet().iterator();
-        while (it.hasNext()) {
-            Map.Entry<Pair<String, Boolean>, HandoverTransfer> pair = it.next();
-            HandoverTransfer transfer = pair.getValue();
-            if (!transfer.isRunning()) {
-                it.remove();
+    final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            String action = intent.getAction();
+            if (action.equals(Intent.ACTION_USER_SWITCHED)) {
+                // Re-bind a service for the current user
+                mContext.unbindService(mConnection);
+                mContext.bindService(new Intent(mContext, HandoverService.class), mConnection,
+                        Context.BIND_AUTO_CREATE, UserHandle.USER_CURRENT);
             }
         }
-    }
+    };
 
     static NdefRecord createCollisionRecord() {
         byte[] random = new byte[2];
@@ -659,7 +202,7 @@
         payload[0] = (byte) (payload.length & 0xFF);
         payload[1] = (byte) ((payload.length >> 8) & 0xFF);
 
-        synchronized (HandoverManager.this) {
+        synchronized (mLock) {
             if (mLocalBluetoothAddress == null) {
                 mLocalBluetoothAddress = mBluetoothAdapter.getAddress();
             }
@@ -698,7 +241,6 @@
         payload.get(payloadBytes);
         return new NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_HANDOVER_SELECT, null,
                 payloadBytes);
-
     }
 
     NdefRecord createHandoverRequestRecord() {
@@ -742,24 +284,32 @@
         }
         if (bluetoothData == null) return null;
 
-        boolean bluetoothActivating = false;
-
-        synchronized(HandoverManager.this) {
-            if (!mHandoverPowerManager.isBluetoothEnabled()) {
-                if (!mHandoverPowerManager.enableBluetooth()) {
-                    return null;
-                }
-                bluetoothActivating = true;
-            } else {
-                mHandoverPowerManager.resetTimer();
+        // Note: there could be a race where we conclude
+        // that Bluetooth is already enabled, and shortly
+        // after the user turns it off. That will cause
+        // the transfer to fail, but there's nothing
+        // much we can do about it anyway. It shouldn't
+        // be common for the user to be changing BT settings
+        // while waiting to receive a picture.
+        boolean bluetoothActivating = !mBluetoothAdapter.isEnabled();
+        synchronized (mLock) {
+            if (!mBound) {
+                Log.e(TAG, "Could not connect to handover service");
+                return null;
             }
-
-            // Create the initial transfer object
-            HandoverTransfer transfer = getOrCreateHandoverTransfer(
-                    bluetoothData.device.getAddress(), true, true);
-            transfer.updateNotification();
+            Message msg = Message.obtain(null, HandoverService.MSG_START_INCOMING_TRANSFER);
+            PendingHandoverTransfer transfer = registerInTransferLocked(bluetoothData.device);
+            Bundle transferData = new Bundle();
+            transferData.putParcelable(HandoverService.BUNDLE_TRANSFER, transfer);
+            msg.setData(transferData);
+            try {
+                mService.send(msg);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Could not connect to handover service");
+               removeTransferLocked(transfer.id);
+               return null;
+            }
         }
-
         // BT OOB found, whitelist it for incoming OPP data
         whitelistOppDevice(bluetoothData.device);
 
@@ -767,13 +317,6 @@
         return (createHandoverSelectMessage(bluetoothActivating));
     }
 
-    void whitelistOppDevice(BluetoothDevice device) {
-        if (DBG) Log.d(TAG, "Whitelisting " + device + " for BT OPP");
-        Intent intent = new Intent(ACTION_WHITELIST_DEVICE);
-        intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
-        mContext.sendBroadcast(intent);
-    }
-
     public boolean tryHandover(NdefMessage m) {
         if (m == null) return false;
         if (mBluetoothAdapter == null) return false;
@@ -784,18 +327,26 @@
         if (handover == null) return false;
         if (!handover.valid) return true;
 
-        synchronized (HandoverManager.this) {
+        synchronized (mLock) {
             if (mBluetoothAdapter == null) {
                 if (DBG) Log.d(TAG, "BT handover, but BT not available");
                 return true;
             }
-            if (mBluetoothHeadsetHandover != null) {
-                if (DBG) Log.d(TAG, "BT handover already in progress, ignoring");
-                return true;
+            if (!mBound) {
+                Log.e(TAG, "Could not connect to handover service");
+                return false;
             }
-            mBluetoothHeadsetHandover = new BluetoothHeadsetHandover(mContext, handover.device,
-                    handover.name, mHandoverPowerManager, this);
-            mBluetoothHeadsetHandover.start();
+
+            Message msg = Message.obtain(null, HandoverService.MSG_HEADSET_HANDOVER, 0, 0);
+            Bundle headsetData = new Bundle();
+            headsetData.putParcelable(HandoverService.EXTRA_HEADSET_DEVICE, handover.device);
+            headsetData.putString(HandoverService.EXTRA_HEADSET_NAME, handover.name);
+            msg.setData(headsetData);
+            try {
+                mService.send(msg);
+            } catch (RemoteException e) {
+                return false;
+            }
         }
         return true;
     }
@@ -807,13 +358,53 @@
         BluetoothHandoverData data = parse(m);
         if (data != null && data.valid) {
             // Register a new handover transfer object
-            getOrCreateHandoverTransfer(data.device.getAddress(), false, true);
-            BluetoothOppHandover handover = new BluetoothOppHandover(mContext, data.device,
-                uris, mHandoverPowerManager, data.carrierActivating);
-            handover.start();
+            synchronized (mLock) {
+                if (!mBound) {
+                    Log.e(TAG, "Could not connect to handover service");
+                    return;
+                }
+
+                Message msg = Message.obtain(null, HandoverService.MSG_START_OUTGOING_TRANSFER, 0, 0);
+                PendingHandoverTransfer transfer = registerOutTransferLocked(data, uris);
+                Bundle transferData = new Bundle();
+                transferData.putParcelable(HandoverService.BUNDLE_TRANSFER, transfer);
+                msg.setData(transferData);
+                try {
+                    mService.send(msg);
+                } catch (RemoteException e) {
+                    removeTransferLocked(transfer.id);
+                }
+            }
         }
     }
 
+    PendingHandoverTransfer registerInTransferLocked(BluetoothDevice remoteDevice) {
+        PendingHandoverTransfer transfer = new PendingHandoverTransfer(
+                mHandoverTransferId++, true, remoteDevice, false, null);
+        mPendingTransfers.put(transfer.id, transfer);
+
+        return transfer;
+    }
+
+    PendingHandoverTransfer registerOutTransferLocked(BluetoothHandoverData data,
+            Uri[] uris) {
+        PendingHandoverTransfer transfer = new PendingHandoverTransfer(
+                mHandoverTransferId++, false, data.device, data.carrierActivating, uris);
+        mPendingTransfers.put(transfer.id, transfer);
+        return transfer;
+    }
+
+    void removeTransferLocked(int id) {
+        mPendingTransfers.remove(id);
+    }
+
+    void whitelistOppDevice(BluetoothDevice device) {
+        if (DBG) Log.d(TAG, "Whitelisting " + device + " for BT OPP");
+        Intent intent = new Intent(ACTION_WHITELIST_DEVICE);
+        intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
+        mContext.sendBroadcastAsUser(intent, UserHandle.CURRENT);
+    }
+
     boolean isCarrierActivating(NdefRecord handoverRec, byte[] carrierId) {
         byte[] payload = handoverRec.getPayload();
         if (payload == null || payload.length <= 1) return false;
@@ -972,79 +563,4 @@
 
         return result;
     }
-
-    @Override
-    public void onBluetoothHeadsetHandoverComplete(boolean connected) {
-        synchronized (HandoverManager.this) {
-            mBluetoothHeadsetHandover = null;
-            mBluetoothHeadsetConnected = connected;
-        }
-    }
-
-    final BroadcastReceiver mReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            String action = intent.getAction();
-
-            if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
-                int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
-                if (state == BluetoothAdapter.STATE_OFF) {
-                    mHandoverPowerManager.stopMonitoring();
-                }
-
-                return;
-            } else if (action.equals(ACTION_CANCEL_HANDOVER_TRANSFER)) {
-                String sourceAddress = intent.getStringExtra(EXTRA_SOURCE_ADDRESS);
-                HandoverTransfer transfer = getOrCreateHandoverTransfer(sourceAddress, true,
-                        false);
-                if (transfer != null) {
-                    transfer.cancel();
-                }
-            } else if (action.equals(ACTION_BT_OPP_TRANSFER_PROGRESS) ||
-                    action.equals(ACTION_BT_OPP_TRANSFER_DONE)) {
-                // Clean up old transfers no longer in progress
-                cleanupTransfers();
-
-                int direction = intent.getIntExtra(EXTRA_BT_OPP_TRANSFER_DIRECTION, -1);
-                int id = intent.getIntExtra(EXTRA_BT_OPP_TRANSFER_ID, -1);
-                String sourceAddress = intent.getStringExtra(EXTRA_BT_OPP_ADDRESS);
-
-                if (direction == -1 || id == -1 || sourceAddress == null) return;
-                boolean incoming = (direction == DIRECTION_BLUETOOTH_INCOMING);
-
-                HandoverTransfer transfer = getOrCreateHandoverTransfer(sourceAddress, incoming,
-                        false);
-                if (transfer == null) {
-                    // There is no transfer running for this source address; most likely
-                    // the transfer was cancelled. We need to tell BT OPP to stop transferring
-                    // in case this was an incoming transfer
-                    Intent cancelIntent = new Intent("android.btopp.intent.action.STOP_HANDOVER_TRANSFER");
-                    cancelIntent.putExtra(EXTRA_BT_OPP_TRANSFER_ID, id);
-                    mContext.sendBroadcast(cancelIntent);
-                    return;
-                }
-
-                if (action.equals(ACTION_BT_OPP_TRANSFER_DONE)) {
-                    int handoverStatus = intent.getIntExtra(EXTRA_BT_OPP_TRANSFER_STATUS,
-                            HANDOVER_TRANSFER_STATUS_FAILURE);
-
-                    if (handoverStatus == HANDOVER_TRANSFER_STATUS_SUCCESS) {
-                        String uriString = intent.getStringExtra(EXTRA_BT_OPP_TRANSFER_URI);
-                        String mimeType = intent.getStringExtra(EXTRA_BT_OPP_TRANSFER_MIMETYPE);
-                        Uri uri = Uri.parse(uriString);
-                        if (uri.getScheme() == null) {
-                            uri = Uri.fromFile(new File(uri.getPath()));
-                        }
-                        transfer.finishTransfer(true, uri, mimeType);
-                    } else {
-                        transfer.finishTransfer(false, null, null);
-                    }
-                } else if (action.equals(ACTION_BT_OPP_TRANSFER_PROGRESS)) {
-                    float progress = intent.getFloatExtra(EXTRA_BT_OPP_TRANSFER_PROGRESS, 0.0f);
-                    transfer.updateFileProgress(progress);
-                }
-            }
-        }
-    };
-
 }
diff --git a/src/com/android/nfc/handover/HandoverServer.java b/src/com/android/nfc/handover/HandoverServer.java
index e789387..093d1dd 100644
--- a/src/com/android/nfc/handover/HandoverServer.java
+++ b/src/com/android/nfc/handover/HandoverServer.java
@@ -210,7 +210,8 @@
                         }
                         // We're done
                         mCallback.onHandoverRequestReceived();
-                        break;
+                        // We can process another handover transfer
+                        byteStream = new ByteArrayOutputStream();
                     }
 
                     synchronized (HandoverServer.this) {
diff --git a/src/com/android/nfc/handover/HandoverService.java b/src/com/android/nfc/handover/HandoverService.java
new file mode 100644
index 0000000..261cbca
--- /dev/null
+++ b/src/com/android/nfc/handover/HandoverService.java
@@ -0,0 +1,403 @@
+package com.android.nfc.handover;
+
+import android.app.Service;
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.media.AudioManager;
+import android.media.SoundPool;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Message;
+import android.os.Messenger;
+import android.os.RemoteException;
+import android.util.Log;
+import android.util.Pair;
+
+import com.android.nfc.R;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.Queue;
+
+public class HandoverService extends Service implements HandoverTransfer.Callback,
+        BluetoothHeadsetHandover.Callback {
+
+    static final String TAG = "HandoverService";
+
+    static final int MSG_REGISTER_CLIENT = 0;
+    static final int MSG_DEREGISTER_CLIENT = 1;
+    static final int MSG_START_INCOMING_TRANSFER = 2;
+    static final int MSG_START_OUTGOING_TRANSFER = 3;
+    static final int MSG_HEADSET_HANDOVER = 4;
+
+    static final String BUNDLE_TRANSFER = "transfer";
+
+    static final String EXTRA_HEADSET_DEVICE = "device";
+    static final String EXTRA_HEADSET_NAME = "headsetname";
+
+    static final String ACTION_CANCEL_HANDOVER_TRANSFER =
+            "com.android.nfc.handover.action.CANCEL_HANDOVER_TRANSFER";
+    static final String EXTRA_SOURCE_ADDRESS =
+            "com.android.nfc.handover.extra.SOURCE_ADDRESS";
+
+    static final String ACTION_BT_OPP_TRANSFER_PROGRESS =
+            "android.btopp.intent.action.BT_OPP_TRANSFER_PROGRESS";
+
+    static final String ACTION_BT_OPP_TRANSFER_DONE =
+            "android.btopp.intent.action.BT_OPP_TRANSFER_DONE";
+
+    static final String EXTRA_BT_OPP_TRANSFER_STATUS =
+            "android.btopp.intent.extra.BT_OPP_TRANSFER_STATUS";
+
+    static final String EXTRA_BT_OPP_TRANSFER_MIMETYPE =
+            "android.btopp.intent.extra.BT_OPP_TRANSFER_MIMETYPE";
+
+    static final String EXTRA_BT_OPP_ADDRESS =
+            "android.btopp.intent.extra.BT_OPP_ADDRESS";
+
+    static final int HANDOVER_TRANSFER_STATUS_SUCCESS = 0;
+
+    static final int HANDOVER_TRANSFER_STATUS_FAILURE = 1;
+
+    static final String EXTRA_BT_OPP_TRANSFER_DIRECTION =
+            "android.btopp.intent.extra.BT_OPP_TRANSFER_DIRECTION";
+
+    static final int DIRECTION_BLUETOOTH_INCOMING = 0;
+
+    static final int DIRECTION_BLUETOOTH_OUTGOING = 1;
+
+    static final String EXTRA_BT_OPP_TRANSFER_ID =
+            "android.btopp.intent.extra.BT_OPP_TRANSFER_ID";
+
+    static final String EXTRA_BT_OPP_TRANSFER_PROGRESS =
+            "android.btopp.intent.extra.BT_OPP_TRANSFER_PROGRESS";
+
+    static final String EXTRA_BT_OPP_TRANSFER_URI =
+            "android.btopp.intent.extra.BT_OPP_TRANSFER_URI";
+
+    // permission needed to be able to receive handover status requests
+    static final String HANDOVER_STATUS_PERMISSION =
+            "com.android.permission.HANDOVER_STATUS";
+
+    // Variables below only accessed on main thread
+    final Queue<BluetoothOppHandover> mPendingOutTransfers;
+    final HashMap<Pair<String, Boolean>, HandoverTransfer> mTransfers;
+    final Messenger mMessenger;
+
+    SoundPool mSoundPool;
+    int mSuccessSound;
+
+    BluetoothAdapter mBluetoothAdapter;
+    Messenger mClient;
+    Handler mHandler;
+    BluetoothHeadsetHandover mBluetoothHeadsetHandover;
+    boolean mBluetoothHeadsetConnected;
+    boolean mBluetoothEnabledByNfc;
+
+    public HandoverService() {
+        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
+        mPendingOutTransfers = new LinkedList<BluetoothOppHandover>();
+        mTransfers = new HashMap<Pair<String, Boolean>, HandoverTransfer>();
+        mHandler = new MessageHandler();
+        mMessenger = new Messenger(mHandler);
+        mBluetoothHeadsetConnected = false;
+        mBluetoothEnabledByNfc = false;
+    }
+
+    @Override
+    public void onCreate() {
+        super.onCreate();
+
+        mSoundPool = new SoundPool(1, AudioManager.STREAM_NOTIFICATION, 0);
+        mSuccessSound = mSoundPool.load(this, R.raw.end, 1);
+
+        IntentFilter filter = new IntentFilter(ACTION_BT_OPP_TRANSFER_DONE);
+        filter.addAction(ACTION_BT_OPP_TRANSFER_PROGRESS);
+        filter.addAction(ACTION_CANCEL_HANDOVER_TRANSFER);
+        filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
+        registerReceiver(mReceiver, filter, HANDOVER_STATUS_PERMISSION, mHandler);
+    }
+
+    @Override
+    public void onDestroy() {
+        super.onDestroy();
+        if (mSoundPool != null) {
+            mSoundPool.release();
+        }
+        unregisterReceiver(mReceiver);
+    }
+
+    void doOutgoingTransfer(Message msg) {
+        Bundle msgData = msg.getData();
+
+        msgData.setClassLoader(getClassLoader());
+        PendingHandoverTransfer pendingTransfer = (PendingHandoverTransfer)
+                msgData.getParcelable(BUNDLE_TRANSFER);
+        createHandoverTransfer(pendingTransfer);
+
+        // Create the actual transfer
+        BluetoothOppHandover handover = new BluetoothOppHandover(HandoverService.this,
+                pendingTransfer.remoteDevice, pendingTransfer.uris,
+                pendingTransfer.remoteActivating);
+        if (mBluetoothAdapter.isEnabled()) {
+            // Start the transfer
+            handover.start();
+        } else {
+            if (!enableBluetooth()) {
+                Log.e(TAG, "Error enabling Bluetooth.");
+                notifyClientTransferComplete(pendingTransfer.id);
+                return;
+            }
+            mPendingOutTransfers.add(handover);
+            // Queue the transfer and enable Bluetooth - when it is enabled
+            // the transfer will be started.
+        }
+    }
+
+    void doIncomingTransfer(Message msg) {
+        Bundle msgData = msg.getData();
+
+        msgData.setClassLoader(getClassLoader());
+        PendingHandoverTransfer pendingTransfer = (PendingHandoverTransfer)
+                msgData.getParcelable(BUNDLE_TRANSFER);
+        if (!mBluetoothAdapter.isEnabled() && !enableBluetooth()) {
+            Log.e(TAG, "Error enabling Bluetooth.");
+            notifyClientTransferComplete(pendingTransfer.id);
+            return;
+        }
+        createHandoverTransfer(pendingTransfer);
+        // Remote device will connect and finish the transfer
+    }
+
+    void doHeadsetHandover(Message msg) {
+        Bundle msgData = msg.getData();
+        BluetoothDevice device = (BluetoothDevice) msgData.getParcelable(EXTRA_HEADSET_DEVICE);
+        String name = (String) msgData.getString(EXTRA_HEADSET_NAME);
+        mBluetoothHeadsetHandover = new BluetoothHeadsetHandover(HandoverService.this,
+                device, name, HandoverService.this);
+        if (mBluetoothAdapter.isEnabled()) {
+            mBluetoothHeadsetHandover.start();
+        } else {
+            // Once BT is enabled, the headset pairing will be started
+            if (!enableBluetooth()) {
+                Log.e(TAG, "Error enabling Bluetooth.");
+                mBluetoothHeadsetHandover = null;
+            }
+        }
+    }
+
+    void startPendingTransfers() {
+        while (!mPendingOutTransfers.isEmpty()) {
+             BluetoothOppHandover handover = mPendingOutTransfers.remove();
+             handover.start();
+        }
+    }
+
+    class MessageHandler extends Handler {
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case MSG_REGISTER_CLIENT:
+                    mClient = msg.replyTo;
+                    break;
+                case MSG_DEREGISTER_CLIENT:
+                    mClient = null;
+                    break;
+                case MSG_START_INCOMING_TRANSFER:
+                    doIncomingTransfer(msg);
+                    break;
+                case MSG_START_OUTGOING_TRANSFER:
+                    doOutgoingTransfer(msg);
+                    break;
+                case MSG_HEADSET_HANDOVER:
+                    doHeadsetHandover(msg);
+                    break;
+            }
+        }
+    }
+
+    boolean enableBluetooth() {
+        if (!mBluetoothAdapter.isEnabled()) {
+            mBluetoothEnabledByNfc = true;
+            return mBluetoothAdapter.enableNoAutoConnect();
+        }
+        return true;
+    }
+
+    void disableBluetoothIfNeeded() {
+        if (!mBluetoothEnabledByNfc) return;
+
+        if (mTransfers.size() == 0 && !mBluetoothHeadsetConnected) {
+            mBluetoothAdapter.disable();
+            mBluetoothEnabledByNfc = false;
+        }
+    }
+
+    void createHandoverTransfer(PendingHandoverTransfer pendingTransfer) {
+        Pair<String, Boolean> key = new Pair<String, Boolean>(
+                pendingTransfer.remoteDevice.getAddress(), pendingTransfer.incoming);
+        if (mTransfers.containsKey(key)) {
+            HandoverTransfer transfer = mTransfers.get(key);
+            if (!transfer.isRunning()) {
+                mTransfers.remove(key); // new one created below
+            } else {
+                // There is already a transfer running to this
+                // device - it will automatically get combined
+                // with the existing transfer.
+                notifyClientTransferComplete(pendingTransfer.id);
+                return;
+            }
+        }
+
+        HandoverTransfer transfer = new HandoverTransfer(this, this, pendingTransfer);
+        mTransfers.put(key, transfer);
+        transfer.updateNotification();
+    }
+
+    HandoverTransfer findHandoverTransfer(String sourceAddress, boolean incoming) {
+        Pair<String, Boolean> key = new Pair<String, Boolean>(sourceAddress, incoming);
+        if (mTransfers.containsKey(key)) {
+            HandoverTransfer transfer = mTransfers.get(key);
+            if (transfer.isRunning()) {
+                return transfer;
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public IBinder onBind(Intent intent) {
+       return mMessenger.getBinder();
+    }
+
+    final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            String action = intent.getAction();
+            if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
+                int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
+                if (state == BluetoothAdapter.STATE_ON) {
+                    // If there is a pending headset pairing, start it
+                    if (mBluetoothHeadsetHandover != null &&
+                            !mBluetoothHeadsetHandover.hasStarted()) {
+                        mBluetoothHeadsetHandover.start();
+                    }
+
+                    // Start any pending transfers
+                    startPendingTransfers();
+                } else if (state == BluetoothAdapter.STATE_OFF) {
+                    mBluetoothEnabledByNfc = false;
+                    mBluetoothHeadsetConnected = false;
+                }
+            }
+            else if (action.equals(ACTION_CANCEL_HANDOVER_TRANSFER)) {
+                String sourceAddress = intent.getStringExtra(EXTRA_SOURCE_ADDRESS);
+                HandoverTransfer transfer = findHandoverTransfer(sourceAddress, true);
+                if (transfer != null) {
+                    transfer.cancel();
+                }
+            } else if (action.equals(ACTION_BT_OPP_TRANSFER_PROGRESS) ||
+                    action.equals(ACTION_BT_OPP_TRANSFER_DONE)) {
+                int direction = intent.getIntExtra(EXTRA_BT_OPP_TRANSFER_DIRECTION, -1);
+                int id = intent.getIntExtra(EXTRA_BT_OPP_TRANSFER_ID, -1);
+                String sourceAddress = intent.getStringExtra(EXTRA_BT_OPP_ADDRESS);
+
+                if (direction == -1 || id == -1 || sourceAddress == null) return;
+                boolean incoming = (direction == DIRECTION_BLUETOOTH_INCOMING);
+
+                HandoverTransfer transfer = findHandoverTransfer(sourceAddress, incoming);
+                if (transfer == null) {
+                    // There is no transfer running for this source address; most likely
+                    // the transfer was cancelled. We need to tell BT OPP to stop transferring
+                    // in case this was an incoming transfer
+                    Intent cancelIntent = new Intent("android.btopp.intent.action.STOP_HANDOVER_TRANSFER");
+                    cancelIntent.putExtra(EXTRA_BT_OPP_TRANSFER_ID, id);
+                    sendBroadcast(cancelIntent);
+                    return;
+                }
+
+                if (action.equals(ACTION_BT_OPP_TRANSFER_DONE)) {
+                    int handoverStatus = intent.getIntExtra(EXTRA_BT_OPP_TRANSFER_STATUS,
+                            HANDOVER_TRANSFER_STATUS_FAILURE);
+                    if (handoverStatus == HANDOVER_TRANSFER_STATUS_SUCCESS) {
+                        String uriString = intent.getStringExtra(EXTRA_BT_OPP_TRANSFER_URI);
+                        String mimeType = intent.getStringExtra(EXTRA_BT_OPP_TRANSFER_MIMETYPE);
+                        Uri uri = Uri.parse(uriString);
+                        if (uri.getScheme() == null) {
+                            uri = Uri.fromFile(new File(uri.getPath()));
+                        }
+                        transfer.finishTransfer(true, uri, mimeType);
+                    } else {
+                        transfer.finishTransfer(false, null, null);
+                    }
+                } else if (action.equals(ACTION_BT_OPP_TRANSFER_PROGRESS)) {
+                    float progress = intent.getFloatExtra(EXTRA_BT_OPP_TRANSFER_PROGRESS, 0.0f);
+                    transfer.updateFileProgress(progress);
+                }
+            }
+        }
+    };
+
+    void notifyClientTransferComplete(int transferId) {
+        if (mClient != null) {
+            Message msg = Message.obtain(null, HandoverManager.MSG_HANDOVER_COMPLETE);
+            msg.arg1 = transferId;
+            try {
+                mClient.send(msg);
+            } catch (RemoteException e) {
+                // Ignore
+            }
+        }
+    }
+
+    @Override
+    public void onTransferComplete(HandoverTransfer transfer, boolean success) {
+        // Called on the main thread
+
+        // First, remove the transfer from our list
+        Iterator it = mTransfers.entrySet().iterator();
+        while (it.hasNext()) {
+            Map.Entry hashPair = (Map.Entry)it.next();
+            HandoverTransfer transferEntry = (HandoverTransfer) hashPair.getValue();
+            if (transferEntry == transfer) {
+                it.remove();
+            }
+        }
+
+        // Notify any clients of the service
+        notifyClientTransferComplete(transfer.getTransferId());
+
+        // Play success sound
+        if (success) {
+            mSoundPool.play(mSuccessSound, 1.0f, 1.0f, 0, 0, 1.0f);
+        }
+        disableBluetoothIfNeeded();
+    }
+
+    @Override
+    public void onBluetoothHeadsetHandoverComplete(boolean connected) {
+        // Called on the main thread
+        mBluetoothHeadsetHandover = null;
+        mBluetoothHeadsetConnected = connected;
+        if (mClient != null) {
+            Message msg = Message.obtain(null,
+                    connected ? HandoverManager.MSG_HEADSET_CONNECTED
+                              : HandoverManager.MSG_HEADSET_NOT_CONNECTED);
+            try {
+                mClient.send(msg);
+            } catch (RemoteException e) {
+                // Ignore
+            }
+        }
+        disableBluetoothIfNeeded();
+    }
+}
diff --git a/src/com/android/nfc/handover/HandoverTransfer.java b/src/com/android/nfc/handover/HandoverTransfer.java
new file mode 100644
index 0000000..98b59a6
--- /dev/null
+++ b/src/com/android/nfc/handover/HandoverTransfer.java
@@ -0,0 +1,423 @@
+package com.android.nfc.handover;
+
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.app.Notification.Builder;
+import android.bluetooth.BluetoothDevice;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.media.MediaScannerConnection;
+import android.net.Uri;
+import android.os.Environment;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.os.SystemClock;
+import android.os.UserHandle;
+import android.util.Log;
+
+import com.android.nfc.R;
+
+import java.io.File;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+
+/**
+ * A HandoverTransfer object represents a set of files
+ * that were received through NFC connection handover
+ * from the same source address.
+ *
+ * For Bluetooth, files are received through OPP, and
+ * we have no knowledge how many files will be transferred
+ * as part of a single transaction.
+ * Hence, a transfer has a notion of being "alive": if
+ * the last update to a transfer was within WAIT_FOR_NEXT_TRANSFER_MS
+ * milliseconds, we consider a new file transfer from the
+ * same source address as part of the same transfer.
+ * The corresponding URIs will be grouped in a single folder.
+ *
+ */
+public class HandoverTransfer implements Handler.Callback,
+        MediaScannerConnection.OnScanCompletedListener {
+
+    interface Callback {
+        void onTransferComplete(HandoverTransfer transfer, boolean success);
+    };
+
+    static final String TAG = "HandoverTransfer";
+
+    static final Boolean DBG = true;
+
+    // In the states below we still accept new file transfer
+    static final int STATE_NEW = 0;
+    static final int STATE_IN_PROGRESS = 1;
+    static final int STATE_W4_NEXT_TRANSFER = 2;
+
+    // In the states below no new files are accepted.
+    static final int STATE_W4_MEDIA_SCANNER = 3;
+    static final int STATE_FAILED = 4;
+    static final int STATE_SUCCESS = 5;
+    static final int STATE_CANCELLED = 6;
+
+    static final int MSG_NEXT_TRANSFER_TIMER = 0;
+    static final int MSG_TRANSFER_TIMEOUT = 1;
+
+    // We need to receive an update within this time period
+    // to still consider this transfer to be "alive" (ie
+    // a reason to keep the handover transport enabled).
+    static final int ALIVE_CHECK_MS = 20000;
+
+    // The amount of time to wait for a new transfer
+    // once the current one completes.
+    static final int WAIT_FOR_NEXT_TRANSFER_MS = 4000;
+
+    static final String BEAM_DIR = "beam";
+
+    final boolean mIncoming;  // whether this is an incoming transfer
+    final int mTransferId; // Unique ID of this transfer used for notifications
+    final PendingIntent mCancelIntent;
+    final Context mContext;
+    final Handler mHandler;
+    final NotificationManager mNotificationManager;
+    final BluetoothDevice mRemoteDevice;
+    final Callback mCallback;
+
+    // Variables below are only accessed on the main thread
+    int mState;
+    boolean mCalledBack;
+    Long mLastUpdate; // Last time an event occurred for this transfer
+    float mProgress; // Progress in range [0..1]
+    ArrayList<Uri> mBtUris; // Received uris from Bluetooth OPP
+    ArrayList<String> mBtMimeTypes; // Mime-types received from Bluetooth OPP
+
+    ArrayList<String> mPaths; // Raw paths on the filesystem for Beam-stored files
+    HashMap<String, String> mMimeTypes; // Mime-types associated with each path
+    HashMap<String, Uri> mMediaUris; // URIs found by the media scanner for each path
+    int mUrisScanned;
+
+    public HandoverTransfer(Context context, Callback callback,
+            PendingHandoverTransfer pendingTransfer) {
+        mContext = context;
+        mCallback = callback;
+        mRemoteDevice = pendingTransfer.remoteDevice;
+        mIncoming = pendingTransfer.incoming;
+        mTransferId = pendingTransfer.id;
+        mLastUpdate = SystemClock.elapsedRealtime();
+        mProgress = 0.0f;
+        mState = STATE_NEW;
+        mBtUris = new ArrayList<Uri>();
+        mBtMimeTypes = new ArrayList<String>();
+        mPaths = new ArrayList<String>();
+        mMimeTypes = new HashMap<String, String>();
+        mMediaUris = new HashMap<String, Uri>();
+        mCancelIntent = buildCancelIntent();
+        mUrisScanned = 0;
+
+        mHandler = new Handler(Looper.getMainLooper(), this);
+        mHandler.sendEmptyMessageDelayed(MSG_TRANSFER_TIMEOUT, ALIVE_CHECK_MS);
+        mNotificationManager = (NotificationManager) mContext.getSystemService(
+                Context.NOTIFICATION_SERVICE);
+    }
+
+    void whitelistOppDevice(BluetoothDevice device) {
+        if (DBG) Log.d(TAG, "Whitelisting " + device + " for BT OPP");
+        Intent intent = new Intent(HandoverManager.ACTION_WHITELIST_DEVICE);
+        intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
+        mContext.sendBroadcastAsUser(intent, UserHandle.CURRENT);
+    }
+
+    public void updateFileProgress(float progress) {
+        if (!isRunning()) return; // Ignore when we're no longer running
+
+        mHandler.removeMessages(MSG_NEXT_TRANSFER_TIMER);
+
+        this.mProgress = progress;
+
+        // We're still receiving data from this device - keep it in
+        // the whitelist for a while longer
+        if (mIncoming) whitelistOppDevice(mRemoteDevice);
+
+        updateStateAndNotification(STATE_IN_PROGRESS);
+    }
+
+    public void finishTransfer(boolean success, Uri uri, String mimeType) {
+        if (!isRunning()) return; // Ignore when we're no longer running
+
+        if (success && uri != null) {
+            if (DBG) Log.d(TAG, "Transfer success, uri " + uri + " mimeType " + mimeType);
+            this.mProgress = 1.0f;
+            if (mimeType == null) {
+                mimeType = BluetoothOppHandover.getMimeTypeForUri(mContext, uri);
+            }
+            if (mimeType != null) {
+                mBtUris.add(uri);
+                mBtMimeTypes.add(mimeType);
+            } else {
+                if (DBG) Log.d(TAG, "Could not get mimeType for file.");
+            }
+        } else {
+            Log.e(TAG, "Handover transfer failed");
+            // Do wait to see if there's another file coming.
+        }
+        mHandler.removeMessages(MSG_NEXT_TRANSFER_TIMER);
+        mHandler.sendEmptyMessageDelayed(MSG_NEXT_TRANSFER_TIMER, WAIT_FOR_NEXT_TRANSFER_MS);
+        updateStateAndNotification(STATE_W4_NEXT_TRANSFER);
+    }
+
+    public boolean isRunning() {
+        if (mState != STATE_NEW && mState != STATE_IN_PROGRESS && mState != STATE_W4_NEXT_TRANSFER) {
+            return false;
+        } else {
+            return true;
+        }
+    }
+
+    void cancel() {
+        if (!isRunning()) return;
+
+        // Delete all files received so far
+        for (Uri uri : mBtUris) {
+            File file = new File(uri.getPath());
+            if (file.exists()) file.delete();
+        }
+
+        updateStateAndNotification(STATE_CANCELLED);
+    }
+
+    void updateNotification() {
+        if (!mIncoming) return; // No notifications for outgoing transfers
+
+        Builder notBuilder = new Notification.Builder(mContext);
+
+        if (mState == STATE_NEW || mState == STATE_IN_PROGRESS ||
+                mState == STATE_W4_NEXT_TRANSFER || mState == STATE_W4_MEDIA_SCANNER) {
+            notBuilder.setAutoCancel(false);
+            notBuilder.setSmallIcon(android.R.drawable.stat_sys_download);
+            notBuilder.setTicker(mContext.getString(R.string.beam_progress));
+            notBuilder.setContentTitle(mContext.getString(R.string.beam_progress));
+            notBuilder.addAction(R.drawable.ic_menu_cancel_holo_dark,
+                    mContext.getString(R.string.cancel), mCancelIntent);
+            notBuilder.setDeleteIntent(mCancelIntent);
+            // We do have progress indication on a per-file basis, but in a multi-file
+            // transfer we don't know the total progress. So for now, just show an
+            // indeterminate progress bar.
+            notBuilder.setProgress(100, 0, true);
+        } else if (mState == STATE_SUCCESS) {
+            notBuilder.setAutoCancel(true);
+            notBuilder.setSmallIcon(android.R.drawable.stat_sys_download_done);
+            notBuilder.setTicker(mContext.getString(R.string.beam_complete));
+            notBuilder.setContentTitle(mContext.getString(R.string.beam_complete));
+            notBuilder.setContentText(mContext.getString(R.string.beam_touch_to_view));
+
+            Intent viewIntent = buildViewIntent();
+            PendingIntent contentIntent = PendingIntent.getActivity(
+                    mContext, 0, viewIntent, 0, null);
+
+            notBuilder.setContentIntent(contentIntent);
+        } else if (mState == STATE_FAILED) {
+            notBuilder.setAutoCancel(false);
+            notBuilder.setSmallIcon(android.R.drawable.stat_sys_download_done);
+            notBuilder.setTicker(mContext.getString(R.string.beam_failed));
+            notBuilder.setContentTitle(mContext.getString(R.string.beam_failed));
+        } else if (mState == STATE_CANCELLED) {
+            notBuilder.setAutoCancel(false);
+            notBuilder.setSmallIcon(android.R.drawable.stat_sys_download_done);
+            notBuilder.setTicker(mContext.getString(R.string.beam_canceled));
+            notBuilder.setContentTitle(mContext.getString(R.string.beam_canceled));
+        } else {
+            return;
+        }
+
+        mNotificationManager.notify(null, mTransferId, notBuilder.build());
+    }
+
+    void updateStateAndNotification(int newState) {
+        this.mState = newState;
+        this.mLastUpdate = SystemClock.elapsedRealtime();
+
+        if (mHandler.hasMessages(MSG_TRANSFER_TIMEOUT)) {
+            // Update timeout timer
+            mHandler.removeMessages(MSG_TRANSFER_TIMEOUT);
+            mHandler.sendEmptyMessageDelayed(MSG_TRANSFER_TIMEOUT, ALIVE_CHECK_MS);
+        }
+
+        updateNotification();
+
+        if ((mState == STATE_SUCCESS || mState == STATE_FAILED || mState == STATE_CANCELLED)
+                && !mCalledBack) {
+            mCalledBack = true;
+            // Notify that we're done with this transfer
+            mCallback.onTransferComplete(this, mState == STATE_SUCCESS);
+        }
+    }
+
+    void processFiles() {
+        // Check the amount of files we received in this transfer;
+        // If more than one, create a separate directory for it.
+        String extRoot = Environment.getExternalStorageDirectory().getPath();
+        File beamPath = new File(extRoot + "/" + BEAM_DIR);
+
+        if (!checkMediaStorage(beamPath) || mBtUris.size() == 0) {
+            Log.e(TAG, "Media storage not valid or no uris received.");
+            updateStateAndNotification(STATE_FAILED);
+            return;
+        }
+
+        if (mBtUris.size() > 1) {
+            beamPath = generateMultiplePath(extRoot + "/" + BEAM_DIR + "/");
+            if (!beamPath.isDirectory() && !beamPath.mkdir()) {
+                Log.e(TAG, "Failed to create multiple path " + beamPath.toString());
+                updateStateAndNotification(STATE_FAILED);
+                return;
+            }
+        }
+
+        for (int i = 0; i < mBtUris.size(); i++) {
+            Uri uri = mBtUris.get(i);
+            String mimeType = mBtMimeTypes.get(i);
+
+            File srcFile = new File(uri.getPath());
+
+            File dstFile = generateUniqueDestination(beamPath.getAbsolutePath(),
+                    uri.getLastPathSegment());
+            if (!srcFile.renameTo(dstFile)) {
+                if (DBG) Log.d(TAG, "Failed to rename from " + srcFile + " to " + dstFile);
+                srcFile.delete();
+                return;
+            } else {
+                mPaths.add(dstFile.getAbsolutePath());
+                mMimeTypes.put(dstFile.getAbsolutePath(), mimeType);
+                if (DBG) Log.d(TAG, "Did successful rename from " + srcFile + " to " + dstFile);
+            }
+        }
+
+        // We can either add files to the media provider, or provide an ACTION_VIEW
+        // intent to the file directly. We base this decision on the mime type
+        // of the first file; if it's media the platform can deal with,
+        // use the media provider, if it's something else, just launch an ACTION_VIEW
+        // on the file.
+        String mimeType = mMimeTypes.get(mPaths.get(0));
+        if (mimeType.startsWith("image/") || mimeType.startsWith("video/") ||
+                mimeType.startsWith("audio/")) {
+            String[] arrayPaths = new String[mPaths.size()];
+            MediaScannerConnection.scanFile(mContext, mPaths.toArray(arrayPaths), null, this);
+            updateStateAndNotification(STATE_W4_MEDIA_SCANNER);
+        } else {
+            // We're done.
+            updateStateAndNotification(STATE_SUCCESS);
+        }
+
+    }
+
+    public int getTransferId() {
+        return mTransferId;
+    }
+
+    public boolean handleMessage(Message msg) {
+        if (msg.what == MSG_NEXT_TRANSFER_TIMER) {
+            // We didn't receive a new transfer in time, finalize this one
+            if (mIncoming) {
+                processFiles();
+            } else {
+                updateStateAndNotification(STATE_SUCCESS);
+            }
+            return true;
+        } else if (msg.what == MSG_TRANSFER_TIMEOUT) {
+            // No update on this transfer for a while, check
+            // to see if it's still running, and fail it if it is.
+            if (isRunning()) {
+                updateStateAndNotification(STATE_FAILED);
+            }
+        }
+        return false;
+    }
+
+    public synchronized void onScanCompleted(String path, Uri uri) {
+        if (DBG) Log.d(TAG, "Scan completed, path " + path + " uri " + uri);
+        if (uri != null) {
+            mMediaUris.put(path, uri);
+        }
+        mUrisScanned++;
+        if (mUrisScanned == mPaths.size()) {
+            // We're done
+            updateStateAndNotification(STATE_SUCCESS);
+        }
+    }
+
+    boolean checkMediaStorage(File path) {
+        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
+            if (!path.isDirectory() && !path.mkdir()) {
+                Log.e(TAG, "Not dir or not mkdir " + path.getAbsolutePath());
+                return false;
+            }
+            return true;
+        } else {
+            Log.e(TAG, "External storage not mounted, can't store file.");
+            return false;
+        }
+    }
+
+    Intent buildViewIntent() {
+        if (mPaths.size() == 0) return null;
+
+        Intent viewIntent = new Intent(Intent.ACTION_VIEW);
+
+        String filePath = mPaths.get(0);
+        Uri mediaUri = mMediaUris.get(filePath);
+        Uri uri =  mediaUri != null ? mediaUri :
+            Uri.parse(ContentResolver.SCHEME_FILE + "://" + filePath);
+        viewIntent.setDataAndTypeAndNormalize(uri, mMimeTypes.get(filePath));
+        viewIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        return viewIntent;
+    }
+
+    PendingIntent buildCancelIntent() {
+        Intent intent = new Intent(HandoverService.ACTION_CANCEL_HANDOVER_TRANSFER);
+        intent.putExtra(HandoverService.EXTRA_SOURCE_ADDRESS, mRemoteDevice.getAddress());
+        PendingIntent pi = PendingIntent.getBroadcast(mContext, 0, intent, 0);
+
+        return pi;
+    }
+
+    File generateUniqueDestination(String path, String fileName) {
+        int dotIndex = fileName.lastIndexOf(".");
+        String extension = null;
+        String fileNameWithoutExtension = null;
+        if (dotIndex < 0) {
+            extension = "";
+            fileNameWithoutExtension = fileName;
+        } else {
+            extension = fileName.substring(dotIndex);
+            fileNameWithoutExtension = fileName.substring(0, dotIndex);
+        }
+        File dstFile = new File(path + File.separator + fileName);
+        int count = 0;
+        while (dstFile.exists()) {
+            dstFile = new File(path + File.separator + fileNameWithoutExtension + "-" +
+                    Integer.toString(count) + extension);
+            count++;
+        }
+        return dstFile;
+    }
+
+    File generateMultiplePath(String beamRoot) {
+        // Generate a unique directory with the date
+        String format = "yyyy-MM-dd";
+        SimpleDateFormat sdf = new SimpleDateFormat(format);
+        String newPath = beamRoot + "beam-" + sdf.format(new Date());
+        File newFile = new File(newPath);
+        int count = 0;
+        while (newFile.exists()) {
+            newPath = beamRoot + "beam-" + sdf.format(new Date()) + "-" +
+                    Integer.toString(count);
+            newFile = new File(newPath);
+            count++;
+        }
+        return newFile;
+    }
+}
+
diff --git a/src/com/android/nfc/handover/PendingHandoverTransfer.java b/src/com/android/nfc/handover/PendingHandoverTransfer.java
new file mode 100644
index 0000000..db5c68b
--- /dev/null
+++ b/src/com/android/nfc/handover/PendingHandoverTransfer.java
@@ -0,0 +1,63 @@
+package com.android.nfc.handover;
+
+import android.bluetooth.BluetoothDevice;
+import android.net.Uri;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+public class PendingHandoverTransfer implements Parcelable {
+    public int id;
+    public boolean incoming;
+    public BluetoothDevice remoteDevice;
+    public boolean remoteActivating;
+    public Uri[] uris;
+
+    PendingHandoverTransfer(int id, boolean incoming, BluetoothDevice remoteDevice,
+            boolean remoteActivating, Uri[] uris) {
+        this.id = id;
+        this.incoming = incoming;
+        this.remoteDevice = remoteDevice;
+        this.remoteActivating = remoteActivating;
+        this.uris = uris;
+    }
+
+    public static final Parcelable.Creator<PendingHandoverTransfer> CREATOR
+            = new Parcelable.Creator<PendingHandoverTransfer>() {
+        public PendingHandoverTransfer createFromParcel(Parcel in) {
+            int id = in.readInt();
+            boolean incoming = (in.readInt() == 1) ? true : false;
+            BluetoothDevice remoteDevice = in.readParcelable(getClass().getClassLoader());
+            boolean remoteActivating = (in.readInt() == 1) ? true : false;
+            int numUris = in.readInt();
+            Uri[] uris = null;
+            if (numUris > 0) {
+                uris = new Uri[numUris];
+                in.readTypedArray(uris, Uri.CREATOR);
+            }
+            return new PendingHandoverTransfer(id, incoming, remoteDevice,
+                    remoteActivating, uris);
+        }
+
+        @Override
+        public PendingHandoverTransfer[] newArray(int size) {
+            return new PendingHandoverTransfer[size];
+        }
+    };
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeInt(id);
+        dest.writeInt(incoming ? 1 : 0);
+        dest.writeParcelable(remoteDevice, 0);
+        dest.writeInt(remoteActivating ? 1 : 0);
+        dest.writeInt(uris != null ? uris.length : 0);
+        if (uris != null && uris.length > 0) {
+            dest.writeTypedArray(uris, 0);
+        }
+    }
+}
