TIF: Register IHdmiInputChangeListener to physical input manager

This lets the manager receive the callback from HdmiControlService
when a CEC device requests that it shall be the active source. It will be
transformed to an intent with a channel URI associated with
the corresponding TV input.

Change-Id: I02d4b24d5d05ad7a093e3b996942cbc43fd1ce8b
diff --git a/services/core/java/com/android/server/tv/TvInputHardwareManager.java b/services/core/java/com/android/server/tv/TvInputHardwareManager.java
index 9433ce4..332e426 100644
--- a/services/core/java/com/android/server/tv/TvInputHardwareManager.java
+++ b/services/core/java/com/android/server/tv/TvInputHardwareManager.java
@@ -21,9 +21,11 @@
 
 import android.content.Context;
 import android.hardware.hdmi.HdmiCecDeviceInfo;
-import android.hardware.hdmi.HdmiControlManager;
 import android.hardware.hdmi.HdmiHotplugEvent;
+import android.hardware.hdmi.IHdmiControlService;
 import android.hardware.hdmi.IHdmiDeviceEventListener;
+import android.hardware.hdmi.IHdmiHotplugEventListener;
+import android.hardware.hdmi.IHdmiInputChangeListener;
 import android.media.AudioDevicePort;
 import android.media.AudioManager;
 import android.media.AudioPatch;
@@ -39,6 +41,7 @@
 import android.os.Looper;
 import android.os.Message;
 import android.os.RemoteException;
+import android.os.ServiceManager;
 import android.util.Slog;
 import android.util.SparseArray;
 import android.util.SparseBooleanArray;
@@ -60,8 +63,7 @@
  *
  * @hide
  */
-class TvInputHardwareManager
-        implements TvInputHal.Callback, HdmiControlManager.HotplugEventListener {
+class TvInputHardwareManager implements TvInputHal.Callback {
     private static final String TAG = TvInputHardwareManager.class.getSimpleName();
     private final TvInputHal mHal = new TvInputHal(this);
     private final SparseArray<Connection> mConnections = new SparseArray<Connection>();
@@ -74,6 +76,9 @@
     // TODO: Should handle INACTIVE case.
     private final SparseArray<TvInputInfo> mTvInputInfoMap = new SparseArray<TvInputInfo>();
     private final IHdmiDeviceEventListener mHdmiDeviceEventListener = new HdmiDeviceEventListener();
+    private final IHdmiHotplugEventListener mHdmiHotplugEventListener =
+            new HdmiHotplugEventListener();
+    private final IHdmiInputChangeListener mHdmiInputChangeListener = new HdmiInputChangeListener();
 
     // Calls to mListener should happen here.
     private final Handler mHandler = new ListenerHandler();
@@ -89,9 +94,17 @@
 
     public void onBootPhase(int phase) {
         if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
-            HdmiControlManager hdmiControlManager =
-                    (HdmiControlManager) mContext.getSystemService(Context.HDMI_CONTROL_SERVICE);
-            hdmiControlManager.addHotplugEventListener(this);
+            IHdmiControlService hdmiControlService = IHdmiControlService.Stub.asInterface(
+                    ServiceManager.getService(Context.HDMI_CONTROL_SERVICE));
+            if (hdmiControlService != null) {
+                try {
+                    hdmiControlService.addHotplugEventListener(mHdmiHotplugEventListener);
+                    hdmiControlService.addDeviceEventListener(mHdmiDeviceEventListener);
+                    hdmiControlService.setInputChangeListener(mHdmiInputChangeListener);
+                } catch (RemoteException e) {
+                    Slog.w(TAG, "Error registering listeners to HdmiControlService:" + e);
+                }
+            }
         }
     }
 
@@ -261,23 +274,6 @@
         return null;
     }
 
-    // HdmiControlManager.HotplugEventListener implementation.
-
-    @Override
-    public void onReceived(HdmiHotplugEvent event) {
-        String inputId = null;
-
-        synchronized (mLock) {
-            mHdmiStateMap.put(event.getPort(), event.isConnected());
-            inputId = findInputIdForHdmiPortLocked(event.getPort());
-            if (inputId == null) {
-                return;
-            }
-            mHandler.obtainMessage(ListenerHandler.STATE_CHANGED,
-                    convertConnectedToState(event.isConnected()), 0, inputId).sendToTarget();
-        }
-    }
-
     private class Connection implements IBinder.DeathRecipient {
         private final TvInputHardwareInfo mHardwareInfo;
         private TvInputInfo mInfo;
@@ -554,6 +550,23 @@
         }
     }
 
+    // Listener implementations for HdmiControlService
+
+    private final class HdmiHotplugEventListener extends IHdmiHotplugEventListener.Stub {
+        @Override
+        public void onReceived(HdmiHotplugEvent event) {
+            synchronized (mLock) {
+                mHdmiStateMap.put(event.getPort(), event.isConnected());
+                String inputId = findInputIdForHdmiPortLocked(event.getPort());
+                if (inputId == null) {
+                    return;
+                }
+                mHandler.obtainMessage(ListenerHandler.STATE_CHANGED,
+                        convertConnectedToState(event.isConnected()), 0, inputId).sendToTarget();
+            }
+        }
+    }
+
     private final class HdmiDeviceEventListener extends IHdmiDeviceEventListener.Stub {
         @Override
         public void onStatusChanged(HdmiCecDeviceInfo deviceInfo, boolean activated) {
@@ -563,4 +576,12 @@
                     0, 0, deviceInfo).sendToTarget();
         }
     }
+
+    private final class HdmiInputChangeListener extends IHdmiInputChangeListener.Stub {
+        @Override
+        public void onChanged(HdmiCecDeviceInfo device) throws RemoteException {
+            // TODO: Build a channel Uri for the TvInputInfo associated with the logical device
+            //       and send an intent to TV app
+        }
+    }
 }