1
0
mirror of https://github.com/etesync/android synced 2024-11-18 06:08:08 +00:00
etesync-android/app/src/main/java/at/bitfire/davdroid/syncadapter/CalendarsSyncAdapterService.java
2016-02-24 23:08:19 +01:00

142 lines
5.8 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* Copyright © 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.syncadapter;
import android.accounts.Account;
import android.app.Service;
import android.content.AbstractThreadedSyncAdapter;
import android.content.ContentProviderClient;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.SyncResult;
import android.database.Cursor;
import android.database.DatabaseUtils;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.os.IBinder;
import android.provider.CalendarContract;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.logging.Level;
import at.bitfire.davdroid.App;
import at.bitfire.davdroid.model.CollectionInfo;
import at.bitfire.davdroid.model.ServiceDB;
import at.bitfire.davdroid.model.ServiceDB.OpenHelper;
import at.bitfire.davdroid.resource.LocalCalendar;
import at.bitfire.ical4android.CalendarStorageException;
import lombok.Cleanup;
public class CalendarsSyncAdapterService extends Service {
private static SyncAdapter syncAdapter;
private OpenHelper dbHelper;
@Override
public void onCreate() {
dbHelper = new OpenHelper(this);
syncAdapter = new SyncAdapter(this, dbHelper.getReadableDatabase());
}
@Override
public void onDestroy() {
dbHelper.close();
}
@Override
public IBinder onBind(Intent intent) {
return syncAdapter.getSyncAdapterBinder();
}
private static class SyncAdapter extends AbstractThreadedSyncAdapter {
private final SQLiteDatabase db;
public SyncAdapter(Context context, SQLiteDatabase db) {
super(context, false);
this.db = db;
}
@Override
public void onPerformSync(Account account, Bundle extras, String authority, ContentProviderClient provider, SyncResult syncResult) {
App.log.info("Starting calendar sync (" + authority + ")");
// required for ical4j and dav4android (ServiceLoader)
Thread.currentThread().setContextClassLoader(getContext().getClassLoader());
try {
updateLocalCalendars(provider, account);
for (LocalCalendar calendar : (LocalCalendar[])LocalCalendar.find(account, provider, LocalCalendar.Factory.INSTANCE, CalendarContract.Calendars.SYNC_EVENTS + "!=0", null)) {
App.log.info("Synchronizing calendar #" + calendar.getId() + ", URL: " + calendar.getName());
CalendarSyncManager syncManager = new CalendarSyncManager(getContext(), account, extras, authority, syncResult, calendar);
syncManager.performSync();
}
} catch (CalendarStorageException e) {
App.log.log(Level.SEVERE, "Couldn't enumerate local calendars", e);
}
App.log.info("Calendar sync complete");
}
private void updateLocalCalendars(ContentProviderClient provider, Account account) throws CalendarStorageException {
long service = getService(account);
// enumerate remote and local calendars
Map<String, CollectionInfo> remote = remoteCalendars(service);
LocalCalendar[] local = (LocalCalendar[])LocalCalendar.find(account, provider, LocalCalendar.Factory.INSTANCE, null, null);
// delete obsolete local calendar
for (LocalCalendar calendar : local) {
String url = calendar.getName();
if (!remote.containsKey(url)) {
App.log.fine("Deleting obsolete local calendar " + url);
calendar.delete();
} else {
// remote CollectionInfo found for this local collection, update data
CollectionInfo info = remote.get(url);
App.log.fine("Updating local calendar " + url + " with " + info);
calendar.update(info);
// we already have a local calendar for this remote collection, don't take into consideration anymore
remote.remove(url);
}
}
// create new local calendars
for (String url : remote.keySet()) {
CollectionInfo info = remote.get(url);
App.log.info("Adding local calendar list " + info);
LocalCalendar.create(account, provider, info);
}
}
long getService(Account account) {
@Cleanup Cursor c = db.query(ServiceDB.Services._TABLE, new String[]{ServiceDB.Services.ID},
ServiceDB.Services.ACCOUNT_NAME + "=? AND " + ServiceDB.Services.SERVICE + "=?", new String[]{account.name, ServiceDB.Services.SERVICE_CALDAV}, null, null, null);
c.moveToNext();
return c.getLong(0);
}
private Map<String, CollectionInfo> remoteCalendars(long service) {
Map<String, CollectionInfo> collections = new LinkedHashMap<>();
@Cleanup Cursor cursor = db.query(ServiceDB.Collections._TABLE, ServiceDB.Collections._COLUMNS,
ServiceDB.Collections.SERVICE_ID + "=? AND " + ServiceDB.Collections.SUPPORTS_VEVENT + "!=0 AND selected",
new String[] { String.valueOf(service) }, null, null, null);
while (cursor.moveToNext()) {
ContentValues values = new ContentValues();
DatabaseUtils.cursorRowToContentValues(cursor, values);
CollectionInfo info = CollectionInfo.fromDB(values);
collections.put(info.url, info);
}
return collections;
}
}
}