PBAP: Clean up SDP record when closing service

* PBAP SDP record was never cleaned up when PBAP service is closed,
  resulting in stacked SDP records for PBAP.
* This CL groups cleanup statements into one method and calls it during
  onAcceptFailed() and closeService()
* onAcceptFailed() will clean up SDP, shutdown server sockets before
  starting a new server socket again
* startSocketListeners() will fail if SDP record already exist before it
  starts, caller is responsible in cleaning up the SDP record
* Also, if SDP record is valid, mAdapter should never be null and the
  check is unnecessary.

Bug: 67381100
Test: Pair with car kit and repeatly toggle Bluetooth ON/OFF
Change-Id: Ibff32289ca3e082b2a56f79d99c0e8dded728b83
diff --git a/src/com/android/bluetooth/pbap/BluetoothPbapService.java b/src/com/android/bluetooth/pbap/BluetoothPbapService.java
index cc2dd25..134b789 100644
--- a/src/com/android/bluetooth/pbap/BluetoothPbapService.java
+++ b/src/com/android/bluetooth/pbap/BluetoothPbapService.java
@@ -438,12 +438,16 @@
             mWakeLock = null;
         }
 
+        // Step 1: clean up active server session
         if (mServerSession != null) {
             mServerSession.close();
             mServerSession = null;
         }
-
+        // Step 2: clean up existing connection socket
         closeConnectionSocket();
+        // Step 3: clean up SDP record
+        cleanUpSdpRecord();
+        // Step 4: clean up existing server socket(s)
         closeServerSocket();
         if (mServerSockets != null) {
             mServerSockets.shutdown(false);
@@ -453,6 +457,24 @@
         if (VERBOSE) Log.v(TAG, "Pbap Service closeService out");
     }
 
+    private void cleanUpSdpRecord() {
+        if (mSdpHandle < 0) {
+            if (VERBOSE) Log.v(TAG, "cleanUpSdpRecord, SDP record never created");
+            return;
+        }
+        int sdpHandle = mSdpHandle;
+        mSdpHandle = -1;
+        SdpManager sdpManager = SdpManager.getDefaultManager();
+        if (sdpManager == null) {
+            Log.e(TAG, "cleanUpSdpRecord failed, sdpManager is null, sdpHandle=" + sdpHandle);
+            return;
+        }
+        Log.i(TAG, "cleanUpSdpRecord, mSdpHandle=" + sdpHandle);
+        if (!sdpManager.removeSdpRecord(sdpHandle)) {
+            Log.e(TAG, "cleanUpSdpRecord, removeSdpRecord failed, sdpHandle=" + sdpHandle);
+        }
+    }
+
     private final void startObexServerSession() throws IOException {
         if (VERBOSE) Log.v(TAG, "Pbap Service startObexServerSession");
 
@@ -940,6 +962,10 @@
         }
     }
 
+    /**
+     * Start server side socket listeners. Caller should make sure that adapter is in a ready state
+     * and SDP record is cleaned up. Otherwise, this method will fail.
+     */
     synchronized private void startSocketListeners() {
         if (DEBUG) Log.d(TAG, "startsocketListener");
         if (mServerSession != null) {
@@ -957,17 +983,10 @@
                 Log.e(TAG, "Failed to start the listeners");
                 return;
             }
-            SdpManager sdpManager = SdpManager.getDefaultManager();
-            if (sdpManager == null) {
-                Log.e(TAG, "Failed to start the listeners sdp null ");
+            if (mSdpHandle >= 0) {
+                Log.e(TAG, "SDP handle was not cleaned up, mSdpHandle=" + mSdpHandle);
                 return;
             }
-            if (mAdapter != null && mSdpHandle >= 0) {
-                Log.d(TAG, "Removing SDP record for PBAP with SDP handle:" + mSdpHandle);
-                boolean status = sdpManager.removeSdpRecord(mSdpHandle);
-                Log.d(TAG, "RemoveSDPrecord returns " + status);
-                mSdpHandle = -1;
-            }
             mSdpHandle = SdpManager.getDefaultManager().createPbapPseRecord(
                     "OBEX Phonebook Access Server", mServerSockets.getRfcommChannel(),
                     mServerSockets.getL2capPsm(), SDP_PBAP_SERVER_VERSION,
@@ -1058,8 +1077,13 @@
      */
     @Override
     public synchronized void onAcceptFailed() {
+        // Clean up SDP record first
+        cleanUpSdpRecord();
         // Force socket listener to restart
-        mServerSockets = null;
+        if (mServerSockets != null) {
+            mServerSockets.shutdown(false);
+            mServerSockets = null;
+        }
         if (!mInterrupted && mAdapter != null && mAdapter.isEnabled()) {
             startSocketListeners();
         }