From a17013e871ddd348874733e74c7633626d0c3ea6 Mon Sep 17 00:00:00 2001 From: Vlad Popa Date: Mon, 7 Nov 2022 21:55:45 +0100 Subject: [PATCH] Add the resetting of the dose after audio server dies For this we need to store the binder for sending information to the SounDoseManager to reset the current CSD values and records. Test: manual e2e, logs and dumpsys Bug: 257238734 Change-Id: I0e6a297935d6263bde2f55bb55d3cbbc7847495f --- core/jni/android_media_AudioSystem.cpp | 17 ++++--- media/java/android/media/AudioSystem.java | 12 +++-- .../android/server/audio/AudioService.java | 1 + .../server/audio/AudioSystemAdapter.java | 7 +-- .../android/server/audio/SoundDoseHelper.java | 47 +++++++++++++++++-- 5 files changed, 68 insertions(+), 16 deletions(-) diff --git a/core/jni/android_media_AudioSystem.cpp b/core/jni/android_media_AudioSystem.cpp index 334a0e0fd0a14..27a5afd4299f2 100644 --- a/core/jni/android_media_AudioSystem.cpp +++ b/core/jni/android_media_AudioSystem.cpp @@ -2868,13 +2868,18 @@ static jboolean android_media_AudioSystem_canBeSpatialized(JNIEnv *env, jobject return canBeSpatialized; } -static jint android_media_AudioSystem_registerSoundDoseCallback(JNIEnv *env, jobject thiz, - jobject jISoundDoseCallback) { +static jobject android_media_AudioSystem_nativeGetSoundDose(JNIEnv *env, jobject thiz, + jobject jISoundDoseCallback) { sp nISoundDoseCallback = interface_cast( ibinderForJavaObject(env, jISoundDoseCallback)); - return static_cast( - check_AudioSystem_Command(AudioSystem::registerSoundDoseCallback(nISoundDoseCallback))); + sp nSoundDose; + status_t status = AudioSystem::getSoundDoseInterface(nISoundDoseCallback, &nSoundDose); + + if (status != NO_ERROR) { + return nullptr; + } + return javaObjectForIBinder(env, IInterface::asBinder(nSoundDose)); } // keep these values in sync with AudioSystem.java @@ -3113,8 +3118,8 @@ static const JNINativeMethod gMethods[] = "(Landroid/media/AudioAttributes;Landroid/media/AudioFormat;" "[Landroid/media/AudioDeviceAttributes;)Z", (void *)android_media_AudioSystem_canBeSpatialized}, - {"registerSoundDoseCallback", "(Landroid/media/ISoundDoseCallback;)I", - (void *)android_media_AudioSystem_registerSoundDoseCallback}, + {"nativeGetSoundDose", "(Landroid/media/ISoundDoseCallback;)Landroid/os/IBinder;", + (void *)android_media_AudioSystem_nativeGetSoundDose}, {"getDirectPlaybackSupport", "(Landroid/media/AudioFormat;Landroid/media/AudioAttributes;)I", (void *)android_media_AudioSystem_getDirectPlaybackSupport}, diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java index fb643507f0373..2e7a4984244a6 100644 --- a/media/java/android/media/AudioSystem.java +++ b/media/java/android/media/AudioSystem.java @@ -2260,11 +2260,17 @@ public class AudioSystem /** * @hide - * Register the sound dose callback with the audio server. + * Register the sound dose callback with the audio server and returns the binder to the + * ISoundDose interface. * - * @return {@link #SUCCESS} if the callback was registered successfully. + * @return ISoundDose interface with registered callback. */ - public static native int registerSoundDoseCallback(ISoundDoseCallback callback); + @Nullable + public static ISoundDose getSoundDoseInterface(ISoundDoseCallback callback) { + return ISoundDose.Stub.asInterface(nativeGetSoundDose(callback)); + } + + private static native IBinder nativeGetSoundDose(ISoundDoseCallback callback); /** * @hide diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java index 21030a81f5e75..c6ffa3015082a 100644 --- a/services/core/java/com/android/server/audio/AudioService.java +++ b/services/core/java/com/android/server/audio/AudioService.java @@ -1699,6 +1699,7 @@ public class AudioService extends IAudioService.Stub } mSpatializerHelper.reset(/* featureEnabled */ mHasSpatializerEffect); + mSoundDoseHelper.reset(); onIndicateSystemReady(); // indicate the end of reconfiguration phase to audio HAL diff --git a/services/core/java/com/android/server/audio/AudioSystemAdapter.java b/services/core/java/com/android/server/audio/AudioSystemAdapter.java index 558daa183afaf..dee35f2371ae9 100644 --- a/services/core/java/com/android/server/audio/AudioSystemAdapter.java +++ b/services/core/java/com/android/server/audio/AudioSystemAdapter.java @@ -21,6 +21,7 @@ import android.annotation.Nullable; import android.media.AudioAttributes; import android.media.AudioDeviceAttributes; import android.media.AudioSystem; +import android.media.ISoundDose; import android.media.ISoundDoseCallback; import android.media.audiopolicy.AudioMix; import android.os.SystemClock; @@ -496,12 +497,12 @@ public class AudioSystemAdapter implements AudioSystem.RoutingUpdateCallback, } /** - * Same as {@link AudioSystem#registerSoundDoseCallback(ISoundDoseCallback)} + * Same as {@link AudioSystem#getSoundDoseInterface(ISoundDoseCallback)} * @param callback * @return */ - public int registerSoundDoseCallback(ISoundDoseCallback callback) { - return AudioSystem.registerSoundDoseCallback(callback); + public ISoundDose getSoundDoseInterface(ISoundDoseCallback callback) { + return AudioSystem.getSoundDoseInterface(callback); } /** diff --git a/services/core/java/com/android/server/audio/SoundDoseHelper.java b/services/core/java/com/android/server/audio/SoundDoseHelper.java index ff6a7f103ce92..0d0de8ad28862 100644 --- a/services/core/java/com/android/server/audio/SoundDoseHelper.java +++ b/services/core/java/com/android/server/audio/SoundDoseHelper.java @@ -27,10 +27,12 @@ import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.media.AudioSystem; +import android.media.ISoundDose; import android.media.ISoundDoseCallback; import android.media.SoundDoseRecord; import android.os.Binder; import android.os.Message; +import android.os.RemoteException; import android.os.SystemClock; import android.os.SystemProperties; import android.os.UserHandle; @@ -43,8 +45,10 @@ import com.android.server.audio.AudioService.AudioHandler; import com.android.server.audio.AudioService.ISafeHearingVolumeController; import java.io.PrintWriter; +import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; +import java.util.List; import java.util.Set; /** @@ -88,6 +92,8 @@ public class SoundDoseHelper { private static final int MUSIC_ACTIVE_POLL_PERIOD_MS = 60000; // 1 minute polling interval private static final int REQUEST_CODE_CHECK_MUSIC_ACTIVE = 1; + private static final float CUSTOM_RS2_VALUE = 90; + private int mMcc = 0; final Object mSafeMediaVolumeStateLock = new Object(); @@ -131,6 +137,10 @@ public class SoundDoseHelper { @NonNull private final AudioHandler mAudioHandler; @NonNull private final ISafeHearingVolumeController mVolumeController; + private ISoundDose mSoundDose; + private float mCurrentCsd = 0.f; + private final List mDoseRecords = new ArrayList<>(); + private final Context mContext; private final ISoundDoseCallback.Stub mSoundDoseCallback = new ISoundDoseCallback.Stub() { @@ -141,6 +151,8 @@ public class SoundDoseHelper { public void onNewCsdValue(float currentCsd, SoundDoseRecord[] records) { Log.i(TAG, "onNewCsdValue: " + currentCsd); + mCurrentCsd = currentCsd; + mDoseRecords.addAll(Arrays.asList(records)); for (SoundDoseRecord record : records) { Log.i(TAG, " new record: csd=" + record.value + " averageMel=" + record.averageMel + " timestamp=" + record.timestamp @@ -162,10 +174,6 @@ public class SoundDoseHelper { mSafeMediaVolumeState = mSettings.getGlobalInt(audioService.getContentResolver(), Settings.Global.AUDIO_SAFE_VOLUME_STATE, 0); - if (USE_CSD_FOR_SAFE_HEARING) { - AudioSystem.registerSoundDoseCallback(mSoundDoseCallback); - mSafeMediaVolumeState = SAFE_MEDIA_VOLUME_DISABLED; - } // The default safe volume index read here will be replaced by the actual value when // the mcc is read by onConfigureSafeVolume() @@ -174,6 +182,8 @@ public class SoundDoseHelper { mAlarmManager = (AlarmManager) mContext.getSystemService( Context.ALARM_SERVICE); + + initCsd(); } /*package*/ int safeMediaVolumeIndex(int device) { @@ -392,6 +402,35 @@ public class SoundDoseHelper { pw.print(" mPendingVolumeCommand="); pw.println(mPendingVolumeCommand); } + /*package*/void reset() { + Log.d(TAG, "Reset the sound dose helper"); + initCsd(); + } + + private void initCsd() { + synchronized (mSafeMediaVolumeStateLock) { + if (USE_CSD_FOR_SAFE_HEARING) { + Log.v(TAG, "Initializing sound dose"); + + mSafeMediaVolumeState = SAFE_MEDIA_VOLUME_DISABLED; + mSoundDose = AudioSystem.getSoundDoseInterface(mSoundDoseCallback); + try { + if (mSoundDose != null && mSoundDose.asBinder().isBinderAlive()) { + mSoundDose.setOutputRs2(CUSTOM_RS2_VALUE); + if (mCurrentCsd != 0.f) { + Log.d(TAG, "Resetting the saved sound dose value " + mCurrentCsd); + SoundDoseRecord[] records = mDoseRecords.toArray( + new SoundDoseRecord[0]); + mSoundDose.resetCsd(mCurrentCsd, records); + } + } + } catch (RemoteException e) { + // noop + } + } + } + } + private void onConfigureSafeVolume(boolean force, String caller) { synchronized (mSafeMediaVolumeStateLock) { int mcc = mContext.getResources().getConfiguration().mcc;