Plumbing for HdmiTvClient and HdmiControlService

Added a few more methods in HdmiTvClient to use the API provided
by HdmiControlService

Change-Id: Ib506699b9661b99cefc837b96ac64347a4e9420c
diff --git a/core/java/android/hardware/hdmi/HdmiClient.java b/core/java/android/hardware/hdmi/HdmiClient.java
index c43e21a..5d26a57 100644
--- a/core/java/android/hardware/hdmi/HdmiClient.java
+++ b/core/java/android/hardware/hdmi/HdmiClient.java
@@ -1,5 +1,6 @@
 package android.hardware.hdmi;
 
+import android.annotation.NonNull;
 import android.annotation.SystemApi;
 import android.hardware.hdmi.HdmiControlManager.VendorCommandListener;
 import android.hardware.hdmi.IHdmiVendorCommandListener;
@@ -25,6 +26,21 @@
     }
 
     /**
+     * Returns the active source information.
+     *
+     * @return {@link HdmiCecDeviceInfo} object that describes the active source
+     *         or active routing path
+     */
+    public HdmiCecDeviceInfo getActiveSource() {
+        try {
+            return mService.getActiveSource();
+        } catch (RemoteException e) {
+            Log.e(TAG, "getActiveSource threw exception ", e);
+        }
+        return null;
+    }
+
+    /**
      * Send a key event to other logical device.
      *
      * @param keyCode key code to send. Defined in {@link android.view.KeyEvent}.
@@ -60,7 +76,10 @@
      *
      * @param listener listener object
      */
-    public void addVendorCommandListener(VendorCommandListener listener) {
+    public void addVendorCommandListener(@NonNull VendorCommandListener listener) {
+        if (listener == null) {
+            throw new IllegalArgumentException("listener cannot be null");
+        }
         try {
             mService.addVendorCommandListener(getListenerWrapper(listener), getDeviceType());
         } catch (RemoteException e) {
diff --git a/core/java/android/hardware/hdmi/HdmiControlManager.java b/core/java/android/hardware/hdmi/HdmiControlManager.java
index a4a3ac3..e7bd3e4 100644
--- a/core/java/android/hardware/hdmi/HdmiControlManager.java
+++ b/core/java/android/hardware/hdmi/HdmiControlManager.java
@@ -245,7 +245,30 @@
     }
 
     /**
-     * Gets an object that represents a HDMI-CEC logical device of type playback on the system.
+     * Gets an object that represents an HDMI-CEC logical device of a specified type.
+     *
+     * @param type CEC device type
+     * @return {@link HdmiClient} instance. {@code null} on failure.
+     * @see {@link HdmiCecDeviceInfo#DEVICE_PLAYBACK}
+     * @see {@link HdmiCecDeviceInfo#DEVICE_TV}
+     */
+    @Nullable
+    public HdmiClient getClient(int type) {
+        if (mService == null) {
+            return null;
+        }
+        switch (type) {
+            case HdmiCecDeviceInfo.DEVICE_TV:
+                return mHasTvDevice ? new HdmiTvClient(mService) : null;
+            case HdmiCecDeviceInfo.DEVICE_PLAYBACK:
+                return mHasPlaybackDevice ? new HdmiPlaybackClient(mService) : null;
+            default:
+                return null;
+        }
+    }
+
+    /**
+     * Gets an object that represents an HDMI-CEC logical device of type playback on the system.
      *
      * <p>Used to send HDMI control messages to other devices like TV or audio amplifier through
      * HDMI bus. It is also possible to communicate with other logical devices hosted in the same
@@ -255,14 +278,11 @@
      */
     @Nullable
     public HdmiPlaybackClient getPlaybackClient() {
-        if (mService == null || !mHasPlaybackDevice) {
-            return null;
-        }
-        return new HdmiPlaybackClient(mService);
+        return (HdmiPlaybackClient) getClient(HdmiCecDeviceInfo.DEVICE_PLAYBACK);
     }
 
     /**
-     * Gets an object that represents a HDMI-CEC logical device of type TV on the system.
+     * Gets an object that represents an HDMI-CEC logical device of type TV on the system.
      *
      * <p>Used to send HDMI control messages to other devices and manage them through
      * HDMI bus. It is also possible to communicate with other logical devices hosted in the same
@@ -272,10 +292,7 @@
      */
     @Nullable
     public HdmiTvClient getTvClient() {
-        if (mService == null || !mHasTvDevice) {
-                return null;
-        }
-        return new HdmiTvClient(mService);
+        return (HdmiTvClient) getClient(HdmiCecDeviceInfo.DEVICE_TV);
     }
 
     /**
diff --git a/core/java/android/hardware/hdmi/HdmiTvClient.java b/core/java/android/hardware/hdmi/HdmiTvClient.java
index 2735108..077a17e 100644
--- a/core/java/android/hardware/hdmi/HdmiTvClient.java
+++ b/core/java/android/hardware/hdmi/HdmiTvClient.java
@@ -114,15 +114,14 @@
     /**
      * Select a CEC logical device to be a new active source.
      *
-     * @param logicalAddress
-     * @param callback
+     * @param logicalAddress logical address of the device to select
+     * @param callback callback to get the result with
+     * @throws {@link IllegalArgumentException} if the {@code callback} is null
      */
     public void deviceSelect(int logicalAddress, @NonNull SelectCallback callback) {
         if (callback == null) {
             throw new IllegalArgumentException("callback must not be null.");
         }
-
-        // TODO: Replace SelectCallback with PartialResult.
         try {
             mService.deviceSelect(logicalAddress, getCallbackWrapper(callback));
         } catch (RemoteException e) {
@@ -131,6 +130,24 @@
     }
 
     /**
+     * Select a HDMI port to be a new route path.
+     *
+     * @param portId HDMI port to select
+     * @param callback callback to get the result with
+     * @throws {@link IllegalArgumentException} if the {@code callback} is null
+     */
+    public void portSelect(int portId, @NonNull SelectCallback callback) {
+        if (callback == null) {
+            throw new IllegalArgumentException("Callback must not be null");
+        }
+        try {
+            mService.portSelect(portId, getCallbackWrapper(callback));
+        } catch (RemoteException e) {
+            Log.e(TAG, "failed to select port: ", e);
+        }
+    }
+
+    /**
      * Set system audio volume
      *
      * @param oldIndex current volume index