-
Notifications
You must be signed in to change notification settings - Fork 14
Expand file tree
/
Copy pathMainActivity.java
More file actions
243 lines (193 loc) · 8.7 KB
/
MainActivity.java
File metadata and controls
243 lines (193 loc) · 8.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
package backtraceio.backtraceio;
import static backtraceio.backtraceio.BuildConfig.BACKTRACE_SUBMISSION_URL;
import android.content.Context;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import android.system.ErrnoException;
import android.system.Os;
import android.util.Log;
import android.view.View;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import backtraceio.library.BacktraceClient;
import backtraceio.library.BacktraceCredentials;
import backtraceio.library.BacktraceDatabase;
import backtraceio.library.base.BacktraceBase;
import backtraceio.library.enums.BacktraceBreadcrumbType;
import backtraceio.library.enums.database.RetryBehavior;
import backtraceio.library.enums.database.RetryOrder;
import backtraceio.library.models.BacktraceData;
import backtraceio.library.models.BacktraceExceptionHandler;
import backtraceio.library.models.BacktraceMetricsSettings;
import backtraceio.library.models.database.BacktraceDatabaseSettings;
import backtraceio.library.models.json.BacktraceReport;
public class MainActivity extends AppCompatActivity {
private BacktraceClient backtraceClient;
private final int anrTimeout = 3000;
// Used to load the 'native-lib' library on application startup.
static {
System.loadLibrary("native-lib");
System.loadLibrary("backtrace-native");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Crash Loop Detector example
BacktraceClient.EnableCrashLoopDetection();
boolean isCLSafeModeReq = BacktraceClient.IsSafeModeRequired();
int crashesCount = BacktraceClient.ConsecutiveCrashesCount();
Log.i("BacktraceAndroid", String.format("ConsecutiveCrashesCount: %d", crashesCount));
// Set this value in your local.properties
if (BuildConfig.BACKTRACE_SUBMISSION_URL != null) {
backtraceClient = initializeBacktrace(BuildConfig.BACKTRACE_SUBMISSION_URL);
}
View viewBackground = findViewById(R.id.viewBackground);
if (viewBackground != null) {
viewBackground.setBackgroundColor(isCLSafeModeReq
? getResources().getColor(R.color.colorAccent)
: getResources().getColor(R.color.colorWhite));
}
symlinkAndWriteFile();
}
/**
* Example of how one would link a static filename to a more dynamic one, since you can only specify
* the attachment to upload for a native crash once at startup
*/
private void symlinkAndWriteFile() {
Context context = getApplicationContext();
final String fileName = context.getFilesDir() + "/" + "myCustomFile.txt";
final String fileNameDateString = context.getFilesDir() + "/" + "myCustomFile06_11_2021.txt";
try {
Os.symlink(fileNameDateString, fileName);
} catch (ErrnoException e) {
e.printStackTrace();
}
writeMyCustomFile(fileNameDateString);
}
private BacktraceClient initializeBacktrace(final String submissionUrl) {
BacktraceCredentials credentials = new BacktraceCredentials(submissionUrl);
Context context = getApplicationContext();
String dbPath = context.getFilesDir().getAbsolutePath();
BacktraceDatabaseSettings settings = new BacktraceDatabaseSettings(dbPath);
settings.setMaxRecordCount(100);
settings.setMaxDatabaseSize(1000);
settings.setRetryBehavior(RetryBehavior.ByInterval);
settings.setAutoSendMode(true);
settings.setRetryOrder(RetryOrder.Queue);
Map<String, Object> attributes = new HashMap<String, Object>() {{
put("custom.attribute", "My Custom Attribute");
}};
List<String> attachments = new ArrayList<String>() {{
add(context.getFilesDir() + "/" + "myCustomFile.txt");
}};
BacktraceDatabase database = new BacktraceDatabase(context, settings);
BacktraceClient backtraceClient = new BacktraceClient(context, credentials, database, attributes, attachments);
BacktraceExceptionHandler.enable(backtraceClient);
// backtraceClient.send("test");
// Enable handling of native crashes
database.setupNativeIntegration(backtraceClient, credentials, true);
final String baseUrl = submissionUrl.contains("backtrace.sp") ? "https://events-test.backtrace.io" : "https://events.backtrace.io";
backtraceClient.metrics.enable(new BacktraceMetricsSettings(credentials, baseUrl));
// Enable ANR detection
backtraceClient.enableAnr(anrTimeout);
return backtraceClient;
}
public native void cppCrash();
public native boolean registerNativeBreadcrumbs(BacktraceBase backtraceBase);
public native boolean addNativeBreadcrumb();
public native boolean addNativeBreadcrumbUserError();
public native void cleanupNativeBreadcrumbHandler();
private List<String> equippedItems;
public List<String> getWarriorArmor() {
return new ArrayList<String>(Arrays.asList("Tough Boots", "Strong Sword", "Sturdy Shield", "Magic Wand"));
}
int findEquipmentIndex(List<String> armor, String equipment) {
return armor.indexOf(equipment);
}
void removeEquipment(List<String> armor, int index) {
armor.remove(index);
}
void equipItem(List<String> armor, int index) {
equippedItems.add(armor.get(index));
}
public void handledException(View view) {
try {
List<String> myWarriorArmor = getWarriorArmor();
int magicWandIndex = findEquipmentIndex(myWarriorArmor, "Magic Wand");
// I don't need a Magic Wand, I am a warrior
removeEquipment(myWarriorArmor, magicWandIndex);
// Where was that magic wand again?
equipItem(myWarriorArmor, magicWandIndex);
} catch (Exception e) {
backtraceClient.send(new BacktraceReport(e));
}
}
public void getSaveData() throws IOException {
// I know for sure this file is there (spoiler alert, it's not)
File mySaveData = new File("mySave.sav");
FileReader mySaveDataReader = new FileReader(mySaveData);
char[] saveDataBuffer = new char[255];
mySaveDataReader.read(saveDataBuffer);
}
public void unhandledException(View view) throws IOException {
getSaveData();
}
public void nativeCrash(View view) {
cppCrash();
}
public void anr(View view) throws InterruptedException {
Thread.sleep(anrTimeout + 2000);
}
public void enableBreadcrumbs(View view) {
backtraceClient.enableBreadcrumbs(view.getContext().getApplicationContext());
registerNativeBreadcrumbs(backtraceClient); // Order should not matter
}
public void enableBreadcrumbsUserOnly(View view) {
EnumSet<BacktraceBreadcrumbType> breadcrumbTypesToEnable = EnumSet.of(BacktraceBreadcrumbType.USER);
backtraceClient.enableBreadcrumbs(view.getContext().getApplicationContext(), breadcrumbTypesToEnable);
registerNativeBreadcrumbs(backtraceClient); // Order should not matter
}
public void sendReport(View view) {
final long id = Thread.currentThread().getId();
Map<String, Object> attributes = new HashMap<String, Object>() {{
put("Caller thread", id);
}};
backtraceClient.addBreadcrumb("About to send Backtrace report", attributes, BacktraceBreadcrumbType.LOG);
addNativeBreadcrumb();
addNativeBreadcrumbUserError();
BacktraceReport report = new BacktraceReport("Test");
backtraceClient.send(report);
}
private void writeMyCustomFile(String filePath) {
String fileData = "My custom data\nMore of my data\nEnd of my data";
try {
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(new FileOutputStream(filePath));
outputStreamWriter.write(fileData);
outputStreamWriter.close();
} catch (IOException e) {
Log.e("BacktraceAndroid", "File write failed due to: " + e.toString());
}
}
public void exit(View view) {
System.exit(0);
}
public void dumpWithoutCrash(View view) {
backtraceClient.dumpWithoutCrash("DumpWithoutCrash");
}
public void disableNativeIntegration(View view) {
backtraceClient.disableNativeIntegration();
}
public void enableNativeIntegration(View view) {
backtraceClient.enableNativeIntegration();
}
}