Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f0eab57f authored by Sumit Pundir's avatar Sumit Pundir
Browse files

Merge remote-tracking branch 'bitfireAT/master' into sprint

parents ca5d3be7 bf4ea05d
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line

buildscript {
    ext.versions = [
        kotlin: '1.3.60',
        kotlin: '1.3.61',
        dokka: '0.10.0'
    ]

@@ -11,7 +11,7 @@ buildscript {
    }

    dependencies {
        classpath 'com.android.tools.build:gradle:3.5.2'
        classpath 'com.android.tools.build:gradle:3.5.3'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${versions.kotlin}"
        classpath "org.jetbrains.dokka:dokka-gradle-plugin:${versions.dokka}"
    }
@@ -72,7 +72,7 @@ android {
dependencies {
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:${versions.kotlin}"

    implementation 'org.apache.commons:commons-text:1.7'
    implementation 'org.apache.commons:commons-text:1.8'
    implementation 'commons-io:commons-io:2.6'

    // ez-vcard to parse/generate VCards
+45 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.rule.GrantPermissionRule
import foundation.e.vcard4android.impl.TestAddressBook
import ezvcard.VCardVersion
import ezvcard.parameter.EmailType
import ezvcard.property.Address
import ezvcard.property.Birthday
import ezvcard.property.Email
@@ -202,6 +203,50 @@ class AndroidContactTest {
        }
    }

    @Test
    @SmallTest
    fun testEmailTypes() {
        val vCard = "BEGIN:VCARD\r\n" +
                "VERSION:4.0\r\n" +
                "FN:Test\r\n" +
                "EMAIL;TYPE=internet;TYPE=work:work@example.com\r\n" +
                "EMAIL;TYPE=home:home@example.com\r\n" +
                "EMAIL;TYPE=internet,pref:other1@example.com\r\n" +
                "EMAIL;TYPE=x400,other:other2@example.com\r\n" +
                "EMAIL;TYPE=x-mobile:mobile@example.com\r\n" +
                "END:VCARD\r\n"
        val contacts = Contact.fromReader(StringReader(vCard), null)

        val dbContact = AndroidContact(addressBook, contacts.first(), null, null)
        dbContact.add()

        val dbContact2 = addressBook.findContactByID(dbContact.id!!)
        try {
            val contact2 = dbContact2.contact!!
            assertEquals("work@example.com", contact2.emails[0].property.value)
            assertArrayEquals(arrayOf(EmailType.WORK), contact2.emails[0].property.types.toTypedArray())
            assertNull(contact2.emails[0].property.pref)

            assertEquals("home@example.com", contact2.emails[1].property.value)
            assertArrayEquals(arrayOf(EmailType.HOME), contact2.emails[1].property.types.toTypedArray())
            assertNull(contact2.emails[1].property.pref)

            assertEquals("other1@example.com", contact2.emails[2].property.value)
            assertTrue(contact2.emails[2].property.types.isEmpty())
            assertNotEquals(0, contact2.emails[2].property.pref)

            assertEquals("other2@example.com", contact2.emails[3].property.value)
            assertTrue(contact2.emails[3].property.types.isEmpty())
            assertNull(contact2.emails[3].property.pref)

            assertEquals("mobile@example.com", contact2.emails[4].property.value)
            assertArrayEquals(arrayOf(Contact.EMAIL_TYPE_MOBILE), contact2.emails[4].property.types.toTypedArray())
            assertNull(contact2.emails[4].property.pref)
        } finally {
            dbContact2.delete()
        }
    }


    @Test
    fun testLabelToXName() {
+33 −12
Original line number Diff line number Diff line
@@ -572,11 +572,28 @@ open class AndroidContact(
        buildContact(builder, true)
        batch.enqueue(BatchOperation.Operation(builder))

        // delete known data rows before adding the new ones; don't delete group memberships!
        // Delete known data rows before adding the new ones.
        // - We don't delete group memberships.
        // - We'll only delete rows we have inserted so that unknown rows like
        //   vnd.android.cursor.item/important_people (= contact is in Samsung "edge panel") remain untouched.
        batch.enqueue(BatchOperation.Operation(
                ContentProviderOperation.newDelete(dataSyncURI())
                .withSelection(Data.RAW_CONTACT_ID + "=? AND " + Data.MIMETYPE + " NOT IN (?,?)",
                        arrayOf(id.toString(), GroupMembership.CONTENT_ITEM_TYPE, CachedGroupMembership.CONTENT_ITEM_TYPE))
                .withSelection(Data.RAW_CONTACT_ID + "=? AND " +
                        Data.MIMETYPE + " IN (?,?,?,?,?,?,?,?,?,?,?,?,?)",
                        arrayOf(id.toString(),
                                StructuredName.CONTENT_ITEM_TYPE,
                                Phone.CONTENT_ITEM_TYPE,
                                Email.CONTENT_ITEM_TYPE,
                                Photo.CONTENT_ITEM_TYPE,
                                Organization.CONTENT_ITEM_TYPE,
                                Im.CONTENT_ITEM_TYPE,
                                Nickname.CONTENT_ITEM_TYPE,
                                Note.CONTENT_ITEM_TYPE,
                                StructuredPostal.CONTENT_ITEM_TYPE,
                                Website.CONTENT_ITEM_TYPE,
                                Event.CONTENT_ITEM_TYPE,
                                Relation.CONTENT_ITEM_TYPE,
                                SipAddress.CONTENT_ITEM_TYPE))
        ))
        insertDataRows(batch)
        batch.commit()
@@ -732,6 +749,7 @@ open class AndroidContact(
                types.contains(Contact.PHONE_TYPE_MMS) ->
                    typeCode = Phone.TYPE_MMS

                types.contains(Contact.PHONE_TYPE_OTHER) ||
                types.contains(TelephoneType.VOICE) ||
                types.contains(TelephoneType.TEXT) -> {}

@@ -768,7 +786,10 @@ open class AndroidContact(
    protected open fun insertEmail(batch: BatchOperation, labeledEmail: LabeledProperty<ezvcard.property.Email>) {
        val email = labeledEmail.property

        // drop TYPE=internet and TYPE=x400 because Android only knows Internet email addresses
        // drop TYPE=other for compatibility, too (non-standard type which is only used by some clients and not useful as an explicit value)
        val types = email.types
        types.removeAll(arrayOf(EmailType.INTERNET, EmailType.X400, Contact.EMAIL_TYPE_OTHER))

        // preferred email address?
        var pref: Int? = null
@@ -795,7 +816,7 @@ open class AndroidContact(
                    EmailType.WORK -> typeCode = Email.TYPE_WORK
                    Contact.EMAIL_TYPE_MOBILE -> typeCode = Email.TYPE_MOBILE
                }
            if (typeCode == 0) {
            if (typeCode == 0) {    // we still didn't find a known type
                if (email.types.isEmpty())
                    typeCode = Email.TYPE_OTHER
                else {
@@ -869,7 +890,6 @@ open class AndroidContact(

        var typeCode: Int = Im.TYPE_OTHER
        var typeLabel: String? = null

        if (labeledImpp.label != null) {
            typeCode = Im.TYPE_CUSTOM
            typeLabel = labeledImpp.label
@@ -1041,22 +1061,23 @@ open class AndroidContact(
            formattedAddress = lines.joinToString("\n")
        }

        val types = address.types
        var typeCode = StructuredPostal.TYPE_OTHER
        var typeLabel: String? = null
        if (labeledAddress.label != null) {
            typeCode = StructuredPostal.TYPE_CUSTOM
            typeLabel = labeledAddress.label
        } else {
            for (type in address.types)
                when (type) {
                    AddressType.HOME -> typeCode = StructuredPostal.TYPE_HOME
                    AddressType.WORK -> typeCode = StructuredPostal.TYPE_WORK
                }
            if (typeCode == StructuredPostal.TYPE_OTHER && address.types.isNotEmpty()) {
            when {
                types.contains(AddressType.HOME) -> typeCode = StructuredPostal.TYPE_HOME
                types.contains(AddressType.WORK) -> typeCode = StructuredPostal.TYPE_WORK
                types.contains(Contact.ADDRESS_TYPE_OTHER) -> {}
                types.isNotEmpty() -> {
                    typeCode = StructuredPostal.TYPE_CUSTOM
                    typeLabel = xNameToLabel(address.types.first().value)
                }
            }
        }

        val op: BatchOperation.Operation
        val builder = ContentProviderOperation.newInsert(dataSyncURI())
+9 −0
Original line number Diff line number Diff line
@@ -11,6 +11,7 @@ package foundation.e.vcard4android
import ezvcard.Ezvcard
import ezvcard.VCard
import ezvcard.VCardVersion
import ezvcard.parameter.AddressType
import ezvcard.parameter.EmailType
import ezvcard.parameter.ImageType
import ezvcard.parameter.TelephoneType
@@ -90,8 +91,16 @@ class Contact {
        val PHONE_TYPE_RADIO = TelephoneType.get("x-radio")!!
        val PHONE_TYPE_ASSISTANT = TelephoneType.get("X-assistant")!!
        val PHONE_TYPE_MMS = TelephoneType.get("x-mms")!!
        /** Sometimes used to denote an "other" phone numbers. Only for compatibility – don't use it yourself! */
        val PHONE_TYPE_OTHER = TelephoneType.get("other")!!

        /** Custom email type to denote "mobile" email addresses. */
        val EMAIL_TYPE_MOBILE = EmailType.get("x-mobile")!!
        /** Sometimes used to denote an "other" email address. Only for compatibility – don't use it yourself! */
        val EMAIL_TYPE_OTHER = EmailType.get("other")!!

        /** Sometimes used to denote an "other" postal address. Only for compatibility – don't use it yourself! */
        val ADDRESS_TYPE_OTHER = AddressType.get("other")!!

        const val NICKNAME_TYPE_MAIDEN_NAME = "x-maiden-name"
        const val NICKNAME_TYPE_SHORT_NAME = "x-short-name"