Skip to content
This repository was archived by the owner on Jun 9, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class AndroidAddressBookTest {
@ClassRule
val permissionRule = GrantPermissionRule.grant(Manifest.permission.READ_CONTACTS, Manifest.permission.WRITE_CONTACTS)!!

private val testAccount = Account("AndroidAddressBookTest", "at.bitfire.vcard4android")
private val testAddressBookAccount = Account("AndroidAddressBookTest", "at.bitfire.vcard4android")
private lateinit var provider: ContentProviderClient

@BeforeClass
Expand All @@ -44,7 +44,7 @@ class AndroidAddressBookTest {

@Test
fun testSettings() {
val addressBook = TestAddressBook(testAccount, provider)
val addressBook = TestAddressBook(testAddressBookAccount, provider)

var values = ContentValues()
values.put(ContactsContract.Settings.SHOULD_SYNC, false)
Expand All @@ -65,7 +65,7 @@ class AndroidAddressBookTest {

@Test
fun testSyncState() {
val addressBook = TestAddressBook(testAccount, provider)
val addressBook = TestAddressBook(testAddressBookAccount, provider)

addressBook.syncState = ByteArray(0)
assertEquals(0, addressBook.syncState!!.size)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class AndroidContactTest {
@ClassRule
val permissionRule = GrantPermissionRule.grant(Manifest.permission.READ_CONTACTS, Manifest.permission.WRITE_CONTACTS)!!

private val testAccount = Account("AndroidContactTest", "at.bitfire.vcard4android")
private val testAddressBookAccount = Account("AndroidContactTest", "at.bitfire.vcard4android")

private lateinit var provider: ContentProviderClient
private lateinit var addressBook: TestAddressBook
Expand All @@ -47,7 +47,7 @@ class AndroidContactTest {
provider = context.contentResolver.acquireContentProviderClient(ContactsContract.AUTHORITY)!!
assertNotNull(provider)

addressBook = TestAddressBook(testAccount, provider)
addressBook = TestAddressBook(testAddressBookAccount, provider)
}

@BeforeClass
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class AndroidGroupTest {
@ClassRule
val permissionRule = GrantPermissionRule.grant(Manifest.permission.READ_CONTACTS, Manifest.permission.WRITE_CONTACTS)!!

private val testAccount = Account("AndroidContactGroupTest", "at.bitfire.vcard4android")
private val testAddressBookAccount = Account("AndroidContactGroupTest", "at.bitfire.vcard4android")

private lateinit var provider: ContentProviderClient
private lateinit var addressBook: TestAddressBook
Expand All @@ -36,7 +36,7 @@ class AndroidGroupTest {
provider = context.contentResolver.acquireContentProviderClient(ContactsContract.AUTHORITY)!!
assertNotNull(provider)

addressBook = TestAddressBook(testAccount, provider)
addressBook = TestAddressBook(testAddressBookAccount, provider)
}

@BeforeClass
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class PhotoBuilderTest {
@ClassRule
val permissionRule = GrantPermissionRule.grant(Manifest.permission.READ_CONTACTS, Manifest.permission.WRITE_CONTACTS)!!

private val testAccount = Account("AndroidContactTest", "at.bitfire.vcard4android")
private val testAddressBookAccount = Account("AndroidContactTest", "at.bitfire.vcard4android")

val testContext = InstrumentationRegistry.getInstrumentation().context
private lateinit var provider: ContentProviderClient
Expand All @@ -43,7 +43,7 @@ class PhotoBuilderTest {
provider = testContext.contentResolver.acquireContentProviderClient(ContactsContract.AUTHORITY)!!
assertNotNull(provider)

addressBook = TestAddressBook(testAccount, provider)
addressBook = TestAddressBook(testAddressBookAccount, provider)
}

@BeforeClass
Expand Down Expand Up @@ -82,7 +82,7 @@ class PhotoBuilderTest {

try {
val photo = TestUtils.resourceToByteArray("/large.jpg")
val photoUri = PhotoBuilder.insertPhoto(provider, testAccount, rawContactId, photo)
val photoUri = PhotoBuilder.insertPhoto(provider, testAddressBookAccount, rawContactId, photo)
assertNotNull(photoUri)

// the photo is processed and often resized by the contacts provider
Expand Down Expand Up @@ -114,7 +114,7 @@ class PhotoBuilderTest {
val contact = AndroidContact(addressBook, Contact().apply { displayName = "Contact with photo" }, null, null)
contact.add()
try {
assertNull(PhotoBuilder.insertPhoto(provider, testAccount, contact.id!!, ByteArray(100) /* invalid photo */))
assertNull(PhotoBuilder.insertPhoto(provider, testAddressBookAccount, contact.id!!, ByteArray(100) /* invalid photo */))
} finally {
contact.delete()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class PhotoHandlerTest {
@ClassRule
val permissionRule = GrantPermissionRule.grant(Manifest.permission.READ_CONTACTS, Manifest.permission.WRITE_CONTACTS)!!

private val testAccount = Account("AndroidContactTest", "at.bitfire.vcard4android")
private val testAddressBookAccount = Account("AndroidContactTest", "at.bitfire.vcard4android")

val testContext = InstrumentationRegistry.getInstrumentation().context
private lateinit var provider: ContentProviderClient
Expand All @@ -44,7 +44,7 @@ class PhotoHandlerTest {
provider = testContext.contentResolver.acquireContentProviderClient(ContactsContract.AUTHORITY)!!
Assert.assertNotNull(provider)

addressBook = TestAddressBook(testAccount, provider)
addressBook = TestAddressBook(testAddressBookAccount, provider)
}

@BeforeClass
Expand Down
22 changes: 11 additions & 11 deletions lib/src/main/kotlin/at/bitfire/vcard4android/AndroidAddressBook.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ import java.io.FileNotFoundException
import java.util.*

open class AndroidAddressBook<T1: AndroidContact, T2: AndroidGroup>(
var account: Account,
val provider: ContentProviderClient?,
protected val contactFactory: AndroidContactFactory<T1>,
protected val groupFactory: AndroidGroupFactory<T2>
var addressBookAccount: Account,
val provider: ContentProviderClient?,
protected val contactFactory: AndroidContactFactory<T1>,
protected val groupFactory: AndroidGroupFactory<T2>
) {

open var readOnly: Boolean = false
Expand All @@ -45,14 +45,14 @@ open class AndroidAddressBook<T1: AndroidContact, T2: AndroidGroup>(
* @throws android.os.RemoteException on content provider errors
*/
set(values) {
values.put(ContactsContract.Settings.ACCOUNT_NAME, account.name)
values.put(ContactsContract.Settings.ACCOUNT_TYPE, account.type)
values.put(ContactsContract.Settings.ACCOUNT_NAME, addressBookAccount.name)
values.put(ContactsContract.Settings.ACCOUNT_TYPE, addressBookAccount.type)
provider!!.insert(syncAdapterURI(ContactsContract.Settings.CONTENT_URI), values)
}

var syncState: ByteArray?
get() = ContactsContract.SyncState.get(provider, account)
set(data) = ContactsContract.SyncState.set(provider, account, data)
get() = ContactsContract.SyncState.get(provider, addressBookAccount)
set(data) = ContactsContract.SyncState.set(provider, addressBookAccount, data)


fun queryContacts(where: String?, whereArgs: Array<String>?): List<T1> {
Expand Down Expand Up @@ -85,7 +85,7 @@ open class AndroidAddressBook<T1: AndroidContact, T2: AndroidGroup>(


fun allGroups(callback: (T2) -> Unit) {
queryGroups("${Groups.ACCOUNT_TYPE}=? AND ${Groups.ACCOUNT_NAME}=?", arrayOf(account.type, account.name)) { group ->
queryGroups("${Groups.ACCOUNT_TYPE}=? AND ${Groups.ACCOUNT_NAME}=?", arrayOf(addressBookAccount.type, addressBookAccount.name)) { group ->
callback(group)
}
}
Expand All @@ -106,8 +106,8 @@ open class AndroidAddressBook<T1: AndroidContact, T2: AndroidGroup>(

fun syncAdapterURI(uri: Uri) = uri.buildUpon()
.appendQueryParameter(ContactsContract.CALLER_IS_SYNCADAPTER, "true")
.appendQueryParameter(RawContacts.ACCOUNT_NAME, account.name)
.appendQueryParameter(RawContacts.ACCOUNT_TYPE, account.type)
.appendQueryParameter(RawContacts.ACCOUNT_NAME, addressBookAccount.name)
.appendQueryParameter(RawContacts.ACCOUNT_TYPE, addressBookAccount.type)
.build()!!

fun rawContactsSyncUri() = syncAdapterURI(RawContacts.CONTENT_URI)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ open class AndroidContact(
id = ContentUris.parseId(resultUri)

getContact().photo?.let { photo ->
PhotoBuilder.insertPhoto(provider, addressBook.account, id!!, photo)
PhotoBuilder.insertPhoto(provider, addressBook.addressBookAccount, id!!, photo)
}

return resultUri
Expand Down Expand Up @@ -158,7 +158,7 @@ open class AndroidContact(
batch.commit()

getContact().photo?.let { photo ->
PhotoBuilder.insertPhoto(provider, addressBook.account, id!!, photo)
PhotoBuilder.insertPhoto(provider, addressBook.addressBookAccount, id!!, photo)
}

return uri
Expand All @@ -177,8 +177,8 @@ open class AndroidContact(
@CallSuper
protected open fun buildContact(builder: BatchOperation.CpoBuilder, update: Boolean) {
if (!update)
builder .withValue(RawContacts.ACCOUNT_NAME, addressBook.account.name)
.withValue(RawContacts.ACCOUNT_TYPE, addressBook.account.type)
builder .withValue(RawContacts.ACCOUNT_NAME, addressBook.addressBookAccount.name)
.withValue(RawContacts.ACCOUNT_TYPE, addressBook.addressBookAccount.type)

builder .withValue(RawContacts.DIRTY, 0)
.withValue(RawContacts.DELETED, 0)
Expand Down
4 changes: 2 additions & 2 deletions lib/src/main/kotlin/at/bitfire/vcard4android/AndroidGroup.kt
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,8 @@ open class AndroidGroup(
*/
fun add(): Uri {
val values = contentValues()
values.put(Groups.ACCOUNT_TYPE, addressBook.account.type)
values.put(Groups.ACCOUNT_NAME, addressBook.account.name)
values.put(Groups.ACCOUNT_TYPE, addressBook.addressBookAccount.type)
values.put(Groups.ACCOUNT_NAME, addressBook.addressBookAccount.name)
values.put(Groups.SHOULD_SYNC, 1)
if (addressBook.readOnly)
values.put(Groups.GROUP_IS_READ_ONLY, 1)
Expand Down
6 changes: 3 additions & 3 deletions lib/src/main/kotlin/at/bitfire/vcard4android/Utils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ object Utils {
fun StructuredName.isEmpty() =
prefixes.isEmpty() && given == null && additionalNames.isEmpty() && family == null && suffixes.isEmpty()

fun Uri.asSyncAdapter(account: Account): Uri = buildUpon()
.appendQueryParameter(ContactsContract.RawContacts.ACCOUNT_NAME, account.name)
.appendQueryParameter(ContactsContract.RawContacts.ACCOUNT_TYPE, account.type)
fun Uri.asSyncAdapter(addressBookAccount: Account): Uri = buildUpon()
.appendQueryParameter(ContactsContract.RawContacts.ACCOUNT_NAME, addressBookAccount.name)
.appendQueryParameter(ContactsContract.RawContacts.ACCOUNT_TYPE, addressBookAccount.type)
.appendQueryParameter(ContactsContract.CALLER_IS_SYNCADAPTER, "true")
.build()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,14 @@ class PhotoBuilder(dataRowUri: Uri, rawContactId: Long?, contact: Contact, readO
* [RawContacts.DIRTY] flag may be set asynchronously by the contacts provider
* as soon as it finishes the operation.
*
* @param provider client to access contacts provider
* @param account account of the contact, used to create sync adapter URIs
* @param rawContactId ID of the raw contact ([RawContacts._ID]])
* @param data contact photo (binary data in a supported format like JPEG or PNG)
* @param provider client to access contacts provider
* @param addressBookAccount account of the contact, used to create sync adapter URIs
* @param rawContactId ID of the raw contact ([RawContacts._ID]])
* @param data contact photo (binary data in a supported format like JPEG or PNG)
*
* @return URI of the raw contact display photo ([Photo.PHOTO_URI]); null if image can't be decoded
*/
fun insertPhoto(provider: ContentProviderClient, account: Account, rawContactId: Long, data: ByteArray): Uri? {
fun insertPhoto(provider: ContentProviderClient, addressBookAccount: Account, rawContactId: Long, data: ByteArray): Uri? {
// verify that data can be decoded by BitmapFactory, so that the contacts provider can process it
val opts = BitmapFactory.Options()
opts.inJustDecodeBounds = true
Expand Down Expand Up @@ -90,7 +90,7 @@ class PhotoBuilder(dataRowUri: Uri, rawContactId: Long?, contact: Contact, readO
// reset dirty flag in any case (however if we didn't wait long enough, the dirty flag will then be set again)
val notDirty = ContentValues(1)
notDirty.put(RawContacts.DIRTY, 0)
val rawContactUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId).asSyncAdapter(account)
val rawContactUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId).asSyncAdapter(addressBookAccount)
provider.update(rawContactUri, notDirty, null, null)

if (photoUri != null)
Expand Down