Merge "Use vibrator HAL controller for composed vibrations"
This commit is contained in:
committed by
Android (Google) Code Review
commit
f5936e40f8
@@ -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
|
||||
|
||||
@@ -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. */
|
||||
|
||||
@@ -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"),
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user