From 5736a614ecaa19c608b0ee0b941bbd02029baa09 Mon Sep 17 00:00:00 2001 From: Hyundo Moon Date: Tue, 19 Nov 2019 15:08:32 +0900 Subject: [PATCH] Make MediaRouter2#getSelectedRoute() non null In the constructor of MediaRouter2, it gets system routes from MediaRouterService. Test: atest mediaroutertest:MediaRouter2Test Change-Id: I26512343faefe11b353734184f0bbae566025b4b --- .../android/media/IMediaRouterService.aidl | 1 + media/java/android/media/MediaRouter2.java | 23 ++++++++ .../mediaroutertest/MediaRouter2Test.java | 53 +++++++++++++++++++ .../server/media/MediaRouter2ServiceImpl.java | 18 +++++++ .../server/media/MediaRouterService.java | 6 +++ .../media/SystemMediaRoute2Provider.java | 16 ++++-- 6 files changed, 113 insertions(+), 4 deletions(-) create mode 100644 media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouter2Test.java diff --git a/media/java/android/media/IMediaRouterService.aidl b/media/java/android/media/IMediaRouterService.aidl index ced8615a3ee6e..81a7ee28c425a 100644 --- a/media/java/android/media/IMediaRouterService.aidl +++ b/media/java/android/media/IMediaRouterService.aidl @@ -43,6 +43,7 @@ interface IMediaRouterService { void setControlCategories(IMediaRouterClient client, in List categories); // Methods for media router 2 + List getSystemRoutes(); void registerClient2(IMediaRouter2Client client, String packageName); void unregisterClient2(IMediaRouter2Client client); void sendControlRequest(IMediaRouter2Client client, in MediaRoute2Info route, in Intent request); diff --git a/media/java/android/media/MediaRouter2.java b/media/java/android/media/MediaRouter2.java index 74d26f0305297..94ac77af3ac35 100644 --- a/media/java/android/media/MediaRouter2.java +++ b/media/java/android/media/MediaRouter2.java @@ -131,6 +131,25 @@ public class MediaRouter2 { mPackageName = mContext.getPackageName(); //TODO: read control categories from the manifest mHandler = new Handler(Looper.getMainLooper()); + + List currentSystemRoutes = null; + try { + currentSystemRoutes = mMediaRouterService.getSystemRoutes(); + } catch (RemoteException ex) { + Log.e(TAG, "Unable to get current currentSystemRoutes", ex); + } + + if (currentSystemRoutes == null || currentSystemRoutes.isEmpty()) { + throw new RuntimeException("Null or empty currentSystemRoutes. Something is wrong."); + } + + for (MediaRoute2Info route : currentSystemRoutes) { + mRoutes.put(route.getId(), route); + } + // The first route is the currently selected system route. + // For example, if there are two system routes (BT and device speaker), + // BT will be the first route in the list. + mSelectedRoute = currentSystemRoutes.get(0); } /** @@ -409,6 +428,10 @@ public class MediaRouter2 { } void addRoutesOnHandler(List routes) { + // TODO: When onRoutesAdded is first called, + // 1) clear mRoutes before adding the routes + // 2) Call onRouteSelected(system_route, reason_fallback) if previously selected route + // does not exist anymore. => We may need 'boolean MediaRoute2Info#isSystemRoute()'. List addedRoutes = new ArrayList<>(); for (MediaRoute2Info route : routes) { mRoutes.put(route.getUniqueId(), route); diff --git a/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouter2Test.java b/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouter2Test.java new file mode 100644 index 0000000000000..2c60d6b3dec72 --- /dev/null +++ b/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouter2Test.java @@ -0,0 +1,53 @@ +/* + * Copyright 2019 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 com.android.mediaroutertest; + +import static org.junit.Assert.assertNotNull; + +import android.content.Context; +import android.media.MediaRoute2Info; +import android.media.MediaRouter2; +import android.support.test.InstrumentationRegistry; +import android.support.test.filters.SmallTest; +import android.support.test.runner.AndroidJUnit4; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(AndroidJUnit4.class) +@SmallTest +public class MediaRouter2Test { + Context mContext; + + @Before + public void setUp() throws Exception { + mContext = InstrumentationRegistry.getTargetContext(); + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testGetSelectedRoute_afterCreation() throws Exception { + MediaRouter2 router = MediaRouter2.getInstance(mContext); + MediaRoute2Info initiallySelectedRoute = router.getSelectedRoute(); + assertNotNull(initiallySelectedRoute); + } +} diff --git a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java index 7820cd705193f..2cf920d1aba45 100644 --- a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java +++ b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java @@ -83,6 +83,24 @@ class MediaRouter2ServiceImpl { mContext = context; } + @NonNull + public List getSystemRoutes() { + final int uid = Binder.getCallingUid(); + final int userId = UserHandle.getUserId(uid); + + Collection systemRoutes; + synchronized (mLock) { + UserRecord userRecord = mUserRecords.get(userId); + if (userRecord == null) { + userRecord = new UserRecord(userId); + mUserRecords.put(userId, userRecord); + initializeUserLocked(userRecord); + } + systemRoutes = userRecord.mHandler.mSystemProvider.getProviderInfo().getRoutes(); + } + return new ArrayList<>(systemRoutes); + } + public void registerClient(@NonNull IMediaRouter2Client client, @NonNull String packageName) { Objects.requireNonNull(client, "client must not be null"); diff --git a/services/core/java/com/android/server/media/MediaRouterService.java b/services/core/java/com/android/server/media/MediaRouterService.java index ecc1abaa2cdfe..9336af427452e 100644 --- a/services/core/java/com/android/server/media/MediaRouterService.java +++ b/services/core/java/com/android/server/media/MediaRouterService.java @@ -441,6 +441,12 @@ public final class MediaRouterService extends IMediaRouterService.Stub } } + // Binder call + @Override + public List getSystemRoutes() { + return mService2.getSystemRoutes(); + } + // Binder call @Override public void registerClient2(IMediaRouter2Client client, String packageName) { diff --git a/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java b/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java index 620775e4aabaa..4f64177ad1350 100644 --- a/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java +++ b/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java @@ -42,8 +42,8 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { private static final String TAG = "MR2SystemProvider"; private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); - private static final String DEFAULT_ROUTE_ID = "DEFAULT_ROUTE"; - private static final String BLUETOOTH_ROUTE_ID = "BLUETOOTH_ROUTE"; + static final String DEFAULT_ROUTE_ID = "DEFAULT_ROUTE"; + static final String BLUETOOTH_ROUTE_ID = "BLUETOOTH_ROUTE"; // TODO: Move these to a proper place public static final String CATEGORY_LIVE_AUDIO = "android.media.intent.category.LIVE_AUDIO"; @@ -191,12 +191,20 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { publishRoutes(); } + + /** + * The first route should be the currently selected system route. + * For example, if there are two system routes (BT and device speaker), + * BT will be the first route in the list. + * + * TODO: Support multiple BT devices + */ void publishRoutes() { - MediaRoute2ProviderInfo.Builder builder = new MediaRoute2ProviderInfo.Builder() - .addRoute(mDefaultRoute); + MediaRoute2ProviderInfo.Builder builder = new MediaRoute2ProviderInfo.Builder(); if (mBluetoothA2dpRoute != null) { builder.addRoute(mBluetoothA2dpRoute); } + builder.addRoute(mDefaultRoute); setAndNotifyProviderInfo(builder.build()); } }