/*
 * Copyright 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.media;

import static android.media.MediaConstants.KEY_ALLOWED_COMMANDS;
import static android.media.MediaConstants.KEY_CONNECTION_HINTS;
import static android.media.MediaConstants.KEY_PACKAGE_NAME;
import static android.media.MediaConstants.KEY_PID;
import static android.media.MediaConstants.KEY_PLAYBACK_ACTIVE;
import static android.media.MediaConstants.KEY_SESSION2LINK;
import static android.media.MediaConstants.KEY_TOKEN_EXTRAS;
import static android.media.Session2Command.Result.RESULT_ERROR_UNKNOWN_ERROR;
import static android.media.Session2Command.Result.RESULT_INFO_SKIPPED;
import static android.media.Session2Token.TYPE_SESSION;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.media.session.MediaSessionManager;
import android.media.session.MediaSessionManager.RemoteUserInfo;
import android.os.BadParcelableException;
import android.os.Bundle;
import android.os.Handler;
import android.os.Parcel;
import android.os.Process;
import android.os.ResultReceiver;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Log;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.Executor;

/**
 * This API is not generally intended for third party application developers.
 * Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a>
 * <a href="{@docRoot}reference/androidx/media2/session/package-summary.html">Media2 session
 * Library</a> for consistent behavior across all devices.
 * <p>
 * Allows a media app to expose its transport controls and playback information in a process to
 * other processes including the Android framework and other apps.
 */
public class MediaSession2 implements AutoCloseable {
    static final String TAG = "MediaSession2";
    static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);

    // Note: This checks the uniqueness of a session ID only in a single process.
    // When the framework becomes able to check the uniqueness, this logic should be removed.
    //@GuardedBy("MediaSession.class")
    private static final List<String> SESSION_ID_LIST = new ArrayList<>();

    @SuppressWarnings("WeakerAccess") /* synthetic access */
    final Object mLock = new Object();
    //@GuardedBy("mLock")
    @SuppressWarnings("WeakerAccess") /* synthetic access */
    final Map<Controller2Link, ControllerInfo> mConnectedControllers = new HashMap<>();

    @SuppressWarnings("WeakerAccess") /* synthetic access */
    final Context mContext;
    @SuppressWarnings("WeakerAccess") /* synthetic access */
    final Executor mCallbackExecutor;
    @SuppressWarnings("WeakerAccess") /* synthetic access */
    final SessionCallback mCallback;
    @SuppressWarnings("WeakerAccess") /* synthetic access */
    final Session2Link mSessionStub;

    private final String mSessionId;
    private final PendingIntent mSessionActivity;
    private final Session2Token mSessionToken;
    private final MediaSessionManager mSessionManager;
    private final Handler mResultHandler;

    //@GuardedBy("mLock")
    private boolean mClosed;
    //@GuardedBy("mLock")
    private boolean mPlaybackActive;
    //@GuardedBy("mLock")
    private ForegroundServiceEventCallback mForegroundServiceEventCallback;

    MediaSession2(@NonNull Context context, @NonNull String id, PendingIntent sessionActivity,
            @NonNull Executor callbackExecutor, @NonNull SessionCallback callback,
            @NonNull Bundle tokenExtras) {
        synchronized (MediaSession2.class) {
            if (SESSION_ID_LIST.contains(id)) {
                throw new IllegalStateException("Session ID must be unique. ID=" + id);
            }
            SESSION_ID_LIST.add(id);
        }

        mContext = context;
        mSessionId = id;
        mSessionActivity = sessionActivity;
        mCallbackExecutor = callbackExecutor;
        mCallback = callback;
        mSessionStub = new Session2Link(this);
        mSessionToken = new Session2Token(Process.myUid(), TYPE_SESSION, context.getPackageName(),
                mSessionStub, tokenExtras);
        mSessionManager = (MediaSessionManager) mContext.getSystemService(
                Context.MEDIA_SESSION_SERVICE);
        // NOTE: mResultHandler uses main looper, so this MUST NOT be blocked.
        mResultHandler = new Handler(context.getMainLooper());
        mClosed = false;
    }

    @Override
    public void close() {
        try {
            List<ControllerInfo> controllerInfos;
            ForegroundServiceEventCallback callback;
            synchronized (mLock) {
                if (mClosed) {
                    return;
                }
                mClosed = true;
                controllerInfos = getConnectedControllers();
                mConnectedControllers.clear();
                callback = mForegroundServiceEventCallback;
                mForegroundServiceEventCallback = null;
            }
            synchronized (MediaSession2.class) {
                SESSION_ID_LIST.remove(mSessionId);
            }
            if (callback != null) {
                callback.onSessionClosed(this);
            }
            for (ControllerInfo info : controllerInfos) {
                info.notifyDisconnected();
            }
        } catch (Exception e) {
            // Should not be here.
        }
    }

    /**
     * Returns the session ID
     */
    @NonNull
    public String getId() {
        return mSessionId;
    }

    /**
     * Returns the {@link Session2Token} for creating {@link MediaController2}.
     */
    @NonNull
    public Session2Token getToken() {
        return mSessionToken;
    }

    /**
     * Broadcasts a session command to all the connected controllers
     * <p>
     * @param command the session command
     * @param args optional arguments
     */
    public void broadcastSessionCommand(@NonNull Session2Command command, @Nullable Bundle args) {
        if (command == null) {
            throw new IllegalArgumentException("command shouldn't be null");
        }
        List<ControllerInfo> controllerInfos = getConnectedControllers();
        for (ControllerInfo controller : controllerInfos) {
            controller.sendSessionCommand(command, args, null);
        }
    }

    /**
     * Sends a session command to a specific controller
     * <p>
     * @param controller the controller to get the session command
     * @param command the session command
     * @param args optional arguments
     * @return a token which will be sent together in {@link SessionCallback#onCommandResult}
     *     when its result is received.
     */
    @NonNull
    public Object sendSessionCommand(@NonNull ControllerInfo controller,
            @NonNull Session2Command command, @Nullable Bundle args) {
        if (controller == null) {
            throw new IllegalArgumentException("controller shouldn't be null");
        }
        if (command == null) {
            throw new IllegalArgumentException("command shouldn't be null");
        }
        ResultReceiver resultReceiver = new ResultReceiver(mResultHandler) {
            protected void onReceiveResult(int resultCode, Bundle resultData) {
                controller.receiveCommandResult(this);
                mCallbackExecutor.execute(() -> {
                    mCallback.onCommandResult(MediaSession2.this, controller, this,
                            command, new Session2Command.Result(resultCode, resultData));
                });
            }
        };
        controller.sendSessionCommand(command, args, resultReceiver);
        return resultReceiver;
    }

    /**
     * Cancels the session command previously sent.
     *
     * @param controller the controller to get the session command
     * @param token the token which is returned from {@link #sendSessionCommand}.
     */
    public void cancelSessionCommand(@NonNull ControllerInfo controller, @NonNull Object token) {
        if (controller == null) {
            throw new IllegalArgumentException("controller shouldn't be null");
        }
        if (token == null) {
            throw new IllegalArgumentException("token shouldn't be null");
        }
        controller.cancelSessionCommand(token);
    }

    /**
     * Sets whether the playback is active (i.e. playing something)
     *
     * @param playbackActive {@code true} if the playback active, {@code false} otherwise.
     **/
    public void setPlaybackActive(boolean playbackActive) {
        final ForegroundServiceEventCallback serviceCallback;
        synchronized (mLock) {
            if (mPlaybackActive == playbackActive) {
                return;
            }
            mPlaybackActive = playbackActive;
            serviceCallback = mForegroundServiceEventCallback;
        }
        if (serviceCallback != null) {
            serviceCallback.onPlaybackActiveChanged(this, playbackActive);
        }
        List<ControllerInfo> controllerInfos = getConnectedControllers();
        for (ControllerInfo controller : controllerInfos) {
            controller.notifyPlaybackActiveChanged(playbackActive);
        }
    }

    /**
     * Returns whehther the playback is active (i.e. playing something)
     *
     * @return {@code true} if the playback active, {@code false} otherwise.
     */
    public boolean isPlaybackActive() {
        synchronized (mLock) {
            return mPlaybackActive;
        }
    }

    /**
     * Gets the list of the connected controllers
     *
     * @return list of the connected controllers.
     */
    @NonNull
    public List<ControllerInfo> getConnectedControllers() {
        List<ControllerInfo> controllers = new ArrayList<>();
        synchronized (mLock) {
            controllers.addAll(mConnectedControllers.values());
        }
        return controllers;
    }

    /**
     * Returns whether the given bundle includes non-framework Parcelables.
     */
    static boolean hasCustomParcelable(@Nullable Bundle bundle) {
        if (bundle == null) {
            return false;
        }

        // Try writing the bundle to parcel, and read it with framework classloader.
        Parcel parcel = null;
        try {
            parcel = Parcel.obtain();
            parcel.writeBundle(bundle);
            parcel.setDataPosition(0);
            Bundle out = parcel.readBundle(null);

            // Calling Bundle#size() will trigger Bundle#unparcel().
            out.size();
        } catch (BadParcelableException e) {
            Log.d(TAG, "Custom parcelable in bundle.", e);
            return true;
        } finally {
            if (parcel != null) {
                parcel.recycle();
            }
        }
        return false;
    }

    boolean isClosed() {
        synchronized (mLock) {
            return mClosed;
        }
    }

    SessionCallback getCallback() {
        return mCallback;
    }

    void setForegroundServiceEventCallback(ForegroundServiceEventCallback callback) {
        synchronized (mLock) {
            if (mForegroundServiceEventCallback == callback) {
                return;
            }
            if (mForegroundServiceEventCallback != null && callback != null) {
                throw new IllegalStateException("A session cannot be added to multiple services");
            }
            mForegroundServiceEventCallback = callback;
        }
    }

    // Called by Session2Link.onConnect and MediaSession2Service.MediaSession2ServiceStub.connect
    void onConnect(final Controller2Link controller, int callingPid, int callingUid, int seq,
            Bundle connectionRequest) {
        if (callingPid == 0) {
            // The pid here is from Binder.getCallingPid(), which can be 0 for an oneway call from
            // the remote process. If it's the case, use PID from the connectionRequest.
            callingPid = connectionRequest.getInt(KEY_PID);
        }
        String callingPkg = connectionRequest.getString(KEY_PACKAGE_NAME);

        RemoteUserInfo remoteUserInfo = new RemoteUserInfo(callingPkg, callingPid, callingUid);

        Bundle connectionHints = connectionRequest.getBundle(KEY_CONNECTION_HINTS);
        if (connectionHints == null) {
            Log.w(TAG, "connectionHints shouldn't be null.");
            connectionHints = Bundle.EMPTY;
        } else if (hasCustomParcelable(connectionHints)) {
            Log.w(TAG, "connectionHints contain custom parcelable. Ignoring.");
            connectionHints = Bundle.EMPTY;
        }

        final ControllerInfo controllerInfo = new ControllerInfo(
                remoteUserInfo,
                mSessionManager.isTrustedForMediaControl(remoteUserInfo),
                controller,
                connectionHints);
        mCallbackExecutor.execute(() -> {
            boolean connected = false;
            try {
                if (isClosed()) {
                    return;
                }
                controllerInfo.mAllowedCommands =
                        mCallback.onConnect(MediaSession2.this, controllerInfo);
                // Don't reject connection for the request from trusted app.
                // Otherwise server will fail to retrieve session's information to dispatch
                // media keys to.
                if (controllerInfo.mAllowedCommands == null && !controllerInfo.isTrusted()) {
                    return;
                }
                if (controllerInfo.mAllowedCommands == null) {
                    // For trusted apps, send non-null allowed commands to keep
                    // connection.
                    controllerInfo.mAllowedCommands =
                            new Session2CommandGroup.Builder().build();
                }
                if (DEBUG) {
                    Log.d(TAG, "Accepting connection: " + controllerInfo);
                }
                // If connection is accepted, notify the current state to the controller.
                // It's needed because we cannot call synchronous calls between
                // session/controller.
                Bundle connectionResult = new Bundle();
                connectionResult.putParcelable(KEY_SESSION2LINK, mSessionStub);
                connectionResult.putParcelable(KEY_ALLOWED_COMMANDS,
                        controllerInfo.mAllowedCommands);
                connectionResult.putBoolean(KEY_PLAYBACK_ACTIVE, isPlaybackActive());
                connectionResult.putBundle(KEY_TOKEN_EXTRAS, mSessionToken.getExtras());

                // Double check if session is still there, because close() can be called in
                // another thread.
                if (isClosed()) {
                    return;
                }
                controllerInfo.notifyConnected(connectionResult);
                synchronized (mLock) {
                    if (mConnectedControllers.containsKey(controller)) {
                        Log.w(TAG, "Controller " + controllerInfo + " has sent connection"
                                + " request multiple times");
                    }
                    mConnectedControllers.put(controller, controllerInfo);
                }
                mCallback.onPostConnect(MediaSession2.this, controllerInfo);
                connected = true;
            } finally {
                if (!connected) {
                    if (DEBUG) {
                        Log.d(TAG, "Rejecting connection or notifying that session is closed"
                                + ", controllerInfo=" + controllerInfo);
                    }
                    synchronized (mLock) {
                        mConnectedControllers.remove(controller);
                    }
                    controllerInfo.notifyDisconnected();
                }
            }
        });
    }

    // Called by Session2Link.onDisconnect
    void onDisconnect(@NonNull final Controller2Link controller, int seq) {
        final ControllerInfo controllerInfo;
        synchronized (mLock) {
            controllerInfo = mConnectedControllers.remove(controller);
        }
        if (controllerInfo == null) {
            return;
        }
        mCallbackExecutor.execute(() -> {
            mCallback.onDisconnected(MediaSession2.this, controllerInfo);
        });
    }

    // Called by Session2Link.onSessionCommand
    void onSessionCommand(@NonNull final Controller2Link controller, final int seq,
            final Session2Command command, final Bundle args,
            @Nullable ResultReceiver resultReceiver) {
        if (controller == null) {
            return;
        }
        final ControllerInfo controllerInfo;
        synchronized (mLock) {
            controllerInfo = mConnectedControllers.get(controller);
        }
        if (controllerInfo == null) {
            return;
        }

        // TODO: check allowed commands.
        synchronized (mLock) {
            controllerInfo.addRequestedCommandSeqNumber(seq);
        }
        mCallbackExecutor.execute(() -> {
            if (!controllerInfo.removeRequestedCommandSeqNumber(seq)) {
                resultReceiver.send(RESULT_INFO_SKIPPED, null);
                return;
            }
            Session2Command.Result result = mCallback.onSessionCommand(
                    MediaSession2.this, controllerInfo, command, args);
            if (resultReceiver != null) {
                if (result == null) {
                    resultReceiver.send(RESULT_INFO_SKIPPED, null);
                } else {
                    resultReceiver.send(result.getResultCode(), result.getResultData());
                }
            }
        });
    }

    // Called by Session2Link.onCancelCommand
    void onCancelCommand(@NonNull final Controller2Link controller, final int seq) {
        final ControllerInfo controllerInfo;
        synchronized (mLock) {
            controllerInfo = mConnectedControllers.get(controller);
        }
        if (controllerInfo == null) {
            return;
        }
        controllerInfo.removeRequestedCommandSeqNumber(seq);
    }

    /**
     * This API is not generally intended for third party application developers.
     * Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a>
     * <a href="{@docRoot}reference/androidx/media2/session/package-summary.html">Media2 session
     * Library</a> for consistent behavior across all devices.
     * <p>
     * Builder for {@link MediaSession2}.
     * <p>
     * Any incoming event from the {@link MediaController2} will be handled on the callback
     * executor. If it's not set, {@link Context#getMainExecutor()} will be used by default.
     */
    public static final class Builder {
        private Context mContext;
        private String mId;
        private PendingIntent mSessionActivity;
        private Executor mCallbackExecutor;
        private SessionCallback mCallback;
        private Bundle mExtras;

        /**
         * Creates a builder for {@link MediaSession2}.
         *
         * @param context Context
         * @throws IllegalArgumentException if context is {@code null}.
         */
        public Builder(@NonNull Context context) {
            if (context == null) {
                throw new IllegalArgumentException("context shouldn't be null");
            }
            mContext = context;
        }

        /**
         * Set an intent for launching UI for this Session. This can be used as a
         * quick link to an ongoing media screen. The intent should be for an
         * activity that may be started using {@link Context#startActivity(Intent)}.
         *
         * @param pi The intent to launch to show UI for this session.
         * @return The Builder to allow chaining
         */
        @NonNull
        public Builder setSessionActivity(@Nullable PendingIntent pi) {
            mSessionActivity = pi;
            return this;
        }

        /**
         * Set ID of the session. If it's not set, an empty string will be used to create a session.
         * <p>
         * Use this if and only if your app supports multiple playback at the same time and also
         * wants to provide external apps to have finer controls of them.
         *
         * @param id id of the session. Must be unique per package.
         * @throws IllegalArgumentException if id is {@code null}.
         * @return The Builder to allow chaining
         */
        @NonNull
        public Builder setId(@NonNull String id) {
            if (id == null) {
                throw new IllegalArgumentException("id shouldn't be null");
            }
            mId = id;
            return this;
        }

        /**
         * Set callback for the session and its executor.
         *
         * @param executor callback executor
         * @param callback session callback.
         * @return The Builder to allow chaining
         */
        @NonNull
        public Builder setSessionCallback(@NonNull Executor executor,
                @NonNull SessionCallback callback) {
            mCallbackExecutor = executor;
            mCallback = callback;
            return this;
        }

        /**
         * Set extras for the session token. If null or not set, {@link Session2Token#getExtras()}
         * will return an empty {@link Bundle}. An {@link IllegalArgumentException} will be thrown
         * if the bundle contains any non-framework Parcelable objects.
         *
         * @return The Builder to allow chaining
         * @see Session2Token#getExtras()
         */
        @NonNull
        public Builder setExtras(@NonNull Bundle extras) {
            if (extras == null) {
                throw new NullPointerException("extras shouldn't be null");
            }
            if (hasCustomParcelable(extras)) {
                throw new IllegalArgumentException(
                        "extras shouldn't contain any custom parcelables");
            }
            mExtras = new Bundle(extras);
            return this;
        }

        /**
         * Build {@link MediaSession2}.
         *
         * @return a new session
         * @throws IllegalStateException if the session with the same id is already exists for the
         *      package.
         */
        @NonNull
        public MediaSession2 build() {
            if (mCallbackExecutor == null) {
                mCallbackExecutor = mContext.getMainExecutor();
            }
            if (mCallback == null) {
                mCallback = new SessionCallback() {};
            }
            if (mId == null) {
                mId = "";
            }
            if (mExtras == null) {
                mExtras = Bundle.EMPTY;
            }
            MediaSession2 session2 = new MediaSession2(mContext, mId, mSessionActivity,
                    mCallbackExecutor, mCallback, mExtras);

            // Notify framework about the newly create session after the constructor is finished.
            // Otherwise, framework may access the session before the initialization is finished.
            try {
                MediaSessionManager manager = (MediaSessionManager) mContext.getSystemService(
                        Context.MEDIA_SESSION_SERVICE);
                manager.notifySession2Created(session2.getToken());
            } catch (Exception e) {
                session2.close();
                throw e;
            }

            return session2;
        }
    }

    /**
     * This API is not generally intended for third party application developers.
     * Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a>
     * <a href="{@docRoot}reference/androidx/media2/session/package-summary.html">Media2 session
     * Library</a> for consistent behavior across all devices.
     * <p>
     * Information of a controller.
     */
    public static final class ControllerInfo {
        private final RemoteUserInfo mRemoteUserInfo;
        private final boolean mIsTrusted;
        private final Controller2Link mControllerBinder;
        private final Bundle mConnectionHints;
        private final Object mLock = new Object();
        //@GuardedBy("mLock")
        private int mNextSeqNumber;
        //@GuardedBy("mLock")
        private ArrayMap<ResultReceiver, Integer> mPendingCommands;
        //@GuardedBy("mLock")
        private ArraySet<Integer> mRequestedCommandSeqNumbers;

        @SuppressWarnings("WeakerAccess") /* synthetic access */
        Session2CommandGroup mAllowedCommands;

        /**
         * @param remoteUserInfo remote user info
         * @param trusted {@code true} if trusted, {@code false} otherwise
         * @param controllerBinder Controller2Link for the connected controller.
         * @param connectionHints a session-specific argument sent from the controller for the
         *                        connection. The contents of this bundle may affect the
         *                        connection result.
         */
        ControllerInfo(@NonNull RemoteUserInfo remoteUserInfo, boolean trusted,
                @Nullable Controller2Link controllerBinder, @NonNull Bundle connectionHints) {
            mRemoteUserInfo = remoteUserInfo;
            mIsTrusted = trusted;
            mControllerBinder = controllerBinder;
            mConnectionHints = connectionHints;
            mPendingCommands = new ArrayMap<>();
            mRequestedCommandSeqNumbers = new ArraySet<>();
        }

        /**
         * @return remote user info of the controller.
         */
        @NonNull
        public RemoteUserInfo getRemoteUserInfo() {
            return mRemoteUserInfo;
        }

        /**
         * @return package name of the controller.
         */
        @NonNull
        public String getPackageName() {
            return mRemoteUserInfo.getPackageName();
        }

        /**
         * @return uid of the controller. Can be a negative value if the uid cannot be obtained.
         */
        public int getUid() {
            return mRemoteUserInfo.getUid();
        }

        /**
         * @return connection hints sent from controller.
         */
        @NonNull
        public Bundle getConnectionHints() {
            return new Bundle(mConnectionHints);
        }

        /**
         * Return if the controller has granted {@code android.permission.MEDIA_CONTENT_CONTROL} or
         * has a enabled notification listener so can be trusted to accept connection and incoming
         * command request.
         *
         * @return {@code true} if the controller is trusted.
         * @hide
         */
        public boolean isTrusted() {
            return mIsTrusted;
        }

        @Override
        public int hashCode() {
            return Objects.hash(mControllerBinder, mRemoteUserInfo);
        }

        @Override
        public boolean equals(@Nullable Object obj) {
            if (!(obj instanceof ControllerInfo)) return false;
            if (this == obj) return true;

            ControllerInfo other = (ControllerInfo) obj;
            if (mControllerBinder != null || other.mControllerBinder != null) {
                return Objects.equals(mControllerBinder, other.mControllerBinder);
            }
            return mRemoteUserInfo.equals(other.mRemoteUserInfo);
        }

        @Override
        @NonNull
        public String toString() {
            return "ControllerInfo {pkg=" + mRemoteUserInfo.getPackageName() + ", uid="
                    + mRemoteUserInfo.getUid() + ", allowedCommands=" + mAllowedCommands + "})";
        }

        void notifyConnected(Bundle connectionResult) {
            if (mControllerBinder == null) return;

            try {
                mControllerBinder.notifyConnected(getNextSeqNumber(), connectionResult);
            } catch (RuntimeException e) {
                // Controller may be died prematurely.
            }
        }

        void notifyDisconnected() {
            if (mControllerBinder == null) return;

            try {
                mControllerBinder.notifyDisconnected(getNextSeqNumber());
            } catch (RuntimeException e) {
                // Controller may be died prematurely.
            }
        }

        void notifyPlaybackActiveChanged(boolean playbackActive) {
            if (mControllerBinder == null) return;

            try {
                mControllerBinder.notifyPlaybackActiveChanged(getNextSeqNumber(), playbackActive);
            } catch (RuntimeException e) {
                // Controller may be died prematurely.
            }
        }

        void sendSessionCommand(Session2Command command, Bundle args,
                ResultReceiver resultReceiver) {
            if (mControllerBinder == null) return;

            try {
                int seq = getNextSeqNumber();
                synchronized (mLock) {
                    mPendingCommands.put(resultReceiver, seq);
                }
                mControllerBinder.sendSessionCommand(seq, command, args, resultReceiver);
            } catch (RuntimeException e) {
                // Controller may be died prematurely.
                synchronized (mLock) {
                    mPendingCommands.remove(resultReceiver);
                }
                resultReceiver.send(RESULT_ERROR_UNKNOWN_ERROR, null);
            }
        }

        void cancelSessionCommand(@NonNull Object token) {
            if (mControllerBinder == null) return;
            Integer seq;
            synchronized (mLock) {
                seq = mPendingCommands.remove(token);
            }
            if (seq != null) {
                mControllerBinder.cancelSessionCommand(seq);
            }
        }

        void receiveCommandResult(ResultReceiver resultReceiver) {
            synchronized (mLock) {
                mPendingCommands.remove(resultReceiver);
            }
        }

        void addRequestedCommandSeqNumber(int seq) {
            synchronized (mLock) {
                mRequestedCommandSeqNumbers.add(seq);
            }
        }

        boolean removeRequestedCommandSeqNumber(int seq) {
            synchronized (mLock) {
                return mRequestedCommandSeqNumbers.remove(seq);
            }
        }

        private int getNextSeqNumber() {
            synchronized (mLock) {
                return mNextSeqNumber++;
            }
        }
    }

    /**
     * This API is not generally intended for third party application developers.
     * Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a>
     * <a href="{@docRoot}reference/androidx/media2/session/package-summary.html">Media2 session
     * Library</a> for consistent behavior across all devices.
     * <p>
     * Callback to be called for all incoming commands from {@link MediaController2}s.
     */
    public abstract static class SessionCallback {
        /**
         * Called when a controller is created for this session. Return allowed commands for
         * controller. By default it returns {@code null}.
         * <p>
         * You can reject the connection by returning {@code null}. In that case, controller
         * receives {@link MediaController2.ControllerCallback#onDisconnected(MediaController2)}
         * and cannot be used.
         * <p>
         * The controller hasn't connected yet in this method, so calls to the controller
         * (e.g. {@link #sendSessionCommand}) would be ignored. Override {@link #onPostConnect} for
         * the custom initialization for the controller instead.
         *
         * @param session the session for this event
         * @param controller controller information.
         * @return allowed commands. Can be {@code null} to reject connection.
         */
        @Nullable
        public Session2CommandGroup onConnect(@NonNull MediaSession2 session,
                @NonNull ControllerInfo controller) {
            return null;
        }

        /**
         * Called immediately after a controller is connected. This is a convenient method to add
         * custom initialization between the session and a controller.
         * <p>
         * Note that calls to the controller (e.g. {@link #sendSessionCommand}) work here but don't
         * work in {@link #onConnect} because the controller hasn't connected yet in
         * {@link #onConnect}.
         *
         * @param session the session for this event
         * @param controller controller information.
         */
        public void onPostConnect(@NonNull MediaSession2 session,
                @NonNull ControllerInfo controller) {
        }

        /**
         * Called when a controller is disconnected
         *
         * @param session the session for this event
         * @param controller controller information
         */
        public void onDisconnected(@NonNull MediaSession2 session,
                @NonNull ControllerInfo controller) {}

        /**
         * Called when a controller sent a session command.
         *
         * @param session the session for this event
         * @param controller controller information
         * @param command the session command
         * @param args optional arguments
         * @return the result for the session command. If {@code null}, RESULT_INFO_SKIPPED
         *         will be sent to the session.
         */
        @Nullable
        public Session2Command.Result onSessionCommand(@NonNull MediaSession2 session,
                @NonNull ControllerInfo controller, @NonNull Session2Command command,
                @Nullable Bundle args) {
            return null;
        }

        /**
         * Called when the command sent to the controller is finished.
         *
         * @param session the session for this event
         * @param controller controller information
         * @param token the token got from {@link MediaSession2#sendSessionCommand}
         * @param command the session command
         * @param result the result of the session command
         */
        public void onCommandResult(@NonNull MediaSession2 session,
                @NonNull ControllerInfo controller, @NonNull Object token,
                @NonNull Session2Command command, @NonNull Session2Command.Result result) {}
    }

    abstract static class ForegroundServiceEventCallback {
        public void onPlaybackActiveChanged(MediaSession2 session, boolean playbackActive) {}
        public void onSessionClosed(MediaSession2 session) {}
    }
}
