diff --git a/Android.bp b/Android.bp index 3d0188a3918d0..8820ee1fa719a 100644 --- a/Android.bp +++ b/Android.bp @@ -404,6 +404,7 @@ java_defaults { "framework-permission-aidl-java", "spatializer-aidl-java", "audiopolicy-types-aidl-java", + "sounddose-aidl-java", ], } diff --git a/core/jni/android_media_AudioSystem.cpp b/core/jni/android_media_AudioSystem.cpp index 2433a05a4e9b7..334a0e0fd0a14 100644 --- a/core/jni/android_media_AudioSystem.cpp +++ b/core/jni/android_media_AudioSystem.cpp @@ -2868,6 +2868,15 @@ static jboolean android_media_AudioSystem_canBeSpatialized(JNIEnv *env, jobject return canBeSpatialized; } +static jint android_media_AudioSystem_registerSoundDoseCallback(JNIEnv *env, jobject thiz, + jobject jISoundDoseCallback) { + sp nISoundDoseCallback = interface_cast( + ibinderForJavaObject(env, jISoundDoseCallback)); + + return static_cast( + check_AudioSystem_Command(AudioSystem::registerSoundDoseCallback(nISoundDoseCallback))); +} + // keep these values in sync with AudioSystem.java #define DIRECT_NOT_SUPPORTED 0 #define DIRECT_OFFLOAD_SUPPORTED 1 @@ -3104,6 +3113,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}, {"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 a48edac8e0803..fb643507f0373 100644 --- a/media/java/android/media/AudioSystem.java +++ b/media/java/android/media/AudioSystem.java @@ -2258,6 +2258,14 @@ public class AudioSystem AudioFormat format, AudioDeviceAttributes[] devices); + /** + * @hide + * Register the sound dose callback with the audio server. + * + * @return {@link #SUCCESS} if the callback was registered successfully. + */ + public static native int registerSoundDoseCallback(ISoundDoseCallback callback); + /** * @hide * @param attributes audio attributes describing the playback use case diff --git a/services/core/java/com/android/server/audio/AudioSystemAdapter.java b/services/core/java/com/android/server/audio/AudioSystemAdapter.java index c3754eb3e44c0..558daa183afaf 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.ISoundDoseCallback; import android.media.audiopolicy.AudioMix; import android.os.SystemClock; import android.util.Log; @@ -494,6 +495,15 @@ public class AudioSystemAdapter implements AudioSystem.RoutingUpdateCallback, return AudioSystem.removeUserIdDeviceAffinities(userId); } + /** + * Same as {@link AudioSystem#registerSoundDoseCallback(ISoundDoseCallback)} + * @param callback + * @return + */ + public int registerSoundDoseCallback(ISoundDoseCallback callback) { + return AudioSystem.registerSoundDoseCallback(callback); + } + /** * Part of AudioService dump * @param pw diff --git a/services/core/java/com/android/server/audio/SoundDoseHelper.java b/services/core/java/com/android/server/audio/SoundDoseHelper.java index 5188a53a58617..5b72581d0da0f 100644 --- a/services/core/java/com/android/server/audio/SoundDoseHelper.java +++ b/services/core/java/com/android/server/audio/SoundDoseHelper.java @@ -27,6 +27,7 @@ import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.media.AudioSystem; +import android.media.ISoundDoseCallback; import android.os.Binder; import android.os.Message; import android.os.SystemClock; @@ -131,6 +132,14 @@ public class SoundDoseHelper { private final Context mContext; + private final ISoundDoseCallback.Stub mSoundDoseCallback = new ISoundDoseCallback.Stub() { + @Override + public void onMomentaryExposure(float currentMel, int deviceId) { + Log.w(TAG, "DeviceId " + deviceId + " triggered momentary exposure with value: " + + currentMel); + } + }; + SoundDoseHelper(@NonNull AudioService audioService, Context context, @NonNull AudioHandler audioHandler, @NonNull SettingsAdapter settings, @@ -145,6 +154,7 @@ 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; }