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

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

Merge "MediaSession2: Implement playFromXXX and prepareFromXXX"

parents 896f1af9 edd9171c
Loading
Loading
Loading
Loading
+10 −3
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.media;

import android.os.Bundle;
import android.os.ResultReceiver;
import android.net.Uri;

import com.android.media.IMediaSession2Callback;

@@ -27,8 +28,7 @@ import com.android.media.IMediaSession2Callback;
 * Keep this interface oneway. Otherwise a malicious app may implement fake version of this,
 * and holds calls from session to make session owner(s) frozen.
 */
// TODO: Consider to make some methods oneway
interface IMediaSession2 {
oneway interface IMediaSession2 {
    // TODO(jaewan): add onCommand() to send private command
    // TODO(jaewan): Due to the nature of oneway calls, APIs can be called in out of order
    //               Add id for individual calls to address this.
@@ -52,6 +52,13 @@ interface IMediaSession2 {
    void sendCustomCommand(IMediaSession2Callback caller, in Bundle command, in Bundle args,
            in ResultReceiver receiver);

    void prepareFromUri(IMediaSession2Callback caller, in Uri uri, in Bundle extra);
    void prepareFromSearch(IMediaSession2Callback caller, String query, in Bundle extra);
    void prepareFromMediaId(IMediaSession2Callback caller, String mediaId, in Bundle extra);
    void playFromUri(IMediaSession2Callback caller, in Uri uri, in Bundle extra);
    void playFromSearch(IMediaSession2Callback caller, String query, in Bundle extra);
    void playFromMediaId(IMediaSession2Callback caller, String mediaId, in Bundle extra);

   //////////////////////////////////////////////////////////////////////////////////////////////
    // Get library service specific
    //////////////////////////////////////////////////////////////////////////////////////////////
+62 −9
Original line number Diff line number Diff line
@@ -320,34 +320,87 @@ public class MediaController2Impl implements MediaController2Provider {

    @Override
    public void prepareFromUri_impl(Uri uri, Bundle extras) {
        // TODO(jaewan): Implement
        final IMediaSession2 binder = mSessionBinder;
        if (binder != null) {
            try {
                binder.prepareFromUri(mSessionCallbackStub, uri, extras);
            } catch (RemoteException e) {
                Log.w(TAG, "Cannot connect to the service or the session is gone", e);
            }
        } else {
            // TODO(jaewan): Handle.
        }
    }

    @Override
    public void prepareFromSearch_impl(String query, Bundle extras) {
        // TODO(jaewan): Implement
        final IMediaSession2 binder = mSessionBinder;
        if (binder != null) {
            try {
                binder.prepareFromSearch(mSessionCallbackStub, query, extras);
            } catch (RemoteException e) {
                Log.w(TAG, "Cannot connect to the service or the session is gone", e);
            }
        } else {
            // TODO(jaewan): Handle.
        }
    }

    @Override
    public void prepareMediaId_impl(String mediaId, Bundle extras) {
        // TODO(jaewan): Implement
        final IMediaSession2 binder = mSessionBinder;
        if (binder != null) {
            try {
                binder.prepareFromMediaId(mSessionCallbackStub, mediaId, extras);
            } catch (RemoteException e) {
                Log.w(TAG, "Cannot connect to the service or the session is gone", e);
            }
        } else {
            // TODO(jaewan): Handle.
        }
    }

    @Override
    public void playFromSearch_impl(String query, Bundle extras) {
        // TODO(jaewan): Implement
    public void playFromUri_impl(Uri uri, Bundle extras) {
        final IMediaSession2 binder = mSessionBinder;
        if (binder != null) {
            try {
                binder.playFromUri(mSessionCallbackStub, uri, extras);
            } catch (RemoteException e) {
                Log.w(TAG, "Cannot connect to the service or the session is gone", e);
            }
        } else {
            // TODO(jaewan): Handle.
        }
    }

    @Override
    public void playFromUri_impl(String uri, Bundle extras) {
        // TODO(jaewan): Implement
    public void playFromSearch_impl(String query, Bundle extras) {
        final IMediaSession2 binder = mSessionBinder;
        if (binder != null) {
            try {
                binder.playFromSearch(mSessionCallbackStub, query, extras);
            } catch (RemoteException e) {
                Log.w(TAG, "Cannot connect to the service or the session is gone", e);
            }
        } else {
            // TODO(jaewan): Handle.
        }
    }

    @Override
    public void playFromMediaId_impl(String mediaId, Bundle extras) {
        // TODO(jaewan): Implement
        final IMediaSession2 binder = mSessionBinder;
        if (binder != null) {
            try {
                binder.playFromMediaId(mSessionCallbackStub, mediaId, extras);
            } catch (RemoteException e) {
                Log.w(TAG, "Cannot connect to the service or the session is gone", e);
            }
        } else {
            // TODO(jaewan): Handle.
        }
    }

    @Override
    public void setRating_impl(Rating2 rating) {
        // TODO(jaewan): Implement
+121 −0
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@ import android.media.MediaSession2.PlaylistParams;
import android.media.PlaybackState2;
import android.media.VolumeProvider2;
import android.media.update.MediaSession2Provider.CommandButtonProvider;
import android.net.Uri;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
@@ -366,6 +367,126 @@ public class MediaSession2Stub extends IMediaSession2.Stub {
        });
    }

    @Override
    public void prepareFromUri(final IMediaSession2Callback caller, final Uri uri,
            final Bundle extra) {
        final MediaSession2Impl sessionImpl = getSession();
        final ControllerInfo controller = getController(caller);
        if (controller == null) {
            if (DEBUG) {
                Log.d(TAG, "Command from a controller that hasn't connected. Ignore");
            }
            return;
        }
        sessionImpl.getCallbackExecutor().execute(() -> {
            final MediaSession2Impl session = mSession.get();
            if (session == null) {
                return;
            }
            session.getCallback().onPrepareFromUri(controller, uri, extra);
        });
    }

    @Override
    public void prepareFromSearch(final IMediaSession2Callback caller, final String query,
            final Bundle extra) {
        final MediaSession2Impl sessionImpl = getSession();
        final ControllerInfo controller = getController(caller);
        if (controller == null) {
            if (DEBUG) {
                Log.d(TAG, "Command from a controller that hasn't connected. Ignore");
            }
            return;
        }
        sessionImpl.getCallbackExecutor().execute(() -> {
            final MediaSession2Impl session = mSession.get();
            if (session == null) {
                return;
            }
            session.getCallback().onPrepareFromSearch(controller, query, extra);
        });
    }

    @Override
    public void prepareFromMediaId(final IMediaSession2Callback caller, final String mediaId,
            final Bundle extra) {
        final MediaSession2Impl sessionImpl = getSession();
        final ControllerInfo controller = getController(caller);
        if (controller == null) {
            if (DEBUG) {
                Log.d(TAG, "Command from a controller that hasn't connected. Ignore");
            }
            return;
        }
        sessionImpl.getCallbackExecutor().execute(() -> {
            final MediaSession2Impl session = mSession.get();
            if (session == null) {
                return;
            }
            session.getCallback().onPrepareFromMediaId(controller, mediaId, extra);
        });
    }

    @Override
    public void playFromUri(final IMediaSession2Callback caller, final Uri uri,
            final Bundle extra) {
        final MediaSession2Impl sessionImpl = getSession();
        final ControllerInfo controller = getController(caller);
        if (controller == null) {
            if (DEBUG) {
                Log.d(TAG, "Command from a controller that hasn't connected. Ignore");
            }
            return;
        }
        sessionImpl.getCallbackExecutor().execute(() -> {
            final MediaSession2Impl session = mSession.get();
            if (session == null) {
                return;
            }
            session.getCallback().onPlayFromUri(controller, uri, extra);
        });
    }

    @Override
    public void playFromSearch(final IMediaSession2Callback caller, final String query,
            final Bundle extra) {
        final MediaSession2Impl sessionImpl = getSession();
        final ControllerInfo controller = getController(caller);
        if (controller == null) {
            if (DEBUG) {
                Log.d(TAG, "Command from a controller that hasn't connected. Ignore");
            }
            return;
        }
        sessionImpl.getCallbackExecutor().execute(() -> {
            final MediaSession2Impl session = mSession.get();
            if (session == null) {
                return;
            }
            session.getCallback().onPlayFromSearch(controller, query, extra);
        });
    }

    @Override
    public void playFromMediaId(final IMediaSession2Callback caller, final String mediaId,
            final Bundle extra) {
        final MediaSession2Impl sessionImpl = getSession();
        final ControllerInfo controller = getController(caller);
        if (controller == null) {
            if (DEBUG) {
                Log.d(TAG, "Command from a controller that hasn't connected. Ignore");
            }
            return;
        }
        sessionImpl.getCallbackExecutor().execute(() -> {
            final MediaSession2Impl session = mSession.get();
            if (session == null) {
                return;
            }
            session.getCallback().onPlayFromMediaId(controller, mediaId, extra);
        });
    }

    @Override
    public void getBrowserRoot(IMediaSession2Callback caller, Bundle rootHints)
            throws RuntimeException {
+149 −0
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ import android.media.MediaSession2.ControllerInfo;
import android.media.MediaSession2.PlaylistParams;
import android.media.MediaSession2.SessionCallback;
import android.media.TestUtils.SyncHandler;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
@@ -375,6 +376,151 @@ public class MediaController2Test extends MediaSession2TestBase {
        waitForDisconnect(mController, true);
    }

    @Test
    public void testPlayFromSearch() throws InterruptedException {
        final String request = "random query";
        final Bundle bundle = new Bundle();
        bundle.putString("key", "value");
        final CountDownLatch latch = new CountDownLatch(1);
        final SessionCallback callback = new SessionCallback(mContext) {
            @Override
            public void onPlayFromSearch(ControllerInfo controller, String query, Bundle extras) {
                assertEquals(mContext.getPackageName(), controller.getPackageName());
                assertEquals(request, query);
                assertTrue(TestUtils.equals(bundle, extras));
                latch.countDown();;
            }
        };
        try (MediaSession2 session = new MediaSession2.Builder(mContext, mPlayer)
                .setSessionCallback(sHandlerExecutor, callback)
                .setId("testPlayFromSearch").build()) {
            MediaController2 controller = createController(session.getToken());
            controller.playFromSearch(request, bundle);
            assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
        }
    }

    @Test
    public void testPlayFromUri() throws InterruptedException {
        final Uri request = Uri.parse("foo://boo");
        final Bundle bundle = new Bundle();
        bundle.putString("key", "value");
        final CountDownLatch latch = new CountDownLatch(1);
        final SessionCallback callback = new SessionCallback(mContext) {
            @Override
            public void onPlayFromUri(ControllerInfo controller, Uri uri, Bundle extras) {
                assertEquals(mContext.getPackageName(), controller.getPackageName());
                assertEquals(request, uri);
                assertTrue(TestUtils.equals(bundle, extras));
                latch.countDown();;
            }
        };
        try (MediaSession2 session = new MediaSession2.Builder(mContext, mPlayer)
                .setSessionCallback(sHandlerExecutor, callback)
                .setId("testPlayFromUri").build()) {
            MediaController2 controller = createController(session.getToken());
            controller.playFromUri(request, bundle);
            assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
        }
    }

    @Test
    public void testPlayFromMediaId() throws InterruptedException {
        final String request = "media_id";
        final Bundle bundle = new Bundle();
        bundle.putString("key", "value");
        final CountDownLatch latch = new CountDownLatch(1);
        final SessionCallback callback = new SessionCallback(mContext) {
            @Override
            public void onPlayFromMediaId(ControllerInfo controller, String id, Bundle extras) {
                assertEquals(mContext.getPackageName(), controller.getPackageName());
                assertEquals(request, id);
                assertTrue(TestUtils.equals(bundle, extras));
                latch.countDown();;
            }
        };
        try (MediaSession2 session = new MediaSession2.Builder(mContext, mPlayer)
                .setSessionCallback(sHandlerExecutor, callback)
                .setId("testPlayFromMediaId").build()) {
            MediaController2 controller = createController(session.getToken());
            controller.playFromMediaId(request, bundle);
            assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
        }
    }


    @Test
    public void testPrepareFromSearch() throws InterruptedException {
        final String request = "random query";
        final Bundle bundle = new Bundle();
        bundle.putString("key", "value");
        final CountDownLatch latch = new CountDownLatch(1);
        final SessionCallback callback = new SessionCallback(mContext) {
            @Override
            public void onPrepareFromSearch(ControllerInfo controller, String query, Bundle extras) {
                assertEquals(mContext.getPackageName(), controller.getPackageName());
                assertEquals(request, query);
                assertTrue(TestUtils.equals(bundle, extras));
                latch.countDown();;
            }
        };
        try (MediaSession2 session = new MediaSession2.Builder(mContext, mPlayer)
                .setSessionCallback(sHandlerExecutor, callback)
                .setId("testPrepareFromSearch").build()) {
            MediaController2 controller = createController(session.getToken());
            controller.prepareFromSearch(request, bundle);
            assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
        }
    }

    @Test
    public void testPrepareFromUri() throws InterruptedException {
        final Uri request = Uri.parse("foo://boo");
        final Bundle bundle = new Bundle();
        bundle.putString("key", "value");
        final CountDownLatch latch = new CountDownLatch(1);
        final SessionCallback callback = new SessionCallback(mContext) {
            @Override
            public void onPrepareFromUri(ControllerInfo controller, Uri uri, Bundle extras) {
                assertEquals(mContext.getPackageName(), controller.getPackageName());
                assertEquals(request, uri);
                assertTrue(TestUtils.equals(bundle, extras));
                latch.countDown();;
            }
        };
        try (MediaSession2 session = new MediaSession2.Builder(mContext, mPlayer)
                .setSessionCallback(sHandlerExecutor, callback)
                .setId("testPrepareFromUri").build()) {
            MediaController2 controller = createController(session.getToken());
            controller.prepareFromUri(request, bundle);
            assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
        }
    }

    @Test
    public void testPrepareFromMediaId() throws InterruptedException {
        final String request = "media_id";
        final Bundle bundle = new Bundle();
        bundle.putString("key", "value");
        final CountDownLatch latch = new CountDownLatch(1);
        final SessionCallback callback = new SessionCallback(mContext) {
            @Override
            public void onPrepareFromMediaId(ControllerInfo controller, String id, Bundle extras) {
                assertEquals(mContext.getPackageName(), controller.getPackageName());
                assertEquals(request, id);
                assertTrue(TestUtils.equals(bundle, extras));
                latch.countDown();;
            }
        };
        try (MediaSession2 session = new MediaSession2.Builder(mContext, mPlayer)
                .setSessionCallback(sHandlerExecutor, callback)
                .setId("testPrepareFromMediaId").build()) {
            MediaController2 controller = createController(session.getToken());
            controller.prepareFromMediaId(request, bundle);
            assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
        }
    }

    @Test
    public void testIsConnected() throws InterruptedException {
        assertTrue(mController.isConnected());
@@ -511,11 +657,14 @@ public class MediaController2Test extends MediaSession2TestBase {
        */
    }

    // TODO(jaewan): Re-enable after b/72792686 is fixed
    @Ignore
    @Test
    public void testControllerAfterSessionIsGone_session() throws InterruptedException {
        testControllerAfterSessionIsGone(mSession.getToken().getId());
    }

    // TODO(jaewan): Re-enable after b/72792686 is fixed
    @Ignore
    @Test
    public void testControllerAfterSessionIsGone_sessionService() throws InterruptedException {