Fix the API for ServiceFactoryBinder to be type safe.

R=ppi@chromium.org

Review URL: https://codereview.chromium.org/1169543002
diff --git a/examples/java_android/echo/src/org/chromium/examples/java_echo/EchoClientApp.java b/examples/java_android/echo/src/org/chromium/examples/java_echo/EchoClientApp.java
index 31dca02..ff8806f 100644
--- a/examples/java_android/echo/src/org/chromium/examples/java_echo/EchoClientApp.java
+++ b/examples/java_android/echo/src/org/chromium/examples/java_echo/EchoClientApp.java
@@ -88,8 +88,8 @@
     @Override
     public void quit() {}
 
-    public static void mojoMain(
-            Context context, Core core, MessagePipeHandle applicationRequestHandle) {
+    public static void mojoMain(@SuppressWarnings("unused") Context context, Core core,
+            MessagePipeHandle applicationRequestHandle) {
         ApplicationRunner.run(new EchoClientApp(core), core, applicationRequestHandle);
     }
 }
diff --git a/examples/java_android/echo/src/org/chromium/examples/java_echo/EchoServerApp.java b/examples/java_android/echo/src/org/chromium/examples/java_echo/EchoServerApp.java
index c4057d5..9c2ac8e 100644
--- a/examples/java_android/echo/src/org/chromium/examples/java_echo/EchoServerApp.java
+++ b/examples/java_android/echo/src/org/chromium/examples/java_echo/EchoServerApp.java
@@ -11,6 +11,7 @@
 import org.chromium.mojo.application.ApplicationDelegate;
 import org.chromium.mojo.application.ApplicationRunner;
 import org.chromium.mojo.application.ServiceFactoryBinder;
+import org.chromium.mojo.bindings.InterfaceRequest;
 import org.chromium.mojo.examples.echo.Echo;
 import org.chromium.mojo.system.Core;
 import org.chromium.mojo.system.MessagePipeHandle;
@@ -21,8 +22,8 @@
  * This is an example Java Mojo Application that receives a message from an echo client and then
  * responds with that same message, prefixed by the string "Java EchoServer: ". The user does not
  * directly request that this application be loaded. Instead the Mojo shell will load this
- * application when the echo client requests that an echo server be loaded. See the README.md
- * file for usage.
+ * application when the echo client requests that an echo server be loaded. See the README.md file
+ * for usage.
  */
 class EchoServerApp implements ApplicationDelegate {
     private static final String TAG = "JavaEchoServer";
@@ -55,8 +56,8 @@
         connection.addService(new ServiceFactoryBinder<Echo>() {
 
             @Override
-            public void bindNewInstanceToMessagePipe(MessagePipeHandle pipe) {
-                Echo.MANAGER.bind(new EchoImpl(), pipe);
+            public void bind(InterfaceRequest<Echo> request) {
+                Echo.MANAGER.bind(new EchoImpl(), request);
             }
 
             @Override
@@ -73,8 +74,8 @@
     @Override
     public void quit() {}
 
-    public static void mojoMain(
-            Context context, Core core, MessagePipeHandle applicationRequestHandle) {
+    public static void mojoMain(@SuppressWarnings("unused") Context context, Core core,
+            MessagePipeHandle applicationRequestHandle) {
         ApplicationRunner.run(new EchoServerApp(), core, applicationRequestHandle);
     }
 }
diff --git a/examples/java_android/example_service/src/org/chromium/examples/android/ExampleServiceApp.java b/examples/java_android/example_service/src/org/chromium/examples/android/ExampleServiceApp.java
index d476d8d..7e18b57 100644
--- a/examples/java_android/example_service/src/org/chromium/examples/android/ExampleServiceApp.java
+++ b/examples/java_android/example_service/src/org/chromium/examples/android/ExampleServiceApp.java
@@ -11,6 +11,7 @@
 import org.chromium.mojo.application.ApplicationDelegate;
 import org.chromium.mojo.application.ApplicationRunner;
 import org.chromium.mojo.application.ServiceFactoryBinder;
+import org.chromium.mojo.bindings.InterfaceRequest;
 import org.chromium.mojo.system.Core;
 import org.chromium.mojo.system.MessagePipeHandle;
 import org.chromium.mojo.system.MojoException;
@@ -45,8 +46,8 @@
         Log.i(TAG, "ExampleServiceApp.ConfigureIncomingConnection() called.");
         connection.addService(new ServiceFactoryBinder<ExampleService>() {
             @Override
-            public void bindNewInstanceToMessagePipe(MessagePipeHandle pipe) {
-                ExampleService.MANAGER.bind(new ExampleServiceImpl(), pipe);
+            public void bind(InterfaceRequest<ExampleService> request) {
+                ExampleService.MANAGER.bind(new ExampleServiceImpl(), request);
             }
 
             @Override
diff --git a/mojo/public/java/application/src/org/chromium/mojo/application/ApplicationConnection.java b/mojo/public/java/application/src/org/chromium/mojo/application/ApplicationConnection.java
index 6b0e548..9ccf8d1 100644
--- a/mojo/public/java/application/src/org/chromium/mojo/application/ApplicationConnection.java
+++ b/mojo/public/java/application/src/org/chromium/mojo/application/ApplicationConnection.java
@@ -5,6 +5,7 @@
 package org.chromium.mojo.application;
 
 import org.chromium.mojo.bindings.Interface;
+import org.chromium.mojo.bindings.InterfaceRequest;
 import org.chromium.mojo.system.MessagePipeHandle;
 import org.chromium.mojo.system.MojoException;
 import org.chromium.mojom.mojo.ServiceProvider;
@@ -90,10 +91,12 @@
         mNameToServiceMap.put(binder.getInterfaceName(), binder);
     }
 
+    @SuppressWarnings("unchecked")
     @Override
     public void connectToService(String interfaceName, MessagePipeHandle pipe) {
         if (mNameToServiceMap.containsKey(interfaceName)) {
-            mNameToServiceMap.get(interfaceName).bindNewInstanceToMessagePipe(pipe);
+            mNameToServiceMap.get(interfaceName)
+                    .bind(InterfaceRequest.asInterfaceRequestUnsafe(pipe));
         } else {
             pipe.close();
         }
@@ -104,4 +107,4 @@
 
     @Override
     public void onConnectionError(MojoException e) {}
-}
\ No newline at end of file
+}
diff --git a/mojo/public/java/application/src/org/chromium/mojo/application/ServiceFactoryBinder.java b/mojo/public/java/application/src/org/chromium/mojo/application/ServiceFactoryBinder.java
index 462d74e..0171a38 100644
--- a/mojo/public/java/application/src/org/chromium/mojo/application/ServiceFactoryBinder.java
+++ b/mojo/public/java/application/src/org/chromium/mojo/application/ServiceFactoryBinder.java
@@ -5,7 +5,7 @@
 package org.chromium.mojo.application;
 
 import org.chromium.mojo.bindings.Interface;
-import org.chromium.mojo.system.MessagePipeHandle;
+import org.chromium.mojo.bindings.InterfaceRequest;
 
 /**
  * ServiceFactoryBinder holds the necessary information to bind a service interface to a message
@@ -15,16 +15,14 @@
  */
 public interface ServiceFactoryBinder<T extends Interface> {
     /**
-     * An application implements to bind a service implementation to |pipe|.
+     * Binds an instance of the interface to the given request.
      *
-     * @param pipe A handle to the incoming connection pipe.
+     * @param request The request to bind to.
      */
-    public void bindNewInstanceToMessagePipe(MessagePipeHandle pipe);
+    public void bind(InterfaceRequest<T> request);
 
     /**
-     * Name of the service interface being implemented.
-     *
-     * @return Service interface name.
+     * Returns the name of the service interface being implemented.
      */
     public String getInterfaceName();
 }
diff --git a/mojo/public/java/bindings/src/org/chromium/mojo/bindings/InterfaceRequest.java b/mojo/public/java/bindings/src/org/chromium/mojo/bindings/InterfaceRequest.java
index 87835e0..61899b4 100644
--- a/mojo/public/java/bindings/src/org/chromium/mojo/bindings/InterfaceRequest.java
+++ b/mojo/public/java/bindings/src/org/chromium/mojo/bindings/InterfaceRequest.java
@@ -47,4 +47,12 @@
         mHandle.close();
     }
 
+    /**
+     * Returns an {@link InterfaceRequest} that wraps the given handle. This method is not type safe
+     * and should be avoided unless absolutely necessary.
+     */
+    @SuppressWarnings("rawtypes")
+    public static InterfaceRequest asInterfaceRequestUnsafe(MessagePipeHandle handle) {
+        return new InterfaceRequest(handle);
+    }
 }
diff --git a/services/authentication/src/org/chromium/mojo/authentication/AuthenticationApp.java b/services/authentication/src/org/chromium/mojo/authentication/AuthenticationApp.java
index 3737648..7805807 100644
--- a/services/authentication/src/org/chromium/mojo/authentication/AuthenticationApp.java
+++ b/services/authentication/src/org/chromium/mojo/authentication/AuthenticationApp.java
@@ -10,6 +10,7 @@
 import org.chromium.mojo.application.ApplicationDelegate;
 import org.chromium.mojo.application.ApplicationRunner;
 import org.chromium.mojo.application.ServiceFactoryBinder;
+import org.chromium.mojo.bindings.InterfaceRequest;
 import org.chromium.mojo.system.Core;
 import org.chromium.mojo.system.MessagePipeHandle;
 import org.chromium.mojom.mojo.Shell;
@@ -43,10 +44,10 @@
         connection.addService(new ServiceFactoryBinder<AuthenticationService>() {
 
             @Override
-            public void bindNewInstanceToMessagePipe(MessagePipeHandle pipe) {
+            public void bind(InterfaceRequest<AuthenticationService> request) {
                 AuthenticationService.MANAGER.bind(new AuthenticationServiceImpl(mContext, mCore,
                                                            connection.getRequestorUrl(), mShell),
-                        pipe);
+                        request);
             }
 
             @Override
diff --git a/services/device_info/src/org/chromium/services/device_info/DeviceInfoService.java b/services/device_info/src/org/chromium/services/device_info/DeviceInfoService.java
index d0fe6ef..26c8605 100644
--- a/services/device_info/src/org/chromium/services/device_info/DeviceInfoService.java
+++ b/services/device_info/src/org/chromium/services/device_info/DeviceInfoService.java
@@ -12,6 +12,7 @@
 import org.chromium.mojo.application.ApplicationDelegate;
 import org.chromium.mojo.application.ApplicationRunner;
 import org.chromium.mojo.application.ServiceFactoryBinder;
+import org.chromium.mojo.bindings.InterfaceRequest;
 import org.chromium.mojo.system.Core;
 import org.chromium.mojo.system.MessagePipeHandle;
 import org.chromium.mojo.system.MojoException;
@@ -22,8 +23,6 @@
  * Android Mojo application which implements |DeviceInfo| interface.
  */
 class DeviceInfoService implements ApplicationDelegate, DeviceInfo {
-    private static final String TAG = "DeviceInfoService";
-
     private final Context mContext;
 
     public DeviceInfoService(Context context) {
@@ -74,15 +73,14 @@
     public void initialize(Shell shell, String[] args, String url) {}
 
     /**
-     * @see ApplicationDelegate#configureIncomingConnection(String, ApplicationConnection)
+     * @see ApplicationDelegate#configureIncomingConnection(ApplicationConnection)
      */
     @Override
     public boolean configureIncomingConnection(ApplicationConnection connection) {
-        final DeviceInfo info = this;
         connection.addService(new ServiceFactoryBinder<DeviceInfo>() {
             @Override
-            public void bindNewInstanceToMessagePipe(MessagePipeHandle pipe) {
-                DeviceInfo.MANAGER.bind(info, pipe);
+            public void bind(InterfaceRequest<DeviceInfo> request) {
+                DeviceInfo.MANAGER.bind(DeviceInfoService.this, request);
             }
 
             @Override
diff --git a/services/location/src/org/chromium/services/location/LocationServiceApp.java b/services/location/src/org/chromium/services/location/LocationServiceApp.java
index 685b8fa..f82608f 100644
--- a/services/location/src/org/chromium/services/location/LocationServiceApp.java
+++ b/services/location/src/org/chromium/services/location/LocationServiceApp.java
@@ -16,6 +16,7 @@
 import org.chromium.mojo.application.ApplicationDelegate;
 import org.chromium.mojo.application.ApplicationRunner;
 import org.chromium.mojo.application.ServiceFactoryBinder;
+import org.chromium.mojo.bindings.InterfaceRequest;
 import org.chromium.mojo.system.Core;
 import org.chromium.mojo.system.MessagePipeHandle;
 import org.chromium.mojom.mojo.LocationService;
@@ -104,11 +105,11 @@
     public boolean configureIncomingConnection(ApplicationConnection connection) {
         connection.addService(new ServiceFactoryBinder<LocationService>() {
             @Override
-            public void bindNewInstanceToMessagePipe(MessagePipeHandle pipe) {
+            public void bind(InterfaceRequest<LocationService> request) {
                 LocationService.MANAGER.bind(
                         new LocationServiceImpl(mGoogleApiClient, mLooperThread.getLooper(),
                                 mCore.getCurrentRunLoop()),
-                        pipe);
+                        request);
             }
 
             @Override
diff --git a/services/sensors/src/org/chromium/mojo/sensors/Sensors.java b/services/sensors/src/org/chromium/mojo/sensors/Sensors.java
index f39d6e9..f9e38cd 100644
--- a/services/sensors/src/org/chromium/mojo/sensors/Sensors.java
+++ b/services/sensors/src/org/chromium/mojo/sensors/Sensors.java
@@ -10,6 +10,7 @@
 import org.chromium.mojo.application.ApplicationDelegate;
 import org.chromium.mojo.application.ApplicationRunner;
 import org.chromium.mojo.application.ServiceFactoryBinder;
+import org.chromium.mojo.bindings.InterfaceRequest;
 import org.chromium.mojo.system.Core;
 import org.chromium.mojo.system.MessagePipeHandle;
 import org.chromium.mojom.mojo.Shell;
@@ -38,8 +39,8 @@
     public boolean configureIncomingConnection(ApplicationConnection connection) {
         connection.addService(new ServiceFactoryBinder<SensorService>() {
             @Override
-            public void bindNewInstanceToMessagePipe(MessagePipeHandle pipe) {
-                SensorService.MANAGER.bind(new SensorServiceImpl(mContext), pipe);
+            public void bind(InterfaceRequest<SensorService> request) {
+                SensorService.MANAGER.bind(new SensorServiceImpl(mContext), request);
             }
 
             @Override