Commit f824386d authored by Ricki Hirner's avatar Ricki Hirner 🐑

Improve error/account settings notifications

* move address book settings from account user data to ContactsContract.SyncState
* remove "VCard4 capable?" setting (as it's detected at every sync)
* show user notification when updating settings version or when Android version was increased
* improve stack trace in DebugInfoActivity
* get rid of Guava (use Commons again)
parent 68ee33b2
......@@ -17,8 +17,8 @@ android {
minSdkVersion 14
targetSdkVersion 23
versionCode 75
versionName "0.9-alpha3"
versionCode 76
versionName "0.9-alpha4"
buildConfigField "java.util.Date", "buildTime", "new java.util.Date()"
}
......@@ -49,8 +49,8 @@ configurations.all {
}
dependencies {
compile 'com.google.guava:guava:18.0'
compile 'dnsjava:dnsjava:2.1.7'
compile 'org.apache.commons:commons-lang3:3.4'
provided 'org.projectlombok:lombok:1.16.6'
compile('org.slf4j:slf4j-android:1.7.12')
......
......@@ -14,8 +14,16 @@ public class Constants {
public static final String
ACCOUNT_TYPE = "bitfire.at.davdroid",
WEB_URL_MAIN = "https://davdroid.bitfire.at/?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_HELP = "https://davdroid.bitfire.at/configuration?pk_campaign=davdroid-app";
public static final Logger log = LoggerFactory.getLogger("davdroid");
// notification IDs
public final static int
NOTIFICATION_ANDROID_VERSION_UPDATED = 0,
NOTIFICATION_ACCOUNT_SETTINGS_UPDATED = 1,
NOTIFICATION_CONTACTS_SYNC = 10,
NOTIFICATION_CALENDAR_SYNC = 11,
NOTIFICATION_TASK_SYNC = 12;
}
......@@ -26,7 +26,9 @@ import lombok.Synchronized;
public class LocalAddressBook extends AndroidAddressBook implements LocalCollection {
protected static final String SYNC_STATE_CTAG = "ctag";
protected static final String
SYNC_STATE_CTAG = "ctag",
SYNC_STATE_URL = "url";
private Bundle syncState = new Bundle();
......@@ -80,6 +82,27 @@ public class LocalAddressBook extends AndroidAddressBook implements LocalCollect
syncState.clear();
}
protected void writeSyncState() throws ContactsStorageException {
@Cleanup("recycle") Parcel parcel = Parcel.obtain();
parcel.writeBundle(syncState);
setSyncState(parcel.marshall());
}
public String getURL() throws ContactsStorageException {
synchronized (syncState) {
readSyncState();
return syncState.getString(SYNC_STATE_URL);
}
}
public void setURL(String url) throws ContactsStorageException {
synchronized (syncState) {
readSyncState();
syncState.putString(SYNC_STATE_URL, url);
writeSyncState();
}
}
@Override
public String getCTag() throws ContactsStorageException {
synchronized (syncState) {
......@@ -93,11 +116,7 @@ public class LocalAddressBook extends AndroidAddressBook implements LocalCollect
synchronized (syncState) {
readSyncState();
syncState.putString(SYNC_STATE_CTAG, cTag);
// write sync state bundle
@Cleanup("recycle") Parcel parcel = Parcel.obtain();
parcel.writeBundle(syncState);
setSyncState(parcel.marshall());
writeSyncState();
}
}
......
......@@ -24,11 +24,10 @@ import android.provider.CalendarContract.Events;
import android.provider.CalendarContract.Reminders;
import android.text.TextUtils;
import com.google.common.base.Joiner;
import net.fortuna.ical4j.data.CalendarBuilder;
import net.fortuna.ical4j.model.component.VTimeZone;
import org.apache.commons.lang3.StringUtils;
import java.io.FileNotFoundException;
import java.util.LinkedList;
import java.util.List;
......@@ -96,8 +95,8 @@ public class LocalCalendar extends AndroidCalendar implements LocalCollection {
}
values.put(Calendars.ALLOWED_REMINDERS, Reminders.METHOD_ALERT);
if (Build.VERSION.SDK_INT >= 15) {
values.put(Calendars.ALLOWED_AVAILABILITY, Joiner.on(",").join(Reminders.AVAILABILITY_TENTATIVE, Reminders.AVAILABILITY_FREE, Reminders.AVAILABILITY_BUSY));
values.put(Calendars.ALLOWED_ATTENDEE_TYPES, Joiner.on(",").join(CalendarContract.Attendees.TYPE_OPTIONAL, CalendarContract.Attendees.TYPE_REQUIRED, CalendarContract.Attendees.TYPE_RESOURCE));
values.put(Calendars.ALLOWED_AVAILABILITY, StringUtils.join(new int[] { Reminders.AVAILABILITY_TENTATIVE, Reminders.AVAILABILITY_FREE, Reminders.AVAILABILITY_BUSY }, ","));
values.put(Calendars.ALLOWED_ATTENDEE_TYPES, StringUtils.join(new int[] { CalendarContract.Attendees.TYPE_OPTIONAL, CalendarContract.Attendees.TYPE_REQUIRED, CalendarContract.Attendees.TYPE_RESOURCE }, ", "));
}
return create(account, provider, values);
}
......
......@@ -16,13 +16,14 @@ import android.os.Bundle;
import android.provider.CalendarContract.Calendars;
import android.text.TextUtils;
import com.google.common.base.Charsets;
import com.google.common.base.Joiner;
import com.squareup.okhttp.HttpUrl;
import com.squareup.okhttp.MediaType;
import com.squareup.okhttp.RequestBody;
import com.squareup.okhttp.ResponseBody;
import org.apache.commons.codec.Charsets;
import org.apache.commons.lang3.StringUtils;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
......@@ -54,13 +55,11 @@ import lombok.Cleanup;
public class CalendarSyncManager extends SyncManager {
protected static final int
MAX_MULTIGET = 30,
NOTIFICATION_ID = 2;
protected static final int MAX_MULTIGET = 20;
public CalendarSyncManager(Context context, Account account, Bundle extras, SyncResult result, LocalCalendar calendar) {
super(NOTIFICATION_ID, context, account, extras, result);
super(Constants.NOTIFICATION_CALENDAR_SYNC, context, account, extras, result);
localCollection = calendar;
}
......@@ -126,7 +125,7 @@ public class CalendarSyncManager extends SyncManager {
// download new/updated iCalendars from server
for (DavResource[] bunch : ArrayUtils.partition(toDownload.toArray(new DavResource[toDownload.size()]), MAX_MULTIGET)) {
Constants.log.info("Downloading " + Joiner.on(" + ").join(bunch));
Constants.log.info("Downloading " + StringUtils.join(bunch, ", "));
if (bunch.length == 1) {
// only one contact, use GET
......
......@@ -13,9 +13,7 @@ import android.content.ContentProviderClient;
import android.content.Context;
import android.content.SyncResult;
import android.os.Bundle;
import android.text.TextUtils;
import com.google.common.base.Charsets;
import com.squareup.okhttp.HttpUrl;
import com.squareup.okhttp.MediaType;
import com.squareup.okhttp.Request;
......@@ -23,6 +21,9 @@ import com.squareup.okhttp.RequestBody;
import com.squareup.okhttp.Response;
import com.squareup.okhttp.ResponseBody;
import org.apache.commons.codec.Charsets;
import org.apache.commons.lang3.StringUtils;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
......@@ -30,8 +31,6 @@ import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import at.bitfire.dav4android.DavAddressBook;
import at.bitfire.dav4android.DavResource;
......@@ -56,27 +55,25 @@ import lombok.Cleanup;
import lombok.RequiredArgsConstructor;
public class ContactsSyncManager extends SyncManager {
protected static final int
MAX_MULTIGET = 10,
NOTIFICATION_ID = 1;
protected static final int MAX_MULTIGET = 10;
final protected ContentProviderClient provider;
protected boolean hasVCard4;
public ContactsSyncManager(Context context, Account account, Bundle extras, ContentProviderClient provider, SyncResult result) {
super(NOTIFICATION_ID, context, account, extras, result);
super(Constants.NOTIFICATION_CONTACTS_SYNC, context, account, extras, result);
this.provider = provider;
}
@Override
protected void prepare() {
collectionURL = HttpUrl.parse(settings.getAddressBookURL());
davCollection = new DavAddressBook(httpClient, collectionURL);
protected void prepare() throws ContactsStorageException {
// prepare local address book
localCollection = new LocalAddressBook(account, provider);
collectionURL = HttpUrl.parse(localAddressBook().getURL());
davCollection = new DavAddressBook(httpClient, collectionURL);
}
@Override
......@@ -122,7 +119,7 @@ public class ContactsSyncManager extends SyncManager {
// download new/updated VCards from server
for (DavResource[] bunch : ArrayUtils.partition(toDownload.toArray(new DavResource[toDownload.size()]), MAX_MULTIGET)) {
Constants.log.info("Downloading " + TextUtils.join(" + ", bunch));
Constants.log.info("Downloading " + StringUtils.join(bunch, ", "));
if (bunch.length == 1) {
// only one contact, use GET
......
......@@ -204,6 +204,9 @@ abstract public class SyncManager {
.setContentTitle(context.getString(R.string.sync_error_title, account.name))
.setContentIntent(PendingIntent.getActivity(context, 0, detailsIntent, PendingIntent.FLAG_UPDATE_CURRENT));
if (Build.VERSION.SDK_INT >= 20)
builder.setLocalOnly(true);
try {
String[] phases = context.getResources().getStringArray(R.array.sync_error_phases);
String message = context.getString(messageString, phases[syncPhase]);
......@@ -225,7 +228,7 @@ abstract public class SyncManager {
}
abstract protected void prepare();
abstract protected void prepare() throws ContactsStorageException;
abstract protected void queryCapabilities() throws IOException, HttpException, DavException, CalendarStorageException, ContactsStorageException;
......
......@@ -15,13 +15,13 @@ import android.content.SyncResult;
import android.os.Bundle;
import android.text.TextUtils;
import com.google.common.base.Charsets;
import com.google.common.base.Joiner;
import com.squareup.okhttp.HttpUrl;
import com.squareup.okhttp.MediaType;
import com.squareup.okhttp.RequestBody;
import com.squareup.okhttp.ResponseBody;
import org.apache.commons.codec.Charsets;
import org.apache.commons.lang3.StringUtils;
import org.dmfs.provider.tasks.TaskContract.TaskLists;
import java.io.ByteArrayInputStream;
......@@ -56,15 +56,13 @@ import lombok.Cleanup;
public class TasksSyncManager extends SyncManager {
protected static final int
MAX_MULTIGET = 30,
NOTIFICATION_ID = 3;
protected static final int MAX_MULTIGET = 30;
final protected TaskProvider provider;
public TasksSyncManager(Context context, Account account, Bundle extras, TaskProvider provider, SyncResult result, LocalTaskList taskList) {
super(NOTIFICATION_ID, context, account, extras, result);
super(Constants.NOTIFICATION_TASK_SYNC, context, account, extras, result);
this.provider = provider;
localCollection = taskList;
}
......@@ -124,7 +122,7 @@ public class TasksSyncManager extends SyncManager {
// download new/updated iCalendars from server
for (DavResource[] bunch : ArrayUtils.partition(toDownload.toArray(new DavResource[toDownload.size()]), MAX_MULTIGET)) {
Constants.log.info("Downloading " + Joiner.on(" + ").join(bunch));
Constants.log.info("Downloading " + StringUtils.join(bunch, ", "));
if (bunch.length == 1) {
// only one contact, use GET
......
......@@ -23,18 +23,12 @@ import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;
import com.google.common.base.Throwables;
import org.apache.commons.lang3.exception.ExceptionUtils;
import java.io.PrintWriter;
import java.io.StringWriter;
import at.bitfire.dav4android.exception.HttpException;
import at.bitfire.davdroid.BuildConfig;
import at.bitfire.davdroid.Constants;
import at.bitfire.davdroid.R;
import lombok.Cleanup;
public class DebugInfoActivity extends Activity {
public static final String
......@@ -141,7 +135,8 @@ public class DebugInfoActivity extends Activity {
if (exception != null) {
report.append("STACK TRACE\n");
report.append(Throwables.getStackTraceAsString(exception));
for (String stackTrace : ExceptionUtils.getRootCauseStackTrace(exception))
report.append(stackTrace + "\n");
}
return report.toString();
......
......@@ -141,22 +141,5 @@ public class AccountFragment extends PreferenceFragment {
prefSyncTasks.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);
}
}
}
......@@ -104,6 +104,11 @@ public class AccountDetailsFragment extends Fragment implements TextWatcher {
public void createLocalCollection(Account account, ServerInfo.ResourceInfo resource) throws ContactsStorageException {
@Cleanup("release") ContentProviderClient provider = getActivity().getContentResolver().acquireContentProviderClient(ContactsContract.AUTHORITY);
LocalAddressBook addressBook = new LocalAddressBook(account, provider);
// set URL
addressBook.setURL(resource.getURL());
// set Settings
ContentValues settings = new ContentValues(2);
settings.put(ContactsContract.Settings.SHOULD_SYNC, 1);
settings.put(ContactsContract.Settings.UNGROUPED_VISIBLE, 1);
......
......@@ -143,7 +143,12 @@
<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="settings_android_update_title">Neue Android-Version</string>
<string name="settings_android_update_description">Die Änderung der Android-Version kann einen Einfluss auf DAVdroid haben. Falls etwas nicht funktioniert, löschen Sie bitte Ihre DAVdroid-Accounts und fügen Sie sie neu hinzu.</string>
<string name="settings_version_update_title">Einstellungen aktualisiert</string>
<string name="settings_version_update_description">Interne Einstellungen wurden aktualisiert. Falls etwas nicht funktioniert, löschen Sie bitte Ihre DAVdroid-Accounts und fügen Sie sie neu hinzu.</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_add_account">Konto hinzufügen</string>
......@@ -178,9 +183,9 @@
<string name="setup_read_only">schreibgeschützt</string>
<string name="sync_error_title">Synchronisierung von %s fehlgeschlagen</string>
<string name="sync_error">Fehler beim %1$s</string>
<string name="sync_error_http_dav">Serverfehler</string>
<string name="sync_error_local_storage">Datenbank-Fehler</string>
<string name="sync_error">Fehler beim %s</string>
<string name="sync_error_http_dav">Serverfehler beim %s</string>
<string name="sync_error_local_storage">Datenbank-Fehler beim %s</string>
<string-array name="sync_error_phases">
<item>Vorbereiten der Synchronisierung</item>
<item>Abfragen der Server-Fähigkeiten</item>
......
......@@ -159,6 +159,11 @@
<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="settings_android_update_title">Android version update</string>
<string name="settings_android_update_description">Android version updates may have an impact on how DAVdroid works. If there are problems, please delete your DAVdroid accounts and add them again.</string>
<string name="settings_version_update_title">Settings have been updated</string>
<string name="settings_version_update_description">Internal settings have been updated. If there are problems, please delete your DAVdroid accounts and add them again.</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_add_account">Add account</string>
......@@ -193,9 +198,9 @@
<!-- sync errors and DebugInfoActivity -->
<string name="debug_info_title">Debug info</string>
<string name="sync_error_title">Synchronization of %s failed</string>
<string name="sync_error">Error while %1$s</string>
<string name="sync_error_http_dav">Server error</string>
<string name="sync_error_local_storage">Database error</string>
<string name="sync_error">Error while %s</string>
<string name="sync_error_http_dav">Server error while %s</string>
<string name="sync_error_local_storage">Database error while %s</string>
<string-array name="sync_error_phases">
<item>preparing synchronization</item>
<item>querying capabilities</item>
......
......@@ -59,15 +59,10 @@
</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>
Subproject commit 6fc7f30b614ecb23b6fa66b6fd848fd6ddc4bafe
Subproject commit 429648cfae534dd0476f813c94ab1cae1f140223
Subproject commit 624287708eb7f093d2ddf2012e2c2c124cd6e206
Subproject commit 662c48c40ad66e9a77f4f4792587dc04ecc4a74e
Subproject commit 83ba3128913ba6e57d021ad003bf992100baae43
Subproject commit 18b26fe48896b2683b1e04e8df4464f5ceacf8f3
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment