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

Commit c1fdd5df authored by Jean-Michel Trivi's avatar Jean-Michel Trivi Committed by Android (Google) Code Review
Browse files

Merge "AudioPlaybackConfiguration has a player control interface"

parents 18de051c 9dc22c22
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -21848,6 +21848,7 @@ package android.media {
    method public android.media.AudioAttributes getAudioAttributes();
    method public int getClientPid();
    method public int getClientUid();
    method public int getPlayerInterfaceId();
    method public int getPlayerState();
    method public int getPlayerType();
    method public void writeToParcel(android.os.Parcel, int);
+9 −0
Original line number Diff line number Diff line
@@ -631,6 +631,15 @@ public class AudioManager {

    private static IAudioService sService;

    /**
     * @hide
     * For test purposes only, will throw NPE with some methods that require a Context.
     */
    public AudioManager() {
        mUseVolumeKeySounds = true;
        mUseFixedVolume = false;
    }

    /**
     * @hide
     */
+102 −0
Original line number Diff line number Diff line
@@ -20,8 +20,10 @@ import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.os.Binder;
import android.os.IBinder;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.RemoteException;
import android.util.Log;

import java.io.PrintWriter;
@@ -36,6 +38,8 @@ import java.util.Objects;
public final class AudioPlaybackConfiguration implements Parcelable {
    private final static String TAG = new String("AudioPlaybackConfiguration");

    private final static boolean DEBUG = false;

    /** @hide */
    public final static int PLAYER_PIID_INVALID = -1;
    /** @hide */
@@ -147,6 +151,8 @@ public final class AudioPlaybackConfiguration implements Parcelable {
    private int mPlayerType;
    private int mClientUid;
    private int mClientPid;
    // the IPlayer reference and death monitor
    private IPlayerShell mIPlayerShell;

    private int mPlayerState;
    private AudioAttributes mPlayerAttr; // never null
@@ -156,18 +162,34 @@ public final class AudioPlaybackConfiguration implements Parcelable {
     */
    private AudioPlaybackConfiguration(int piid) {
        mPlayerIId = piid;
        mIPlayerShell = null;
    }

    /**
     * @hide
     */
    public AudioPlaybackConfiguration(PlayerBase.PlayerIdCard pic, int piid, int uid, int pid) {
        if (DEBUG) { Log.d(TAG, "new: piid=" + piid + " iplayer=" + pic.mIPlayer); }
        mPlayerIId = piid;
        mPlayerType = pic.mPlayerType;
        mClientUid = uid;
        mClientPid = pid;
        mPlayerState = PLAYER_STATE_IDLE;
        mPlayerAttr = pic.mAttributes;
        if ((sPlayerDeathMonitor != null) && (pic.mIPlayer != null)) {
            mIPlayerShell = new IPlayerShell(this, pic.mIPlayer);
        } else {
            mIPlayerShell = null;
        }
    }

    /**
     * @hide
     */
    public void init() {
        if (mIPlayerShell != null) {
            mIPlayerShell.monitorDeath();
        }
    }

    // Note that this method is called server side, so no "privileged" information is ever sent
@@ -191,6 +213,7 @@ public final class AudioPlaybackConfiguration implements Parcelable {
        anonymCopy.mPlayerType = PLAYER_TYPE_UNKNOWN;
        anonymCopy.mClientUid = PLAYER_UPID_INVALID;
        anonymCopy.mClientPid = PLAYER_UPID_INVALID;
        anonymCopy.mIPlayerShell = null;
        return anonymCopy;
    }

@@ -248,6 +271,25 @@ public final class AudioPlaybackConfiguration implements Parcelable {
        return mPlayerState;
    }

    /**
     * @hide
     * Return an identifier unique for the lifetime of the player.
     * @return a player interface identifier
     */
    @SystemApi
    public int getPlayerInterfaceId() {
        return mPlayerIId;
    }

    /**
     * @hide
     * FIXME return a player proxy instead, make systemApi
     * @return
     */
    public IPlayer getPlayerProxy() {
        return mIPlayerShell == null ? null : mIPlayerShell.getIPlayer();
    }

    /**
     * @hide
     * Handle a change of audio attributes
@@ -268,9 +310,26 @@ public final class AudioPlaybackConfiguration implements Parcelable {
    public boolean handleStateEvent(int event) {
        final boolean changed = (mPlayerState != event);
        mPlayerState = event;
        if ((event == PLAYER_STATE_RELEASED) && (mIPlayerShell != null)) {
            mIPlayerShell.release();
        }
        return changed;
    }

    // To report IPlayer death from death recipient
    /** @hide */
    public interface PlayerDeathMonitor {
        public void playerDeath(int piid);
    }
    /** @hide */
    public static PlayerDeathMonitor sPlayerDeathMonitor;

    private void playerDied() {
        if (sPlayerDeathMonitor != null) {
            sPlayerDeathMonitor.playerDeath(mPlayerIId);
        }
    }

    /**
     * @hide
     * Returns true if the player is considered "active", i.e. actively playing, and thus
@@ -338,6 +397,7 @@ public final class AudioPlaybackConfiguration implements Parcelable {
        dest.writeInt(mClientPid);
        dest.writeInt(mPlayerState);
        mPlayerAttr.writeToParcel(dest, 0);
        dest.writeStrongInterface(mIPlayerShell == null ? null : mIPlayerShell.getIPlayer());
    }

    private AudioPlaybackConfiguration(Parcel in) {
@@ -347,6 +407,8 @@ public final class AudioPlaybackConfiguration implements Parcelable {
        mClientPid = in.readInt();
        mPlayerState = in.readInt();
        mPlayerAttr = AudioAttributes.CREATOR.createFromParcel(in);
        final IPlayer p = IPlayer.Stub.asInterface(in.readStrongBinder());
        mIPlayerShell = (p == null) ? null : new IPlayerShell(null, p);
    }

    @Override
@@ -362,6 +424,46 @@ public final class AudioPlaybackConfiguration implements Parcelable {
                && (mClientPid == that.mClientPid));
    }

    //=====================================================================
    // Inner class for corresponding IPlayer and its death monitoring
    final static class IPlayerShell implements IBinder.DeathRecipient {

        final AudioPlaybackConfiguration mMonitor; // never null
        private IPlayer mIPlayer;

        IPlayerShell(@NonNull AudioPlaybackConfiguration monitor, @NonNull IPlayer iplayer) {
            mMonitor = monitor;
            mIPlayer = iplayer;
        }

        void monitorDeath() {
            try {
                mIPlayer.asBinder().linkToDeath(this, 0);
            } catch (RemoteException e) {
                if (mMonitor != null) {
                    Log.w(TAG, "Could not link to client death for piid=" + mMonitor.mPlayerIId, e);
                } else {
                    Log.w(TAG, "Could not link to client death", e);
                }
            }
        }

        IPlayer getIPlayer() {
            return mIPlayer;
        }

        public void binderDied() {
            if (mMonitor != null) {
                if (DEBUG) { Log.i(TAG, "IPlayerShell binderDied for piid=" + mMonitor.mPlayerIId);}
                mMonitor.playerDied();
            } else if (DEBUG) { Log.i(TAG, "IPlayerShell binderDied"); }
        }

        void release() {
            mIPlayer.asBinder().unlinkToDeath(this, 0);
        }
    }

    //=====================================================================
    // Utilities

+21 −0
Original line number Diff line number Diff line
@@ -537,6 +537,8 @@ public class AudioTrack extends PlayerBase
        } else {
            mState = STATE_INITIALIZED;
        }

        baseRegisterPlayer();
    }

    /**
@@ -566,6 +568,7 @@ public class AudioTrack extends PlayerBase

        // other initialization...
        if (nativeTrackInJavaObj != 0) {
            baseRegisterPlayer();
            deferred_connect(nativeTrackInJavaObj);
        } else {
            mState = STATE_UNINITIALIZED;
@@ -2738,6 +2741,24 @@ public class AudioTrack extends PlayerBase
        }
    }

    //---------------------------------------------------------
    // Methods for IPlayer interface
    //--------------------
    @Override
    void playerStart() {
        play();
    }

    @Override
    void playerPause() {
        pause();
    }

    @Override
    void playerStop() {
        stop();
    }

    //---------------------------------------------------------
    // Java methods called from the native side
    //--------------------
+1 −0
Original line number Diff line number Diff line
@@ -24,4 +24,5 @@ interface IPlayer {
    oneway void start();
    oneway void pause();
    oneway void stop();
    oneway void setVolume(float vol);
}
Loading