Loading core/jni/android_media_AudioSystem.cpp +50 −2 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ #include <nativehelper/JNIHelp.h> #include "core_jni_helpers.h" #include <android/media/AudioVibratorInfo.h> #include <audiomanager/AudioManager.h> #include <media/AudioPolicy.h> #include <media/AudioSystem.h> Loading Loading @@ -176,7 +177,12 @@ static struct { jmethodID postRoutingUpdatedFromNative; } gAudioPolicyEventHandlerMethods; static struct { jmethodID add; } gListMethods; jclass gListClass; static struct { jmethodID add; jmethodID get; jmethodID size; } gListMethods; static jclass gAudioDescriptorClass; static jmethodID gAudiODescriptorCstor; Loading @@ -195,6 +201,13 @@ jclass gClsAudioRecordRoutingProxy; jclass gAudioProfileClass; jmethodID gAudioProfileCstor; jclass gVibratorClass; static struct { jmethodID getId; jmethodID getResonantFrequency; jmethodID getQFactor; } gVibratorMethods; static Mutex gLock; enum AudioError { Loading Loading @@ -2627,6 +2640,29 @@ android_media_AudioSystem_getDevicesForAttributes(JNIEnv *env, jobject thiz, return jStatus; } static jint android_media_AudioSystem_setVibratorInfos(JNIEnv *env, jobject thiz, jobject jVibrators) { if (!env->IsInstanceOf(jVibrators, gListClass)) { return (jint)AUDIO_JAVA_BAD_VALUE; } const jint size = env->CallIntMethod(jVibrators, gListMethods.size); std::vector<media::AudioVibratorInfo> vibratorInfos; for (jint i = 0; i < size; ++i) { ScopedLocalRef<jobject> jVibrator(env, env->CallObjectMethod(jVibrators, gListMethods.get, i)); if (!env->IsInstanceOf(jVibrator.get(), gVibratorClass)) { return (jint)AUDIO_JAVA_BAD_VALUE; } media::AudioVibratorInfo vibratorInfo; vibratorInfo.id = env->CallIntMethod(jVibrator.get(), gVibratorMethods.getId); vibratorInfo.resonantFrequency = env->CallFloatMethod(jVibrator.get(), gVibratorMethods.getResonantFrequency); vibratorInfo.qFactor = env->CallFloatMethod(jVibrator.get(), gVibratorMethods.getQFactor); vibratorInfos.push_back(vibratorInfo); } return (jint)check_AudioSystem_Command(AudioSystem::setVibratorInfos(vibratorInfos)); } // ---------------------------------------------------------------------------- static const JNINativeMethod gMethods[] = Loading Loading @@ -2757,7 +2793,9 @@ static const JNINativeMethod gMethods[] = (void *)android_media_AudioSystem_setUserIdDeviceAffinities}, {"removeUserIdDeviceAffinities", "(I)I", (void *)android_media_AudioSystem_removeUserIdDeviceAffinities}, {"setCurrentImeUid", "(I)I", (void *)android_media_AudioSystem_setCurrentImeUid}}; {"setCurrentImeUid", "(I)I", (void *)android_media_AudioSystem_setCurrentImeUid}, {"setVibratorInfos", "(Ljava/util/List;)I", (void *)android_media_AudioSystem_setVibratorInfos}}; static const JNINativeMethod gEventHandlerMethods[] = { {"native_setup", Loading Loading @@ -2959,7 +2997,10 @@ int register_android_media_AudioSystem(JNIEnv *env) android::GetMethodIDOrDie(env, gClsAudioRecordRoutingProxy, "native_release", "()V"); jclass listClass = FindClassOrDie(env, "java/util/List"); gListClass = MakeGlobalRefOrDie(env, listClass); gListMethods.add = GetMethodIDOrDie(env, listClass, "add", "(Ljava/lang/Object;)Z"); gListMethods.get = GetMethodIDOrDie(env, listClass, "get", "(I)Ljava/lang/Object;"); gListMethods.size = GetMethodIDOrDie(env, listClass, "size", "()I"); jclass audioProfileClass = FindClassOrDie(env, "android/media/AudioProfile"); gAudioProfileClass = MakeGlobalRefOrDie(env, audioProfileClass); Loading @@ -2969,6 +3010,13 @@ int register_android_media_AudioSystem(JNIEnv *env) gAudioDescriptorClass = MakeGlobalRefOrDie(env, audioDescriptorClass); gAudiODescriptorCstor = GetMethodIDOrDie(env, audioDescriptorClass, "<init>", "(II[B)V"); jclass vibratorClass = FindClassOrDie(env, "android/os/Vibrator"); gVibratorClass = MakeGlobalRefOrDie(env, vibratorClass); gVibratorMethods.getId = GetMethodIDOrDie(env, vibratorClass, "getId", "()I"); gVibratorMethods.getResonantFrequency = GetMethodIDOrDie(env, vibratorClass, "getResonantFrequency", "()F"); gVibratorMethods.getQFactor = GetMethodIDOrDie(env, vibratorClass, "getQFactor", "()F"); AudioSystem::addErrorCallback(android_media_AudioSystem_error_callback); RegisterMethodsOrDie(env, kClassPathName, gMethods, NELEM(gMethods)); Loading media/java/android/media/AudioSystem.java +9 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ import android.content.pm.PackageManager; import android.media.audiofx.AudioEffect; import android.media.audiopolicy.AudioMix; import android.os.Build; import android.os.Vibrator; import android.telephony.TelephonyManager; import android.util.Log; import android.util.Pair; Loading Loading @@ -1937,6 +1938,14 @@ public class AudioSystem public static native int getDevicesForRoleAndCapturePreset( int capturePreset, int role, @NonNull List<AudioDeviceAttributes> devices); /** * @hide * Set the vibrators' information. The value will be used to initialize HapticGenerator. * @param vibrators a list of all available vibrators * @return command completion status */ public static native int setVibratorInfos(@NonNull List<Vibrator> vibrators); // Items shared with audio service /** Loading services/core/java/com/android/server/audio/AudioService.java +33 −0 Original line number Diff line number Diff line Loading @@ -128,6 +128,7 @@ import android.os.UserHandle; import android.os.UserManager; import android.os.VibrationEffect; import android.os.Vibrator; import android.os.VibratorManager; import android.provider.Settings; import android.provider.Settings.System; import android.service.notification.ZenModeConfig; Loading Loading @@ -1092,6 +1093,33 @@ public class AudioService extends IAudioService.Stub } } private void updateVibratorInfos() { VibratorManager vibratorManager = mContext.getSystemService(VibratorManager.class); if (vibratorManager == null) { Slog.e(TAG, "Vibrator manager is not found"); return; } int[] vibratorIds = vibratorManager.getVibratorIds(); if (vibratorIds.length == 0) { Slog.d(TAG, "No vibrator found"); return; } List<Vibrator> vibrators = new ArrayList<>(vibratorIds.length); for (int id : vibratorIds) { Vibrator vibrator = vibratorManager.getVibrator(id); if (vibrator != null) { vibrators.add(vibrator); } else { Slog.w(TAG, "Vibrator(" + id + ") is not found"); } } if (vibrators.isEmpty()) { Slog.w(TAG, "Cannot find any available vibrator"); return; } AudioSystem.setVibratorInfos(vibrators); } public void onSystemReady() { mSystemReady = true; scheduleLoadSoundEffects(); Loading Loading @@ -1149,6 +1177,8 @@ public class AudioService extends IAudioService.Stub setMicMuteFromSwitchInput(); initMinStreamVolumeWithoutModifyAudioSettings(); updateVibratorInfos(); } RoleObserver mRoleObserver; Loading Loading @@ -1341,6 +1371,9 @@ public class AudioService extends IAudioService.Stub setMicrophoneMuteNoCallerCheck(getCurrentUserId()); // will also update the mic mute cache setMicMuteFromSwitchInput(); // Restore vibrator info updateVibratorInfos(); } private void onReinitVolumes(@NonNull String caller) { Loading Loading
core/jni/android_media_AudioSystem.cpp +50 −2 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ #include <nativehelper/JNIHelp.h> #include "core_jni_helpers.h" #include <android/media/AudioVibratorInfo.h> #include <audiomanager/AudioManager.h> #include <media/AudioPolicy.h> #include <media/AudioSystem.h> Loading Loading @@ -176,7 +177,12 @@ static struct { jmethodID postRoutingUpdatedFromNative; } gAudioPolicyEventHandlerMethods; static struct { jmethodID add; } gListMethods; jclass gListClass; static struct { jmethodID add; jmethodID get; jmethodID size; } gListMethods; static jclass gAudioDescriptorClass; static jmethodID gAudiODescriptorCstor; Loading @@ -195,6 +201,13 @@ jclass gClsAudioRecordRoutingProxy; jclass gAudioProfileClass; jmethodID gAudioProfileCstor; jclass gVibratorClass; static struct { jmethodID getId; jmethodID getResonantFrequency; jmethodID getQFactor; } gVibratorMethods; static Mutex gLock; enum AudioError { Loading Loading @@ -2627,6 +2640,29 @@ android_media_AudioSystem_getDevicesForAttributes(JNIEnv *env, jobject thiz, return jStatus; } static jint android_media_AudioSystem_setVibratorInfos(JNIEnv *env, jobject thiz, jobject jVibrators) { if (!env->IsInstanceOf(jVibrators, gListClass)) { return (jint)AUDIO_JAVA_BAD_VALUE; } const jint size = env->CallIntMethod(jVibrators, gListMethods.size); std::vector<media::AudioVibratorInfo> vibratorInfos; for (jint i = 0; i < size; ++i) { ScopedLocalRef<jobject> jVibrator(env, env->CallObjectMethod(jVibrators, gListMethods.get, i)); if (!env->IsInstanceOf(jVibrator.get(), gVibratorClass)) { return (jint)AUDIO_JAVA_BAD_VALUE; } media::AudioVibratorInfo vibratorInfo; vibratorInfo.id = env->CallIntMethod(jVibrator.get(), gVibratorMethods.getId); vibratorInfo.resonantFrequency = env->CallFloatMethod(jVibrator.get(), gVibratorMethods.getResonantFrequency); vibratorInfo.qFactor = env->CallFloatMethod(jVibrator.get(), gVibratorMethods.getQFactor); vibratorInfos.push_back(vibratorInfo); } return (jint)check_AudioSystem_Command(AudioSystem::setVibratorInfos(vibratorInfos)); } // ---------------------------------------------------------------------------- static const JNINativeMethod gMethods[] = Loading Loading @@ -2757,7 +2793,9 @@ static const JNINativeMethod gMethods[] = (void *)android_media_AudioSystem_setUserIdDeviceAffinities}, {"removeUserIdDeviceAffinities", "(I)I", (void *)android_media_AudioSystem_removeUserIdDeviceAffinities}, {"setCurrentImeUid", "(I)I", (void *)android_media_AudioSystem_setCurrentImeUid}}; {"setCurrentImeUid", "(I)I", (void *)android_media_AudioSystem_setCurrentImeUid}, {"setVibratorInfos", "(Ljava/util/List;)I", (void *)android_media_AudioSystem_setVibratorInfos}}; static const JNINativeMethod gEventHandlerMethods[] = { {"native_setup", Loading Loading @@ -2959,7 +2997,10 @@ int register_android_media_AudioSystem(JNIEnv *env) android::GetMethodIDOrDie(env, gClsAudioRecordRoutingProxy, "native_release", "()V"); jclass listClass = FindClassOrDie(env, "java/util/List"); gListClass = MakeGlobalRefOrDie(env, listClass); gListMethods.add = GetMethodIDOrDie(env, listClass, "add", "(Ljava/lang/Object;)Z"); gListMethods.get = GetMethodIDOrDie(env, listClass, "get", "(I)Ljava/lang/Object;"); gListMethods.size = GetMethodIDOrDie(env, listClass, "size", "()I"); jclass audioProfileClass = FindClassOrDie(env, "android/media/AudioProfile"); gAudioProfileClass = MakeGlobalRefOrDie(env, audioProfileClass); Loading @@ -2969,6 +3010,13 @@ int register_android_media_AudioSystem(JNIEnv *env) gAudioDescriptorClass = MakeGlobalRefOrDie(env, audioDescriptorClass); gAudiODescriptorCstor = GetMethodIDOrDie(env, audioDescriptorClass, "<init>", "(II[B)V"); jclass vibratorClass = FindClassOrDie(env, "android/os/Vibrator"); gVibratorClass = MakeGlobalRefOrDie(env, vibratorClass); gVibratorMethods.getId = GetMethodIDOrDie(env, vibratorClass, "getId", "()I"); gVibratorMethods.getResonantFrequency = GetMethodIDOrDie(env, vibratorClass, "getResonantFrequency", "()F"); gVibratorMethods.getQFactor = GetMethodIDOrDie(env, vibratorClass, "getQFactor", "()F"); AudioSystem::addErrorCallback(android_media_AudioSystem_error_callback); RegisterMethodsOrDie(env, kClassPathName, gMethods, NELEM(gMethods)); Loading
media/java/android/media/AudioSystem.java +9 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ import android.content.pm.PackageManager; import android.media.audiofx.AudioEffect; import android.media.audiopolicy.AudioMix; import android.os.Build; import android.os.Vibrator; import android.telephony.TelephonyManager; import android.util.Log; import android.util.Pair; Loading Loading @@ -1937,6 +1938,14 @@ public class AudioSystem public static native int getDevicesForRoleAndCapturePreset( int capturePreset, int role, @NonNull List<AudioDeviceAttributes> devices); /** * @hide * Set the vibrators' information. The value will be used to initialize HapticGenerator. * @param vibrators a list of all available vibrators * @return command completion status */ public static native int setVibratorInfos(@NonNull List<Vibrator> vibrators); // Items shared with audio service /** Loading
services/core/java/com/android/server/audio/AudioService.java +33 −0 Original line number Diff line number Diff line Loading @@ -128,6 +128,7 @@ import android.os.UserHandle; import android.os.UserManager; import android.os.VibrationEffect; import android.os.Vibrator; import android.os.VibratorManager; import android.provider.Settings; import android.provider.Settings.System; import android.service.notification.ZenModeConfig; Loading Loading @@ -1092,6 +1093,33 @@ public class AudioService extends IAudioService.Stub } } private void updateVibratorInfos() { VibratorManager vibratorManager = mContext.getSystemService(VibratorManager.class); if (vibratorManager == null) { Slog.e(TAG, "Vibrator manager is not found"); return; } int[] vibratorIds = vibratorManager.getVibratorIds(); if (vibratorIds.length == 0) { Slog.d(TAG, "No vibrator found"); return; } List<Vibrator> vibrators = new ArrayList<>(vibratorIds.length); for (int id : vibratorIds) { Vibrator vibrator = vibratorManager.getVibrator(id); if (vibrator != null) { vibrators.add(vibrator); } else { Slog.w(TAG, "Vibrator(" + id + ") is not found"); } } if (vibrators.isEmpty()) { Slog.w(TAG, "Cannot find any available vibrator"); return; } AudioSystem.setVibratorInfos(vibrators); } public void onSystemReady() { mSystemReady = true; scheduleLoadSoundEffects(); Loading Loading @@ -1149,6 +1177,8 @@ public class AudioService extends IAudioService.Stub setMicMuteFromSwitchInput(); initMinStreamVolumeWithoutModifyAudioSettings(); updateVibratorInfos(); } RoleObserver mRoleObserver; Loading Loading @@ -1341,6 +1371,9 @@ public class AudioService extends IAudioService.Stub setMicrophoneMuteNoCallerCheck(getCurrentUserId()); // will also update the mic mute cache setMicMuteFromSwitchInput(); // Restore vibrator info updateVibratorInfos(); } private void onReinitVolumes(@NonNull String caller) { Loading