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

Commit b14c463c authored by Lais Andrade's avatar Lais Andrade
Browse files

Start using vibrator HAL controller in VibratorService

This change does not cover the vibrate methods (on, perform and
compose). The controller is used in all other service native
methods.

This also removes the getters for amplitude and external controls, and
relies only on the HAL capabilities for both checks.

Bug: b/153418251
Test: atest FrameworksServicesTests:VibratorServiceTest
Change-Id: Ia79137b4d34c9224c14b596845dcd95dd3c92067
parent 679825e9
Loading
Loading
Loading
Loading
+52 −43
Original line number Diff line number Diff line
@@ -76,6 +76,8 @@ import com.android.internal.app.IBatteryStats;
import com.android.internal.util.DumpUtils;
import com.android.internal.util.FrameworkStatsLog;

import libcore.util.NativeAllocationRegistry;

import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
@@ -115,7 +117,6 @@ public class VibratorService extends IVibratorService.Stub
    // If HAL supports callbacks set the timeout to ASYNC_TIMEOUT_MULTIPLIER * duration.
    private static final long ASYNC_TIMEOUT_MULTIPLIER = 2;


    // A mapping from the intensity adjustment to the scaling to apply, where the intensity
    // adjustment is defined as the delta between the default intensity level and the user selected
    // intensity level. It's important that we apply the scaling on the delta between the two so
@@ -128,8 +129,6 @@ public class VibratorService extends IVibratorService.Stub
    private final LinkedList<VibrationInfo> mPreviousVibrations;
    private final int mPreviousVibrationsLimit;
    private final boolean mAllowPriorityVibrationsInLowPowerMode;
    private final boolean mSupportsAmplitudeControl;
    private final boolean mSupportsExternalControl;
    private final List<Integer> mSupportedEffects;
    private final long mCapabilities;
    private final int mDefaultVibrationAmplitude;
@@ -174,22 +173,23 @@ public class VibratorService extends IVibratorService.Stub
    private int mRingIntensity;
    private SparseArray<Vibration> mAlwaysOnEffects = new SparseArray<>();

    static native boolean vibratorExists();
    static native void vibratorInit();
    static native long vibratorInit();

    static native long vibratorGetFinalizer();
    static native boolean vibratorExists(long controllerPtr);
    static native void vibratorOn(long milliseconds);
    static native void vibratorOff();
    static native boolean vibratorSupportsAmplitudeControl();
    static native void vibratorSetAmplitude(int amplitude);
    static native int[] vibratorGetSupportedEffects();
    static native void vibratorOff(long controllerPtr);
    static native void vibratorSetAmplitude(long controllerPtr, int amplitude);
    static native int[] vibratorGetSupportedEffects(long controllerPtr);
    static native long vibratorPerformEffect(long effect, long strength, Vibration vibration,
            boolean withCallback);
    static native void vibratorPerformComposedEffect(
            VibrationEffect.Composition.PrimitiveEffect[] effect, Vibration vibration);
    static native boolean vibratorSupportsExternalControl();
    static native void vibratorSetExternalControl(boolean enabled);
    static native long vibratorGetCapabilities();
    static native void vibratorAlwaysOnEnable(long id, long effect, long strength);
    static native void vibratorAlwaysOnDisable(long id);
    static native void vibratorSetExternalControl(long controllerPtr, boolean enabled);
    static native long vibratorGetCapabilities(long controllerPtr);
    static native void vibratorAlwaysOnEnable(long controllerPtr, long id, long effect,
            long strength);
    static native void vibratorAlwaysOnDisable(long controllerPtr, long id);

    private final IUidObserver mUidObserver = new IUidObserver.Stub() {
        @Override public void onUidStateChanged(int uid, int procState, long procStateSeq,
@@ -370,13 +370,20 @@ public class VibratorService extends IVibratorService.Stub
        mNativeWrapper = injector.getNativeWrapper();
        mH = injector.createHandler(Looper.myLooper());

        mNativeWrapper.vibratorInit();
        long controllerPtr = mNativeWrapper.vibratorInit();
        long finalizerPtr = mNativeWrapper.vibratorGetFinalizer();

        if (finalizerPtr != 0) {
            NativeAllocationRegistry registry =
                    NativeAllocationRegistry.createMalloced(
                            VibratorService.class.getClassLoader(), finalizerPtr);
            registry.registerNativeAllocation(this, controllerPtr);
        }

        // Reset the hardware to a default state, in case this is a runtime
        // restart instead of a fresh boot.
        mNativeWrapper.vibratorOff();

        mSupportsAmplitudeControl = mNativeWrapper.vibratorSupportsAmplitudeControl();
        mSupportsExternalControl = mNativeWrapper.vibratorSupportsExternalControl();
        mSupportedEffects = asList(mNativeWrapper.vibratorGetSupportedEffects());
        mCapabilities = mNativeWrapper.vibratorGetCapabilities();

@@ -605,7 +612,8 @@ public class VibratorService extends IVibratorService.Stub
        synchronized (mInputDeviceVibrators) {
            // Input device vibrators don't support amplitude controls yet, but are still used over
            // the system vibrator when connected.
            return mSupportsAmplitudeControl && mInputDeviceVibrators.isEmpty();
            return hasCapability(IVibrator.CAP_AMPLITUDE_CONTROL)
                    && mInputDeviceVibrators.isEmpty();
        }
    }

@@ -1288,7 +1296,7 @@ public class VibratorService extends IVibratorService.Stub
    }

    private void doVibratorSetAmplitude(int amplitude) {
        if (mSupportsAmplitudeControl) {
        if (hasCapability(IVibrator.CAP_AMPLITUDE_CONTROL)) {
            mNativeWrapper.vibratorSetAmplitude(amplitude);
        }
    }
@@ -1708,14 +1716,25 @@ public class VibratorService extends IVibratorService.Stub
    @VisibleForTesting
    public static class NativeWrapper {

        private long mNativeControllerPtr = 0;

        /** Checks if vibrator exists on device. */
        public boolean vibratorExists() {
            return VibratorService.vibratorExists();
            return VibratorService.vibratorExists(mNativeControllerPtr);
        }

        /** Initializes connection to vibrator HAL service. */
        public void vibratorInit() {
            VibratorService.vibratorInit();
        /**
         * Returns native pointer to newly created controller and initializes connection to vibrator
         * HAL service.
         */
        public long vibratorInit() {
            mNativeControllerPtr = VibratorService.vibratorInit();
            return mNativeControllerPtr;
        }

        /** Returns pointer to native finalizer function to be called by GC. */
        public long vibratorGetFinalizer() {
            return VibratorService.vibratorGetFinalizer();
        }

        /** Turns vibrator on for given time. */
@@ -1725,22 +1744,17 @@ public class VibratorService extends IVibratorService.Stub

        /** Turns vibrator off. */
        public void vibratorOff() {
            VibratorService.vibratorOff();
        }

        /** Returns true if vibrator supports {@link #vibratorSetAmplitude(int)}. */
        public boolean vibratorSupportsAmplitudeControl() {
            return VibratorService.vibratorSupportsAmplitudeControl();
            VibratorService.vibratorOff(mNativeControllerPtr);
        }

        /** Sets the amplitude for the vibrator to run. */
        public void vibratorSetAmplitude(int amplitude) {
            VibratorService.vibratorSetAmplitude(amplitude);
            VibratorService.vibratorSetAmplitude(mNativeControllerPtr, amplitude);
        }

        /** Returns all predefined effects supported by the device vibrator. */
        public int[] vibratorGetSupportedEffects() {
            return VibratorService.vibratorGetSupportedEffects();
            return VibratorService.vibratorGetSupportedEffects(mNativeControllerPtr);
        }

        /** Turns vibrator on to perform one of the supported effects. */
@@ -1755,29 +1769,24 @@ public class VibratorService extends IVibratorService.Stub
            VibratorService.vibratorPerformComposedEffect(effect, vibration);
        }

        /** Returns true if vibrator supports {@link #vibratorSetExternalControl(boolean)}. */
        public boolean vibratorSupportsExternalControl() {
            return VibratorService.vibratorSupportsExternalControl();
        }

        /** Enabled the device vibrator to be controlled by another service. */
        public void vibratorSetExternalControl(boolean enabled) {
            VibratorService.vibratorSetExternalControl(enabled);
            VibratorService.vibratorSetExternalControl(mNativeControllerPtr, enabled);
        }

        /** Returns all capabilities of the device vibrator. */
        public long vibratorGetCapabilities() {
            return VibratorService.vibratorGetCapabilities();
            return VibratorService.vibratorGetCapabilities(mNativeControllerPtr);
        }

        /** Enable always-on vibration with given id and effect. */
        public void vibratorAlwaysOnEnable(long id, long effect, long strength) {
            VibratorService.vibratorAlwaysOnEnable(id, effect, strength);
            VibratorService.vibratorAlwaysOnEnable(mNativeControllerPtr, id, effect, strength);
        }

        /** Disable always-on vibration for given id. */
        public void vibratorAlwaysOnDisable(long id) {
            VibratorService.vibratorAlwaysOnDisable(id);
            VibratorService.vibratorAlwaysOnDisable(mNativeControllerPtr, id);
        }
    }

@@ -1852,7 +1861,7 @@ public class VibratorService extends IVibratorService.Stub

        @Override
        public int onExternalVibrationStart(ExternalVibration vib) {
            if (!mSupportsExternalControl) {
            if (!hasCapability(IVibrator.CAP_EXTERNAL_CONTROL)) {
                return SCALE_MUTE;
            }
            if (ActivityManager.checkComponentPermission(android.Manifest.permission.VIBRATE,
@@ -2142,10 +2151,10 @@ public class VibratorService extends IVibratorService.Stub
                if (hasCapability(IVibrator.CAP_COMPOSE_EFFECTS)) {
                    pw.println("  Compose effects");
                }
                if (mSupportsAmplitudeControl || hasCapability(IVibrator.CAP_AMPLITUDE_CONTROL)) {
                if (hasCapability(IVibrator.CAP_AMPLITUDE_CONTROL)) {
                    pw.println("  Amplitude control");
                }
                if (mSupportsExternalControl || hasCapability(IVibrator.CAP_EXTERNAL_CONTROL)) {
                if (hasCapability(IVibrator.CAP_EXTERNAL_CONTROL)) {
                    pw.println("  External control");
                }
                if (hasCapability(IVibrator.CAP_EXTERNAL_AMPLITUDE_CONTROL)) {
+1 −0
Original line number Diff line number Diff line
@@ -99,6 +99,7 @@ cc_defaults {
        "libpowermanager",
        "libutils",
        "libui",
        "libvibratorservice",
        "libinput",
        "libinputflinger",
        "libinputflinger_base",
+112 −136
Original line number Diff line number Diff line
@@ -33,6 +33,8 @@
#include <inttypes.h>
#include <stdio.h>

#include <vibratorservice/VibratorHalController.h>

using android::hardware::Return;
using android::hardware::Void;
using android::hardware::vibrator::V1_0::EffectStrength;
@@ -226,8 +228,24 @@ bool isValidEffect(jlong effect) {
    return val >= *iter.begin() && val <= *std::prev(iter.end());
}

static void vibratorInit(JNIEnv *env, jclass clazz)
{
static aidl::CompositeEffect effectFromJavaPrimitive(JNIEnv* env, jobject primitive) {
    aidl::CompositeEffect effect;
    effect.primitive = static_cast<aidl::CompositePrimitive>(
            env->GetIntField(primitive, gPrimitiveClassInfo.id));
    effect.scale = static_cast<float>(env->GetFloatField(primitive, gPrimitiveClassInfo.scale));
    effect.delayMs = static_cast<int32_t>(env->GetIntField(primitive, gPrimitiveClassInfo.delay));
    return effect;
}

static void destroyVibratorController(void* rawVibratorController) {
    vibrator::HalController* vibratorController =
            reinterpret_cast<vibrator::HalController*>(rawVibratorController);
    if (vibratorController) {
        delete vibratorController;
    }
}

static jlong vibratorInit(JNIEnv* /* env */, jclass /* clazz */) {
    if (auto hal = getHal<aidl::IVibrator>()) {
        // IBinder::pingBinder isn't accessible as a pointer function
        // but getCapabilities can serve the same purpose
@@ -236,25 +254,26 @@ static void vibratorInit(JNIEnv *env, jclass clazz)
    } else {
        halCall(&V1_0::IVibrator::ping).isOk();
    }
    std::unique_ptr<vibrator::HalController> controller =
            std::make_unique<vibrator::HalController>();
    controller->init();
    return reinterpret_cast<jlong>(controller.release());
}

static jboolean vibratorExists(JNIEnv* /* env */, jclass /* clazz */)
{
    bool ok;
static jlong vibratorGetFinalizer(JNIEnv* /* env */, jclass /* clazz */) {
    return static_cast<jlong>(reinterpret_cast<uintptr_t>(&destroyVibratorController));
}

    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();
static jboolean vibratorExists(JNIEnv* env, jclass /* clazz */, jlong controllerPtr) {
    vibrator::HalController* controller = reinterpret_cast<vibrator::HalController*>(controllerPtr);
    if (controller == nullptr) {
        ALOGE("vibratorExists failed because controller was not initialized");
        return JNI_FALSE;
    }
    return ok ? JNI_TRUE : JNI_FALSE;
    return controller->ping().isOk() ? JNI_TRUE : JNI_FALSE;
}

static void vibratorOn(JNIEnv* /* env */, jclass /* clazz */, jlong timeout_ms)
{
static void vibratorOn(JNIEnv* /* env */, jclass /* clazz */, jlong timeout_ms) {
    if (auto hal = getHal<aidl::IVibrator>()) {
        auto status = hal->call(&aidl::IVibrator::on, timeout_ms, nullptr);
        if (!status.isOk()) {
@@ -268,93 +287,53 @@ static void vibratorOn(JNIEnv* /* env */, jclass /* clazz */, jlong timeout_ms)
    }
}

static void vibratorOff(JNIEnv* /* env */, jclass /* clazz */)
{
    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) {
    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) {
    if (auto hal = getHal<aidl::IVibrator>()) {
        auto status = hal->call(&aidl::IVibrator::IVibrator::setAmplitude, static_cast<float>(amplitude) / UINT8_MAX);
        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 void vibratorOff(JNIEnv* env, jclass /* clazz */, jlong controllerPtr) {
    vibrator::HalController* controller = reinterpret_cast<vibrator::HalController*>(controllerPtr);
    if (controller == nullptr) {
        ALOGE("vibratorOff failed because controller was not initialized");
        return;
    }
    controller->off();
}

static jboolean vibratorSupportsExternalControl(JNIEnv*, jclass) {
    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 vibratorSetAmplitude(JNIEnv* env, jclass /* clazz */, jlong controllerPtr,
                                 jint amplitude) {
    vibrator::HalController* controller = reinterpret_cast<vibrator::HalController*>(controllerPtr);
    if (controller == nullptr) {
        ALOGE("vibratorSetAmplitude failed because controller was not initialized");
        return;
    }
    controller->setAmplitude(static_cast<int32_t>(amplitude));
}

static void vibratorSetExternalControl(JNIEnv*, jclass, jboolean enabled) {
    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 void vibratorSetExternalControl(JNIEnv* env, jclass /* clazz */, jlong controllerPtr,
                                       jboolean enabled) {
    vibrator::HalController* controller = reinterpret_cast<vibrator::HalController*>(controllerPtr);
    if (controller == nullptr) {
        ALOGE("vibratorSetExternalControl failed because controller was not initialized");
        return;
    }
    controller->setExternalControl(enabled);
}

static jintArray vibratorGetSupportedEffects(JNIEnv *env, jclass) {
    if (auto hal = getHal<aidl::IVibrator>()) {
        std::vector<aidl::Effect> supportedEffects;
        if (!hal->call(&aidl::IVibrator::getSupportedEffects, &supportedEffects).isOk()) {
static jintArray vibratorGetSupportedEffects(JNIEnv* env, jclass /* clazz */, jlong controllerPtr) {
    vibrator::HalController* controller = reinterpret_cast<vibrator::HalController*>(controllerPtr);
    if (controller == nullptr) {
        ALOGE("vibratorGetSupportedEffects failed because controller was not initialized");
        return nullptr;
    }
        jintArray arr = env->NewIntArray(supportedEffects.size());
        env->SetIntArrayRegion(arr, 0, supportedEffects.size(),
                reinterpret_cast<jint*>(supportedEffects.data()));
        return arr;
    } else {
    auto result = controller->getSupportedEffects();
    if (!result.isOk()) {
        return nullptr;
    }
    std::vector<aidl::Effect> supportedEffects = result.value();
    jintArray effects = env->NewIntArray(supportedEffects.size());
    env->SetIntArrayRegion(effects, 0, supportedEffects.size(),
                           reinterpret_cast<jint*>(supportedEffects.data()));
    return effects;
}

static jlong vibratorPerformEffect(JNIEnv* env, jclass, jlong effect, jlong strength,
static jlong vibratorPerformEffect(JNIEnv* env, jclass /* clazz */, jlong effect, jlong strength,
                                   jobject vibration, jboolean withCallback) {
    if (auto hal = getHal<aidl::IVibrator>()) {
        int32_t lengthMs;
@@ -420,16 +399,7 @@ static jlong vibratorPerformEffect(JNIEnv* env, jclass, jlong effect, jlong stre
    return -1;
}

static aidl::CompositeEffect effectFromJavaPrimitive(JNIEnv* env, jobject primitive) {
    aidl::CompositeEffect effect;
    effect.primitive = static_cast<aidl::CompositePrimitive>(
            env->GetIntField(primitive, gPrimitiveClassInfo.id));
    effect.scale = static_cast<float>(env->GetFloatField(primitive, gPrimitiveClassInfo.scale));
    effect.delayMs = static_cast<int>(env->GetIntField(primitive, gPrimitiveClassInfo.delay));
    return effect;
}

static void vibratorPerformComposedEffect(JNIEnv* env, jclass, jobjectArray composition,
static void vibratorPerformComposedEffect(JNIEnv* env, jclass /* clazz */, jobjectArray composition,
                                          jobject vibration) {
    auto hal = getHal<aidl::IVibrator>();
    if (!hal) {
@@ -451,65 +421,71 @@ static void vibratorPerformComposedEffect(JNIEnv* env, jclass, jobjectArray comp
    }
}

static jlong vibratorGetCapabilities(JNIEnv*, jclass) {
    if (auto hal = getHal<aidl::IVibrator>()) {
        int32_t cap = 0;
        if (!hal->call(&aidl::IVibrator::getCapabilities, &cap).isOk()) {
static jlong vibratorGetCapabilities(JNIEnv* env, jclass /* clazz */, jlong controllerPtr) {
    vibrator::HalController* controller = reinterpret_cast<vibrator::HalController*>(controllerPtr);
    if (controller == nullptr) {
        ALOGE("vibratorGetCapabilities failed because controller was not initialized");
        return 0;
    }
        return cap;
    }

    return 0;
    auto result = controller->getCapabilities();
    return result.isOk() ? static_cast<jlong>(result.value()) : 0;
}

static void vibratorAlwaysOnEnable(JNIEnv* env, jclass, jlong id, jlong effect, jlong strength) {
    auto status = halCall(&aidl::IVibrator::alwaysOnEnable, id,
            static_cast<aidl::Effect>(effect), static_cast<aidl::EffectStrength>(strength));
    if (!status.isOk()) {
        ALOGE("vibratortAlwaysOnEnable command failed (%s).", status.toString8().string());
static void vibratorAlwaysOnEnable(JNIEnv* env, jclass /* clazz */, jlong controllerPtr, jlong id,
                                   jlong effect, jlong strength) {
    vibrator::HalController* controller = reinterpret_cast<vibrator::HalController*>(controllerPtr);
    if (controller == nullptr) {
        ALOGE("vibratorAlwaysOnEnable failed because controller was not initialized");
        return;
    }
    controller->alwaysOnEnable(static_cast<int32_t>(id), static_cast<aidl::Effect>(effect),
                               static_cast<aidl::EffectStrength>(strength));
}

static void vibratorAlwaysOnDisable(JNIEnv* env, jclass, jlong id) {
    auto status = halCall(&aidl::IVibrator::alwaysOnDisable, id);
    if (!status.isOk()) {
        ALOGE("vibratorAlwaysOnDisable command failed (%s).", status.toString8().string());
static void vibratorAlwaysOnDisable(JNIEnv* env, jclass /* clazz */, jlong controllerPtr,
                                    jlong id) {
    vibrator::HalController* controller = reinterpret_cast<vibrator::HalController*>(controllerPtr);
    if (controller == nullptr) {
        ALOGE("vibratorAlwaysOnDisable failed because controller was not initialized");
        return;
    }
    controller->alwaysOnDisable(static_cast<int32_t>(id));
}

static const JNINativeMethod method_table[] = {
        {"vibratorExists", "()Z", (void*)vibratorExists},
        {"vibratorInit", "()V", (void*)vibratorInit},
        {"vibratorInit", "()J", (void*)vibratorInit},
        {"vibratorGetFinalizer", "()J", (void*)vibratorGetFinalizer},
        {"vibratorExists", "(J)Z", (void*)vibratorExists},
        {"vibratorOn", "(J)V", (void*)vibratorOn},
        {"vibratorOff", "()V", (void*)vibratorOff},
        {"vibratorSupportsAmplitudeControl", "()Z", (void*)vibratorSupportsAmplitudeControl},
        {"vibratorSetAmplitude", "(I)V", (void*)vibratorSetAmplitude},
        {"vibratorOff", "(J)V", (void*)vibratorOff},
        {"vibratorSetAmplitude", "(JI)V", (void*)vibratorSetAmplitude},
        {"vibratorPerformEffect", "(JJLcom/android/server/VibratorService$Vibration;Z)J",
         (void*)vibratorPerformEffect},
        {"vibratorPerformComposedEffect",
         "([Landroid/os/VibrationEffect$Composition$PrimitiveEffect;Lcom/android/server/"
         "VibratorService$Vibration;)V",
         (void*)vibratorPerformComposedEffect},
        {"vibratorGetSupportedEffects", "()[I", (void*)vibratorGetSupportedEffects},
        {"vibratorSupportsExternalControl", "()Z", (void*)vibratorSupportsExternalControl},
        {"vibratorSetExternalControl", "(Z)V", (void*)vibratorSetExternalControl},
        {"vibratorGetCapabilities", "()J", (void*)vibratorGetCapabilities},
        {"vibratorAlwaysOnEnable", "(JJJ)V", (void*)vibratorAlwaysOnEnable},
        {"vibratorAlwaysOnDisable", "(J)V", (void*)vibratorAlwaysOnDisable},
        {"vibratorGetSupportedEffects", "(J)[I", (void*)vibratorGetSupportedEffects},
        {"vibratorSetExternalControl", "(JZ)V", (void*)vibratorSetExternalControl},
        {"vibratorGetCapabilities", "(J)J", (void*)vibratorGetCapabilities},
        {"vibratorAlwaysOnEnable", "(JJJJ)V", (void*)vibratorAlwaysOnEnable},
        {"vibratorAlwaysOnDisable", "(JJ)V", (void*)vibratorAlwaysOnDisable},
};

int register_android_server_VibratorService(JNIEnv *env) {
    sMethodIdOnComplete = GetMethodIDOrDie(env,
    sMethodIdOnComplete =
            GetMethodIDOrDie(env,
                             FindClassOrDie(env, "com/android/server/VibratorService$Vibration"),
                             "onComplete", "()V");
    jclass primitiveClass = FindClassOrDie(env,
            "android/os/VibrationEffect$Composition$PrimitiveEffect");

    jclass primitiveClass =
            FindClassOrDie(env, "android/os/VibrationEffect$Composition$PrimitiveEffect");
    gPrimitiveClassInfo.id = GetFieldIDOrDie(env, primitiveClass, "id", "I");
    gPrimitiveClassInfo.scale = GetFieldIDOrDie(env, primitiveClass, "scale", "F");
    gPrimitiveClassInfo.delay = GetFieldIDOrDie(env, primitiveClass, "delay", "I");
    return jniRegisterNativeMethods(env, "com/android/server/VibratorService",
            method_table, NELEM(method_table));

    return jniRegisterNativeMethods(env, "com/android/server/VibratorService", method_table,
                                    NELEM(method_table));
}

};
}; // namespace android
+4 −5

File changed.

Preview size limit exceeded, changes collapsed.