Bluetooth: Protect pointers and callbacks

Test: kill com.android.bluetooth
Bug: 36150800
Change-Id: I9533731c9ce3776c84e6c1d3fdf3e266b328a084
diff --git a/bluetooth/1.0/default/bluetooth_hci.cc b/bluetooth/1.0/default/bluetooth_hci.cc
index fec5b81..8eccfc7 100644
--- a/bluetooth/1.0/default/bluetooth_hci.cc
+++ b/bluetooth/1.0/default/bluetooth_hci.cc
@@ -15,9 +15,10 @@
 //
 
 #define LOG_TAG "android.hardware.bluetooth@1.0-impl"
+#include "bluetooth_hci.h"
+
 #include <utils/Log.h>
 
-#include "bluetooth_hci.h"
 #include "vendor_interface.h"
 
 namespace android {
@@ -38,59 +39,77 @@
       uint64_t /*cookie*/,
       const wp<::android::hidl::base::V1_0::IBase>& /*who*/) {
     ALOGE("BluetoothDeathRecipient::serviceDied - Bluetooth service died");
+    has_died_ = true;
     mHci->close();
   }
   sp<IBluetoothHci> mHci;
+  bool getHasDied() const { return has_died_; }
+  void setHasDied(bool has_died) { has_died_ = has_died; }
+
+ private:
+  bool has_died_;
 };
 
 BluetoothHci::BluetoothHci()
-    : deathRecipient(new BluetoothDeathRecipient(this)) {}
+    : death_recipient_(new BluetoothDeathRecipient(this)) {}
 
 Return<void> BluetoothHci::initialize(
     const ::android::sp<IBluetoothHciCallbacks>& cb) {
-  ALOGW("BluetoothHci::initialize()");
-  cb->linkToDeath(deathRecipient, 0);
-  event_cb_ = cb;
+  ALOGI("BluetoothHci::initialize()");
+  if (cb == nullptr) {
+    ALOGE("cb == nullptr! -> Unable to call initializationComplete(ERR)");
+    return Void();
+  }
+
+  death_recipient_->setHasDied(false);
+  cb->linkToDeath(death_recipient_, 0);
 
   bool rc = VendorInterface::Initialize(
-      [this](bool status) {
-        auto hidl_status = event_cb_->initializationComplete(
+      [cb](bool status) {
+        auto hidl_status = cb->initializationComplete(
             status ? Status::SUCCESS : Status::INITIALIZATION_ERROR);
         if (!hidl_status.isOk()) {
           ALOGE("VendorInterface -> Unable to call initializationComplete()");
         }
       },
-      [this](const hidl_vec<uint8_t>& packet) {
-        auto hidl_status = event_cb_->hciEventReceived(packet);
+      [cb](const hidl_vec<uint8_t>& packet) {
+        auto hidl_status = cb->hciEventReceived(packet);
         if (!hidl_status.isOk()) {
           ALOGE("VendorInterface -> Unable to call hciEventReceived()");
         }
       },
-      [this](const hidl_vec<uint8_t>& packet) {
-        auto hidl_status = event_cb_->aclDataReceived(packet);
+      [cb](const hidl_vec<uint8_t>& packet) {
+        auto hidl_status = cb->aclDataReceived(packet);
         if (!hidl_status.isOk()) {
           ALOGE("VendorInterface -> Unable to call aclDataReceived()");
         }
       },
-      [this](const hidl_vec<uint8_t>& packet) {
-        auto hidl_status = event_cb_->scoDataReceived(packet);
+      [cb](const hidl_vec<uint8_t>& packet) {
+        auto hidl_status = cb->scoDataReceived(packet);
         if (!hidl_status.isOk()) {
           ALOGE("VendorInterface -> Unable to call scoDataReceived()");
         }
       });
   if (!rc) {
-    auto hidl_status =
-        event_cb_->initializationComplete(Status::INITIALIZATION_ERROR);
+    auto hidl_status = cb->initializationComplete(Status::INITIALIZATION_ERROR);
     if (!hidl_status.isOk()) {
       ALOGE("VendorInterface -> Unable to call initializationComplete(ERR)");
     }
   }
+
+  unlink_cb_ = [cb](sp<BluetoothDeathRecipient>& death_recipient) {
+    if (death_recipient->getHasDied())
+      ALOGI("Skipping unlink call, service died.");
+    else
+      cb->unlinkToDeath(death_recipient);
+  };
+
   return Void();
 }
 
 Return<void> BluetoothHci::close() {
-  ALOGW("BluetoothHci::close()");
-  event_cb_->unlinkToDeath(deathRecipient);
+  ALOGI("BluetoothHci::close()");
+  unlink_cb_(death_recipient_);
   VendorInterface::Shutdown();
   return Void();
 }