def test_modify_phonebook(self):
        """Test Modify Phonebook

        Test changing contacts and reconnecting PBAP.

        Precondition:
        1. Devices are paired.

        Steps:
        1. Add a predefined list of contacts to PSE.
        2. Connect PCE to PSE to perform transfer.
        3. Verify that contacts match.
        4. Change some contacts on the PSE.
        5. Reconnect PCE to PSE to perform transfer.
        6. Verify that new contacts match.

        Returns:
            Pass if True
            Fail if False
        """
        bt_contacts_utils.generate_contact_list(self.contacts_destination_path,
                                                PSE_CONTACTS_FILE, 100)
        phone_numbers_added = bt_contacts_utils.import_device_contacts_from_vcf(
            self.pse, self.contacts_destination_path, PSE_CONTACTS_FILE)
        if not self.connect_and_verify(phone_numbers_added):
            return False

        bt_contacts_utils.erase_contacts(self.pse)
        bt_contacts_utils.generate_contact_list(self.contacts_destination_path,
                                                PSE_CONTACTS_FILE, 110, 2)
        phone_numbers_added = bt_contacts_utils.import_device_contacts_from_vcf(
            self.pse, self.contacts_destination_path, PSE_CONTACTS_FILE)
        return self.connect_and_verify(phone_numbers_added)
    def test_contact_download(self):
        """Test Contact Download

        Test download of contacts from a clean state.

        Precondition:
        1. Devices are paired.

        Steps:
        1. Erase contacts from PSE and PCE.
        2. Add a predefined list of contacts to PSE.
        3. Connect PCE to PSE to perform transfer.
        4. Compare transfered contacts.
        5. Disconnect.
        6. Verify PCE cleaned up contact list.

        Returns:
            Pass if True
            Fail if False
        """
        bt_contacts_utils.generate_contact_list(self.contacts_destination_path,
                                                PSE_CONTACTS_FILE, 100)
        phone_numbers_added = bt_contacts_utils.import_device_contacts_from_vcf(
            self.pse, self.contacts_destination_path, PSE_CONTACTS_FILE)
        bt_test_utils.connect_pri_to_sec(
            self.pce, self.pse,
            set([BtEnum.BluetoothProfile.PBAP_CLIENT.value]))
        bt_contacts_utils.wait_for_phone_number_update_complete(
            self.pce, phone_numbers_added)
        if not self.verify_contacts_match():
            return False
        return bt_contacts_utils.erase_contacts(self.pce)
    def test_multiple_phones(self):
        """Test Multiple Phones

        Test that connects two phones and confirms contacts are transfered
        and merged while still being associated with their original phone.

        Precondition:
        1. Devices are paired.

        Steps:
        1. Add a unique list of contacts to PSE on each phone.
        2. Connect PCE to PSE 1 to perform transfer.
        3. Verify contacts match.
        4. Connect PCE to PSE 2 to perform transfer.
        5. Verify that the PCE has a union set of contacts from
           PSE 1 and PSE 2.
        6. Disconnect PCE from PSE 1 to clean up contacts.
        7. Verify that only PSE 2 contacts remain on PCE and they match.
        8. Disconnect PCE from PSE 2 to clean up contacts.

        Returns:
           Pass if True
           Fail if False
        """

        PSE1_CONTACTS_FILE = "{}{}".format(PSE_CONTACTS_FILE, "1")
        PSE2_CONTACTS_FILE = "{}{}".format(PSE_CONTACTS_FILE, "2")

        bt_contacts_utils.generate_contact_list(self.contacts_destination_path,
                                                PSE1_CONTACTS_FILE, 100)
        phone_numbers_added = bt_contacts_utils.import_device_contacts_from_vcf(
            self.pse, self.contacts_destination_path, PSE1_CONTACTS_FILE)
        bt_contacts_utils.generate_contact_list(self.contacts_destination_path,
                                                PSE2_CONTACTS_FILE, 100)
        phone_numbers_added = bt_contacts_utils.import_device_contacts_from_vcf(
            self.pse2, self.contacts_destination_path, PSE2_CONTACTS_FILE)

        self.pce.droid.bluetoothPbapClientDisconnect(
            self.pse.droid.bluetoothGetLocalAddress())
        self.pce.droid.bluetoothPbapClientDisconnect(
            self.pse2.droid.bluetoothGetLocalAddress())

        bt_test_utils.connect_pri_to_sec(
            self.pce, self.pse,
            set([BtEnum.BluetoothProfile.PBAP_CLIENT.value]))
        bt_contacts_utils.wait_for_phone_number_update_complete(self.pce, 100)
        bt_contacts_utils.export_device_contacts_to_vcf(
            self.pce, self.contacts_destination_path, PCE_CONTACTS_FILE)
        pse1_matches = bt_contacts_utils.count_contacts_with_differences(
            self.contacts_destination_path, PCE_CONTACTS_FILE,
            PSE1_CONTACTS_FILE) == 0

        bt_test_utils.connect_pri_to_sec(
            self.pce, self.pse2,
            set([BtEnum.BluetoothProfile.PBAP_CLIENT.value]))

        bt_contacts_utils.wait_for_phone_number_update_complete(self.pce, 200)

        bt_contacts_utils.export_device_contacts_to_vcf(
            self.pce, self.contacts_destination_path, PCE_CONTACTS_FILE)

        merged_file = open(
            '{}{}'.format(self.contacts_destination_path,
                          MERGED_CONTACTS_FILE), 'w')
        for contacts_file in [PSE1_CONTACTS_FILE, PSE2_CONTACTS_FILE]:
            infile = open(self.contacts_destination_path + contacts_file)
            merged_file.write(infile.read())

        self.log.info("Checking combined phonebook.")
        pse1andpse2_matches = bt_contacts_utils.count_contacts_with_differences(
            self.contacts_destination_path, PCE_CONTACTS_FILE,
            MERGED_CONTACTS_FILE) == 0

        self.pce.droid.bluetoothPbapClientDisconnect(
            self.pse.droid.bluetoothGetLocalAddress())
        bt_contacts_utils.wait_for_phone_number_update_complete(self.pce, 100)

        self.log.info("Checking phonebook after disconnecting first device.")
        bt_contacts_utils.export_device_contacts_to_vcf(
            self.pce, self.contacts_destination_path, PCE_CONTACTS_FILE)
        pse2_matches = bt_contacts_utils.count_contacts_with_differences(
            self.contacts_destination_path, PCE_CONTACTS_FILE,
            PSE2_CONTACTS_FILE) == 0

        bt_contacts_utils.erase_contacts(self.pse)
        bt_contacts_utils.erase_contacts(self.pse2)
        return pse1_matches and pse2_matches and pse1andpse2_matches
    def test_special_contacts(self):
        """Test Special Contacts

        Test numerous special cases of contacts that could cause errors.

        Precondition:
        1. Devices are paired.

        Steps:
        1. Add a predefined list of contacts to PSE that includes special cases:
        2. Connect PCE to PSE to perform transfer.
        3. Verify that contacts match.

        Returns:
            Pass if True
            Fail if False
        """

        vcards = []

        # Generate a contact with no email address
        current_contact = bt_contacts_utils.VCard()
        current_contact.first_name = "Mr."
        current_contact.last_name = "Smiley"
        current_contact.add_phone_number(
            bt_contacts_utils.generate_random_phone_number())
        vcards.append(current_contact)

        # Generate a 2nd contact with the same name but different phone number
        current_contact = bt_contacts_utils.VCard()
        current_contact.first_name = "Mr."
        current_contact.last_name = "Smiley"
        current_contact.add_phone_number(
            bt_contacts_utils.generate_random_phone_number())
        vcards.append(current_contact)

        # Generate a contact with no name
        current_contact = bt_contacts_utils.VCard()
        current_contact.email = "{}@gmail.com".format(
            bt_contacts_utils.generate_random_string())
        current_contact.add_phone_number(
            bt_contacts_utils.generate_random_phone_number())
        vcards.append(current_contact)

        # Generate a contact with random characters in its name
        current_contact = bt_contacts_utils.VCard()
        current_contact.first_name = bt_contacts_utils.generate_random_string()
        current_contact.last_name = bt_contacts_utils.generate_random_string()
        current_contact.add_phone_number(
            bt_contacts_utils.generate_random_phone_number())
        vcards.append(current_contact)

        # Generate a contact with only a phone number
        current_contact = bt_contacts_utils.VCard()
        current_contact.add_phone_number(
            bt_contacts_utils.generate_random_phone_number())
        vcards.append(current_contact)

        # Generate a 2nd contact with only a phone number
        current_contact = bt_contacts_utils.VCard()
        current_contact.add_phone_number(
            bt_contacts_utils.generate_random_phone_number())
        vcards.append(current_contact)

        bt_contacts_utils.create_new_contacts_vcf_from_vcards(
            self.contacts_destination_path, PSE_CONTACTS_FILE, vcards)

        phone_numbers_added = bt_contacts_utils.import_device_contacts_from_vcf(
            self.pse, self.contacts_destination_path, PSE_CONTACTS_FILE)

        return self.connect_and_verify(phone_numbers_added)