From ee3a589204a5f621f0a0f8eac81f074f25724a8f Mon Sep 17 00:00:00 2001 From: Steven Moreland Date: Tue, 5 Nov 2019 16:11:59 -0800 Subject: [PATCH] vibrator: handle aidl HAL dying Vibrator just tries to reconnect when commands fail, but because of the HIDL->AIDL shim's handling of errors, we were dropping binder-level errors, and the client code wasn't properly handling them. Now, we convert dead object and other errors appropriately so that the client code is given the errors it is expecting. Bug: 141828236 Test: kill aidl vibrator HAL repeatedly, and ensure that it reconnects and starts handling vibrator commands. Change-Id: I9719ec030f514905f1c5e57a1bdf455956d88e76 --- .../com_android_server_VibratorService.cpp | 24 +++++++++++++++---- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/services/core/jni/com_android_server_VibratorService.cpp b/services/core/jni/com_android_server_VibratorService.cpp index 8ddb86b08ea31..51bea1f068ad8 100644 --- a/services/core/jni/com_android_server_VibratorService.cpp +++ b/services/core/jni/com_android_server_VibratorService.cpp @@ -154,21 +154,29 @@ class VibratorShim : public V1_4::IVibrator { sp cb = callback ? new CallbackShim(callback) : nullptr; int timeoutMs = 0; - V1_0::Status status = toHidlStatus( + Return status = toHidlStatus( mVib->perform(static_cast(effect), static_cast(strength), cb, &timeoutMs)); - _hidl_cb(status, timeoutMs); - return android::hardware::Status::ok(); + + if (status.isOk()) { + _hidl_cb(status, timeoutMs); + return android::hardware::Status::ok(); + } else { + return android::hardware::details::StatusOf(status); + } } private: sp mVib; - V1_0::Status toHidlStatus(const android::binder::Status& status) { + Return toHidlStatus(const android::binder::Status& status) { switch(status.exceptionCode()) { using android::hardware::Status; case Status::EX_NONE: return V1_0::Status::OK; case Status::EX_ILLEGAL_ARGUMENT: return V1_0::Status::BAD_VALUE; case Status::EX_UNSUPPORTED_OPERATION: return V1_0::Status::UNSUPPORTED_OPERATION; + case Status::EX_TRANSACTION_FAILED: { + return Status::fromStatusT(status.transactionError()); + } } return V1_0::Status::UNKNOWN_ERROR; } @@ -247,8 +255,14 @@ class HalWrapper { } ALOGE("Failed to issue command to vibrator HAL. Retrying."); + // Restoring connection to the HAL. - mHal = I::tryGetService(); + sp aidlVib = checkVintfService(); + if (aidlVib) { + mHal = new VibratorShim(aidlVib); + } else { + mHal = I::tryGetService(); + } } return ret; }