Loading services/core/java/com/android/server/VibratorService.java +52 −43 Original line number Original line Diff line number Diff line Loading @@ -76,6 +76,8 @@ import com.android.internal.app.IBatteryStats; import com.android.internal.util.DumpUtils; import com.android.internal.util.DumpUtils; import com.android.internal.util.FrameworkStatsLog; import com.android.internal.util.FrameworkStatsLog; import libcore.util.NativeAllocationRegistry; import java.io.FileDescriptor; import java.io.FileDescriptor; import java.io.PrintWriter; import java.io.PrintWriter; import java.util.ArrayList; import java.util.ArrayList; Loading Loading @@ -115,7 +117,6 @@ public class VibratorService extends IVibratorService.Stub // If HAL supports callbacks set the timeout to ASYNC_TIMEOUT_MULTIPLIER * duration. // If HAL supports callbacks set the timeout to ASYNC_TIMEOUT_MULTIPLIER * duration. private static final long ASYNC_TIMEOUT_MULTIPLIER = 2; private static final long ASYNC_TIMEOUT_MULTIPLIER = 2; // A mapping from the intensity adjustment to the scaling to apply, where the intensity // 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 // 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 // intensity level. It's important that we apply the scaling on the delta between the two so Loading @@ -128,8 +129,6 @@ public class VibratorService extends IVibratorService.Stub private final LinkedList<VibrationInfo> mPreviousVibrations; private final LinkedList<VibrationInfo> mPreviousVibrations; private final int mPreviousVibrationsLimit; private final int mPreviousVibrationsLimit; private final boolean mAllowPriorityVibrationsInLowPowerMode; private final boolean mAllowPriorityVibrationsInLowPowerMode; private final boolean mSupportsAmplitudeControl; private final boolean mSupportsExternalControl; private final List<Integer> mSupportedEffects; private final List<Integer> mSupportedEffects; private final long mCapabilities; private final long mCapabilities; private final int mDefaultVibrationAmplitude; private final int mDefaultVibrationAmplitude; Loading Loading @@ -174,22 +173,23 @@ public class VibratorService extends IVibratorService.Stub private int mRingIntensity; private int mRingIntensity; private SparseArray<Vibration> mAlwaysOnEffects = new SparseArray<>(); private SparseArray<Vibration> mAlwaysOnEffects = new SparseArray<>(); static native boolean vibratorExists(); static native long vibratorInit(); static native void vibratorInit(); static native long vibratorGetFinalizer(); static native boolean vibratorExists(long controllerPtr); static native void vibratorOn(long milliseconds); static native void vibratorOn(long milliseconds); static native void vibratorOff(); static native void vibratorOff(long controllerPtr); static native boolean vibratorSupportsAmplitudeControl(); static native void vibratorSetAmplitude(long controllerPtr, int amplitude); static native void vibratorSetAmplitude(int amplitude); static native int[] vibratorGetSupportedEffects(long controllerPtr); static native int[] vibratorGetSupportedEffects(); static native long vibratorPerformEffect(long effect, long strength, Vibration vibration, static native long vibratorPerformEffect(long effect, long strength, Vibration vibration, boolean withCallback); boolean withCallback); static native void vibratorPerformComposedEffect( static native void vibratorPerformComposedEffect( VibrationEffect.Composition.PrimitiveEffect[] effect, Vibration vibration); VibrationEffect.Composition.PrimitiveEffect[] effect, Vibration vibration); static native boolean vibratorSupportsExternalControl(); static native void vibratorSetExternalControl(long controllerPtr, boolean enabled); static native void vibratorSetExternalControl(boolean enabled); static native long vibratorGetCapabilities(long controllerPtr); static native long vibratorGetCapabilities(); static native void vibratorAlwaysOnEnable(long controllerPtr, long id, long effect, static native void vibratorAlwaysOnEnable(long id, long effect, long strength); long strength); static native void vibratorAlwaysOnDisable(long id); static native void vibratorAlwaysOnDisable(long controllerPtr, long id); private final IUidObserver mUidObserver = new IUidObserver.Stub() { private final IUidObserver mUidObserver = new IUidObserver.Stub() { @Override public void onUidStateChanged(int uid, int procState, long procStateSeq, @Override public void onUidStateChanged(int uid, int procState, long procStateSeq, Loading Loading @@ -370,13 +370,20 @@ public class VibratorService extends IVibratorService.Stub mNativeWrapper = injector.getNativeWrapper(); mNativeWrapper = injector.getNativeWrapper(); mH = injector.createHandler(Looper.myLooper()); 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 // Reset the hardware to a default state, in case this is a runtime // restart instead of a fresh boot. // restart instead of a fresh boot. mNativeWrapper.vibratorOff(); mNativeWrapper.vibratorOff(); mSupportsAmplitudeControl = mNativeWrapper.vibratorSupportsAmplitudeControl(); mSupportsExternalControl = mNativeWrapper.vibratorSupportsExternalControl(); mSupportedEffects = asList(mNativeWrapper.vibratorGetSupportedEffects()); mSupportedEffects = asList(mNativeWrapper.vibratorGetSupportedEffects()); mCapabilities = mNativeWrapper.vibratorGetCapabilities(); mCapabilities = mNativeWrapper.vibratorGetCapabilities(); Loading Loading @@ -605,7 +612,8 @@ public class VibratorService extends IVibratorService.Stub synchronized (mInputDeviceVibrators) { synchronized (mInputDeviceVibrators) { // Input device vibrators don't support amplitude controls yet, but are still used over // Input device vibrators don't support amplitude controls yet, but are still used over // the system vibrator when connected. // the system vibrator when connected. return mSupportsAmplitudeControl && mInputDeviceVibrators.isEmpty(); return hasCapability(IVibrator.CAP_AMPLITUDE_CONTROL) && mInputDeviceVibrators.isEmpty(); } } } } Loading Loading @@ -1288,7 +1296,7 @@ public class VibratorService extends IVibratorService.Stub } } private void doVibratorSetAmplitude(int amplitude) { private void doVibratorSetAmplitude(int amplitude) { if (mSupportsAmplitudeControl) { if (hasCapability(IVibrator.CAP_AMPLITUDE_CONTROL)) { mNativeWrapper.vibratorSetAmplitude(amplitude); mNativeWrapper.vibratorSetAmplitude(amplitude); } } } } Loading Loading @@ -1708,14 +1716,25 @@ public class VibratorService extends IVibratorService.Stub @VisibleForTesting @VisibleForTesting public static class NativeWrapper { public static class NativeWrapper { private long mNativeControllerPtr = 0; /** Checks if vibrator exists on device. */ /** Checks if vibrator exists on device. */ public boolean vibratorExists() { public boolean vibratorExists() { return VibratorService.vibratorExists(); return VibratorService.vibratorExists(mNativeControllerPtr); } } /** Initializes connection to vibrator HAL service. */ /** public void vibratorInit() { * Returns native pointer to newly created controller and initializes connection to vibrator VibratorService.vibratorInit(); * 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. */ /** Turns vibrator on for given time. */ Loading @@ -1725,22 +1744,17 @@ public class VibratorService extends IVibratorService.Stub /** Turns vibrator off. */ /** Turns vibrator off. */ public void vibratorOff() { public void vibratorOff() { VibratorService.vibratorOff(); VibratorService.vibratorOff(mNativeControllerPtr); } /** Returns true if vibrator supports {@link #vibratorSetAmplitude(int)}. */ public boolean vibratorSupportsAmplitudeControl() { return VibratorService.vibratorSupportsAmplitudeControl(); } } /** Sets the amplitude for the vibrator to run. */ /** Sets the amplitude for the vibrator to run. */ public void vibratorSetAmplitude(int amplitude) { public void vibratorSetAmplitude(int amplitude) { VibratorService.vibratorSetAmplitude(amplitude); VibratorService.vibratorSetAmplitude(mNativeControllerPtr, amplitude); } } /** Returns all predefined effects supported by the device vibrator. */ /** Returns all predefined effects supported by the device vibrator. */ public int[] vibratorGetSupportedEffects() { public int[] vibratorGetSupportedEffects() { return VibratorService.vibratorGetSupportedEffects(); return VibratorService.vibratorGetSupportedEffects(mNativeControllerPtr); } } /** Turns vibrator on to perform one of the supported effects. */ /** Turns vibrator on to perform one of the supported effects. */ Loading @@ -1755,29 +1769,24 @@ public class VibratorService extends IVibratorService.Stub VibratorService.vibratorPerformComposedEffect(effect, vibration); 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. */ /** Enabled the device vibrator to be controlled by another service. */ public void vibratorSetExternalControl(boolean enabled) { public void vibratorSetExternalControl(boolean enabled) { VibratorService.vibratorSetExternalControl(enabled); VibratorService.vibratorSetExternalControl(mNativeControllerPtr, enabled); } } /** Returns all capabilities of the device vibrator. */ /** Returns all capabilities of the device vibrator. */ public long vibratorGetCapabilities() { public long vibratorGetCapabilities() { return VibratorService.vibratorGetCapabilities(); return VibratorService.vibratorGetCapabilities(mNativeControllerPtr); } } /** Enable always-on vibration with given id and effect. */ /** Enable always-on vibration with given id and effect. */ public void vibratorAlwaysOnEnable(long id, long effect, long strength) { 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. */ /** Disable always-on vibration for given id. */ public void vibratorAlwaysOnDisable(long id) { public void vibratorAlwaysOnDisable(long id) { VibratorService.vibratorAlwaysOnDisable(id); VibratorService.vibratorAlwaysOnDisable(mNativeControllerPtr, id); } } } } Loading Loading @@ -1852,7 +1861,7 @@ public class VibratorService extends IVibratorService.Stub @Override @Override public int onExternalVibrationStart(ExternalVibration vib) { public int onExternalVibrationStart(ExternalVibration vib) { if (!mSupportsExternalControl) { if (!hasCapability(IVibrator.CAP_EXTERNAL_CONTROL)) { return SCALE_MUTE; return SCALE_MUTE; } } if (ActivityManager.checkComponentPermission(android.Manifest.permission.VIBRATE, if (ActivityManager.checkComponentPermission(android.Manifest.permission.VIBRATE, Loading Loading @@ -2142,10 +2151,10 @@ public class VibratorService extends IVibratorService.Stub if (hasCapability(IVibrator.CAP_COMPOSE_EFFECTS)) { if (hasCapability(IVibrator.CAP_COMPOSE_EFFECTS)) { pw.println(" Compose effects"); pw.println(" Compose effects"); } } if (mSupportsAmplitudeControl || hasCapability(IVibrator.CAP_AMPLITUDE_CONTROL)) { if (hasCapability(IVibrator.CAP_AMPLITUDE_CONTROL)) { pw.println(" Amplitude control"); pw.println(" Amplitude control"); } } if (mSupportsExternalControl || hasCapability(IVibrator.CAP_EXTERNAL_CONTROL)) { if (hasCapability(IVibrator.CAP_EXTERNAL_CONTROL)) { pw.println(" External control"); pw.println(" External control"); } } if (hasCapability(IVibrator.CAP_EXTERNAL_AMPLITUDE_CONTROL)) { if (hasCapability(IVibrator.CAP_EXTERNAL_AMPLITUDE_CONTROL)) { Loading services/core/jni/Android.bp +1 −0 Original line number Original line Diff line number Diff line Loading @@ -99,6 +99,7 @@ cc_defaults { "libpowermanager", "libpowermanager", "libutils", "libutils", "libui", "libui", "libvibratorservice", "libinput", "libinput", "libinputflinger", "libinputflinger", "libinputflinger_base", "libinputflinger_base", Loading services/core/jni/com_android_server_VibratorService.cpp +112 −136 Original line number Original line Diff line number Diff line Loading @@ -33,6 +33,8 @@ #include <inttypes.h> #include <inttypes.h> #include <stdio.h> #include <stdio.h> #include <vibratorservice/VibratorHalController.h> using android::hardware::Return; using android::hardware::Return; using android::hardware::Void; using android::hardware::Void; using android::hardware::vibrator::V1_0::EffectStrength; using android::hardware::vibrator::V1_0::EffectStrength; Loading Loading @@ -226,8 +228,24 @@ bool isValidEffect(jlong effect) { return val >= *iter.begin() && val <= *std::prev(iter.end()); 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>()) { if (auto hal = getHal<aidl::IVibrator>()) { // IBinder::pingBinder isn't accessible as a pointer function // IBinder::pingBinder isn't accessible as a pointer function // but getCapabilities can serve the same purpose // but getCapabilities can serve the same purpose Loading @@ -236,25 +254,26 @@ static void vibratorInit(JNIEnv *env, jclass clazz) } else { } else { halCall(&V1_0::IVibrator::ping).isOk(); 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 */) static jlong vibratorGetFinalizer(JNIEnv* /* env */, jclass /* clazz */) { { return static_cast<jlong>(reinterpret_cast<uintptr_t>(&destroyVibratorController)); bool ok; } if (auto hal = getHal<aidl::IVibrator>()) { static jboolean vibratorExists(JNIEnv* env, jclass /* clazz */, jlong controllerPtr) { // IBinder::pingBinder isn't accessible as a pointer function vibrator::HalController* controller = reinterpret_cast<vibrator::HalController*>(controllerPtr); // but getCapabilities can serve the same purpose if (controller == nullptr) { int32_t cap; ALOGE("vibratorExists failed because controller was not initialized"); ok = hal->call(&aidl::IVibrator::getCapabilities, &cap).isOk(); return JNI_FALSE; } else { ok = halCall(&V1_0::IVibrator::ping).isOk(); } } 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>()) { if (auto hal = getHal<aidl::IVibrator>()) { auto status = hal->call(&aidl::IVibrator::on, timeout_ms, nullptr); auto status = hal->call(&aidl::IVibrator::on, timeout_ms, nullptr); if (!status.isOk()) { if (!status.isOk()) { Loading @@ -268,93 +287,53 @@ static void vibratorOn(JNIEnv* /* env */, jclass /* clazz */, jlong timeout_ms) } } } } static void vibratorOff(JNIEnv* /* env */, jclass /* clazz */) static void vibratorOff(JNIEnv* env, jclass /* clazz */, jlong controllerPtr) { { vibrator::HalController* controller = reinterpret_cast<vibrator::HalController*>(controllerPtr); if (auto hal = getHal<aidl::IVibrator>()) { if (controller == nullptr) { auto status = hal->call(&aidl::IVibrator::off); ALOGE("vibratorOff failed because controller was not initialized"); if (!status.isOk()) { return; 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)); } } } controller->off(); } } static jboolean vibratorSupportsExternalControl(JNIEnv*, jclass) { static void vibratorSetAmplitude(JNIEnv* env, jclass /* clazz */, jlong controllerPtr, if (auto hal = getHal<aidl::IVibrator>()) { jint amplitude) { int32_t cap = 0; vibrator::HalController* controller = reinterpret_cast<vibrator::HalController*>(controllerPtr); if (!hal->call(&aidl::IVibrator::getCapabilities, &cap).isOk()) { if (controller == nullptr) { return false; ALOGE("vibratorSetAmplitude failed because controller was not initialized"); } return; return (cap & aidl::IVibrator::CAP_EXTERNAL_CONTROL) > 0; } else { return halCall(&V1_3::IVibrator::supportsExternalControl).withDefault(false); } } controller->setAmplitude(static_cast<int32_t>(amplitude)); } } static void vibratorSetExternalControl(JNIEnv*, jclass, jboolean enabled) { static void vibratorSetExternalControl(JNIEnv* env, jclass /* clazz */, jlong controllerPtr, if (auto hal = getHal<aidl::IVibrator>()) { jboolean enabled) { auto status = hal->call(&aidl::IVibrator::IVibrator::setExternalControl, enabled); vibrator::HalController* controller = reinterpret_cast<vibrator::HalController*>(controllerPtr); if (!status.isOk()) { if (controller == nullptr) { ALOGE("Failed to set vibrator external control: %s", status.toString8().string()); ALOGE("vibratorSetExternalControl failed because controller was not initialized"); } return; } 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)); } } } controller->setExternalControl(enabled); } } static jintArray vibratorGetSupportedEffects(JNIEnv *env, jclass) { static jintArray vibratorGetSupportedEffects(JNIEnv* env, jclass /* clazz */, jlong controllerPtr) { if (auto hal = getHal<aidl::IVibrator>()) { vibrator::HalController* controller = reinterpret_cast<vibrator::HalController*>(controllerPtr); std::vector<aidl::Effect> supportedEffects; if (controller == nullptr) { if (!hal->call(&aidl::IVibrator::getSupportedEffects, &supportedEffects).isOk()) { ALOGE("vibratorGetSupportedEffects failed because controller was not initialized"); return nullptr; return nullptr; } } jintArray arr = env->NewIntArray(supportedEffects.size()); auto result = controller->getSupportedEffects(); env->SetIntArrayRegion(arr, 0, supportedEffects.size(), if (!result.isOk()) { reinterpret_cast<jint*>(supportedEffects.data())); return arr; } else { return nullptr; 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) { jobject vibration, jboolean withCallback) { if (auto hal = getHal<aidl::IVibrator>()) { if (auto hal = getHal<aidl::IVibrator>()) { int32_t lengthMs; int32_t lengthMs; Loading Loading @@ -420,16 +399,7 @@ static jlong vibratorPerformEffect(JNIEnv* env, jclass, jlong effect, jlong stre return -1; return -1; } } static aidl::CompositeEffect effectFromJavaPrimitive(JNIEnv* env, jobject primitive) { static void vibratorPerformComposedEffect(JNIEnv* env, jclass /* clazz */, jobjectArray composition, 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, jobject vibration) { jobject vibration) { auto hal = getHal<aidl::IVibrator>(); auto hal = getHal<aidl::IVibrator>(); if (!hal) { if (!hal) { Loading @@ -451,65 +421,71 @@ static void vibratorPerformComposedEffect(JNIEnv* env, jclass, jobjectArray comp } } } } static jlong vibratorGetCapabilities(JNIEnv*, jclass) { static jlong vibratorGetCapabilities(JNIEnv* env, jclass /* clazz */, jlong controllerPtr) { if (auto hal = getHal<aidl::IVibrator>()) { vibrator::HalController* controller = reinterpret_cast<vibrator::HalController*>(controllerPtr); int32_t cap = 0; if (controller == nullptr) { if (!hal->call(&aidl::IVibrator::getCapabilities, &cap).isOk()) { ALOGE("vibratorGetCapabilities failed because controller was not initialized"); return 0; return 0; } } return cap; auto result = controller->getCapabilities(); } return result.isOk() ? static_cast<jlong>(result.value()) : 0; return 0; } } static void vibratorAlwaysOnEnable(JNIEnv* env, jclass, jlong id, jlong effect, jlong strength) { static void vibratorAlwaysOnEnable(JNIEnv* env, jclass /* clazz */, jlong controllerPtr, jlong id, auto status = halCall(&aidl::IVibrator::alwaysOnEnable, id, jlong effect, jlong strength) { static_cast<aidl::Effect>(effect), static_cast<aidl::EffectStrength>(strength)); vibrator::HalController* controller = reinterpret_cast<vibrator::HalController*>(controllerPtr); if (!status.isOk()) { if (controller == nullptr) { ALOGE("vibratortAlwaysOnEnable command failed (%s).", status.toString8().string()); 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) { static void vibratorAlwaysOnDisable(JNIEnv* env, jclass /* clazz */, jlong controllerPtr, auto status = halCall(&aidl::IVibrator::alwaysOnDisable, id); jlong id) { if (!status.isOk()) { vibrator::HalController* controller = reinterpret_cast<vibrator::HalController*>(controllerPtr); ALOGE("vibratorAlwaysOnDisable command failed (%s).", status.toString8().string()); if (controller == nullptr) { ALOGE("vibratorAlwaysOnDisable failed because controller was not initialized"); return; } } controller->alwaysOnDisable(static_cast<int32_t>(id)); } } static const JNINativeMethod method_table[] = { static const JNINativeMethod method_table[] = { {"vibratorExists", "()Z", (void*)vibratorExists}, {"vibratorInit", "()J", (void*)vibratorInit}, {"vibratorInit", "()V", (void*)vibratorInit}, {"vibratorGetFinalizer", "()J", (void*)vibratorGetFinalizer}, {"vibratorExists", "(J)Z", (void*)vibratorExists}, {"vibratorOn", "(J)V", (void*)vibratorOn}, {"vibratorOn", "(J)V", (void*)vibratorOn}, {"vibratorOff", "()V", (void*)vibratorOff}, {"vibratorOff", "(J)V", (void*)vibratorOff}, {"vibratorSupportsAmplitudeControl", "()Z", (void*)vibratorSupportsAmplitudeControl}, {"vibratorSetAmplitude", "(JI)V", (void*)vibratorSetAmplitude}, {"vibratorSetAmplitude", "(I)V", (void*)vibratorSetAmplitude}, {"vibratorPerformEffect", "(JJLcom/android/server/VibratorService$Vibration;Z)J", {"vibratorPerformEffect", "(JJLcom/android/server/VibratorService$Vibration;Z)J", (void*)vibratorPerformEffect}, (void*)vibratorPerformEffect}, {"vibratorPerformComposedEffect", {"vibratorPerformComposedEffect", "([Landroid/os/VibrationEffect$Composition$PrimitiveEffect;Lcom/android/server/" "([Landroid/os/VibrationEffect$Composition$PrimitiveEffect;Lcom/android/server/" "VibratorService$Vibration;)V", "VibratorService$Vibration;)V", (void*)vibratorPerformComposedEffect}, (void*)vibratorPerformComposedEffect}, {"vibratorGetSupportedEffects", "()[I", (void*)vibratorGetSupportedEffects}, {"vibratorGetSupportedEffects", "(J)[I", (void*)vibratorGetSupportedEffects}, {"vibratorSupportsExternalControl", "()Z", (void*)vibratorSupportsExternalControl}, {"vibratorSetExternalControl", "(JZ)V", (void*)vibratorSetExternalControl}, {"vibratorSetExternalControl", "(Z)V", (void*)vibratorSetExternalControl}, {"vibratorGetCapabilities", "(J)J", (void*)vibratorGetCapabilities}, {"vibratorGetCapabilities", "()J", (void*)vibratorGetCapabilities}, {"vibratorAlwaysOnEnable", "(JJJJ)V", (void*)vibratorAlwaysOnEnable}, {"vibratorAlwaysOnEnable", "(JJJ)V", (void*)vibratorAlwaysOnEnable}, {"vibratorAlwaysOnDisable", "(JJ)V", (void*)vibratorAlwaysOnDisable}, {"vibratorAlwaysOnDisable", "(J)V", (void*)vibratorAlwaysOnDisable}, }; }; int register_android_server_VibratorService(JNIEnv *env) { int register_android_server_VibratorService(JNIEnv *env) { sMethodIdOnComplete = GetMethodIDOrDie(env, sMethodIdOnComplete = GetMethodIDOrDie(env, FindClassOrDie(env, "com/android/server/VibratorService$Vibration"), FindClassOrDie(env, "com/android/server/VibratorService$Vibration"), "onComplete", "()V"); "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.id = GetFieldIDOrDie(env, primitiveClass, "id", "I"); gPrimitiveClassInfo.scale = GetFieldIDOrDie(env, primitiveClass, "scale", "F"); gPrimitiveClassInfo.scale = GetFieldIDOrDie(env, primitiveClass, "scale", "F"); gPrimitiveClassInfo.delay = GetFieldIDOrDie(env, primitiveClass, "delay", "I"); 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 services/tests/servicestests/src/com/android/server/VibratorServiceTest.java +4 −5 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
services/core/java/com/android/server/VibratorService.java +52 −43 Original line number Original line Diff line number Diff line Loading @@ -76,6 +76,8 @@ import com.android.internal.app.IBatteryStats; import com.android.internal.util.DumpUtils; import com.android.internal.util.DumpUtils; import com.android.internal.util.FrameworkStatsLog; import com.android.internal.util.FrameworkStatsLog; import libcore.util.NativeAllocationRegistry; import java.io.FileDescriptor; import java.io.FileDescriptor; import java.io.PrintWriter; import java.io.PrintWriter; import java.util.ArrayList; import java.util.ArrayList; Loading Loading @@ -115,7 +117,6 @@ public class VibratorService extends IVibratorService.Stub // If HAL supports callbacks set the timeout to ASYNC_TIMEOUT_MULTIPLIER * duration. // If HAL supports callbacks set the timeout to ASYNC_TIMEOUT_MULTIPLIER * duration. private static final long ASYNC_TIMEOUT_MULTIPLIER = 2; private static final long ASYNC_TIMEOUT_MULTIPLIER = 2; // A mapping from the intensity adjustment to the scaling to apply, where the intensity // 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 // 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 // intensity level. It's important that we apply the scaling on the delta between the two so Loading @@ -128,8 +129,6 @@ public class VibratorService extends IVibratorService.Stub private final LinkedList<VibrationInfo> mPreviousVibrations; private final LinkedList<VibrationInfo> mPreviousVibrations; private final int mPreviousVibrationsLimit; private final int mPreviousVibrationsLimit; private final boolean mAllowPriorityVibrationsInLowPowerMode; private final boolean mAllowPriorityVibrationsInLowPowerMode; private final boolean mSupportsAmplitudeControl; private final boolean mSupportsExternalControl; private final List<Integer> mSupportedEffects; private final List<Integer> mSupportedEffects; private final long mCapabilities; private final long mCapabilities; private final int mDefaultVibrationAmplitude; private final int mDefaultVibrationAmplitude; Loading Loading @@ -174,22 +173,23 @@ public class VibratorService extends IVibratorService.Stub private int mRingIntensity; private int mRingIntensity; private SparseArray<Vibration> mAlwaysOnEffects = new SparseArray<>(); private SparseArray<Vibration> mAlwaysOnEffects = new SparseArray<>(); static native boolean vibratorExists(); static native long vibratorInit(); static native void vibratorInit(); static native long vibratorGetFinalizer(); static native boolean vibratorExists(long controllerPtr); static native void vibratorOn(long milliseconds); static native void vibratorOn(long milliseconds); static native void vibratorOff(); static native void vibratorOff(long controllerPtr); static native boolean vibratorSupportsAmplitudeControl(); static native void vibratorSetAmplitude(long controllerPtr, int amplitude); static native void vibratorSetAmplitude(int amplitude); static native int[] vibratorGetSupportedEffects(long controllerPtr); static native int[] vibratorGetSupportedEffects(); static native long vibratorPerformEffect(long effect, long strength, Vibration vibration, static native long vibratorPerformEffect(long effect, long strength, Vibration vibration, boolean withCallback); boolean withCallback); static native void vibratorPerformComposedEffect( static native void vibratorPerformComposedEffect( VibrationEffect.Composition.PrimitiveEffect[] effect, Vibration vibration); VibrationEffect.Composition.PrimitiveEffect[] effect, Vibration vibration); static native boolean vibratorSupportsExternalControl(); static native void vibratorSetExternalControl(long controllerPtr, boolean enabled); static native void vibratorSetExternalControl(boolean enabled); static native long vibratorGetCapabilities(long controllerPtr); static native long vibratorGetCapabilities(); static native void vibratorAlwaysOnEnable(long controllerPtr, long id, long effect, static native void vibratorAlwaysOnEnable(long id, long effect, long strength); long strength); static native void vibratorAlwaysOnDisable(long id); static native void vibratorAlwaysOnDisable(long controllerPtr, long id); private final IUidObserver mUidObserver = new IUidObserver.Stub() { private final IUidObserver mUidObserver = new IUidObserver.Stub() { @Override public void onUidStateChanged(int uid, int procState, long procStateSeq, @Override public void onUidStateChanged(int uid, int procState, long procStateSeq, Loading Loading @@ -370,13 +370,20 @@ public class VibratorService extends IVibratorService.Stub mNativeWrapper = injector.getNativeWrapper(); mNativeWrapper = injector.getNativeWrapper(); mH = injector.createHandler(Looper.myLooper()); 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 // Reset the hardware to a default state, in case this is a runtime // restart instead of a fresh boot. // restart instead of a fresh boot. mNativeWrapper.vibratorOff(); mNativeWrapper.vibratorOff(); mSupportsAmplitudeControl = mNativeWrapper.vibratorSupportsAmplitudeControl(); mSupportsExternalControl = mNativeWrapper.vibratorSupportsExternalControl(); mSupportedEffects = asList(mNativeWrapper.vibratorGetSupportedEffects()); mSupportedEffects = asList(mNativeWrapper.vibratorGetSupportedEffects()); mCapabilities = mNativeWrapper.vibratorGetCapabilities(); mCapabilities = mNativeWrapper.vibratorGetCapabilities(); Loading Loading @@ -605,7 +612,8 @@ public class VibratorService extends IVibratorService.Stub synchronized (mInputDeviceVibrators) { synchronized (mInputDeviceVibrators) { // Input device vibrators don't support amplitude controls yet, but are still used over // Input device vibrators don't support amplitude controls yet, but are still used over // the system vibrator when connected. // the system vibrator when connected. return mSupportsAmplitudeControl && mInputDeviceVibrators.isEmpty(); return hasCapability(IVibrator.CAP_AMPLITUDE_CONTROL) && mInputDeviceVibrators.isEmpty(); } } } } Loading Loading @@ -1288,7 +1296,7 @@ public class VibratorService extends IVibratorService.Stub } } private void doVibratorSetAmplitude(int amplitude) { private void doVibratorSetAmplitude(int amplitude) { if (mSupportsAmplitudeControl) { if (hasCapability(IVibrator.CAP_AMPLITUDE_CONTROL)) { mNativeWrapper.vibratorSetAmplitude(amplitude); mNativeWrapper.vibratorSetAmplitude(amplitude); } } } } Loading Loading @@ -1708,14 +1716,25 @@ public class VibratorService extends IVibratorService.Stub @VisibleForTesting @VisibleForTesting public static class NativeWrapper { public static class NativeWrapper { private long mNativeControllerPtr = 0; /** Checks if vibrator exists on device. */ /** Checks if vibrator exists on device. */ public boolean vibratorExists() { public boolean vibratorExists() { return VibratorService.vibratorExists(); return VibratorService.vibratorExists(mNativeControllerPtr); } } /** Initializes connection to vibrator HAL service. */ /** public void vibratorInit() { * Returns native pointer to newly created controller and initializes connection to vibrator VibratorService.vibratorInit(); * 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. */ /** Turns vibrator on for given time. */ Loading @@ -1725,22 +1744,17 @@ public class VibratorService extends IVibratorService.Stub /** Turns vibrator off. */ /** Turns vibrator off. */ public void vibratorOff() { public void vibratorOff() { VibratorService.vibratorOff(); VibratorService.vibratorOff(mNativeControllerPtr); } /** Returns true if vibrator supports {@link #vibratorSetAmplitude(int)}. */ public boolean vibratorSupportsAmplitudeControl() { return VibratorService.vibratorSupportsAmplitudeControl(); } } /** Sets the amplitude for the vibrator to run. */ /** Sets the amplitude for the vibrator to run. */ public void vibratorSetAmplitude(int amplitude) { public void vibratorSetAmplitude(int amplitude) { VibratorService.vibratorSetAmplitude(amplitude); VibratorService.vibratorSetAmplitude(mNativeControllerPtr, amplitude); } } /** Returns all predefined effects supported by the device vibrator. */ /** Returns all predefined effects supported by the device vibrator. */ public int[] vibratorGetSupportedEffects() { public int[] vibratorGetSupportedEffects() { return VibratorService.vibratorGetSupportedEffects(); return VibratorService.vibratorGetSupportedEffects(mNativeControllerPtr); } } /** Turns vibrator on to perform one of the supported effects. */ /** Turns vibrator on to perform one of the supported effects. */ Loading @@ -1755,29 +1769,24 @@ public class VibratorService extends IVibratorService.Stub VibratorService.vibratorPerformComposedEffect(effect, vibration); 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. */ /** Enabled the device vibrator to be controlled by another service. */ public void vibratorSetExternalControl(boolean enabled) { public void vibratorSetExternalControl(boolean enabled) { VibratorService.vibratorSetExternalControl(enabled); VibratorService.vibratorSetExternalControl(mNativeControllerPtr, enabled); } } /** Returns all capabilities of the device vibrator. */ /** Returns all capabilities of the device vibrator. */ public long vibratorGetCapabilities() { public long vibratorGetCapabilities() { return VibratorService.vibratorGetCapabilities(); return VibratorService.vibratorGetCapabilities(mNativeControllerPtr); } } /** Enable always-on vibration with given id and effect. */ /** Enable always-on vibration with given id and effect. */ public void vibratorAlwaysOnEnable(long id, long effect, long strength) { 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. */ /** Disable always-on vibration for given id. */ public void vibratorAlwaysOnDisable(long id) { public void vibratorAlwaysOnDisable(long id) { VibratorService.vibratorAlwaysOnDisable(id); VibratorService.vibratorAlwaysOnDisable(mNativeControllerPtr, id); } } } } Loading Loading @@ -1852,7 +1861,7 @@ public class VibratorService extends IVibratorService.Stub @Override @Override public int onExternalVibrationStart(ExternalVibration vib) { public int onExternalVibrationStart(ExternalVibration vib) { if (!mSupportsExternalControl) { if (!hasCapability(IVibrator.CAP_EXTERNAL_CONTROL)) { return SCALE_MUTE; return SCALE_MUTE; } } if (ActivityManager.checkComponentPermission(android.Manifest.permission.VIBRATE, if (ActivityManager.checkComponentPermission(android.Manifest.permission.VIBRATE, Loading Loading @@ -2142,10 +2151,10 @@ public class VibratorService extends IVibratorService.Stub if (hasCapability(IVibrator.CAP_COMPOSE_EFFECTS)) { if (hasCapability(IVibrator.CAP_COMPOSE_EFFECTS)) { pw.println(" Compose effects"); pw.println(" Compose effects"); } } if (mSupportsAmplitudeControl || hasCapability(IVibrator.CAP_AMPLITUDE_CONTROL)) { if (hasCapability(IVibrator.CAP_AMPLITUDE_CONTROL)) { pw.println(" Amplitude control"); pw.println(" Amplitude control"); } } if (mSupportsExternalControl || hasCapability(IVibrator.CAP_EXTERNAL_CONTROL)) { if (hasCapability(IVibrator.CAP_EXTERNAL_CONTROL)) { pw.println(" External control"); pw.println(" External control"); } } if (hasCapability(IVibrator.CAP_EXTERNAL_AMPLITUDE_CONTROL)) { if (hasCapability(IVibrator.CAP_EXTERNAL_AMPLITUDE_CONTROL)) { Loading
services/core/jni/Android.bp +1 −0 Original line number Original line Diff line number Diff line Loading @@ -99,6 +99,7 @@ cc_defaults { "libpowermanager", "libpowermanager", "libutils", "libutils", "libui", "libui", "libvibratorservice", "libinput", "libinput", "libinputflinger", "libinputflinger", "libinputflinger_base", "libinputflinger_base", Loading
services/core/jni/com_android_server_VibratorService.cpp +112 −136 Original line number Original line Diff line number Diff line Loading @@ -33,6 +33,8 @@ #include <inttypes.h> #include <inttypes.h> #include <stdio.h> #include <stdio.h> #include <vibratorservice/VibratorHalController.h> using android::hardware::Return; using android::hardware::Return; using android::hardware::Void; using android::hardware::Void; using android::hardware::vibrator::V1_0::EffectStrength; using android::hardware::vibrator::V1_0::EffectStrength; Loading Loading @@ -226,8 +228,24 @@ bool isValidEffect(jlong effect) { return val >= *iter.begin() && val <= *std::prev(iter.end()); 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>()) { if (auto hal = getHal<aidl::IVibrator>()) { // IBinder::pingBinder isn't accessible as a pointer function // IBinder::pingBinder isn't accessible as a pointer function // but getCapabilities can serve the same purpose // but getCapabilities can serve the same purpose Loading @@ -236,25 +254,26 @@ static void vibratorInit(JNIEnv *env, jclass clazz) } else { } else { halCall(&V1_0::IVibrator::ping).isOk(); 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 */) static jlong vibratorGetFinalizer(JNIEnv* /* env */, jclass /* clazz */) { { return static_cast<jlong>(reinterpret_cast<uintptr_t>(&destroyVibratorController)); bool ok; } if (auto hal = getHal<aidl::IVibrator>()) { static jboolean vibratorExists(JNIEnv* env, jclass /* clazz */, jlong controllerPtr) { // IBinder::pingBinder isn't accessible as a pointer function vibrator::HalController* controller = reinterpret_cast<vibrator::HalController*>(controllerPtr); // but getCapabilities can serve the same purpose if (controller == nullptr) { int32_t cap; ALOGE("vibratorExists failed because controller was not initialized"); ok = hal->call(&aidl::IVibrator::getCapabilities, &cap).isOk(); return JNI_FALSE; } else { ok = halCall(&V1_0::IVibrator::ping).isOk(); } } 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>()) { if (auto hal = getHal<aidl::IVibrator>()) { auto status = hal->call(&aidl::IVibrator::on, timeout_ms, nullptr); auto status = hal->call(&aidl::IVibrator::on, timeout_ms, nullptr); if (!status.isOk()) { if (!status.isOk()) { Loading @@ -268,93 +287,53 @@ static void vibratorOn(JNIEnv* /* env */, jclass /* clazz */, jlong timeout_ms) } } } } static void vibratorOff(JNIEnv* /* env */, jclass /* clazz */) static void vibratorOff(JNIEnv* env, jclass /* clazz */, jlong controllerPtr) { { vibrator::HalController* controller = reinterpret_cast<vibrator::HalController*>(controllerPtr); if (auto hal = getHal<aidl::IVibrator>()) { if (controller == nullptr) { auto status = hal->call(&aidl::IVibrator::off); ALOGE("vibratorOff failed because controller was not initialized"); if (!status.isOk()) { return; 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)); } } } controller->off(); } } static jboolean vibratorSupportsExternalControl(JNIEnv*, jclass) { static void vibratorSetAmplitude(JNIEnv* env, jclass /* clazz */, jlong controllerPtr, if (auto hal = getHal<aidl::IVibrator>()) { jint amplitude) { int32_t cap = 0; vibrator::HalController* controller = reinterpret_cast<vibrator::HalController*>(controllerPtr); if (!hal->call(&aidl::IVibrator::getCapabilities, &cap).isOk()) { if (controller == nullptr) { return false; ALOGE("vibratorSetAmplitude failed because controller was not initialized"); } return; return (cap & aidl::IVibrator::CAP_EXTERNAL_CONTROL) > 0; } else { return halCall(&V1_3::IVibrator::supportsExternalControl).withDefault(false); } } controller->setAmplitude(static_cast<int32_t>(amplitude)); } } static void vibratorSetExternalControl(JNIEnv*, jclass, jboolean enabled) { static void vibratorSetExternalControl(JNIEnv* env, jclass /* clazz */, jlong controllerPtr, if (auto hal = getHal<aidl::IVibrator>()) { jboolean enabled) { auto status = hal->call(&aidl::IVibrator::IVibrator::setExternalControl, enabled); vibrator::HalController* controller = reinterpret_cast<vibrator::HalController*>(controllerPtr); if (!status.isOk()) { if (controller == nullptr) { ALOGE("Failed to set vibrator external control: %s", status.toString8().string()); ALOGE("vibratorSetExternalControl failed because controller was not initialized"); } return; } 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)); } } } controller->setExternalControl(enabled); } } static jintArray vibratorGetSupportedEffects(JNIEnv *env, jclass) { static jintArray vibratorGetSupportedEffects(JNIEnv* env, jclass /* clazz */, jlong controllerPtr) { if (auto hal = getHal<aidl::IVibrator>()) { vibrator::HalController* controller = reinterpret_cast<vibrator::HalController*>(controllerPtr); std::vector<aidl::Effect> supportedEffects; if (controller == nullptr) { if (!hal->call(&aidl::IVibrator::getSupportedEffects, &supportedEffects).isOk()) { ALOGE("vibratorGetSupportedEffects failed because controller was not initialized"); return nullptr; return nullptr; } } jintArray arr = env->NewIntArray(supportedEffects.size()); auto result = controller->getSupportedEffects(); env->SetIntArrayRegion(arr, 0, supportedEffects.size(), if (!result.isOk()) { reinterpret_cast<jint*>(supportedEffects.data())); return arr; } else { return nullptr; 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) { jobject vibration, jboolean withCallback) { if (auto hal = getHal<aidl::IVibrator>()) { if (auto hal = getHal<aidl::IVibrator>()) { int32_t lengthMs; int32_t lengthMs; Loading Loading @@ -420,16 +399,7 @@ static jlong vibratorPerformEffect(JNIEnv* env, jclass, jlong effect, jlong stre return -1; return -1; } } static aidl::CompositeEffect effectFromJavaPrimitive(JNIEnv* env, jobject primitive) { static void vibratorPerformComposedEffect(JNIEnv* env, jclass /* clazz */, jobjectArray composition, 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, jobject vibration) { jobject vibration) { auto hal = getHal<aidl::IVibrator>(); auto hal = getHal<aidl::IVibrator>(); if (!hal) { if (!hal) { Loading @@ -451,65 +421,71 @@ static void vibratorPerformComposedEffect(JNIEnv* env, jclass, jobjectArray comp } } } } static jlong vibratorGetCapabilities(JNIEnv*, jclass) { static jlong vibratorGetCapabilities(JNIEnv* env, jclass /* clazz */, jlong controllerPtr) { if (auto hal = getHal<aidl::IVibrator>()) { vibrator::HalController* controller = reinterpret_cast<vibrator::HalController*>(controllerPtr); int32_t cap = 0; if (controller == nullptr) { if (!hal->call(&aidl::IVibrator::getCapabilities, &cap).isOk()) { ALOGE("vibratorGetCapabilities failed because controller was not initialized"); return 0; return 0; } } return cap; auto result = controller->getCapabilities(); } return result.isOk() ? static_cast<jlong>(result.value()) : 0; return 0; } } static void vibratorAlwaysOnEnable(JNIEnv* env, jclass, jlong id, jlong effect, jlong strength) { static void vibratorAlwaysOnEnable(JNIEnv* env, jclass /* clazz */, jlong controllerPtr, jlong id, auto status = halCall(&aidl::IVibrator::alwaysOnEnable, id, jlong effect, jlong strength) { static_cast<aidl::Effect>(effect), static_cast<aidl::EffectStrength>(strength)); vibrator::HalController* controller = reinterpret_cast<vibrator::HalController*>(controllerPtr); if (!status.isOk()) { if (controller == nullptr) { ALOGE("vibratortAlwaysOnEnable command failed (%s).", status.toString8().string()); 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) { static void vibratorAlwaysOnDisable(JNIEnv* env, jclass /* clazz */, jlong controllerPtr, auto status = halCall(&aidl::IVibrator::alwaysOnDisable, id); jlong id) { if (!status.isOk()) { vibrator::HalController* controller = reinterpret_cast<vibrator::HalController*>(controllerPtr); ALOGE("vibratorAlwaysOnDisable command failed (%s).", status.toString8().string()); if (controller == nullptr) { ALOGE("vibratorAlwaysOnDisable failed because controller was not initialized"); return; } } controller->alwaysOnDisable(static_cast<int32_t>(id)); } } static const JNINativeMethod method_table[] = { static const JNINativeMethod method_table[] = { {"vibratorExists", "()Z", (void*)vibratorExists}, {"vibratorInit", "()J", (void*)vibratorInit}, {"vibratorInit", "()V", (void*)vibratorInit}, {"vibratorGetFinalizer", "()J", (void*)vibratorGetFinalizer}, {"vibratorExists", "(J)Z", (void*)vibratorExists}, {"vibratorOn", "(J)V", (void*)vibratorOn}, {"vibratorOn", "(J)V", (void*)vibratorOn}, {"vibratorOff", "()V", (void*)vibratorOff}, {"vibratorOff", "(J)V", (void*)vibratorOff}, {"vibratorSupportsAmplitudeControl", "()Z", (void*)vibratorSupportsAmplitudeControl}, {"vibratorSetAmplitude", "(JI)V", (void*)vibratorSetAmplitude}, {"vibratorSetAmplitude", "(I)V", (void*)vibratorSetAmplitude}, {"vibratorPerformEffect", "(JJLcom/android/server/VibratorService$Vibration;Z)J", {"vibratorPerformEffect", "(JJLcom/android/server/VibratorService$Vibration;Z)J", (void*)vibratorPerformEffect}, (void*)vibratorPerformEffect}, {"vibratorPerformComposedEffect", {"vibratorPerformComposedEffect", "([Landroid/os/VibrationEffect$Composition$PrimitiveEffect;Lcom/android/server/" "([Landroid/os/VibrationEffect$Composition$PrimitiveEffect;Lcom/android/server/" "VibratorService$Vibration;)V", "VibratorService$Vibration;)V", (void*)vibratorPerformComposedEffect}, (void*)vibratorPerformComposedEffect}, {"vibratorGetSupportedEffects", "()[I", (void*)vibratorGetSupportedEffects}, {"vibratorGetSupportedEffects", "(J)[I", (void*)vibratorGetSupportedEffects}, {"vibratorSupportsExternalControl", "()Z", (void*)vibratorSupportsExternalControl}, {"vibratorSetExternalControl", "(JZ)V", (void*)vibratorSetExternalControl}, {"vibratorSetExternalControl", "(Z)V", (void*)vibratorSetExternalControl}, {"vibratorGetCapabilities", "(J)J", (void*)vibratorGetCapabilities}, {"vibratorGetCapabilities", "()J", (void*)vibratorGetCapabilities}, {"vibratorAlwaysOnEnable", "(JJJJ)V", (void*)vibratorAlwaysOnEnable}, {"vibratorAlwaysOnEnable", "(JJJ)V", (void*)vibratorAlwaysOnEnable}, {"vibratorAlwaysOnDisable", "(JJ)V", (void*)vibratorAlwaysOnDisable}, {"vibratorAlwaysOnDisable", "(J)V", (void*)vibratorAlwaysOnDisable}, }; }; int register_android_server_VibratorService(JNIEnv *env) { int register_android_server_VibratorService(JNIEnv *env) { sMethodIdOnComplete = GetMethodIDOrDie(env, sMethodIdOnComplete = GetMethodIDOrDie(env, FindClassOrDie(env, "com/android/server/VibratorService$Vibration"), FindClassOrDie(env, "com/android/server/VibratorService$Vibration"), "onComplete", "()V"); "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.id = GetFieldIDOrDie(env, primitiveClass, "id", "I"); gPrimitiveClassInfo.scale = GetFieldIDOrDie(env, primitiveClass, "scale", "F"); gPrimitiveClassInfo.scale = GetFieldIDOrDie(env, primitiveClass, "scale", "F"); gPrimitiveClassInfo.delay = GetFieldIDOrDie(env, primitiveClass, "delay", "I"); 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
services/tests/servicestests/src/com/android/server/VibratorServiceTest.java +4 −5 File changed.Preview size limit exceeded, changes collapsed. Show changes