Revert "Revert "Avoid calling back to dead service""

This reverts commit e0a8997646d130e2d9a2af2210ff39ad3d1eb14a.

Reason for revert: need to fix build break and submit solution

Change-Id: Iec45078a2ab19a2e665ed872ba7574e4ccbd015b
diff --git a/1.2/Nfc.cpp b/1.2/Nfc.cpp
index 3273294..80945f0 100644
--- a/1.2/Nfc.cpp
+++ b/1.2/Nfc.cpp
@@ -44,8 +44,11 @@
     ALOGD_IF(nfc_debug_enabled,"Nfc::open null callback");
     return V1_0::NfcStatus::FAILED;
   } else {
+    pthread_mutex_lock(&mLockOpenClose);
+    mOpenCount++;
     mCallbackV1_1 = clientCallback;
-    mCallbackV1_1->linkToDeath(this, 0 /*cookie*/);
+    mCallbackV1_1->linkToDeath(this, mOpenCount /*cookie*/);
+    pthread_mutex_unlock(&mLockOpenClose);
   }
   return open(clientCallback);
 }
@@ -54,16 +57,20 @@
 Return<V1_0::NfcStatus> Nfc::open(
     const sp<V1_0::INfcClientCallback>& clientCallback) {
   ALOGD_IF(nfc_debug_enabled, "Nfc::open Enter");
+  pthread_mutex_lock(&mLockOpenClose);
+  if (mCallbackV1_1 == nullptr) mOpenCount++;
   if (clientCallback == nullptr) {
     ALOGD_IF(nfc_debug_enabled, "Nfc::open null callback");
+    pthread_mutex_unlock(&mLockOpenClose);
     return V1_0::NfcStatus::FAILED;
   } else {
     mCallbackV1_0 = clientCallback;
-    mCallbackV1_0->linkToDeath(this, 0 /*cookie*/);
+    mCallbackV1_0->linkToDeath(this, mOpenCount /*cookie*/);
   }
 
   int ret = StNfc_hal_open(eventCallback, dataCallback);
-  ALOGD_IF(nfc_debug_enabled, "Nfc::open Exit");
+  ALOGD_IF(nfc_debug_enabled, "Nfc::open Exit (count:%llu)", (unsigned long long)mOpenCount);
+  pthread_mutex_unlock(&mLockOpenClose);
   return ret == 0 ? V1_0::NfcStatus::OK : V1_0::NfcStatus::FAILED;
 }
 
@@ -90,9 +97,7 @@
 }
 
 Return<V1_0::NfcStatus> Nfc::close() {
-  if (mCallbackV1_1 == nullptr && mCallbackV1_0 == nullptr) {
-    return V1_0::NfcStatus::FAILED;
-  }
+  pthread_mutex_lock(&mLockOpenClose);
   int ret = StNfc_hal_close(NFC_MODE_OFF);
 
   if (mCallbackV1_1 != nullptr) {
@@ -103,6 +108,7 @@
     mCallbackV1_0->unlinkToDeath(this);
     mCallbackV1_0 = nullptr;
   }
+  pthread_mutex_unlock(&mLockOpenClose);
   return ret == 0 ? V1_0::NfcStatus::OK : V1_0::NfcStatus::FAILED;
 }
 
@@ -127,6 +133,7 @@
     return V1_0::NfcStatus::FAILED;
   }
 
+  pthread_mutex_lock(&mLockOpenClose);
   int ret = StNfc_hal_closeForPowerOffCase();
 
   if (mCallbackV1_1 != nullptr) {
@@ -137,6 +144,7 @@
     mCallbackV1_0->unlinkToDeath(this);
     mCallbackV1_0 = nullptr;
   }
+  pthread_mutex_unlock(&mLockOpenClose);
   return ret == 0 ? V1_0::NfcStatus::OK : V1_0::NfcStatus::FAILED;
 }
 
diff --git a/1.2/Nfc.h b/1.2/Nfc.h
index 77657d8..df966f9 100644
--- a/1.2/Nfc.h
+++ b/1.2/Nfc.h
@@ -24,6 +24,7 @@
 #include <hidl/MQDescriptor.h>
 #include <hidl/Status.h>
 #include <log/log.h>
+#include <pthread.h>
 
 namespace android {
 namespace hardware {
@@ -96,13 +97,34 @@
     }
   }
 
-  virtual void serviceDied(uint64_t /*cookie*/, const wp<IBase>& /*who*/) {
-    close();
+  virtual void serviceDied(uint64_t cookie, const wp<IBase>& /*who*/) {
+    pthread_mutex_lock(&mLockOpenClose);
+    ALOGE("serviceDied!!! %llu, %llu, %s, %s",
+          (unsigned long long)cookie,
+          (unsigned long long)mOpenCount,
+          (mCallbackV1_0 == nullptr ? "null" : "defined"),
+          (mCallbackV1_1 == nullptr ? "null" : "defined"));
+    if (cookie == mOpenCount) {
+      if (mCallbackV1_1 != nullptr) {
+        mCallbackV1_1->unlinkToDeath(this);
+        mCallbackV1_1 = nullptr;
+      }
+      if (mCallbackV1_0 != nullptr) {
+        mCallbackV1_0->unlinkToDeath(this);
+        mCallbackV1_0 = nullptr;
+      }
+      pthread_mutex_unlock(&mLockOpenClose);
+      close();
+    } else {
+      pthread_mutex_unlock(&mLockOpenClose);
+    }
   }
 
  private:
   static sp<V1_1::INfcClientCallback> mCallbackV1_1;
   static sp<V1_0::INfcClientCallback> mCallbackV1_0;
+  pthread_mutex_t mLockOpenClose = PTHREAD_MUTEX_INITIALIZER;
+  uint64_t mOpenCount = 0;
 };
 
 }  // namespace implementation
diff --git a/1.2/hal_st21nfc.cc b/1.2/hal_st21nfc.cc
index 74e8c2c..5efc6b1 100644
--- a/1.2/hal_st21nfc.cc
+++ b/1.2/hal_st21nfc.cc
@@ -367,7 +367,7 @@
     (void)pthread_mutex_unlock(&hal_mtx);
     return 1;
   }
-  if (hal_wrapper_close(1, nfc_mode_value) == 0) {
+  if (hal_wrapper_close(1, nfc_mode_value) == -1) {
     hal_is_closed = 1;
     (void)pthread_mutex_unlock(&hal_mtx);
     return 1;