mirror of
https://github.com/bitfireAT/davx5-ose
synced 2024-09-06 18:01:11 +00:00
Add SQLite dump to debug report
This commit is contained in:
parent
730a875e23
commit
9dce028f31
|
@ -23,7 +23,6 @@ public class Service {
|
|||
service.accountName = values.getAsString(ServiceDB.Services.ACCOUNT_NAME);
|
||||
service.service = values.getAsString(ServiceDB.Services.SERVICE);
|
||||
service.principal = values.getAsString(ServiceDB.Services.PRINCIPAL);
|
||||
//FIXME service.lastRefresh = values.getAsLong(ServiceDB.Services.LAST_REFRESH);
|
||||
return service;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,11 +9,14 @@
|
|||
package at.bitfire.davdroid.model;
|
||||
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.database.sqlite.SQLiteException;
|
||||
import android.database.sqlite.SQLiteOpenHelper;
|
||||
import android.os.Build;
|
||||
|
||||
import at.bitfire.davdroid.App;
|
||||
import lombok.Cleanup;
|
||||
|
||||
public class ServiceDB {
|
||||
|
||||
|
@ -23,8 +26,7 @@ public class ServiceDB {
|
|||
ID = "_id",
|
||||
ACCOUNT_NAME = "accountName",
|
||||
SERVICE = "service",
|
||||
PRINCIPAL = "principal",
|
||||
LAST_REFRESH = "lastRefresh";
|
||||
PRINCIPAL = "principal";
|
||||
|
||||
// allowed values for SERVICE column
|
||||
public static final String
|
||||
|
@ -87,9 +89,8 @@ public class ServiceDB {
|
|||
Services.ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
|
||||
Services.ACCOUNT_NAME + " TEXT NOT NULL," +
|
||||
Services.SERVICE + " TEXT NOT NULL," +
|
||||
Services.PRINCIPAL + " TEXT NULL, " +
|
||||
Services.LAST_REFRESH + " INTEGER NULL" +
|
||||
")");
|
||||
Services.PRINCIPAL + " TEXT NULL" +
|
||||
")");
|
||||
db.execSQL("CREATE UNIQUE INDEX services_account ON " + Services._TABLE + " (" + Services.ACCOUNT_NAME + "," + Services.SERVICE + ")");
|
||||
|
||||
db.execSQL("CREATE TABLE " + HomeSets._TABLE + "(" +
|
||||
|
@ -117,6 +118,53 @@ public class ServiceDB {
|
|||
@Override
|
||||
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
|
||||
}
|
||||
|
||||
|
||||
public void dump(StringBuilder sb) {
|
||||
SQLiteDatabase db = getReadableDatabase();
|
||||
db.beginTransactionNonExclusive();
|
||||
|
||||
// iterate through all tables
|
||||
@Cleanup Cursor cursorTables = db.query("sqlite_master", new String[] { "name" }, "type='table'", null, null, null, null);
|
||||
while (cursorTables.moveToNext()) {
|
||||
String table = cursorTables.getString(0);
|
||||
sb.append("\t").append(table).append("\n");
|
||||
@Cleanup Cursor cursor = db.query(table, null, null, null, null, null, null);
|
||||
|
||||
// print columns
|
||||
int cols = cursor.getColumnCount();
|
||||
sb.append("\t\t| ");
|
||||
for (int i = 0; i < cols; i++) {
|
||||
sb.append(" ");
|
||||
sb.append(cursor.getColumnName(i));
|
||||
sb.append(" |");
|
||||
}
|
||||
sb.append("\n");
|
||||
|
||||
// print rows
|
||||
while (cursor.moveToNext()) {
|
||||
sb.append("\t\t| ");
|
||||
for (int i = 0; i < cols; i++) {
|
||||
sb.append(" ");
|
||||
try {
|
||||
String value = cursor.getString(i);
|
||||
if (value != null)
|
||||
sb.append(value
|
||||
.replace("\r", "<CR>")
|
||||
.replace("\n", "<LF>"));
|
||||
else
|
||||
sb.append("<null>");
|
||||
|
||||
} catch (SQLiteException e) {
|
||||
sb.append("<unprintable>");
|
||||
}
|
||||
sb.append(" |");
|
||||
}
|
||||
sb.append("\n");
|
||||
}
|
||||
}
|
||||
db.endTransaction();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -7,50 +7,51 @@
|
|||
*/
|
||||
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.text.TextUtils;
|
||||
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;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Level;
|
||||
import java.io.IOException;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import at.bitfire.dav4android.DavResource;
|
||||
import at.bitfire.dav4android.exception.ConflictException;
|
||||
import at.bitfire.dav4android.exception.DavException;
|
||||
import at.bitfire.dav4android.exception.HttpException;
|
||||
import at.bitfire.dav4android.exception.PreconditionFailedException;
|
||||
import at.bitfire.dav4android.exception.ServiceUnavailableException;
|
||||
import at.bitfire.dav4android.exception.UnauthorizedException;
|
||||
import at.bitfire.dav4android.property.GetCTag;
|
||||
import at.bitfire.dav4android.property.GetETag;
|
||||
import at.bitfire.davdroid.AccountSettings;
|
||||
import at.bitfire.davdroid.App;
|
||||
import at.bitfire.davdroid.HttpClient;
|
||||
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.DebugInfoActivity;
|
||||
import at.bitfire.ical4android.CalendarStorageException;
|
||||
import at.bitfire.vcard4android.ContactsStorageException;
|
||||
import okhttp3.HttpUrl;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.RequestBody;
|
||||
import at.bitfire.dav4android.DavResource;
|
||||
import at.bitfire.dav4android.exception.ConflictException;
|
||||
import at.bitfire.dav4android.exception.DavException;
|
||||
import at.bitfire.dav4android.exception.HttpException;
|
||||
import at.bitfire.dav4android.exception.PreconditionFailedException;
|
||||
import at.bitfire.dav4android.exception.ServiceUnavailableException;
|
||||
import at.bitfire.dav4android.exception.UnauthorizedException;
|
||||
import at.bitfire.dav4android.property.GetCTag;
|
||||
import at.bitfire.dav4android.property.GetETag;
|
||||
import at.bitfire.davdroid.AccountSettings;
|
||||
import at.bitfire.davdroid.App;
|
||||
import at.bitfire.davdroid.HttpClient;
|
||||
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.DebugInfoActivity;
|
||||
import at.bitfire.ical4android.CalendarStorageException;
|
||||
import at.bitfire.vcard4android.ContactsStorageException;
|
||||
import okhttp3.HttpUrl;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.RequestBody;
|
||||
|
||||
abstract public class SyncManager {
|
||||
|
||||
|
@ -218,14 +219,12 @@ abstract public class SyncManager {
|
|||
detailsIntent.putExtra(DebugInfoActivity.KEY_PHASE, syncPhase);
|
||||
}
|
||||
|
||||
Notification.Builder builder = new Notification.Builder(context);
|
||||
Notification notification;
|
||||
builder.setSmallIcon(R.drawable.ic_launcher)
|
||||
NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
|
||||
builder .setSmallIcon(R.drawable.ic_launcher)
|
||||
.setContentTitle(getSyncErrorTitle())
|
||||
.setContentIntent(PendingIntent.getActivity(context, notificationId, detailsIntent, PendingIntent.FLAG_UPDATE_CURRENT));
|
||||
|
||||
if (Build.VERSION.SDK_INT >= 20)
|
||||
builder.setLocalOnly(true);
|
||||
.setContentIntent(PendingIntent.getActivity(context, notificationId, detailsIntent, PendingIntent.FLAG_UPDATE_CURRENT))
|
||||
.setCategory(NotificationCompat.CATEGORY_ERROR)
|
||||
.setLocalOnly(true);
|
||||
|
||||
try {
|
||||
String[] phases = context.getResources().getStringArray(R.array.sync_error_phases);
|
||||
|
@ -235,14 +234,7 @@ abstract public class SyncManager {
|
|||
// should never happen
|
||||
}
|
||||
|
||||
if (Build.VERSION.SDK_INT >= 16) {
|
||||
if (Build.VERSION.SDK_INT >= 21)
|
||||
builder.setCategory(Notification.CATEGORY_ERROR);
|
||||
notification = builder.build();
|
||||
} else {
|
||||
notification = builder.getNotification();
|
||||
}
|
||||
notificationManager.notify(account.name, notificationId, notification);
|
||||
notificationManager.notify(account.name, notificationId, builder.build());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -50,6 +50,16 @@ public class AccountsActivity extends AppCompatActivity implements NavigationVie
|
|||
|
||||
NavigationView navigationView = (NavigationView)findViewById(R.id.nav_view);
|
||||
navigationView.setNavigationItemSelectedListener(this);
|
||||
|
||||
if (savedInstanceState == null && !getPackageName().equals(getCallingPackage())) {
|
||||
final String installedFrom = installedFrom();
|
||||
if (installedFrom == null || installedFrom.startsWith("org.fdroid"))
|
||||
getSupportFragmentManager().beginTransaction()
|
||||
.add(new DonateDialogFragment(), null)
|
||||
.commit();
|
||||
else if ("com.android.vending".equals(installedFrom))
|
||||
/* TODO Play Store Dialog */;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -81,4 +91,13 @@ public class AccountsActivity extends AppCompatActivity implements NavigationVie
|
|||
drawer.closeDrawer(GravityCompat.START);
|
||||
return true;
|
||||
}
|
||||
|
||||
private String installedFrom() {
|
||||
try {
|
||||
return getPackageManager().getInstallerPackageName(getPackageName());
|
||||
} catch(IllegalArgumentException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -17,11 +17,16 @@ 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;
|
||||
|
@ -43,6 +48,8 @@ import at.bitfire.davdroid.App;
|
|||
import at.bitfire.davdroid.BuildConfig;
|
||||
import at.bitfire.davdroid.Constants;
|
||||
import at.bitfire.davdroid.R;
|
||||
import at.bitfire.davdroid.model.ServiceDB;
|
||||
import lombok.Cleanup;
|
||||
|
||||
public class DebugInfoActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<String> {
|
||||
public static final String
|
||||
|
@ -57,6 +64,8 @@ public class DebugInfoActivity extends AppCompatActivity implements LoaderManage
|
|||
TextView tvReport;
|
||||
String report;
|
||||
|
||||
File reportFile;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
@ -86,7 +95,7 @@ public class DebugInfoActivity extends AppCompatActivity implements LoaderManage
|
|||
if (report.length() > MAX_INLINE_REPORT_LENGTH)
|
||||
// report is too long for inline text, send it as an attachment
|
||||
try {
|
||||
File reportFile = File.createTempFile("davdroid-debug", ".txt", getExternalCacheDir());
|
||||
reportFile = File.createTempFile("davdroid-debug", ".txt", getExternalCacheDir());
|
||||
App.log.fine("Writing debug info to " + reportFile.getAbsolutePath());
|
||||
FileWriter writer = new FileWriter(reportFile);
|
||||
writer.write(report);
|
||||
|
@ -217,6 +226,11 @@ public class DebugInfoActivity extends AppCompatActivity implements LoaderManage
|
|||
}
|
||||
report.append("\n");
|
||||
|
||||
report.append("SQLITE DUMP\n");
|
||||
@Cleanup ServiceDB.OpenHelper dbHelper = new ServiceDB.OpenHelper(getContext());
|
||||
dbHelper.dump(report);
|
||||
report.append("\n");
|
||||
|
||||
try {
|
||||
report.append(
|
||||
"SYSTEM INFORMATION\n" +
|
||||
|
|
|
@ -8,12 +8,13 @@
|
|||
|
||||
package at.bitfire.davdroid.ui;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
import android.app.DialogFragment;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.app.DialogFragment;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
|
||||
import at.bitfire.davdroid.Constants;
|
||||
import at.bitfire.davdroid.R;
|
||||
|
@ -23,6 +24,7 @@ public class DonateDialogFragment extends DialogFragment {
|
|||
public DonateDialogFragment() {
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||
setCancelable(false);
|
||||
|
@ -36,7 +38,7 @@ public class DonateDialogFragment extends DialogFragment {
|
|||
startActivity(new Intent(Intent.ACTION_VIEW, Constants.webUri.buildUpon().appendEncodedPath("donate/").build()));
|
||||
}
|
||||
})
|
||||
.setNegativeButton(R.string.donate_later, new DialogInterface.OnClickListener() {
|
||||
.setNeutralButton(R.string.donate_later, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
dismiss();
|
||||
|
|
|
@ -8,10 +8,10 @@
|
|||
-->
|
||||
|
||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:padding="10dp">
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:padding="10dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
|
|
Loading…
Reference in a new issue