Fix sentry + arch specific builds

Signed-off-by: androidacy-user <opensource@androidacy.com>
pull/27/head
androidacy-user 3 years ago
parent edea473b09
commit a61ca71221

@ -33,6 +33,28 @@ android {
signingConfig signingConfigs.release signingConfig signingConfigs.release
} }
splits {
// Configures multiple APKs based on ABI.
abi {
// Enables building multiple APKs per ABI.
enable true
// By default all ABIs are included, so use reset() and include to specify that we only
// want APKs for x86 and x86_64.
// Resets the list of ABIs that Gradle should create APKs for to none.
reset()
// Specifies a list of ABIs that Gradle should create APKs for.
include "x86", "x86_64", "armeabi-v7a", "arm64-v8a"
// Specifies that we do not want to also generate a universal APK that includes all ABIs.
universalApk true
}
}
buildTypes { buildTypes {
release { release {
minifyEnabled true minifyEnabled true

@ -59,13 +59,10 @@ import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection; import java.net.HttpURLConnection;
import java.net.URL; import java.net.URL;
import eightbitlab.com.blurview.BlurView; import eightbitlab.com.blurview.BlurView;
import io.sentry.Sentry;
public class MainActivity extends FoxActivity implements SwipeRefreshLayout.OnRefreshListener, SearchView.OnQueryTextListener, SearchView.OnCloseListener, OverScrollManager.OverScrollHelper { public class MainActivity extends FoxActivity implements SwipeRefreshLayout.OnRefreshListener, SearchView.OnQueryTextListener, SearchView.OnCloseListener, OverScrollManager.OverScrollHelper {
private static final String TAG = "MainActivity"; private static final String TAG = "MainActivity";
@ -258,8 +255,10 @@ public class MainActivity extends FoxActivity implements SwipeRefreshLayout.OnRe
if (MainApplication.isCrashReportingEnabled()) { if (MainApplication.isCrashReportingEnabled()) {
SharedPreferences preferences = getSharedPreferences("sentry", MODE_PRIVATE); SharedPreferences preferences = getSharedPreferences("sentry", MODE_PRIVATE);
String lastExitReason = preferences.getString("lastExitReason", ""); String lastExitReason = preferences.getString("lastExitReason", "");
if (BuildConfig.DEBUG) Log.d("NoodleDebug", "Last Exit Reason: " + lastExitReason);
if (lastExitReason.equals("crash")) { if (lastExitReason.equals("crash")) {
String lastEventId = preferences.getString("lastEventId", ""); String lastEventId = preferences.getString("lastEventId", "");
if (BuildConfig.DEBUG) Log.d("NoodleDebug", "Last Event ID: " + lastEventId);
if (!lastEventId.equals("")) { if (!lastEventId.equals("")) {
// Three edit texts for the user to enter their email, name and a description of the issue // Three edit texts for the user to enter their email, name and a description of the issue
EditText email = new EditText(this); EditText email = new EditText(this);
@ -299,47 +298,31 @@ public class MainActivity extends FoxActivity implements SwipeRefreshLayout.OnRe
connection.setRequestMethod("POST"); connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "application/json"); connection.setRequestProperty("Content-Type", "application/json");
connection.setRequestProperty("Authorization", "Bearer " + BuildConfig.SENTRY_TOKEN); connection.setRequestProperty("Authorization", "Bearer " + BuildConfig.SENTRY_TOKEN);
connection.setDoOutput(true); // Setups the JSON body
connection.setDoInput(true);
connection.setChunkedStreamingMode(0);
connection.connect();
// Write the JSON data to the output stream
OutputStream outputStream = connection.getOutputStream();
// Name and email are optional, so if they are empty, set them to
// Anonymous and Anonymous respectively
String nameString = name.getText().toString(); String nameString = name.getText().toString();
String emailString = email.getText().toString(); String emailString = email.getText().toString();
if (nameString.equals("")) nameString = "Anonymous"; if (nameString.equals("")) nameString = "Anonymous";
if (emailString.equals("")) emailString = "Anonymous"; if (emailString.equals("")) emailString = "Anonymous";
String finalNameString = nameString; JSONObject body = new JSONObject();
String finalEmailString = emailString; body.put("event_id", lastEventId);
outputStream.write(new JSONObject() {{ body.put("name", nameString);
put("event_id", lastEventId); body.put("email", emailString);
put("name", finalNameString); body.put("comments", description.getText().toString());
put("email", finalEmailString); // Send the request
put("comments", description.getText().toString()); connection.setDoOutput(true);
}}.toString().getBytes()); connection.getOutputStream().write(body.toString().getBytes());
outputStream.flush(); connection.connect();
outputStream.close(); // For debug builds, log the response code and response body
// Read the response if (BuildConfig.DEBUG) {
InputStream inputStream = connection.getInputStream(); Log.d("NoodleDebug", "Response Code: " + connection.getResponseCode());
byte[] buffer = new byte[1024]; }
int length; // Check if the request was successful
StringBuilder stringBuilder = new StringBuilder(); if (connection.getResponseCode() == 200) {
while ((length = inputStream.read(buffer)) != -1) {
stringBuilder.append(new String(buffer, 0, length));
}
inputStream.close();
connection.disconnect();
if (BuildConfig.DEBUG) Log.d("Sentry", stringBuilder.toString());
// Valid responses will be a json object with a key "id"
JSONObject jsonObject = new JSONObject(stringBuilder.toString());
if (jsonObject.has("id")) {
// Show a toast to the user to confirm that the feedback has been sent
runOnUiThread(() -> Toast.makeText(this, R.string.sentry_dialogue_success, Toast.LENGTH_LONG).show()); runOnUiThread(() -> Toast.makeText(this, R.string.sentry_dialogue_success, Toast.LENGTH_LONG).show());
} else { } else {
// Show a toast to the user to confirm that the feedback has not been sent runOnUiThread(() -> Toast.makeText(this,
runOnUiThread(() -> Toast.makeText(this, R.string.sentry_dialogue_failed_toast, Toast.LENGTH_LONG).show()); R.string.sentry_dialogue_failed_toast,
Toast.LENGTH_LONG).show());
} }
} catch (IOException | JSONException ignored) { } catch (IOException | JSONException ignored) {
// Show a toast if the user feedback could not be submitted // Show a toast if the user feedback could not be submitted
@ -348,7 +331,8 @@ public class MainActivity extends FoxActivity implements SwipeRefreshLayout.OnRe
}).start(); }).start();
}).setNegativeButton(R.string.cancel, (dialog, which) -> { }).setNegativeButton(R.string.cancel, (dialog, which) -> {
preferences.edit().remove("lastEventId").apply(); preferences.edit().remove("lastEventId").apply();
Sentry.captureMessage("User has ignored the crash"); preferences.edit().putString("lastExitReason", "").apply();
Log.w(TAG, "User cancelled sentry dialog");
}).show(); }).show();
} }
} }

@ -330,7 +330,7 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity {
} else { } else {
findPreference("pref_crash").setOnPreferenceClickListener(preference -> { findPreference("pref_crash").setOnPreferenceClickListener(preference -> {
// Hard crash the app // Hard crash the app
throw new RuntimeException("This is a test crash"); throw new Error("This is a test crash");
}); });
} }
if (InstallerInitializer.peekMagiskVersion() < Constants.MAGISK_VER_CODE_INSTALL_COMMAND || !MainApplication.isDeveloper()) { if (InstallerInitializer.peekMagiskVersion() < Constants.MAGISK_VER_CODE_INSTALL_COMMAND || !MainApplication.isDeveloper()) {

@ -1,28 +1,18 @@
package com.fox2code.mmm.sentry; package com.fox2code.mmm.sentry;
import static io.sentry.TypeCheckHint.SENTRY_TYPE_CHECK_HINT;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.content.Context; import android.content.Context;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.net.Uri; import android.net.Uri;
import android.util.Log;
import com.fox2code.mmm.BuildConfig;
import com.fox2code.mmm.MainApplication; import com.fox2code.mmm.MainApplication;
import com.fox2code.mmm.androidacy.AndroidacyUtil; import com.fox2code.mmm.androidacy.AndroidacyUtil;
import java.io.IOException;
import java.io.Writer;
import java.util.Objects; import java.util.Objects;
import io.sentry.JsonObjectWriter;
import io.sentry.NoOpLogger;
import io.sentry.Sentry; import io.sentry.Sentry;
import io.sentry.android.core.SentryAndroid; import io.sentry.android.core.SentryAndroid;
import io.sentry.android.fragment.FragmentLifecycleIntegration; import io.sentry.android.fragment.FragmentLifecycleIntegration;
import io.sentry.hints.DiskFlushNotification;
import io.sentry.protocol.SentryId;
public class SentryMain { public class SentryMain {
public static final boolean IS_SENTRY_INSTALLED = true; public static final boolean IS_SENTRY_INSTALLED = true;
@ -34,6 +24,16 @@ public class SentryMain {
*/ */
@SuppressLint({"RestrictedApi", "UnspecifiedImmutableFlag"}) @SuppressLint({"RestrictedApi", "UnspecifiedImmutableFlag"})
public static void initialize(final MainApplication mainApplication) { public static void initialize(final MainApplication mainApplication) {
Thread.setDefaultUncaughtExceptionHandler((thread, throwable) -> {
SharedPreferences.Editor editor = mainApplication.getSharedPreferences(
"sentry", Context.MODE_PRIVATE).edit();
editor.putString("lastExitReason", "crash");
editor.apply();
// If we just let the default uncaught exception handler handle the
// exception, the app will hang and never close.
// So we need to kill the app ourselves.
System.exit(1);
});
SentryAndroid.init(mainApplication, options -> { SentryAndroid.init(mainApplication, options -> {
// If crash reporting is disabled, stop here. // If crash reporting is disabled, stop here.
if (!MainApplication.isCrashReportingEnabled()) { if (!MainApplication.isCrashReportingEnabled()) {
@ -55,54 +55,15 @@ public class SentryMain {
// Add a callback that will be used before the event is sent to Sentry. // Add a callback that will be used before the event is sent to Sentry.
// With this callback, you can modify the event or, when returning null, also discard the event. // With this callback, you can modify the event or, when returning null, also discard the event.
options.setBeforeSend((event, hint) -> { options.setBeforeSend((event, hint) -> {
if (BuildConfig.DEBUG) { // Debug sentry events for debug.
StringBuilder stringBuilder = new StringBuilder("Sentry report debug: ");
try {
event.serialize(new JsonObjectWriter(new Writer() {
@Override
public void write(char[] cbuf) {
stringBuilder.append(cbuf);
}
@Override
public void write(String str) {
stringBuilder.append(str);
}
@Override
public void write(char[] chars, int i, int i1) {
stringBuilder.append(chars, i, i1);
}
@Override
public void write(String str, int off, int len) {
stringBuilder.append(str, off, len);
}
@Override
public void flush() {
}
@Override
public void close() {
}
}, 4), NoOpLogger.getInstance());
} catch (IOException ignored) {
}
Log.i(TAG, stringBuilder.toString());
}
if (MainApplication.isCrashReportingEnabled()) {
// Save lastEventId to private shared preferences // Save lastEventId to private shared preferences
SharedPreferences sharedPreferences = mainApplication.getSharedPreferences("sentry", Context.MODE_PRIVATE); SharedPreferences sharedPreferences = MainApplication.getINSTANCE().getSharedPreferences(
sharedPreferences.edit().putString("lastEventId", "sentry",
Objects.requireNonNull(event.getEventId()).toString()).apply(); Context.MODE_PRIVATE);
String lastEventId = Objects.requireNonNull(event.getEventId()).toString();
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString("lastEventId", lastEventId);
editor.apply();
return event; return event;
} else {
// We need to do this to avoid crash delay on crash when the event is dropped
DiskFlushNotification diskFlushNotification = hint.getAs(SENTRY_TYPE_CHECK_HINT, DiskFlushNotification.class);
if (diskFlushNotification != null) diskFlushNotification.markFlushed();
return null;
}
}); });
// Filter breadrcrumb content from crash report. // Filter breadrcrumb content from crash report.
options.setBeforeBreadcrumb((breadcrumb, hint) -> { options.setBeforeBreadcrumb((breadcrumb, hint) -> {
@ -114,16 +75,6 @@ public class SentryMain {
} }
return breadcrumb; return breadcrumb;
}); });
// On uncaught exception, set the lastEventId in private sentry preferences
Thread.setDefaultUncaughtExceptionHandler((thread, throwable) -> {
SentryId lastEventId = Sentry.captureException(throwable);
SharedPreferences.Editor editor = mainApplication.getSharedPreferences(
"sentry", Context.MODE_PRIVATE).edit();
editor.putString("lastExitReason", "crash");
editor.apply();
// Kill the app
System.exit(2);
});
} }
}); });
} }

Loading…
Cancel
Save