bluetooth: Rearrange some common function and create a utilily function

Move log_settings and log_flags to bluetooth_adapter_tests.
Add wait_till_condition_holds
Fix default_state_test after the changes

BUG=b:148638216
TEST=Run the affected tests

Change-Id: I53e02374390ad67161643fe40921990284542895
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/autotest/+/2040454
Tested-by: Shijin Abraham <shijinabraham@google.com>
Reviewed-by: Daniel Winkler <danielwinkler@google.com>
Commit-Queue: Shijin Abraham <shijinabraham@google.com>
diff --git a/server/cros/bluetooth/bluetooth_adapter_tests.py b/server/cros/bluetooth/bluetooth_adapter_tests.py
index 648436d..2da604f 100644
--- a/server/cros/bluetooth/bluetooth_adapter_tests.py
+++ b/server/cros/bluetooth/bluetooth_adapter_tests.py
@@ -19,8 +19,10 @@
 from autotest_lib.client.bin import utils
 from autotest_lib.client.bin.input import input_event_recorder as recorder
 from autotest_lib.client.common_lib import error
+from autotest_lib.client.common_lib.cros.bluetooth import bluetooth_socket
 from autotest_lib.client.cros.chameleon import chameleon
 from autotest_lib.server import test
+
 from autotest_lib.client.bin.input.linux_input import (
         BTN_LEFT, BTN_RIGHT, EV_KEY, EV_REL, REL_X, REL_Y, REL_WHEEL)
 from autotest_lib.server.cros.bluetooth.bluetooth_gatt_client_utils import (
@@ -520,6 +522,12 @@
 
     HID_REPORT_SLEEP_SECS = 1
 
+
+    DEFAULT_START_DELAY_SECS = 0
+    DEFAULT_HOLD_INTERVAL_SECS = 10
+    DEFAULT_HOLD_TIMEOUT_SECS = 60
+    DEFAULT_HOLD_SLEEP_SECS = 1
+
     # Default suspend time in seconds for suspend resume.
     SUSPEND_TIME_SECS=10
 
@@ -793,9 +801,54 @@
         logging.info('The DUT is waken up.')
 
 
+    def _wait_till_condition_holds(self, func, method_name,
+                                   timeout=DEFAULT_HOLD_TIMEOUT_SECS,
+                                   sleep_interval=DEFAULT_HOLD_SLEEP_SECS,
+                                   hold_interval=DEFAULT_HOLD_INTERVAL_SECS,
+                                   start_delay=DEFAULT_START_DELAY_SECS):
+        """ Wait for the func() to hold true for a period of time
+
+
+        @param func: the function to wait for.
+        @param method_name: the invoking class method.
+        @param timeout: number of seconds to wait before giving up.
+        @param sleep_interval: the interval in seconds to sleep between
+                invoking func().
+        @param hold_interval: the interval in seconds for the condition to
+                             remain true
+        @param start_delay: interval in seconds to wait before starting
+
+        @returns: True if the condition is met,
+                  False otherwise
+
+        """
+        if start_delay > 0:
+            logging.debug('waiting for %s secs before checking %s',start_delay,
+                          method_name)
+            time.sleep(start_delay)
+
+        try:
+            utils.poll_till_condition_holds(condition=func,
+                                            timeout=timeout,
+                                            sleep_interval=sleep_interval,
+                                            hold_interval = hold_interval,
+                                            desc=('Waiting %s' % method_name))
+            return True
+        except utils.TimeoutError as e:
+            logging.error('%s: %s', method_name, e)
+        except Exception as e:
+            logging.error('%s: %s', method_name, e)
+            err = 'bluetoothd possibly crashed. Check out /var/log/messages.'
+            logging.error(err)
+        except:
+            logging.error('%s: unexpected error', method_name)
+        return False
+
+
     def _wait_for_condition(self, func, method_name,
                             timeout=ADAPTER_WAIT_DEFAULT_TIMEOUT_SECS,
-                            sleep_interval=ADAPTER_POLLING_DEFAULT_SLEEP_SECS):
+                            sleep_interval=ADAPTER_POLLING_DEFAULT_SLEEP_SECS,
+                            start_delay=DEFAULT_START_DELAY_SECS):
         """Wait for the func() to become True.
 
         @param func: the function to wait for.
@@ -803,12 +856,18 @@
         @param timeout: number of seconds to wait before giving up.
         @param sleep_interval: the interval in seconds to sleep between
                 invoking func().
+        @param start_delay: interval in seconds to wait before starting
 
         @returns: True if the condition is met,
                   False otherwise
 
         """
 
+        if start_delay > 0:
+            logging.debug('waiting for %s secs before checking %s',start_delay,
+                          method_name)
+            time.sleep(start_delay)
+
         try:
             utils.poll_for_condition(condition=func,
                                      timeout=timeout,
@@ -2444,6 +2503,68 @@
         """Read raw HCI device information."""
         return self.bluetooth_facade.get_dev_info()
 
+    def log_settings(self, msg, settings):
+        """function convert MGMT_OP_READ_INFO settings to string
+
+        @param msg: string to include in output
+        @param settings: bitstring returned by MGMT_OP_READ_INFO
+        @return : List of strings indicating different settings
+        """
+        strs = []
+        if settings & bluetooth_socket.MGMT_SETTING_POWERED:
+            strs.append("POWERED")
+        if settings & bluetooth_socket.MGMT_SETTING_CONNECTABLE:
+            strs.append("CONNECTABLE")
+        if settings & bluetooth_socket.MGMT_SETTING_FAST_CONNECTABLE:
+            strs.append("FAST-CONNECTABLE")
+        if settings & bluetooth_socket.MGMT_SETTING_DISCOVERABLE:
+            strs.append("DISCOVERABLE")
+        if settings & bluetooth_socket.MGMT_SETTING_PAIRABLE:
+            strs.append("PAIRABLE")
+        if settings & bluetooth_socket.MGMT_SETTING_LINK_SECURITY:
+            strs.append("LINK-SECURITY")
+        if settings & bluetooth_socket.MGMT_SETTING_SSP:
+            strs.append("SSP")
+        if settings & bluetooth_socket.MGMT_SETTING_BREDR:
+            strs.append("BR/EDR")
+        if settings & bluetooth_socket.MGMT_SETTING_HS:
+            strs.append("HS")
+        if settings & bluetooth_socket.MGMT_SETTING_LE:
+            strs.append("LE")
+        logging.debug('%s : %s', msg, " ".join(strs))
+        return strs
+
+    def log_flags(self, msg, flags):
+        """Function to convert HCI state configuration to a string
+
+        @param msg: string to include in output
+        @param settings: bitstring returned by get_dev_info
+        @return : List of strings indicating different flags
+        """
+        strs = []
+        if flags & bluetooth_socket.HCI_UP:
+            strs.append("UP")
+        else:
+            strs.append("DOWN")
+        if flags & bluetooth_socket.HCI_INIT:
+            strs.append("INIT")
+        if flags & bluetooth_socket.HCI_RUNNING:
+            strs.append("RUNNING")
+        if flags & bluetooth_socket.HCI_PSCAN:
+            strs.append("PSCAN")
+        if flags & bluetooth_socket.HCI_ISCAN:
+            strs.append("ISCAN")
+        if flags & bluetooth_socket.HCI_AUTH:
+            strs.append("AUTH")
+        if flags & bluetooth_socket.HCI_ENCRYPT:
+            strs.append("ENCRYPT")
+        if flags & bluetooth_socket.HCI_INQUIRY:
+            strs.append("INQUIRY")
+        if flags & bluetooth_socket.HCI_RAW:
+            strs.append("RAW")
+        logging.debug('%s [HCI]: %s', msg, " ".join(strs))
+        return strs
+
 
     @_test_retry_and_log(False)
     def test_service_resolved(self, address):
diff --git a/server/cros/bluetooth/bluetooth_default_state_test.py b/server/cros/bluetooth/bluetooth_default_state_test.py
index 49b03f8..8b6bfe5 100644
--- a/server/cros/bluetooth/bluetooth_default_state_test.py
+++ b/server/cros/bluetooth/bluetooth_default_state_test.py
@@ -20,55 +20,6 @@
     """
     version = 1
 
-    def _log_settings(self, msg, settings):
-        """helper function to log the states in settings"""
-        strs = []
-        if settings & bluetooth_socket.MGMT_SETTING_POWERED:
-            strs.append("POWERED")
-        if settings & bluetooth_socket.MGMT_SETTING_CONNECTABLE:
-            strs.append("CONNECTABLE")
-        if settings & bluetooth_socket.MGMT_SETTING_FAST_CONNECTABLE:
-            strs.append("FAST-CONNECTABLE")
-        if settings & bluetooth_socket.MGMT_SETTING_DISCOVERABLE:
-            strs.append("DISCOVERABLE")
-        if settings & bluetooth_socket.MGMT_SETTING_PAIRABLE:
-            strs.append("PAIRABLE")
-        if settings & bluetooth_socket.MGMT_SETTING_LINK_SECURITY:
-            strs.append("LINK-SECURITY")
-        if settings & bluetooth_socket.MGMT_SETTING_SSP:
-            strs.append("SSP")
-        if settings & bluetooth_socket.MGMT_SETTING_BREDR:
-            strs.append("BR/EDR")
-        if settings & bluetooth_socket.MGMT_SETTING_HS:
-            strs.append("HS")
-        if settings & bluetooth_socket.MGMT_SETTING_LE:
-            strs.append("LE")
-        logging.debug(msg + ': %s', " ".join(strs))
-
-    def _log_flags(self, msg, flags):
-        """helper function to log the flags in flags"""
-        strs = []
-        if flags & bluetooth_socket.HCI_UP:
-            strs.append("UP")
-        else:
-            strs.append("DOWN")
-        if flags & bluetooth_socket.HCI_INIT:
-            strs.append("INIT")
-        if flags & bluetooth_socket.HCI_RUNNING:
-            strs.append("RUNNING")
-        if flags & bluetooth_socket.HCI_PSCAN:
-            strs.append("PSCAN")
-        if flags & bluetooth_socket.HCI_ISCAN:
-            strs.append("ISCAN")
-        if flags & bluetooth_socket.HCI_AUTH:
-            strs.append("AUTH")
-        if flags & bluetooth_socket.HCI_ENCRYPT:
-            strs.append("ENCRYPT")
-        if flags & bluetooth_socket.HCI_INQUIRY:
-            strs.append("INQUIRY")
-        if flags & bluetooth_socket.HCI_RAW:
-            strs.append("RAW")
-        logging.debug(msg + ' [HCI]: %s', " ".join(strs))
 
 
     def compare_property(self, bluez_property, mgmt_setting, current_settings):
@@ -99,7 +50,7 @@
         ( address, bluetooth_version, manufacturer_id,
                 supported_settings, current_settings, class_of_device,
                 name, short_name ) = self.read_info()
-        self._log_settings('Initial state', current_settings)
+        self.log_settings('Initial state', current_settings)
 
         if current_settings & bluetooth_socket.MGMT_SETTING_POWERED:
             raise error.TestFail('Bluetooth adapter is powered')
@@ -128,7 +79,7 @@
         # Compare with the raw HCI state of the adapter as well, this should
         # be just not "UP", otherwise something deeply screwy is happening.
         flags = self.get_dev_info()[3]
-        self._log_flags('Initial state', flags)
+        self.log_flags('Initial state', flags)
 
         if flags & bluetooth_socket.HCI_UP:
             raise error.TestFail('HCI UP flag does not match kernel while '
@@ -138,7 +89,7 @@
         # powered up, pairable, but not discoverable.
         self.test_power_on_adapter()
         current_settings = self.read_info()[4]
-        self._log_settings("Powered up", current_settings)
+        self.log_settings("Powered up", current_settings)
 
         if not current_settings & bluetooth_socket.MGMT_SETTING_POWERED:
             raise error.TestFail('Bluetooth adapter is not powered')
@@ -176,7 +127,7 @@
         # Compare with the raw HCI state of the adapter while powered up as
         # well.
         flags = self.get_dev_info()[3]
-        self._log_flags('Powered up', flags)
+        self.log_flags('Powered up', flags)
 
         if not flags & bluetooth_socket.HCI_UP:
             raise error.TestFail('HCI UP flag does not match kernel while '
@@ -218,7 +169,7 @@
                 self.test_nondiscoverable()
                 current_settings = self.read_info()[4]
                 flags = self.get_dev_info()[3]
-                self._log_flags('Discoverability Toggled', flags)
+                self.log_flags('Discoverability Toggled', flags)
                 if flags & bluetooth_socket.HCI_PSCAN:
                     raise error.TestFail('PSCAN on after toggling DISCOVERABLE')
 
@@ -230,14 +181,15 @@
             # Wait for a few seconds before reading the settings
             time.sleep(3)
             current_settings = self.read_info()[4]
-            self._log_settings("After add device", current_settings)
+            self.log_settings("After add device",
+                                              current_settings)
 
             flags = self.get_dev_info()[3]
-            self._log_flags('After add device', flags)
+            self.log_flags('After add device', flags)
 
             if current_settings != previous_settings:
-                self._log_settings("previous settings", previous_settings)
-                self._log_settings("current settings", current_settings)
+                self.log_settings("previous settings", previous_settings)
+                self.log_settings("current settings", current_settings)
                 raise error.TestFail(
                     'Bluetooth adapter settings changed after add device')
             if not flags & bluetooth_socket.HCI_PSCAN:
@@ -250,10 +202,10 @@
             # on older devices. Wait for few second before reading the settigs
             time.sleep(3)
             current_settings = self.read_info()[4]
-            self._log_settings("After remove device", current_settings)
+            self.log_settings("After remove device", current_settings)
 
             flags = self.get_dev_info()[3]
-            self._log_flags('After remove device', flags)
+            self.log_flags('After remove device', flags)
 
             if current_settings != previous_settings:
                 raise error.TestFail(
@@ -265,7 +217,7 @@
         # returned to powered down.
         self.test_power_off_adapter()
         current_settings = self.read_info()[4]
-        self._log_settings("After power down", current_settings)
+        self.log_settings("After power down", current_settings)
 
         if current_settings & bluetooth_socket.MGMT_SETTING_POWERED:
             raise error.TestFail('Bluetooth adapter is powered after power off')
@@ -287,7 +239,7 @@
 
         # And one last comparison with the raw HCI state of the adapter.
         flags = self.get_dev_info()[3]
-        self._log_flags('After power down', flags)
+        self.log_flags('After power down', flags)
 
         if flags & bluetooth_socket.HCI_UP:
             raise error.TestFail('HCI UP flag does not match kernel after '