Commit 41ae7b05 authored by akwizgran's avatar akwizgran

Merge branch 'internal-logger' into 'master'

Use internal log handler for crash reports and feedback

Closes #986

See merge request akwizgran/briar!802
parents c2214f5e b23baf70
Pipeline #1538 passed with stage
in 7 minutes and 59 seconds
......@@ -12,7 +12,6 @@
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_LOGS"/>
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission-sdk-23 android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/>
......
package org.briarproject.briar.android;
import java.util.Collection;
import java.util.logging.LogRecord;
/**
* This exists so that the Application object will not necessarily be cast
* directly to the Briar application object.
*/
public interface BriarApplication {
Collection<LogRecord> getRecentLogRecords();
AndroidComponent getApplicationComponent();
}
......@@ -12,12 +12,17 @@ import org.acra.annotation.ReportsCrashes;
import org.briarproject.bramble.BrambleCoreModule;
import org.briarproject.briar.BriarCoreModule;
import org.briarproject.briar.R;
import org.briarproject.briar.android.logging.CachingLogHandler;
import org.briarproject.briar.android.reporting.BriarReportPrimer;
import org.briarproject.briar.android.reporting.BriarReportSenderFactory;
import org.briarproject.briar.android.reporting.DevReportActivity;
import java.util.Collection;
import java.util.logging.Handler;
import java.util.logging.LogRecord;
import java.util.logging.Logger;
import static java.util.logging.Level.INFO;
import static org.acra.ReportField.ANDROID_VERSION;
import static org.acra.ReportField.APP_VERSION_CODE;
import static org.acra.ReportField.APP_VERSION_NAME;
......@@ -28,7 +33,6 @@ import static org.acra.ReportField.CUSTOM_DATA;
import static org.acra.ReportField.DEVICE_FEATURES;
import static org.acra.ReportField.DISPLAY;
import static org.acra.ReportField.INITIAL_CONFIGURATION;
import static org.acra.ReportField.LOGCAT;
import static org.acra.ReportField.PACKAGE_NAME;
import static org.acra.ReportField.PHONE_MODEL;
import static org.acra.ReportField.PRODUCT;
......@@ -36,7 +40,7 @@ import static org.acra.ReportField.REPORT_ID;
import static org.acra.ReportField.STACK_TRACE;
import static org.acra.ReportField.USER_APP_START_DATE;
import static org.acra.ReportField.USER_CRASH_DATE;
import static org.briarproject.briar.android.TestingConstants.DEFAULT_LOG_LEVEL;
import static org.briarproject.briar.android.TestingConstants.IS_BETA_BUILD;
import static org.briarproject.briar.android.TestingConstants.IS_DEBUG_BUILD;
@ReportsCrashes(
......@@ -56,8 +60,7 @@ import static org.briarproject.briar.android.TestingConstants.IS_DEBUG_BUILD;
STACK_TRACE,
INITIAL_CONFIGURATION, CRASH_CONFIGURATION,
DISPLAY, DEVICE_FEATURES,
USER_APP_START_DATE, USER_CRASH_DATE,
LOGCAT
USER_APP_START_DATE, USER_CRASH_DATE
}
)
public class BriarApplicationImpl extends Application
......@@ -66,6 +69,8 @@ public class BriarApplicationImpl extends Application
private static final Logger LOG =
Logger.getLogger(BriarApplicationImpl.class.getName());
private final CachingLogHandler logHandler = new CachingLogHandler();
private AndroidComponent applicationComponent;
@Override
......@@ -79,7 +84,17 @@ public class BriarApplicationImpl extends Application
super.onCreate();
if (IS_DEBUG_BUILD) enableStrictMode();
Logger.getLogger("").setLevel(DEFAULT_LOG_LEVEL);
Logger rootLogger = Logger.getLogger("");
if (!IS_DEBUG_BUILD && !IS_BETA_BUILD) {
// Remove default log handlers so system log is not used
for (Handler handler : rootLogger.getHandlers()) {
rootLogger.removeHandler(handler);
}
}
rootLogger.addHandler(logHandler);
rootLogger.setLevel(INFO);
LOG.info("Created");
applicationComponent = DaggerAndroidComponent.builder()
......@@ -104,6 +119,11 @@ public class BriarApplicationImpl extends Application
StrictMode.setVmPolicy(vmPolicy.build());
}
@Override
public Collection<LogRecord> getRecentLogRecords() {
return logHandler.getRecentLogRecords();
}
@Override
public AndroidComponent getApplicationComponent() {
return applicationComponent;
......
......@@ -2,11 +2,6 @@ package org.briarproject.briar.android;
import org.briarproject.briar.BuildConfig;
import java.util.logging.Level;
import static java.util.logging.Level.INFO;
import static java.util.logging.Level.OFF;
public interface TestingConstants {
/**
......@@ -20,12 +15,6 @@ public interface TestingConstants {
*/
boolean IS_BETA_BUILD = false;
/**
* Default log level. Disable logging for final release builds.
*/
@SuppressWarnings("ConstantConditions")
Level DEFAULT_LOG_LEVEL = IS_DEBUG_BUILD || IS_BETA_BUILD ? INFO : OFF;
/**
* Whether to prevent screenshots from being taken. Setting this to true
* prevents Recent Apps from storing screenshots of private information.
......
package org.briarproject.briar.android.logging;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
import java.util.logging.Formatter;
import java.util.logging.LogRecord;
import javax.annotation.concurrent.ThreadSafe;
import static java.util.Locale.US;
@ThreadSafe
@NotNullByDefault
public class BriefLogFormatter extends Formatter {
private final Object lock = new Object();
private final DateFormat dateFormat; // Locking: lock
private final Date date; // Locking: lock
public BriefLogFormatter() {
synchronized (lock) {
dateFormat = new SimpleDateFormat("MM-dd HH:mm:ss.SSS ", US);
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
date = new Date();
}
}
@Override
public String format(LogRecord record) {
String dateString;
synchronized (lock) {
date.setTime(record.getMillis());
dateString = dateFormat.format(date);
}
StringBuilder sb = new StringBuilder(dateString);
sb.append(record.getLevel().getName().charAt(0)).append('/');
String tag = record.getLoggerName();
tag = tag.substring(tag.lastIndexOf('.') + 1);
sb.append(tag).append(": ");
sb.append(record.getMessage());
return sb.toString();
}
}
package org.briarproject.briar.android.logging;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedList;
import java.util.Queue;
import java.util.logging.Handler;
import java.util.logging.LogRecord;
import javax.annotation.concurrent.ThreadSafe;
@ThreadSafe
@NotNullByDefault
public class CachingLogHandler extends Handler {
private static final int MAX_RECENT_RECORDS = 100;
private final Object lock = new Object();
// Locking: lock
private final Queue<LogRecord> recent = new LinkedList<>();
@Override
public void publish(LogRecord record) {
synchronized (lock) {
recent.add(record);
if (recent.size() > MAX_RECENT_RECORDS) recent.poll();
}
}
@Override
public void flush() {
}
@Override
public void close() {
synchronized (lock) {
recent.clear();
}
}
public Collection<LogRecord> getRecentLogRecords() {
synchronized (lock) {
return new ArrayList<>(recent);
}
}
}
......@@ -18,6 +18,8 @@ import org.acra.builder.ReportBuilder;
import org.acra.builder.ReportPrimer;
import org.briarproject.bramble.util.StringUtils;
import org.briarproject.briar.BuildConfig;
import org.briarproject.briar.android.BriarApplication;
import org.briarproject.briar.android.logging.BriefLogFormatter;
import java.io.File;
import java.lang.reflect.InvocationTargetException;
......@@ -28,6 +30,8 @@ import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
import java.util.logging.Formatter;
import java.util.logging.LogRecord;
import static android.bluetooth.BluetoothAdapter.SCAN_MODE_CONNECTABLE;
import static android.bluetooth.BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE;
......@@ -69,6 +73,16 @@ public class BriarReportPrimer implements ReportPrimer {
public Map<String, String> call() {
Map<String, String> customData = new LinkedHashMap<>();
// Log
BriarApplication app =
(BriarApplication) ctx.getApplicationContext();
StringBuilder sb = new StringBuilder();
Formatter formatter = new BriefLogFormatter();
for (LogRecord record : app.getRecentLogRecords()) {
sb.append(formatter.format(record)).append('\n');
}
customData.put("Log", sb.toString());
// System memory
Object o = ctx.getSystemService(ACTIVITY_SERVICE);
ActivityManager am = (ActivityManager) o;
......@@ -223,9 +237,10 @@ public class BriarReportPrimer implements ReportPrimer {
customData.put("Bluetooth LE status", btLeStatus);
}
if (bt != null)
if (bt != null) {
customData.put("Bluetooth address",
scrubMacAddress(bt.getAddress()));
}
String btSettingsAddr;
try {
btSettingsAddr = Settings.Secure.getString(
......
......@@ -5,8 +5,12 @@ import android.app.Application;
import org.briarproject.bramble.BrambleCoreModule;
import org.briarproject.briar.BriarCoreModule;
import java.util.Collection;
import java.util.logging.LogRecord;
import java.util.logging.Logger;
import static java.util.Collections.emptyList;
/**
* This class only exists to avoid static initialisation of ACRA
*/
......@@ -34,6 +38,11 @@ public class TestBriarApplication extends Application
AndroidEagerSingletons.initEagerSingletons(applicationComponent);
}
@Override
public Collection<LogRecord> getRecentLogRecords() {
return emptyList();
}
@Override
public AndroidComponent getApplicationComponent() {
return applicationComponent;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment