Merge changes from topic "rm-vibrator-1.4-pass-2"

* changes:
  Remove vibrator@1.4
  VibratorService: avoid shim
diff --git a/services/core/Android.bp b/services/core/Android.bp
index a05c2cc..084a747 100644
--- a/services/core/Android.bp
+++ b/services/core/Android.bp
@@ -32,6 +32,7 @@
         "android.hardware.power-V1.0-java",
         "android.hardware.tv.cec-V1.0-java",
         "app-compat-annotations",
+        "vintf-vibrator-java",
     ],
 
     required: [
@@ -50,7 +51,6 @@
         "android.hardware.biometrics.fingerprint-V2.1-java",
         "android.hardware.oemlock-V1.0-java",
         "android.hardware.tetheroffload.control-V1.0-java",
-        "android.hardware.vibrator-V1.4-java",
         "android.hardware.configstore-V1.0-java",
         "android.hardware.contexthub-V1.0-java",
         "android.hidl.manager-V1.2-java",
diff --git a/services/core/java/com/android/server/VibratorService.java b/services/core/java/com/android/server/VibratorService.java
index d622fb4..0db8495 100644
--- a/services/core/java/com/android/server/VibratorService.java
+++ b/services/core/java/com/android/server/VibratorService.java
@@ -28,8 +28,8 @@
 import android.content.res.Resources;
 import android.database.ContentObserver;
 import android.hardware.input.InputManager;
+import android.hardware.vibrator.IVibrator;
 import android.hardware.vibrator.V1_0.EffectStrength;
-import android.hardware.vibrator.V1_4.Capabilities;
 import android.icu.text.DateFormat;
 import android.media.AudioAttributes;
 import android.media.AudioManager;
@@ -1153,7 +1153,7 @@
                 long duration = vibratorPerformEffect(prebaked.getId(),
                         prebaked.getEffectStrength(), vib);
                 long timeout = duration;
-                if ((mCapabilities & Capabilities.PERFORM_COMPLETION_CALLBACK) != 0) {
+                if ((mCapabilities & IVibrator.CAP_PERFORM_CALLBACK) != 0) {
                     timeout *= ASYNC_TIMEOUT_MULTIPLIER;
                 }
                 if (timeout > 0) {
diff --git a/services/core/jni/Android.bp b/services/core/jni/Android.bp
index 6175d41..7b3fbb9 100644
--- a/services/core/jni/Android.bp
+++ b/services/core/jni/Android.bp
@@ -130,7 +130,6 @@
         "android.hardware.vibrator@1.1",
         "android.hardware.vibrator@1.2",
         "android.hardware.vibrator@1.3",
-        "android.hardware.vibrator@1.4",
         "android.hardware.vr@1.0",
         "android.frameworks.schedulerservice@1.0",
         "android.frameworks.sensorservice@1.0",
diff --git a/services/core/jni/com_android_server_VibratorService.cpp b/services/core/jni/com_android_server_VibratorService.cpp
index 3726228..746610d 100644
--- a/services/core/jni/com_android_server_VibratorService.cpp
+++ b/services/core/jni/com_android_server_VibratorService.cpp
@@ -16,7 +16,7 @@
 
 #define LOG_TAG "VibratorService"
 
-#include <android/hardware/vibrator/1.4/IVibrator.h>
+#include <android/hardware/vibrator/1.3/IVibrator.h>
 #include <android/hardware/vibrator/BnVibratorCallback.h>
 #include <android/hardware/vibrator/IVibrator.h>
 #include <binder/IServiceManager.h>
@@ -43,166 +43,41 @@
 namespace V1_1 = android::hardware::vibrator::V1_1;
 namespace V1_2 = android::hardware::vibrator::V1_2;
 namespace V1_3 = android::hardware::vibrator::V1_3;
-namespace V1_4 = android::hardware::vibrator::V1_4;
 namespace aidl = android::hardware::vibrator;
 
 namespace android {
 
 static jmethodID sMethodIdOnComplete;
 
-// TODO(b/141828236): remove HIDL 1.4 and re-write all of this code to remove
-// shim
-class VibratorShim : public V1_4::IVibrator {
-  public:
-    VibratorShim(const sp<aidl::IVibrator>& vib) : mVib(vib) {}
+static_assert(static_cast<uint8_t>(V1_0::EffectStrength::LIGHT) ==
+                static_cast<uint8_t>(aidl::EffectStrength::LIGHT));
+static_assert(static_cast<uint8_t>(V1_0::EffectStrength::MEDIUM) ==
+                static_cast<uint8_t>(aidl::EffectStrength::MEDIUM));
+static_assert(static_cast<uint8_t>(V1_0::EffectStrength::STRONG) ==
+                static_cast<uint8_t>(aidl::EffectStrength::STRONG));
 
-    Return<V1_0::Status> on(uint32_t timeoutMs) override {
-        return on_1_4(timeoutMs, nullptr);
-    }
+static_assert(static_cast<uint8_t>(V1_3::Effect::CLICK) ==
+                static_cast<uint8_t>(aidl::Effect::CLICK));
+static_assert(static_cast<uint8_t>(V1_3::Effect::DOUBLE_CLICK) ==
+                static_cast<uint8_t>(aidl::Effect::DOUBLE_CLICK));
+static_assert(static_cast<uint8_t>(V1_3::Effect::TICK) ==
+                static_cast<uint8_t>(aidl::Effect::TICK));
+static_assert(static_cast<uint8_t>(V1_3::Effect::THUD) ==
+                static_cast<uint8_t>(aidl::Effect::THUD));
+static_assert(static_cast<uint8_t>(V1_3::Effect::POP) ==
+                static_cast<uint8_t>(aidl::Effect::POP));
+static_assert(static_cast<uint8_t>(V1_3::Effect::HEAVY_CLICK) ==
+                static_cast<uint8_t>(aidl::Effect::HEAVY_CLICK));
+static_assert(static_cast<uint8_t>(V1_3::Effect::RINGTONE_1) ==
+                static_cast<uint8_t>(aidl::Effect::RINGTONE_1));
+static_assert(static_cast<uint8_t>(V1_3::Effect::RINGTONE_2) ==
+                static_cast<uint8_t>(aidl::Effect::RINGTONE_2));
+static_assert(static_cast<uint8_t>(V1_3::Effect::RINGTONE_15) ==
+                static_cast<uint8_t>(aidl::Effect::RINGTONE_15));
+static_assert(static_cast<uint8_t>(V1_3::Effect::TEXTURE_TICK) ==
+                static_cast<uint8_t>(aidl::Effect::TEXTURE_TICK));
 
-    Return<V1_0::Status> off() override {
-        return toHidlStatus(mVib->off());
-    }
-
-    Return<bool> supportsAmplitudeControl() override {
-        int32_t cap = 0;
-        if (!mVib->getCapabilities(&cap).isOk()) return false;
-        if (mUnderExternalControl) {
-           return (cap & aidl::IVibrator::CAP_EXTERNAL_AMPLITUDE_CONTROL) > 0;
-        } else {
-           return (cap & aidl::IVibrator::CAP_AMPLITUDE_CONTROL) > 0;
-        }
-    }
-
-    Return<V1_0::Status> setAmplitude(uint8_t amplitude) override {
-        return toHidlStatus(mVib->setAmplitude(amplitude));
-    }
-
-    Return<void> perform(V1_0::Effect effect, V1_0::EffectStrength strength,
-                         perform_cb _hidl_cb) override {
-        return perform_1_4(static_cast<V1_3::Effect>(effect), strength, nullptr, _hidl_cb);
-    }
-
-    Return<void> perform_1_1(V1_1::Effect_1_1 effect, V1_0::EffectStrength strength,
-                             perform_1_1_cb _hidl_cb) override {
-        return perform_1_4(static_cast<V1_3::Effect>(effect), strength, nullptr, _hidl_cb);
-    }
-
-    Return<void> perform_1_2(V1_2::Effect effect, V1_0::EffectStrength strength,
-                             perform_1_2_cb _hidl_cb) override {
-        return perform_1_4(static_cast<V1_3::Effect>(effect), strength, nullptr, _hidl_cb);
-    }
-
-    Return<bool> supportsExternalControl() override {
-        int32_t cap = 0;
-        if (!mVib->getCapabilities(&cap).isOk()) return false;
-        return (cap & aidl::IVibrator::CAP_EXTERNAL_CONTROL) > 0;
-    }
-
-    Return<V1_0::Status> setExternalControl(bool enabled) override {
-        Return<V1_0::Status> status = toHidlStatus(mVib->setExternalControl(enabled));
-        if (status.isOk() && status == V1_0::Status::OK) {
-            mUnderExternalControl = enabled;
-        }
-        return status;
-    }
-
-    Return<void> perform_1_3(V1_3::Effect effect, V1_0::EffectStrength strength,
-                             perform_1_3_cb _hidl_cb) override {
-        return perform_1_4(static_cast<V1_3::Effect>(effect), strength, nullptr, _hidl_cb);
-    }
-
-    Return<uint32_t> getCapabilities() override {
-        static_assert(static_cast<int32_t>(V1_4::Capabilities::ON_COMPLETION_CALLBACK) ==
-                      static_cast<int32_t>(aidl::IVibrator::CAP_ON_CALLBACK));
-        static_assert(static_cast<int32_t>(V1_4::Capabilities::PERFORM_COMPLETION_CALLBACK) ==
-                      static_cast<int32_t>(aidl::IVibrator::CAP_PERFORM_CALLBACK));
-
-        int32_t cap;
-        if (!mVib->getCapabilities(&cap).isOk()) return 0;
-        return (cap & (aidl::IVibrator::CAP_ON_CALLBACK |
-                       aidl::IVibrator::CAP_PERFORM_CALLBACK)) > 0;
-    }
-
-    Return<V1_0::Status> on_1_4(uint32_t timeoutMs,
-                                const sp<V1_4::IVibratorCallback>& callback) override {
-        sp<aidl::IVibratorCallback> cb = callback ? new CallbackShim(callback) : nullptr;
-        return toHidlStatus(mVib->on(timeoutMs, cb));
-    }
-
-    Return<void> perform_1_4(V1_3::Effect effect, V1_0::EffectStrength strength,
-                             const sp<V1_4::IVibratorCallback>& callback,
-                             perform_1_4_cb _hidl_cb) override {
-        static_assert(static_cast<uint8_t>(V1_0::EffectStrength::LIGHT) ==
-                      static_cast<uint8_t>(aidl::EffectStrength::LIGHT));
-        static_assert(static_cast<uint8_t>(V1_0::EffectStrength::MEDIUM) ==
-                      static_cast<uint8_t>(aidl::EffectStrength::MEDIUM));
-        static_assert(static_cast<uint8_t>(V1_0::EffectStrength::STRONG) ==
-                      static_cast<uint8_t>(aidl::EffectStrength::STRONG));
-        static_assert(static_cast<uint8_t>(V1_3::Effect::CLICK) ==
-                      static_cast<uint8_t>(aidl::Effect::CLICK));
-        static_assert(static_cast<uint8_t>(V1_3::Effect::DOUBLE_CLICK) ==
-                      static_cast<uint8_t>(aidl::Effect::DOUBLE_CLICK));
-        static_assert(static_cast<uint8_t>(V1_3::Effect::TICK) ==
-                      static_cast<uint8_t>(aidl::Effect::TICK));
-        static_assert(static_cast<uint8_t>(V1_3::Effect::THUD) ==
-                      static_cast<uint8_t>(aidl::Effect::THUD));
-        static_assert(static_cast<uint8_t>(V1_3::Effect::POP) ==
-                      static_cast<uint8_t>(aidl::Effect::POP));
-        static_assert(static_cast<uint8_t>(V1_3::Effect::HEAVY_CLICK) ==
-                      static_cast<uint8_t>(aidl::Effect::HEAVY_CLICK));
-        static_assert(static_cast<uint8_t>(V1_3::Effect::RINGTONE_1) ==
-                      static_cast<uint8_t>(aidl::Effect::RINGTONE_1));
-        static_assert(static_cast<uint8_t>(V1_3::Effect::RINGTONE_2) ==
-                      static_cast<uint8_t>(aidl::Effect::RINGTONE_2));
-        static_assert(static_cast<uint8_t>(V1_3::Effect::RINGTONE_15) ==
-                      static_cast<uint8_t>(aidl::Effect::RINGTONE_15));
-        static_assert(static_cast<uint8_t>(V1_3::Effect::TEXTURE_TICK) ==
-                      static_cast<uint8_t>(aidl::Effect::TEXTURE_TICK));
-
-        sp<aidl::IVibratorCallback> cb = callback ? new CallbackShim(callback) : nullptr;
-        int timeoutMs = 0;
-        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;
-    bool mUnderExternalControl = false;
-
-    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;
-    }
-
-    class CallbackShim : public aidl::BnVibratorCallback {
-      public:
-        CallbackShim(const sp<V1_4::IVibratorCallback>& cb) : mCb(cb) {}
-        binder::Status onComplete() {
-            mCb->onComplete();
-            return binder::Status::ok(); // oneway, local call
-        }
-      private:
-        sp<V1_4::IVibratorCallback> mCb;
-    };
-};
-
-class VibratorCallback : public V1_4::IVibratorCallback {
+class VibratorCallback {
     public:
         VibratorCallback(JNIEnv *env, jobject vibration) :
         mVibration(MakeGlobalRefOrDie(env, vibration)) {}
@@ -212,47 +87,92 @@
             env->DeleteGlobalRef(mVibration);
         }
 
-        Return<void> onComplete() override {
+        void onComplete() {
             auto env = AndroidRuntime::getJNIEnv();
             env->CallVoidMethod(mVibration, sMethodIdOnComplete);
-            return Void();
         }
 
     private:
         jobject mVibration;
 };
 
+class AidlVibratorCallback : public aidl::BnVibratorCallback {
+  public:
+    AidlVibratorCallback(JNIEnv *env, jobject vibration) :
+    mCb(env, vibration) {}
+
+    binder::Status onComplete() override {
+        mCb.onComplete();
+        return binder::Status::ok(); // oneway, local call
+    }
+
+  private:
+    VibratorCallback mCb;
+};
+
 static constexpr int NUM_TRIES = 2;
 
+template<class R>
+inline R NoneStatus() {
+    using ::android::hardware::Status;
+    return Status::fromExceptionCode(Status::EX_NONE);
+}
+
+template<>
+inline binder::Status NoneStatus() {
+    using binder::Status;
+    return Status::fromExceptionCode(Status::EX_NONE);
+}
+
 // Creates a Return<R> with STATUS::EX_NULL_POINTER.
 template<class R>
-inline Return<R> NullptrStatus() {
+inline R NullptrStatus() {
     using ::android::hardware::Status;
-    return Return<R>{Status::fromExceptionCode(Status::EX_NULL_POINTER)};
+    return Status::fromExceptionCode(Status::EX_NULL_POINTER);
+}
+
+template<>
+inline binder::Status NullptrStatus() {
+    using binder::Status;
+    return Status::fromExceptionCode(Status::EX_NULL_POINTER);
+}
+
+template <typename I>
+sp<I> getService() {
+    return I::getService();
+}
+
+template <>
+sp<aidl::IVibrator> getService() {
+    return waitForVintfService<aidl::IVibrator>();
+}
+
+template <typename I>
+sp<I> tryGetService() {
+    return I::tryGetService();
+}
+
+template <>
+sp<aidl::IVibrator> tryGetService() {
+    return checkVintfService<aidl::IVibrator>();
 }
 
 template <typename I>
 class HalWrapper {
   public:
     static std::unique_ptr<HalWrapper> Create() {
-        sp<aidl::IVibrator> aidlVib = waitForVintfService<aidl::IVibrator>();
-        if (aidlVib) {
-            return std::unique_ptr<HalWrapper>(new HalWrapper(new VibratorShim(aidlVib)));
-        }
-
         // Assume that if getService returns a nullptr, HAL is not available on the
         // device.
-        auto hal = I::getService();
+        auto hal = getService<I>();
         return hal ? std::unique_ptr<HalWrapper>(new HalWrapper(std::move(hal))) : nullptr;
     }
 
     // Helper used to transparently deal with the vibrator HAL becoming unavailable.
     template<class R, class... Args0, class... Args1>
-    Return<R> call(Return<R> (I::* fn)(Args0...), Args1&&... args1) {
+    R call(R (I::* fn)(Args0...), Args1&&... args1) {
         // Return<R> doesn't have a default constructor, so make a Return<R> with
         // STATUS::EX_NONE.
-        using ::android::hardware::Status;
-        Return<R> ret{Status::fromExceptionCode(Status::EX_NONE)};
+        R ret{NoneStatus<R>()};
 
         // Note that ret is guaranteed to be changed after this loop.
         for (int i = 0; i < NUM_TRIES; ++i) {
@@ -266,12 +186,7 @@
             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();
-            }
+            mHal = tryGetService<I>();
         }
         return ret;
     }
@@ -290,7 +205,7 @@
 }
 
 template<class R, class I, class... Args0, class... Args1>
-Return<R> halCall(Return<R> (I::* fn)(Args0...), Args1&&... args1) {
+R halCall(R (I::* fn)(Args0...), Args1&&... args1) {
     auto hal = getHal<I>();
     return hal ? hal->call(fn, std::forward<Args1>(args1)...) : NullptrStatus<R>();
 }
@@ -307,110 +222,192 @@
 
 static void vibratorInit(JNIEnv *env, jclass clazz)
 {
-    halCall(&V1_0::IVibrator::ping).isOk();
+    if (auto hal = getHal<aidl::IVibrator>()) {
+        // IBinder::pingBinder isn't accessible as a pointer function
+        // but getCapabilities can serve the same purpose
+        int32_t cap;
+        hal->call(&aidl::IVibrator::getCapabilities, &cap).isOk();
+    } else {
+        halCall(&V1_0::IVibrator::ping).isOk();
+    }
 }
 
 static jboolean vibratorExists(JNIEnv* /* env */, jclass /* clazz */)
 {
-    return halCall(&V1_0::IVibrator::ping).isOk() ? JNI_TRUE : JNI_FALSE;
+    bool ok;
+
+    if (auto hal = getHal<aidl::IVibrator>()) {
+        // IBinder::pingBinder isn't accessible as a pointer function
+        // but getCapabilities can serve the same purpose
+        int32_t cap;
+        ok = hal->call(&aidl::IVibrator::getCapabilities, &cap).isOk();
+    } else {
+        ok = halCall(&V1_0::IVibrator::ping).isOk();
+    }
+    return ok ? JNI_TRUE : JNI_FALSE;
 }
 
 static void vibratorOn(JNIEnv* /* env */, jclass /* clazz */, jlong timeout_ms)
 {
-    Status retStatus = halCall(&V1_0::IVibrator::on, timeout_ms).withDefault(Status::UNKNOWN_ERROR);
-    if (retStatus != Status::OK) {
-        ALOGE("vibratorOn command failed (%" PRIu32 ").", static_cast<uint32_t>(retStatus));
+    if (auto hal = getHal<aidl::IVibrator>()) {
+        auto status = hal->call(&aidl::IVibrator::on, timeout_ms, nullptr);
+        if (!status.isOk()) {
+            ALOGE("vibratorOn command failed: %s", status.toString8().string());
+        }
+    } else {
+        Status retStatus = halCall(&V1_0::IVibrator::on, timeout_ms).withDefault(Status::UNKNOWN_ERROR);
+        if (retStatus != Status::OK) {
+            ALOGE("vibratorOn command failed (%" PRIu32 ").", static_cast<uint32_t>(retStatus));
+        }
     }
 }
 
 static void vibratorOff(JNIEnv* /* env */, jclass /* clazz */)
 {
-    Status retStatus = halCall(&V1_0::IVibrator::off).withDefault(Status::UNKNOWN_ERROR);
-    if (retStatus != Status::OK) {
-        ALOGE("vibratorOff command failed (%" PRIu32 ").", static_cast<uint32_t>(retStatus));
+    if (auto hal = getHal<aidl::IVibrator>()) {
+        auto status = hal->call(&aidl::IVibrator::off);
+        if (!status.isOk()) {
+            ALOGE("vibratorOff command failed: %s", status.toString8().string());
+        }
+    } else {
+        Status retStatus = halCall(&V1_0::IVibrator::off).withDefault(Status::UNKNOWN_ERROR);
+        if (retStatus != Status::OK) {
+            ALOGE("vibratorOff command failed (%" PRIu32 ").", static_cast<uint32_t>(retStatus));
+        }
     }
 }
 
 static jlong vibratorSupportsAmplitudeControl(JNIEnv*, jclass) {
-    return halCall(&V1_0::IVibrator::supportsAmplitudeControl).withDefault(false);
+    if (auto hal = getHal<aidl::IVibrator>()) {
+        int32_t cap = 0;
+        if (!hal->call(&aidl::IVibrator::getCapabilities, &cap).isOk()) {
+            return false;
+        }
+        return (cap & aidl::IVibrator::CAP_AMPLITUDE_CONTROL) > 0;
+    } else {
+        return halCall(&V1_0::IVibrator::supportsAmplitudeControl).withDefault(false);
+    }
 }
 
 static void vibratorSetAmplitude(JNIEnv*, jclass, jint amplitude) {
-    Status status = halCall(&V1_0::IVibrator::setAmplitude, static_cast<uint32_t>(amplitude))
-        .withDefault(Status::UNKNOWN_ERROR);
-    if (status != Status::OK) {
-      ALOGE("Failed to set vibrator amplitude (%" PRIu32 ").",
-            static_cast<uint32_t>(status));
+    if (auto hal = getHal<aidl::IVibrator>()) {
+        auto status = hal->call(&aidl::IVibrator::IVibrator::setAmplitude, amplitude);
+        if (!status.isOk()) {
+            ALOGE("Failed to set vibrator amplitude: %s", status.toString8().string());
+        }
+    } else {
+        Status status = halCall(&V1_0::IVibrator::setAmplitude, static_cast<uint32_t>(amplitude))
+            .withDefault(Status::UNKNOWN_ERROR);
+        if (status != Status::OK) {
+            ALOGE("Failed to set vibrator amplitude (%" PRIu32 ").",
+                  static_cast<uint32_t>(status));
+        }
     }
 }
 
 static jboolean vibratorSupportsExternalControl(JNIEnv*, jclass) {
-    return halCall(&V1_3::IVibrator::supportsExternalControl).withDefault(false);
+    if (auto hal = getHal<aidl::IVibrator>()) {
+        int32_t cap = 0;
+        if (!hal->call(&aidl::IVibrator::getCapabilities, &cap).isOk()) {
+            return false;
+        }
+        return (cap & aidl::IVibrator::CAP_EXTERNAL_CONTROL) > 0;
+    } else {
+        return halCall(&V1_3::IVibrator::supportsExternalControl).withDefault(false);
+    }
 }
 
 static void vibratorSetExternalControl(JNIEnv*, jclass, jboolean enabled) {
-    Status status = halCall(&V1_3::IVibrator::setExternalControl, static_cast<uint32_t>(enabled))
-        .withDefault(Status::UNKNOWN_ERROR);
-    if (status != Status::OK) {
-      ALOGE("Failed to set vibrator external control (%" PRIu32 ").",
-            static_cast<uint32_t>(status));
+    if (auto hal = getHal<aidl::IVibrator>()) {
+        auto status = hal->call(&aidl::IVibrator::IVibrator::setExternalControl, enabled);
+        if (!status.isOk()) {
+            ALOGE("Failed to set vibrator external control: %s", status.toString8().string());
+        }
+    } else {
+        Status status = halCall(&V1_3::IVibrator::setExternalControl, static_cast<uint32_t>(enabled))
+            .withDefault(Status::UNKNOWN_ERROR);
+        if (status != Status::OK) {
+            ALOGE("Failed to set vibrator external control (%" PRIu32 ").",
+                static_cast<uint32_t>(status));
+        }
     }
 }
 
 static jlong vibratorPerformEffect(JNIEnv* env, jclass, jlong effect, jlong strength,
                                    jobject vibration) {
-    Status status;
-    uint32_t lengthMs;
-    auto callback = [&status, &lengthMs](Status retStatus, uint32_t retLengthMs) {
-        status = retStatus;
-        lengthMs = retLengthMs;
-    };
-    EffectStrength effectStrength(static_cast<EffectStrength>(strength));
+    if (auto hal = getHal<aidl::IVibrator>()) {
+        int32_t lengthMs;
+        sp<AidlVibratorCallback> effectCallback = new AidlVibratorCallback(env, vibration);
+        aidl::Effect effectType(static_cast<aidl::Effect>(strength));
+        aidl::EffectStrength effectStrength(static_cast<aidl::EffectStrength>(strength));
 
-    Return<void> ret;
-    if (auto hal = getHal<V1_4::IVibrator>(); hal && isValidEffect<V1_3::Effect>(effect)) {
-        sp<VibratorCallback> effectCallback = new VibratorCallback(env, vibration);
-        ret = hal->call(&V1_4::IVibrator::perform_1_4, static_cast<V1_3::Effect>(effect),
-                effectStrength, effectCallback, callback);
-    } else if (isValidEffect<V1_0::Effect>(effect)) {
-        ret = halCall(&V1_0::IVibrator::perform, static_cast<V1_0::Effect>(effect),
-                effectStrength, callback);
-    } else if (isValidEffect<Effect_1_1>(effect)) {
-        ret = halCall(&V1_1::IVibrator::perform_1_1, static_cast<Effect_1_1>(effect),
-                           effectStrength, callback);
-    } else if (isValidEffect<V1_2::Effect>(effect)) {
-        ret = halCall(&V1_2::IVibrator::perform_1_2, static_cast<V1_2::Effect>(effect),
-                           effectStrength, callback);
-    } else if (isValidEffect<V1_3::Effect>(effect)) {
-        ret = halCall(&V1_3::IVibrator::perform_1_3, static_cast<V1_3::Effect>(effect),
-                           effectStrength, callback);
-    } else {
-        ALOGW("Unable to perform haptic effect, invalid effect ID (%" PRId32 ")",
-                static_cast<int32_t>(effect));
-        return -1;
-    }
-
-    if (!ret.isOk()) {
-        ALOGW("Failed to perform effect (%" PRId32 ")", static_cast<int32_t>(effect));
-        return -1;
-    }
-
-    if (status == Status::OK) {
+        auto status = hal->call(&aidl::IVibrator::perform, effectType, effectStrength, effectCallback, &lengthMs);
+        if (!status.isOk()) {
+            if (status.exceptionCode() != binder::Status::EX_UNSUPPORTED_OPERATION) {
+                ALOGE("Failed to perform haptic effect: effect=%" PRId64 ", strength=%" PRId32
+                        ": %s", static_cast<int64_t>(effect), static_cast<int32_t>(strength), status.toString8().string());
+            }
+            return -1;
+        }
         return lengthMs;
-    } else if (status != Status::UNSUPPORTED_OPERATION) {
-        // Don't warn on UNSUPPORTED_OPERATION, that's a normal event and just means the motor
-        // doesn't have a pre-defined waveform to perform for it, so we should just give the
-        // opportunity to fall back to the framework waveforms.
-        ALOGE("Failed to perform haptic effect: effect=%" PRId64 ", strength=%" PRId32
-                ", error=%" PRIu32 ").", static_cast<int64_t>(effect),
-                static_cast<int32_t>(strength), static_cast<uint32_t>(status));
+    } else {
+        Status status;
+        uint32_t lengthMs;
+        auto callback = [&status, &lengthMs](Status retStatus, uint32_t retLengthMs) {
+            status = retStatus;
+            lengthMs = retLengthMs;
+        };
+        EffectStrength effectStrength(static_cast<EffectStrength>(strength));
+
+        Return<void> ret;
+        if (isValidEffect<V1_0::Effect>(effect)) {
+            ret = halCall(&V1_0::IVibrator::perform, static_cast<V1_0::Effect>(effect),
+                    effectStrength, callback);
+        } else if (isValidEffect<Effect_1_1>(effect)) {
+            ret = halCall(&V1_1::IVibrator::perform_1_1, static_cast<Effect_1_1>(effect),
+                            effectStrength, callback);
+        } else if (isValidEffect<V1_2::Effect>(effect)) {
+            ret = halCall(&V1_2::IVibrator::perform_1_2, static_cast<V1_2::Effect>(effect),
+                            effectStrength, callback);
+        } else if (isValidEffect<V1_3::Effect>(effect)) {
+            ret = halCall(&V1_3::IVibrator::perform_1_3, static_cast<V1_3::Effect>(effect),
+                            effectStrength, callback);
+        } else {
+            ALOGW("Unable to perform haptic effect, invalid effect ID (%" PRId32 ")",
+                    static_cast<int32_t>(effect));
+            return -1;
+        }
+
+        if (!ret.isOk()) {
+            ALOGW("Failed to perform effect (%" PRId32 ")", static_cast<int32_t>(effect));
+            return -1;
+        }
+
+        if (status == Status::OK) {
+            return lengthMs;
+        } else if (status != Status::UNSUPPORTED_OPERATION) {
+            // Don't warn on UNSUPPORTED_OPERATION, that's a normal event and just means the motor
+            // doesn't have a pre-defined waveform to perform for it, so we should just give the
+            // opportunity to fall back to the framework waveforms.
+            ALOGE("Failed to perform haptic effect: effect=%" PRId64 ", strength=%" PRId32
+                    ", error=%" PRIu32 ").", static_cast<int64_t>(effect),
+                    static_cast<int32_t>(strength), static_cast<uint32_t>(status));
+        }
     }
 
     return -1;
 }
 
 static jlong vibratorGetCapabilities(JNIEnv*, jclass) {
-    return halCall(&V1_4::IVibrator::getCapabilities).withDefault(0);
+    if (auto hal = getHal<aidl::IVibrator>()) {
+        int32_t cap = 0;
+        if (!hal->call(&aidl::IVibrator::getCapabilities, &cap).isOk()) {
+            return 0;
+        }
+        return cap;
+    }
+
+    return 0;
 }
 
 static const JNINativeMethod method_table[] = {