Merge "Make MediaRouter2#getSelectedRoute() non null"
diff --git a/media/java/android/media/IMediaRouterService.aidl b/media/java/android/media/IMediaRouterService.aidl
index ced8615..81a7ee2 100644
--- a/media/java/android/media/IMediaRouterService.aidl
+++ b/media/java/android/media/IMediaRouterService.aidl
@@ -43,6 +43,7 @@
     void setControlCategories(IMediaRouterClient client, in List<String> categories);
 
     // Methods for media router 2
+    List<MediaRoute2Info> 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 74d26f0..94ac77a 100644
--- a/media/java/android/media/MediaRouter2.java
+++ b/media/java/android/media/MediaRouter2.java
@@ -131,6 +131,25 @@
         mPackageName = mContext.getPackageName();
         //TODO: read control categories from the manifest
         mHandler = new Handler(Looper.getMainLooper());
+
+        List<MediaRoute2Info> 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 @@
     }
 
     void addRoutesOnHandler(List<MediaRoute2Info> 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<MediaRoute2Info> 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 0000000..2c60d6b
--- /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 7820cd7..2cf920d 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 @@
         mContext = context;
     }
 
+    @NonNull
+    public List<MediaRoute2Info> getSystemRoutes() {
+        final int uid = Binder.getCallingUid();
+        final int userId = UserHandle.getUserId(uid);
+
+        Collection<MediaRoute2Info> 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 ecc1aba..9336af4 100644
--- a/services/core/java/com/android/server/media/MediaRouterService.java
+++ b/services/core/java/com/android/server/media/MediaRouterService.java
@@ -443,6 +443,12 @@
 
     // Binder call
     @Override
+    public List<MediaRoute2Info> getSystemRoutes() {
+        return mService2.getSystemRoutes();
+    }
+
+    // Binder call
+    @Override
     public void registerClient2(IMediaRouter2Client client, String packageName) {
         final int uid = Binder.getCallingUid();
         if (!validatePackageName(uid, packageName)) {
diff --git a/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java b/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java
index 620775e..4f64177 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 @@
     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 @@
 
         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());
     }
 }