Add buttons for exporting persisted logs to SD card.

This commit is contained in:
akwizgran
2020-07-03 11:51:26 +01:00
parent a63619ab47
commit 81ed5978d6
4 changed files with 164 additions and 2 deletions

View File

@@ -16,5 +16,7 @@ public interface RequestCodes {
int REQUEST_KEYGUARD_UNLOCK = 12;
int REQUEST_ATTACH_IMAGE = 13;
int REQUEST_SAVE_ATTACHMENT = 14;
int REQUEST_EXPORT_LOG = 15;
int REQUEST_EXPORT_OLD_LOG = 16;
}

View File

@@ -1,18 +1,64 @@
package org.briarproject.briar.android.settings;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.MenuItem;
import android.widget.Toast;
import org.briarproject.bramble.api.lifecycle.IoExecutor;
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
import org.briarproject.briar.R;
import org.briarproject.briar.android.activity.ActivityComponent;
import org.briarproject.briar.android.activity.BriarActivity;
import org.briarproject.briar.api.logging.PersistentLogManager;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.concurrent.Executor;
import java.util.logging.Logger;
import javax.annotation.Nullable;
import javax.inject.Inject;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.ActionBar;
import static android.content.Intent.ACTION_CREATE_DOCUMENT;
import static android.content.Intent.CATEGORY_OPENABLE;
import static android.content.Intent.EXTRA_TITLE;
import static android.os.Build.VERSION.SDK_INT;
import static android.os.Environment.DIRECTORY_DOWNLOADS;
import static android.os.Environment.getExternalStoragePublicDirectory;
import static android.widget.Toast.LENGTH_LONG;
import static java.util.logging.Level.WARNING;
import static java.util.logging.Logger.getLogger;
import static org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_EXPORT_LOG;
import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_EXPORT_OLD_LOG;
@MethodsNotNullByDefault
@ParametersNotNullByDefault
public class SettingsActivity extends BriarActivity {
private static final Logger LOG =
getLogger(SettingsActivity.class.getName());
private static final String LOG_EXPORT_FILENAME = "briar-log.txt";
@Inject
@IoExecutor
Executor ioExecutor;
@Inject
PersistentLogManager logManager;
@Override
public void onCreate(Bundle bundle) {
public void onCreate(@Nullable Bundle bundle) {
super.onCreate(bundle);
ActionBar actionBar = getSupportActionBar();
@@ -37,4 +83,88 @@ public class SettingsActivity extends BriarActivity {
}
return false;
}
@Override
protected void onActivityResult(int request, int result,
@Nullable Intent data) {
super.onActivityResult(request, result, data);
if (request == REQUEST_EXPORT_LOG && result == RESULT_OK &&
data != null && data.getData() != null) {
exportLog(false, data.getData());
} else if (request == REQUEST_EXPORT_OLD_LOG && result == RESULT_OK &&
data != null && data.getData() != null) {
exportLog(true, data.getData());
}
}
private void exportLog(boolean old, Uri uri) {
copyLog(old, () -> getOutputStream(uri));
}
private void copyLog(boolean old, OutputStreamProvider osp) {
ioExecutor.execute(() -> {
try {
PrintWriter w = new PrintWriter(osp.getOutputStream());
File logDir = getApplication().getDir("log", MODE_PRIVATE);
for (String line : logManager.getPersistedLog(logDir, old)) {
w.println(line);
}
w.close();
runOnUiThreadUnlessDestroyed(() ->
Toast.makeText(getApplication(), "Log exported",
LENGTH_LONG).show());
} catch (IOException e) {
logException(LOG, WARNING, e);
runOnUiThreadUnlessDestroyed(() ->
Toast.makeText(getApplication(), "Failed to export log",
LENGTH_LONG).show());
}
});
}
void onExportLogClick(boolean old) {
if (SDK_INT >= 19) {
Intent intent = getExportLogIntent();
int request = old ? REQUEST_EXPORT_OLD_LOG : REQUEST_EXPORT_LOG;
startActivityForResult(intent, request);
} else {
exportLog(old);
}
}
@RequiresApi(api = 19)
private Intent getExportLogIntent() {
Intent intent = new Intent(ACTION_CREATE_DOCUMENT);
intent.addCategory(CATEGORY_OPENABLE);
intent.setType("text/plain");
intent.putExtra(EXTRA_TITLE, LOG_EXPORT_FILENAME);
return intent;
}
private void exportLog(boolean old) {
File file = getLogOutputFile();
copyLog(old, () -> getOutputStream(file));
}
private File getLogOutputFile() {
File path = getExternalStoragePublicDirectory(DIRECTORY_DOWNLOADS);
//noinspection ResultOfMethodCallIgnored
path.mkdirs();
return new File(path, LOG_EXPORT_FILENAME);
}
private OutputStream getOutputStream(File file) throws IOException {
return new FileOutputStream(file);
}
private OutputStream getOutputStream(Uri uri) throws IOException {
OutputStream os =
getApplication().getContentResolver().openOutputStream(uri);
if (os == null) throw new IOException();
return os;
}
private interface OutputStreamProvider {
OutputStream getOutputStream() throws IOException;
}
}

View File

@@ -1,5 +1,6 @@
package org.briarproject.briar.android.settings;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.AlertDialog;
import android.content.Context;
@@ -74,6 +75,7 @@ import static android.widget.Toast.LENGTH_SHORT;
import static androidx.core.view.ViewCompat.LAYOUT_DIRECTION_LTR;
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.api.plugin.Plugin.PREF_PLUGIN_ENABLE;
import static org.briarproject.bramble.api.plugin.TorConstants.DEFAULT_PREF_TOR_MOBILE;
import static org.briarproject.bramble.api.plugin.TorConstants.DEFAULT_PREF_TOR_NETWORK;
@@ -133,7 +135,7 @@ public class SettingsFragment extends PreferenceFragmentCompat
"pref_key_tor_only_when_charging";
private static final Logger LOG =
Logger.getLogger(SettingsFragment.class.getName());
getLogger(SettingsFragment.class.getName());
private SettingsActivity listener;
private ListPreference language;
@@ -251,8 +253,25 @@ public class SettingsFragment extends PreferenceFragmentCompat
throw new RuntimeException("Boom!");
}
);
findPreference("pref_key_export_log").setOnPreferenceClickListener(
preference -> {
((SettingsActivity) requireActivity())
.onExportLogClick(false);
return true;
}
);
findPreference("pref_key_export_old_log")
.setOnPreferenceClickListener(
preference -> {
((SettingsActivity) requireActivity())
.onExportLogClick(true);
return true;
}
);
} else {
findPreference("pref_key_explode").setVisible(false);
findPreference("pref_key_export_log").setVisible(false);
findPreference("pref_key_export_old_log").setVisible(false);
findPreference("pref_key_test_data").setVisible(false);
PreferenceGroup testing =
findPreference("pref_key_explode").getParent();
@@ -331,6 +350,7 @@ public class SettingsFragment extends PreferenceFragmentCompat
return direction == LAYOUT_DIRECTION_LTR;
}
@SuppressLint("StringFormatInvalid")
private void setTorNetworkSummary(int torNetworkSetting) {
if (torNetworkSetting != PREF_TOR_NETWORK_AUTOMATIC) {
torNetwork.setSummary("%s"); // use setting value

View File

@@ -227,6 +227,16 @@
android:targetPackage="@string/app_package"/>
</Preference>
<Preference
android:key="pref_key_export_log"
android:title="Export Current Log to SD Card"
app:iconSpaceReserved="false"/>
<Preference
android:key="pref_key_export_old_log"
android:title="Export Previous Log to SD Card"
app:iconSpaceReserved="false"/>
<Preference
android:key="pref_key_explode"
android:title="Crash"