diff options
| -rw-r--r-- | core/jni/core_jni_helpers.h | 25 | ||||
| -rw-r--r-- | services/core/java/com/android/server/VibratorService.java | 12 | ||||
| -rw-r--r-- | services/core/jni/com_android_server_VibratorService.cpp | 34 | ||||
| -rw-r--r-- | services/core/jni/com_android_server_pm_PackageManagerShellCommandDataLoader.cpp | 27 | ||||
| -rw-r--r-- | services/core/jni/onload.cpp | 4 |
5 files changed, 57 insertions, 45 deletions
diff --git a/core/jni/core_jni_helpers.h b/core/jni/core_jni_helpers.h index eeda275b811c..d629e0dae6dd 100644 --- a/core/jni/core_jni_helpers.h +++ b/core/jni/core_jni_helpers.h @@ -104,6 +104,31 @@ static inline std::string getStringField(JNIEnv* env, jobject obj, jfieldID fiel return std::string(defaultValue); } +static inline JNIEnv* GetJNIEnvironment(JavaVM* vm, jint version = JNI_VERSION_1_4) { + JNIEnv* env; + if (vm->GetEnv(reinterpret_cast<void**>(&env), version) != JNI_OK) { + return nullptr; + } + return env; +} + +static inline JNIEnv* GetOrAttachJNIEnvironment(JavaVM* jvm, jint version = JNI_VERSION_1_4) { + JNIEnv* env = GetJNIEnvironment(jvm, version); + if (!env) { + int result = jvm->AttachCurrentThread(&env, nullptr); + LOG_ALWAYS_FATAL_IF(result != JNI_OK, "JVM thread attach failed."); + struct VmDetacher { + VmDetacher(JavaVM* vm) : mVm(vm) {} + ~VmDetacher() { mVm->DetachCurrentThread(); } + + private: + JavaVM* const mVm; + }; + static thread_local VmDetacher detacher(jvm); + } + return env; +} + } // namespace android #endif // CORE_JNI_HELPERS diff --git a/services/core/java/com/android/server/VibratorService.java b/services/core/java/com/android/server/VibratorService.java index 847f92a409c3..045c51a516f4 100644 --- a/services/core/java/com/android/server/VibratorService.java +++ b/services/core/java/com/android/server/VibratorService.java @@ -183,7 +183,7 @@ public class VibratorService extends IVibratorService.Stub static native int[] vibratorGetSupportedEffects(long controllerPtr); static native long vibratorPerformEffect(long effect, long strength, Vibration vibration, boolean withCallback); - static native void vibratorPerformComposedEffect( + static native void vibratorPerformComposedEffect(long controllerPtr, VibrationEffect.Composition.PrimitiveEffect[] effect, Vibration vibration); static native void vibratorSetExternalControl(long controllerPtr, boolean enabled); static native long vibratorGetCapabilities(long controllerPtr); @@ -251,6 +251,9 @@ public class VibratorService extends IVibratorService.Stub public void binderDied() { synchronized (mLock) { if (this == mCurrentVibration) { + if (DEBUG) { + Slog.d(TAG, "Vibration finished because binder died, cleaning up"); + } doCancelVibrateLocked(); } } @@ -261,6 +264,9 @@ public class VibratorService extends IVibratorService.Stub public void onComplete() { synchronized (mLock) { if (this == mCurrentVibration) { + if (DEBUG) { + Slog.d(TAG, "Vibration finished by callback, cleaning up"); + } doCancelVibrateLocked(); } } @@ -915,7 +921,7 @@ public class VibratorService extends IVibratorService.Stub // Callback for whenever the current vibration has finished played out public void onVibrationFinished() { if (DEBUG) { - Slog.e(TAG, "Vibration finished, cleaning up"); + Slog.d(TAG, "Vibration finished, cleaning up"); } synchronized (mLock) { // Make sure the vibration is really done. This also reports that the vibration is @@ -1766,7 +1772,7 @@ public class VibratorService extends IVibratorService.Stub /** Turns vibrator on to perform one of the supported composed effects. */ public void vibratorPerformComposedEffect( VibrationEffect.Composition.PrimitiveEffect[] effect, Vibration vibration) { - VibratorService.vibratorPerformComposedEffect(effect, vibration); + VibratorService.vibratorPerformComposedEffect(mNativeControllerPtr, effect, vibration); } /** Enabled the device vibrator to be controlled by another service. */ diff --git a/services/core/jni/com_android_server_VibratorService.cpp b/services/core/jni/com_android_server_VibratorService.cpp index 74e2328105dc..f0618c23b025 100644 --- a/services/core/jni/com_android_server_VibratorService.cpp +++ b/services/core/jni/com_android_server_VibratorService.cpp @@ -49,6 +49,8 @@ namespace aidl = android::hardware::vibrator; namespace android { +static JavaVM* sJvm = nullptr; + static jmethodID sMethodIdOnComplete; static struct { @@ -228,6 +230,12 @@ bool isValidEffect(jlong effect) { return val >= *iter.begin() && val <= *std::prev(iter.end()); } +static void callVibrationOnComplete(jobject vibration) { + auto jniEnv = GetOrAttachJNIEnvironment(sJvm); + jniEnv->CallVoidMethod(vibration, sMethodIdOnComplete); + jniEnv->DeleteGlobalRef(vibration); +} + static aidl::CompositeEffect effectFromJavaPrimitive(JNIEnv* env, jobject primitive) { aidl::CompositeEffect effect; effect.primitive = static_cast<aidl::CompositePrimitive>( @@ -399,10 +407,11 @@ static jlong vibratorPerformEffect(JNIEnv* env, jclass /* clazz */, jlong effect return -1; } -static void vibratorPerformComposedEffect(JNIEnv* env, jclass /* clazz */, jobjectArray composition, - jobject vibration) { - auto hal = getHal<aidl::IVibrator>(); - if (!hal) { +static void vibratorPerformComposedEffect(JNIEnv* env, jclass /* clazz */, jlong controllerPtr, + jobjectArray composition, jobject vibration) { + vibrator::HalController* controller = reinterpret_cast<vibrator::HalController*>(controllerPtr); + if (controller == nullptr) { + ALOGE("vibratorPerformComposedEffect failed because controller was not initialized"); return; } size_t size = env->GetArrayLength(composition); @@ -411,14 +420,10 @@ static void vibratorPerformComposedEffect(JNIEnv* env, jclass /* clazz */, jobje jobject element = env->GetObjectArrayElement(composition, i); effects.push_back(effectFromJavaPrimitive(env, element)); } - sp<AidlVibratorCallback> effectCallback = new AidlVibratorCallback(env, vibration); - - auto status = hal->call(&aidl::IVibrator::compose, effects, effectCallback); - if (!status.isOk()) { - if (status.exceptionCode() != binder::Status::EX_UNSUPPORTED_OPERATION) { - ALOGE("Failed to play haptic effect composition"); - } - } + auto callback = [vibrationRef(MakeGlobalRefOrDie(env, vibration))]() { + callVibrationOnComplete(vibrationRef); + }; + controller->performComposedEffect(effects, callback); } static jlong vibratorGetCapabilities(JNIEnv* env, jclass /* clazz */, jlong controllerPtr) { @@ -462,7 +467,7 @@ static const JNINativeMethod method_table[] = { {"vibratorPerformEffect", "(JJLcom/android/server/VibratorService$Vibration;Z)J", (void*)vibratorPerformEffect}, {"vibratorPerformComposedEffect", - "([Landroid/os/VibrationEffect$Composition$PrimitiveEffect;Lcom/android/server/" + "(J[Landroid/os/VibrationEffect$Composition$PrimitiveEffect;Lcom/android/server/" "VibratorService$Vibration;)V", (void*)vibratorPerformComposedEffect}, {"vibratorGetSupportedEffects", "(J)[I", (void*)vibratorGetSupportedEffects}, @@ -472,7 +477,8 @@ static const JNINativeMethod method_table[] = { {"vibratorAlwaysOnDisable", "(JJ)V", (void*)vibratorAlwaysOnDisable}, }; -int register_android_server_VibratorService(JNIEnv *env) { +int register_android_server_VibratorService(JavaVM* vm, JNIEnv* env) { + sJvm = vm; sMethodIdOnComplete = GetMethodIDOrDie(env, FindClassOrDie(env, "com/android/server/VibratorService$Vibration"), diff --git a/services/core/jni/com_android_server_pm_PackageManagerShellCommandDataLoader.cpp b/services/core/jni/com_android_server_pm_PackageManagerShellCommandDataLoader.cpp index e904645bda8f..9e2bb45ab341 100644 --- a/services/core/jni/com_android_server_pm_PackageManagerShellCommandDataLoader.cpp +++ b/services/core/jni/com_android_server_pm_PackageManagerShellCommandDataLoader.cpp @@ -314,31 +314,6 @@ static inline InputDescs openInputs(JNIEnv* env, const JniIds& jni, jobject shel return result; } -static inline JNIEnv* GetJNIEnvironment(JavaVM* vm) { - JNIEnv* env; - if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) { - return 0; - } - return env; -} - -static inline JNIEnv* GetOrAttachJNIEnvironment(JavaVM* jvm) { - JNIEnv* env = GetJNIEnvironment(jvm); - if (!env) { - int result = jvm->AttachCurrentThread(&env, nullptr); - CHECK_EQ(result, JNI_OK) << "thread attach failed"; - struct VmDetacher { - VmDetacher(JavaVM* vm) : mVm(vm) {} - ~VmDetacher() { mVm->DetachCurrentThread(); } - - private: - JavaVM* const mVm; - }; - static thread_local VmDetacher detacher(jvm); - } - return env; -} - class PMSCDataLoader; struct OnTraceChanged { @@ -415,7 +390,7 @@ private: bool onPrepareImage(dataloader::DataLoaderInstallationFiles addedFiles) final { ALOGE("onPrepareImage: start."); - JNIEnv* env = GetOrAttachJNIEnvironment(mJvm); + JNIEnv* env = GetOrAttachJNIEnvironment(mJvm, JNI_VERSION_1_6); const auto& jni = jniIds(env); jobject shellCommand = env->CallStaticObjectMethod(jni.packageManagerShellCommandDataLoader, diff --git a/services/core/jni/onload.cpp b/services/core/jni/onload.cpp index 6f24e3b580b7..5df1adafed5e 100644 --- a/services/core/jni/onload.cpp +++ b/services/core/jni/onload.cpp @@ -37,7 +37,7 @@ int register_android_server_UsbDeviceManager(JNIEnv* env); int register_android_server_UsbMidiDevice(JNIEnv* env); int register_android_server_UsbHostManager(JNIEnv* env); int register_android_server_vr_VrManagerService(JNIEnv* env); -int register_android_server_VibratorService(JNIEnv* env); +int register_android_server_VibratorService(JavaVM* vm, JNIEnv* env); int register_android_server_location_GnssLocationProvider(JNIEnv* env); int register_android_server_connectivity_Vpn(JNIEnv* env); int register_android_server_TestNetworkService(JNIEnv* env); @@ -90,7 +90,7 @@ extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */) register_android_server_UsbAlsaJackDetector(env); register_android_server_UsbHostManager(env); register_android_server_vr_VrManagerService(env); - register_android_server_VibratorService(env); + register_android_server_VibratorService(vm, env); register_android_server_SystemServer(env); register_android_server_location_GnssLocationProvider(env); register_android_server_connectivity_Vpn(env); |