mirror of
https://github.com/etesync/android
synced 2025-02-10 14:43:17 +00:00
![Tom Hacohen](/assets/img/avatar_default.png)
Android allows only having one address book per account, so until now users of EteSync were only able to have one address book. This was always an annoying limitation, but even more so now that journal sharing is implemented. Luckily, DAVdroid recently implemented multiple account support by creating sub-accounts for address books. This patch is an import of the DAVdroid changes, with adjustments to work with EteSync, and a few changes that did not make sense for EteSync. The original commits' split didn't provide any value over this squash, and the amount of adjustments and addition needed to be done to apply them, made me decide to squash this change together. This commit is mostly based on: dfec72ce6b8ff5e0780e9ac4418c81d080f4b60b 9817594da14ad8dffae18de386e14aeaf41312b9
133 lines
4.2 KiB
Java
133 lines
4.2 KiB
Java
/*
|
||
* 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 com.etesync.syncadapter;
|
||
|
||
import android.accounts.Account;
|
||
import android.accounts.AccountManager;
|
||
import android.annotation.SuppressLint;
|
||
import android.app.Service;
|
||
import android.content.Intent;
|
||
import android.database.DatabaseUtils;
|
||
import android.os.Binder;
|
||
import android.os.IBinder;
|
||
import android.support.annotation.NonNull;
|
||
|
||
import com.etesync.syncadapter.model.ServiceEntity;
|
||
import com.etesync.syncadapter.resource.LocalAddressBook;
|
||
|
||
import java.lang.ref.WeakReference;
|
||
import java.util.HashSet;
|
||
import java.util.Iterator;
|
||
import java.util.LinkedList;
|
||
import java.util.List;
|
||
import java.util.Set;
|
||
import java.util.logging.Level;
|
||
|
||
import at.bitfire.vcard4android.ContactsStorageException;
|
||
import io.requery.Persistable;
|
||
import io.requery.sql.EntityDataStore;
|
||
|
||
public class AccountUpdateService extends Service {
|
||
|
||
public static final String
|
||
ACTION_ACCOUNTS_UPDATED = "accountsUpdated";
|
||
|
||
private final IBinder binder = new InfoBinder();
|
||
|
||
private final Set<Long> runningRefresh = new HashSet<>();
|
||
private final List<WeakReference<RefreshingStatusListener>> refreshingStatusListeners = new LinkedList<>();
|
||
|
||
|
||
@Override
|
||
public int onStartCommand(Intent intent, int flags, int startId) {
|
||
if (intent != null) {
|
||
String action = intent.getAction();
|
||
|
||
switch (action) {
|
||
case ACTION_ACCOUNTS_UPDATED:
|
||
cleanupAccounts();
|
||
break;
|
||
}
|
||
}
|
||
|
||
return START_NOT_STICKY;
|
||
}
|
||
|
||
|
||
/* BOUND SERVICE PART
|
||
for communicating with the activities
|
||
*/
|
||
|
||
@Override
|
||
public IBinder onBind(Intent intent) {
|
||
return binder;
|
||
}
|
||
|
||
public interface RefreshingStatusListener {
|
||
void onDavRefreshStatusChanged(long id, boolean refreshing);
|
||
}
|
||
|
||
public class InfoBinder extends Binder {
|
||
public boolean isRefreshing(long id) {
|
||
return runningRefresh.contains(id);
|
||
}
|
||
|
||
public void addRefreshingStatusListener(@NonNull RefreshingStatusListener listener, boolean callImmediate) {
|
||
refreshingStatusListeners.add(new WeakReference<>(listener));
|
||
if (callImmediate)
|
||
for (long id : runningRefresh)
|
||
listener.onDavRefreshStatusChanged(id, true);
|
||
}
|
||
|
||
public void removeRefreshingStatusListener(@NonNull RefreshingStatusListener listener) {
|
||
for (Iterator<WeakReference<RefreshingStatusListener>> iterator = refreshingStatusListeners.iterator(); iterator.hasNext(); ) {
|
||
RefreshingStatusListener item = iterator.next().get();
|
||
if (listener.equals(item))
|
||
iterator.remove();
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
/* ACTION RUNNABLES
|
||
which actually do the work
|
||
*/
|
||
|
||
@SuppressLint("MissingPermission")
|
||
void cleanupAccounts() {
|
||
App.log.info("Cleaning up orphaned accounts");
|
||
|
||
List<String> accountNames = new LinkedList<>();
|
||
AccountManager am = AccountManager.get(this);
|
||
for (Account account : am.getAccountsByType(App.getAccountType())) {
|
||
accountNames.add(account.name);
|
||
}
|
||
|
||
EntityDataStore<Persistable> data = ((App) getApplication()).getData();
|
||
|
||
// delete orphaned address book accounts
|
||
for (Account addrBookAccount : am.getAccountsByType(App.getAddressBookAccountType())) {
|
||
LocalAddressBook addressBook = new LocalAddressBook(this, addrBookAccount, null);
|
||
try {
|
||
if (!accountNames.contains(addressBook.getMainAccount().name))
|
||
addressBook.delete();
|
||
} catch(ContactsStorageException e) {
|
||
App.log.log(Level.SEVERE, "Couldn't get address book main account", e);
|
||
}
|
||
}
|
||
|
||
|
||
if (accountNames.isEmpty()) {
|
||
data.delete(ServiceEntity.class).get().value();
|
||
} else {
|
||
data.delete(ServiceEntity.class).where(ServiceEntity.ACCOUNT.notIn(accountNames)).get().value();
|
||
}
|
||
}
|
||
}
|