From e2a281aa250654cfc3e1d57629c10721ac2e0867 Mon Sep 17 00:00:00 2001 From: Jean-Michel Trivi Date: Mon, 11 Jul 2022 01:45:39 +0000 Subject: [PATCH] AudioService: do not log sound effects in audio dumpsys "audio" dumpsys captures the logs from PlaybackActivityMonitor. This includes the activity of the SoundPool in AudioService which handles the sounds effects for the UI, such as touchsounds. But with touchsounds enabled, too many important player logs are lost as UI playback events fill the rolling window of logs. The fix consists in SoundEffectsHelper giving a handle of the PlayerBase used for effect playback to AudioService, which then tells PlaybackActivityMonitor to not log playback events for this player. Bug: 236983951 Test: with touch sounds enabled, verify events absent from dumpsys audio Change-Id: I6fb0289ef3b72e4dd505f9114dd59da174f53238 Merged-In: I6fb0289ef3b72e4dd505f9114dd59da174f53238 --- .../android/server/audio/AudioService.java | 22 +++++++++- .../server/audio/PlaybackActivityMonitor.java | 44 ++++++++++++++++--- .../server/audio/SoundEffectsHelper.java | 8 +++- 3 files changed, 67 insertions(+), 7 deletions(-) diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java index e8f25490e61ac..c804ef2cf8b47 100644 --- a/services/core/java/com/android/server/audio/AudioService.java +++ b/services/core/java/com/android/server/audio/AudioService.java @@ -255,6 +255,9 @@ public class AudioService extends IAudioService.Stub /** Debug communication route */ protected static final boolean DEBUG_COMM_RTE = false; + /** Debug log sound fx (touchsounds...) in dumpsys */ + protected static final boolean DEBUG_LOG_SOUND_FX = false; + /** How long to delay before persisting a change in volume/ringer mode. */ private static final int PERSIST_DELAY = 500; @@ -376,6 +379,7 @@ public class AudioService extends IAudioService.Stub private static final int MSG_ROTATION_UPDATE = 48; private static final int MSG_FOLD_UPDATE = 49; private static final int MSG_RESET_SPATIALIZER = 50; + private static final int MSG_NO_LOG_FOR_PLAYER_I = 51; // start of messages handled under wakelock // these messages can only be queued, i.e. sent with queueMsgUnderWakeLock(), @@ -1010,7 +1014,7 @@ public class AudioService extends IAudioService.Stub PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE); mAudioEventWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "handleAudioEvent"); - mSfxHelper = new SoundEffectsHelper(mContext); + mSfxHelper = new SoundEffectsHelper(mContext, playerBase -> ignorePlayerLogs(playerBase)); final boolean headTrackingDefault = mContext.getResources().getBoolean( com.android.internal.R.bool.config_spatial_audio_head_tracking_enabled_default); @@ -1493,6 +1497,18 @@ public class AudioService extends IAudioService.Stub /*obj*/ foldParameter, /*delay*/ 0); } + //----------------------------------------------------------------- + // Communicate to PlayackActivityMonitor whether to log or not + // the sound FX activity (useful for removing touch sounds in the activity logs) + void ignorePlayerLogs(@NonNull PlayerBase playerToIgnore) { + if (DEBUG_LOG_SOUND_FX) { + return; + } + sendMsg(mAudioHandler, MSG_NO_LOG_FOR_PLAYER_I, SENDMSG_REPLACE, + /*arg1, piid of the player*/ playerToIgnore.getPlayerIId(), + /*arg2 ignored*/ 0, /*obj ignored*/ null, /*delay*/ 0); + } + //----------------------------------------------------------------- // monitoring requests for volume range initialization @Override // AudioSystemAdapter.OnVolRangeInitRequestListener @@ -8640,6 +8656,10 @@ public class AudioService extends IAudioService.Stub // fold parameter format: "device_folded=x" where x is one of on, off mAudioSystem.setParameters((String) msg.obj); break; + + case MSG_NO_LOG_FOR_PLAYER_I: + mPlaybackMonitor.ignorePlayerIId(msg.arg1); + break; } } } diff --git a/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java b/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java index 93841fe288e1e..54be4bbd8f82b 100644 --- a/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java +++ b/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java @@ -171,6 +171,18 @@ public final class PlaybackActivityMonitor return toBan; } + //================================================================= + // Player to ignore (only handling single player, designed for ignoring + // in the logs one specific player such as the touch sounds player) + @GuardedBy("mPlayerLock") + private ArrayList mDoNotLogPiidList = new ArrayList<>(); + + /*package*/ void ignorePlayerIId(int doNotLogPiid) { + synchronized (mPlayerLock) { + mDoNotLogPiidList.add(doNotLogPiid); + } + } + //================================================================= // Track players and their states // methods playerAttributes, playerEvent, releasePlayer are all oneway calls @@ -295,13 +307,20 @@ public final class PlaybackActivityMonitor Log.v(TAG, String.format("playerEvent(piid=%d, deviceId=%d, event=%s)", piid, deviceId, AudioPlaybackConfiguration.playerStateToString(event))); } - final boolean change; + boolean change; synchronized(mPlayerLock) { final AudioPlaybackConfiguration apc = mPlayers.get(new Integer(piid)); if (apc == null) { return; } + + final boolean doNotLog = mDoNotLogPiidList.contains(piid); + if (doNotLog && event != AudioPlaybackConfiguration.PLAYER_STATE_RELEASED) { + // do not log nor dispatch events for "ignored" players other than the release + return; + } sEventLogger.log(new PlayerEvent(piid, event, deviceId)); + if (event == AudioPlaybackConfiguration.PLAYER_STATE_STARTED) { for (Integer uidInteger: mBannedUids) { if (checkBanPlayer(apc, uidInteger.intValue())) { @@ -312,7 +331,8 @@ public final class PlaybackActivityMonitor } } } - if (apc.getPlayerType() == AudioPlaybackConfiguration.PLAYER_TYPE_JAM_SOUNDPOOL) { + if (apc.getPlayerType() == AudioPlaybackConfiguration.PLAYER_TYPE_JAM_SOUNDPOOL + && event != AudioPlaybackConfiguration.PLAYER_STATE_RELEASED) { // FIXME SoundPool not ready for state reporting return; } @@ -324,9 +344,15 @@ public final class PlaybackActivityMonitor Log.e(TAG, "Error handling event " + event); change = false; } - if (change && event == AudioPlaybackConfiguration.PLAYER_STATE_STARTED) { - mDuckingManager.checkDuck(apc); - mFadingManager.checkFade(apc); + if (change) { + if (event == AudioPlaybackConfiguration.PLAYER_STATE_STARTED) { + mDuckingManager.checkDuck(apc); + mFadingManager.checkFade(apc); + } + if (doNotLog) { + // do not dispatch events for "ignored" players + change = false; + } } } if (change) { @@ -354,6 +380,11 @@ public final class PlaybackActivityMonitor checkVolumeForPrivilegedAlarm(apc, AudioPlaybackConfiguration.PLAYER_STATE_RELEASED); change = apc.handleStateEvent(AudioPlaybackConfiguration.PLAYER_STATE_RELEASED, AudioPlaybackConfiguration.PLAYER_DEVICEID_INVALID); + + if (change && mDoNotLogPiidList.contains(piid)) { + // do not dispatch a change for a "do not log" player + change = false; + } } } if (change) { @@ -467,6 +498,9 @@ public final class PlaybackActivityMonitor for (Integer piidInt : piidIntList) { final AudioPlaybackConfiguration apc = mPlayers.get(piidInt); if (apc != null) { + if (mDoNotLogPiidList.contains(apc.getPlayerInterfaceId())) { + pw.print("(not logged)"); + } apc.dump(pw); } } diff --git a/services/core/java/com/android/server/audio/SoundEffectsHelper.java b/services/core/java/com/android/server/audio/SoundEffectsHelper.java index 7031e02af05a5..518b113a9f2d7 100644 --- a/services/core/java/com/android/server/audio/SoundEffectsHelper.java +++ b/services/core/java/com/android/server/audio/SoundEffectsHelper.java @@ -25,6 +25,7 @@ import android.media.AudioSystem; import android.media.MediaPlayer; import android.media.MediaPlayer.OnCompletionListener; import android.media.MediaPlayer.OnErrorListener; +import android.media.PlayerBase; import android.media.SoundPool; import android.os.Environment; import android.os.Handler; @@ -46,6 +47,7 @@ import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.function.Consumer; /** * A helper class for managing sound effects loading / unloading @@ -107,11 +109,14 @@ class SoundEffectsHelper { private final int[] mEffects = new int[AudioManager.NUM_SOUND_EFFECTS]; // indexes in mResources private SoundPool mSoundPool; private SoundPoolLoader mSoundPoolLoader; + /** callback to provide handle to the player of the sound effects */ + private final Consumer mPlayerAvailableCb; - SoundEffectsHelper(Context context) { + SoundEffectsHelper(Context context, Consumer playerAvailableCb) { mContext = context; mSfxAttenuationDb = mContext.getResources().getInteger( com.android.internal.R.integer.config_soundEffectVolumeDb); + mPlayerAvailableCb = playerAvailableCb; startWorker(); } @@ -187,6 +192,7 @@ class SoundEffectsHelper { .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION) .build()) .build(); + mPlayerAvailableCb.accept(mSoundPool); loadSoundAssets(); mSoundPoolLoader = new SoundPoolLoader();