mirror of
https://github.com/etesync/android
synced 2024-12-23 15:18:14 +00:00
OOM handling, DB transactions, calandar VISIBLE, service refresh notification
* handle and show OutOfMemoryErrors correctly (they're not Exceptions) * use db.beginTransactionNonExclusive() because WAL is enabled * set calendar VISIBLE=1 AND SYNC=1 only at creation and not at every sync * update PendingIntent of service refresh notification
This commit is contained in:
parent
2280f899ee
commit
c6aed90c96
@ -22,6 +22,8 @@ import android.database.sqlite.SQLiteDatabase;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.os.Binder;
|
||||
import android.os.IBinder;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.app.NotificationCompat;
|
||||
import android.text.TextUtils;
|
||||
|
||||
@ -274,7 +276,7 @@ public class DavService extends Service {
|
||||
}
|
||||
|
||||
try {
|
||||
db.beginTransaction();
|
||||
db.beginTransactionNonExclusive();
|
||||
saveHomeSets(homeSets);
|
||||
saveCollections(collections.values());
|
||||
db.setTransactionSuccessful();
|
||||
@ -288,7 +290,7 @@ public class DavService extends Service {
|
||||
App.log.log(Level.SEVERE, "Couldn't refresh collection list", e);
|
||||
|
||||
Intent debugIntent = new Intent(DavService.this, DebugInfoActivity.class);
|
||||
debugIntent.putExtra(DebugInfoActivity.KEY_EXCEPTION, e);
|
||||
debugIntent.putExtra(DebugInfoActivity.KEY_THROWABLE, e);
|
||||
if (account != null)
|
||||
debugIntent.putExtra(DebugInfoActivity.KEY_ACCOUNT, account);
|
||||
|
||||
@ -298,7 +300,7 @@ public class DavService extends Service {
|
||||
.setLargeIcon(((BitmapDrawable)getResources().getDrawable(R.drawable.ic_launcher)).getBitmap())
|
||||
.setContentTitle(getString(R.string.dav_service_refresh_failed))
|
||||
.setContentText(getString(R.string.dav_service_refresh_couldnt_refresh))
|
||||
.setContentIntent(PendingIntent.getActivity(DavService.this, 0, debugIntent, 0))
|
||||
.setContentIntent(PendingIntent.getActivity(DavService.this, 0, debugIntent, PendingIntent.FLAG_UPDATE_CURRENT))
|
||||
.build();
|
||||
nm.notify(Constants.NOTIFICATION_REFRESH_COLLECTIONS, notify);
|
||||
} finally {
|
||||
@ -333,6 +335,7 @@ public class DavService extends Service {
|
||||
}
|
||||
|
||||
|
||||
@NonNull
|
||||
private Account account() {
|
||||
@Cleanup Cursor cursor = db.query(Services._TABLE, new String[] { Services.ACCOUNT_NAME }, Services.ID + "=?", new String[] { String.valueOf(service) }, null, null, null);
|
||||
if (cursor.moveToNext()) {
|
||||
@ -341,6 +344,7 @@ public class DavService extends Service {
|
||||
throw new IllegalArgumentException("Service not found");
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private String serviceType() {
|
||||
@Cleanup Cursor cursor = db.query(Services._TABLE, new String[] { Services.SERVICE }, Services.ID + "=?", new String[] { String.valueOf(service) }, null, null, null);
|
||||
if (cursor.moveToNext())
|
||||
@ -349,6 +353,7 @@ public class DavService extends Service {
|
||||
throw new IllegalArgumentException("Service not found");
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private HttpUrl readPrincipal() {
|
||||
@Cleanup Cursor cursor = db.query(Services._TABLE, new String[] { Services.PRINCIPAL }, Services.ID + "=?", new String[] { String.valueOf(service) }, null, null, null);
|
||||
if (cursor.moveToNext()) {
|
||||
@ -359,6 +364,7 @@ public class DavService extends Service {
|
||||
return null;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private Set<HttpUrl> readHomeSets() {
|
||||
Set<HttpUrl> homeSets = new LinkedHashSet<>();
|
||||
@Cleanup Cursor cursor = db.query(HomeSets._TABLE, new String[] { HomeSets.URL }, HomeSets.SERVICE_ID + "=?", new String[] { String.valueOf(service) }, null, null, null);
|
||||
@ -377,6 +383,7 @@ public class DavService extends Service {
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private Map<HttpUrl, CollectionInfo> readCollections() {
|
||||
Map<HttpUrl, CollectionInfo> collections = new LinkedHashMap<>();
|
||||
@Cleanup Cursor cursor = db.query(Collections._TABLE, null, Collections.SERVICE_ID + "=?", new String[]{String.valueOf(service)}, null, null, null);
|
||||
|
@ -80,6 +80,10 @@ public class LocalCalendar extends AndroidCalendar implements LocalCollection {
|
||||
values.put(Calendars.ACCOUNT_TYPE, account.type);
|
||||
values.put(Calendars.OWNER_ACCOUNT, account.name);
|
||||
|
||||
// flag as visible & synchronizable at creation, might be changed by user at any time
|
||||
values.put(Calendars.VISIBLE, 1);
|
||||
values.put(Calendars.SYNC_EVENTS, 1);
|
||||
|
||||
return create(account, provider, values);
|
||||
}
|
||||
|
||||
@ -102,8 +106,6 @@ public class LocalCalendar extends AndroidCalendar implements LocalCollection {
|
||||
values.put(Calendars.CAN_ORGANIZER_RESPOND, 1);
|
||||
}
|
||||
|
||||
values.put(Calendars.SYNC_EVENTS, 1);
|
||||
values.put(Calendars.VISIBLE, 1);
|
||||
if (!TextUtils.isEmpty(info.timeZone)) {
|
||||
VTimeZone timeZone = DateUtils.parseVTimeZone(info.timeZone);
|
||||
if (timeZone != null && timeZone.getTimeZoneId() != null)
|
||||
|
@ -9,14 +9,12 @@ package at.bitfire.davdroid.syncadapter;
|
||||
|
||||
import android.accounts.Account;
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.Notification;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SyncResult;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.app.NotificationCompat;
|
||||
import android.text.TextUtils;
|
||||
@ -46,7 +44,6 @@ import at.bitfire.davdroid.InvalidAccountException;
|
||||
import at.bitfire.davdroid.R;
|
||||
import at.bitfire.davdroid.resource.LocalCollection;
|
||||
import at.bitfire.davdroid.resource.LocalResource;
|
||||
import at.bitfire.davdroid.ui.AccountActivity;
|
||||
import at.bitfire.davdroid.ui.AccountSettingsActivity;
|
||||
import at.bitfire.davdroid.ui.DebugInfoActivity;
|
||||
import at.bitfire.ical4android.CalendarStorageException;
|
||||
@ -215,7 +212,7 @@ abstract public class SyncManager {
|
||||
detailsIntent.putExtra(AccountSettingsActivity.EXTRA_ACCOUNT, account);
|
||||
} else {
|
||||
detailsIntent = new Intent(context, DebugInfoActivity.class);
|
||||
detailsIntent.putExtra(DebugInfoActivity.KEY_EXCEPTION, e);
|
||||
detailsIntent.putExtra(DebugInfoActivity.KEY_THROWABLE, e);
|
||||
detailsIntent.putExtra(DebugInfoActivity.KEY_ACCOUNT, account);
|
||||
detailsIntent.putExtra(DebugInfoActivity.KEY_AUTHORITY, authority);
|
||||
detailsIntent.putExtra(DebugInfoActivity.KEY_PHASE, syncPhase);
|
||||
|
@ -197,7 +197,7 @@ public class AccountActivity extends AppCompatActivity implements Toolbar.OnMenu
|
||||
OpenHelper dbHelper = new OpenHelper(AccountActivity.this);
|
||||
try {
|
||||
SQLiteDatabase db = dbHelper.getWritableDatabase();
|
||||
db.beginTransaction();
|
||||
db.beginTransactionNonExclusive();
|
||||
|
||||
if (list.getChoiceMode() == AbsListView.CHOICE_MODE_SINGLE) {
|
||||
// disable all other collections
|
||||
|
@ -17,19 +17,13 @@ import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.Loader;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.database.Cursor;
|
||||
import android.database.DatabaseUtils;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.database.sqlite.SQLiteException;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.provider.CalendarContract;
|
||||
import android.provider.ContactsContract;
|
||||
import android.support.v4.database.DatabaseUtilsCompat;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.widget.TextView;
|
||||
@ -55,7 +49,7 @@ import lombok.Cleanup;
|
||||
|
||||
public class DebugInfoActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<String> {
|
||||
public static final String
|
||||
KEY_EXCEPTION = "exception",
|
||||
KEY_THROWABLE = "throwable",
|
||||
KEY_LOGS = "logs",
|
||||
KEY_ACCOUNT = "account",
|
||||
KEY_AUTHORITY = "authority",
|
||||
@ -151,14 +145,14 @@ public class DebugInfoActivity extends AppCompatActivity implements LoaderManage
|
||||
|
||||
@Override
|
||||
public String loadInBackground() {
|
||||
Exception exception = null;
|
||||
Throwable throwable = null;
|
||||
String logs = null,
|
||||
authority = null;
|
||||
Account account = null;
|
||||
int phase = -1;
|
||||
|
||||
if (extras != null) {
|
||||
exception = (Exception)extras.getSerializable(KEY_EXCEPTION);
|
||||
throwable = (Throwable)extras.getSerializable(KEY_THROWABLE);
|
||||
logs = extras.getString(KEY_LOGS);
|
||||
account = extras.getParcelable(KEY_ACCOUNT);
|
||||
authority = extras.getString(KEY_AUTHORITY);
|
||||
@ -176,17 +170,17 @@ public class DebugInfoActivity extends AppCompatActivity implements LoaderManage
|
||||
if (authority != null)
|
||||
report.append("Authority: ").append(authority).append("\n");
|
||||
|
||||
if (exception instanceof HttpException) {
|
||||
HttpException http = (HttpException)exception;
|
||||
if (throwable instanceof HttpException) {
|
||||
HttpException http = (HttpException)throwable;
|
||||
if (http.request != null)
|
||||
report.append("\nHTTP REQUEST:\n").append(http.request).append("\n\n");
|
||||
if (http.response != null)
|
||||
report.append("HTTP RESPONSE:\n").append(http.response).append("\n");
|
||||
}
|
||||
|
||||
if (exception != null)
|
||||
if (throwable != null)
|
||||
report .append("\nEXCEPTION:\n")
|
||||
.append(ExceptionUtils.getStackTrace(exception));
|
||||
.append(ExceptionUtils.getStackTrace(throwable));
|
||||
|
||||
if (logs != null)
|
||||
report.append("\nLOGS:\n").append(logs).append("\n");
|
||||
|
@ -57,7 +57,7 @@ public class ExceptionInfoFragment extends DialogFragment {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
Intent intent = new Intent(getContext(), DebugInfoActivity.class);
|
||||
intent.putExtra(DebugInfoActivity.KEY_EXCEPTION, exception);
|
||||
intent.putExtra(DebugInfoActivity.KEY_THROWABLE, exception);
|
||||
if (account != null)
|
||||
intent.putExtra(DebugInfoActivity.KEY_ACCOUNT, account);
|
||||
startActivity(intent);
|
||||
|
Loading…
Reference in New Issue
Block a user