mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-21 15:19:53 +01:00
Address review feedback for ACRA replacement
This commit is contained in:
@@ -79,11 +79,8 @@
|
|||||||
android:windowSoftInputMode="adjustResize|stateHidden" />
|
android:windowSoftInputMode="adjustResize|stateHidden" />
|
||||||
<activity
|
<activity
|
||||||
android:name="org.briarproject.briar.android.reporting.FeedbackActivity"
|
android:name="org.briarproject.briar.android.reporting.FeedbackActivity"
|
||||||
android:excludeFromRecents="true"
|
|
||||||
android:exported="false"
|
android:exported="false"
|
||||||
android:finishOnTaskLaunch="true"
|
|
||||||
android:label="@string/feedback_title"
|
android:label="@string/feedback_title"
|
||||||
android:launchMode="singleInstance"
|
|
||||||
android:theme="@style/BriarTheme.NoActionBar"
|
android:theme="@style/BriarTheme.NoActionBar"
|
||||||
android:windowSoftInputMode="adjustResize|stateHidden" />
|
android:windowSoftInputMode="adjustResize|stateHidden" />
|
||||||
|
|
||||||
|
|||||||
@@ -33,9 +33,6 @@ import org.briarproject.briar.BriarCoreModule;
|
|||||||
import org.briarproject.briar.android.attachment.AttachmentModule;
|
import org.briarproject.briar.android.attachment.AttachmentModule;
|
||||||
import org.briarproject.briar.android.conversation.glide.BriarModelLoader;
|
import org.briarproject.briar.android.conversation.glide.BriarModelLoader;
|
||||||
import org.briarproject.briar.android.login.SignInReminderReceiver;
|
import org.briarproject.briar.android.login.SignInReminderReceiver;
|
||||||
import org.briarproject.briar.android.reporting.CrashFragment;
|
|
||||||
import org.briarproject.briar.android.reporting.CrashReportActivity;
|
|
||||||
import org.briarproject.briar.android.reporting.ReportFormFragment;
|
|
||||||
import org.briarproject.briar.android.view.EmojiTextInputView;
|
import org.briarproject.briar.android.view.EmojiTextInputView;
|
||||||
import org.briarproject.briar.api.android.AndroidNotificationManager;
|
import org.briarproject.briar.api.android.AndroidNotificationManager;
|
||||||
import org.briarproject.briar.api.android.DozeWatchdog;
|
import org.briarproject.briar.api.android.DozeWatchdog;
|
||||||
@@ -175,10 +172,6 @@ public interface AndroidComponent
|
|||||||
|
|
||||||
void inject(BriarService briarService);
|
void inject(BriarService briarService);
|
||||||
|
|
||||||
void inject(CrashReportActivity crashReportActivity);
|
|
||||||
void inject(ReportFormFragment reportFormFragment);
|
|
||||||
void inject(CrashFragment crashFragment);
|
|
||||||
|
|
||||||
void inject(NotificationCleanupService notificationCleanupService);
|
void inject(NotificationCleanupService notificationCleanupService);
|
||||||
|
|
||||||
void inject(EmojiTextInputView textInputView);
|
void inject(EmojiTextInputView textInputView);
|
||||||
|
|||||||
@@ -23,7 +23,5 @@ public interface BriarApplication extends BrambleApplication {
|
|||||||
|
|
||||||
SharedPreferences getDefaultSharedPreferences();
|
SharedPreferences getDefaultSharedPreferences();
|
||||||
|
|
||||||
void triggerFeedback();
|
|
||||||
|
|
||||||
boolean isRunningInBackground();
|
boolean isRunningInBackground();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -151,11 +151,6 @@ public class BriarApplicationImpl extends Application
|
|||||||
return prefs;
|
return prefs;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void triggerFeedback() {
|
|
||||||
exceptionHandler.feedback();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isRunningInBackground() {
|
public boolean isRunningInBackground() {
|
||||||
RunningAppProcessInfo info = new RunningAppProcessInfo();
|
RunningAppProcessInfo info = new RunningAppProcessInfo();
|
||||||
|
|||||||
@@ -66,6 +66,9 @@ import org.briarproject.briar.android.privategroup.memberlist.GroupMemberModule;
|
|||||||
import org.briarproject.briar.android.privategroup.reveal.GroupRevealModule;
|
import org.briarproject.briar.android.privategroup.reveal.GroupRevealModule;
|
||||||
import org.briarproject.briar.android.privategroup.reveal.RevealContactsActivity;
|
import org.briarproject.briar.android.privategroup.reveal.RevealContactsActivity;
|
||||||
import org.briarproject.briar.android.privategroup.reveal.RevealContactsFragment;
|
import org.briarproject.briar.android.privategroup.reveal.RevealContactsFragment;
|
||||||
|
import org.briarproject.briar.android.reporting.CrashFragment;
|
||||||
|
import org.briarproject.briar.android.reporting.CrashReportActivity;
|
||||||
|
import org.briarproject.briar.android.reporting.ReportFormFragment;
|
||||||
import org.briarproject.briar.android.settings.SettingsActivity;
|
import org.briarproject.briar.android.settings.SettingsActivity;
|
||||||
import org.briarproject.briar.android.settings.SettingsFragment;
|
import org.briarproject.briar.android.settings.SettingsFragment;
|
||||||
import org.briarproject.briar.android.sharing.BlogInvitationActivity;
|
import org.briarproject.briar.android.sharing.BlogInvitationActivity;
|
||||||
@@ -184,6 +187,8 @@ public interface ActivityComponent {
|
|||||||
|
|
||||||
void inject(PendingContactListActivity activity);
|
void inject(PendingContactListActivity activity);
|
||||||
|
|
||||||
|
void inject(CrashReportActivity crashReportActivity);
|
||||||
|
|
||||||
// Fragments
|
// Fragments
|
||||||
|
|
||||||
void inject(AuthorNameFragment fragment);
|
void inject(AuthorNameFragment fragment);
|
||||||
@@ -234,4 +239,8 @@ public interface ActivityComponent {
|
|||||||
|
|
||||||
void inject(ImageFragment imageFragment);
|
void inject(ImageFragment imageFragment);
|
||||||
|
|
||||||
|
void inject(ReportFormFragment reportFormFragment);
|
||||||
|
|
||||||
|
void inject(CrashFragment crashFragment);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ import org.briarproject.briar.android.controller.ActivityLifecycleController;
|
|||||||
import org.briarproject.briar.android.forum.ForumModule;
|
import org.briarproject.briar.android.forum.ForumModule;
|
||||||
import org.briarproject.briar.android.fragment.BaseFragment;
|
import org.briarproject.briar.android.fragment.BaseFragment;
|
||||||
import org.briarproject.briar.android.fragment.ScreenFilterDialogFragment;
|
import org.briarproject.briar.android.fragment.ScreenFilterDialogFragment;
|
||||||
import org.briarproject.briar.android.reporting.CrashReportActivity;
|
|
||||||
import org.briarproject.briar.android.util.UiUtils;
|
import org.briarproject.briar.android.util.UiUtils;
|
||||||
import org.briarproject.briar.android.widget.TapSafeFrameLayout;
|
import org.briarproject.briar.android.widget.TapSafeFrameLayout;
|
||||||
import org.briarproject.briar.android.widget.TapSafeFrameLayout.OnTapFilteredListener;
|
import org.briarproject.briar.android.widget.TapSafeFrameLayout.OnTapFilteredListener;
|
||||||
@@ -50,7 +49,6 @@ import static org.briarproject.briar.android.util.UiUtils.hideSoftKeyboard;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Warning: Some activities don't extend {@link BaseActivity}.
|
* Warning: Some activities don't extend {@link BaseActivity}.
|
||||||
* E.g. {@link CrashReportActivity}
|
|
||||||
*/
|
*/
|
||||||
@MethodsNotNullByDefault
|
@MethodsNotNullByDefault
|
||||||
@ParametersNotNullByDefault
|
@ParametersNotNullByDefault
|
||||||
@@ -123,6 +121,7 @@ public abstract class BaseActivity extends AppCompatActivity
|
|||||||
return new ActivityModule(this);
|
return new ActivityModule(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO use a test module where this is used in tests
|
||||||
protected ForumModule getForumModule() {
|
protected ForumModule getForumModule() {
|
||||||
return new ForumModule();
|
return new ForumModule();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,13 +10,10 @@ import android.widget.TextView;
|
|||||||
|
|
||||||
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
||||||
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
|
||||||
import org.briarproject.bramble.api.system.AndroidExecutor;
|
|
||||||
import org.briarproject.briar.R;
|
import org.briarproject.briar.R;
|
||||||
import org.briarproject.briar.android.BriarApplication;
|
|
||||||
import org.briarproject.briar.android.activity.ActivityComponent;
|
import org.briarproject.briar.android.activity.ActivityComponent;
|
||||||
import org.briarproject.briar.android.fragment.BaseFragment;
|
import org.briarproject.briar.android.fragment.BaseFragment;
|
||||||
|
import org.briarproject.briar.android.util.UiUtils;
|
||||||
import javax.inject.Inject;
|
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.fragment.app.FragmentActivity;
|
import androidx.fragment.app.FragmentActivity;
|
||||||
@@ -41,9 +38,6 @@ public class ContactExchangeErrorFragment extends BaseFragment {
|
|||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject
|
|
||||||
AndroidExecutor androidExecutor;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getUniqueTag() {
|
public String getUniqueTag() {
|
||||||
return TAG;
|
return TAG;
|
||||||
@@ -88,10 +82,8 @@ public class ContactExchangeErrorFragment extends BaseFragment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void triggerFeedback() {
|
private void triggerFeedback() {
|
||||||
BriarApplication app =
|
UiUtils.triggerFeedback(requireContext());
|
||||||
(BriarApplication) requireContext().getApplicationContext();
|
|
||||||
finish();
|
finish();
|
||||||
app.triggerFeedback();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,19 +1,13 @@
|
|||||||
package org.briarproject.briar.android.reporting;
|
package org.briarproject.briar.android.reporting;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
|
||||||
import android.os.Process;
|
import android.os.Process;
|
||||||
|
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
import org.briarproject.briar.android.util.UserFeedback;
|
|
||||||
|
|
||||||
import java.lang.Thread.UncaughtExceptionHandler;
|
import java.lang.Thread.UncaughtExceptionHandler;
|
||||||
|
|
||||||
import androidx.fragment.app.FragmentActivity;
|
import static org.briarproject.briar.android.util.UiUtils.startDevReportActivity;
|
||||||
|
|
||||||
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
|
|
||||||
import static org.briarproject.briar.android.reporting.CrashReportActivity.EXTRA_APP_START_TIME;
|
|
||||||
import static org.briarproject.briar.android.reporting.CrashReportActivity.EXTRA_THROWABLE;
|
|
||||||
|
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
public class BriarExceptionHandler implements UncaughtExceptionHandler {
|
public class BriarExceptionHandler implements UncaughtExceptionHandler {
|
||||||
@@ -29,22 +23,9 @@ public class BriarExceptionHandler implements UncaughtExceptionHandler {
|
|||||||
@Override
|
@Override
|
||||||
public void uncaughtException(Thread t, Throwable e) {
|
public void uncaughtException(Thread t, Throwable e) {
|
||||||
// activity runs in its own process, so we can kill the old one
|
// activity runs in its own process, so we can kill the old one
|
||||||
startDevReportActivity(CrashReportActivity.class, e);
|
startDevReportActivity(ctx, CrashReportActivity.class, e, appStartTime);
|
||||||
Process.killProcess(Process.myPid());
|
Process.killProcess(Process.myPid());
|
||||||
System.exit(10);
|
System.exit(10);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void feedback() {
|
|
||||||
startDevReportActivity(FeedbackActivity.class, new UserFeedback());
|
|
||||||
}
|
|
||||||
|
|
||||||
private void startDevReportActivity(
|
|
||||||
Class<? extends FragmentActivity> activity, Throwable e) {
|
|
||||||
final Intent dialogIntent = new Intent(ctx, activity);
|
|
||||||
dialogIntent.setFlags(FLAG_ACTIVITY_NEW_TASK);
|
|
||||||
dialogIntent.putExtra(EXTRA_THROWABLE, e);
|
|
||||||
dialogIntent.putExtra(EXTRA_APP_START_TIME, appStartTime);
|
|
||||||
ctx.startActivity(dialogIntent);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,12 +21,14 @@ import android.os.Build;
|
|||||||
import android.os.Environment;
|
import android.os.Environment;
|
||||||
|
|
||||||
import org.briarproject.bramble.api.Pair;
|
import org.briarproject.bramble.api.Pair;
|
||||||
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
import org.briarproject.briar.BuildConfig;
|
import org.briarproject.briar.BuildConfig;
|
||||||
import org.briarproject.briar.R;
|
import org.briarproject.briar.R;
|
||||||
import org.briarproject.briar.android.BriarApplication;
|
import org.briarproject.briar.android.BriarApplication;
|
||||||
import org.briarproject.briar.android.logging.BriefLogFormatter;
|
import org.briarproject.briar.android.logging.BriefLogFormatter;
|
||||||
import org.briarproject.briar.android.reporting.ReportData.MultiReportInfo;
|
import org.briarproject.briar.android.reporting.ReportData.MultiReportInfo;
|
||||||
import org.briarproject.briar.android.reporting.ReportData.ReportItem;
|
import org.briarproject.briar.android.reporting.ReportData.ReportItem;
|
||||||
|
import org.briarproject.briar.android.reporting.ReportData.SingleReportInfo;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
@@ -40,6 +42,8 @@ import java.util.Date;
|
|||||||
import java.util.logging.Formatter;
|
import java.util.logging.Formatter;
|
||||||
import java.util.logging.LogRecord;
|
import java.util.logging.LogRecord;
|
||||||
|
|
||||||
|
import javax.annotation.concurrent.Immutable;
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
import static android.bluetooth.BluetoothAdapter.SCAN_MODE_CONNECTABLE;
|
import static android.bluetooth.BluetoothAdapter.SCAN_MODE_CONNECTABLE;
|
||||||
@@ -56,6 +60,8 @@ import static org.briarproject.bramble.util.PrivacyUtils.scrubInetAddress;
|
|||||||
import static org.briarproject.bramble.util.PrivacyUtils.scrubMacAddress;
|
import static org.briarproject.bramble.util.PrivacyUtils.scrubMacAddress;
|
||||||
import static org.briarproject.bramble.util.StringUtils.isNullOrEmpty;
|
import static org.briarproject.bramble.util.StringUtils.isNullOrEmpty;
|
||||||
|
|
||||||
|
@Immutable
|
||||||
|
@NotNullByDefault
|
||||||
class BriarReportCollector {
|
class BriarReportCollector {
|
||||||
|
|
||||||
private final Context ctx;
|
private final Context ctx;
|
||||||
@@ -66,9 +72,11 @@ class BriarReportCollector {
|
|||||||
|
|
||||||
public ReportData collectReportData(@Nullable Throwable t,
|
public ReportData collectReportData(@Nullable Throwable t,
|
||||||
long appStartTime) {
|
long appStartTime) {
|
||||||
return new ReportData()
|
ReportData reportData = new ReportData()
|
||||||
.add(getBasicInfo(t))
|
.add(getBasicInfo(t))
|
||||||
.add(getDeviceInfo())
|
.add(getDeviceInfo());
|
||||||
|
if (t != null) reportData.add(getStacktrace(t));
|
||||||
|
return reportData
|
||||||
.add(getTimeInfo(appStartTime))
|
.add(getTimeInfo(appStartTime))
|
||||||
.add(getMemory())
|
.add(getMemory())
|
||||||
.add(getStorage())
|
.add(getStorage())
|
||||||
@@ -91,27 +99,18 @@ class BriarReportCollector {
|
|||||||
versionCode = "?";
|
versionCode = "?";
|
||||||
}
|
}
|
||||||
MultiReportInfo basicInfo = new MultiReportInfo()
|
MultiReportInfo basicInfo = new MultiReportInfo()
|
||||||
.add("Package name", packageName)
|
.add("PackageName", packageName)
|
||||||
.add("Version name", versionName)
|
.add("VersionName", versionName)
|
||||||
.add("Version code", versionCode);
|
.add("VersionCode", versionCode)
|
||||||
// print stacktrace of Throwable if this is not feedback
|
.add("isCrashReport", String.valueOf(t != null));
|
||||||
if (t != null) {
|
|
||||||
final Writer sw = new StringWriter();
|
|
||||||
final PrintWriter printWriter = new PrintWriter(sw);
|
|
||||||
if (!isNullOrEmpty(t.getMessage())) {
|
|
||||||
printWriter.println(t.getMessage());
|
|
||||||
}
|
|
||||||
t.printStackTrace(printWriter);
|
|
||||||
basicInfo.add("stracktrace", sw.toString());
|
|
||||||
}
|
|
||||||
return new ReportItem("BasicInfo", R.string.dev_report_basic_info,
|
return new ReportItem("BasicInfo", R.string.dev_report_basic_info,
|
||||||
basicInfo, false);
|
basicInfo, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ReportItem getDeviceInfo() {
|
private ReportItem getDeviceInfo() {
|
||||||
MultiReportInfo deviceInfo = new MultiReportInfo()
|
MultiReportInfo deviceInfo = new MultiReportInfo()
|
||||||
.add("Android version", Build.VERSION.RELEASE)
|
.add("AndroidVersion", Build.VERSION.RELEASE)
|
||||||
.add("Android SDK API", String.valueOf(SDK_INT))
|
.add("AndroidApi", String.valueOf(SDK_INT))
|
||||||
.add("Product", Build.PRODUCT)
|
.add("Product", Build.PRODUCT)
|
||||||
.add("Model", Build.MODEL)
|
.add("Model", Build.MODEL)
|
||||||
.add("Brand", Build.BRAND);
|
.add("Brand", Build.BRAND);
|
||||||
@@ -119,10 +118,24 @@ class BriarReportCollector {
|
|||||||
deviceInfo);
|
deviceInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ReportItem getStacktrace(Throwable t) {
|
||||||
|
final Writer sw = new StringWriter();
|
||||||
|
final PrintWriter printWriter = new PrintWriter(sw);
|
||||||
|
if (!isNullOrEmpty(t.getMessage())) {
|
||||||
|
printWriter.println(t.getMessage());
|
||||||
|
}
|
||||||
|
t.printStackTrace(printWriter);
|
||||||
|
SingleReportInfo stacktrace = new SingleReportInfo(sw.toString());
|
||||||
|
return new ReportItem("Stacktrace", R.string.dev_report_stacktrace,
|
||||||
|
stacktrace);
|
||||||
|
}
|
||||||
|
|
||||||
private ReportItem getTimeInfo(long startTime) {
|
private ReportItem getTimeInfo(long startTime) {
|
||||||
MultiReportInfo timeInfo = new MultiReportInfo()
|
MultiReportInfo timeInfo = new MultiReportInfo()
|
||||||
.add("App start time", formatTime(startTime))
|
.add("ReportTime", formatTime(System.currentTimeMillis()));
|
||||||
.add("Crash time", formatTime(System.currentTimeMillis()));
|
if (startTime > -1) {
|
||||||
|
timeInfo.add("AppStartTime", formatTime(startTime));
|
||||||
|
}
|
||||||
return new ReportItem("DeviceInfo", R.string.dev_report_time_info,
|
return new ReportItem("DeviceInfo", R.string.dev_report_time_info,
|
||||||
timeInfo);
|
timeInfo);
|
||||||
}
|
}
|
||||||
@@ -132,53 +145,59 @@ class BriarReportCollector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private ReportItem getMemory() {
|
private ReportItem getMemory() {
|
||||||
|
MultiReportInfo memInfo = new MultiReportInfo();
|
||||||
|
|
||||||
// System memory
|
// System memory
|
||||||
ActivityManager am = getSystemService(ctx, ActivityManager.class);
|
ActivityManager am = getSystemService(ctx, ActivityManager.class);
|
||||||
ActivityManager.MemoryInfo mem = new ActivityManager.MemoryInfo();
|
ActivityManager.MemoryInfo mem = new ActivityManager.MemoryInfo();
|
||||||
requireNonNull(am).getMemoryInfo(mem);
|
requireNonNull(am).getMemoryInfo(mem);
|
||||||
String systemMemory;
|
String systemTotal = (mem.totalMem / 1024 / 1024) + " MiB";
|
||||||
systemMemory = (mem.totalMem / 1024 / 1024) + " MiB total, "
|
String systemFree = (mem.availMem / 1024 / 1024) + " MiB";
|
||||||
+ (mem.availMem / 1024 / 1204) + " MiB free, "
|
String systemThreshold = (mem.threshold / 1024 / 1024) + " MiB";
|
||||||
+ (mem.threshold / 1024 / 1024) + " MiB threshold";
|
memInfo.add("SystemMemoryTotal", systemTotal);
|
||||||
|
memInfo.add("SystemMemoryFree", systemFree);
|
||||||
|
memInfo.add("SystemMemoryThreshold", systemThreshold);
|
||||||
|
|
||||||
// Virtual machine memory
|
// Virtual machine memory
|
||||||
Runtime runtime = Runtime.getRuntime();
|
Runtime runtime = Runtime.getRuntime();
|
||||||
long heap = runtime.totalMemory();
|
long heap = runtime.totalMemory();
|
||||||
long heapFree = runtime.freeMemory();
|
long heapFree = runtime.freeMemory();
|
||||||
long heapMax = runtime.maxMemory();
|
long heapMax = runtime.maxMemory();
|
||||||
String vmMemory = (heap / 1024 / 1024) + " MiB allocated, "
|
String vmMemoryAllocated = (heap / 1024 / 1024) + " MiB";
|
||||||
+ (heapFree / 1024 / 1024) + " MiB free, "
|
String vmMemoryFree = (heapFree / 1024 / 1024) + " MiB";
|
||||||
+ (heapMax / 1024 / 1024) + " MiB maximum";
|
String vmMemoryMax = (heapMax / 1024 / 1024) + " MiB";
|
||||||
|
memInfo.add("VirtualMachineMemoryAllocated", vmMemoryAllocated);
|
||||||
|
memInfo.add("VirtualMachineMemoryFree", vmMemoryFree);
|
||||||
|
memInfo.add("VirtualMachineMemoryMaximum", vmMemoryMax);
|
||||||
|
|
||||||
MultiReportInfo memInfo = new MultiReportInfo()
|
|
||||||
.add("System memory", systemMemory)
|
|
||||||
.add("Virtual machine memory", vmMemory);
|
|
||||||
return new ReportItem("Memory", R.string.dev_report_memory, memInfo);
|
return new ReportItem("Memory", R.string.dev_report_memory, memInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ReportItem getStorage() {
|
private ReportItem getStorage() {
|
||||||
|
MultiReportInfo storageInfo = new MultiReportInfo();
|
||||||
|
|
||||||
// Internal storage
|
// Internal storage
|
||||||
File root = Environment.getRootDirectory();
|
File root = Environment.getRootDirectory();
|
||||||
long rootTotal = root.getTotalSpace();
|
long rootTotal = root.getTotalSpace();
|
||||||
long rootFree = root.getFreeSpace();
|
long rootFree = root.getFreeSpace();
|
||||||
String internal = (rootTotal / 1024 / 1024) + " MiB total, "
|
storageInfo.add("InternalStorageTotal",
|
||||||
+ (rootFree / 1024 / 1024) + " MiB free";
|
(rootTotal / 1024 / 1024) + " MiB");
|
||||||
|
storageInfo.add("InternalStorageFree",
|
||||||
|
(rootFree / 1024 / 1024) + " MiB");
|
||||||
|
|
||||||
// External storage (SD card)
|
// External storage (SD card)
|
||||||
File sd = Environment.getExternalStorageDirectory();
|
File sd = Environment.getExternalStorageDirectory();
|
||||||
long sdTotal = sd.getTotalSpace();
|
long sdTotal = sd.getTotalSpace();
|
||||||
long sdFree = sd.getFreeSpace();
|
long sdFree = sd.getFreeSpace();
|
||||||
String external = (sdTotal / 1024 / 1024) + " MiB total, "
|
storageInfo.add("ExternalStorageTotal",
|
||||||
+ (sdFree / 1024 / 1024) + " MiB free";
|
(sdTotal / 1024 / 1024) + " MiB");
|
||||||
|
storageInfo.add("ExternalStorageFree",
|
||||||
|
(sdFree / 1024 / 1024) + " MiB");
|
||||||
|
|
||||||
MultiReportInfo storageInfo = new MultiReportInfo()
|
|
||||||
.add("Internal storage", internal)
|
|
||||||
.add("External storage", external);
|
|
||||||
return new ReportItem("Storage", R.string.dev_report_storage,
|
return new ReportItem("Storage", R.string.dev_report_storage,
|
||||||
storageInfo);
|
storageInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private ReportItem getConnectivity() {
|
private ReportItem getConnectivity() {
|
||||||
MultiReportInfo connectivityInfo = new MultiReportInfo();
|
MultiReportInfo connectivityInfo = new MultiReportInfo();
|
||||||
|
|
||||||
@@ -193,7 +212,6 @@ class BriarReportCollector {
|
|||||||
Class<?> clazz = Class.forName(cm.getClass().getName());
|
Class<?> clazz = Class.forName(cm.getClass().getName());
|
||||||
Method method = clazz.getDeclaredMethod("getMobileDataEnabled");
|
Method method = clazz.getDeclaredMethod("getMobileDataEnabled");
|
||||||
method.setAccessible(true);
|
method.setAccessible(true);
|
||||||
//noinspection ConstantConditions
|
|
||||||
mobileEnabled = (Boolean) method.invoke(cm);
|
mobileEnabled = (Boolean) method.invoke(cm);
|
||||||
} catch (ClassNotFoundException
|
} catch (ClassNotFoundException
|
||||||
| NoSuchMethodException
|
| NoSuchMethodException
|
||||||
@@ -201,7 +219,7 @@ class BriarReportCollector {
|
|||||||
| InvocationTargetException
|
| InvocationTargetException
|
||||||
| IllegalAccessException e) {
|
| IllegalAccessException e) {
|
||||||
connectivityInfo
|
connectivityInfo
|
||||||
.add("Mobile data reflection exception", e.toString());
|
.add("MobileDataReflectionException", e.toString());
|
||||||
}
|
}
|
||||||
// Is mobile data connected ?
|
// Is mobile data connected ?
|
||||||
boolean mobileConnected = mobile != null && mobile.isConnected();
|
boolean mobileConnected = mobile != null && mobile.isConnected();
|
||||||
@@ -213,7 +231,7 @@ class BriarReportCollector {
|
|||||||
else mobileStatus += "not enabled, ";
|
else mobileStatus += "not enabled, ";
|
||||||
if (mobileConnected) mobileStatus += "connected";
|
if (mobileConnected) mobileStatus += "connected";
|
||||||
else mobileStatus += "not connected";
|
else mobileStatus += "not connected";
|
||||||
connectivityInfo.add("Mobile data status", mobileStatus);
|
connectivityInfo.add("MobileDataStatus", mobileStatus);
|
||||||
|
|
||||||
// Is wifi available?
|
// Is wifi available?
|
||||||
NetworkInfo wifi = cm.getNetworkInfo(TYPE_WIFI);
|
NetworkInfo wifi = cm.getNetworkInfo(TYPE_WIFI);
|
||||||
@@ -232,13 +250,13 @@ class BriarReportCollector {
|
|||||||
else wifiStatus += "not enabled, ";
|
else wifiStatus += "not enabled, ";
|
||||||
if (wifiConnected) wifiStatus += "connected";
|
if (wifiConnected) wifiStatus += "connected";
|
||||||
else wifiStatus += "not connected";
|
else wifiStatus += "not connected";
|
||||||
connectivityInfo.add("Wi-Fi status", wifiStatus);
|
connectivityInfo.add("WiFiStatus", wifiStatus);
|
||||||
|
|
||||||
// Is wifi direct supported?
|
// Is wifi direct supported?
|
||||||
String wifiDirectStatus = "Supported";
|
String wifiDirectStatus = "Supported";
|
||||||
if (ctx.getSystemService(WIFI_P2P_SERVICE) == null)
|
if (ctx.getSystemService(WIFI_P2P_SERVICE) == null)
|
||||||
wifiDirectStatus = "Not supported";
|
wifiDirectStatus = "NotSupported";
|
||||||
connectivityInfo.add("Wi-Fi Direct", wifiDirectStatus);
|
connectivityInfo.add("WiFiDirect", wifiDirectStatus);
|
||||||
|
|
||||||
if (wm != null) {
|
if (wm != null) {
|
||||||
WifiInfo wifiInfo = wm.getConnectionInfo();
|
WifiInfo wifiInfo = wm.getConnectionInfo();
|
||||||
@@ -252,7 +270,7 @@ class BriarReportCollector {
|
|||||||
try {
|
try {
|
||||||
InetAddress address = InetAddress.getByAddress(ipBytes);
|
InetAddress address = InetAddress.getByAddress(ipBytes);
|
||||||
connectivityInfo
|
connectivityInfo
|
||||||
.add("Wi-Fi address", scrubInetAddress(address));
|
.add("Wi-FiAddress", scrubInetAddress(address));
|
||||||
} catch (UnknownHostException ignored) {
|
} catch (UnknownHostException ignored) {
|
||||||
// Should only be thrown if address has illegal length
|
// Should only be thrown if address has illegal length
|
||||||
}
|
}
|
||||||
@@ -262,7 +280,7 @@ class BriarReportCollector {
|
|||||||
// Is Bluetooth available?
|
// Is Bluetooth available?
|
||||||
BluetoothAdapter bt = BluetoothAdapter.getDefaultAdapter();
|
BluetoothAdapter bt = BluetoothAdapter.getDefaultAdapter();
|
||||||
if (bt == null) {
|
if (bt == null) {
|
||||||
connectivityInfo.add("Bluetooth status", "Not available");
|
connectivityInfo.add("BluetoothStatus", "Not available");
|
||||||
} else {
|
} else {
|
||||||
// Is Bluetooth enabled?
|
// Is Bluetooth enabled?
|
||||||
@SuppressLint("HardwareIds")
|
@SuppressLint("HardwareIds")
|
||||||
@@ -283,7 +301,7 @@ class BriarReportCollector {
|
|||||||
else btStatus += "not connectable, ";
|
else btStatus += "not connectable, ";
|
||||||
if (btDiscoverable) btStatus += "discoverable";
|
if (btDiscoverable) btStatus += "discoverable";
|
||||||
else btStatus += "not discoverable";
|
else btStatus += "not discoverable";
|
||||||
connectivityInfo.add("Bluetooth status", btStatus);
|
connectivityInfo.add("BluetoothStatus", btStatus);
|
||||||
|
|
||||||
if (SDK_INT >= 21) {
|
if (SDK_INT >= 21) {
|
||||||
// Is Bluetooth LE scanning and advertising supported?
|
// Is Bluetooth LE scanning and advertising supported?
|
||||||
@@ -295,14 +313,14 @@ class BriarReportCollector {
|
|||||||
else btLeStatus = "No scanning, ";
|
else btLeStatus = "No scanning, ";
|
||||||
if (btLeAdvertise) btLeStatus += "advertising";
|
if (btLeAdvertise) btLeStatus += "advertising";
|
||||||
else btLeStatus += "no advertising";
|
else btLeStatus += "no advertising";
|
||||||
connectivityInfo.add("Bluetooth LE status", btLeStatus);
|
connectivityInfo.add("BluetoothLeStatus", btLeStatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
Pair<String, String> p = getBluetoothAddressAndMethod(ctx, bt);
|
Pair<String, String> p = getBluetoothAddressAndMethod(ctx, bt);
|
||||||
String address = p.getFirst();
|
String address = p.getFirst();
|
||||||
String method = p.getSecond();
|
String method = p.getSecond();
|
||||||
connectivityInfo.add("Bluetooth address", scrubMacAddress(address));
|
connectivityInfo.add("BluetoothAddress", scrubMacAddress(address));
|
||||||
connectivityInfo.add("Bluetooth address method", method);
|
connectivityInfo.add("BluetoothAddressMethod", method);
|
||||||
}
|
}
|
||||||
return new ReportItem("Connectivity", R.string.dev_report_connectivity,
|
return new ReportItem("Connectivity", R.string.dev_report_connectivity,
|
||||||
connectivityInfo);
|
connectivityInfo);
|
||||||
|
|||||||
@@ -8,34 +8,34 @@ import android.view.ViewGroup;
|
|||||||
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
||||||
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
|
||||||
import org.briarproject.briar.R;
|
import org.briarproject.briar.R;
|
||||||
import org.briarproject.briar.android.AndroidComponent;
|
import org.briarproject.briar.android.activity.ActivityComponent;
|
||||||
import org.briarproject.briar.android.BriarApplication;
|
import org.briarproject.briar.android.fragment.BaseFragment;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.fragment.app.Fragment;
|
|
||||||
import androidx.fragment.app.FragmentActivity;
|
|
||||||
import androidx.lifecycle.ViewModelProvider;
|
import androidx.lifecycle.ViewModelProvider;
|
||||||
|
|
||||||
@MethodsNotNullByDefault
|
@MethodsNotNullByDefault
|
||||||
@ParametersNotNullByDefault
|
@ParametersNotNullByDefault
|
||||||
public class CrashFragment extends Fragment {
|
public class CrashFragment extends BaseFragment {
|
||||||
|
|
||||||
|
public final static String TAG = CrashFragment.class.getName();
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
ViewModelProvider.Factory viewModelFactory;
|
ViewModelProvider.Factory viewModelFactory;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void injectFragment(ActivityComponent component) {
|
||||||
|
component.inject(this);
|
||||||
|
}
|
||||||
|
|
||||||
private ReportViewModel viewModel;
|
private ReportViewModel viewModel;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
FragmentActivity a = requireActivity();
|
viewModel = new ViewModelProvider(requireActivity(), viewModelFactory)
|
||||||
BriarApplication app =
|
|
||||||
(BriarApplication) a.getApplicationContext();
|
|
||||||
AndroidComponent androidComponent = app.getApplicationComponent();
|
|
||||||
androidComponent.inject(this);
|
|
||||||
viewModel = new ViewModelProvider(a, viewModelFactory)
|
|
||||||
.get(ReportViewModel.class);
|
.get(ReportViewModel.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,4 +55,9 @@ public class CrashFragment extends Fragment {
|
|||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getUniqueTag() {
|
||||||
|
return TAG;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,62 +1,60 @@
|
|||||||
package org.briarproject.briar.android.reporting;
|
package org.briarproject.briar.android.reporting;
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.os.Process;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
||||||
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
|
||||||
import org.briarproject.briar.R;
|
import org.briarproject.briar.R;
|
||||||
import org.briarproject.briar.android.AndroidComponent;
|
import org.briarproject.briar.android.activity.ActivityComponent;
|
||||||
import org.briarproject.briar.android.BriarApplication;
|
import org.briarproject.briar.android.activity.BaseActivity;
|
||||||
import org.briarproject.briar.android.Localizer;
|
import org.briarproject.briar.android.fragment.BaseFragment;
|
||||||
|
import org.briarproject.briar.android.fragment.BaseFragment.BaseFragmentListener;
|
||||||
import org.briarproject.briar.android.logout.HideUiActivity;
|
import org.briarproject.briar.android.logout.HideUiActivity;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
|
||||||
import androidx.appcompat.widget.Toolbar;
|
import androidx.appcompat.widget.Toolbar;
|
||||||
import androidx.fragment.app.Fragment;
|
|
||||||
import androidx.lifecycle.ViewModelProvider;
|
import androidx.lifecycle.ViewModelProvider;
|
||||||
|
|
||||||
import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK;
|
import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK;
|
||||||
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
|
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
|
||||||
import static android.content.Intent.FLAG_ACTIVITY_NO_ANIMATION;
|
import static android.content.Intent.FLAG_ACTIVITY_NO_ANIMATION;
|
||||||
import static android.view.WindowManager.LayoutParams.FLAG_SECURE;
|
|
||||||
import static android.widget.Toast.LENGTH_LONG;
|
import static android.widget.Toast.LENGTH_LONG;
|
||||||
import static java.util.Objects.requireNonNull;
|
import static java.util.Objects.requireNonNull;
|
||||||
import static org.briarproject.briar.android.TestingConstants.PREVENT_SCREENSHOTS;
|
|
||||||
|
|
||||||
@MethodsNotNullByDefault
|
@MethodsNotNullByDefault
|
||||||
@ParametersNotNullByDefault
|
@ParametersNotNullByDefault
|
||||||
public class CrashReportActivity extends AppCompatActivity {
|
public class CrashReportActivity extends BaseActivity
|
||||||
|
implements BaseFragmentListener {
|
||||||
|
|
||||||
static final String EXTRA_THROWABLE = "throwable";
|
public static final String EXTRA_THROWABLE = "throwable";
|
||||||
static final String EXTRA_APP_START_TIME = "appStartTime";
|
public static final String EXTRA_APP_START_TIME = "appStartTime";
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
ViewModelProvider.Factory viewModelFactory;
|
ViewModelProvider.Factory viewModelFactory;
|
||||||
|
|
||||||
private ReportViewModel viewModel;
|
private ReportViewModel viewModel;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void injectActivity(ActivityComponent component) {
|
||||||
|
component.inject(this);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
if (PREVENT_SCREENSHOTS) getWindow().addFlags(FLAG_SECURE);
|
|
||||||
setContentView(R.layout.activity_dev_report);
|
setContentView(R.layout.activity_dev_report);
|
||||||
|
|
||||||
AndroidComponent androidComponent =
|
|
||||||
((BriarApplication) getApplication()).getApplicationComponent();
|
|
||||||
androidComponent.inject(this);
|
|
||||||
|
|
||||||
viewModel = new ViewModelProvider(this, viewModelFactory)
|
viewModel = new ViewModelProvider(this, viewModelFactory)
|
||||||
.get(ReportViewModel.class);
|
.get(ReportViewModel.class);
|
||||||
Intent intent = getIntent();
|
Intent intent = getIntent();
|
||||||
Throwable t = (Throwable) intent.getSerializableExtra(EXTRA_THROWABLE);
|
Throwable t = (Throwable) intent.getSerializableExtra(EXTRA_THROWABLE);
|
||||||
long appStartTime = intent.getLongExtra(EXTRA_APP_START_TIME, 0);
|
long appStartTime = intent.getLongExtra(EXTRA_APP_START_TIME, -1);
|
||||||
viewModel.init(requireNonNull(t), appStartTime);
|
viewModel.init(t, appStartTime);
|
||||||
viewModel.getShowReport().observeEvent(this, show -> {
|
viewModel.getShowReport().observeEvent(this, show -> {
|
||||||
if (show) displayFragment(true);
|
if (show) displayFragment(true);
|
||||||
});
|
});
|
||||||
@@ -74,8 +72,8 @@ public class CrashReportActivity extends AppCompatActivity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void attachBaseContext(Context base) {
|
public void runOnDbThread(Runnable runnable) {
|
||||||
super.attachBaseContext(Localizer.getInstance().setLocale(base));
|
throw new AssertionError("deprecated!!!");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -84,7 +82,7 @@ public class CrashReportActivity extends AppCompatActivity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void displayFragment(boolean showReportForm) {
|
void displayFragment(boolean showReportForm) {
|
||||||
Fragment f;
|
BaseFragment f;
|
||||||
if (showReportForm) {
|
if (showReportForm) {
|
||||||
f = new ReportFormFragment();
|
f = new ReportFormFragment();
|
||||||
requireNonNull(getSupportActionBar()).show();
|
requireNonNull(getSupportActionBar()).show();
|
||||||
@@ -93,7 +91,7 @@ public class CrashReportActivity extends AppCompatActivity {
|
|||||||
requireNonNull(getSupportActionBar()).hide();
|
requireNonNull(getSupportActionBar()).hide();
|
||||||
}
|
}
|
||||||
getSupportFragmentManager().beginTransaction()
|
getSupportFragmentManager().beginTransaction()
|
||||||
.replace(R.id.fragmentContainer, f, f.getTag())
|
.replace(R.id.fragmentContainer, f, f.getUniqueTag())
|
||||||
.commit();
|
.commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -104,6 +102,10 @@ public class CrashReportActivity extends AppCompatActivity {
|
|||||||
| FLAG_ACTIVITY_NO_ANIMATION
|
| FLAG_ACTIVITY_NO_ANIMATION
|
||||||
| FLAG_ACTIVITY_CLEAR_TASK);
|
| FLAG_ACTIVITY_CLEAR_TASK);
|
||||||
startActivity(i);
|
startActivity(i);
|
||||||
|
// crash reports run in their own process that we should kill now
|
||||||
|
// otherwise it keeps running and e.g. doesn't pick up theme changes
|
||||||
|
Process.killProcess(Process.myPid());
|
||||||
|
System.exit(10);
|
||||||
}
|
}
|
||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,11 +10,13 @@ import java.util.Map;
|
|||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
|
|
||||||
import javax.annotation.concurrent.Immutable;
|
import javax.annotation.concurrent.Immutable;
|
||||||
|
import javax.annotation.concurrent.NotThreadSafe;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.annotation.StringRes;
|
import androidx.annotation.StringRes;
|
||||||
|
|
||||||
|
@NotThreadSafe
|
||||||
|
@NotNullByDefault
|
||||||
class ReportData {
|
class ReportData {
|
||||||
|
|
||||||
private final ArrayList<ReportItem> items = new ArrayList<>();
|
private final ArrayList<ReportItem> items = new ArrayList<>();
|
||||||
@@ -28,7 +30,6 @@ class ReportData {
|
|||||||
return items;
|
return items;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
|
||||||
public JSONObject toJson(boolean includeReport) throws JSONException {
|
public JSONObject toJson(boolean includeReport) throws JSONException {
|
||||||
JSONObject json = new JSONObject();
|
JSONObject json = new JSONObject();
|
||||||
for (ReportItem item : items) {
|
for (ReportItem item : items) {
|
||||||
@@ -48,7 +49,7 @@ class ReportData {
|
|||||||
final int nameRes;
|
final int nameRes;
|
||||||
final ReportInfo info;
|
final ReportInfo info;
|
||||||
final boolean isOptional;
|
final boolean isOptional;
|
||||||
volatile boolean isIncluded = true;
|
boolean isIncluded = true;
|
||||||
|
|
||||||
ReportItem(String name, int nameRes, ReportInfo info) {
|
ReportItem(String name, int nameRes, ReportInfo info) {
|
||||||
this(name, nameRes, info, true);
|
this(name, nameRes, info, true);
|
||||||
@@ -91,7 +92,6 @@ class ReportData {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Immutable
|
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
static class MultiReportInfo implements ReportInfo {
|
static class MultiReportInfo implements ReportInfo {
|
||||||
private final Map<String, String> map = new TreeMap<>();
|
private final Map<String, String> map = new TreeMap<>();
|
||||||
|
|||||||
@@ -15,14 +15,12 @@ import android.widget.Toast;
|
|||||||
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
||||||
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
|
||||||
import org.briarproject.briar.R;
|
import org.briarproject.briar.R;
|
||||||
import org.briarproject.briar.android.AndroidComponent;
|
import org.briarproject.briar.android.activity.ActivityComponent;
|
||||||
import org.briarproject.briar.android.BriarApplication;
|
import org.briarproject.briar.android.fragment.BaseFragment;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.fragment.app.Fragment;
|
|
||||||
import androidx.fragment.app.FragmentActivity;
|
|
||||||
import androidx.lifecycle.ViewModelProvider;
|
import androidx.lifecycle.ViewModelProvider;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
@@ -34,7 +32,9 @@ import static java.util.Objects.requireNonNull;
|
|||||||
|
|
||||||
@MethodsNotNullByDefault
|
@MethodsNotNullByDefault
|
||||||
@ParametersNotNullByDefault
|
@ParametersNotNullByDefault
|
||||||
public class ReportFormFragment extends Fragment {
|
public class ReportFormFragment extends BaseFragment {
|
||||||
|
|
||||||
|
public final static String TAG = ReportFormFragment.class.getName();
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
ViewModelProvider.Factory viewModelFactory;
|
ViewModelProvider.Factory viewModelFactory;
|
||||||
@@ -50,15 +50,16 @@ public class ReportFormFragment extends Fragment {
|
|||||||
@Nullable
|
@Nullable
|
||||||
private MenuItem sendReport;
|
private MenuItem sendReport;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void injectFragment(ActivityComponent component) {
|
||||||
|
component.inject(this);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
setHasOptionsMenu(true);
|
setHasOptionsMenu(true);
|
||||||
FragmentActivity a = requireActivity();
|
viewModel = new ViewModelProvider(requireActivity(), viewModelFactory)
|
||||||
BriarApplication app = (BriarApplication) a.getApplicationContext();
|
|
||||||
AndroidComponent androidComponent = app.getApplicationComponent();
|
|
||||||
androidComponent.inject(this);
|
|
||||||
viewModel = new ViewModelProvider(a, viewModelFactory)
|
|
||||||
.get(ReportViewModel.class);
|
.get(ReportViewModel.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -131,6 +132,11 @@ public class ReportFormFragment extends Fragment {
|
|||||||
return super.onOptionsItemSelected(item);
|
return super.onOptionsItemSelected(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getUniqueTag() {
|
||||||
|
return TAG;
|
||||||
|
}
|
||||||
|
|
||||||
private void sendReport() {
|
private void sendReport() {
|
||||||
userCommentView.setEnabled(false);
|
userCommentView.setEnabled(false);
|
||||||
userEmailView.setEnabled(false);
|
userEmailView.setEnabled(false);
|
||||||
|
|||||||
@@ -4,8 +4,7 @@ import android.app.Application;
|
|||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
|
|
||||||
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
|
|
||||||
import org.briarproject.bramble.api.plugin.Plugin;
|
import org.briarproject.bramble.api.plugin.Plugin;
|
||||||
import org.briarproject.bramble.api.plugin.PluginManager;
|
import org.briarproject.bramble.api.plugin.PluginManager;
|
||||||
import org.briarproject.bramble.api.plugin.TorConstants;
|
import org.briarproject.bramble.api.plugin.TorConstants;
|
||||||
@@ -13,7 +12,6 @@ import org.briarproject.bramble.api.reporting.DevReporter;
|
|||||||
import org.briarproject.bramble.util.AndroidUtils;
|
import org.briarproject.bramble.util.AndroidUtils;
|
||||||
import org.briarproject.briar.R;
|
import org.briarproject.briar.R;
|
||||||
import org.briarproject.briar.android.reporting.ReportData.MultiReportInfo;
|
import org.briarproject.briar.android.reporting.ReportData.MultiReportInfo;
|
||||||
import org.briarproject.briar.android.util.UserFeedback;
|
|
||||||
import org.briarproject.briar.android.viewmodel.LiveEvent;
|
import org.briarproject.briar.android.viewmodel.LiveEvent;
|
||||||
import org.briarproject.briar.android.viewmodel.MutableLiveEvent;
|
import org.briarproject.briar.android.viewmodel.MutableLiveEvent;
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
@@ -26,6 +24,7 @@ import java.util.logging.Logger;
|
|||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
import androidx.annotation.UiThread;
|
import androidx.annotation.UiThread;
|
||||||
import androidx.lifecycle.AndroidViewModel;
|
import androidx.lifecycle.AndroidViewModel;
|
||||||
import androidx.lifecycle.LiveData;
|
import androidx.lifecycle.LiveData;
|
||||||
@@ -38,8 +37,7 @@ import static org.briarproject.bramble.api.plugin.Plugin.State.ACTIVE;
|
|||||||
import static org.briarproject.bramble.util.LogUtils.logException;
|
import static org.briarproject.bramble.util.LogUtils.logException;
|
||||||
import static org.briarproject.bramble.util.StringUtils.isNullOrEmpty;
|
import static org.briarproject.bramble.util.StringUtils.isNullOrEmpty;
|
||||||
|
|
||||||
@MethodsNotNullByDefault
|
@NotNullByDefault
|
||||||
@ParametersNotNullByDefault
|
|
||||||
public class ReportViewModel extends AndroidViewModel {
|
public class ReportViewModel extends AndroidViewModel {
|
||||||
|
|
||||||
private static final Logger LOG =
|
private static final Logger LOG =
|
||||||
@@ -68,11 +66,11 @@ public class ReportViewModel extends AndroidViewModel {
|
|||||||
this.pluginManager = pluginManager;
|
this.pluginManager = pluginManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
void init(Throwable throwable, long appStartTime) {
|
void init(@Nullable Throwable t, long appStartTime) {
|
||||||
isFeedback = throwable instanceof UserFeedback;
|
isFeedback = t == null;
|
||||||
if (reportData.getValue() == null) new SingleShotAndroidExecutor(() -> {
|
if (reportData.getValue() == null) new SingleShotAndroidExecutor(() -> {
|
||||||
Throwable t = isFeedback ? null : throwable;
|
ReportData data = collector.collectReportData(t, appStartTime);
|
||||||
reportData.postValue(collector.collectReportData(t, appStartTime));
|
reportData.postValue(data);
|
||||||
}).start();
|
}).start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,6 @@ import org.briarproject.bramble.api.system.LocationUtils;
|
|||||||
import org.briarproject.bramble.plugin.tor.CircumventionProvider;
|
import org.briarproject.bramble.plugin.tor.CircumventionProvider;
|
||||||
import org.briarproject.bramble.util.StringUtils;
|
import org.briarproject.bramble.util.StringUtils;
|
||||||
import org.briarproject.briar.R;
|
import org.briarproject.briar.R;
|
||||||
import org.briarproject.briar.android.BriarApplication;
|
|
||||||
import org.briarproject.briar.android.Localizer;
|
import org.briarproject.briar.android.Localizer;
|
||||||
import org.briarproject.briar.android.util.UiUtils;
|
import org.briarproject.briar.android.util.UiUtils;
|
||||||
|
|
||||||
@@ -93,6 +92,7 @@ import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_RINGT
|
|||||||
import static org.briarproject.briar.android.navdrawer.NavDrawerActivity.SIGN_OUT_URI;
|
import static org.briarproject.briar.android.navdrawer.NavDrawerActivity.SIGN_OUT_URI;
|
||||||
import static org.briarproject.briar.android.util.UiUtils.getCountryDisplayName;
|
import static org.briarproject.briar.android.util.UiUtils.getCountryDisplayName;
|
||||||
import static org.briarproject.briar.android.util.UiUtils.hasScreenLock;
|
import static org.briarproject.briar.android.util.UiUtils.hasScreenLock;
|
||||||
|
import static org.briarproject.briar.android.util.UiUtils.triggerFeedback;
|
||||||
import static org.briarproject.briar.api.android.AndroidNotificationManager.BLOG_CHANNEL_ID;
|
import static org.briarproject.briar.api.android.AndroidNotificationManager.BLOG_CHANNEL_ID;
|
||||||
import static org.briarproject.briar.api.android.AndroidNotificationManager.CONTACT_CHANNEL_ID;
|
import static org.briarproject.briar.api.android.AndroidNotificationManager.CONTACT_CHANNEL_ID;
|
||||||
import static org.briarproject.briar.api.android.AndroidNotificationManager.FORUM_CHANNEL_ID;
|
import static org.briarproject.briar.api.android.AndroidNotificationManager.FORUM_CHANNEL_ID;
|
||||||
@@ -226,9 +226,7 @@ public class SettingsFragment extends PreferenceFragmentCompat
|
|||||||
Preference prefFeedback =
|
Preference prefFeedback =
|
||||||
requireNonNull(findPreference("pref_key_send_feedback"));
|
requireNonNull(findPreference("pref_key_send_feedback"));
|
||||||
prefFeedback.setOnPreferenceClickListener(preference -> {
|
prefFeedback.setOnPreferenceClickListener(preference -> {
|
||||||
BriarApplication app =
|
triggerFeedback(requireContext());
|
||||||
(BriarApplication) requireContext().getApplicationContext();
|
|
||||||
app.triggerFeedback();
|
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ import org.briarproject.bramble.api.identity.Author;
|
|||||||
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
||||||
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
|
||||||
import org.briarproject.briar.R;
|
import org.briarproject.briar.R;
|
||||||
|
import org.briarproject.briar.android.reporting.FeedbackActivity;
|
||||||
import org.briarproject.briar.android.view.ArticleMovementMethod;
|
import org.briarproject.briar.android.view.ArticleMovementMethod;
|
||||||
import org.briarproject.briar.android.widget.LinkDialogFragment;
|
import org.briarproject.briar.android.widget.LinkDialogFragment;
|
||||||
|
|
||||||
@@ -49,6 +50,7 @@ import androidx.appcompat.app.AlertDialog;
|
|||||||
import androidx.core.content.ContextCompat;
|
import androidx.core.content.ContextCompat;
|
||||||
import androidx.core.hardware.fingerprint.FingerprintManagerCompat;
|
import androidx.core.hardware.fingerprint.FingerprintManagerCompat;
|
||||||
import androidx.core.text.HtmlCompat;
|
import androidx.core.text.HtmlCompat;
|
||||||
|
import androidx.fragment.app.FragmentActivity;
|
||||||
import androidx.fragment.app.FragmentManager;
|
import androidx.fragment.app.FragmentManager;
|
||||||
import androidx.lifecycle.LifecycleOwner;
|
import androidx.lifecycle.LifecycleOwner;
|
||||||
import androidx.lifecycle.LiveData;
|
import androidx.lifecycle.LiveData;
|
||||||
@@ -90,6 +92,8 @@ import static java.util.Objects.requireNonNull;
|
|||||||
import static java.util.concurrent.TimeUnit.DAYS;
|
import static java.util.concurrent.TimeUnit.DAYS;
|
||||||
import static org.briarproject.briar.BuildConfig.APPLICATION_ID;
|
import static org.briarproject.briar.BuildConfig.APPLICATION_ID;
|
||||||
import static org.briarproject.briar.android.TestingConstants.EXPIRY_DATE;
|
import static org.briarproject.briar.android.TestingConstants.EXPIRY_DATE;
|
||||||
|
import static org.briarproject.briar.android.reporting.CrashReportActivity.EXTRA_APP_START_TIME;
|
||||||
|
import static org.briarproject.briar.android.reporting.CrashReportActivity.EXTRA_THROWABLE;
|
||||||
|
|
||||||
@MethodsNotNullByDefault
|
@MethodsNotNullByDefault
|
||||||
@ParametersNotNullByDefault
|
@ParametersNotNullByDefault
|
||||||
@@ -343,6 +347,20 @@ public class UiUtils {
|
|||||||
return fm.hasEnrolledFingerprints() && fm.isHardwareDetected();
|
return fm.hasEnrolledFingerprints() && fm.isHardwareDetected();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void triggerFeedback(Context ctx) {
|
||||||
|
startDevReportActivity(ctx, FeedbackActivity.class, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void startDevReportActivity(Context ctx,
|
||||||
|
Class<? extends FragmentActivity> activity, @Nullable Throwable t,
|
||||||
|
@Nullable Long appStartTime) {
|
||||||
|
final Intent dialogIntent = new Intent(ctx, activity);
|
||||||
|
dialogIntent.setFlags(FLAG_ACTIVITY_NEW_TASK);
|
||||||
|
dialogIntent.putExtra(EXTRA_THROWABLE, t);
|
||||||
|
dialogIntent.putExtra(EXTRA_APP_START_TIME, appStartTime);
|
||||||
|
ctx.startActivity(dialogIntent);
|
||||||
|
}
|
||||||
|
|
||||||
public static boolean enterPressed(int actionId,
|
public static boolean enterPressed(int actionId,
|
||||||
@Nullable KeyEvent keyEvent) {
|
@Nullable KeyEvent keyEvent) {
|
||||||
return actionId == IME_NULL &&
|
return actionId == IME_NULL &&
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
package org.briarproject.briar.android.util;
|
|
||||||
|
|
||||||
public class UserFeedback extends Exception {
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -570,6 +570,7 @@
|
|||||||
<string name="could_not_load_report_data">Could not load report data.</string>
|
<string name="could_not_load_report_data">Could not load report data.</string>
|
||||||
<string name="dev_report_basic_info">Basic information</string>
|
<string name="dev_report_basic_info">Basic information</string>
|
||||||
<string name="dev_report_device_info">Device information</string>
|
<string name="dev_report_device_info">Device information</string>
|
||||||
|
<string name="dev_report_stacktrace">Stacktrace</string>
|
||||||
<string name="dev_report_time_info">Time information</string>
|
<string name="dev_report_time_info">Time information</string>
|
||||||
<string name="dev_report_memory">Memory</string>
|
<string name="dev_report_memory">Memory</string>
|
||||||
<string name="dev_report_storage">Storage</string>
|
<string name="dev_report_storage">Storage</string>
|
||||||
@@ -579,7 +580,7 @@
|
|||||||
<string name="dev_report_device_features">Device Features</string>
|
<string name="dev_report_device_features">Device Features</string>
|
||||||
<string name="send_report">Send report</string>
|
<string name="send_report">Send report</string>
|
||||||
<string name="close">Close</string>
|
<string name="close">Close</string>
|
||||||
<string name="dev_report_sending">Trying to send feedback now…</string>
|
<string name="dev_report_sending">Sending feedback…</string>
|
||||||
<string name="dev_report_sent">Feedback sent.</string>
|
<string name="dev_report_sent">Feedback sent.</string>
|
||||||
<string name="dev_report_saved">Report saved. It will be sent the next time you log into Briar.</string>
|
<string name="dev_report_saved">Report saved. It will be sent the next time you log into Briar.</string>
|
||||||
<string name="dev_report_error">Error: Sending report failed.</string>
|
<string name="dev_report_error">Error: Sending report failed.</string>
|
||||||
|
|||||||
@@ -1,85 +0,0 @@
|
|||||||
package org.briarproject.briar.android;
|
|
||||||
|
|
||||||
import android.app.Application;
|
|
||||||
import android.content.SharedPreferences;
|
|
||||||
import android.preference.PreferenceManager;
|
|
||||||
|
|
||||||
import com.vanniktech.emoji.EmojiManager;
|
|
||||||
import com.vanniktech.emoji.google.GoogleEmojiProvider;
|
|
||||||
|
|
||||||
import org.briarproject.bramble.BrambleAndroidEagerSingletons;
|
|
||||||
import org.briarproject.bramble.BrambleAppComponent;
|
|
||||||
import org.briarproject.bramble.BrambleCoreEagerSingletons;
|
|
||||||
import org.briarproject.briar.BriarCoreEagerSingletons;
|
|
||||||
|
|
||||||
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
|
|
||||||
*/
|
|
||||||
public class TestBriarApplication extends Application
|
|
||||||
implements BriarApplication {
|
|
||||||
|
|
||||||
private static final Logger LOG =
|
|
||||||
Logger.getLogger(TestBriarApplication.class.getName());
|
|
||||||
|
|
||||||
private AndroidComponent applicationComponent;
|
|
||||||
private volatile SharedPreferences prefs;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCreate() {
|
|
||||||
super.onCreate();
|
|
||||||
LOG.info("Created");
|
|
||||||
|
|
||||||
prefs = PreferenceManager.getDefaultSharedPreferences(this);
|
|
||||||
Localizer.initialize(prefs);
|
|
||||||
applicationComponent = DaggerAndroidComponent.builder()
|
|
||||||
.appModule(new AppModule(this))
|
|
||||||
.build();
|
|
||||||
|
|
||||||
// We need to load the eager singletons directly after making the
|
|
||||||
// dependency graphs
|
|
||||||
BrambleCoreEagerSingletons.Helper
|
|
||||||
.injectEagerSingletons(applicationComponent);
|
|
||||||
BrambleAndroidEagerSingletons.Helper
|
|
||||||
.injectEagerSingletons(applicationComponent);
|
|
||||||
BriarCoreEagerSingletons.Helper
|
|
||||||
.injectEagerSingletons(applicationComponent);
|
|
||||||
AndroidEagerSingletons.Helper
|
|
||||||
.injectEagerSingletons(applicationComponent);
|
|
||||||
EmojiManager.install(new GoogleEmojiProvider());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BrambleAppComponent getBrambleAppComponent() {
|
|
||||||
return applicationComponent;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Collection<LogRecord> getRecentLogRecords() {
|
|
||||||
return emptyList();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AndroidComponent getApplicationComponent() {
|
|
||||||
return applicationComponent;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SharedPreferences getDefaultSharedPreferences() {
|
|
||||||
return prefs;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void triggerFeedback() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isRunningInBackground() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -3,7 +3,6 @@ package org.briarproject.briar.android.account;
|
|||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
import org.briarproject.briar.R;
|
import org.briarproject.briar.R;
|
||||||
import org.briarproject.briar.android.TestBriarApplication;
|
|
||||||
import org.briarproject.briar.android.login.StrengthMeter;
|
import org.briarproject.briar.android.login.StrengthMeter;
|
||||||
import org.hamcrest.Description;
|
import org.hamcrest.Description;
|
||||||
import org.hamcrest.Matcher;
|
import org.hamcrest.Matcher;
|
||||||
@@ -42,7 +41,7 @@ import static org.briarproject.briar.android.login.StrengthMeter.YELLOW;
|
|||||||
import static org.hamcrest.Matchers.not;
|
import static org.hamcrest.Matchers.not;
|
||||||
|
|
||||||
@RunWith(AndroidJUnit4.class)
|
@RunWith(AndroidJUnit4.class)
|
||||||
@Config(sdk = 21, application = TestBriarApplication.class)
|
@Config(sdk = 21)
|
||||||
public class SetupActivityTest {
|
public class SetupActivityTest {
|
||||||
|
|
||||||
@Rule
|
@Rule
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import org.briarproject.bramble.api.db.DbException;
|
|||||||
import org.briarproject.bramble.api.identity.Author;
|
import org.briarproject.bramble.api.identity.Author;
|
||||||
import org.briarproject.bramble.api.identity.AuthorInfo;
|
import org.briarproject.bramble.api.identity.AuthorInfo;
|
||||||
import org.briarproject.bramble.api.sync.MessageId;
|
import org.briarproject.bramble.api.sync.MessageId;
|
||||||
import org.briarproject.briar.android.TestBriarApplication;
|
|
||||||
import org.briarproject.briar.android.controller.handler.UiResultExceptionHandler;
|
import org.briarproject.briar.android.controller.handler.UiResultExceptionHandler;
|
||||||
import org.briarproject.briar.android.threaded.ThreadItemAdapter;
|
import org.briarproject.briar.android.threaded.ThreadItemAdapter;
|
||||||
import org.briarproject.briar.android.threaded.ThreadItemList;
|
import org.briarproject.briar.android.threaded.ThreadItemList;
|
||||||
@@ -36,7 +35,7 @@ import static org.mockito.Mockito.times;
|
|||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
|
|
||||||
@RunWith(RobolectricTestRunner.class)
|
@RunWith(RobolectricTestRunner.class)
|
||||||
@Config(sdk = 21, application = TestBriarApplication.class)
|
@Config(sdk = 21)
|
||||||
public class ForumActivityTest {
|
public class ForumActivityTest {
|
||||||
|
|
||||||
private final static MessageId[] MESSAGE_IDS = new MessageId[6];
|
private final static MessageId[] MESSAGE_IDS = new MessageId[6];
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import com.google.android.material.textfield.TextInputLayout;
|
|||||||
|
|
||||||
import org.briarproject.bramble.api.crypto.DecryptionResult;
|
import org.briarproject.bramble.api.crypto.DecryptionResult;
|
||||||
import org.briarproject.briar.R;
|
import org.briarproject.briar.R;
|
||||||
import org.briarproject.briar.android.TestBriarApplication;
|
|
||||||
import org.briarproject.briar.android.viewmodel.MutableLiveEvent;
|
import org.briarproject.briar.android.viewmodel.MutableLiveEvent;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
@@ -36,7 +35,7 @@ import static org.mockito.Mockito.verify;
|
|||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
@RunWith(RobolectricTestRunner.class)
|
@RunWith(RobolectricTestRunner.class)
|
||||||
@Config(sdk = 21, application = TestBriarApplication.class)
|
@Config(sdk = 21)
|
||||||
public class ChangePasswordActivityTest {
|
public class ChangePasswordActivityTest {
|
||||||
|
|
||||||
private ChangePasswordActivity changePasswordActivity;
|
private ChangePasswordActivity changePasswordActivity;
|
||||||
|
|||||||
Reference in New Issue
Block a user