mirror of
https://github.com/etesync/android
synced 2025-02-18 02:22:08 +00:00
Version bump to 0.7.5
* account settings: show whether CardDAV server supports VCard 4.0 * CardDAV GET: ask for VCard 3.0 or VCard 4.0 (preferred) contacts * CardDAV multiget: ask for VCard 4.0 contacts if the server supports it * CardDAV PUT: send VCard 4.0 contacts if the server supports it * import Apache httpclient-android rev. 1652769 correctly (hopefully fixes #491)
This commit is contained in:
parent
f738f74dea
commit
b5c99265c3
@ -1,62 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2013 – 2015 Ricki Hirner (bitfire web engineering).
|
|
||||||
* All rights reserved. This program and the accompanying materials
|
|
||||||
* are made available under the terms of the GNU Public License v3.0
|
|
||||||
* which accompanies this distribution, and is available at
|
|
||||||
* http://www.gnu.org/licenses/gpl.html
|
|
||||||
*/
|
|
||||||
package at.bitfire.davdroid;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
|
|
||||||
import lombok.Cleanup;
|
|
||||||
import net.fortuna.ical4j.data.ParserException;
|
|
||||||
import android.content.res.AssetManager;
|
|
||||||
import android.test.InstrumentationTestCase;
|
|
||||||
import at.bitfire.davdroid.resource.Contact;
|
|
||||||
import ezvcard.property.Impp;
|
|
||||||
|
|
||||||
public class ContactTest extends InstrumentationTestCase {
|
|
||||||
AssetManager assetMgr;
|
|
||||||
|
|
||||||
public void setUp() {
|
|
||||||
assetMgr = getInstrumentation().getContext().getResources().getAssets();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testIMPP() throws IOException {
|
|
||||||
Contact c = parseVCard("impp.vcf");
|
|
||||||
assertEquals("test mctest", c.getDisplayName());
|
|
||||||
|
|
||||||
Impp jabber = c.getImpps().get(0);
|
|
||||||
assertNull(jabber.getProtocol());
|
|
||||||
assertEquals("test-without-valid-scheme@test.tld", jabber.getHandle());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void testParseVcard3() throws IOException, ParserException {
|
|
||||||
Contact c = parseVCard("vcard3-sample1.vcf");
|
|
||||||
|
|
||||||
assertEquals("Forrest Gump", c.getDisplayName());
|
|
||||||
assertEquals("Forrest", c.getGivenName());
|
|
||||||
assertEquals("Gump", c.getFamilyName());
|
|
||||||
|
|
||||||
assertEquals(2, c.getPhoneNumbers().size());
|
|
||||||
assertEquals("(111) 555-1212", c.getPhoneNumbers().get(0).getText());
|
|
||||||
|
|
||||||
assertEquals(1, c.getEmails().size());
|
|
||||||
assertEquals("forrestgump@example.com", c.getEmails().get(0).getValue());
|
|
||||||
|
|
||||||
assertFalse(c.isStarred());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private Contact parseVCard(String fileName) throws IOException {
|
|
||||||
@Cleanup InputStream in = assetMgr.open(fileName, AssetManager.ACCESS_STREAMING);
|
|
||||||
|
|
||||||
Contact c = new Contact(fileName, null);
|
|
||||||
c.parseEntity(in, null);
|
|
||||||
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
}
|
|
@ -7,6 +7,11 @@
|
|||||||
*/
|
*/
|
||||||
package at.bitfire.davdroid.resource;
|
package at.bitfire.davdroid.resource;
|
||||||
|
|
||||||
|
import android.content.res.AssetManager;
|
||||||
|
import android.test.InstrumentationTestCase;
|
||||||
|
|
||||||
|
import org.apache.commons.io.IOUtils;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
@ -15,16 +20,10 @@ import java.util.Arrays;
|
|||||||
|
|
||||||
import at.bitfire.davdroid.webdav.DavException;
|
import at.bitfire.davdroid.webdav.DavException;
|
||||||
import at.bitfire.davdroid.webdav.HttpException;
|
import at.bitfire.davdroid.webdav.HttpException;
|
||||||
|
import ezvcard.VCardVersion;
|
||||||
import ezvcard.property.Email;
|
import ezvcard.property.Email;
|
||||||
import ezvcard.property.Telephone;
|
import ezvcard.property.Telephone;
|
||||||
import lombok.Cleanup;
|
import lombok.Cleanup;
|
||||||
import android.content.res.AssetManager;
|
|
||||||
import android.test.InstrumentationTestCase;
|
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils;
|
|
||||||
|
|
||||||
import at.bitfire.davdroid.resource.Contact;
|
|
||||||
import at.bitfire.davdroid.resource.InvalidResourceException;
|
|
||||||
|
|
||||||
public class ContactTest extends InstrumentationTestCase {
|
public class ContactTest extends InstrumentationTestCase {
|
||||||
AssetManager assetMgr;
|
AssetManager assetMgr;
|
||||||
@ -32,6 +31,19 @@ public class ContactTest extends InstrumentationTestCase {
|
|||||||
public void setUp() throws IOException, InvalidResourceException {
|
public void setUp() throws IOException, InvalidResourceException {
|
||||||
assetMgr = getInstrumentation().getContext().getResources().getAssets();
|
assetMgr = getInstrumentation().getContext().getResources().getAssets();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testGenerateDifferentVersions() throws Exception {
|
||||||
|
Contact c = new Contact("test.vcf", null);
|
||||||
|
|
||||||
|
// should generate VCard 3.0 by default
|
||||||
|
assertEquals("text/vcard", c.getMimeType());
|
||||||
|
assertTrue(new String(c.toEntity().toByteArray()).contains("VERSION:3.0"));
|
||||||
|
|
||||||
|
// now let's generate VCard 4.0
|
||||||
|
c.setVCardVersion(VCardVersion.V4_0);
|
||||||
|
assertEquals("text/vcard;version=4.0", c.getMimeType());
|
||||||
|
assertTrue(new String(c.toEntity().toByteArray()).contains("VERSION:4.0"));
|
||||||
|
}
|
||||||
|
|
||||||
public void testReferenceVCard() throws IOException, InvalidResourceException {
|
public void testReferenceVCard() throws IOException, InvalidResourceException {
|
||||||
Contact c = parseVCF("reference.vcf");
|
Contact c = parseVCF("reference.vcf");
|
||||||
|
@ -7,16 +7,16 @@
|
|||||||
*/
|
*/
|
||||||
package at.bitfire.davdroid.resource;
|
package at.bitfire.davdroid.resource;
|
||||||
|
|
||||||
|
import android.content.res.AssetManager;
|
||||||
|
import android.test.InstrumentationTestCase;
|
||||||
|
import android.text.format.Time;
|
||||||
|
|
||||||
|
import net.fortuna.ical4j.data.ParserException;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
|
||||||
import lombok.Cleanup;
|
import lombok.Cleanup;
|
||||||
import net.fortuna.ical4j.data.ParserException;
|
|
||||||
import android.content.res.AssetManager;
|
|
||||||
import android.test.InstrumentationTestCase;
|
|
||||||
import android.text.format.Time;
|
|
||||||
import at.bitfire.davdroid.resource.Event;
|
|
||||||
import at.bitfire.davdroid.resource.InvalidResourceException;
|
|
||||||
|
|
||||||
public class EventTest extends InstrumentationTestCase {
|
public class EventTest extends InstrumentationTestCase {
|
||||||
AssetManager assetMgr;
|
AssetManager assetMgr;
|
||||||
|
@ -7,19 +7,13 @@
|
|||||||
*/
|
*/
|
||||||
package at.bitfire.davdroid.resource;
|
package at.bitfire.davdroid.resource;
|
||||||
|
|
||||||
import java.util.Calendar;
|
|
||||||
|
|
||||||
import lombok.Cleanup;
|
|
||||||
|
|
||||||
import android.Manifest;
|
import android.Manifest;
|
||||||
import android.accounts.Account;
|
import android.accounts.Account;
|
||||||
import android.annotation.TargetApi;
|
import android.annotation.TargetApi;
|
||||||
import android.content.ContentProviderClient;
|
import android.content.ContentProviderClient;
|
||||||
import android.content.ContentResolver;
|
|
||||||
import android.content.ContentUris;
|
import android.content.ContentUris;
|
||||||
import android.content.ContentValues;
|
import android.content.ContentValues;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
@ -30,11 +24,11 @@ import android.provider.CalendarContract.Calendars;
|
|||||||
import android.provider.CalendarContract.Events;
|
import android.provider.CalendarContract.Events;
|
||||||
import android.provider.CalendarContract.Reminders;
|
import android.provider.CalendarContract.Reminders;
|
||||||
import android.test.InstrumentationTestCase;
|
import android.test.InstrumentationTestCase;
|
||||||
import android.test.IsolatedContext;
|
|
||||||
import android.test.mock.MockContentResolver;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import at.bitfire.davdroid.resource.LocalCalendar;
|
|
||||||
import at.bitfire.davdroid.resource.LocalStorageException;
|
import java.util.Calendar;
|
||||||
|
|
||||||
|
import lombok.Cleanup;
|
||||||
|
|
||||||
public class LocalCalendarTest extends InstrumentationTestCase {
|
public class LocalCalendarTest extends InstrumentationTestCase {
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
package="at.bitfire.davdroid"
|
package="at.bitfire.davdroid"
|
||||||
android:versionCode="59" android:versionName="0.7.3"
|
android:versionCode="61" android:versionName="0.7.5"
|
||||||
android:installLocation="internalOnly">
|
android:installLocation="internalOnly">
|
||||||
|
|
||||||
<uses-sdk
|
<uses-sdk
|
||||||
|
@ -9,7 +9,7 @@ package at.bitfire.davdroid;
|
|||||||
|
|
||||||
public class Constants {
|
public class Constants {
|
||||||
public static final String
|
public static final String
|
||||||
APP_VERSION = "0.7.3",
|
APP_VERSION = "0.7.5",
|
||||||
ACCOUNT_TYPE = "bitfire.at.davdroid",
|
ACCOUNT_TYPE = "bitfire.at.davdroid",
|
||||||
WEB_URL_HELP = "https://davdroid.bitfire.at/configuration?pk_campaign=davdroid-app",
|
WEB_URL_HELP = "https://davdroid.bitfire.at/configuration?pk_campaign=davdroid-app",
|
||||||
WEB_URL_VIEW_LOGS = "https://github.com/bitfireAT/davdroid/wiki/How-to-view-the-logs";
|
WEB_URL_VIEW_LOGS = "https://github.com/bitfireAT/davdroid/wiki/How-to-view-the-logs";
|
||||||
|
@ -7,17 +7,20 @@
|
|||||||
*/
|
*/
|
||||||
package at.bitfire.davdroid.resource;
|
package at.bitfire.davdroid.resource;
|
||||||
|
|
||||||
|
import android.accounts.Account;
|
||||||
|
|
||||||
import org.apache.http.impl.client.CloseableHttpClient;
|
import org.apache.http.impl.client.CloseableHttpClient;
|
||||||
|
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
|
|
||||||
|
import at.bitfire.davdroid.syncadapter.AccountSettings;
|
||||||
import at.bitfire.davdroid.webdav.DavMultiget;
|
import at.bitfire.davdroid.webdav.DavMultiget;
|
||||||
|
|
||||||
public class CalDavCalendar extends RemoteCollection<Event> {
|
public class CalDavCalendar extends RemoteCollection<Event> {
|
||||||
//private final static String TAG = "davdroid.CalDavCalendar";
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String memberContentType() {
|
protected String memberAcceptedMimeTypes()
|
||||||
|
{
|
||||||
return "text/calendar";
|
return "text/calendar";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,23 +7,28 @@
|
|||||||
*/
|
*/
|
||||||
package at.bitfire.davdroid.resource;
|
package at.bitfire.davdroid.resource;
|
||||||
|
|
||||||
|
import android.accounts.Account;
|
||||||
|
|
||||||
import org.apache.http.impl.client.CloseableHttpClient;
|
import org.apache.http.impl.client.CloseableHttpClient;
|
||||||
|
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
|
|
||||||
|
import at.bitfire.davdroid.syncadapter.AccountSettings;
|
||||||
import at.bitfire.davdroid.webdav.DavMultiget;
|
import at.bitfire.davdroid.webdav.DavMultiget;
|
||||||
|
import ezvcard.VCardVersion;
|
||||||
|
|
||||||
public class CardDavAddressBook extends RemoteCollection<Contact> {
|
public class CardDavAddressBook extends RemoteCollection<Contact> {
|
||||||
//private final static String TAG = "davdroid.CardDavAddressBook";
|
AccountSettings accountSettings;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String memberContentType() {
|
protected String memberAcceptedMimeTypes() {
|
||||||
return Contact.MIME_TYPE;
|
return "text/vcard;q=0.8, text/vcard;version=4.0";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected DavMultiget.Type multiGetType() {
|
protected DavMultiget.Type multiGetType() {
|
||||||
return DavMultiget.Type.ADDRESS_BOOK;
|
return accountSettings.getAddressBookVCardVersion() == VCardVersion.V4_0 ?
|
||||||
|
DavMultiget.Type.ADDRESS_BOOK_V4 : DavMultiget.Type.ADDRESS_BOOK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -32,7 +37,8 @@ public class CardDavAddressBook extends RemoteCollection<Contact> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public CardDavAddressBook(CloseableHttpClient httpClient, String baseURL, String user, String password, boolean preemptiveAuth) throws URISyntaxException {
|
public CardDavAddressBook(AccountSettings settings, CloseableHttpClient httpClient, String baseURL, String user, String password, boolean preemptiveAuth) throws URISyntaxException {
|
||||||
super(httpClient, baseURL, user, password, preemptiveAuth);
|
super(httpClient, baseURL, user, password, preemptiveAuth);
|
||||||
|
accountSettings = settings;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -65,9 +65,9 @@ import lombok.ToString;
|
|||||||
@ToString(callSuper = true)
|
@ToString(callSuper = true)
|
||||||
public class Contact extends Resource {
|
public class Contact extends Resource {
|
||||||
private final static String TAG = "davdroid.Contact";
|
private final static String TAG = "davdroid.Contact";
|
||||||
|
|
||||||
public final static String MIME_TYPE = "text/vcard";
|
@Getter @Setter protected VCardVersion vCardVersion = VCardVersion.V3_0;
|
||||||
|
|
||||||
public final static String
|
public final static String
|
||||||
PROPERTY_STARRED = "X-DAVDROID-STARRED",
|
PROPERTY_STARRED = "X-DAVDROID-STARRED",
|
||||||
PROPERTY_PHONETIC_FIRST_NAME = "X-PHONETIC-FIRST-NAME",
|
PROPERTY_PHONETIC_FIRST_NAME = "X-PHONETIC-FIRST-NAME",
|
||||||
@ -110,11 +110,11 @@ public class Contact extends Resource {
|
|||||||
|
|
||||||
/* instance methods */
|
/* instance methods */
|
||||||
|
|
||||||
public Contact(String name, String ETag) {
|
Contact(String name, String ETag) {
|
||||||
super(name, ETag);
|
super(name, ETag);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Contact(long localID, String resourceName, String eTag) {
|
Contact(long localID, String resourceName, String eTag) {
|
||||||
super(localID, resourceName, eTag);
|
super(localID, resourceName, eTag);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -300,6 +300,14 @@ public class Contact extends Resource {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getMimeType() {
|
||||||
|
if (vCardVersion == VCardVersion.V4_0)
|
||||||
|
return "text/vcard;version=4.0";
|
||||||
|
else
|
||||||
|
return "text/vcard";
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteArrayOutputStream toEntity() throws IOException {
|
public ByteArrayOutputStream toEntity() throws IOException {
|
||||||
@ -409,14 +417,14 @@ public class Contact extends Resource {
|
|||||||
vcard.setRevision(Revision.now());
|
vcard.setRevision(Revision.now());
|
||||||
|
|
||||||
// validate and print warnings
|
// validate and print warnings
|
||||||
ValidationWarnings warnings = vcard.validate(VCardVersion.V3_0);
|
ValidationWarnings warnings = vcard.validate(vCardVersion);
|
||||||
if (!warnings.isEmpty())
|
if (!warnings.isEmpty())
|
||||||
Log.w(TAG, "Created potentially invalid VCard! " + warnings);
|
Log.w(TAG, "Created potentially invalid VCard! " + warnings);
|
||||||
|
|
||||||
ByteArrayOutputStream os = new ByteArrayOutputStream();
|
ByteArrayOutputStream os = new ByteArrayOutputStream();
|
||||||
Ezvcard
|
Ezvcard
|
||||||
.write(vcard)
|
.write(vcard)
|
||||||
.version(VCardVersion.V3_0)
|
.version(vCardVersion)
|
||||||
.versionStrict(false)
|
.versionStrict(false)
|
||||||
.prodId(false) // we provide our own PRODID
|
.prodId(false) // we provide our own PRODID
|
||||||
.go(os);
|
.go(os);
|
||||||
|
@ -75,8 +75,6 @@ import lombok.Setter;
|
|||||||
public class Event extends Resource {
|
public class Event extends Resource {
|
||||||
private final static String TAG = "davdroid.Event";
|
private final static String TAG = "davdroid.Event";
|
||||||
|
|
||||||
public final static String MIME_TYPE = "text/calendar";
|
|
||||||
|
|
||||||
private final static TimeZoneRegistry tzRegistry = new DefaultTimeZoneRegistryFactory().createRegistry();
|
private final static TimeZoneRegistry tzRegistry = new DefaultTimeZoneRegistryFactory().createRegistry();
|
||||||
|
|
||||||
@Getter @Setter protected RecurrenceId recurrenceId;
|
@Getter @Setter protected RecurrenceId recurrenceId;
|
||||||
@ -236,6 +234,11 @@ public class Event extends Resource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getMimeType() {
|
||||||
|
return "text/calendar";
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public ByteArrayOutputStream toEntity() throws IOException {
|
public ByteArrayOutputStream toEntity() throws IOException {
|
||||||
|
@ -123,7 +123,9 @@ public class LocalAddressBook extends LocalCollection<Contact> {
|
|||||||
/* create/update/delete */
|
/* create/update/delete */
|
||||||
|
|
||||||
public Contact newResource(long localID, String resourceName, String eTag) {
|
public Contact newResource(long localID, String resourceName, String eTag) {
|
||||||
return new Contact(localID, resourceName, eTag);
|
Contact c = new Contact(localID, resourceName, eTag);
|
||||||
|
c.setVCardVersion(accountSettings.getAddressBookVCardVersion());
|
||||||
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void deleteAllExceptRemoteNames(Resource[] remoteResources) {
|
public void deleteAllExceptRemoteNames(Resource[] remoteResources) {
|
||||||
|
@ -7,12 +7,12 @@
|
|||||||
*/
|
*/
|
||||||
package at.bitfire.davdroid.resource;
|
package at.bitfire.davdroid.resource;
|
||||||
|
|
||||||
|
import android.accounts.Account;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import net.fortuna.ical4j.model.ValidationException;
|
import net.fortuna.ical4j.model.ValidationException;
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.apache.http.client.utils.URIUtilsHC4;
|
|
||||||
import org.apache.http.impl.client.CloseableHttpClient;
|
import org.apache.http.impl.client.CloseableHttpClient;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
@ -21,11 +21,11 @@ import java.io.IOException;
|
|||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
import java.net.URL;
|
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import at.bitfire.davdroid.URIUtils;
|
import at.bitfire.davdroid.URIUtils;
|
||||||
|
import at.bitfire.davdroid.syncadapter.AccountSettings;
|
||||||
import at.bitfire.davdroid.webdav.DavException;
|
import at.bitfire.davdroid.webdav.DavException;
|
||||||
import at.bitfire.davdroid.webdav.DavMultiget;
|
import at.bitfire.davdroid.webdav.DavMultiget;
|
||||||
import at.bitfire.davdroid.webdav.DavNoContentException;
|
import at.bitfire.davdroid.webdav.DavNoContentException;
|
||||||
@ -50,8 +50,7 @@ public abstract class RemoteCollection<T extends Resource> {
|
|||||||
URI baseURI;
|
URI baseURI;
|
||||||
@Getter WebDavResource collection;
|
@Getter WebDavResource collection;
|
||||||
|
|
||||||
abstract protected String memberContentType();
|
abstract protected String memberAcceptedMimeTypes();
|
||||||
|
|
||||||
abstract protected DavMultiget.Type multiGetType();
|
abstract protected DavMultiget.Type multiGetType();
|
||||||
|
|
||||||
abstract protected T newResourceSkeleton(String name, String ETag);
|
abstract protected T newResourceSkeleton(String name, String ETag);
|
||||||
@ -132,14 +131,7 @@ public abstract class RemoteCollection<T extends Resource> {
|
|||||||
public Resource get(Resource resource) throws URISyntaxException, IOException, HttpException, DavException, InvalidResourceException {
|
public Resource get(Resource resource) throws URISyntaxException, IOException, HttpException, DavException, InvalidResourceException {
|
||||||
WebDavResource member = new WebDavResource(collection, resource.getName());
|
WebDavResource member = new WebDavResource(collection, resource.getName());
|
||||||
|
|
||||||
if (resource instanceof Contact)
|
member.get(memberAcceptedMimeTypes());
|
||||||
member.get(Contact.MIME_TYPE);
|
|
||||||
else if (resource instanceof Event)
|
|
||||||
member.get(Event.MIME_TYPE);
|
|
||||||
else {
|
|
||||||
Log.wtf(TAG, "Should fetch something, but neither contact nor calendar");
|
|
||||||
throw new InvalidResourceException("Didn't now which MIME type to accept");
|
|
||||||
}
|
|
||||||
|
|
||||||
byte[] data = member.getContent();
|
byte[] data = member.getContent();
|
||||||
if (data == null)
|
if (data == null)
|
||||||
@ -157,7 +149,7 @@ public abstract class RemoteCollection<T extends Resource> {
|
|||||||
// returns ETag of the created resource, if returned by server
|
// returns ETag of the created resource, if returned by server
|
||||||
public String add(Resource res) throws URISyntaxException, IOException, HttpException, ValidationException {
|
public String add(Resource res) throws URISyntaxException, IOException, HttpException, ValidationException {
|
||||||
WebDavResource member = new WebDavResource(collection, res.getName(), res.getETag());
|
WebDavResource member = new WebDavResource(collection, res.getName(), res.getETag());
|
||||||
member.setContentType(memberContentType());
|
member.setContentType(res.getMimeType());
|
||||||
|
|
||||||
@Cleanup ByteArrayOutputStream os = res.toEntity();
|
@Cleanup ByteArrayOutputStream os = res.toEntity();
|
||||||
String eTag = member.put(os.toByteArray(), PutMode.ADD_DONT_OVERWRITE);
|
String eTag = member.put(os.toByteArray(), PutMode.ADD_DONT_OVERWRITE);
|
||||||
@ -178,7 +170,7 @@ public abstract class RemoteCollection<T extends Resource> {
|
|||||||
// returns ETag of the updated resource, if returned by server
|
// returns ETag of the updated resource, if returned by server
|
||||||
public String update(Resource res) throws URISyntaxException, IOException, HttpException, ValidationException {
|
public String update(Resource res) throws URISyntaxException, IOException, HttpException, ValidationException {
|
||||||
WebDavResource member = new WebDavResource(collection, res.getName(), res.getETag());
|
WebDavResource member = new WebDavResource(collection, res.getName(), res.getETag());
|
||||||
member.setContentType(memberContentType());
|
member.setContentType(res.getMimeType());
|
||||||
|
|
||||||
@Cleanup ByteArrayOutputStream os = res.toEntity();
|
@Cleanup ByteArrayOutputStream os = res.toEntity();
|
||||||
String eTag = member.put(os.toByteArray(), PutMode.UPDATE_DONT_OVERWRITE);
|
String eTag = member.put(os.toByteArray(), PutMode.UPDATE_DONT_OVERWRITE);
|
||||||
|
@ -30,7 +30,6 @@ public abstract class Resource {
|
|||||||
@Getter @Setter protected String uid;
|
@Getter @Setter protected String uid;
|
||||||
@Getter protected long localID;
|
@Getter protected long localID;
|
||||||
|
|
||||||
|
|
||||||
public Resource(String name, String ETag) {
|
public Resource(String name, String ETag) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.ETag = ETag;
|
this.ETag = ETag;
|
||||||
@ -50,6 +49,10 @@ public abstract class Resource {
|
|||||||
**/
|
**/
|
||||||
public abstract void parseEntity(InputStream entity, AssetDownloader downloader) throws IOException, InvalidResourceException;
|
public abstract void parseEntity(InputStream entity, AssetDownloader downloader) throws IOException, InvalidResourceException;
|
||||||
|
|
||||||
|
|
||||||
|
/* returns the MIME type that toEntity() will produce */
|
||||||
|
public abstract String getMimeType();
|
||||||
|
|
||||||
/** writes the resource data to an output stream (for instance, .vcf file for Contact) */
|
/** writes the resource data to an output stream (for instance, .vcf file for Contact) */
|
||||||
public abstract ByteArrayOutputStream toEntity() throws IOException;
|
public abstract ByteArrayOutputStream toEntity() throws IOException;
|
||||||
|
|
||||||
|
@ -67,7 +67,7 @@ public class ContactsSyncAdapterService extends Service {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
LocalCollection<?> database = new LocalAddressBook(account, provider, settings);
|
LocalCollection<?> database = new LocalAddressBook(account, provider, settings);
|
||||||
RemoteCollection<?> dav = new CardDavAddressBook(httpClient, addressBookURL, userName, password, preemptive);
|
RemoteCollection<?> dav = new CardDavAddressBook(settings, httpClient, addressBookURL, userName, password, preemptive);
|
||||||
|
|
||||||
Map<LocalCollection<?>, RemoteCollection<?>> map = new HashMap<LocalCollection<?>, RemoteCollection<?>>();
|
Map<LocalCollection<?>, RemoteCollection<?>> map = new HashMap<LocalCollection<?>, RemoteCollection<?>>();
|
||||||
map.put(database, dav);
|
map.put(database, dav);
|
||||||
|
@ -9,15 +9,18 @@
|
|||||||
package at.bitfire.davdroid.ui.settings;
|
package at.bitfire.davdroid.ui.settings;
|
||||||
|
|
||||||
import android.accounts.Account;
|
import android.accounts.Account;
|
||||||
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.preference.CheckBoxPreference;
|
import android.preference.CheckBoxPreference;
|
||||||
import android.preference.EditTextPreference;
|
import android.preference.EditTextPreference;
|
||||||
import android.preference.ListPreference;
|
import android.preference.ListPreference;
|
||||||
import android.preference.Preference;
|
import android.preference.Preference;
|
||||||
import android.preference.PreferenceFragment;
|
import android.preference.PreferenceFragment;
|
||||||
|
import android.preference.SwitchPreference;
|
||||||
|
|
||||||
import at.bitfire.davdroid.R;
|
import at.bitfire.davdroid.R;
|
||||||
import at.bitfire.davdroid.syncadapter.AccountSettings;
|
import at.bitfire.davdroid.syncadapter.AccountSettings;
|
||||||
|
import ezvcard.VCardVersion;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
|
||||||
public class AccountFragment extends PreferenceFragment {
|
public class AccountFragment extends PreferenceFragment {
|
||||||
@ -38,6 +41,7 @@ public class AccountFragment extends PreferenceFragment {
|
|||||||
public void readFromAccount() {
|
public void readFromAccount() {
|
||||||
final AccountSettings settings = new AccountSettings(getActivity(), account);
|
final AccountSettings settings = new AccountSettings(getActivity(), account);
|
||||||
|
|
||||||
|
// category: authentication
|
||||||
final EditTextPreference prefUserName = (EditTextPreference)findPreference("username");
|
final EditTextPreference prefUserName = (EditTextPreference)findPreference("username");
|
||||||
prefUserName.setSummary(settings.getUserName());
|
prefUserName.setSummary(settings.getUserName());
|
||||||
prefUserName.setText(settings.getUserName());
|
prefUserName.setText(settings.getUserName());
|
||||||
@ -61,7 +65,7 @@ public class AccountFragment extends PreferenceFragment {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
final CheckBoxPreference prefPreemptive = (CheckBoxPreference)findPreference("preemptive");
|
final SwitchPreference prefPreemptive = (SwitchPreference)findPreference("preemptive");
|
||||||
prefPreemptive.setChecked(settings.getPreemptiveAuth());
|
prefPreemptive.setChecked(settings.getPreemptiveAuth());
|
||||||
prefPreemptive.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
prefPreemptive.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||||
@Override
|
@Override
|
||||||
@ -72,6 +76,7 @@ public class AccountFragment extends PreferenceFragment {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// category: synchronization
|
||||||
final ListPreference prefSyncContacts = (ListPreference)findPreference("sync_interval_contacts");
|
final ListPreference prefSyncContacts = (ListPreference)findPreference("sync_interval_contacts");
|
||||||
final Long syncIntervalContacts = settings.getContactsSyncInterval();
|
final Long syncIntervalContacts = settings.getContactsSyncInterval();
|
||||||
if (syncIntervalContacts != null) {
|
if (syncIntervalContacts != null) {
|
||||||
@ -113,5 +118,23 @@ public class AccountFragment extends PreferenceFragment {
|
|||||||
prefSyncCalendars.setEnabled(false);
|
prefSyncCalendars.setEnabled(false);
|
||||||
prefSyncCalendars.setSummary(R.string.settings_sync_summary_not_available);
|
prefSyncCalendars.setSummary(R.string.settings_sync_summary_not_available);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// category: address book
|
||||||
|
final CheckBoxPreference prefVCard4 = (CheckBoxPreference) findPreference("vcard4_support");
|
||||||
|
if (settings.getAddressBookURL() != null) { // does this account even have an address book?
|
||||||
|
final VCardVersion vCardVersion = settings.getAddressBookVCardVersion();
|
||||||
|
prefVCard4.setChecked(vCardVersion == VCardVersion.V4_0);
|
||||||
|
prefVCard4.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||||
|
@Override
|
||||||
|
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||||
|
// don't change the value (it's not really a setting, only a display)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// account doesn't have an adress book, disable contact settings
|
||||||
|
prefVCard4.setEnabled(false);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@ import java.util.List;
|
|||||||
public class DavMultiget {
|
public class DavMultiget {
|
||||||
public enum Type {
|
public enum Type {
|
||||||
ADDRESS_BOOK,
|
ADDRESS_BOOK,
|
||||||
|
ADDRESS_BOOK_V4,
|
||||||
CALENDAR
|
CALENDAR
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -29,15 +30,24 @@ public class DavMultiget {
|
|||||||
|
|
||||||
|
|
||||||
public static DavMultiget newRequest(Type type, String names[]) {
|
public static DavMultiget newRequest(Type type, String names[]) {
|
||||||
DavMultiget multiget = (type == Type.ADDRESS_BOOK) ? new DavAddressbookMultiget() : new DavCalendarMultiget();
|
DavMultiget multiget = (type == Type.CALENDAR) ? new DavCalendarMultiget() : new DavAddressbookMultiget();
|
||||||
|
|
||||||
multiget.prop = new DavProp();
|
multiget.prop = new DavProp();
|
||||||
multiget.prop.getetag = new DavProp.GetETag();
|
multiget.prop.getetag = new DavProp.GetETag();
|
||||||
|
|
||||||
if (type == Type.ADDRESS_BOOK)
|
switch (type) {
|
||||||
multiget.prop.addressData = new DavProp.AddressData();
|
case ADDRESS_BOOK:
|
||||||
else if (type == Type.CALENDAR)
|
multiget.prop.addressData = new DavProp.AddressData();
|
||||||
multiget.prop.calendarData = new DavProp.CalendarData();
|
break;
|
||||||
|
case ADDRESS_BOOK_V4:
|
||||||
|
DavProp.AddressData addressData = new DavProp.AddressData();
|
||||||
|
addressData.setContentType("text/vcard");
|
||||||
|
addressData.setVersion("4.0");
|
||||||
|
multiget.prop.addressData = addressData;
|
||||||
|
break;
|
||||||
|
case CALENDAR:
|
||||||
|
multiget.prop.calendarData = new DavProp.CalendarData();
|
||||||
|
}
|
||||||
|
|
||||||
multiget.hrefs = new ArrayList<DavHref>(names.length);
|
multiget.hrefs = new ArrayList<DavHref>(names.length);
|
||||||
for (String name : names)
|
for (String name : names)
|
||||||
|
@ -17,6 +17,7 @@ import org.simpleframework.xml.Text;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
@Namespace(prefix="D",reference="DAV:")
|
@Namespace(prefix="D",reference="DAV:")
|
||||||
@Root(strict=false)
|
@Root(strict=false)
|
||||||
@ -199,6 +200,12 @@ public class DavProp {
|
|||||||
|
|
||||||
@Namespace(prefix="CD",reference="urn:ietf:params:xml:ns:carddav")
|
@Namespace(prefix="CD",reference="urn:ietf:params:xml:ns:carddav")
|
||||||
public static class AddressData {
|
public static class AddressData {
|
||||||
|
@Attribute(name="content-type", required=false)
|
||||||
|
@Getter @Setter String contentType;
|
||||||
|
|
||||||
|
@Attribute(required=false)
|
||||||
|
@Getter @Setter String version;
|
||||||
|
|
||||||
@Text(required=false)
|
@Text(required=false)
|
||||||
@Getter String vcard;
|
@Getter String vcard;
|
||||||
}
|
}
|
||||||
|
@ -335,9 +335,9 @@ public class WebDavResource {
|
|||||||
|
|
||||||
/* resource operations */
|
/* resource operations */
|
||||||
|
|
||||||
public void get(String acceptedType) throws URISyntaxException, IOException, HttpException, DavException {
|
public void get(String acceptedMimeTypes) throws URISyntaxException, IOException, HttpException, DavException {
|
||||||
HttpGetHC4 get = new HttpGetHC4(location);
|
HttpGetHC4 get = new HttpGetHC4(location);
|
||||||
get.addHeader("Accept", acceptedType);
|
get.addHeader("Accept", acceptedMimeTypes);
|
||||||
|
|
||||||
@Cleanup CloseableHttpResponse response = httpClient.execute(get, context);
|
@Cleanup CloseableHttpResponse response = httpClient.execute(get, context);
|
||||||
checkResponse(response);
|
checkResponse(response);
|
||||||
|
@ -137,6 +137,10 @@
|
|||||||
<item>Alle 4 Stunden</item>
|
<item>Alle 4 Stunden</item>
|
||||||
<item>Täglich</item>
|
<item>Täglich</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
|
<string name="settings_carddav">Adressbuch</string>
|
||||||
|
<string name="settings_carddav_vcard4_support">VCard 4.0-Unterstützung</string>
|
||||||
|
<string name="settings_carddav_vcard4_supported">Kontakte werden als VCard 4.0 gesendet</string>
|
||||||
|
<string name="settings_carddav_vcard4_not_supported">Kontakte werden als VCard 3.0 gesendet</string>
|
||||||
|
|
||||||
<string name="setup_select_collections">DAVdroid: Ordner auswählen</string>
|
<string name="setup_select_collections">DAVdroid: Ordner auswählen</string>
|
||||||
<string name="setup_neither_caldav_nor_carddav">An dieser Adresse konnte kein CalDAV- oder CardDAV-Dienst gefunden werden.</string>
|
<string name="setup_neither_caldav_nor_carddav">An dieser Adresse konnte kein CalDAV- oder CardDAV-Dienst gefunden werden.</string>
|
||||||
|
@ -151,6 +151,10 @@
|
|||||||
<item>Every 4 hours</item>
|
<item>Every 4 hours</item>
|
||||||
<item>Once a day</item>
|
<item>Once a day</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
|
<string name="settings_carddav">Address book</string>
|
||||||
|
<string name="settings_carddav_vcard4_support">VCard 4.0 support</string>
|
||||||
|
<string name="settings_carddav_vcard4_supported">Contacts are sent in VCard 4.0 format</string>
|
||||||
|
<string name="settings_carddav_vcard4_not_supported">Contacts are sent in VCard 3.0 format</string>
|
||||||
|
|
||||||
<string name="setup_select_collections">DAVdroid: Select collections</string>
|
<string name="setup_select_collections">DAVdroid: Select collections</string>
|
||||||
<string name="setup_neither_caldav_nor_carddav">No CalDAV-/CardDAV service is available at this location.</string>
|
<string name="setup_neither_caldav_nor_carddav">No CalDAV-/CardDAV service is available at this location.</string>
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
android:summary="@string/settings_password_summary"
|
android:summary="@string/settings_password_summary"
|
||||||
android:dialogTitle="@string/settings_enter_password" />
|
android:dialogTitle="@string/settings_enter_password" />
|
||||||
|
|
||||||
<CheckBoxPreference
|
<SwitchPreference
|
||||||
android:key="preemptive"
|
android:key="preemptive"
|
||||||
android:persistent="false"
|
android:persistent="false"
|
||||||
android:title="@string/settings_preemptive"
|
android:title="@string/settings_preemptive"
|
||||||
@ -52,4 +52,15 @@
|
|||||||
|
|
||||||
</PreferenceCategory>
|
</PreferenceCategory>
|
||||||
|
|
||||||
|
<PreferenceCategory android:title="@string/settings_carddav">
|
||||||
|
|
||||||
|
<CheckBoxPreference
|
||||||
|
android:key="vcard4_support"
|
||||||
|
android:title="@string/settings_carddav_vcard4_support"
|
||||||
|
android:persistent="false"
|
||||||
|
android:summaryOn="@string/settings_carddav_vcard4_supported"
|
||||||
|
android:summaryOff="@string/settings_carddav_vcard4_not_supported" />
|
||||||
|
|
||||||
|
</PreferenceCategory>
|
||||||
|
|
||||||
</PreferenceScreen>
|
</PreferenceScreen>
|
||||||
|
@ -282,7 +282,7 @@ public class SSLConnectionSocketFactory implements LayeredConnectionSocketFactor
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@TargetApi(17)
|
@TargetApi(9)
|
||||||
public Socket createLayeredSocket(
|
public Socket createLayeredSocket(
|
||||||
final Socket socket,
|
final Socket socket,
|
||||||
final String target,
|
final String target,
|
||||||
@ -319,7 +319,7 @@ public class SSLConnectionSocketFactory implements LayeredConnectionSocketFactor
|
|||||||
prepareSocket(sslsock);
|
prepareSocket(sslsock);
|
||||||
|
|
||||||
// Android specific code to enable SNI
|
// Android specific code to enable SNI
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
|
||||||
if (Log.isLoggable(TAG, Log.DEBUG)) {
|
if (Log.isLoggable(TAG, Log.DEBUG)) {
|
||||||
Log.d(TAG, "Enabling SNI for " + target);
|
Log.d(TAG, "Enabling SNI for " + target);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user