Loading packages/MediaComponents/test/src/android/media/MediaController2Test.java +30 −20 Original line number Diff line number Diff line Loading @@ -21,9 +21,11 @@ import android.content.Context; import android.content.Intent; import android.media.MediaPlayerInterface.PlaybackListener; import android.media.MediaSession2.Command; import android.media.MediaSession2.CommandGroup; import android.media.MediaSession2.ControllerInfo; import android.media.MediaSession2.PlaylistParams; import android.media.MediaSession2.SessionCallback; import android.media.TestServiceRegistry.SessionCallbackProxy; import android.media.TestUtils.SyncHandler; import android.net.Uri; import android.os.Bundle; Loading @@ -34,6 +36,7 @@ import android.os.ResultReceiver; import android.support.test.filters.FlakyTest; import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; import android.text.TextUtils; import org.junit.After; import org.junit.Before; Loading Loading @@ -618,24 +621,32 @@ public class MediaController2Test extends MediaSession2TestBase { @Ignore @Test public void testConnectToService_sessionService() throws InterruptedException { connectToService(TestUtils.getServiceToken(mContext, MockMediaSessionService2.ID)); testConnectToService(); testConnectToService(MockMediaSessionService2.ID); } // TODO(jaewan): Reenable when session manager detects app installs @Ignore @Test public void testConnectToService_libraryService() throws InterruptedException { connectToService(TestUtils.getServiceToken(mContext, MockMediaLibraryService2.ID)); testConnectToService(); testConnectToService(MockMediaLibraryService2.ID); } public void testConnectToService() throws InterruptedException { TestServiceRegistry serviceInfo = TestServiceRegistry.getInstance(); ControllerInfo info = serviceInfo.getOnConnectControllerInfo(); assertEquals(mContext.getPackageName(), info.getPackageName()); assertEquals(Process.myUid(), info.getUid()); assertFalse(info.isTrusted()); public void testConnectToService(String id) throws InterruptedException { final CountDownLatch latch = new CountDownLatch(1); final SessionCallbackProxy proxy = new SessionCallbackProxy(mContext) { @Override public CommandGroup onConnect(ControllerInfo controller) { if (Process.myUid() == controller.getUid()) { assertEquals(mContext.getPackageName(), controller.getPackageName()); assertFalse(controller.isTrusted()); latch.countDown();; } return super.onConnect(controller); } }; TestServiceRegistry.getInstance().setSessionCallbackProxy(proxy); mController = createController(TestUtils.getServiceToken(mContext, id)); assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)); // Test command from controller to session service mController.play(); Loading Loading @@ -701,27 +712,26 @@ public class MediaController2Test extends MediaSession2TestBase { @Ignore @Test public void testClose_sessionService() throws InterruptedException { connectToService(TestUtils.getServiceToken(mContext, MockMediaSessionService2.ID)); testCloseFromService(); testCloseFromService(MockMediaSessionService2.ID); } // TODO(jaewan): Reenable when session manager detects app installs @Ignore @Test public void testClose_libraryService() throws InterruptedException { connectToService(TestUtils.getServiceToken(mContext, MockMediaSessionService2.ID)); testCloseFromService(); testCloseFromService(MockMediaLibraryService2.ID); } private void testCloseFromService() throws InterruptedException { final String id = mController.getSessionToken().getId(); private void testCloseFromService(String id) throws InterruptedException { final CountDownLatch latch = new CountDownLatch(1); TestServiceRegistry.getInstance().setServiceInstanceChangedCallback((service) -> { if (service == null) { // Destroying.. final SessionCallbackProxy proxy = new SessionCallbackProxy(mContext) { @Override public void onServiceDestroyed() { latch.countDown(); } }); }; TestServiceRegistry.getInstance().setSessionCallbackProxy(proxy); mController = createController(TestUtils.getServiceToken(mContext, id)); mController.close(); // Wait until close triggers onDestroy() of the session service. assertTrue(latch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS)); Loading packages/MediaComponents/test/src/android/media/MockMediaLibraryService2.java +24 −17 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import static org.junit.Assert.assertEquals; import android.content.Context; import android.media.MediaSession2.CommandGroup; import android.media.MediaSession2.ControllerInfo; import android.media.TestServiceRegistry.SessionCallbackProxy; import android.media.TestUtils.SyncHandler; import android.os.Bundle; import android.os.Process; Loading @@ -32,6 +33,8 @@ import java.io.FileDescriptor; import java.util.ArrayList; import java.util.List; import java.util.concurrent.Executor; import javax.annotation.concurrent.GuardedBy; /** Loading Loading @@ -74,20 +77,27 @@ public class MockMediaLibraryService2 extends MediaLibraryService2 { } } @Override public void onCreate() { super.onCreate(); TestServiceRegistry.getInstance().setServiceInstance(this); } @Override public MediaLibrarySession onCreateSession(String sessionId) { final MockPlayer player = new MockPlayer(1); final SyncHandler handler = (SyncHandler) TestServiceRegistry.getInstance().getHandler(); try { handler.postAndSync(() -> { TestLibrarySessionCallback callback = new TestLibrarySessionCallback(); mSession = new MediaLibrarySessionBuilder(MockMediaLibraryService2.this, player, (runnable) -> handler.post(runnable), callback) .setId(sessionId).build(); }); } catch (InterruptedException e) { fail(e.toString()); } final Executor executor = (runnable) -> handler.post(runnable); SessionCallbackProxy sessionCallbackProxy = TestServiceRegistry.getInstance() .getSessionCallbackProxy(); if (sessionCallbackProxy == null) { // Ensures non-null sessionCallbackProxy = new SessionCallbackProxy(this) {}; } TestLibrarySessionCallback callback = new TestLibrarySessionCallback(sessionCallbackProxy); mSession = new MediaLibrarySessionBuilder(MockMediaLibraryService2.this, player, executor, callback).setId(sessionId).build(); return mSession; } Loading @@ -109,19 +119,16 @@ public class MockMediaLibraryService2 extends MediaLibraryService2 { } private class TestLibrarySessionCallback extends MediaLibrarySessionCallback { public TestLibrarySessionCallback() { private final SessionCallbackProxy mCallbackProxy; public TestLibrarySessionCallback(SessionCallbackProxy callbackProxy) { super(MockMediaLibraryService2.this); mCallbackProxy = callbackProxy; } @Override public CommandGroup onConnect(ControllerInfo controller) { if (Process.myUid() != controller.getUid()) { // It's system app wants to listen changes. Ignore. return super.onConnect(controller); } TestServiceRegistry.getInstance().setServiceInstance( MockMediaLibraryService2.this, controller); return super.onConnect(controller); return mCallbackProxy.onConnect(controller); } @Override Loading packages/MediaComponents/test/src/android/media/MockMediaSessionService2.java +26 −26 Original line number Diff line number Diff line Loading @@ -22,11 +22,11 @@ import android.app.Notification; import android.app.NotificationChannel; import android.app.NotificationManager; import android.content.Context; import android.media.MediaSession2.CommandGroup; import android.media.MediaSession2.ControllerInfo; import android.media.MediaSession2.SessionCallback; import android.media.TestServiceRegistry.SessionCallbackProxy; import android.media.TestUtils.SyncHandler; import android.media.session.PlaybackState; import android.os.Process; import java.util.concurrent.Executor; Loading @@ -44,29 +44,32 @@ public class MockMediaSessionService2 extends MediaSessionService2 { private MediaSession2 mSession; private NotificationManager mNotificationManager; @Override public void onCreate() { super.onCreate(); TestServiceRegistry.getInstance().setServiceInstance(this); mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); } @Override public MediaSession2 onCreateSession(String sessionId) { final MockPlayer player = new MockPlayer(1); final SyncHandler handler = (SyncHandler) TestServiceRegistry.getInstance().getHandler(); final Executor executor = (runnable) -> handler.post(runnable); try { handler.postAndSync(() -> { mSession = new MediaSession2.Builder(MockMediaSessionService2.this, player) .setSessionCallback(executor, new MySessionCallback()) .setId(sessionId).build(); }); } catch (InterruptedException e) { fail(e.toString()); SessionCallbackProxy sessionCallbackProxy = TestServiceRegistry.getInstance() .getSessionCallbackProxy(); if (sessionCallbackProxy == null) { // Ensures non-null sessionCallbackProxy = new SessionCallbackProxy(this) {}; } TestSessionServiceCallback callback = new TestSessionServiceCallback(sessionCallbackProxy); mSession = new MediaSession2.Builder(this, player) .setSessionCallback(executor, callback) .setId(sessionId).build(); return mSession; } @Override public void onCreate() { super.onCreate(); mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); } @Override public void onDestroy() { TestServiceRegistry.getInstance().cleanUp(); Loading @@ -90,20 +93,17 @@ public class MockMediaSessionService2 extends MediaSessionService2 { return new MediaNotification(this, DEFAULT_MEDIA_NOTIFICATION_ID, notification); } private class MySessionCallback extends SessionCallback { public MySessionCallback() { private class TestSessionServiceCallback extends SessionCallback { private final SessionCallbackProxy mCallbackProxy; public TestSessionServiceCallback(SessionCallbackProxy callbackProxy) { super(MockMediaSessionService2.this); mCallbackProxy = callbackProxy; } @Override public MediaSession2.CommandGroup onConnect(ControllerInfo controller) { if (Process.myUid() != controller.getUid()) { // It's system app wants to listen changes. Ignore. return super.onConnect(controller); } TestServiceRegistry.getInstance().setServiceInstance( MockMediaSessionService2.this, controller); return super.onConnect(controller); public CommandGroup onConnect(ControllerInfo controller) { return mCallbackProxy.onConnect(controller); } } } packages/MediaComponents/test/src/android/media/TestServiceRegistry.java +62 −37 Original line number Diff line number Diff line Loading @@ -18,10 +18,12 @@ package android.media; import static org.junit.Assert.fail; import android.content.Context; import android.media.MediaSession2.CommandGroup; import android.media.MediaSession2.ControllerInfo; import android.media.TestUtils.SyncHandler; import android.os.Handler; import android.os.Looper; import android.os.Process; import android.support.annotation.GuardedBy; /** Loading @@ -31,8 +33,46 @@ import android.support.annotation.GuardedBy; * It only support only one service at a time. */ public class TestServiceRegistry { public interface ServiceInstanceChangedCallback { void OnServiceInstanceChanged(MediaSessionService2 service); /** * Proxy for both {@link MediaSession2.SessionCallback} and * {@link MediaLibraryService2.MediaLibrarySessionCallback}. */ public static abstract class SessionCallbackProxy { private final Context mContext; /** * Constructor */ public SessionCallbackProxy(Context context) { mContext = context; } public final Context getContext() { return mContext; } /** * @param controller * @return */ public CommandGroup onConnect(ControllerInfo controller) { if (Process.myUid() == controller.getUid()) { CommandGroup commands = new CommandGroup(mContext); commands.addAllPredefinedCommands(); return commands; } return null; } /** * Called when enclosing service is created. */ public void onServiceCreated(MediaSessionService2 service) { } /** * Called when enclosing service is destroyed. */ public void onServiceDestroyed() { } } @GuardedBy("TestServiceRegistry.class") Loading @@ -42,9 +82,7 @@ public class TestServiceRegistry { @GuardedBy("TestServiceRegistry.class") private SyncHandler mHandler; @GuardedBy("TestServiceRegistry.class") private ControllerInfo mOnConnectControllerInfo; @GuardedBy("TestServiceRegistry.class") private ServiceInstanceChangedCallback mCallback; private SessionCallbackProxy mCallbackProxy; public static TestServiceRegistry getInstance() { synchronized (TestServiceRegistry.class) { Loading @@ -61,28 +99,33 @@ public class TestServiceRegistry { } } public void setServiceInstanceChangedCallback(ServiceInstanceChangedCallback callback) { public Handler getHandler() { synchronized (TestServiceRegistry.class) { mCallback = callback; return mHandler; } } public Handler getHandler() { public void setSessionCallbackProxy(SessionCallbackProxy callbackProxy) { synchronized (TestServiceRegistry.class) { return mHandler; mCallbackProxy = callbackProxy; } } public SessionCallbackProxy getSessionCallbackProxy() { synchronized (TestServiceRegistry.class) { return mCallbackProxy; } } public void setServiceInstance(MediaSessionService2 service, ControllerInfo controller) { public void setServiceInstance(MediaSessionService2 service) { synchronized (TestServiceRegistry.class) { if (mService != null) { fail("Previous service instance is still running. Clean up manually to ensure" + " previoulsy running service doesn't break current test"); } mService = service; mOnConnectControllerInfo = controller; if (mCallback != null) { mCallback.OnServiceInstanceChanged(service); if (mCallbackProxy != null) { mCallbackProxy.onServiceCreated(service); } } } Loading @@ -93,28 +136,11 @@ public class TestServiceRegistry { } } public ControllerInfo getOnConnectControllerInfo() { synchronized (TestServiceRegistry.class) { return mOnConnectControllerInfo; } } public void cleanUp() { synchronized (TestServiceRegistry.class) { final ServiceInstanceChangedCallback callback = mCallback; final SessionCallbackProxy callbackProxy = mCallbackProxy; if (mService != null) { try { if (mHandler.getLooper() == Looper.myLooper()) { mService.getSession().close(); } else { mHandler.postAndSync(() -> { mService.getSession().close(); }); } } catch (InterruptedException e) { // No-op. Service containing session will die, but shouldn't be a huge issue. } // stopSelf() would not kill service while the binder connection established by // bindService() exists, and close() above will do the job instead. // So stopSelf() isn't really needed, but just for sure. Loading @@ -124,11 +150,10 @@ public class TestServiceRegistry { if (mHandler != null) { mHandler.removeCallbacksAndMessages(null); } mCallback = null; mOnConnectControllerInfo = null; mCallbackProxy = null; if (callback != null) { callback.OnServiceInstanceChanged(null); if (callbackProxy != null) { callbackProxy.onServiceDestroyed(); } } } Loading Loading
packages/MediaComponents/test/src/android/media/MediaController2Test.java +30 −20 Original line number Diff line number Diff line Loading @@ -21,9 +21,11 @@ import android.content.Context; import android.content.Intent; import android.media.MediaPlayerInterface.PlaybackListener; import android.media.MediaSession2.Command; import android.media.MediaSession2.CommandGroup; import android.media.MediaSession2.ControllerInfo; import android.media.MediaSession2.PlaylistParams; import android.media.MediaSession2.SessionCallback; import android.media.TestServiceRegistry.SessionCallbackProxy; import android.media.TestUtils.SyncHandler; import android.net.Uri; import android.os.Bundle; Loading @@ -34,6 +36,7 @@ import android.os.ResultReceiver; import android.support.test.filters.FlakyTest; import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; import android.text.TextUtils; import org.junit.After; import org.junit.Before; Loading Loading @@ -618,24 +621,32 @@ public class MediaController2Test extends MediaSession2TestBase { @Ignore @Test public void testConnectToService_sessionService() throws InterruptedException { connectToService(TestUtils.getServiceToken(mContext, MockMediaSessionService2.ID)); testConnectToService(); testConnectToService(MockMediaSessionService2.ID); } // TODO(jaewan): Reenable when session manager detects app installs @Ignore @Test public void testConnectToService_libraryService() throws InterruptedException { connectToService(TestUtils.getServiceToken(mContext, MockMediaLibraryService2.ID)); testConnectToService(); testConnectToService(MockMediaLibraryService2.ID); } public void testConnectToService() throws InterruptedException { TestServiceRegistry serviceInfo = TestServiceRegistry.getInstance(); ControllerInfo info = serviceInfo.getOnConnectControllerInfo(); assertEquals(mContext.getPackageName(), info.getPackageName()); assertEquals(Process.myUid(), info.getUid()); assertFalse(info.isTrusted()); public void testConnectToService(String id) throws InterruptedException { final CountDownLatch latch = new CountDownLatch(1); final SessionCallbackProxy proxy = new SessionCallbackProxy(mContext) { @Override public CommandGroup onConnect(ControllerInfo controller) { if (Process.myUid() == controller.getUid()) { assertEquals(mContext.getPackageName(), controller.getPackageName()); assertFalse(controller.isTrusted()); latch.countDown();; } return super.onConnect(controller); } }; TestServiceRegistry.getInstance().setSessionCallbackProxy(proxy); mController = createController(TestUtils.getServiceToken(mContext, id)); assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)); // Test command from controller to session service mController.play(); Loading Loading @@ -701,27 +712,26 @@ public class MediaController2Test extends MediaSession2TestBase { @Ignore @Test public void testClose_sessionService() throws InterruptedException { connectToService(TestUtils.getServiceToken(mContext, MockMediaSessionService2.ID)); testCloseFromService(); testCloseFromService(MockMediaSessionService2.ID); } // TODO(jaewan): Reenable when session manager detects app installs @Ignore @Test public void testClose_libraryService() throws InterruptedException { connectToService(TestUtils.getServiceToken(mContext, MockMediaSessionService2.ID)); testCloseFromService(); testCloseFromService(MockMediaLibraryService2.ID); } private void testCloseFromService() throws InterruptedException { final String id = mController.getSessionToken().getId(); private void testCloseFromService(String id) throws InterruptedException { final CountDownLatch latch = new CountDownLatch(1); TestServiceRegistry.getInstance().setServiceInstanceChangedCallback((service) -> { if (service == null) { // Destroying.. final SessionCallbackProxy proxy = new SessionCallbackProxy(mContext) { @Override public void onServiceDestroyed() { latch.countDown(); } }); }; TestServiceRegistry.getInstance().setSessionCallbackProxy(proxy); mController = createController(TestUtils.getServiceToken(mContext, id)); mController.close(); // Wait until close triggers onDestroy() of the session service. assertTrue(latch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS)); Loading
packages/MediaComponents/test/src/android/media/MockMediaLibraryService2.java +24 −17 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import static org.junit.Assert.assertEquals; import android.content.Context; import android.media.MediaSession2.CommandGroup; import android.media.MediaSession2.ControllerInfo; import android.media.TestServiceRegistry.SessionCallbackProxy; import android.media.TestUtils.SyncHandler; import android.os.Bundle; import android.os.Process; Loading @@ -32,6 +33,8 @@ import java.io.FileDescriptor; import java.util.ArrayList; import java.util.List; import java.util.concurrent.Executor; import javax.annotation.concurrent.GuardedBy; /** Loading Loading @@ -74,20 +77,27 @@ public class MockMediaLibraryService2 extends MediaLibraryService2 { } } @Override public void onCreate() { super.onCreate(); TestServiceRegistry.getInstance().setServiceInstance(this); } @Override public MediaLibrarySession onCreateSession(String sessionId) { final MockPlayer player = new MockPlayer(1); final SyncHandler handler = (SyncHandler) TestServiceRegistry.getInstance().getHandler(); try { handler.postAndSync(() -> { TestLibrarySessionCallback callback = new TestLibrarySessionCallback(); mSession = new MediaLibrarySessionBuilder(MockMediaLibraryService2.this, player, (runnable) -> handler.post(runnable), callback) .setId(sessionId).build(); }); } catch (InterruptedException e) { fail(e.toString()); } final Executor executor = (runnable) -> handler.post(runnable); SessionCallbackProxy sessionCallbackProxy = TestServiceRegistry.getInstance() .getSessionCallbackProxy(); if (sessionCallbackProxy == null) { // Ensures non-null sessionCallbackProxy = new SessionCallbackProxy(this) {}; } TestLibrarySessionCallback callback = new TestLibrarySessionCallback(sessionCallbackProxy); mSession = new MediaLibrarySessionBuilder(MockMediaLibraryService2.this, player, executor, callback).setId(sessionId).build(); return mSession; } Loading @@ -109,19 +119,16 @@ public class MockMediaLibraryService2 extends MediaLibraryService2 { } private class TestLibrarySessionCallback extends MediaLibrarySessionCallback { public TestLibrarySessionCallback() { private final SessionCallbackProxy mCallbackProxy; public TestLibrarySessionCallback(SessionCallbackProxy callbackProxy) { super(MockMediaLibraryService2.this); mCallbackProxy = callbackProxy; } @Override public CommandGroup onConnect(ControllerInfo controller) { if (Process.myUid() != controller.getUid()) { // It's system app wants to listen changes. Ignore. return super.onConnect(controller); } TestServiceRegistry.getInstance().setServiceInstance( MockMediaLibraryService2.this, controller); return super.onConnect(controller); return mCallbackProxy.onConnect(controller); } @Override Loading
packages/MediaComponents/test/src/android/media/MockMediaSessionService2.java +26 −26 Original line number Diff line number Diff line Loading @@ -22,11 +22,11 @@ import android.app.Notification; import android.app.NotificationChannel; import android.app.NotificationManager; import android.content.Context; import android.media.MediaSession2.CommandGroup; import android.media.MediaSession2.ControllerInfo; import android.media.MediaSession2.SessionCallback; import android.media.TestServiceRegistry.SessionCallbackProxy; import android.media.TestUtils.SyncHandler; import android.media.session.PlaybackState; import android.os.Process; import java.util.concurrent.Executor; Loading @@ -44,29 +44,32 @@ public class MockMediaSessionService2 extends MediaSessionService2 { private MediaSession2 mSession; private NotificationManager mNotificationManager; @Override public void onCreate() { super.onCreate(); TestServiceRegistry.getInstance().setServiceInstance(this); mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); } @Override public MediaSession2 onCreateSession(String sessionId) { final MockPlayer player = new MockPlayer(1); final SyncHandler handler = (SyncHandler) TestServiceRegistry.getInstance().getHandler(); final Executor executor = (runnable) -> handler.post(runnable); try { handler.postAndSync(() -> { mSession = new MediaSession2.Builder(MockMediaSessionService2.this, player) .setSessionCallback(executor, new MySessionCallback()) .setId(sessionId).build(); }); } catch (InterruptedException e) { fail(e.toString()); SessionCallbackProxy sessionCallbackProxy = TestServiceRegistry.getInstance() .getSessionCallbackProxy(); if (sessionCallbackProxy == null) { // Ensures non-null sessionCallbackProxy = new SessionCallbackProxy(this) {}; } TestSessionServiceCallback callback = new TestSessionServiceCallback(sessionCallbackProxy); mSession = new MediaSession2.Builder(this, player) .setSessionCallback(executor, callback) .setId(sessionId).build(); return mSession; } @Override public void onCreate() { super.onCreate(); mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); } @Override public void onDestroy() { TestServiceRegistry.getInstance().cleanUp(); Loading @@ -90,20 +93,17 @@ public class MockMediaSessionService2 extends MediaSessionService2 { return new MediaNotification(this, DEFAULT_MEDIA_NOTIFICATION_ID, notification); } private class MySessionCallback extends SessionCallback { public MySessionCallback() { private class TestSessionServiceCallback extends SessionCallback { private final SessionCallbackProxy mCallbackProxy; public TestSessionServiceCallback(SessionCallbackProxy callbackProxy) { super(MockMediaSessionService2.this); mCallbackProxy = callbackProxy; } @Override public MediaSession2.CommandGroup onConnect(ControllerInfo controller) { if (Process.myUid() != controller.getUid()) { // It's system app wants to listen changes. Ignore. return super.onConnect(controller); } TestServiceRegistry.getInstance().setServiceInstance( MockMediaSessionService2.this, controller); return super.onConnect(controller); public CommandGroup onConnect(ControllerInfo controller) { return mCallbackProxy.onConnect(controller); } } }
packages/MediaComponents/test/src/android/media/TestServiceRegistry.java +62 −37 Original line number Diff line number Diff line Loading @@ -18,10 +18,12 @@ package android.media; import static org.junit.Assert.fail; import android.content.Context; import android.media.MediaSession2.CommandGroup; import android.media.MediaSession2.ControllerInfo; import android.media.TestUtils.SyncHandler; import android.os.Handler; import android.os.Looper; import android.os.Process; import android.support.annotation.GuardedBy; /** Loading @@ -31,8 +33,46 @@ import android.support.annotation.GuardedBy; * It only support only one service at a time. */ public class TestServiceRegistry { public interface ServiceInstanceChangedCallback { void OnServiceInstanceChanged(MediaSessionService2 service); /** * Proxy for both {@link MediaSession2.SessionCallback} and * {@link MediaLibraryService2.MediaLibrarySessionCallback}. */ public static abstract class SessionCallbackProxy { private final Context mContext; /** * Constructor */ public SessionCallbackProxy(Context context) { mContext = context; } public final Context getContext() { return mContext; } /** * @param controller * @return */ public CommandGroup onConnect(ControllerInfo controller) { if (Process.myUid() == controller.getUid()) { CommandGroup commands = new CommandGroup(mContext); commands.addAllPredefinedCommands(); return commands; } return null; } /** * Called when enclosing service is created. */ public void onServiceCreated(MediaSessionService2 service) { } /** * Called when enclosing service is destroyed. */ public void onServiceDestroyed() { } } @GuardedBy("TestServiceRegistry.class") Loading @@ -42,9 +82,7 @@ public class TestServiceRegistry { @GuardedBy("TestServiceRegistry.class") private SyncHandler mHandler; @GuardedBy("TestServiceRegistry.class") private ControllerInfo mOnConnectControllerInfo; @GuardedBy("TestServiceRegistry.class") private ServiceInstanceChangedCallback mCallback; private SessionCallbackProxy mCallbackProxy; public static TestServiceRegistry getInstance() { synchronized (TestServiceRegistry.class) { Loading @@ -61,28 +99,33 @@ public class TestServiceRegistry { } } public void setServiceInstanceChangedCallback(ServiceInstanceChangedCallback callback) { public Handler getHandler() { synchronized (TestServiceRegistry.class) { mCallback = callback; return mHandler; } } public Handler getHandler() { public void setSessionCallbackProxy(SessionCallbackProxy callbackProxy) { synchronized (TestServiceRegistry.class) { return mHandler; mCallbackProxy = callbackProxy; } } public SessionCallbackProxy getSessionCallbackProxy() { synchronized (TestServiceRegistry.class) { return mCallbackProxy; } } public void setServiceInstance(MediaSessionService2 service, ControllerInfo controller) { public void setServiceInstance(MediaSessionService2 service) { synchronized (TestServiceRegistry.class) { if (mService != null) { fail("Previous service instance is still running. Clean up manually to ensure" + " previoulsy running service doesn't break current test"); } mService = service; mOnConnectControllerInfo = controller; if (mCallback != null) { mCallback.OnServiceInstanceChanged(service); if (mCallbackProxy != null) { mCallbackProxy.onServiceCreated(service); } } } Loading @@ -93,28 +136,11 @@ public class TestServiceRegistry { } } public ControllerInfo getOnConnectControllerInfo() { synchronized (TestServiceRegistry.class) { return mOnConnectControllerInfo; } } public void cleanUp() { synchronized (TestServiceRegistry.class) { final ServiceInstanceChangedCallback callback = mCallback; final SessionCallbackProxy callbackProxy = mCallbackProxy; if (mService != null) { try { if (mHandler.getLooper() == Looper.myLooper()) { mService.getSession().close(); } else { mHandler.postAndSync(() -> { mService.getSession().close(); }); } } catch (InterruptedException e) { // No-op. Service containing session will die, but shouldn't be a huge issue. } // stopSelf() would not kill service while the binder connection established by // bindService() exists, and close() above will do the job instead. // So stopSelf() isn't really needed, but just for sure. Loading @@ -124,11 +150,10 @@ public class TestServiceRegistry { if (mHandler != null) { mHandler.removeCallbacksAndMessages(null); } mCallback = null; mOnConnectControllerInfo = null; mCallbackProxy = null; if (callback != null) { callback.OnServiceInstanceChanged(null); if (callbackProxy != null) { callbackProxy.onServiceDestroyed(); } } } Loading