Merge "MediaRouter2: Remove sendControlRequest"
diff --git a/media/java/android/media/IMediaRoute2Provider.aidl b/media/java/android/media/IMediaRoute2Provider.aidl
index 0c64564..7097166 100644
--- a/media/java/android/media/IMediaRoute2Provider.aidl
+++ b/media/java/android/media/IMediaRoute2Provider.aidl
@@ -35,7 +35,6 @@
     void deselectRoute(String sessionId, String routeId);
     void transferToRoute(String sessionId, String routeId);
 
-    void notifyControlRequestSent(String id, in Intent request);
     void setRouteVolume(String routeId, int volume);
     void setSessionVolume(String sessionId, int volume);
 }
diff --git a/media/java/android/media/IMediaRouterService.aidl b/media/java/android/media/IMediaRouterService.aidl
index f919dce..8be2884 100644
--- a/media/java/android/media/IMediaRouterService.aidl
+++ b/media/java/android/media/IMediaRouterService.aidl
@@ -49,8 +49,6 @@
     RoutingSessionInfo getSystemSessionInfo();
     void registerClient2(IMediaRouter2Client client, String packageName);
     void unregisterClient2(IMediaRouter2Client client);
-    void sendControlRequest(IMediaRouter2Client client, in MediaRoute2Info route,
-            in Intent request);
     void setRouteVolume2(IMediaRouter2Client client, in MediaRoute2Info route, int volume);
     void setSessionVolume2(IMediaRouter2Client client, String sessionId, int volume);
 
diff --git a/media/java/android/media/MediaRoute2ProviderService.java b/media/java/android/media/MediaRoute2ProviderService.java
index aac195d..7d72b1c 100644
--- a/media/java/android/media/MediaRoute2ProviderService.java
+++ b/media/java/android/media/MediaRoute2ProviderService.java
@@ -115,16 +115,6 @@
     }
 
     /**
-     * Called when sendControlRequest is called on a route of the provider
-     *
-     * @param routeId the id of the target route
-     * @param request the media control request intent
-     * @hide
-     */
-    //TODO: Discuss what to use for request (e.g., Intent? Request class?)
-    public void onControlRequest(@NonNull String routeId, @NonNull Intent request) {}
-
-    /**
      * Called when a volume setting is requested on a route of the provider
      *
      * @param routeId the id of the route
@@ -513,15 +503,6 @@
         }
 
         @Override
-        public void notifyControlRequestSent(String routeId, Intent request) {
-            if (!checkCallerisSystem()) {
-                return;
-            }
-            mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::onControlRequest,
-                    MediaRoute2ProviderService.this, routeId, request));
-        }
-
-        @Override
         public void setRouteVolume(String routeId, int volume) {
             if (!checkCallerisSystem()) {
                 return;
diff --git a/media/java/android/media/MediaRouter2.java b/media/java/android/media/MediaRouter2.java
index 2178393..274169c 100644
--- a/media/java/android/media/MediaRouter2.java
+++ b/media/java/android/media/MediaRouter2.java
@@ -22,7 +22,6 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.Context;
-import android.content.Intent;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Looper;
@@ -412,32 +411,6 @@
     }
 
     /**
-     * Sends a media control request to be performed asynchronously by the route's destination.
-     *
-     * @param route the route that will receive the control request
-     * @param request the media control request
-     * @hide
-     */
-    //TODO: Discuss what to use for request (e.g., Intent? Request class?)
-    //TODO: Provide a way to obtain the result
-    public void sendControlRequest(@NonNull MediaRoute2Info route, @NonNull Intent request) {
-        Objects.requireNonNull(route, "route must not be null");
-        Objects.requireNonNull(request, "request must not be null");
-
-        Client2 client;
-        synchronized (sRouterLock) {
-            client = mClient;
-        }
-        if (client != null) {
-            try {
-                mMediaRouterService.sendControlRequest(client, route, request);
-            } catch (RemoteException ex) {
-                Log.e(TAG, "Unable to send control request.", ex);
-            }
-        }
-    }
-
-    /**
      * Requests a volume change for the route asynchronously.
      * <p>
      * It may have no effect if the route is currently not selected.
diff --git a/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouter2ManagerTest.java b/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouter2ManagerTest.java
index 615dc48..cbaf527 100644
--- a/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouter2ManagerTest.java
+++ b/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouter2ManagerTest.java
@@ -20,7 +20,6 @@
 import static android.media.MediaRoute2Info.PLAYBACK_VOLUME_FIXED;
 import static android.media.MediaRoute2Info.PLAYBACK_VOLUME_VARIABLE;
 
-import static com.android.mediaroutertest.SampleMediaRoute2ProviderService.ACTION_REMOVE_ROUTE;
 import static com.android.mediaroutertest.SampleMediaRoute2ProviderService.FEATURE_SAMPLE;
 import static com.android.mediaroutertest.SampleMediaRoute2ProviderService.FEATURE_SPECIAL;
 import static com.android.mediaroutertest.SampleMediaRoute2ProviderService.ROUTE_ID1;
@@ -29,7 +28,6 @@
 import static com.android.mediaroutertest.SampleMediaRoute2ProviderService.ROUTE_ID_FIXED_VOLUME;
 import static com.android.mediaroutertest.SampleMediaRoute2ProviderService.ROUTE_ID_SPECIAL_FEATURE;
 import static com.android.mediaroutertest.SampleMediaRoute2ProviderService.ROUTE_ID_VARIABLE_VOLUME;
-import static com.android.mediaroutertest.SampleMediaRoute2ProviderService.ROUTE_NAME1;
 import static com.android.mediaroutertest.SampleMediaRoute2ProviderService.ROUTE_NAME2;
 import static com.android.mediaroutertest.SampleMediaRoute2ProviderService.VOLUME_MAX;
 
@@ -38,7 +36,6 @@
 import static org.junit.Assert.assertTrue;
 
 import android.content.Context;
-import android.content.Intent;
 import android.media.MediaRoute2Info;
 import android.media.MediaRouter2;
 import android.media.MediaRouter2.RouteCallback;
@@ -116,34 +113,18 @@
         clearCallbacks();
     }
 
-    /**
-     * Tests if routes are added correctly when a new callback is registered.
-     */
     @Test
-    public void testOnRoutesAdded() throws Exception {
-        CountDownLatch latch = new CountDownLatch(1);
-        addManagerCallback(new MediaRouter2Manager.Callback() {
-            @Override
-            public void onRoutesAdded(List<MediaRoute2Info> routes) {
-                assertTrue(routes.size() > 0);
-                for (MediaRoute2Info route : routes) {
-                    if (route.getOriginalId().equals(ROUTE_ID1)
-                            && route.getName().equals(ROUTE_NAME1)) {
-                        latch.countDown();
-                    }
-                }
-            }
-        });
+    public void testOnRoutesRemovedAndAdded() throws Exception {
+        RouteCallback routeCallback = new RouteCallback();
+        mRouteCallbacks.add(routeCallback);
+        mRouter2.registerRouteCallback(mExecutor, routeCallback,
+                new RouteDiscoveryPreference.Builder(FEATURES_ALL, true).build());
 
-        assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-    }
-
-    @Test
-    public void testOnRoutesRemoved() throws Exception {
-        CountDownLatch latch = new CountDownLatch(1);
         Map<String, MediaRoute2Info> routes = waitAndGetRoutesWithManager(FEATURES_ALL);
 
-        addRouterCallback(new RouteCallback());
+        CountDownLatch removedLatch = new CountDownLatch(1);
+        CountDownLatch addedLatch = new CountDownLatch(1);
+
         addManagerCallback(new MediaRouter2Manager.Callback() {
             @Override
             public void onRoutesRemoved(List<MediaRoute2Info> routes) {
@@ -151,16 +132,39 @@
                 for (MediaRoute2Info route : routes) {
                     if (route.getOriginalId().equals(ROUTE_ID2)
                             && route.getName().equals(ROUTE_NAME2)) {
-                        latch.countDown();
+                        removedLatch.countDown();
+                    }
+                }
+            }
+            @Override
+            public void onRoutesAdded(List<MediaRoute2Info> routes) {
+                assertTrue(routes.size() > 0);
+                if (removedLatch.getCount() > 0) {
+                    return;
+                }
+                for (MediaRoute2Info route : routes) {
+                    if (route.getOriginalId().equals(ROUTE_ID2)
+                            && route.getName().equals(ROUTE_NAME2)) {
+                        addedLatch.countDown();
                     }
                 }
             }
         });
 
-        //TODO: Figure out a more proper way to test.
-        // (Control requests shouldn't be used in this way.)
-        mRouter2.sendControlRequest(routes.get(ROUTE_ID2), new Intent(ACTION_REMOVE_ROUTE));
-        assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+        MediaRoute2Info routeToRemove = routes.get(ROUTE_ID2);
+
+        try {
+            SampleMediaRoute2ProviderService sInstance =
+                    SampleMediaRoute2ProviderService.getInstance();
+            assertNotNull(sInstance);
+            sInstance.removeRoute(ROUTE_ID2);
+            assertTrue(removedLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+
+            sInstance.addRoute(routeToRemove);
+            assertTrue(addedLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+        } finally {
+            mRouter2.unregisterRouteCallback(routeCallback);
+        }
     }
 
     /**
diff --git a/media/tests/MediaRouter/src/com/android/mediaroutertest/SampleMediaRoute2ProviderService.java b/media/tests/MediaRouter/src/com/android/mediaroutertest/SampleMediaRoute2ProviderService.java
index f1dcf3d..3faefdb 100644
--- a/media/tests/MediaRouter/src/com/android/mediaroutertest/SampleMediaRoute2ProviderService.java
+++ b/media/tests/MediaRouter/src/com/android/mediaroutertest/SampleMediaRoute2ProviderService.java
@@ -20,6 +20,7 @@
 import static android.media.MediaRoute2Info.DEVICE_TYPE_REMOTE_TV;
 import static android.media.MediaRoute2Info.PLAYBACK_VOLUME_VARIABLE;
 
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.Intent;
 import android.media.MediaRoute2Info;
@@ -31,9 +32,13 @@
 
 import java.util.HashMap;
 import java.util.Map;
+import java.util.Objects;
+
+import javax.annotation.concurrent.GuardedBy;
 
 public class SampleMediaRoute2ProviderService extends MediaRoute2ProviderService {
     private static final String TAG = "SampleMR2ProviderSvc";
+    private static final Object sLock = new Object();
 
     public static final String ROUTE_ID1 = "route_id1";
     public static final String ROUTE_NAME1 = "Sample Route 1";
@@ -59,9 +64,6 @@
     public static final String ROUTE_ID_VARIABLE_VOLUME = "route_variable_volume";
     public static final String ROUTE_NAME_VARIABLE_VOLUME = "Variable Volume Route";
 
-    public static final String ACTION_REMOVE_ROUTE =
-            "com.android.mediarouteprovider.action_remove_route";
-
     public static final String FEATURE_SAMPLE =
             "com.android.mediarouteprovider.FEATURE_SAMPLE";
     public static final String FEATURE_SPECIAL =
@@ -71,6 +73,9 @@
     Map<String, String> mRouteIdToSessionId = new HashMap<>();
     private int mNextSessionId = 1000;
 
+    @GuardedBy("sLock")
+    private static SampleMediaRoute2ProviderService sInstance;
+
     private void initializeRoutes() {
         MediaRoute2Info route1 = new MediaRoute2Info.Builder(ROUTE_ID1, ROUTE_NAME1)
                 .addFeature(FEATURE_SAMPLE)
@@ -92,6 +97,7 @@
                 ROUTE_ID5_TO_TRANSFER_TO, ROUTE_NAME5)
                 .addFeature(FEATURE_SAMPLE)
                 .build();
+
         MediaRoute2Info routeSpecial =
                 new MediaRoute2Info.Builder(ROUTE_ID_SPECIAL_FEATURE, ROUTE_NAME_SPECIAL_FEATURE)
                         .addFeature(FEATURE_SAMPLE)
@@ -114,36 +120,65 @@
         mRoutes.put(route3.getId(), route3);
         mRoutes.put(route4.getId(), route4);
         mRoutes.put(route5.getId(), route5);
+
         mRoutes.put(routeSpecial.getId(), routeSpecial);
         mRoutes.put(fixedVolumeRoute.getId(), fixedVolumeRoute);
         mRoutes.put(variableVolumeRoute.getId(), variableVolumeRoute);
     }
 
+    public static SampleMediaRoute2ProviderService getInstance() {
+        synchronized (sLock) {
+            return sInstance;
+        }
+    }
+
+    /**
+     * Adds a route and publishes it. It could replace a route in the provider if
+     * they have the same route id.
+     */
+    public void addRoute(@NonNull MediaRoute2Info route) {
+        Objects.requireNonNull(route, "route must not be null");
+        mRoutes.put(route.getOriginalId(), route);
+        publishRoutes();
+    }
+
+    /**
+     * Removes a route and publishes it.
+     */
+    public void removeRoute(@NonNull String routeId) {
+        Objects.requireNonNull(routeId, "routeId must not be null");
+        MediaRoute2Info route = mRoutes.get(routeId);
+        if (route != null) {
+            mRoutes.remove(routeId);
+            publishRoutes();
+        }
+    }
+
     @Override
     public void onCreate() {
+        synchronized (sLock) {
+            sInstance = this;
+        }
         initializeRoutes();
     }
 
     @Override
+    public void onDestroy() {
+        super.onDestroy();
+        synchronized (sLock) {
+            if (sInstance == this) {
+                sInstance = null;
+            }
+        }
+    }
+
+    @Override
     public IBinder onBind(Intent intent) {
         publishRoutes();
         return super.onBind(intent);
     }
 
     @Override
-    public void onControlRequest(String routeId, Intent request) {
-        String action = request.getAction();
-        if (ACTION_REMOVE_ROUTE.equals(action)) {
-            MediaRoute2Info route = mRoutes.get(routeId);
-            if (route != null) {
-                mRoutes.remove(routeId);
-                publishRoutes();
-                mRoutes.put(routeId, route);
-            }
-        }
-    }
-
-    @Override
     public void onSetRouteVolume(String routeId, int volume) {
         MediaRoute2Info route = mRoutes.get(routeId);
         if (route == null) {
diff --git a/services/core/java/com/android/server/media/MediaRoute2Provider.java b/services/core/java/com/android/server/media/MediaRoute2Provider.java
index 3de5cf1..477122c 100644
--- a/services/core/java/com/android/server/media/MediaRoute2Provider.java
+++ b/services/core/java/com/android/server/media/MediaRoute2Provider.java
@@ -19,7 +19,6 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.ComponentName;
-import android.content.Intent;
 import android.media.MediaRoute2ProviderInfo;
 import android.media.RouteDiscoveryPreference;
 import android.media.RoutingSessionInfo;
@@ -61,7 +60,6 @@
     public abstract void deselectRoute(String sessionId, String routeId);
     public abstract void transferToRoute(String sessionId, String routeId);
 
-    public abstract void sendControlRequest(String routeId, Intent request);
     public abstract void setRouteVolume(String routeId, int volume);
     public abstract void setSessionVolume(String sessionId, int volume);
 
diff --git a/services/core/java/com/android/server/media/MediaRoute2ProviderProxy.java b/services/core/java/com/android/server/media/MediaRoute2ProviderProxy.java
index c1ea697..252855e 100644
--- a/services/core/java/com/android/server/media/MediaRoute2ProviderProxy.java
+++ b/services/core/java/com/android/server/media/MediaRoute2ProviderProxy.java
@@ -123,14 +123,6 @@
     }
 
     @Override
-    public void sendControlRequest(String routeId, Intent request) {
-        if (mConnectionReady) {
-            mActiveConnection.sendControlRequest(routeId, request);
-            updateBinding();
-        }
-    }
-
-    @Override
     public void setRouteVolume(String routeId, int volume) {
         if (mConnectionReady) {
             mActiveConnection.setRouteVolume(routeId, volume);
@@ -508,14 +500,6 @@
             }
         }
 
-        public void sendControlRequest(String routeId, Intent request) {
-            try {
-                mProvider.notifyControlRequestSent(routeId, request);
-            } catch (RemoteException ex) {
-                Slog.e(TAG, "sendControlRequest: Failed to deliver request.", ex);
-            }
-        }
-
         public void setRouteVolume(String routeId, int volume) {
             try {
                 mProvider.setRouteVolume(routeId, volume);
diff --git a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
index 2096531..c5320b6 100644
--- a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
+++ b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
@@ -25,7 +25,6 @@
 import android.annotation.Nullable;
 import android.app.ActivityManager;
 import android.content.Context;
-import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.media.IMediaRouter2Client;
 import android.media.IMediaRouter2Manager;
@@ -288,22 +287,6 @@
         }
     }
 
-    public void sendControlRequest(@NonNull IMediaRouter2Client client,
-            @NonNull MediaRoute2Info route, @NonNull Intent request) {
-        Objects.requireNonNull(client, "client must not be null");
-        Objects.requireNonNull(route, "route must not be null");
-        Objects.requireNonNull(request, "request must not be null");
-
-        final long token = Binder.clearCallingIdentity();
-        try {
-            synchronized (mLock) {
-                sendControlRequestLocked(client, route, request);
-            }
-        } finally {
-            Binder.restoreCallingIdentity(token);
-        }
-    }
-
     public void setDiscoveryRequest2(@NonNull IMediaRouter2Client client,
             @NonNull RouteDiscoveryPreference preference) {
         Objects.requireNonNull(client, "client must not be null");
@@ -605,18 +588,6 @@
         }
     }
 
-    private void sendControlRequestLocked(IMediaRouter2Client client, MediaRoute2Info route,
-            Intent request) {
-        final IBinder binder = client.asBinder();
-        Client2Record clientRecord = mAllClientRecords.get(binder);
-
-        if (clientRecord != null) {
-            clientRecord.mUserRecord.mHandler.sendMessage(
-                    obtainMessage(UserHandler::sendControlRequest,
-                            clientRecord.mUserRecord.mHandler, route, request));
-        }
-    }
-
     private void setRouteVolumeLocked(IMediaRouter2Client client, MediaRoute2Info route,
             int volume) {
         final IBinder binder = client.asBinder();
@@ -1446,13 +1417,6 @@
             }
         }
 
-        private void sendControlRequest(MediaRoute2Info route, Intent request) {
-            final MediaRoute2Provider provider = findProvider(route.getProviderId());
-            if (provider != null) {
-                provider.sendControlRequest(route.getOriginalId(), request);
-            }
-        }
-
         private void setRouteVolume(MediaRoute2Info route, int volume) {
             final MediaRoute2Provider provider = findProvider(route.getProviderId());
             if (provider != null) {
diff --git a/services/core/java/com/android/server/media/MediaRouterService.java b/services/core/java/com/android/server/media/MediaRouterService.java
index b38e47a..83cc894 100644
--- a/services/core/java/com/android/server/media/MediaRouterService.java
+++ b/services/core/java/com/android/server/media/MediaRouterService.java
@@ -498,13 +498,6 @@
 
     // Binder call
     @Override
-    public void sendControlRequest(IMediaRouter2Client client, MediaRoute2Info route,
-            Intent request) {
-        mService2.sendControlRequest(client, route, request);
-    }
-
-    // Binder call
-    @Override
     public void registerManager(IMediaRouter2Manager manager, 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 7f7a663..777a8fe 100644
--- a/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java
+++ b/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java
@@ -151,11 +151,6 @@
         }
     }
 
-    //TODO: implement method
-    @Override
-    public void sendControlRequest(@NonNull String routeId, @NonNull Intent request) {
-    }
-
     @Override
     public void setRouteVolume(String routeId, int volume) {
         if (!TextUtils.equals(routeId, mSelectedRouteId)) {