Save encrypted logs to disk on debug builds.

This commit is contained in:
akwizgran
2021-09-22 18:12:16 +01:00
parent 1d04bbcb4f
commit 719e3c6138
30 changed files with 610 additions and 53 deletions

View File

@@ -3,9 +3,11 @@ package org.briarproject.bramble.account;
import android.app.Application;
import android.content.SharedPreferences;
import org.briarproject.bramble.api.FeatureFlags;
import org.briarproject.bramble.api.crypto.CryptoComponent;
import org.briarproject.bramble.api.db.DatabaseConfig;
import org.briarproject.bramble.api.identity.IdentityManager;
import org.briarproject.bramble.api.logging.PersistentLogManager;
import org.briarproject.briar.R;
import org.briarproject.briar.android.Localizer;
import org.briarproject.briar.android.util.UiUtils;
@@ -15,10 +17,16 @@ import javax.inject.Inject;
class BriarAccountManager extends AndroidAccountManager {
@Inject
BriarAccountManager(DatabaseConfig databaseConfig, CryptoComponent crypto,
IdentityManager identityManager, SharedPreferences prefs,
BriarAccountManager(
DatabaseConfig databaseConfig,
CryptoComponent crypto,
IdentityManager identityManager,
SharedPreferences prefs,
PersistentLogManager logManager,
FeatureFlags featureFlags,
Application app) {
super(databaseConfig, crypto, identityManager, prefs, app);
super(databaseConfig, crypto, identityManager, prefs, logManager,
featureFlags, app);
}
@Override

View File

@@ -22,6 +22,7 @@ import org.briarproject.bramble.api.keyagreement.PayloadEncoder;
import org.briarproject.bramble.api.keyagreement.PayloadParser;
import org.briarproject.bramble.api.lifecycle.IoExecutor;
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
import org.briarproject.bramble.api.logging.PersistentLogManager;
import org.briarproject.bramble.api.plugin.PluginManager;
import org.briarproject.bramble.api.settings.SettingsManager;
import org.briarproject.bramble.api.system.AndroidExecutor;
@@ -78,6 +79,7 @@ import org.briarproject.briar.api.privategroup.invitation.GroupInvitationManager
import org.briarproject.briar.api.test.TestDataCreator;
import java.util.concurrent.Executor;
import java.util.logging.Formatter;
import javax.inject.Singleton;
@@ -204,6 +206,10 @@ public interface AndroidComponent
AutoDeleteManager autoDeleteManager();
PersistentLogManager persistentLogManager();
Formatter formatter();
void inject(SignInReminderReceiver briarService);
void inject(BriarService briarService);

View File

@@ -245,8 +245,9 @@ public class AppModule {
}
@Override
public File getLogcatFile() {
return AndroidUtils.getLogcatFile(app.getApplicationContext());
public File getTemporaryLogFile() {
return AndroidUtils
.getTemporaryLogFile(app.getApplicationContext());
}
};
return devConfig;
@@ -337,6 +338,11 @@ public class AppModule {
public boolean shouldEnableDisappearingMessages() {
return true;
}
@Override
public boolean shouldEnablePersistentLogs() {
return IS_DEBUG_BUILD;
}
};
}
}

View File

@@ -17,11 +17,14 @@ import com.vanniktech.emoji.google.GoogleEmojiProvider;
import org.briarproject.bramble.BrambleAndroidEagerSingletons;
import org.briarproject.bramble.BrambleAppComponent;
import org.briarproject.bramble.BrambleCoreEagerSingletons;
import org.briarproject.bramble.api.logging.PersistentLogManager;
import org.briarproject.briar.BriarCoreEagerSingletons;
import org.briarproject.briar.R;
import org.briarproject.briar.android.logging.CachingLogHandler;
import org.briarproject.briar.android.util.UiUtils;
import java.io.File;
import java.io.IOException;
import java.lang.Thread.UncaughtExceptionHandler;
import java.util.logging.Handler;
import java.util.logging.Logger;
@@ -31,7 +34,10 @@ import androidx.annotation.NonNull;
import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
import static java.util.logging.Level.FINE;
import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING;
import static java.util.logging.Logger.getLogger;
import static org.briarproject.bramble.util.AndroidUtils.getPersistentLogDir;
import static org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.briar.android.TestingConstants.IS_DEBUG_BUILD;
public class BriarApplicationImpl extends Application
@@ -81,6 +87,17 @@ public class BriarApplicationImpl extends Application
rootLogger.addHandler(logHandler);
rootLogger.setLevel(IS_DEBUG_BUILD ? FINE : INFO);
if (applicationComponent.featureFlags().shouldEnablePersistentLogs()) {
PersistentLogManager logManager =
applicationComponent.persistentLogManager();
File logDir = getPersistentLogDir(this);
try {
rootLogger.addHandler(logManager.createLogHandler(logDir));
} catch (IOException e) {
logException(LOG, WARNING, e);
}
}
LOG.info("Created");
EmojiManager.install(new GoogleEmojiProvider());

View File

@@ -1,74 +0,0 @@
package org.briarproject.briar.android.logging;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Collection;
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 {
public static String formatLog(Formatter formatter,
Collection<LogRecord> logRecords) {
StringBuilder sb = new StringBuilder();
for (LogRecord record : logRecords) {
String formatted = formatter.format(record);
sb.append(formatted).append('\n');
}
return sb.toString();
}
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());
Throwable t = record.getThrown();
if (t != null) {
sb.append('\n');
appendThrowable(sb, t);
}
return sb.toString();
}
private void appendThrowable(StringBuilder sb, Throwable t) {
sb.append(t);
for (StackTraceElement e : t.getStackTrace())
sb.append("\n at ").append(e);
Throwable cause = t.getCause();
if (cause != null) {
sb.append("\n Caused by: ");
appendThrowable(sb, cause);
}
}
}

View File

@@ -8,8 +8,9 @@ import androidx.annotation.Nullable;
@NotNullByDefault
public interface LogDecrypter {
/**
* Returns decrypted log records from {@link AndroidUtils#getLogcatFile}
* or null if there was an error reading the logs.
* Returns decrypted log records from
* {@link AndroidUtils#getTemporaryLogFile} or null if there was an error
* reading the logs.
*/
@Nullable
String decryptLogs(@Nullable byte[] logKey);

View File

@@ -41,7 +41,7 @@ class LogDecrypterImpl implements LogDecrypter {
public String decryptLogs(@Nullable byte[] logKey) {
if (logKey == null) return null;
SecretKey key = new SecretKey(logKey);
File logFile = devConfig.getLogcatFile();
File logFile = devConfig.getTemporaryLogFile();
try (InputStream in = new FileInputStream(logFile)) {
InputStream reader =
streamReaderFactory.createLogStreamReader(in, key);

View File

@@ -8,7 +8,7 @@ import androidx.annotation.Nullable;
@NotNullByDefault
public interface LogEncrypter {
/**
* Writes encrypted log records to {@link AndroidUtils#getLogcatFile}
* Writes encrypted log records to {@link AndroidUtils#getTemporaryLogFile}
* and returns the encryption key if everything went fine.
*/
@Nullable

View File

@@ -33,16 +33,19 @@ class LogEncrypterImpl implements LogEncrypter {
private final DevConfig devConfig;
private final CachingLogHandler logHandler;
private final Formatter formatter;
private final CryptoComponent crypto;
private final StreamWriterFactory streamWriterFactory;
@Inject
LogEncrypterImpl(DevConfig devConfig,
CachingLogHandler logHandler,
Formatter formatter,
CryptoComponent crypto,
StreamWriterFactory streamWriterFactory) {
this.devConfig = devConfig;
this.logHandler = logHandler;
this.formatter = formatter;
this.crypto = crypto;
this.streamWriterFactory = streamWriterFactory;
}
@@ -51,7 +54,7 @@ class LogEncrypterImpl implements LogEncrypter {
@Override
public byte[] encryptLogs() {
SecretKey logKey = crypto.generateSecretKey();
File logFile = devConfig.getLogcatFile();
File logFile = devConfig.getTemporaryLogFile();
try (OutputStream out = new FileOutputStream(logFile)) {
StreamWriter streamWriter =
streamWriterFactory.createLogStreamWriter(out, logKey);
@@ -67,10 +70,8 @@ class LogEncrypterImpl implements LogEncrypter {
}
private void writeLogString(Writer writer) throws IOException {
Formatter formatter = new BriefLogFormatter();
for (LogRecord record : logHandler.getRecentLogRecords()) {
String formatted = formatter.format(record);
writer.append(formatted).append('\n');
writer.append(formatter.format(record)).append('\n');
}
}

View File

@@ -26,6 +26,7 @@ import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.briar.BuildConfig;
import org.briarproject.briar.R;
import org.briarproject.briar.android.reporting.ReportData.MultiReportInfo;
import org.briarproject.briar.android.reporting.ReportData.ReportInfo;
import org.briarproject.briar.android.reporting.ReportData.ReportItem;
import org.briarproject.briar.android.reporting.ReportData.SingleReportInfo;
@@ -71,7 +72,7 @@ class BriarReportCollector {
}
ReportData collectReportData(@Nullable Throwable t, long appStartTime,
String logs) {
ReportInfo logs) {
ReportData reportData = new ReportData()
.add(getBasicInfo(t))
.add(getDeviceInfo());
@@ -82,7 +83,7 @@ class BriarReportCollector {
.add(getStorage())
.add(getConnectivity())
.add(getBuildConfig())
.add(getLogcat(logs))
.add(getLogs(logs))
.add(getDeviceFeatures());
}
@@ -309,8 +310,8 @@ class BriarReportCollector {
buildConfig);
}
private ReportItem getLogcat(String logs) {
return new ReportItem("Logcat", R.string.dev_report_logcat, logs);
private ReportItem getLogs(ReportInfo logs) {
return new ReportItem("Logs", R.string.dev_report_logcat, logs);
}
private ReportItem getDeviceFeatures() {

View File

@@ -4,6 +4,8 @@ import android.app.Application;
import android.os.Handler;
import android.os.Looper;
import org.briarproject.bramble.api.FeatureFlags;
import org.briarproject.bramble.api.logging.PersistentLogManager;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.plugin.Plugin;
import org.briarproject.bramble.api.plugin.PluginManager;
@@ -11,7 +13,6 @@ import org.briarproject.bramble.api.plugin.TorConstants;
import org.briarproject.bramble.api.reporting.DevReporter;
import org.briarproject.bramble.util.AndroidUtils;
import org.briarproject.briar.R;
import org.briarproject.briar.android.logging.BriefLogFormatter;
import org.briarproject.briar.android.logging.CachingLogHandler;
import org.briarproject.briar.android.logging.LogDecrypter;
import org.briarproject.briar.android.reporting.ReportData.MultiReportInfo;
@@ -22,6 +23,9 @@ import org.json.JSONException;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.LinkedList;
import java.util.Scanner;
import java.util.UUID;
import java.util.logging.Formatter;
import java.util.logging.Logger;
@@ -39,18 +43,24 @@ import static java.util.Objects.requireNonNull;
import static java.util.logging.Level.WARNING;
import static java.util.logging.Logger.getLogger;
import static org.briarproject.bramble.api.plugin.Plugin.State.ACTIVE;
import static org.briarproject.bramble.util.AndroidUtils.getPersistentLogDir;
import static org.briarproject.bramble.util.LogUtils.formatLog;
import static org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.bramble.util.StringUtils.isNullOrEmpty;
import static org.briarproject.briar.android.logging.BriefLogFormatter.formatLog;
@NotNullByDefault
class ReportViewModel extends AndroidViewModel {
private static final int MAX_PERSISTENT_LOG_LINES = 1000;
private static final Logger LOG =
getLogger(ReportViewModel.class.getName());
private final CachingLogHandler logHandler;
private final LogDecrypter logDecrypter;
private final Formatter formatter;
private final PersistentLogManager logManager;
private final FeatureFlags featureFlags;
private final BriarReportCollector collector;
private final DevReporter reporter;
private final PluginManager pluginManager;
@@ -71,12 +81,18 @@ class ReportViewModel extends AndroidViewModel {
ReportViewModel(@NonNull Application application,
CachingLogHandler logHandler,
LogDecrypter logDecrypter,
Formatter formatter,
PersistentLogManager logManager,
FeatureFlags featureFlags,
DevReporter reporter,
PluginManager pluginManager) {
super(application);
collector = new BriarReportCollector(application);
this.logHandler = logHandler;
this.logDecrypter = logDecrypter;
this.formatter = formatter;
this.logManager = logManager;
this.featureFlags = featureFlags;
this.reporter = reporter;
this.pluginManager = pluginManager;
}
@@ -86,22 +102,30 @@ class ReportViewModel extends AndroidViewModel {
this.initialComment = initialComment;
isFeedback = t == null;
if (reportData.getValue() == null) new SingleShotAndroidExecutor(() -> {
String decryptedLogs;
String currentLog;
if (isFeedback) {
Formatter formatter = new BriefLogFormatter();
decryptedLogs =
formatLog(formatter, logHandler.getRecentLogRecords());
// We're in the main process, so get the log for this process
currentLog = formatLog(formatter,
logHandler.getRecentLogRecords());
} else {
decryptedLogs = logDecrypter.decryptLogs(logKey);
if (decryptedLogs == null) {
// We're in the crash reporter process, so try to load
// the encrypted log that was saved by the main process
currentLog = logDecrypter.decryptLogs(logKey);
if (currentLog == null) {
// error decrypting logs, get logs from this process
Formatter formatter = new BriefLogFormatter();
decryptedLogs = formatLog(formatter,
currentLog = formatLog(formatter,
logHandler.getRecentLogRecords());
}
}
MultiReportInfo logs = new MultiReportInfo();
logs.add("Current", currentLog);
if (isFeedback && featureFlags.shouldEnablePersistentLogs()) {
// Add persistent logs for the current and previous processes
logs.add("Persistent", getPersistentLog(false));
logs.add("PersistentOld", getPersistentLog(true));
}
ReportData data =
collector.collectReportData(t, appStartTime, decryptedLogs);
collector.collectReportData(t, appStartTime, logs);
reportData.postValue(data);
}).start();
}
@@ -226,6 +250,27 @@ class ReportViewModel extends AndroidViewModel {
return closeReport;
}
private String getPersistentLog(boolean old) {
File logDir = getPersistentLogDir(getApplication());
StringBuilder sb = new StringBuilder();
try {
Scanner scanner = logManager.getPersistentLog(logDir, old);
LinkedList<String> lines = new LinkedList<>();
int numLines = 0;
while (scanner.hasNextLine()) {
lines.add(scanner.nextLine());
// If there are too many lines, return the most recent ones
if (numLines == MAX_PERSISTENT_LOG_LINES) lines.pollFirst();
else numLines++;
}
scanner.close();
for (String line : lines) sb.append(line).append('\n');
} catch (IOException e) {
sb.append("Could not recover persistent log: ").append(e);
}
return sb.toString();
}
// Used for a new thread as the Android executor thread may have died
private static class SingleShotAndroidExecutor extends Thread {

View File

@@ -8,6 +8,7 @@ import android.view.View;
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
import org.briarproject.briar.R;
import org.briarproject.briar.android.util.ActivityLaunchers.CreateDocumentAdvanced;
import org.briarproject.briar.android.util.ActivityLaunchers.GetImageAdvanced;
import javax.inject.Inject;
@@ -37,6 +38,10 @@ public class SettingsFragment extends PreferenceFragmentCompat {
private static final String PREF_KEY_DEV = "pref_key_dev";
private static final String PREF_KEY_EXPLODE = "pref_key_explode";
private static final String PREF_KEY_SHARE_APP = "pref_key_share_app";
private static final String PREF_KEY_EXPORT_LOG = "pref_key_export_log";
private static final String PREF_EXPORT_OLD_LOG = "pref_key_export_old_log";
private static final String LOG_EXPORT_FILENAME = "briar-log.txt";
@Inject
ViewModelProvider.Factory viewModelFactory;
@@ -44,10 +49,18 @@ public class SettingsFragment extends PreferenceFragmentCompat {
private SettingsViewModel viewModel;
private AvatarPreference prefAvatar;
private final ActivityResultLauncher<String> launcher =
private final ActivityResultLauncher<String> imageLauncher =
registerForActivityResult(new GetImageAdvanced(),
this::onImageSelected);
private final ActivityResultLauncher<String> logLauncher =
registerForActivityResult(new CreateDocumentAdvanced(),
uri -> onLogFileSelected(false, uri));
private final ActivityResultLauncher<String> oldLogLauncher =
registerForActivityResult(new CreateDocumentAdvanced(),
uri -> onLogFileSelected(true, uri));
@Override
public void onAttach(@NonNull Context context) {
super.onAttach(context);
@@ -63,7 +76,7 @@ public class SettingsFragment extends PreferenceFragmentCompat {
prefAvatar = requireNonNull(findPreference(PREF_KEY_AVATAR));
if (viewModel.shouldEnableProfilePictures()) {
prefAvatar.setOnPreferenceClickListener(preference -> {
launcher.launch("image/*");
imageLauncher.launch("image/*");
return true;
});
} else {
@@ -77,11 +90,24 @@ public class SettingsFragment extends PreferenceFragmentCompat {
return true;
});
Preference explode = requireNonNull(findPreference(PREF_KEY_EXPLODE));
if (IS_DEBUG_BUILD) {
Preference explode =
requireNonNull(findPreference(PREF_KEY_EXPLODE));
explode.setOnPreferenceClickListener(preference -> {
throw new RuntimeException("Boom!");
});
Preference exportLog =
requireNonNull(findPreference(PREF_KEY_EXPORT_LOG));
exportLog.setOnPreferenceClickListener(preference -> {
logLauncher.launch(LOG_EXPORT_FILENAME);
return true;
});
Preference exportOldLog =
requireNonNull(findPreference(PREF_EXPORT_OLD_LOG));
exportOldLog.setOnPreferenceClickListener(preference -> {
oldLogLauncher.launch(LOG_EXPORT_FILENAME);
return true;
});
} else {
PreferenceGroup dev = requireNonNull(findPreference(PREF_KEY_DEV));
dev.setVisible(false);
@@ -111,4 +137,7 @@ public class SettingsFragment extends PreferenceFragmentCompat {
ConfirmAvatarDialogFragment.TAG);
}
private void onLogFileSelected(boolean old, @Nullable Uri uri) {
if (uri != null) viewModel.exportPersistentLog(old, uri);
}
}

View File

@@ -16,6 +16,7 @@ import org.briarproject.bramble.api.identity.IdentityManager;
import org.briarproject.bramble.api.identity.LocalAuthor;
import org.briarproject.bramble.api.lifecycle.IoExecutor;
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
import org.briarproject.bramble.api.logging.PersistentLogManager;
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
import org.briarproject.bramble.api.plugin.BluetoothConstants;
@@ -35,8 +36,12 @@ import org.briarproject.briar.api.avatar.AvatarManager;
import org.briarproject.briar.api.identity.AuthorInfo;
import org.briarproject.briar.api.identity.AuthorManager;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Scanner;
import java.util.concurrent.Executor;
import java.util.logging.Logger;
@@ -50,6 +55,7 @@ import static android.widget.Toast.LENGTH_LONG;
import static java.util.Arrays.asList;
import static java.util.logging.Level.WARNING;
import static java.util.logging.Logger.getLogger;
import static org.briarproject.bramble.util.AndroidUtils.getPersistentLogDir;
import static org.briarproject.bramble.util.AndroidUtils.getSupportedImageContentTypes;
import static org.briarproject.bramble.util.LogUtils.logDuration;
import static org.briarproject.bramble.util.LogUtils.logException;
@@ -78,6 +84,7 @@ class SettingsViewModel extends DbViewModel implements EventListener {
private final ImageCompressor imageCompressor;
private final Executor ioExecutor;
private final FeatureFlags featureFlags;
private final PersistentLogManager logManager;
final SettingsStore settingsStore;
final TorSummaryProvider torSummaryProvider;
@@ -108,7 +115,8 @@ class SettingsViewModel extends DbViewModel implements EventListener {
LocationUtils locationUtils,
CircumventionProvider circumventionProvider,
@IoExecutor Executor ioExecutor,
FeatureFlags featureFlags) {
FeatureFlags featureFlags,
PersistentLogManager logManager) {
super(application, dbExecutor, lifecycleManager, db, androidExecutor);
this.settingsManager = settingsManager;
this.identityManager = identityManager;
@@ -118,6 +126,7 @@ class SettingsViewModel extends DbViewModel implements EventListener {
this.authorManager = authorManager;
this.ioExecutor = ioExecutor;
this.featureFlags = featureFlags;
this.logManager = logManager;
settingsStore = new SettingsStore(settingsManager, dbExecutor,
SETTINGS_NAMESPACE);
torSummaryProvider = new TorSummaryProvider(getApplication(),
@@ -262,4 +271,38 @@ class SettingsViewModel extends DbViewModel implements EventListener {
return screenLockTimeout;
}
void exportPersistentLog(boolean old, Uri uri) {
// We can use untranslated strings here, as this method is only called
// in debug builds
ioExecutor.execute(() -> {
Application app = getApplication();
try {
OutputStream os =
app.getContentResolver().openOutputStream(uri);
if (os == null) throw new IOException();
File logDir = getPersistentLogDir(app);
Scanner scanner = logManager.getPersistentLog(logDir, old);
if (!scanner.hasNextLine()) {
scanner.close();
androidExecutor.runOnUiThread(() ->
Toast.makeText(app, "Log is empty",
LENGTH_LONG).show());
return;
}
PrintWriter w = new PrintWriter(os);
while (scanner.hasNextLine()) w.println(scanner.nextLine());
w.flush();
w.close();
scanner.close();
androidExecutor.runOnUiThread(() ->
Toast.makeText(app, "Log exported",
LENGTH_LONG).show());
} catch (IOException e) {
logException(LOG, WARNING, e);
androidExecutor.runOnUiThread(() ->
Toast.makeText(app, "Failed to export log",
LENGTH_LONG).show());
}
});
}
}

View File

@@ -58,6 +58,14 @@
android:targetPackage="@string/app_package" />
</Preference>
<Preference
android:key="pref_key_export_log"
android:title="Export current log to SD card" />
<Preference
android:key="pref_key_export_old_log"
android:title="Export previous log to SD card" />
<Preference
android:key="pref_key_explode"
android:title="Crash" />

View File

@@ -1,5 +1,6 @@
package org.briarproject.briar.android.logging;
import org.briarproject.bramble.logging.BriefLogFormatter;
import org.briarproject.bramble.test.BrambleMockTestCase;
import org.junit.ClassRule;
import org.junit.Test;
@@ -15,8 +16,8 @@ import static java.util.logging.Level.FINE;
import static java.util.logging.Level.INFO;
import static java.util.logging.Level.SEVERE;
import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.util.LogUtils.formatLog;
import static org.briarproject.bramble.util.StringUtils.getRandomString;
import static org.briarproject.briar.android.logging.BriefLogFormatter.formatLog;
import static org.junit.Assert.assertEquals;
public class LogEncryptionDecryptionTest extends BrambleMockTestCase {

View File

@@ -42,7 +42,7 @@ class LoggingTestModule {
}
@Override
public File getLogcatFile() {
public File getTemporaryLogFile() {
return logFile;
}
};