Nfc: deal with the framework going away.
By calling close() when the framework client dies.
Bug: 35624326
Test: NFC HAL stays alive and works after com.android.nfc is killed
Change-Id: I91fcf6685783cd630a44d19b4cb99127a2c0e89b
diff --git a/nfc/1.0/default/Nfc.cpp b/nfc/1.0/default/Nfc.cpp
index 3bd5e41..c610406 100644
--- a/nfc/1.0/default/Nfc.cpp
+++ b/nfc/1.0/default/Nfc.cpp
@@ -14,12 +14,14 @@
sp<INfcClientCallback> Nfc::mCallback = NULL;
-Nfc::Nfc(nfc_nci_device_t* device) : mDevice(device) {
+Nfc::Nfc(nfc_nci_device_t* device) : mDevice(device),
+ mDeathRecipient(new NfcDeathRecipient(this)) {
}
// Methods from ::android::hardware::nfc::V1_0::INfc follow.
::android::hardware::Return<NfcStatus> Nfc::open(const sp<INfcClientCallback>& clientCallback) {
mCallback = clientCallback;
+ mCallback->linkToDeath(mDeathRecipient, 0 /*cookie*/);
int ret = mDevice->open(mDevice, eventCallback, dataCallback);
return ret == 0 ? NfcStatus::OK : NfcStatus::FAILED;
}
@@ -39,6 +41,7 @@
}
::android::hardware::Return<NfcStatus> Nfc::close() {
+ mCallback->unlinkToDeath(mDeathRecipient);
return mDevice->close(mDevice) ? NfcStatus::FAILED : NfcStatus::OK;
}
diff --git a/nfc/1.0/default/Nfc.h b/nfc/1.0/default/Nfc.h
index 13004a5..d8787fd 100644
--- a/nfc/1.0/default/Nfc.h
+++ b/nfc/1.0/default/Nfc.h
@@ -19,6 +19,16 @@
using ::android::hardware::hidl_string;
using ::android::sp;
+struct NfcDeathRecipient : hidl_death_recipient {
+ NfcDeathRecipient(const sp<INfc> nfc) : mNfc(nfc) {
+ }
+
+ virtual void serviceDied(uint64_t /*cookie*/, const wp<::android::hidl::base::V1_0::IBase>& /*who*/) {
+ mNfc->close();
+ }
+ sp<INfc> mNfc;
+};
+
struct Nfc : public INfc {
Nfc(nfc_nci_device_t* device);
::android::hardware::Return<NfcStatus> open(const sp<INfcClientCallback>& clientCallback) override;
@@ -31,21 +41,28 @@
static void eventCallback(uint8_t event, uint8_t status) {
if (mCallback != nullptr) {
- mCallback->sendEvent(
+ auto ret = mCallback->sendEvent(
(::android::hardware::nfc::V1_0::NfcEvent) event,
(::android::hardware::nfc::V1_0::NfcStatus) status);
+ if (!ret.isOk()) {
+ ALOGW("Failed to call back into NFC process.");
+ }
}
}
static void dataCallback(uint16_t data_len, uint8_t* p_data) {
hidl_vec<uint8_t> data;
data.setToExternal(p_data, data_len);
if (mCallback != nullptr) {
- mCallback->sendData(data);
+ auto ret = mCallback->sendData(data);
+ if (!ret.isOk()) {
+ ALOGW("Failed to call back into NFC process.");
+ }
}
}
private:
static sp<INfcClientCallback> mCallback;
const nfc_nci_device_t* mDevice;
+ sp<NfcDeathRecipient> mDeathRecipient;
};
extern "C" INfc* HIDL_FETCH_INfc(const char* name);