Remove the internal dependency on the public API WaitVideoInputStable

The method WaitVideoInputStable is a public API. It is heavily used
by internal methods. This change moves the implementations to the RX
classes in order to remove the dependency.

BUG=None
TEST=make; make remote-install; run a chameleon test

Change-Id: Ic00bc9e83763581370ebdf95399a3c40c38994f4
Reviewed-on: https://chromium-review.googlesource.com/425083
Commit-Ready: Wai-Hong Tam <waihong@google.com>
Tested-by: Wai-Hong Tam <waihong@google.com>
Reviewed-by: Cheng-Yi Chiang <cychiang@chromium.org>
Reviewed-by: Hsu Wei-Cheng <mojahsu@chromium.org>
diff --git a/chameleond/utils/input_flow.py b/chameleond/utils/input_flow.py
index 5dde728..c3d95d5 100644
--- a/chameleond/utils/input_flow.py
+++ b/chameleond/utils/input_flow.py
@@ -540,16 +540,7 @@
 
   def WaitVideoInputStable(self, timeout=None):
     """Waits the video input stable or timeout."""
-    if timeout is None:
-      timeout = self._TIMEOUT_VIDEO_STABLE_PROBE
-
-    try:
-      common.WaitForCondition(
-          self._rx.IsVideoInputStable, True, self._DELAY_VIDEO_MODE_PROBE,
-          timeout)
-      return True
-    except common.TimeoutError:
-      return False
+    return self._rx.WaitVideoInputStable(timeout)
 
   def _IsFrameLocked(self):
     """Returns whether the FPGA frame is locked.
@@ -629,14 +620,14 @@
     """
     if not self._rx.IsVideoInputStable() or not self._IsFrameLocked():
       self.Initialize()  # reset rx
-      video_input_stable = self.WaitVideoInputStable()
+      video_input_stable = self._rx.WaitVideoInputStable()
 
       if not video_input_stable:
         logging.info('Send DP HPD pulse to reset source...')
         self._fpga.hpd.Unplug(self._input_id)
         time.sleep(self._HPD_PULSE_WIDTH)
         self._fpga.hpd.Plug(self._input_id)
-        video_input_stable = self.WaitVideoInputStable()
+        video_input_stable = self._rx.WaitVideoInputStable()
 
       if video_input_stable:
         self._SetPixelMode()
@@ -811,7 +802,7 @@
     if is_reset_needed:
       self._rx.Reset()
 
-    if self.WaitVideoInputStable():
+    if self._rx.WaitVideoInputStable():
       pixel_mode_changed = self._SetPixelMode()
       if is_reset_needed or pixel_mode_changed:
         self.WaitVideoOutputStable()
@@ -825,15 +816,7 @@
 
   def WaitVideoInputStable(self, timeout=None):
     """Waits the video input stable or timeout. Returns success or not."""
-    if timeout is None:
-      timeout = self._TIMEOUT_VIDEO_STABLE_PROBE
-    try:
-      common.WaitForCondition(
-          self._rx.IsVideoInputStable, True, self._DELAY_VIDEO_MODE_PROBE,
-          timeout)
-    except common.TimeoutError:
-      return False
-    return True
+    return self._rx.WaitVideoInputStable(timeout)
 
   def _IsFrameLocked(self):
     """Returns whether the FPGA frame is locked.
@@ -930,7 +913,7 @@
     plugged_before_check = self.IsPlugged()
     if not plugged_before_check:
       self.Plug()
-    is_stable = self.WaitVideoInputStable()
+    is_stable = self._rx.WaitVideoInputStable()
     if not plugged_before_check:
       self.Unplug()
     return is_stable
@@ -1027,7 +1010,7 @@
     """
     if self._auto_vga_mode:
       # Detect the VGA mode and set it properly.
-      if self.WaitVideoInputStable():
+      if self._rx.WaitVideoInputStable():
         self._rx.SetMode(self._rx.DetectMode())
         self.WaitVideoOutputStable()
       else:
@@ -1035,16 +1018,7 @@
 
   def WaitVideoInputStable(self, timeout=None):
     """Waits the video input stable or timeout. Returns success or not."""
-    if timeout is None:
-      timeout = self._TIMEOUT_CHECKING_STABLE
-    try:
-      # Check if H-Sync/V-Sync recevied from the source.
-      common.WaitForCondition(
-          self._rx.IsSyncDetected, True, self._DELAY_CHECKING_STABLE_PROBE,
-          timeout)
-    except common.TimeoutError:
-      return False
-    return True
+    return self._rx.WaitVideoInputStable(timeout)
 
   def _IsResolutionValid(self):
     """Returns True if the resolution from FPGA is valid and not floating."""
diff --git a/chameleond/utils/rx.py b/chameleond/utils/rx.py
index 120a4b9..8a5459e 100644
--- a/chameleond/utils/rx.py
+++ b/chameleond/utils/rx.py
@@ -7,6 +7,7 @@
 import time
 
 import chameleon_common  # pylint: disable=W0611
+from chameleond.utils import common
 from chameleond.utils import i2c
 
 
@@ -20,6 +21,9 @@
 
   SLAVE_ADDRESSES = (0x58, 0x59)
 
+  _DELAY_VIDEO_MODE_PROBE = 1.0
+  _TIMEOUT_VIDEO_STABLE_PROBE = 5
+
   _AUDIO_RESET_DELAY = 0.001
   _VIDEO_RESET_DELAY = 0.001
 
@@ -101,6 +105,23 @@
     input_status = self.Get(self._REG_INPUT_STATUS)
     return bool(input_status & self._BIT_VIDEO_STABLE)
 
+  def WaitVideoInputStable(self, timeout=None):
+    """Waits the video input stable or timeout.
+
+    Returns:
+      True if the video input is stable before timeout; otherwise, False.
+    """
+    if timeout is None:
+      timeout = self._TIMEOUT_VIDEO_STABLE_PROBE
+
+    try:
+      common.WaitForCondition(
+          self.IsVideoInputStable, True, self._DELAY_VIDEO_MODE_PROBE,
+          timeout)
+      return True
+    except common.TimeoutError:
+      return False
+
   def GetPixelClock(self):
     """Returns the pixel clock of the input signal in MHz."""
     # PCLK = 27MHz * 1024 / PCLK_COUNT
@@ -144,6 +165,9 @@
 
   SLAVE_ADDRESSES = (0x48, )
 
+  _DELAY_VIDEO_MODE_PROBE = 0.1
+  _TIMEOUT_VIDEO_STABLE_PROBE = 10
+
   _AUDIO_RESET_DELAY = 0.001
 
   _REG_P0_INTERRUPT = 0x05
@@ -326,6 +350,23 @@
     video_mode = self.Get(self._REG_VIDEO_MODE)
     return bool(video_mode & self._BIT_VIDEO_STABLE)
 
+  def WaitVideoInputStable(self, timeout=None):
+    """Waits the video input stable or timeout.
+
+    Returns:
+      True if the video input is stable before timeout; otherwise, False.
+    """
+    if timeout is None:
+      timeout = self._TIMEOUT_VIDEO_STABLE_PROBE
+
+    try:
+      common.WaitForCondition(
+          self.IsVideoInputStable, True, self._DELAY_VIDEO_MODE_PROBE,
+          timeout)
+      return True
+    except common.TimeoutError:
+      return False
+
   def GetPixelClock(self):
     """Returns the pixel clock of the input signal in MHz."""
     pclk_div = self.Get(self._REG_PIXEL_CLOCK_DIV)
@@ -420,6 +461,9 @@
 
   SLAVE_ADDRESSES = (0x4c, )
 
+  _DELAY_CHECKING_STABLE_PROBE = 0.1
+  _TIMEOUT_CHECKING_STABLE = 5
+
   _REG_SYNC_DETECT = 0x14
   _BIT_HSYNC_DETECTED = 1 << 7
   _BIT_TV_MODE = 1 << 6
@@ -609,6 +653,23 @@
     """Returns True if Hsync or Vsync is detected."""
     return bool(self.Get(self._REG_SYNC_DETECT) & self._BITS_SYNC_MASK)
 
+  def WaitVideoInputStable(self, timeout=None):
+    """Waits the video input stable or timeout.
+
+    Returns:
+      True if the video input is stable before timeout; otherwise, False.
+    """
+    if timeout is None:
+      timeout = self._TIMEOUT_CHECKING_STABLE
+    try:
+      # Check if H-Sync/V-Sync recevied from the source.
+      common.WaitForCondition(
+          self.IsSyncDetected, True, self._DELAY_CHECKING_STABLE_PROBE,
+          timeout)
+    except common.TimeoutError:
+      return False
+    return True
+
   def IsInterlaced(self):
     """Returns True if the input video is in interlaced mode."""
     # TODO(waihong): Support checking interlaced.