Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9d52faa2 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Pass vibrator information to audio server." into sc-dev

parents 6a725247 c1f0b55b
Loading
Loading
Loading
Loading
+50 −2
Original line number Diff line number Diff line
@@ -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>
@@ -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;
@@ -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 {
@@ -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[] =
@@ -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",
@@ -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);
@@ -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));
+9 −0
Original line number Diff line number Diff line
@@ -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;
@@ -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

    /**
+33 −0
Original line number Diff line number Diff line
@@ -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;
@@ -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();
@@ -1149,6 +1177,8 @@ public class AudioService extends IAudioService.Stub
        setMicMuteFromSwitchInput();

        initMinStreamVolumeWithoutModifyAudioSettings();

        updateVibratorInfos();
    }

    RoleObserver mRoleObserver;
@@ -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) {