mirror of
https://github.com/etesync/android
synced 2025-06-05 23:58:50 +00:00
Handle invalid accounts where accounts are used
* add InvalidAccountException for invalid (=not existent/invalid settings version) accounts * handle invalid accounts properly * HttpClient: add constructors without Account when authentication is not needed * drop upgrade compatibility for accounts without version (version<1)
This commit is contained in:
parent
100b78a6a4
commit
a594fd3d14
@ -26,7 +26,7 @@ public class HttpClientTest extends InstrumentationTestCase {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setUp() throws IOException {
|
public void setUp() throws IOException {
|
||||||
httpClient = HttpClient.create(getInstrumentation().getTargetContext().getApplicationContext(), null);
|
httpClient = HttpClient.create();
|
||||||
|
|
||||||
server = new MockWebServer();
|
server = new MockWebServer();
|
||||||
server.start();
|
server.start();
|
||||||
|
@ -39,7 +39,9 @@ import java.util.Set;
|
|||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
|
||||||
import at.bitfire.davdroid.model.ServiceDB;
|
import at.bitfire.davdroid.model.ServiceDB;
|
||||||
import at.bitfire.davdroid.model.ServiceDB.*;
|
import at.bitfire.davdroid.model.ServiceDB.Collections;
|
||||||
|
import at.bitfire.davdroid.model.ServiceDB.HomeSets;
|
||||||
|
import at.bitfire.davdroid.model.ServiceDB.Services;
|
||||||
import at.bitfire.davdroid.resource.LocalAddressBook;
|
import at.bitfire.davdroid.resource.LocalAddressBook;
|
||||||
import at.bitfire.davdroid.resource.LocalCalendar;
|
import at.bitfire.davdroid.resource.LocalCalendar;
|
||||||
import at.bitfire.davdroid.resource.LocalTaskList;
|
import at.bitfire.davdroid.resource.LocalTaskList;
|
||||||
@ -50,12 +52,12 @@ import lombok.Cleanup;
|
|||||||
import okhttp3.HttpUrl;
|
import okhttp3.HttpUrl;
|
||||||
|
|
||||||
public class AccountSettings {
|
public class AccountSettings {
|
||||||
private final static int CURRENT_VERSION = 3;
|
private final static int CURRENT_VERSION = 3;
|
||||||
private final static String
|
private final static String
|
||||||
KEY_SETTINGS_VERSION = "version",
|
KEY_SETTINGS_VERSION = "version",
|
||||||
|
|
||||||
KEY_USERNAME = "user_name",
|
KEY_USERNAME = "user_name",
|
||||||
KEY_AUTH_PREEMPTIVE = "auth_preemptive";
|
KEY_AUTH_PREEMPTIVE = "auth_preemptive";
|
||||||
|
|
||||||
/** Time range limitation to the past [in days]
|
/** Time range limitation to the past [in days]
|
||||||
value = null default value (DEFAULT_TIME_RANGE_PAST_DAYS)
|
value = null default value (DEFAULT_TIME_RANGE_PAST_DAYS)
|
||||||
@ -65,28 +67,32 @@ public class AccountSettings {
|
|||||||
private final static String KEY_TIME_RANGE_PAST_DAYS = "time_range_past_days";
|
private final static String KEY_TIME_RANGE_PAST_DAYS = "time_range_past_days";
|
||||||
private final static int DEFAULT_TIME_RANGE_PAST_DAYS = 90;
|
private final static int DEFAULT_TIME_RANGE_PAST_DAYS = 90;
|
||||||
|
|
||||||
public final static long SYNC_INTERVAL_MANUALLY = -1;
|
public final static long SYNC_INTERVAL_MANUALLY = -1;
|
||||||
|
|
||||||
final Context context;
|
final Context context;
|
||||||
final AccountManager accountManager;
|
final AccountManager accountManager;
|
||||||
final Account account;
|
final Account account;
|
||||||
|
|
||||||
|
|
||||||
public AccountSettings(@NonNull Context context, @NonNull Account account) {
|
public AccountSettings(@NonNull Context context, @NonNull Account account) throws InvalidAccountException {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.account = account;
|
this.account = account;
|
||||||
|
|
||||||
accountManager = AccountManager.get(context);
|
accountManager = AccountManager.get(context);
|
||||||
|
|
||||||
synchronized(AccountSettings.class) {
|
synchronized(AccountSettings.class) {
|
||||||
int version = 0;
|
String versionStr = accountManager.getUserData(account, KEY_SETTINGS_VERSION);
|
||||||
try {
|
if (versionStr == null)
|
||||||
version = Integer.parseInt(accountManager.getUserData(account, KEY_SETTINGS_VERSION));
|
throw new InvalidAccountException(account);
|
||||||
} catch(NumberFormatException ignored) {
|
|
||||||
}
|
int version = 0;
|
||||||
|
try {
|
||||||
|
version = Integer.parseInt(versionStr);
|
||||||
|
} catch (NumberFormatException ignored) {
|
||||||
|
}
|
||||||
App.log.info("Account " + account.name + " has version " + version + ", current version: " + CURRENT_VERSION);
|
App.log.info("Account " + account.name + " has version " + version + ", current version: " + CURRENT_VERSION);
|
||||||
|
|
||||||
if (version < CURRENT_VERSION) {
|
if (version < CURRENT_VERSION) {
|
||||||
Notification notify = new NotificationCompat.Builder(context)
|
Notification notify = new NotificationCompat.Builder(context)
|
||||||
.setSmallIcon(R.drawable.ic_new_releases_light)
|
.setSmallIcon(R.drawable.ic_new_releases_light)
|
||||||
.setLargeIcon(((BitmapDrawable)context.getResources().getDrawable(R.drawable.ic_launcher)).getBitmap())
|
.setLargeIcon(((BitmapDrawable)context.getResources().getDrawable(R.drawable.ic_launcher)).getBitmap())
|
||||||
@ -104,54 +110,54 @@ public class AccountSettings {
|
|||||||
|
|
||||||
update(version);
|
update(version);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Bundle initialUserData(String userName, boolean preemptive) {
|
public static Bundle initialUserData(String userName, boolean preemptive) {
|
||||||
Bundle bundle = new Bundle();
|
Bundle bundle = new Bundle();
|
||||||
bundle.putString(KEY_SETTINGS_VERSION, String.valueOf(CURRENT_VERSION));
|
bundle.putString(KEY_SETTINGS_VERSION, String.valueOf(CURRENT_VERSION));
|
||||||
bundle.putString(KEY_USERNAME, userName);
|
bundle.putString(KEY_USERNAME, userName);
|
||||||
bundle.putString(KEY_AUTH_PREEMPTIVE, Boolean.toString(preemptive));
|
bundle.putString(KEY_AUTH_PREEMPTIVE, Boolean.toString(preemptive));
|
||||||
return bundle;
|
return bundle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// authentication settings
|
|
||||||
|
|
||||||
public String username() { return accountManager.getUserData(account, KEY_USERNAME); }
|
|
||||||
public void username(@NonNull String userName) { accountManager.setUserData(account, KEY_USERNAME, userName); }
|
|
||||||
|
|
||||||
public String password() { return accountManager.getPassword(account); }
|
|
||||||
public void password(@NonNull String password) { accountManager.setPassword(account, password); }
|
|
||||||
|
|
||||||
public boolean preemptiveAuth() { return Boolean.parseBoolean(accountManager.getUserData(account, KEY_AUTH_PREEMPTIVE)); }
|
|
||||||
public void preemptiveAuth(boolean preemptive) { accountManager.setUserData(account, KEY_AUTH_PREEMPTIVE, Boolean.toString(preemptive)); }
|
|
||||||
|
|
||||||
|
|
||||||
// sync. settings
|
// authentication settings
|
||||||
|
|
||||||
public Long getSyncInterval(@NonNull String authority) {
|
public String username() { return accountManager.getUserData(account, KEY_USERNAME); }
|
||||||
if (ContentResolver.getIsSyncable(account, authority) <= 0)
|
public void username(@NonNull String userName) { accountManager.setUserData(account, KEY_USERNAME, userName); }
|
||||||
return null;
|
|
||||||
|
|
||||||
if (ContentResolver.getSyncAutomatically(account, authority)) {
|
public String password() { return accountManager.getPassword(account); }
|
||||||
List<PeriodicSync> syncs = ContentResolver.getPeriodicSyncs(account, authority);
|
public void password(@NonNull String password) { accountManager.setPassword(account, password); }
|
||||||
if (syncs.isEmpty())
|
|
||||||
return SYNC_INTERVAL_MANUALLY;
|
|
||||||
else
|
|
||||||
return syncs.get(0).period;
|
|
||||||
} else
|
|
||||||
return SYNC_INTERVAL_MANUALLY;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSyncInterval(@NonNull String authority, long seconds) {
|
public boolean preemptiveAuth() { return Boolean.parseBoolean(accountManager.getUserData(account, KEY_AUTH_PREEMPTIVE)); }
|
||||||
if (seconds == SYNC_INTERVAL_MANUALLY) {
|
public void preemptiveAuth(boolean preemptive) { accountManager.setUserData(account, KEY_AUTH_PREEMPTIVE, Boolean.toString(preemptive)); }
|
||||||
ContentResolver.setSyncAutomatically(account, authority, false);
|
|
||||||
} else {
|
|
||||||
ContentResolver.setSyncAutomatically(account, authority, true);
|
// sync. settings
|
||||||
ContentResolver.addPeriodicSync(account, authority, new Bundle(), seconds);
|
|
||||||
}
|
public Long getSyncInterval(@NonNull String authority) {
|
||||||
}
|
if (ContentResolver.getIsSyncable(account, authority) <= 0)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
if (ContentResolver.getSyncAutomatically(account, authority)) {
|
||||||
|
List<PeriodicSync> syncs = ContentResolver.getPeriodicSyncs(account, authority);
|
||||||
|
if (syncs.isEmpty())
|
||||||
|
return SYNC_INTERVAL_MANUALLY;
|
||||||
|
else
|
||||||
|
return syncs.get(0).period;
|
||||||
|
} else
|
||||||
|
return SYNC_INTERVAL_MANUALLY;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSyncInterval(@NonNull String authority, long seconds) {
|
||||||
|
if (seconds == SYNC_INTERVAL_MANUALLY) {
|
||||||
|
ContentResolver.setSyncAutomatically(account, authority, false);
|
||||||
|
} else {
|
||||||
|
ContentResolver.setSyncAutomatically(account, authority, true);
|
||||||
|
ContentResolver.addPeriodicSync(account, authority, new Bundle(), seconds);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public Integer getTimeRangePastDays() {
|
public Integer getTimeRangePastDays() {
|
||||||
String strDays = accountManager.getUserData(account, KEY_TIME_RANGE_PAST_DAYS);
|
String strDays = accountManager.getUserData(account, KEY_TIME_RANGE_PAST_DAYS);
|
||||||
@ -166,11 +172,11 @@ public class AccountSettings {
|
|||||||
accountManager.setUserData(account, KEY_TIME_RANGE_PAST_DAYS, String.valueOf(days == null ? -1 : days));
|
accountManager.setUserData(account, KEY_TIME_RANGE_PAST_DAYS, String.valueOf(days == null ? -1 : days));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// update from previous account settings
|
// update from previous account settings
|
||||||
|
|
||||||
private void update(int fromVersion) {
|
private void update(int fromVersion) {
|
||||||
for (int toVersion = fromVersion + 1; toVersion <= CURRENT_VERSION; toVersion++) {
|
for (int toVersion = fromVersion + 1; toVersion <= CURRENT_VERSION; toVersion++) {
|
||||||
App.log.info("Updating account " + account.name + " from version " + fromVersion + " to " + toVersion);
|
App.log.info("Updating account " + account.name + " from version " + fromVersion + " to " + toVersion);
|
||||||
try {
|
try {
|
||||||
Method updateProc = getClass().getDeclaredMethod("update_" + fromVersion + "_" + toVersion);
|
Method updateProc = getClass().getDeclaredMethod("update_" + fromVersion + "_" + toVersion);
|
||||||
@ -180,51 +186,7 @@ public class AccountSettings {
|
|||||||
}
|
}
|
||||||
fromVersion = toVersion;
|
fromVersion = toVersion;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings({ "Recycle", "unused" })
|
|
||||||
private void update_0_1() throws URISyntaxException {
|
|
||||||
String v0_principalURL = accountManager.getUserData(account, "principal_url"),
|
|
||||||
v0_addressBookPath = accountManager.getUserData(account, "addressbook_path");
|
|
||||||
App.log.fine("Old principal URL = " + v0_principalURL);
|
|
||||||
App.log.fine("Old address book path = " + v0_addressBookPath);
|
|
||||||
|
|
||||||
URI principalURI = new URI(v0_principalURL);
|
|
||||||
|
|
||||||
// update address book
|
|
||||||
if (v0_addressBookPath != null) {
|
|
||||||
String addressBookURL = principalURI.resolve(v0_addressBookPath).toASCIIString();
|
|
||||||
App.log.fine("New address book URL = " + addressBookURL);
|
|
||||||
accountManager.setUserData(account, "addressbook_url", addressBookURL);
|
|
||||||
}
|
|
||||||
|
|
||||||
// update calendars
|
|
||||||
ContentResolver resolver = context.getContentResolver();
|
|
||||||
Uri calendars = Calendars.CONTENT_URI.buildUpon()
|
|
||||||
.appendQueryParameter(Calendars.ACCOUNT_NAME, account.name)
|
|
||||||
.appendQueryParameter(Calendars.ACCOUNT_TYPE, account.type)
|
|
||||||
.appendQueryParameter(CalendarContract.CALLER_IS_SYNCADAPTER, "true").build();
|
|
||||||
@Cleanup Cursor cursor = resolver.query(calendars, new String[] { Calendars._ID, Calendars.NAME }, null, null, null);
|
|
||||||
while (cursor != null && cursor.moveToNext()) {
|
|
||||||
int id = cursor.getInt(0);
|
|
||||||
String v0_path = cursor.getString(1),
|
|
||||||
v1_url = principalURI.resolve(v0_path).toASCIIString();
|
|
||||||
App.log.fine("Updating calendar #" + id + " name: " + v0_path + " -> " + v1_url);
|
|
||||||
Uri calendar = ContentUris.appendId(Calendars.CONTENT_URI.buildUpon()
|
|
||||||
.appendQueryParameter(Calendars.ACCOUNT_NAME, account.name)
|
|
||||||
.appendQueryParameter(Calendars.ACCOUNT_TYPE, account.type)
|
|
||||||
.appendQueryParameter(CalendarContract.CALLER_IS_SYNCADAPTER, "true"), id).build();
|
|
||||||
ContentValues newValues = new ContentValues(1);
|
|
||||||
newValues.put(Calendars.NAME, v1_url);
|
|
||||||
if (resolver.update(calendar, newValues, null, null) != 1)
|
|
||||||
App.log.fine("Number of modified calendars != 1");
|
|
||||||
}
|
|
||||||
|
|
||||||
accountManager.setUserData(account, "principal_url", null);
|
|
||||||
accountManager.setUserData(account, "addressbook_path", null);
|
|
||||||
|
|
||||||
accountManager.setUserData(account, KEY_SETTINGS_VERSION, "1");
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings({ "Recycle", "unused" })
|
@SuppressWarnings({ "Recycle", "unused" })
|
||||||
private void update_1_2() throws ContactsStorageException {
|
private void update_1_2() throws ContactsStorageException {
|
||||||
|
@ -202,7 +202,7 @@ public class DavService extends Service {
|
|||||||
DavResource group = new DavResource(httpClient, dav.location.resolve(href));
|
DavResource group = new DavResource(httpClient, dav.location.resolve(href));
|
||||||
try {
|
try {
|
||||||
queryHomeSets(serviceType, group, homeSets);
|
queryHomeSets(serviceType, group, homeSets);
|
||||||
} catch (HttpException|DavException e) {
|
} catch(HttpException|DavException e) {
|
||||||
App.log.log(Level.WARNING, "Couldn't query member group ", e);
|
App.log.log(Level.WARNING, "Couldn't query member group ", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -217,7 +217,7 @@ public class DavService extends Service {
|
|||||||
if (info.selected)
|
if (info.selected)
|
||||||
selectedCollections.add(HttpUrl.parse(info.url));
|
selectedCollections.add(HttpUrl.parse(info.url));
|
||||||
|
|
||||||
for (Iterator<HttpUrl> iterator = homeSets.iterator(); iterator.hasNext();) {
|
for (Iterator<HttpUrl> iterator = homeSets.iterator(); iterator.hasNext(); ) {
|
||||||
HttpUrl homeSet = iterator.next();
|
HttpUrl homeSet = iterator.next();
|
||||||
App.log.fine("Listing home set " + homeSet);
|
App.log.fine("Listing home set " + homeSet);
|
||||||
|
|
||||||
@ -241,7 +241,7 @@ public class DavService extends Service {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// check/refresh unconfirmed collections
|
// check/refresh unconfirmed collections
|
||||||
for (Iterator<Map.Entry<HttpUrl, CollectionInfo>> iterator = collections.entrySet().iterator(); iterator.hasNext();) {
|
for (Iterator<Map.Entry<HttpUrl, CollectionInfo>> iterator = collections.entrySet().iterator(); iterator.hasNext(); ) {
|
||||||
Map.Entry<HttpUrl, CollectionInfo> entry = iterator.next();
|
Map.Entry<HttpUrl, CollectionInfo> entry = iterator.next();
|
||||||
HttpUrl url = entry.getKey();
|
HttpUrl url = entry.getKey();
|
||||||
CollectionInfo info = entry.getValue();
|
CollectionInfo info = entry.getValue();
|
||||||
@ -282,7 +282,9 @@ public class DavService extends Service {
|
|||||||
db.endTransaction();
|
db.endTransaction();
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (IOException|HttpException|DavException e) {
|
} catch(InvalidAccountException e) {
|
||||||
|
App.log.log(Level.SEVERE, "Invalid account", e);
|
||||||
|
} catch(IOException|HttpException|DavException e) {
|
||||||
App.log.log(Level.SEVERE, "Couldn't refresh collection list", e);
|
App.log.log(Level.SEVERE, "Couldn't refresh collection list", e);
|
||||||
|
|
||||||
Intent debugIntent = new Intent(DavService.this, DebugInfoActivity.class);
|
Intent debugIntent = new Intent(DavService.this, DebugInfoActivity.class);
|
||||||
@ -387,7 +389,7 @@ public class DavService extends Service {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void saveCollections(Iterable<CollectionInfo> collections) {
|
private void saveCollections(Iterable<CollectionInfo> collections) {
|
||||||
db.delete(Collections._TABLE, HomeSets.SERVICE_ID + "=?", new String[]{String.valueOf(service)});
|
db.delete(Collections._TABLE, HomeSets.SERVICE_ID + "=?", new String[] { String.valueOf(service) });
|
||||||
for (CollectionInfo collection : collections) {
|
for (CollectionInfo collection : collections) {
|
||||||
ContentValues values = collection.toDB();
|
ContentValues values = collection.toDB();
|
||||||
App.log.log(Level.FINE, "Saving collection", values);
|
App.log.log(Level.FINE, "Saving collection", values);
|
||||||
|
@ -43,7 +43,33 @@ public class HttpClient {
|
|||||||
private HttpClient() {
|
private HttpClient() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static OkHttpClient create(Context context, Account account, @NonNull final Logger logger) {
|
public static OkHttpClient create(@NonNull Context context, @NonNull Account account, @NonNull final Logger logger) throws InvalidAccountException {
|
||||||
|
OkHttpClient.Builder builder = defaultBuilder(logger);
|
||||||
|
|
||||||
|
// use account settings for authentication and logging
|
||||||
|
AccountSettings settings = new AccountSettings(context, account);
|
||||||
|
|
||||||
|
if (settings.preemptiveAuth())
|
||||||
|
builder.addNetworkInterceptor(new PreemptiveAuthenticationInterceptor(settings.username(), settings.password()));
|
||||||
|
else
|
||||||
|
builder.authenticator(new BasicDigestAuthenticator(null, settings.username(), settings.password()));
|
||||||
|
|
||||||
|
return builder.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static OkHttpClient create(@NonNull Logger logger) {
|
||||||
|
return defaultBuilder(logger).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static OkHttpClient create(@NonNull Context context, @NonNull Account account) throws InvalidAccountException {
|
||||||
|
return create(context, account, App.log);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static OkHttpClient create() {
|
||||||
|
return create(App.log);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static OkHttpClient.Builder defaultBuilder(@NonNull final Logger logger) {
|
||||||
OkHttpClient.Builder builder = client.newBuilder();
|
OkHttpClient.Builder builder = client.newBuilder();
|
||||||
|
|
||||||
// use MemorizingTrustManager to manage self-signed certificates
|
// use MemorizingTrustManager to manage self-signed certificates
|
||||||
@ -66,16 +92,7 @@ public class HttpClient {
|
|||||||
// add cookie store for non-persistent cookies (some services like Horde use cookies for session tracking)
|
// add cookie store for non-persistent cookies (some services like Horde use cookies for session tracking)
|
||||||
builder.cookieJar(MemoryCookieStore.INSTANCE);
|
builder.cookieJar(MemoryCookieStore.INSTANCE);
|
||||||
|
|
||||||
if (context != null && account != null) {
|
// add network logging, if requested
|
||||||
// use account settings for authentication and logging
|
|
||||||
AccountSettings settings = new AccountSettings(context, account);
|
|
||||||
|
|
||||||
if (settings.preemptiveAuth())
|
|
||||||
builder.addNetworkInterceptor(new PreemptiveAuthenticationInterceptor(settings.username(), settings.password()));
|
|
||||||
else
|
|
||||||
builder.authenticator(new BasicDigestAuthenticator(null, settings.username(), settings.password()));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (logger.isLoggable(Level.FINEST)) {
|
if (logger.isLoggable(Level.FINEST)) {
|
||||||
HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
|
HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
|
||||||
@Override
|
@Override
|
||||||
@ -87,11 +104,7 @@ public class HttpClient {
|
|||||||
builder.addInterceptor(loggingInterceptor);
|
builder.addInterceptor(loggingInterceptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
return builder.build();
|
return builder;
|
||||||
}
|
|
||||||
|
|
||||||
public static OkHttpClient create(Context context, Account account) {
|
|
||||||
return create(context, account, App.log);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static OkHttpClient.Builder addAuthentication(@NonNull OkHttpClient.Builder builder, @NonNull String username, @NonNull String password, boolean preemptive) {
|
private static OkHttpClient.Builder addAuthentication(@NonNull OkHttpClient.Builder builder, @NonNull String username, @NonNull String password, boolean preemptive) {
|
||||||
|
@ -0,0 +1,19 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2013 – 2016 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 android.accounts.Account;
|
||||||
|
|
||||||
|
public class InvalidAccountException extends Exception {
|
||||||
|
|
||||||
|
public InvalidAccountException(Account account) {
|
||||||
|
super("Invalid account: " + account);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -40,16 +40,14 @@ public class PlainTextFormatter extends Formatter {
|
|||||||
|
|
||||||
builder.append(String.format("[%s] %s", shortClassName(r.getSourceClassName()), r.getMessage()));
|
builder.append(String.format("[%s] %s", shortClassName(r.getSourceClassName()), r.getMessage()));
|
||||||
|
|
||||||
if (r.getThrown() != null) {
|
if (r.getThrown() != null)
|
||||||
Throwable thrown = r.getThrown();
|
builder .append("\nEXCEPTION ")
|
||||||
builder.append("\nEXCEPTION ").append(ExceptionUtils.getMessage(thrown));
|
.append(ExceptionUtils.getStackTrace(r.getThrown()));
|
||||||
builder.append("\tstrack trace = ").append(ExceptionUtils.getStackTrace(thrown));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (r.getParameters() != null) {
|
if (r.getParameters() != null) {
|
||||||
int idx = 1;
|
int idx = 1;
|
||||||
for (Object param : r.getParameters())
|
for (Object param : r.getParameters())
|
||||||
builder.append("\n\tPARAMETER #").append(idx).append(" = ").append(param);
|
builder.append("\n\tPARAMETER #").append(idx++).append(" = ").append(param);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!logcat)
|
if (!logcat)
|
||||||
|
@ -43,6 +43,7 @@ import at.bitfire.dav4android.property.GetETag;
|
|||||||
import at.bitfire.davdroid.App;
|
import at.bitfire.davdroid.App;
|
||||||
import at.bitfire.davdroid.ArrayUtils;
|
import at.bitfire.davdroid.ArrayUtils;
|
||||||
import at.bitfire.davdroid.Constants;
|
import at.bitfire.davdroid.Constants;
|
||||||
|
import at.bitfire.davdroid.InvalidAccountException;
|
||||||
import at.bitfire.davdroid.R;
|
import at.bitfire.davdroid.R;
|
||||||
import at.bitfire.davdroid.resource.LocalCalendar;
|
import at.bitfire.davdroid.resource.LocalCalendar;
|
||||||
import at.bitfire.davdroid.resource.LocalEvent;
|
import at.bitfire.davdroid.resource.LocalEvent;
|
||||||
@ -62,7 +63,7 @@ public class CalendarSyncManager extends SyncManager {
|
|||||||
protected static final int MAX_MULTIGET = 20;
|
protected static final int MAX_MULTIGET = 20;
|
||||||
|
|
||||||
|
|
||||||
public CalendarSyncManager(Context context, Account account, Bundle extras, String authority, SyncResult result, LocalCalendar calendar) {
|
public CalendarSyncManager(Context context, Account account, Bundle extras, String authority, SyncResult result, LocalCalendar calendar) throws InvalidAccountException {
|
||||||
super(Constants.NOTIFICATION_CALENDAR_SYNC, context, account, extras, authority, result);
|
super(Constants.NOTIFICATION_CALENDAR_SYNC, context, account, extras, authority, result);
|
||||||
localCollection = calendar;
|
localCollection = calendar;
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,7 @@ import java.util.Map;
|
|||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
|
||||||
import at.bitfire.davdroid.App;
|
import at.bitfire.davdroid.App;
|
||||||
|
import at.bitfire.davdroid.InvalidAccountException;
|
||||||
import at.bitfire.davdroid.model.CollectionInfo;
|
import at.bitfire.davdroid.model.CollectionInfo;
|
||||||
import at.bitfire.davdroid.model.ServiceDB.Collections;
|
import at.bitfire.davdroid.model.ServiceDB.Collections;
|
||||||
import at.bitfire.davdroid.model.ServiceDB.OpenHelper;
|
import at.bitfire.davdroid.model.ServiceDB.OpenHelper;
|
||||||
@ -64,6 +65,9 @@ public class CalendarsSyncAdapterService extends SyncAdapterService {
|
|||||||
}
|
}
|
||||||
} catch (CalendarStorageException e) {
|
} catch (CalendarStorageException e) {
|
||||||
App.log.log(Level.SEVERE, "Couldn't enumerate local calendars", e);
|
App.log.log(Level.SEVERE, "Couldn't enumerate local calendars", e);
|
||||||
|
syncResult.databaseError = true;
|
||||||
|
} catch (InvalidAccountException e) {
|
||||||
|
App.log.log(Level.SEVERE, "Couldn't get account settings", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
App.log.info("Calendar sync complete");
|
App.log.info("Calendar sync complete");
|
||||||
|
@ -24,9 +24,11 @@ import android.support.annotation.NonNull;
|
|||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
import at.bitfire.davdroid.AccountSettings;
|
import at.bitfire.davdroid.AccountSettings;
|
||||||
import at.bitfire.davdroid.App;
|
import at.bitfire.davdroid.App;
|
||||||
|
import at.bitfire.davdroid.InvalidAccountException;
|
||||||
import at.bitfire.davdroid.model.CollectionInfo;
|
import at.bitfire.davdroid.model.CollectionInfo;
|
||||||
import at.bitfire.davdroid.model.ServiceDB;
|
import at.bitfire.davdroid.model.ServiceDB;
|
||||||
import at.bitfire.davdroid.model.ServiceDB.Collections;
|
import at.bitfire.davdroid.model.ServiceDB.Collections;
|
||||||
@ -55,10 +57,14 @@ public class ContactsSyncAdapterService extends SyncAdapterService {
|
|||||||
Long service = getService(account);
|
Long service = getService(account);
|
||||||
if (service != null) {
|
if (service != null) {
|
||||||
CollectionInfo remote = remoteAddressBook(service);
|
CollectionInfo remote = remoteAddressBook(service);
|
||||||
if (remote != null) {
|
if (remote != null)
|
||||||
ContactsSyncManager syncManager = new ContactsSyncManager(getContext(), account, extras, authority, provider, syncResult, remote);
|
try {
|
||||||
syncManager.performSync();
|
ContactsSyncManager syncManager = new ContactsSyncManager(getContext(), account, extras, authority, provider, syncResult, remote);
|
||||||
} else
|
syncManager.performSync();
|
||||||
|
} catch (InvalidAccountException e) {
|
||||||
|
App.log.log(Level.SEVERE, "Couldn't get account settings", e);
|
||||||
|
}
|
||||||
|
else
|
||||||
App.log.info("No address book collection selected for synchronization");
|
App.log.info("No address book collection selected for synchronization");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,6 +39,7 @@ import at.bitfire.davdroid.App;
|
|||||||
import at.bitfire.davdroid.ArrayUtils;
|
import at.bitfire.davdroid.ArrayUtils;
|
||||||
import at.bitfire.davdroid.Constants;
|
import at.bitfire.davdroid.Constants;
|
||||||
import at.bitfire.davdroid.HttpClient;
|
import at.bitfire.davdroid.HttpClient;
|
||||||
|
import at.bitfire.davdroid.InvalidAccountException;
|
||||||
import at.bitfire.davdroid.R;
|
import at.bitfire.davdroid.R;
|
||||||
import at.bitfire.davdroid.model.CollectionInfo;
|
import at.bitfire.davdroid.model.CollectionInfo;
|
||||||
import at.bitfire.davdroid.resource.LocalAddressBook;
|
import at.bitfire.davdroid.resource.LocalAddressBook;
|
||||||
@ -68,7 +69,7 @@ public class ContactsSyncManager extends SyncManager {
|
|||||||
private boolean hasVCard4;
|
private boolean hasVCard4;
|
||||||
|
|
||||||
|
|
||||||
public ContactsSyncManager(Context context, Account account, Bundle extras, String authority, ContentProviderClient provider, SyncResult result, CollectionInfo remote) {
|
public ContactsSyncManager(Context context, Account account, Bundle extras, String authority, ContentProviderClient provider, SyncResult result, CollectionInfo remote) throws InvalidAccountException {
|
||||||
super(Constants.NOTIFICATION_CONTACTS_SYNC, context, account, extras, authority, result);
|
super(Constants.NOTIFICATION_CONTACTS_SYNC, context, account, extras, authority, result);
|
||||||
this.provider = provider;
|
this.provider = provider;
|
||||||
this.remote = remote;
|
this.remote = remote;
|
||||||
@ -291,7 +292,7 @@ public class ContactsSyncManager extends SyncManager {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
OkHttpClient resourceClient = HttpClient.create(context, null);
|
OkHttpClient resourceClient = HttpClient.create();
|
||||||
|
|
||||||
// authenticate only against a certain host, and only upon request
|
// authenticate only against a certain host, and only upon request
|
||||||
resourceClient = HttpClient.addAuthentication(resourceClient, baseUrl.host(), settings.username(), settings.password());
|
resourceClient = HttpClient.addAuthentication(resourceClient, baseUrl.host(), settings.username(), settings.password());
|
||||||
|
@ -20,8 +20,11 @@ import android.os.Bundle;
|
|||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
|
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
import at.bitfire.davdroid.AccountSettings;
|
import at.bitfire.davdroid.AccountSettings;
|
||||||
import at.bitfire.davdroid.App;
|
import at.bitfire.davdroid.App;
|
||||||
|
import at.bitfire.davdroid.InvalidAccountException;
|
||||||
import at.bitfire.davdroid.model.ServiceDB;
|
import at.bitfire.davdroid.model.ServiceDB;
|
||||||
|
|
||||||
public abstract class SyncAdapterService extends Service {
|
public abstract class SyncAdapterService extends Service {
|
||||||
@ -62,7 +65,11 @@ public abstract class SyncAdapterService extends Service {
|
|||||||
Thread.currentThread().setContextClassLoader(getContext().getClassLoader());
|
Thread.currentThread().setContextClassLoader(getContext().getClassLoader());
|
||||||
|
|
||||||
// peek into AccountSettings to cause possible migration (v0.9 -> v1.0)
|
// peek into AccountSettings to cause possible migration (v0.9 -> v1.0)
|
||||||
new AccountSettings(getContext(), account);
|
try {
|
||||||
|
new AccountSettings(getContext(), account);
|
||||||
|
} catch (InvalidAccountException e) {
|
||||||
|
App.log.log(Level.SEVERE, "Couldn't check for updated account settings", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,6 +42,7 @@ import at.bitfire.dav4android.property.GetETag;
|
|||||||
import at.bitfire.davdroid.AccountSettings;
|
import at.bitfire.davdroid.AccountSettings;
|
||||||
import at.bitfire.davdroid.App;
|
import at.bitfire.davdroid.App;
|
||||||
import at.bitfire.davdroid.HttpClient;
|
import at.bitfire.davdroid.HttpClient;
|
||||||
|
import at.bitfire.davdroid.InvalidAccountException;
|
||||||
import at.bitfire.davdroid.R;
|
import at.bitfire.davdroid.R;
|
||||||
import at.bitfire.davdroid.resource.LocalCollection;
|
import at.bitfire.davdroid.resource.LocalCollection;
|
||||||
import at.bitfire.davdroid.resource.LocalResource;
|
import at.bitfire.davdroid.resource.LocalResource;
|
||||||
@ -99,7 +100,7 @@ abstract public class SyncManager {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
public SyncManager(int notificationId, Context context, Account account, Bundle extras, String authority, SyncResult syncResult) {
|
public SyncManager(int notificationId, Context context, Account account, Bundle extras, String authority, SyncResult syncResult) throws InvalidAccountException {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.account = account;
|
this.account = account;
|
||||||
this.extras = extras;
|
this.extras = extras;
|
||||||
|
@ -26,6 +26,7 @@ import java.util.Map;
|
|||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
|
||||||
import at.bitfire.davdroid.App;
|
import at.bitfire.davdroid.App;
|
||||||
|
import at.bitfire.davdroid.InvalidAccountException;
|
||||||
import at.bitfire.davdroid.model.CollectionInfo;
|
import at.bitfire.davdroid.model.CollectionInfo;
|
||||||
import at.bitfire.davdroid.model.ServiceDB.Collections;
|
import at.bitfire.davdroid.model.ServiceDB.Collections;
|
||||||
import at.bitfire.davdroid.model.ServiceDB.OpenHelper;
|
import at.bitfire.davdroid.model.ServiceDB.OpenHelper;
|
||||||
@ -68,6 +69,8 @@ public class TasksSyncAdapterService extends SyncAdapterService {
|
|||||||
}
|
}
|
||||||
} catch (CalendarStorageException e) {
|
} catch (CalendarStorageException e) {
|
||||||
App.log.log(Level.SEVERE, "Couldn't enumerate local task lists", e);
|
App.log.log(Level.SEVERE, "Couldn't enumerate local task lists", e);
|
||||||
|
} catch (InvalidAccountException e) {
|
||||||
|
App.log.log(Level.SEVERE, "Couldn't get account settings", e);
|
||||||
} finally {
|
} finally {
|
||||||
db.close();
|
db.close();
|
||||||
}
|
}
|
||||||
|
@ -43,6 +43,7 @@ import at.bitfire.dav4android.property.GetETag;
|
|||||||
import at.bitfire.davdroid.App;
|
import at.bitfire.davdroid.App;
|
||||||
import at.bitfire.davdroid.ArrayUtils;
|
import at.bitfire.davdroid.ArrayUtils;
|
||||||
import at.bitfire.davdroid.Constants;
|
import at.bitfire.davdroid.Constants;
|
||||||
|
import at.bitfire.davdroid.InvalidAccountException;
|
||||||
import at.bitfire.davdroid.R;
|
import at.bitfire.davdroid.R;
|
||||||
import at.bitfire.davdroid.resource.LocalResource;
|
import at.bitfire.davdroid.resource.LocalResource;
|
||||||
import at.bitfire.davdroid.resource.LocalTask;
|
import at.bitfire.davdroid.resource.LocalTask;
|
||||||
@ -64,7 +65,7 @@ public class TasksSyncManager extends SyncManager {
|
|||||||
final protected TaskProvider provider;
|
final protected TaskProvider provider;
|
||||||
|
|
||||||
|
|
||||||
public TasksSyncManager(Context context, Account account, Bundle extras, String authority, TaskProvider provider, SyncResult result, LocalTaskList taskList) {
|
public TasksSyncManager(Context context, Account account, Bundle extras, String authority, TaskProvider provider, SyncResult result, LocalTaskList taskList) throws InvalidAccountException {
|
||||||
super(Constants.NOTIFICATION_TASK_SYNC, context, account, extras, authority, result);
|
super(Constants.NOTIFICATION_TASK_SYNC, context, account, extras, authority, result);
|
||||||
this.provider = provider;
|
this.provider = provider;
|
||||||
localCollection = taskList;
|
localCollection = taskList;
|
||||||
|
@ -66,6 +66,7 @@ import at.bitfire.davdroid.AccountSettings;
|
|||||||
import at.bitfire.davdroid.App;
|
import at.bitfire.davdroid.App;
|
||||||
import at.bitfire.davdroid.Constants;
|
import at.bitfire.davdroid.Constants;
|
||||||
import at.bitfire.davdroid.DavService;
|
import at.bitfire.davdroid.DavService;
|
||||||
|
import at.bitfire.davdroid.InvalidAccountException;
|
||||||
import at.bitfire.davdroid.R;
|
import at.bitfire.davdroid.R;
|
||||||
import at.bitfire.davdroid.model.CollectionInfo;
|
import at.bitfire.davdroid.model.CollectionInfo;
|
||||||
import at.bitfire.davdroid.model.ServiceDB;
|
import at.bitfire.davdroid.model.ServiceDB;
|
||||||
@ -275,6 +276,12 @@ public class AccountActivity extends AppCompatActivity implements Toolbar.OnMenu
|
|||||||
public void onLoadFinished(Loader<AccountInfo> loader, final AccountInfo info) {
|
public void onLoadFinished(Loader<AccountInfo> loader, final AccountInfo info) {
|
||||||
accountInfo = info;
|
accountInfo = info;
|
||||||
|
|
||||||
|
if (accountInfo == null) {
|
||||||
|
// account doesn't exist anymore
|
||||||
|
finish();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
CardView card = (CardView)findViewById(R.id.carddav);
|
CardView card = (CardView)findViewById(R.id.carddav);
|
||||||
if (info.carddav != null) {
|
if (info.carddav != null) {
|
||||||
ProgressBar progress = (ProgressBar)findViewById(R.id.carddav_refreshing);
|
ProgressBar progress = (ProgressBar)findViewById(R.id.carddav_refreshing);
|
||||||
@ -368,9 +375,13 @@ public class AccountActivity extends AppCompatActivity implements Toolbar.OnMenu
|
|||||||
public AccountInfo loadInBackground() {
|
public AccountInfo loadInBackground() {
|
||||||
// peek into AccountSettings to call possible 0.9 -> 1.0 migration
|
// peek into AccountSettings to call possible 0.9 -> 1.0 migration
|
||||||
// The next line can be removed as soon as migration from 0.9 is not required anymore!
|
// The next line can be removed as soon as migration from 0.9 is not required anymore!
|
||||||
new AccountSettings(getContext(), new Account(accountName, Constants.ACCOUNT_TYPE));
|
try {
|
||||||
|
new AccountSettings(getContext(), new Account(accountName, Constants.ACCOUNT_TYPE));
|
||||||
|
} catch (InvalidAccountException e) {
|
||||||
|
App.log.log(Level.INFO, "Account doesn't exist (anymore)", e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
// get account info
|
|
||||||
AccountInfo info = new AccountInfo();
|
AccountInfo info = new AccountInfo();
|
||||||
try {
|
try {
|
||||||
SQLiteDatabase db = dbHelper.getReadableDatabase();
|
SQLiteDatabase db = dbHelper.getReadableDatabase();
|
||||||
|
@ -24,7 +24,11 @@ import android.support.v7.preference.PreferenceFragmentCompat;
|
|||||||
import android.support.v7.preference.SwitchPreferenceCompat;
|
import android.support.v7.preference.SwitchPreferenceCompat;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
|
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
import at.bitfire.davdroid.AccountSettings;
|
import at.bitfire.davdroid.AccountSettings;
|
||||||
|
import at.bitfire.davdroid.App;
|
||||||
|
import at.bitfire.davdroid.InvalidAccountException;
|
||||||
import at.bitfire.davdroid.R;
|
import at.bitfire.davdroid.R;
|
||||||
import at.bitfire.ical4android.TaskProvider;
|
import at.bitfire.ical4android.TaskProvider;
|
||||||
|
|
||||||
@ -77,7 +81,15 @@ public class AccountSettingsActivity extends AppCompatActivity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void refresh() {
|
public void refresh() {
|
||||||
final AccountSettings settings = new AccountSettings(getActivity(), account);
|
final AccountSettings settings;
|
||||||
|
|
||||||
|
try {
|
||||||
|
settings = new AccountSettings(getActivity(), account);
|
||||||
|
} catch(InvalidAccountException e) {
|
||||||
|
App.log.log(Level.INFO, "Account is invalid or doesn't exist (anymore)", e);
|
||||||
|
getActivity().finish();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// category: authentication
|
// category: authentication
|
||||||
final EditTextPreference prefUserName = (EditTextPreference)findPreference("username");
|
final EditTextPreference prefUserName = (EditTextPreference)findPreference("username");
|
||||||
|
@ -36,6 +36,7 @@ import at.bitfire.dav4android.exception.HttpException;
|
|||||||
import at.bitfire.davdroid.App;
|
import at.bitfire.davdroid.App;
|
||||||
import at.bitfire.davdroid.DavUtils;
|
import at.bitfire.davdroid.DavUtils;
|
||||||
import at.bitfire.davdroid.HttpClient;
|
import at.bitfire.davdroid.HttpClient;
|
||||||
|
import at.bitfire.davdroid.InvalidAccountException;
|
||||||
import at.bitfire.davdroid.R;
|
import at.bitfire.davdroid.R;
|
||||||
import at.bitfire.davdroid.model.CollectionInfo;
|
import at.bitfire.davdroid.model.CollectionInfo;
|
||||||
import at.bitfire.davdroid.model.ServiceDB;
|
import at.bitfire.davdroid.model.ServiceDB;
|
||||||
@ -208,9 +209,10 @@ public class CreateCollectionFragment extends DialogFragment implements LoaderMa
|
|||||||
|
|
||||||
ServiceDB.OpenHelper dbHelper = new ServiceDB.OpenHelper(getContext());
|
ServiceDB.OpenHelper dbHelper = new ServiceDB.OpenHelper(getContext());
|
||||||
|
|
||||||
OkHttpClient client = HttpClient.create(getContext(), account);
|
|
||||||
DavResource collection = new DavResource(client, HttpUrl.parse(info.url));
|
|
||||||
try {
|
try {
|
||||||
|
OkHttpClient client = HttpClient.create(getContext(), account);
|
||||||
|
DavResource collection = new DavResource(client, HttpUrl.parse(info.url));
|
||||||
|
|
||||||
// create collection on remote server
|
// create collection on remote server
|
||||||
collection.mkCol(writer.toString());
|
collection.mkCol(writer.toString());
|
||||||
|
|
||||||
@ -237,7 +239,7 @@ public class CreateCollectionFragment extends DialogFragment implements LoaderMa
|
|||||||
ContentValues values = info.toDB();
|
ContentValues values = info.toDB();
|
||||||
values.put(ServiceDB.Collections.SERVICE_ID, serviceID);
|
values.put(ServiceDB.Collections.SERVICE_ID, serviceID);
|
||||||
db.insert(ServiceDB.Collections._TABLE, null, values);
|
db.insert(ServiceDB.Collections._TABLE, null, values);
|
||||||
} catch(IOException|HttpException|IllegalStateException e) {
|
} catch(InvalidAccountException|IOException|HttpException|IllegalStateException e) {
|
||||||
return e;
|
return e;
|
||||||
} finally {
|
} finally {
|
||||||
dbHelper.close();
|
dbHelper.close();
|
||||||
|
@ -48,6 +48,7 @@ import at.bitfire.davdroid.AccountSettings;
|
|||||||
import at.bitfire.davdroid.App;
|
import at.bitfire.davdroid.App;
|
||||||
import at.bitfire.davdroid.BuildConfig;
|
import at.bitfire.davdroid.BuildConfig;
|
||||||
import at.bitfire.davdroid.Constants;
|
import at.bitfire.davdroid.Constants;
|
||||||
|
import at.bitfire.davdroid.InvalidAccountException;
|
||||||
import at.bitfire.davdroid.R;
|
import at.bitfire.davdroid.R;
|
||||||
import at.bitfire.davdroid.model.ServiceDB;
|
import at.bitfire.davdroid.model.ServiceDB;
|
||||||
import lombok.Cleanup;
|
import lombok.Cleanup;
|
||||||
@ -185,7 +186,6 @@ public class DebugInfoActivity extends AppCompatActivity implements LoaderManage
|
|||||||
|
|
||||||
if (exception != null)
|
if (exception != null)
|
||||||
report .append("\nEXCEPTION:\n")
|
report .append("\nEXCEPTION:\n")
|
||||||
.append(ExceptionUtils.getMessage(exception)).append("\n")
|
|
||||||
.append(ExceptionUtils.getStackTrace(exception));
|
.append(ExceptionUtils.getStackTrace(exception));
|
||||||
|
|
||||||
if (logs != null)
|
if (logs != null)
|
||||||
@ -212,14 +212,17 @@ public class DebugInfoActivity extends AppCompatActivity implements LoaderManage
|
|||||||
"CONFIGURATION\n" +
|
"CONFIGURATION\n" +
|
||||||
"System-wide synchronization: ").append(ContentResolver.getMasterSyncAutomatically() ? "automatically" : "manually").append("\n");
|
"System-wide synchronization: ").append(ContentResolver.getMasterSyncAutomatically() ? "automatically" : "manually").append("\n");
|
||||||
AccountManager accountManager = AccountManager.get(getContext());
|
AccountManager accountManager = AccountManager.get(getContext());
|
||||||
for (Account acct : accountManager.getAccountsByType(Constants.ACCOUNT_TYPE)) {
|
for (Account acct : accountManager.getAccountsByType(Constants.ACCOUNT_TYPE))
|
||||||
AccountSettings settings = new AccountSettings(getContext(), acct);
|
try {
|
||||||
report.append(
|
AccountSettings settings = new AccountSettings(getContext(), acct);
|
||||||
"Account: ").append(acct.name).append("\n" +
|
report.append(
|
||||||
" Address book sync. interval: ").append(syncStatus(settings, ContactsContract.AUTHORITY)).append("\n" +
|
"Account: ").append(acct.name).append("\n" +
|
||||||
" Calendar sync. interval: ").append(syncStatus(settings, CalendarContract.AUTHORITY)).append("\n" +
|
" Address book sync. interval: ").append(syncStatus(settings, ContactsContract.AUTHORITY)).append("\n" +
|
||||||
" OpenTasks sync. interval: ").append(syncStatus(settings, "org.dmfs.tasks")).append("\n");
|
" Calendar sync. interval: ").append(syncStatus(settings, CalendarContract.AUTHORITY)).append("\n" +
|
||||||
}
|
" OpenTasks sync. interval: ").append(syncStatus(settings, "org.dmfs.tasks")).append("\n");
|
||||||
|
} catch(InvalidAccountException e) {
|
||||||
|
report.append(acct).append(" is invalid (unsupported settings version) or does not exist\n");
|
||||||
|
}
|
||||||
report.append("\n");
|
report.append("\n");
|
||||||
|
|
||||||
report.append("SQLITE DUMP\n");
|
report.append("SQLITE DUMP\n");
|
||||||
|
@ -29,6 +29,7 @@ import java.io.IOException;
|
|||||||
import at.bitfire.dav4android.DavResource;
|
import at.bitfire.dav4android.DavResource;
|
||||||
import at.bitfire.dav4android.exception.HttpException;
|
import at.bitfire.dav4android.exception.HttpException;
|
||||||
import at.bitfire.davdroid.HttpClient;
|
import at.bitfire.davdroid.HttpClient;
|
||||||
|
import at.bitfire.davdroid.InvalidAccountException;
|
||||||
import at.bitfire.davdroid.R;
|
import at.bitfire.davdroid.R;
|
||||||
import at.bitfire.davdroid.model.CollectionInfo;
|
import at.bitfire.davdroid.model.CollectionInfo;
|
||||||
import at.bitfire.davdroid.model.ServiceDB;
|
import at.bitfire.davdroid.model.ServiceDB;
|
||||||
@ -109,10 +110,10 @@ public class DeleteCollectionFragment extends DialogFragment implements LoaderMa
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Exception loadInBackground() {
|
public Exception loadInBackground() {
|
||||||
OkHttpClient httpClient = HttpClient.create(getContext(), account);
|
|
||||||
|
|
||||||
DavResource collection = new DavResource(httpClient, HttpUrl.parse(collectionInfo.url));
|
|
||||||
try {
|
try {
|
||||||
|
OkHttpClient httpClient = HttpClient.create(getContext(), account);
|
||||||
|
DavResource collection = new DavResource(httpClient, HttpUrl.parse(collectionInfo.url));
|
||||||
|
|
||||||
// delete collection from server
|
// delete collection from server
|
||||||
collection.delete(null);
|
collection.delete(null);
|
||||||
|
|
||||||
@ -121,7 +122,7 @@ public class DeleteCollectionFragment extends DialogFragment implements LoaderMa
|
|||||||
db.delete(ServiceDB.Collections._TABLE, ServiceDB.Collections.ID + "=?", new String[] { String.valueOf(collectionInfo.id) });
|
db.delete(ServiceDB.Collections._TABLE, ServiceDB.Collections.ID + "=?", new String[] { String.valueOf(collectionInfo.id) });
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
} catch (IOException|HttpException e) {
|
} catch (InvalidAccountException|IOException|HttpException e) {
|
||||||
return e;
|
return e;
|
||||||
} finally {
|
} finally {
|
||||||
dbHelper.close();
|
dbHelper.close();
|
||||||
|
@ -92,15 +92,16 @@ public class AccountDetailsFragment extends Fragment {
|
|||||||
protected boolean createAccount(String accountName, DavResourceFinder.Configuration config) {
|
protected boolean createAccount(String accountName, DavResourceFinder.Configuration config) {
|
||||||
Account account = new Account(accountName, Constants.ACCOUNT_TYPE);
|
Account account = new Account(accountName, Constants.ACCOUNT_TYPE);
|
||||||
|
|
||||||
App.log.log(Level.INFO, "Creating account " + accountName + " with initial config", config);
|
|
||||||
|
|
||||||
// create Android account
|
// create Android account
|
||||||
AccountManager accountManager = AccountManager.get(getContext());
|
|
||||||
Bundle userData = AccountSettings.initialUserData(config.userName, config.preemptive);
|
Bundle userData = AccountSettings.initialUserData(config.userName, config.preemptive);
|
||||||
|
App.log.log(Level.INFO, "Creating Android account with initial config", new Object[] { account, userData });
|
||||||
|
|
||||||
|
AccountManager accountManager = AccountManager.get(getContext());
|
||||||
if (!accountManager.addAccountExplicitly(account, config.password, userData))
|
if (!accountManager.addAccountExplicitly(account, config.password, userData))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// add entries for account to service DB
|
// add entries for account to service DB
|
||||||
|
App.log.log(Level.INFO, "Writing account configuration to database", config);
|
||||||
@Cleanup OpenHelper dbHelper = new OpenHelper(getContext());
|
@Cleanup OpenHelper dbHelper = new OpenHelper(getContext());
|
||||||
SQLiteDatabase db = dbHelper.getWritableDatabase();
|
SQLiteDatabase db = dbHelper.getWritableDatabase();
|
||||||
db.beginTransactionNonExclusive();
|
db.beginTransactionNonExclusive();
|
||||||
|
@ -45,6 +45,7 @@ import at.bitfire.dav4android.property.DisplayName;
|
|||||||
import at.bitfire.dav4android.property.ResourceType;
|
import at.bitfire.dav4android.property.ResourceType;
|
||||||
import at.bitfire.dav4android.property.SupportedCalendarComponentSet;
|
import at.bitfire.dav4android.property.SupportedCalendarComponentSet;
|
||||||
import at.bitfire.davdroid.HttpClient;
|
import at.bitfire.davdroid.HttpClient;
|
||||||
|
import at.bitfire.davdroid.InvalidAccountException;
|
||||||
import at.bitfire.davdroid.log.StringHandler;
|
import at.bitfire.davdroid.log.StringHandler;
|
||||||
import at.bitfire.davdroid.model.CollectionInfo;
|
import at.bitfire.davdroid.model.CollectionInfo;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
@ -76,7 +77,7 @@ public class DavResourceFinder {
|
|||||||
log = Logger.getLogger("davdroid.DavResourceFinder");
|
log = Logger.getLogger("davdroid.DavResourceFinder");
|
||||||
log.addHandler(logBuffer);
|
log.addHandler(logBuffer);
|
||||||
|
|
||||||
httpClient = HttpClient.create(context, null, log);
|
httpClient = HttpClient.create(log);
|
||||||
httpClient = HttpClient.addAuthentication(httpClient, credentials.userName, credentials.password, credentials.authPreemptive);
|
httpClient = HttpClient.addAuthentication(httpClient, credentials.userName, credentials.password, credentials.authPreemptive);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,6 +21,8 @@ import android.support.v4.content.AsyncTaskLoader;
|
|||||||
import android.support.v4.content.Loader;
|
import android.support.v4.content.Loader;
|
||||||
import android.support.v7.app.AlertDialog;
|
import android.support.v7.app.AlertDialog;
|
||||||
|
|
||||||
|
import at.bitfire.davdroid.App;
|
||||||
|
import at.bitfire.davdroid.InvalidAccountException;
|
||||||
import at.bitfire.davdroid.R;
|
import at.bitfire.davdroid.R;
|
||||||
import at.bitfire.davdroid.ui.DebugInfoActivity;
|
import at.bitfire.davdroid.ui.DebugInfoActivity;
|
||||||
import at.bitfire.davdroid.ui.setup.DavResourceFinder.Configuration;
|
import at.bitfire.davdroid.ui.setup.DavResourceFinder.Configuration;
|
||||||
@ -62,17 +64,20 @@ public class DetectConfigurationFragment extends DialogFragment implements Loade
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLoadFinished(Loader<Configuration> loader, Configuration data) {
|
public void onLoadFinished(Loader<Configuration> loader, Configuration data) {
|
||||||
if (data.calDAV == null && data.cardDAV == null)
|
if (data != null) {
|
||||||
// no service found: show error message
|
if (data.calDAV == null && data.cardDAV == null)
|
||||||
getFragmentManager().beginTransaction()
|
// no service found: show error message
|
||||||
.add(NothingDetectedFragment.newInstance(data.logs), null)
|
getFragmentManager().beginTransaction()
|
||||||
.commitAllowingStateLoss();
|
.add(NothingDetectedFragment.newInstance(data.logs), null)
|
||||||
else
|
.commitAllowingStateLoss();
|
||||||
// service found: continue
|
else
|
||||||
getFragmentManager().beginTransaction()
|
// service found: continue
|
||||||
.replace(android.R.id.content, AccountDetailsFragment.newInstance(data))
|
getFragmentManager().beginTransaction()
|
||||||
.addToBackStack(null)
|
.replace(android.R.id.content, AccountDetailsFragment.newInstance(data))
|
||||||
.commitAllowingStateLoss();
|
.addToBackStack(null)
|
||||||
|
.commitAllowingStateLoss();
|
||||||
|
} else
|
||||||
|
App.log.severe("Configuration detection failed");
|
||||||
|
|
||||||
dismissAllowingStateLoss();
|
dismissAllowingStateLoss();
|
||||||
}
|
}
|
||||||
@ -94,6 +99,7 @@ public class DetectConfigurationFragment extends DialogFragment implements Loade
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@NonNull
|
||||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||||
return new AlertDialog.Builder(getActivity())
|
return new AlertDialog.Builder(getActivity())
|
||||||
.setTitle(R.string.login_configuration_detection)
|
.setTitle(R.string.login_configuration_detection)
|
||||||
@ -134,8 +140,7 @@ public class DetectConfigurationFragment extends DialogFragment implements Loade
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Configuration loadInBackground() {
|
public Configuration loadInBackground() {
|
||||||
DavResourceFinder finder = new DavResourceFinder(context, credentials);
|
return new DavResourceFinder(context, credentials).findInitialConfiguration();
|
||||||
return finder.findInitialConfiguration();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user