def test_play_pause(self):
        """
        Test the Play and Pause passthrough commands

        Pre-Condition:
        1. Devices previously bonded & Connected

        Steps:
        1. Invoke Play, Pause from CT
        2. Wait to receive the corresponding received event from TG

        Returns:
        True    if the event was received
        False   if the event was not received

        Priority: 0
        """
        # Set up the MediaBrowserService
        self._init_mbs()
        if not car_media_utils.send_media_passthrough_cmd(
                self.log, self.CT, self.TG, car_media_utils.CMD_MEDIA_PLAY,
                car_media_utils.EVENT_PLAY_RECEIVED, DEFAULT_EVENT_TIMEOUT):
            return False
        if not car_media_utils.send_media_passthrough_cmd(
                self.log, self.CT, self.TG, car_media_utils.CMD_MEDIA_PAUSE,
                car_media_utils.EVENT_PAUSE_RECEIVED, DEFAULT_EVENT_TIMEOUT):
            return False
        return True
    def test_passthrough(self):
        """
        Test the Skip Next & Skip Previous passthrough commands

        Pre-Condition:
        1. Devices previously bonded & Connected

        Steps:
        1. Invoke other passthrough commands (skip >> & <<) from CT
        2. Wait to receive the corresponding received event from TG

        Returns:
        True    if the event was received
        False   if the event was not received

        Priority: 0
        """
        # Set up the MediaBrowserService
        self._init_mbs()
        if not car_media_utils.send_media_passthrough_cmd(
                self.log, self.CT, self.TG,
                car_media_utils.CMD_MEDIA_SKIP_NEXT,
                car_media_utils.EVENT_SKIP_NEXT_RECEIVED,
                DEFAULT_EVENT_TIMEOUT):
            return False
        if not car_media_utils.send_media_passthrough_cmd(
                self.log, self.CT, self.TG,
                car_media_utils.CMD_MEDIA_SKIP_PREV,
                car_media_utils.EVENT_SKIP_PREV_RECEIVED,
                DEFAULT_EVENT_TIMEOUT):
            return False

        # Just pause media before test ends
        if not car_media_utils.send_media_passthrough_cmd(
                self.log, self.CT, self.TG, car_media_utils.CMD_MEDIA_PAUSE,
                car_media_utils.EVENT_PAUSE_RECEIVED):
            return False

        return True
    def test_disconnect_while_media_playing(self):
        """
        Disconnect BT between CT and TG in the middle of a audio streaming session and check
        1) If TG continues to still play music
        2) If CT stops playing

        Pre-Condition:
        1. Devices previously bonded & Connected

        Steps:
        1. Invoke Play from CT
        2. Check if both CT and TG are playing music by checking if the respective
           MediaSessions are active
        3. Fail if either the CT or TG is not playing
        4. Disconnect Bluetooth connection between CT and TG
        5. Check if the CT MediaSession stopped being active.
           Fail if its mediasession is still active.
        6. Check if the TG MediaSession is still active.
        7. Fail if TG stopped playing music.

        Returns:
        True    if the CT stopped playing audio and the TG continued after BT disconnect
        False   if the CT still was playing audio or TG stopped after BT disconnect.

        Priority: 0
        """
        self._init_mbs()
        self.log.info("Sending Play command from Car")
        if not car_media_utils.send_media_passthrough_cmd(
                self.log, self.CT, self.TG, car_media_utils.CMD_MEDIA_PLAY,
                car_media_utils.EVENT_PLAY_RECEIVED, DEFAULT_EVENT_TIMEOUT):
            return False

        time.sleep(DEFAULT_WAIT_TIME)

        self.TG.log.info("Phone Media Sessions:")
        if not car_media_utils.isMediaSessionActive(
                self.log, self.TG, PHONE_MEDIA_BROWSER_SERVICE_NAME):
            self.TG.log.error("Media not playing in connected Phone")
            return False

        self.CT.log.info("Car Media Sessions:")
        if not car_media_utils.isMediaSessionActive(
                self.log, self.CT, CAR_MEDIA_BROWSER_SERVICE_NAME):
            self.CT.log.error("Media not playing in connected Car")
            return False

        self.log.info("Bluetooth Disconnect the car and phone")
        result = bt_test_utils.disconnect_pri_from_sec(
            self.SRC, self.SNK, [BtEnum.BluetoothProfile.A2DP.value])
        if not result:
            if bt_test_utils.is_a2dp_src_device_connected(
                    self.SRC, self.SNK.droid.bluetoothGetLocalAddress()):
                self.SRC.log.error("Failed to disconnect on A2dp")
                return False

        self.TG.log.info("Phone Media Sessions:")
        if not car_media_utils.isMediaSessionActive(
                self.log, self.TG, PHONE_MEDIA_BROWSER_SERVICE_NAME):
            self.TG.log.error(
                "Media stopped playing in phone after BT disconnect")
            return False

        self.CT.log.info("Car Media Sessions:")
        if car_media_utils.isMediaSessionActive(
                self.log, self.CT, CAR_MEDIA_BROWSER_SERVICE_NAME):
            self.CT.log.error(
                "Media still playing in a Car after BT disconnect")
            return False

        return True
    def test_media_metadata(self):
        """
        Test if the metadata matches between the two ends.
        Send some random sequence of passthrough commands and compare metadata.
        TODO: truely randomize of the seq of passthrough commands.
        Pre-Condition:
        1. Devices previously bonded & Connected

        Steps:
        1. Invoke Play from CT
        2. Compare the metadata between CT and TG. Fail if they don't match
        3. Send Skip Next from CT
        4. Compare the metadata between CT and TG. Fail if they don't match
        5. Repeat steps 3 & 4
        6. Send Skip Prev from CT
        7. Compare the metadata between CT and TG. Fail if they don't match

        Returns:
        True    if the metadata matched all the way
        False   if there was a metadata mismatch at any point

        Priority: 0
        """
        if not (car_media_utils.is_a2dp_connected(self.log, self.SNK,
                                                  self.SRC)):
            self.SNK.log.error('No A2dp Connection')
            return False

        self._init_mbs()
        if not car_media_utils.send_media_passthrough_cmd(
                self.log, self.CT, self.TG, car_media_utils.CMD_MEDIA_PLAY,
                car_media_utils.EVENT_PLAY_RECEIVED, DEFAULT_EVENT_TIMEOUT):
            return False
        time.sleep(DEFAULT_WAIT_TIME)
        if not car_media_utils.check_metadata(self.log, self.TG, self.CT):
            return False

        if not car_media_utils.send_media_passthrough_cmd(
                self.log, self.CT, self.TG,
                car_media_utils.CMD_MEDIA_SKIP_NEXT,
                car_media_utils.EVENT_SKIP_NEXT_RECEIVED,
                DEFAULT_EVENT_TIMEOUT):
            return False
        time.sleep(DEFAULT_WAIT_TIME)
        if not car_media_utils.check_metadata(self.log, self.TG, self.CT):
            return False

        if not car_media_utils.send_media_passthrough_cmd(
                self.log, self.CT, self.TG,
                car_media_utils.CMD_MEDIA_SKIP_NEXT,
                car_media_utils.EVENT_SKIP_NEXT_RECEIVED,
                DEFAULT_EVENT_TIMEOUT):
            return False
        time.sleep(DEFAULT_WAIT_TIME)
        if not car_media_utils.check_metadata(self.log, self.TG, self.CT):
            return False

        if not car_media_utils.send_media_passthrough_cmd(
                self.log, self.CT, self.TG,
                car_media_utils.CMD_MEDIA_SKIP_PREV,
                car_media_utils.EVENT_SKIP_PREV_RECEIVED,
                DEFAULT_EVENT_TIMEOUT):
            return False
        time.sleep(DEFAULT_WAIT_TIME)
        if not car_media_utils.check_metadata(self.log, self.TG, self.CT):
            return False