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

Commit b7f8f718 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Handle disconnection of MediaSession2/Controller2"

parents 1ebc3f0d cfd36a5a
Loading
Loading
Loading
Loading
+16 −0
Original line number Diff line number Diff line
@@ -21,6 +21,8 @@ import android.os.Parcel;
import android.os.Parcelable;
import android.os.RemoteException;

import java.util.Objects;

/**
 * Handles incoming commands from {@link MediaSession2} and {@link MediaLibrarySession}
 * to both {@link MediaController2} and {@link MediaBrowser2}.
@@ -68,6 +70,20 @@ public final class Controller2Link implements Parcelable {
        dest.writeStrongBinder(mIController.asBinder());
    }

    @Override
    public int hashCode() {
        return mIController.asBinder().hashCode();
    }

    @Override
    public boolean equals(Object obj) {
        if (!(obj instanceof Controller2Link)) {
            return false;
        }
        Controller2Link other = (Controller2Link) obj;
        return Objects.equals(mIController.asBinder(), other.mIController.asBinder());
    }

    /** Interface method for IMediaController2.notifyConnected */
    public void notifyConnected(int seq, Bundle connectionResult) {
        try {
+11 −2
Original line number Diff line number Diff line
@@ -98,7 +98,6 @@ public class MediaController2 implements AutoCloseable {

        mNextSeqNumber = 0;

        Session2Link sessionBinder = token.getSessionLink();
        if (token.getType() == TYPE_SESSION) {
            connectToSession();
        } else {
@@ -120,9 +119,11 @@ public class MediaController2 implements AutoCloseable {
            mCallbackExecutor.execute(() -> {
                mCallback.onDisconnected(MediaController2.this);
            });
            mSessionBinder = null;
        }
    }

    // Called by Controller2Link.onConnected
    void onConnected(int seq, Bundle connectionResult) {
        final long token = Binder.clearCallingIdentity();
        try {
@@ -155,10 +156,18 @@ public class MediaController2 implements AutoCloseable {
        }
    }

    // Called by Controller2Link.onDisconnected
    void onDisconnected(int seq) {
        // TODO: Implement this
        final long token = Binder.clearCallingIdentity();
        try {
            // close() will call mCallback.onDisconnected
            close();
        } finally {
            Binder.restoreCallingIdentity(token);
        }
    }

    // Called by Controller2Link.onSessionCommand
    void onSessionCommand(int seq, Session2Command command, Bundle args) {
        // TODO: Implement this
    }
+59 −22
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@ import android.os.Process;
import android.util.Log;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -107,7 +108,13 @@ public class MediaSession2 implements AutoCloseable {
            synchronized (MediaSession2.class) {
                SESSION_ID_LIST.remove(mSessionId);
            }
            // TODO: Implement this
            Collection<ControllerInfo> controllerInfos;
            synchronized (mLock) {
                controllerInfos = mConnectedControllers.values();
            }
            for (ControllerInfo info : controllerInfos) {
                info.notifyDisconnected();
            }
        } catch (Exception e) {
            // Should not be here.
        }
@@ -118,6 +125,7 @@ public class MediaSession2 implements AutoCloseable {
        return true;
    }

    // Called by Session2Link.onConnect
    void onConnect(final Controller2Link controller, int seq, Bundle connectionRequest) {
        if (controller == null || connectionRequest == null) {
            return;
@@ -173,21 +181,12 @@ public class MediaSession2 implements AutoCloseable {
                    if (isClosed()) {
                        return;
                    }
                    try {
                        controller.notifyConnected(
                                controllerInfo.mNextSeqNumber++, connectionResult);
                    } catch (RuntimeException e) {
                        // Controller may be died prematurely.
                    }
                    controllerInfo.notifyConnected(connectionResult);
                } else {
                    if (DEBUG) {
                        Log.d(TAG, "Rejecting connection, controllerInfo=" + controllerInfo);
                    }
                    try {
                        controller.notifyDisconnected(controllerInfo.mNextSeqNumber++);
                    } catch (RuntimeException e) {
                        // Controller may be died prematurely.
                    }
                    controllerInfo.notifyDisconnected();
                }
            });
        } finally {
@@ -195,20 +194,24 @@ public class MediaSession2 implements AutoCloseable {
        }
    }

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

        final long token = Binder.clearCallingIdentity();
        try {
            synchronized (mLock) {
                final ControllerInfo controllerInfo = mConnectedControllers.get(controller);
                mCallbackExecutor.execute(() -> {
                    try {
                        controller.notifyDisconnected(controllerInfo.mNextSeqNumber++);
                    } catch (RuntimeException e) {
                        // Controller may be died prematurely.
                    }
                    mCallback.onDisconnected(MediaSession2.this, controllerInfo);
                });
                mConnectedControllers.remove(controller);
            }
@@ -217,6 +220,7 @@ public class MediaSession2 implements AutoCloseable {
        }
    }

    // Called by Session2Link.onSessionCommand
    void onSessionCommand(final Controller2Link controller, final int seq,
            final Session2Command command, final Bundle args) {
        // TODO: Implement this
@@ -323,13 +327,12 @@ public class MediaSession2 implements AutoCloseable {
     * <p>
     * This API is not generally intended for third party application developers.
     */
    public static final class ControllerInfo {
    static final class ControllerInfo {
        private final RemoteUserInfo mRemoteUserInfo;
        private final boolean mIsTrusted;
        private final Controller2Link mControllerBinder;
        private int mNextSeqNumber;

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

@@ -348,7 +351,7 @@ public class MediaSession2 implements AutoCloseable {
        }

        /**
         * @hide
         * @return remote user info of the controller.
         */
        @NonNull
        public RemoteUserInfo getRemoteUserInfo() {
@@ -370,6 +373,36 @@ public class MediaSession2 implements AutoCloseable {
            return mRemoteUserInfo.getUid();
        }

        public void notifyConnected(Bundle connectionResult) {
            if (mControllerBinder != null) {
                try {
                    mControllerBinder.notifyConnected(getNextSeqNumber(), connectionResult);
                } catch (RuntimeException e) {
                    // Controller may be died prematurely.
                }
            }
        }

        public void notifyDisconnected() {
            if (mControllerBinder != null) {
                try {
                    mControllerBinder.notifyDisconnected(getNextSeqNumber());
                } catch (RuntimeException e) {
                    // Controller may be died prematurely.
                }
            }
        }

        public void sendSessionCommand(Session2Command command, Bundle args) {
            if (mControllerBinder != null) {
                try {
                    mControllerBinder.sendSessionCommand(getNextSeqNumber(), command, args);
                } catch (RuntimeException e) {
                    // Controller may be died prematurely.
                }
            }
        }

        /**
         * 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
@@ -407,6 +440,10 @@ public class MediaSession2 implements AutoCloseable {
            return "ControllerInfo {pkg=" + mRemoteUserInfo.getPackageName() + ", uid="
                    + mRemoteUserInfo.getUid() + ", allowedCommands=" + mAllowedCommands + "})";
        }

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

    /**