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

Unverified Commit 22656023 authored by Sunik Kupfer's avatar Sunik Kupfer Committed by GitHub
Browse files

Collection list refresh: Don't update fetched homesets (#1222)



* Collection list refresh: Don't update home sets that have been fetched already

* Expand testDiscoverHomesets for personal flag

* Add comment

* Rename property; Update its kdoc

* Make class properties function params

* Extract home set class and property definitions for home set discovery

* Pull out HomeSetClassName and property names

* Minor KDoc changes

* Move collection and principal query properties

* Make properties private

* Make collectionProperties service-specific; drop unused SupportedAddressData

---------

Co-authored-by: default avatarRicki Hirner <hirner@bitfire.at>
parent 6a08497b
Loading
Loading
Loading
Loading
+69 −33
Original line number Diff line number Diff line
@@ -37,24 +37,7 @@ import javax.inject.Inject
@HiltAndroidTest
class CollectionListRefresherTest {

    companion object {
        private const val PATH_CALDAV = "/caldav"
        private const val PATH_CARDDAV = "/carddav"

        private const val SUBPATH_PRINCIPAL = "/principal"
        private const val SUBPATH_PRINCIPAL_INACCESSIBLE = "/inaccessible-principal"
        private const val SUBPATH_PRINCIPAL_WITHOUT_COLLECTIONS = "/principal2"
        private const val SUBPATH_ADDRESSBOOK_HOMESET = "/addressbooks-homeset"
        private const val SUBPATH_ADDRESSBOOK_HOMESET_EMPTY = "/addressbooks-homeset-empty"
        private const val SUBPATH_ADDRESSBOOK = "/addressbooks/my-contacts"
        private const val SUBPATH_ADDRESSBOOK_INACCESSIBLE = "/addressbooks/inaccessible-contacts"
    }

    @get:Rule
    var hiltRule = HiltAndroidRule(this)

    @Inject
    @ApplicationContext
    @Inject @ApplicationContext
    lateinit var context: Context

    @Inject
@@ -69,6 +52,9 @@ class CollectionListRefresherTest {
    @Inject
    lateinit var settings: SettingsManager

    @get:Rule
    var hiltRule = HiltAndroidRule(this)

    private val mockServer = MockWebServer()
    private lateinit var client: HttpClient

@@ -100,9 +86,23 @@ class CollectionListRefresherTest {
        // Query home sets
        refresherFactory.create(service, client.okHttpClient).discoverHomesets(baseUrl)

        // Check home sets have been saved to database
        assertEquals(mockServer.url("$PATH_CARDDAV$SUBPATH_ADDRESSBOOK_HOMESET/"), db.homeSetDao().getByService(service.id).first().url)
        assertEquals(1, db.homeSetDao().getByService(service.id).size)
        // Check home set has been saved correctly to database
        val savedHomesets = db.homeSetDao().getByService(service.id)
        assertEquals(2, savedHomesets.size)

        // Home set from current-user-principal
        val personalHomeset = savedHomesets[1]
        assertEquals(mockServer.url("$PATH_CARDDAV$SUBPATH_ADDRESSBOOK_HOMESET_PERSONAL/"), personalHomeset.url)
        assertEquals(service.id, personalHomeset.serviceId)
        // personal should be true for homesets detected at first query of current-user-principal (Even if they occur in a group principal as well!!!)
        assertEquals(true, personalHomeset.personal)

        // Home set found in a group principal
        val groupHomeset = savedHomesets[0]
        assertEquals(mockServer.url("$PATH_CARDDAV$SUBPATH_ADDRESSBOOK_HOMESET_NON_PERSONAL/"), groupHomeset.url)
        assertEquals(service.id, groupHomeset.serviceId)
        // personal should be false for homesets not detected at the first query of current-user-principal (IE. in groups)
        assertEquals(false, groupHomeset.personal)
    }


@@ -114,7 +114,7 @@ class CollectionListRefresherTest {

        // save homeset in DB
        val homesetId = db.homeSetDao().insert(
            HomeSet(id=0, service.id, true, mockServer.url("$PATH_CARDDAV$SUBPATH_ADDRESSBOOK_HOMESET"))
            HomeSet(id=0, service.id, true, mockServer.url("$PATH_CARDDAV$SUBPATH_ADDRESSBOOK_HOMESET_PERSONAL"))
        )

        // Refresh
@@ -248,7 +248,7 @@ class CollectionListRefresherTest {

        // save a homeset in DB
        val homesetId = db.homeSetDao().insert(
            HomeSet(id=0, service.id, true, mockServer.url("$PATH_CARDDAV$SUBPATH_ADDRESSBOOK_HOMESET"))
            HomeSet(id=0, service.id, true, mockServer.url("$PATH_CARDDAV$SUBPATH_ADDRESSBOOK_HOMESET_PERSONAL"))
        )

        // place collection in DB - as part of the homeset
@@ -482,7 +482,7 @@ class CollectionListRefresherTest {
                url = mockServer.url("$PATH_CARDDAV$SUBPATH_ADDRESSBOOK/")
            )
            val homesets = listOf(
                HomeSet(0, service.id, true, mockServer.url("$PATH_CARDDAV$SUBPATH_ADDRESSBOOK_HOMESET"))
                HomeSet(0, service.id, true, mockServer.url("$PATH_CARDDAV$SUBPATH_ADDRESSBOOK_HOMESET_PERSONAL"))
            )

            val refresher = refresherFactory.create(service, client.okHttpClient)
@@ -506,7 +506,7 @@ class CollectionListRefresherTest {
                url = mockServer.url("$PATH_CARDDAV$SUBPATH_ADDRESSBOOK/")
            )
            val homesets = listOf(
                HomeSet(0, service.id, false, mockServer.url("$PATH_CARDDAV$SUBPATH_ADDRESSBOOK_HOMESET"))
                HomeSet(0, service.id, false, mockServer.url("$PATH_CARDDAV$SUBPATH_ADDRESSBOOK_HOMESET_PERSONAL"))
            )

            val refresher = refresherFactory.create(service, client.okHttpClient)
@@ -531,7 +531,7 @@ class CollectionListRefresherTest {
                url = url
            )
            val homesets = listOf(
                HomeSet(0, service.id, false, mockServer.url("$PATH_CARDDAV$SUBPATH_ADDRESSBOOK_HOMESET"))
                HomeSet(0, service.id, false, mockServer.url("$PATH_CARDDAV$SUBPATH_ADDRESSBOOK_HOMESET_PERSONAL"))
            )

            val refresher = refresherFactory.create(service, client.okHttpClient)
@@ -555,7 +555,7 @@ class CollectionListRefresherTest {
                url = mockServer.url("$PATH_CARDDAV$SUBPATH_ADDRESSBOOK/")
            )
            val homesets = listOf(
                HomeSet(0, service.id, false, mockServer.url("$PATH_CARDDAV$SUBPATH_ADDRESSBOOK_HOMESET"))
                HomeSet(0, service.id, false, mockServer.url("$PATH_CARDDAV$SUBPATH_ADDRESSBOOK_HOMESET_PERSONAL"))
            )

            val refresher = refresherFactory.create(service, client.okHttpClient)
@@ -579,7 +579,7 @@ class CollectionListRefresherTest {
                url = mockServer.url("$PATH_CARDDAV$SUBPATH_ADDRESSBOOK/")
            )
            val homesets = listOf(
                HomeSet(0, service.id, true, mockServer.url("$PATH_CARDDAV$SUBPATH_ADDRESSBOOK_HOMESET"))
                HomeSet(0, service.id, true, mockServer.url("$PATH_CARDDAV$SUBPATH_ADDRESSBOOK_HOMESET_PERSONAL"))
            )

            val refresher = refresherFactory.create(service, client.okHttpClient)
@@ -604,7 +604,7 @@ class CollectionListRefresherTest {
                url = collectionUrl
            )
            val homesets = listOf(
                HomeSet(0, service.id, true, mockServer.url("$PATH_CARDDAV$SUBPATH_ADDRESSBOOK_HOMESET"))
                HomeSet(0, service.id, true, mockServer.url("$PATH_CARDDAV$SUBPATH_ADDRESSBOOK_HOMESET_PERSONAL"))
            )

            val refresher = refresherFactory.create(service, client.okHttpClient)
@@ -620,6 +620,20 @@ class CollectionListRefresherTest {
        return db.serviceDao().get(serviceId)
    }

    companion object {
        private const val PATH_CALDAV = "/caldav"
        private const val PATH_CARDDAV = "/carddav"

        private const val SUBPATH_PRINCIPAL = "/principal"
        private const val SUBPATH_PRINCIPAL_INACCESSIBLE = "/inaccessible-principal"
        private const val SUBPATH_PRINCIPAL_WITHOUT_COLLECTIONS = "/principal2"
        private const val SUBPATH_GROUPPRINCIPAL_0 = "/groups/0"
        private const val SUBPATH_ADDRESSBOOK_HOMESET_PERSONAL = "/addressbooks-homeset"
        private const val SUBPATH_ADDRESSBOOK_HOMESET_NON_PERSONAL = "/addressbooks-homeset-non-personal"
        private const val SUBPATH_ADDRESSBOOK_HOMESET_EMPTY = "/addressbooks-homeset-empty"
        private const val SUBPATH_ADDRESSBOOK = "/addressbooks/my-contacts"
        private const val SUBPATH_ADDRESSBOOK_INACCESSIBLE = "/addressbooks/inaccessible-contacts"
    }

    class TestDispatcher(
        private val logger: Logger
@@ -640,8 +654,11 @@ class CollectionListRefresherTest {
                        "<resourcetype><principal/></resourcetype>" +
                        "<displayname>Mr. Wobbles</displayname>" +
                        "<CARD:addressbook-home-set>" +
                        "   <href>${PATH_CARDDAV}${SUBPATH_ADDRESSBOOK_HOMESET}</href>" +
                        "</CARD:addressbook-home-set>"
                        "   <href>${PATH_CARDDAV}${SUBPATH_ADDRESSBOOK_HOMESET_PERSONAL}</href>" +
                        "</CARD:addressbook-home-set>" +
                        "<group-membership>" +
                        "   <href>${PATH_CARDDAV}${SUBPATH_GROUPPRINCIPAL_0}</href>" +
                        "</group-membership>"

                    PATH_CARDDAV + SUBPATH_PRINCIPAL_WITHOUT_COLLECTIONS ->
                        "<CARD:addressbook-home-set>" +
@@ -649,8 +666,16 @@ class CollectionListRefresherTest {
                        "</CARD:addressbook-home-set>" +
                        "<displayname>Mr. Wobbles Jr.</displayname>"

                    PATH_CARDDAV + SUBPATH_GROUPPRINCIPAL_0 ->
                        "<resourcetype><principal/></resourcetype>" +
                        "<displayname>All address books</displayname>" +
                        "<CARD:addressbook-home-set>" +
                        "   <href>${PATH_CARDDAV}${SUBPATH_ADDRESSBOOK_HOMESET_PERSONAL}</href>" +
                        "   <href>${PATH_CARDDAV}${SUBPATH_ADDRESSBOOK_HOMESET_NON_PERSONAL}</href>" +
                        "</CARD:addressbook-home-set>"

                    PATH_CARDDAV + SUBPATH_ADDRESSBOOK,
                    PATH_CARDDAV + SUBPATH_ADDRESSBOOK_HOMESET ->
                    PATH_CARDDAV + SUBPATH_ADDRESSBOOK_HOMESET_PERSONAL ->
                        "<resourcetype>" +
                        "   <collection/>" +
                        "   <CARD:addressbook/>" +
@@ -661,6 +686,17 @@ class CollectionListRefresherTest {
                        "   <href>${PATH_CARDDAV + SUBPATH_PRINCIPAL}</href>" +
                        "</owner>"

                    PATH_CARDDAV + SUBPATH_ADDRESSBOOK_HOMESET_NON_PERSONAL ->
                        "<resourcetype>" +
                        "   <collection/>" +
                        "   <CARD:addressbook/>" +
                        "</resourcetype>" +
                        "<displayname>Freds Contacts (not mine)</displayname>" +
                        "<CARD:addressbook-description>Not personal contacts</CARD:addressbook-description>" +
                        "<owner>" +
                        "   <href>${PATH_CARDDAV + SUBPATH_PRINCIPAL}</href>" + // OK, user is allowed to own non-personal contacts
                        "</owner>"

                    PATH_CALDAV + SUBPATH_PRINCIPAL ->
                        "<CAL:calendar-user-address-set>" +
                        "  <href>urn:unknown-entry</href>" +
@@ -676,7 +712,7 @@ class CollectionListRefresherTest {
                var responseBody = ""
                var responseCode = 207
                when (path) {
                    PATH_CARDDAV + SUBPATH_ADDRESSBOOK_HOMESET ->
                    PATH_CARDDAV + SUBPATH_ADDRESSBOOK_HOMESET_PERSONAL ->
                        responseBody =
                            "<multistatus xmlns='DAV:' xmlns:CARD='urn:ietf:params:xml:ns:carddav' xmlns:CAL='urn:ietf:params:xml:ns:caldav'>" +
                            "<response>" +
+3 −0
Original line number Diff line number Diff line
@@ -15,6 +15,9 @@ import at.bitfire.dav4jvm.property.webdav.ResourceType
import at.bitfire.davdroid.util.trimToNull
import okhttp3.HttpUrl

/**
 * A principal entity representing a WebDAV principal (rfc3744).
 */
@Entity(tableName = "principal",
    foreignKeys = [
        ForeignKey(entity = Service::class, parentColumns = arrayOf("id"), childColumns = arrayOf("serviceId"), onDelete = ForeignKey.CASCADE)
+115 −49
Original line number Diff line number Diff line
@@ -9,10 +9,19 @@ import at.bitfire.dav4jvm.Property
import at.bitfire.dav4jvm.Response
import at.bitfire.dav4jvm.UrlUtils
import at.bitfire.dav4jvm.exception.HttpException
import at.bitfire.dav4jvm.property.caldav.CalendarColor
import at.bitfire.dav4jvm.property.caldav.CalendarDescription
import at.bitfire.dav4jvm.property.caldav.CalendarHomeSet
import at.bitfire.dav4jvm.property.caldav.CalendarProxyReadFor
import at.bitfire.dav4jvm.property.caldav.CalendarProxyWriteFor
import at.bitfire.dav4jvm.property.caldav.CalendarTimezone
import at.bitfire.dav4jvm.property.caldav.CalendarTimezoneId
import at.bitfire.dav4jvm.property.caldav.Source
import at.bitfire.dav4jvm.property.caldav.SupportedCalendarComponentSet
import at.bitfire.dav4jvm.property.carddav.AddressbookDescription
import at.bitfire.dav4jvm.property.carddav.AddressbookHomeSet
import at.bitfire.dav4jvm.property.push.PushTransports
import at.bitfire.dav4jvm.property.push.Topic
import at.bitfire.dav4jvm.property.webdav.CurrentUserPrivilegeSet
import at.bitfire.dav4jvm.property.webdav.DisplayName
import at.bitfire.dav4jvm.property.webdav.GroupMembership
@@ -55,68 +64,120 @@ class CollectionListRefresher @AssistedInject constructor(
        fun create(service: Service, httpClient: OkHttpClient): CollectionListRefresher
    }


    private val alreadyQueried = mutableSetOf<HttpUrl>()

    /**
     * Starting at current-user-principal URL, tries to recursively find and save all user relevant home sets.
     *
     *
     * @param principalUrl  URL of principal to query (user-provided principal or current-user-principal)
     * @param level         Current recursion level (limited to 0, 1 or 2):
     *
     * - 0: We assume found home sets belong to the current-user-principal
     * - 1 or 2: We assume found home sets don't directly belong to the current-user-principal
     *
     * @throws java.io.IOException
     * @throws HttpException
     * @throws at.bitfire.dav4jvm.exception.DavException
     * Principal properties to ask the server for.
     */
    internal fun discoverHomesets(principalUrl: HttpUrl, level: Int = 0) {
        logger.fine("Discovering homesets of $principalUrl")
        val relatedResources = mutableSetOf<HttpUrl>()
    private val principalProperties = arrayOf(
        DisplayName.NAME,
        ResourceType.NAME
    )

        // Define homeset class and properties to look for
        val homeSetClass: Class<out HrefListProperty>
        val properties: Array<Property.Name>
    /**
     * Home-set class to use depending on the given service type.
     */
    private val homeSetClass: Class<out HrefListProperty> =
        when (service.type) {
            Service.TYPE_CARDDAV -> {
                homeSetClass = AddressbookHomeSet::class.java
                properties = arrayOf(DisplayName.NAME, AddressbookHomeSet.NAME, GroupMembership.NAME, ResourceType.NAME)
            Service.TYPE_CARDDAV -> AddressbookHomeSet::class.java
            Service.TYPE_CALDAV -> CalendarHomeSet::class.java
            else -> throw IllegalArgumentException()
        }
            Service.TYPE_CALDAV -> {
                homeSetClass = CalendarHomeSet::class.java
                properties = arrayOf(

    /**
     * Home-set properties to ask for in a PROPFIND request to the principal URL,
     * depending on the given service type.
     */
    private val homeSetProperties: Array<Property.Name> =
        arrayOf(                        // generic WebDAV properties
            DisplayName.NAME,
                    CalendarHomeSet.NAME,
                    CalendarProxyReadFor.NAME,
                    CalendarProxyWriteFor.NAME,
            GroupMembership.NAME,
            ResourceType.NAME
        ) + when (service.type) {       // service-specific CalDAV/CardDAV properties
                Service.TYPE_CARDDAV -> arrayOf(
                    AddressbookHomeSet.NAME,
                )
                Service.TYPE_CALDAV -> arrayOf(
                    CalendarHomeSet.NAME,
                    CalendarProxyReadFor.NAME,
                    CalendarProxyWriteFor.NAME
                )
                else -> throw IllegalArgumentException()
            }

    /**
     * Collection properties to ask for in a PROPFIND request on a collection.
     */
    private val collectionProperties: Array<Property.Name> =
        arrayOf(                        // generic WebDAV properties
            CurrentUserPrivilegeSet.NAME,
            DisplayName.NAME,
            Owner.NAME,
            ResourceType.NAME,
            PushTransports.NAME,        // WebDAV-Push
            Topic.NAME
        ) + when (service.type) {       // service-specific CalDAV/CardDAV properties
            Service.TYPE_CARDDAV -> arrayOf(
                AddressbookDescription.NAME
            )
            Service.TYPE_CALDAV -> arrayOf(
                CalendarColor.NAME,
                CalendarDescription.NAME,
                CalendarTimezone.NAME,
                CalendarTimezoneId.NAME,
                SupportedCalendarComponentSet.NAME,
                Source.NAME
            )
            else -> throw IllegalArgumentException()
        }



    /**
     * Starting at given principal URL, tries to recursively find and save all user relevant home sets.
     *
     * @param principalUrl              URL of principal to query (user-provided principal or current-user-principal)
     * @param level                     Current recursion level (limited to 0, 1 or 2):
     *   - 0: We assume found home sets belong to the current-user-principal
     *   - 1 or 2: We assume found home sets don't directly belong to the current-user-principal
     * @param alreadyQueriedPrincipals  The HttpUrls of principals which have been queried already, to avoid querying principals more than once.
     * @param alreadySavedHomeSets      The HttpUrls of home sets which have been saved to database already, to avoid saving home sets
     * more than once, which could overwrite the already set "personal" flag with `false`.
     *
     * @throws java.io.IOException                          on I/O errors
     * @throws HttpException                                on HTTP errors
     * @throws at.bitfire.dav4jvm.exception.DavException    on application-level or logical errors
     */
    internal fun discoverHomesets(
        principalUrl: HttpUrl,
        level: Int = 0,
        alreadyQueriedPrincipals: MutableSet<HttpUrl> = mutableSetOf(),
        alreadySavedHomeSets: MutableSet<HttpUrl> = mutableSetOf()
    ) {
        logger.fine("Discovering homesets of $principalUrl")
        val relatedResources = mutableSetOf<HttpUrl>()

        // Query the URL
        val principal = DavResource(httpClient, principalUrl)
        val personal = level == 0
        try {
            principal.propfind(0, *properties) { davResponse, _ ->
                alreadyQueried += davResponse.href
            principal.propfind(0, *homeSetProperties) { davResponse, _ ->
                alreadyQueriedPrincipals += davResponse.href

                // If response holds home sets, save them
                davResponse[homeSetClass]?.let { homeSets ->
                    for (homeSetHref in homeSets.hrefs)
                        principal.location.resolve(homeSetHref)?.let { homesetUrl ->
                            val resolvedHomeSetUrl = UrlUtils.withTrailingSlash(homesetUrl)
                            // Homeset is considered personal if this is the outer recursion call,
                            if (!alreadySavedHomeSets.contains(resolvedHomeSetUrl)) {
                                homeSetRepository.insertOrUpdateByUrl(
                                    // HomeSet is considered personal if this is the outer recursion call,
                                    // This is because we assume the first call to query the current-user-principal
                                    // Note: This is not be be confused with the DAV:owner attribute. Home sets can be owned by
                            // other principals and still be considered "personal" (belonging to the current-user-principal).
                            homeSetRepository.insertOrUpdateByUrl(
                                    // other principals while still being considered "personal" (belonging to the current-user-principal)
                                    // and an owned home set need not always be personal either.
                                    HomeSet(0, service.id, personal, resolvedHomeSetUrl)
                                )
                                alreadySavedHomeSets += resolvedHomeSetUrl
                            }
                        }
                }

@@ -158,10 +219,15 @@ class CollectionListRefresher @AssistedInject constructor(
        // query related resources
        if (level <= 1)
            for (resource in relatedResources)
                if (alreadyQueried.contains(resource))
                if (alreadyQueriedPrincipals.contains(resource))
                    logger.warning("$resource already queried, skipping")
                else
                    discoverHomesets(resource, level + 1)
                    discoverHomesets(
                        principalUrl = resource,
                        level = level + 1,
                        alreadyQueriedPrincipals = alreadyQueriedPrincipals,
                        alreadySavedHomeSets = alreadySavedHomeSets
                    )
    }

    /**
@@ -186,7 +252,7 @@ class CollectionListRefresher @AssistedInject constructor(
                .toMutableMap()

            try {
                DavResource(httpClient, homeSetUrl).propfind(1, *RefreshCollectionsWorker.DAV_COLLECTION_PROPERTIES) { response, relation ->
                DavResource(httpClient, homeSetUrl).propfind(1, *collectionProperties) { response, relation ->
                    // Note: This callback may be called multiple times ([MultiResponseCallback])
                    if (!response.isSuccess())
                        return@propfind
@@ -241,7 +307,7 @@ class CollectionListRefresher @AssistedInject constructor(
    internal fun refreshHomelessCollections() {
        val homelessCollections = db.collectionDao().getByServiceAndHomeset(service.id, null).associateBy { it.url }.toMutableMap()
        for((url, localCollection) in homelessCollections) try {
            DavResource(httpClient, url).propfind(0, *RefreshCollectionsWorker.DAV_COLLECTION_PROPERTIES) { response, _ ->
            DavResource(httpClient, url).propfind(0, *collectionProperties) { response, _ ->
                if (!response.isSuccess()) {
                    collectionRepository.delete(localCollection)
                    return@propfind
@@ -281,7 +347,7 @@ class CollectionListRefresher @AssistedInject constructor(
            val principalUrl = oldPrincipal.url
            logger.fine("Querying principal $principalUrl")
            try {
                DavResource(httpClient, principalUrl).propfind(0, *RefreshCollectionsWorker.DAV_PRINCIPAL_PROPERTIES) { response, _ ->
                DavResource(httpClient, principalUrl).propfind(0, *principalProperties) { response, _ ->
                    if (!response.isSuccess())
                        return@propfind
                    Principal.fromDavResponse(service.id, response)?.let { principal ->
@@ -321,10 +387,10 @@ class CollectionListRefresher @AssistedInject constructor(
     * [Settings.PRESELECT_COLLECTIONS_EXCLUDED], in which case *false* is returned.
     *
     * @param collection the collection to check
     * @param homesets list of home-sets (to check whether collection is in a personal home-set)
     * @param homeSets list of home-sets (to check whether collection is in a personal home-set)
     * @return *true* if the collection should be preselected for synchronization; *false* otherwise
     */
    internal fun shouldPreselect(collection: Collection, homesets: Iterable<HomeSet>): Boolean {
    internal fun shouldPreselect(collection: Collection, homeSets: Iterable<HomeSet>): Boolean {
        val shouldPreselect = settings.getIntOrNull(Settings.PRESELECT_COLLECTIONS)

        val excluded by lazy {
@@ -342,7 +408,7 @@ class CollectionListRefresher @AssistedInject constructor(

            Settings.PRESELECT_COLLECTIONS_PERSONAL ->
                // preselect if is personal (in a personal home-set), but not excluded
                homesets
                homeSets
                    .filter { homeset -> homeset.personal }
                    .map { homeset -> homeset.id }
                    .contains(collection.homeSetId)
+0 −35
Original line number Diff line number Diff line
@@ -22,25 +22,10 @@ import androidx.work.WorkInfo
import androidx.work.WorkManager
import androidx.work.WorkerParameters
import at.bitfire.dav4jvm.exception.UnauthorizedException
import at.bitfire.dav4jvm.property.caldav.CalendarColor
import at.bitfire.dav4jvm.property.caldav.CalendarDescription
import at.bitfire.dav4jvm.property.caldav.CalendarTimezone
import at.bitfire.dav4jvm.property.caldav.CalendarTimezoneId
import at.bitfire.dav4jvm.property.caldav.Source
import at.bitfire.dav4jvm.property.caldav.SupportedCalendarComponentSet
import at.bitfire.dav4jvm.property.carddav.AddressbookDescription
import at.bitfire.dav4jvm.property.carddav.SupportedAddressData
import at.bitfire.dav4jvm.property.push.PushTransports
import at.bitfire.dav4jvm.property.push.Topic
import at.bitfire.dav4jvm.property.webdav.CurrentUserPrivilegeSet
import at.bitfire.dav4jvm.property.webdav.DisplayName
import at.bitfire.dav4jvm.property.webdav.Owner
import at.bitfire.dav4jvm.property.webdav.ResourceType
import at.bitfire.davdroid.InvalidAccountException
import at.bitfire.davdroid.R
import at.bitfire.davdroid.network.HttpClient
import at.bitfire.davdroid.repository.DavServiceRepository
import at.bitfire.davdroid.servicedetection.RefreshCollectionsWorker.Companion.ARG_SERVICE_ID
import at.bitfire.davdroid.settings.AccountSettings
import at.bitfire.davdroid.ui.DebugInfoActivity
import at.bitfire.davdroid.ui.NotificationRegistry
@@ -87,26 +72,6 @@ class RefreshCollectionsWorker @AssistedInject constructor(
        const val ARG_SERVICE_ID = "serviceId"
        const val WORKER_TAG = "refreshCollectionsWorker"

        // Collection properties to ask for in a propfind request to the CalDAV/CardDAV server
        val DAV_COLLECTION_PROPERTIES = arrayOf(
            ResourceType.NAME,
            CurrentUserPrivilegeSet.NAME,
            DisplayName.NAME,
            Owner.NAME,
            AddressbookDescription.NAME, SupportedAddressData.NAME,
            CalendarDescription.NAME, CalendarColor.NAME, CalendarTimezone.NAME, CalendarTimezoneId.NAME, SupportedCalendarComponentSet.NAME,
            Source.NAME,
            // WebDAV Push
            PushTransports.NAME,
            Topic.NAME
        )

        // Principal properties to ask the server
        val DAV_PRINCIPAL_PROPERTIES = arrayOf(
            DisplayName.NAME,
            ResourceType.NAME
        )

        /**
         * Uniquely identifies a refresh worker. Useful for stopping work, or querying its state.
         *