Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ee3a5892 authored by Steven Moreland's avatar Steven Moreland
Browse files

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
parent bfc11892
Loading
Loading
Loading
Loading
+19 −5
Original line number Diff line number Diff line
@@ -154,21 +154,29 @@ class VibratorShim : public V1_4::IVibrator {

        sp<aidl::IVibratorCallback> cb = callback ? new CallbackShim(callback) : nullptr;
        int timeoutMs = 0;
        V1_0::Status status = toHidlStatus(
        Return<V1_0::Status> status = toHidlStatus(
            mVib->perform(static_cast<aidl::Effect>(effect),
                          static_cast<aidl::EffectStrength>(strength), cb, &timeoutMs));

        if (status.isOk()) {
            _hidl_cb(status, timeoutMs);
            return android::hardware::Status::ok();
        } else {
            return android::hardware::details::StatusOf<V1_0::Status, void>(status);
        }
    }
  private:
    sp<aidl::IVibrator> mVib;

    V1_0::Status toHidlStatus(const android::binder::Status& status) {
    Return<V1_0::Status> 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,9 +255,15 @@ class HalWrapper {
            }

            ALOGE("Failed to issue command to vibrator HAL. Retrying.");

            // Restoring connection to the HAL.
            sp<aidl::IVibrator> aidlVib = checkVintfService<aidl::IVibrator>();
            if (aidlVib) {
                mHal = new VibratorShim(aidlVib);
            } else {
                mHal = I::tryGetService();
            }
        }
        return ret;
    }