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

Commit 0b67b9fa authored by Jean-Michel Trivi's avatar Jean-Michel Trivi
Browse files

AudioService: log focus changes and limit focus stack size

Log audio focus request and abandon commands.
Limit the size of the audio focus stack to prevent malicious
  applications trying to run the process out of memory.

Test: use media apps and speech reco, check dumpsys audio
Bug: 67055749
Change-Id: I529529fe40f33a8f67c64c3c61ba22d9530fb4d9
parent d675f51c
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -49,9 +49,9 @@ public class AudioEventLogger {
        }

        /**
         * Causes the string message for the event to appear in the verbose logcat.
         * Causes the string message for the event to appear in the logcat.
         * Here is an example of how to create a new event (a StringEvent), adding it to the logger
         * (an instance of AudioEventLogger) while also making it show in the verbose logcat:
         * (an instance of AudioEventLogger) while also making it show in the logcat:
         * <pre>
         *     myLogger.log(
         *         (new StringEvent("something for logcat and logger")).printLog(MyClass.TAG) );
@@ -60,7 +60,7 @@ public class AudioEventLogger {
         * @return the same instance of the event
         */
        public Event printLog(String tag) {
            Log.v(tag, eventToString());
            Log.i(tag, eventToString());
            return this;
        }

+30 −9
Original line number Diff line number Diff line
@@ -89,6 +89,9 @@ public class MediaFocusControl implements PlayerFocusEnforcer {
        pw.println("\nMediaFocusControl dump time: "
                + DateFormat.getTimeInstance().format(new Date()));
        dumpFocusStack(pw);
        pw.println("\n");
        // log
        mEventLogger.dump(pw);
    }

    //=================================================================
@@ -119,6 +122,14 @@ public class MediaFocusControl implements PlayerFocusEnforcer {

    private final static Object mAudioFocusLock = new Object();

    /**
     * Arbitrary maximum size of audio focus stack to prevent apps OOM'ing this process.
     */
    private static final int MAX_STACK_SIZE = 100;

    private static final AudioEventLogger mEventLogger = new AudioEventLogger(50,
            "focus commands as seen by MediaFocusControl");

    /**
     * Discard the current audio focus owner.
     * Notify top of audio focus stack that it lost focus (regardless of possibility to reassign
@@ -643,11 +654,14 @@ public class MediaFocusControl implements PlayerFocusEnforcer {
    protected int requestAudioFocus(AudioAttributes aa, int focusChangeHint, IBinder cb,
            IAudioFocusDispatcher fd, String clientId, String callingPackageName, int flags,
            int sdk) {
        Log.i(TAG, " AudioFocus  requestAudioFocus() from uid/pid " + Binder.getCallingUid()
        mEventLogger.log((new AudioEventLogger.StringEvent(
                "requestAudioFocus() from uid/pid " + Binder.getCallingUid()
                    + "/" + Binder.getCallingPid()
                + " clientId=" + clientId
                    + " clientId=" + clientId + " callingPack=" + callingPackageName
                    + " req=" + focusChangeHint
                + " flags=0x" + Integer.toHexString(flags));
                    + " flags=0x" + Integer.toHexString(flags)
                    + " sdk=" + sdk))
                .printLog(TAG));
        // we need a valid binder callback for clients
        if (!cb.pingBinder()) {
            Log.e(TAG, " AudioFocus DOA client for requestAudioFocus(), aborting.");
@@ -660,6 +674,11 @@ public class MediaFocusControl implements PlayerFocusEnforcer {
        }

        synchronized(mAudioFocusLock) {
            if (mFocusStack.size() > MAX_STACK_SIZE) {
                Log.e(TAG, "Max AudioFocus stack size reached, failing requestAudioFocus()");
                return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
            }

            boolean enteringRingOrCall = !mRingOrCallActive
                    & (AudioSystem.IN_VOICE_COMM_FOCUS_ID.compareTo(clientId) == 0);
            if (enteringRingOrCall) { mRingOrCallActive = true; }
@@ -770,10 +789,12 @@ public class MediaFocusControl implements PlayerFocusEnforcer {
     * */
    protected int abandonAudioFocus(IAudioFocusDispatcher fl, String clientId, AudioAttributes aa,
            String callingPackageName) {
        // AudioAttributes are currently ignored, to be used for zones
        Log.i(TAG, " AudioFocus  abandonAudioFocus() from uid/pid " + Binder.getCallingUid()
        // AudioAttributes are currently ignored, to be used for zones / a11y
        mEventLogger.log((new AudioEventLogger.StringEvent(
                "abandonAudioFocus() from uid/pid " + Binder.getCallingUid()
                    + "/" + Binder.getCallingPid()
                + " clientId=" + clientId);
                    + " clientId=" + clientId))
                .printLog(TAG));
        try {
            // this will take care of notifying the new focus owner if needed
            synchronized(mAudioFocusLock) {