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();