summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/jni/core_jni_helpers.h25
-rw-r--r--services/core/java/com/android/server/VibratorService.java12
-rw-r--r--services/core/jni/com_android_server_VibratorService.cpp34
-rw-r--r--services/core/jni/com_android_server_pm_PackageManagerShellCommandDataLoader.cpp27
-rw-r--r--services/core/jni/onload.cpp4
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);