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

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

AudioService: Make suspended apps lose audio focus

Handle ACTION_PACKAGES_SUSPENDED in AudioService.
Send FOCUS_LOSS to any suspended app that is in the focus
  stack and remove it from the stack
Annotate nullability of package name, AudioAttributes
  and clientId for audio focus.

Bug: 119328282
Test: suspend app with focus, check output of dumpsys audio
Change-Id: I34103f8910146fc573c9efc806e8f1a1ffc722c9
parent 826e270c
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -3409,13 +3409,13 @@ package android.media {
  public final class AudioFocusInfo implements android.os.Parcelable {
    method public int describeContents();
    method public android.media.AudioAttributes getAttributes();
    method public String getClientId();
    method @NonNull public android.media.AudioAttributes getAttributes();
    method @NonNull public String getClientId();
    method public int getClientUid();
    method public int getFlags();
    method public int getGainRequest();
    method public int getLossReceived();
    method public String getPackageName();
    method @NonNull public String getPackageName();
    method public void writeToParcel(android.os.Parcel, int);
    field public static final android.os.Parcelable.Creator<android.media.AudioFocusInfo> CREATOR;
  }
+16 −7
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package android.media;

import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
@@ -29,10 +30,10 @@ import java.util.Objects;
@SystemApi
public final class AudioFocusInfo implements Parcelable {

    private final AudioAttributes mAttributes;
    private final @NonNull AudioAttributes mAttributes;
    private final int mClientUid;
    private final String mClientId;
    private final String mPackageName;
    private final @NonNull String mClientId;
    private final @NonNull String mPackageName;
    private final int mSdkTarget;
    private int mGainRequest;
    private int mLossReceived;
@@ -80,13 +81,21 @@ public final class AudioFocusInfo implements Parcelable {
     * The audio attributes for the audio focus request.
     * @return non-null {@link AudioAttributes}.
     */
    public AudioAttributes getAttributes() { return mAttributes; }
    public @NonNull AudioAttributes getAttributes() {
        return mAttributes;
    }

    public int getClientUid() { return mClientUid; }
    public int getClientUid() {
        return mClientUid;
    }

    public String getClientId() { return mClientId; }
    public @NonNull String getClientId() {
        return mClientId;
    }

    public String getPackageName() { return mPackageName; }
    public @NonNull String getPackageName() {
        return mPackageName;
    }

    /**
     * The type of audio focus gain request.
+3 −3
Original line number Diff line number Diff line
@@ -225,9 +225,9 @@ public final class AudioFocusRequest {
    /** @hide */
    public static final String KEY_ACCESSIBILITY_FORCE_FOCUS_DUCKING = "a11y_force_ducking";

    private final OnAudioFocusChangeListener mFocusListener; // may be null
    private final Handler mListenerHandler;                  // may be null
    private final AudioAttributes mAttr;                     // never null
    private final @Nullable OnAudioFocusChangeListener mFocusListener;
    private final @Nullable Handler mListenerHandler;
    private final @NonNull AudioAttributes mAttr;
    private final int mFocusGain;
    private final int mFlags;

+20 −0
Original line number Diff line number Diff line
@@ -754,6 +754,7 @@ public class AudioService extends IAudioService.Stub
        intentFilter.addAction(Intent.ACTION_USER_FOREGROUND);
        intentFilter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
        intentFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
        intentFilter.addAction(Intent.ACTION_PACKAGES_SUSPENDED);

        intentFilter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
        mMonitorRotation = SystemProperties.getBoolean("ro.audio.monitorRotation", false);
@@ -5183,6 +5184,20 @@ public class AudioService extends IAudioService.Stub
            } else if (action.equals(AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION) ||
                    action.equals(AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION)) {
                handleAudioEffectBroadcast(context, intent);
            } else if (action.equals(Intent.ACTION_PACKAGES_SUSPENDED)) {
                final int[] suspendedUids = intent.getIntArrayExtra(Intent.EXTRA_CHANGED_UID_LIST);
                final String[] suspendedPackages =
                        intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
                if (suspendedPackages == null || suspendedUids == null
                        || suspendedPackages.length != suspendedUids.length) {
                    return;
                }
                for (int i = 0; i < suspendedUids.length; i++) {
                    if (!TextUtils.isEmpty(suspendedPackages[i])) {
                        mMediaFocusControl.noFocusForSuspendedApp(
                                suspendedPackages[i], suspendedUids[i]);
                    }
                }
            }
        }
    } // end class AudioServiceBroadcastReceiver
@@ -5347,6 +5362,11 @@ public class AudioService extends IAudioService.Stub
            }
        }

        if (callingPackageName == null || clientId == null || aa == null) {
            Log.e(TAG, "Invalid null parameter to request audio focus");
            return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
        }

        return mMediaFocusControl.requestAudioFocus(aa, durationHint, cb, fd,
                clientId, callingPackageName, flags, sdk,
                forceFocusDuckingForAccessibility(aa, durationHint, Binder.getCallingUid()));
+10 −17
Original line number Diff line number Diff line
@@ -45,8 +45,8 @@ public class FocusRequester {
    private AudioFocusDeathHandler mDeathHandler; // may be null
    private IAudioFocusDispatcher mFocusDispatcher; // may be null
    private final IBinder mSourceRef; // may be null
    private final String mClientId;
    private final String mPackageName;
    private final @NonNull String mClientId;
    private final @NonNull String mPackageName;
    private final int mCallingUid;
    private final MediaFocusControl mFocusController; // never null
    private final int mSdkTarget;
@@ -72,7 +72,7 @@ public class FocusRequester {
    /**
     * the audio attributes associated with the focus request
     */
    private final AudioAttributes mAttributes;
    private final @NonNull AudioAttributes mAttributes;

    /**
     * Class constructor
@@ -87,9 +87,10 @@ public class FocusRequester {
     * @param uid
     * @param ctlr cannot be null
     */
    FocusRequester(AudioAttributes aa, int focusRequest, int grantFlags,
            IAudioFocusDispatcher afl, IBinder source, String id, AudioFocusDeathHandler hdlr,
            String pn, int uid, @NonNull MediaFocusControl ctlr, int sdk) {
    FocusRequester(@NonNull AudioAttributes aa, int focusRequest, int grantFlags,
            IAudioFocusDispatcher afl, IBinder source, @NonNull String id,
            AudioFocusDeathHandler hdlr, @NonNull String pn, int uid,
            @NonNull MediaFocusControl ctlr, int sdk) {
        mAttributes = aa;
        mFocusDispatcher = afl;
        mSourceRef = source;
@@ -124,11 +125,7 @@ public class FocusRequester {
    }

    boolean hasSameClient(String otherClient) {
        try {
        return mClientId.compareTo(otherClient) == 0;
        } catch (NullPointerException e) {
            return false;
        }
    }

    boolean isLockedFocusOwner() {
@@ -143,12 +140,8 @@ public class FocusRequester {
        return (mFocusDispatcher != null) && mFocusDispatcher.equals(fd);
    }

    boolean hasSamePackage(String pack) {
        try {
    boolean hasSamePackage(@NonNull String pack) {
        return mPackageName.compareTo(pack) == 0;
        } catch (NullPointerException e) {
            return false;
        }
    }

    boolean hasSameUid(int uid) {
Loading