Skip to content

Commit

Permalink
Add Markdown export of crash logs
Browse files Browse the repository at this point in the history
Add content country as additional debug information to reports
  • Loading branch information
TobiGr committed May 13, 2020
1 parent b3eadb5 commit 4846094
Show file tree
Hide file tree
Showing 3 changed files with 150 additions and 33 deletions.
155 changes: 124 additions & 31 deletions app/src/main/java/org/schabi/newpipe/report/ErrorActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import android.app.Activity;
import android.app.AlertDialog;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
Expand All @@ -20,6 +22,7 @@
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
Expand Down Expand Up @@ -81,6 +84,10 @@ public class ErrorActivity extends AppCompatActivity {
public static final String ERROR_EMAIL_ADDRESS = "[email protected]";
public static final String ERROR_EMAIL_SUBJECT
= "Exception in NewPipe " + BuildConfig.VERSION_NAME;

public static final String ERROR_GITHUB_ISSUE_URL
= "https://github.com/TeamNewPipe/NewPipe/issues";

private String[] errorList;
private ErrorInfo errorInfo;
private Class returnActivity;
Expand Down Expand Up @@ -200,7 +207,10 @@ protected void onCreate(final Bundle savedInstanceState) {
actionBar.setDisplayShowTitleEnabled(true);
}

Button reportButton = findViewById(R.id.errorReportButton);
Button reportEmailButton = findViewById(R.id.errorReportEmailButton);
Button copyButton = findViewById(R.id.errorReportCopyButton);
Button reportGithubButton = findViewById(R.id.errorReportGitHubButton);

userCommentBox = findViewById(R.id.errorCommentBox);
TextView errorView = findViewById(R.id.errorView);
TextView infoView = findViewById(R.id.errorInfosView);
Expand All @@ -212,37 +222,28 @@ protected void onCreate(final Bundle savedInstanceState) {
errorList = intent.getStringArrayExtra(ERROR_LIST);

// important add guru meditation
addGuruMeditaion();
addGuruMeditation();
currentTimeStamp = getCurrentTimeStamp();

reportButton.setOnClickListener((View v) -> {
Context context = this;
new AlertDialog.Builder(context)
.setIcon(android.R.drawable.ic_dialog_alert)
.setTitle(R.string.privacy_policy_title)
.setMessage(R.string.start_accept_privacy_policy)
.setCancelable(false)
.setNeutralButton(R.string.read_privacy_policy, (dialog, which) -> {
Intent webIntent = new Intent(Intent.ACTION_VIEW,
Uri.parse(context.getString(R.string.privacy_policy_url))
);
context.startActivity(webIntent);
})
.setPositiveButton(R.string.accept, (dialog, which) -> {
Intent i = new Intent(Intent.ACTION_SENDTO);
i.setData(Uri.parse("mailto:" + ERROR_EMAIL_ADDRESS))
.putExtra(Intent.EXTRA_SUBJECT, ERROR_EMAIL_SUBJECT)
.putExtra(Intent.EXTRA_TEXT, buildJson());
reportEmailButton.setOnClickListener((View v) -> {
openPrivacyPolicyDialog(this, "EMAIL");
});

startActivity(Intent.createChooser(i, "Send Email"));
})
.setNegativeButton(R.string.decline, (dialog, which) -> {
// do nothing
})
.show();
copyButton.setOnClickListener((View v) -> {
ClipboardManager clipboard =
(ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
ClipData clip = ClipData.newPlainText(
"NewPipe error report",
buildMarkdown());
clipboard.setPrimaryClip(clip);
Toast.makeText(this, R.string.msg_copied, Toast.LENGTH_SHORT).show();
});

reportGithubButton.setOnClickListener((View v) -> {
openPrivacyPolicyDialog(this, "GITHUB");
});


// normal bugreport
buildInfo(errorInfo);
if (errorInfo.message != 0) {
Expand Down Expand Up @@ -285,6 +286,38 @@ public boolean onOptionsItemSelected(final MenuItem item) {
return false;
}

private void openPrivacyPolicyDialog(final Context context, final String action) {
new AlertDialog.Builder(context)
.setIcon(android.R.drawable.ic_dialog_alert)
.setTitle(R.string.privacy_policy_title)
.setMessage(R.string.start_accept_privacy_policy)
.setCancelable(false)
.setNeutralButton(R.string.read_privacy_policy, (dialog, which) -> {
Intent webIntent = new Intent(Intent.ACTION_VIEW,
Uri.parse(context.getString(R.string.privacy_policy_url))
);
context.startActivity(webIntent);
})
.setPositiveButton(R.string.accept, (dialog, which) -> {
if (action.equals("EMAIL")) { // send on email
Intent i = new Intent(Intent.ACTION_SENDTO);
i.setData(Uri.parse("mailto:" + ERROR_EMAIL_ADDRESS))
.putExtra(Intent.EXTRA_SUBJECT, ERROR_EMAIL_SUBJECT)
.putExtra(Intent.EXTRA_TEXT, buildJson());
startActivity(Intent.createChooser(i, "Send Email"));
} else if (action.equals("GITHUB")) { // open the NewPipe issue page on GitHub
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(ERROR_GITHUB_ISSUE_URL));
startActivity(Intent.createChooser(i, "Report issue on GitHub"));
}

})
.setNegativeButton(R.string.decline, (dialog, which) -> {
// do nothing
})
.show();
}

private String formErrorText(final String[] el) {
StringBuilder text = new StringBuilder();
if (el != null) {
Expand Down Expand Up @@ -335,7 +368,8 @@ private void buildInfo(final ErrorInfo info) {

text += getUserActionString(info.userAction) + "\n"
+ info.request + "\n"
+ getContentLangString() + "\n"
+ getContentLanguageString() + "\n"
+ getContentCountryString() + "\n"
+ info.serviceName + "\n"
+ currentTimeStamp + "\n"
+ getPackageName() + "\n"
Expand All @@ -351,7 +385,8 @@ private String buildJson() {
.object()
.value("user_action", getUserActionString(errorInfo.userAction))
.value("request", errorInfo.request)
.value("content_language", getContentLangString())
.value("content_language", getContentLanguageString())
.value("content_country", getContentLanguageString())
.value("service", errorInfo.serviceName)
.value("package", getPackageName())
.value("version", BuildConfig.VERSION_NAME)
Expand All @@ -369,6 +404,55 @@ private String buildJson() {
return "";
}

private String buildMarkdown() {
StringBuilder htmlErrorReport = new StringBuilder();

final String userComment = userCommentBox.getText().toString();
if (!userComment.isEmpty()) {
htmlErrorReport.append(userComment).append("\n");
}

// basic error info
htmlErrorReport
.append("## Exception")
.append("\n* __User Action:__ ").append(getUserActionString(errorInfo.userAction))
.append("\n* __Request:__ ").append(errorInfo.request)
.append("\n* __Content Country:__ ").append(getContentCountryString())
.append("\n* __Content Language:__ ").append(getContentLanguageString())
.append("\n* __Service:__ ").append(errorInfo.serviceName)
.append("\n* __Version:__ ").append(BuildConfig.VERSION_NAME)
.append("\n* __OS:__ ").append(getOsString()).append("\n");


// Collapse all logs to a single paragraph when there are more than one
// to keep the GitHub issue clean.
if (errorList.length > 1) {
htmlErrorReport
.append("<details><summary><b>Exceptions (")
.append(errorList.length)
.append(")</b></summary><p>\n");
}

// add the logs
for (int i = 0; i < errorList.length; i++) {
htmlErrorReport.append("<details><summary><b>Crash log ");
if (errorList.length > 1) {
htmlErrorReport.append(i + 1);
}
htmlErrorReport.append("</b>")
.append("</summary><p>\n")
.append("\n```\n").append(errorList[i]).append("\n```\n")
.append("</details>\n");
}

// make sure to close everything
if (errorList.length > 1) {
htmlErrorReport.append("</p></details>\n");
}
htmlErrorReport.append("<hr>\n");
return htmlErrorReport.toString();
}

private String getUserActionString(final UserAction userAction) {
if (userAction == null) {
return "Your description is in another castle.";
Expand All @@ -377,9 +461,18 @@ private String getUserActionString(final UserAction userAction) {
}
}

private String getContentLangString() {
String contentLanguage = PreferenceManager.getDefaultSharedPreferences(this)
private String getContentCountryString() {
String contentCountry = PreferenceManager.getDefaultSharedPreferences(this)
.getString(this.getString(R.string.content_country_key), "none");
if (contentCountry.equals(getString(R.string.default_localization_key))) {
contentCountry = Locale.getDefault().toString();
}
return contentCountry;
}

private String getContentLanguageString() {
String contentLanguage = PreferenceManager.getDefaultSharedPreferences(this)
.getString(this.getString(R.string.content_language_key), "none");
if (contentLanguage.equals(getString(R.string.default_localization_key))) {
contentLanguage = Locale.getDefault().toString();
}
Expand All @@ -394,7 +487,7 @@ private String getOsString() {
+ " - " + Build.VERSION.SDK_INT;
}

private void addGuruMeditaion() {
private void addGuruMeditation() {
//just an easter egg
TextView sorryView = findViewById(R.id.errorSorryView);
String text = sorryView.getText().toString();
Expand Down
22 changes: 21 additions & 1 deletion app/src/main/res/layout/activity_error.xml
Original file line number Diff line number Diff line change
Expand Up @@ -118,11 +118,31 @@
android:inputType="" />

<Button
android:id="@+id/errorReportButton"
android:id="@+id/errorReportEmailButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/error_report_button_text" />

<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_marginBottom="5dp"
android:textStyle="bold"
android:text="@string/error_report_open_github_notice" />

<Button
android:id="@+id/errorReportCopyButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/copy_for_github" />

<Button
android:id="@+id/errorReportGitHubButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/error_report_open_issue_button_text" />

</LinearLayout>
</ScrollView>

Expand Down
6 changes: 5 additions & 1 deletion app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -234,11 +234,15 @@
<string name="sorry_string">Sorry, that should not have happened.</string>
<string name="guru_meditation" translatable="false">Guru Meditation.</string>
<string name="error_report_button_text">Report this error via e-mail</string>
<string name="copy_for_github">Copy formatted report</string>
<string name="error_report_open_issue_button_text">Report error on GitHub</string>
<string name="error_report_switch_document_text">Append page content which possibly caused the crash to the error report.</string>
<string name="error_report_open_github_notice">Please check whether an issue discussing your crash already exists. When creating duplicate tickets, you take time from us which we could spend with fixing the actual bug.</string>
<string name="error_snackbar_message">Sorry, some errors occurred.</string>
<string name="error_snackbar_action">Report</string>
<string name="what_device_headline">Info:</string>
<string name="what_happened_headline">What happened:</string>
<string name="info_labels">What:\\nRequest:\\nContent Lang:\\nService:\\nGMT Time:\\nPackage:\\nVersion:\\nOS version:</string>
<string name="info_labels">What:\\nRequest:\\nContent Lang:\\nContent Country:\\nService:\\nGMT Time:\\nPackage:\\nVersion:\\nOS version:</string>
<string name="your_comment">Your comment (in English):</string>
<string name="error_details_headline">Details:</string>
<!-- Content descriptions (for better accessibility) -->
Expand Down

0 comments on commit 4846094

Please sign in to comment.