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

Commit 6415355a authored by Ricki Hirner's avatar Ricki Hirner
Browse files

Correctly handle EMAIL reminders

parent 95898395
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -29,8 +29,7 @@ class TestCalendar(
                val values = ContentValues(3)
                values.put(CalendarContract.Calendars.NAME, "TestCalendar")
                values.put(CalendarContract.Calendars.CALENDAR_DISPLAY_NAME, "ical4android Test Calendar")
                values.put(CalendarContract.Calendars.ALLOWED_REMINDERS,
                        CalendarContract.Reminders.METHOD_DEFAULT)
                values.put(CalendarContract.Calendars.ALLOWED_REMINDERS, CalendarContract.Reminders.METHOD_DEFAULT)
                val uri = AndroidCalendar.create(account, provider, values)

                TestCalendar(account, provider, ContentUris.parseId(uri))
+13 −6
Original line number Diff line number Diff line
@@ -13,7 +13,6 @@ import android.content.ContentProviderClient
import android.content.ContentUris
import android.content.ContentValues
import android.net.Uri
import android.provider.CalendarContract
import android.provider.CalendarContract.*
import at.bitfire.ical4android.MiscUtils.CursorHelper.toValues
import java.io.FileNotFoundException
@@ -30,18 +29,28 @@ abstract class AndroidCalendar<out T: AndroidEvent>(
        val provider: ContentProviderClient,
        val eventFactory: AndroidEventFactory<T>,

        /** the calendar ID ([CalendarContract.Calendars._ID]) **/
        /** the calendar ID ([Calendars._ID]) **/
        val id: Long
) {

    companion object {

        /**
         * Recommended initial values when creating Android [Calendars].
         */
        val calendarBaseValues = ContentValues(3)
        init {
            calendarBaseValues.put(Calendars.ALLOWED_AVAILABILITY, "${Events.AVAILABILITY_BUSY},${Events.AVAILABILITY_FREE},${Events.AVAILABILITY_TENTATIVE}")
            calendarBaseValues.put(Calendars.ALLOWED_ATTENDEE_TYPES, "${Attendees.TYPE_NONE},${Attendees.TYPE_OPTIONAL},${Attendees.TYPE_REQUIRED},${Attendees.TYPE_RESOURCE}")
            calendarBaseValues.put(Calendars.ALLOWED_REMINDERS, "${Reminders.METHOD_DEFAULT},${Reminders.METHOD_ALERT},${Reminders.METHOD_EMAIL}")
        }

        /**
         * Creates a local (Android calendar provider) calendar.
         *
         * @param account       account which the calendar should be assigned to
         * @param provider      client for Android calendar provider
         * @param info          initial calendar properties ([Calendars.CALENDAR_DISPLAY_NAME] etc.)
         * @param info          initial calendar properties ([Calendars.CALENDAR_DISPLAY_NAME] etc.) – *may be modified by this method*
         *
         * @return              [Uri] of the created calendar
         *
@@ -51,9 +60,7 @@ abstract class AndroidCalendar<out T: AndroidEvent>(
            info.put(Calendars.ACCOUNT_NAME, account.name)
            info.put(Calendars.ACCOUNT_TYPE, account.type)

            // these values are generated by ical4android
            info.put(Calendars.ALLOWED_AVAILABILITY, "${Events.AVAILABILITY_BUSY},${Events.AVAILABILITY_FREE},${Events.AVAILABILITY_TENTATIVE}")
            info.put(Calendars.ALLOWED_ATTENDEE_TYPES, "${Attendees.TYPE_NONE},${Attendees.TYPE_OPTIONAL},${Attendees.TYPE_REQUIRED},${Attendees.TYPE_RESOURCE}")
            info.putAll(calendarBaseValues)

            Constants.log.info("Creating local calendar: $info")
            return provider.insert(syncAdapterURI(Calendars.CONTENT_URI, account), info) ?:
+27 −8
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@ import android.net.Uri
import android.os.RemoteException
import android.provider.CalendarContract.*
import android.util.Base64
import android.util.Patterns
import at.bitfire.ical4android.MiscUtils.CursorHelper.toValues
import net.fortuna.ical4j.model.*
import net.fortuna.ical4j.model.Date
@@ -310,15 +311,30 @@ abstract class AndroidEvent(
        val alarm = VAlarm(Dur(0, 0, -row.getAsInteger(Reminders.MINUTES), 0))

        val props = alarm.properties
        props += when (row.getAsInteger(Reminders.METHOD)) {
            Reminders.METHOD_EMAIL,
            Reminders.METHOD_SMS ->
                Action.EMAIL
            else ->
                // show alarm by default
                Action.DISPLAY
        when (row.getAsInteger(Reminders.METHOD)) {
            Reminders.METHOD_EMAIL -> {
                val accountName = calendar.account.name
                if (Patterns.EMAIL_ADDRESS.matcher(accountName).matches()) {
                    props += Action.EMAIL
                    // ACTION:EMAIL requires SUMMARY, DESCRIPTION, ATTENDEE
                    props += Summary(event.summary)
                    props += Description(event.description ?: event.summary)
                    // Android doesn't allow to save email reminder recipients, so we always use the
                    // account name (should be account owner's email address)
                    props += Attendee(URI("mailto", calendar.account.name, null))
                } else {
                    Constants.log.warning("Account name is not an email address; changing EMAIL reminder to DISPLAY")
                    props += Action.DISPLAY
                    props += Description(event.summary)
                }
            }

            // default: set ACTION:DISPLAY (requires DESCRIPTION)
            else -> {
                props += Action.DISPLAY
                props += Description(event.summary)
            }
        }
        event.alarms += alarm
    }

@@ -622,7 +638,10 @@ abstract class AndroidEvent(
        val method = when (alarm.action?.value?.toUpperCase(Locale.US)) {
            Action.DISPLAY.value,
            Action.AUDIO.value -> Reminders.METHOD_ALERT

            // Note: The calendar provider doesn't support saving specific attendees for email reminders.
            Action.EMAIL.value -> Reminders.METHOD_EMAIL

            else               -> Reminders.METHOD_DEFAULT
        }