@logbrew/react-native 0.1.23 → 0.1.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/README.md +62 -5
  2. package/android/CMakeLists.txt +7 -0
  3. package/android/build.gradle +12 -0
  4. package/android/src/main/cpp/android_diagnostics.cpp +363 -0
  5. package/android/src/main/java/co/logbrew/reactnative/AndroidDiagnosticsRuntime.java +214 -0
  6. package/android/src/main/java/co/logbrew/reactnative/AndroidNativeDiagnostics.java +363 -0
  7. package/android/src/main/java/co/logbrew/reactnative/AndroidNativeSignalStore.java +233 -0
  8. package/android/src/main/java/co/logbrew/reactnative/AndroidParentDirectorySync.java +12 -12
  9. package/android/src/main/java/co/logbrew/reactnative/EventRecordStore.java +15 -5
  10. package/android/src/main/java/co/logbrew/reactnative/FatalStoreModuleImpl.java +111 -156
  11. package/android/src/newarch/java/co/logbrew/reactnative/FatalStoreModule.java +15 -20
  12. package/android/src/oldarch/java/co/logbrew/reactnative/FatalStoreModule.java +15 -20
  13. package/android-native-diagnostics.d.ts +29 -0
  14. package/android-native-diagnostics.js +176 -0
  15. package/fatal-replay.cjs +35 -3
  16. package/global-errors.d.cts +3 -3
  17. package/global-errors.d.ts +3 -3
  18. package/global-errors.native.js +1 -12
  19. package/index.cjs +1 -1
  20. package/index.native.d.ts +4 -0
  21. package/index.native.js +21 -3
  22. package/ios/AppleDiagnostics/LBRNAppleNativeDiagnostics.swift +1 -1
  23. package/ios/GeneratedAppleDiagnostics/LogBrew/LogBrewLogger.swift +2 -10
  24. package/ios/GeneratedAppleDiagnostics/LogBrew/OperationTrace.swift +56 -0
  25. package/ios/GeneratedAppleDiagnostics/LogBrew/URLSessionTracer.swift +48 -56
  26. package/ios/GeneratedAppleDiagnostics/LogBrew/Validation.swift +6 -0
  27. package/ios/GeneratedAppleDiagnostics/LogBrewCrash/NativeCrashCorrelation.swift +0 -1
  28. package/ios/GeneratedAppleDiagnostics/SOURCE-MANIFEST.json +5 -4
  29. package/ios/LBRNFatalStoreModule.mm +15 -86
  30. package/package.json +17 -5
  31. package/persistent-delivery.native.js +4 -3
  32. package/src/NativeLogBrewFatalStore.ts +5 -4
  33. package/android/src/main/java/co/logbrew/reactnative/FatalRecordStore.java +0 -623
  34. package/ios/LBRNFatalRecordStore.h +0 -25
  35. package/ios/LBRNFatalRecordStore.m +0 -542
@@ -34,11 +34,11 @@ final class EventRecordStore {
34
34
  Pattern.compile("^event-([0-9]{20})\\.record$");
35
35
  private static final Pattern MARKER_PATTERN =
36
36
  Pattern.compile("^accepted-([0-9]{20})\\.marker$");
37
- private static final FatalRecordStore.ParentDirectorySync UNSUPPORTED_PARENT_DIRECTORY_SYNC =
38
- directory -> FatalRecordStore.ParentDirectorySyncResult.UNSUPPORTED;
37
+ private static final ParentDirectorySync UNSUPPORTED_PARENT_DIRECTORY_SYNC =
38
+ directory -> ParentDirectorySyncResult.UNSUPPORTED;
39
39
 
40
40
  private final File directory;
41
- private final FatalRecordStore.ParentDirectorySync parentDirectorySync;
41
+ private final ParentDirectorySync parentDirectorySync;
42
42
  private boolean poisoned;
43
43
 
44
44
  EventRecordStore(File directory) {
@@ -46,7 +46,7 @@ final class EventRecordStore {
46
46
  }
47
47
 
48
48
  EventRecordStore(
49
- File directory, FatalRecordStore.ParentDirectorySync parentDirectorySync) {
49
+ File directory, ParentDirectorySync parentDirectorySync) {
50
50
  this.directory = resolveCanonicalParent(directory);
51
51
  this.parentDirectorySync = parentDirectorySync;
52
52
  }
@@ -332,7 +332,7 @@ final class EventRecordStore {
332
332
  return false;
333
333
  }
334
334
  if (parentDirectorySync.sync(directory)
335
- == FatalRecordStore.ParentDirectorySyncResult.FAILED) {
335
+ == ParentDirectorySyncResult.FAILED) {
336
336
  poisoned = true;
337
337
  return false;
338
338
  }
@@ -555,6 +555,16 @@ final class EventRecordStore {
555
555
  && value.setWritable(true, true);
556
556
  }
557
557
 
558
+ interface ParentDirectorySync {
559
+ ParentDirectorySyncResult sync(File directory);
560
+ }
561
+
562
+ enum ParentDirectorySyncResult {
563
+ SYNCHRONIZED,
564
+ UNSUPPORTED,
565
+ FAILED
566
+ }
567
+
558
568
  static final class Record {
559
569
  final long sequence;
560
570
  final String serializedEvent;
@@ -2,7 +2,6 @@ package co.logbrew.reactnative;
2
2
 
3
3
  import com.facebook.react.bridge.Arguments;
4
4
  import com.facebook.react.bridge.ReactApplicationContext;
5
- import com.facebook.react.bridge.ReadableArray;
6
5
  import com.facebook.react.bridge.ReadableMap;
7
6
  import com.facebook.react.bridge.ReadableMapKeySetIterator;
8
7
  import com.facebook.react.bridge.ReadableType;
@@ -13,11 +12,9 @@ import java.nio.charset.StandardCharsets;
13
12
  import java.security.MessageDigest;
14
13
  import java.security.NoSuchAlgorithmException;
15
14
  import java.security.SecureRandom;
16
- import java.util.ArrayList;
17
15
  import java.util.Arrays;
18
16
  import java.util.HashMap;
19
17
  import java.util.HashSet;
20
- import java.util.List;
21
18
  import java.util.Map;
22
19
  import java.util.Set;
23
20
 
@@ -25,32 +22,26 @@ final class FatalStoreModuleImpl {
25
22
  static final String NAME = "LogBrewFatalStore";
26
23
  private static final SecureRandom SECURE_RANDOM = new SecureRandom();
27
24
 
28
- private static final Set<String> RECORD_KEYS =
25
+ private static final Set<String> ANDROID_DIAGNOSTICS_KEYS =
29
26
  new HashSet<>(
30
27
  Arrays.asList(
31
- "schemaVersion",
32
- "id",
33
- "timestamp",
34
- "errorName",
35
- "stackFrames",
36
- "droppedRecords",
37
- "corruptRecords"));
38
- private static final Set<String> FRAME_KEYS =
39
- new HashSet<>(Arrays.asList("filename", "line", "column"));
28
+ "anrThresholdMs",
29
+ "clientKey",
30
+ "environment",
31
+ "fatalHandlerOwnership",
32
+ "projectId",
33
+ "release",
34
+ "service"));
40
35
 
41
- private final FatalRecordStore store;
42
36
  private final File eventStoreParent;
37
+ private final ReactApplicationContext context;
43
38
  private final Map<String, EventRecordStore> eventStores = new HashMap<>();
39
+ private AndroidDiagnosticsRuntime androidDiagnostics;
44
40
 
45
41
  FatalStoreModuleImpl(ReactApplicationContext context) {
42
+ this.context = context;
46
43
  File root = context.getNoBackupFilesDir();
47
44
  eventStoreParent = root;
48
- store =
49
- root == null
50
- ? null
51
- : new FatalRecordStore(
52
- new File(root, "logbrew-fatal-js"),
53
- new AndroidParentDirectorySync());
54
45
  }
55
46
 
56
47
  String secureRandomHex(double length) {
@@ -122,127 +113,111 @@ final class FatalStoreModuleImpl {
122
113
  return eventResultMap(eventStore.close());
123
114
  } catch (RuntimeException error) {
124
115
  return status("storage_error");
125
- } finally {
126
- eventStores.remove(queueHash);
127
116
  }
128
117
  }
129
118
 
130
- WritableMap writeFatalRecord(ReadableMap input) {
131
- if (store == null) {
132
- return status("storage_error");
119
+ synchronized WritableMap installAndroidDiagnostics(ReadableMap input) {
120
+ AndroidDiagnosticsInput configuration = readAndroidDiagnosticsInput(input);
121
+ EventRecordStore eventStore =
122
+ configuration == null ? null : eventStore(configuration.clientKey);
123
+ String queueHash =
124
+ configuration == null ? null : queueHash(configuration.clientKey);
125
+ if (eventStore == null || queueHash == null || eventStoreParent == null) {
126
+ return error("android_diagnostics_invalid_configuration");
127
+ }
128
+ if (androidDiagnostics != null && androidDiagnostics.installed()) {
129
+ return androidDiagnostics.matches(eventStore, configuration.configuration)
130
+ ? androidDiagnosticsReceipt("already_installed", androidDiagnostics.pending())
131
+ : error("android_diagnostics_owned");
132
+ }
133
+ File storageRoot = new File(eventStoreParent, "logbrew-android-diagnostics-v1-" + queueHash);
134
+ if ((!storageRoot.isDirectory() && !storageRoot.mkdirs()) || !storageRoot.isDirectory()) {
135
+ return error("android_diagnostics_storage_failed");
133
136
  }
134
137
  try {
135
- FatalRecordStore.Record record = readRecord(input);
136
- return record == null ? status("invalid_record") : resultMap(store.write(record));
138
+ androidDiagnostics =
139
+ new AndroidDiagnosticsRuntime(
140
+ context, storageRoot, eventStore, configuration.configuration);
141
+ String statusValue = androidDiagnostics.install();
142
+ return androidDiagnosticsResult(statusValue);
137
143
  } catch (RuntimeException error) {
138
- return status("storage_error");
144
+ androidDiagnostics = null;
145
+ return error("android_diagnostics_install_failed");
139
146
  }
140
147
  }
141
148
 
142
- WritableMap readFatalRecord() {
143
- if (store == null) {
144
- return status("storage_error");
145
- }
146
- try {
147
- return resultMap(store.read());
148
- } catch (RuntimeException error) {
149
- return status("storage_error");
149
+ synchronized WritableMap androidDiagnosticsStatus() {
150
+ if (androidDiagnostics == null || !androidDiagnostics.installed()) {
151
+ return androidDiagnosticsReceipt("not_installed", 0);
150
152
  }
153
+ return androidDiagnosticsResult("ready");
151
154
  }
152
155
 
153
- WritableMap acknowledgeFatalRecord(String recordId) {
154
- if (store == null) {
155
- return status("storage_error");
156
+ synchronized WritableMap uninstallAndroidDiagnostics() {
157
+ if (androidDiagnostics == null) {
158
+ return androidDiagnosticsReceipt("not_installed", 0);
156
159
  }
157
160
  try {
158
- return resultMap(store.acknowledge(recordId));
161
+ String statusValue = androidDiagnostics.uninstall();
162
+ WritableMap result = androidDiagnosticsResult(statusValue);
163
+ androidDiagnostics = null;
164
+ return result;
159
165
  } catch (RuntimeException error) {
160
- return status("storage_error");
166
+ return error("android_diagnostics_uninstall_failed");
161
167
  }
162
168
  }
163
169
 
164
- WritableMap discardFatalRecord() {
165
- if (store == null) {
166
- return status("storage_error");
167
- }
168
- try {
169
- return resultMap(store.discard());
170
- } catch (RuntimeException error) {
171
- return status("storage_error");
172
- }
173
- }
174
-
175
- private static FatalRecordStore.Record readRecord(ReadableMap input) {
170
+ private static AndroidDiagnosticsInput readAndroidDiagnosticsInput(ReadableMap input) {
176
171
  if (input == null
177
- || !hasExactKeys(input, RECORD_KEYS)
178
- || !hasType(input, "schemaVersion", ReadableType.Number)
179
- || !hasType(input, "id", ReadableType.String)
180
- || !hasType(input, "timestamp", ReadableType.String)
181
- || !hasType(input, "errorName", ReadableType.String)
182
- || !hasType(input, "stackFrames", ReadableType.Array)
183
- || !hasType(input, "droppedRecords", ReadableType.Number)
184
- || !hasType(input, "corruptRecords", ReadableType.Number)) {
185
- return null;
186
- }
187
- Integer schemaVersion = integer(input, "schemaVersion");
188
- Integer droppedRecords = integer(input, "droppedRecords");
189
- Integer corruptRecords = integer(input, "corruptRecords");
190
- if (schemaVersion == null || droppedRecords == null || corruptRecords == null) {
191
- return null;
192
- }
193
-
194
- ReadableArray values = input.getArray("stackFrames");
195
- if (values == null) {
172
+ || !hasExactKeys(input, ANDROID_DIAGNOSTICS_KEYS)
173
+ || !hasType(input, "anrThresholdMs", ReadableType.Number)
174
+ || !hasType(input, "clientKey", ReadableType.String)
175
+ || !hasType(input, "environment", ReadableType.String)
176
+ || !hasType(input, "fatalHandlerOwnership", ReadableType.String)
177
+ || !hasType(input, "projectId", ReadableType.String)
178
+ || !hasType(input, "release", ReadableType.String)
179
+ || !hasType(input, "service", ReadableType.String)
180
+ || !"logbrew".equals(input.getString("fatalHandlerOwnership"))) {
196
181
  return null;
197
182
  }
198
- List<FatalRecordStore.Frame> frames = new ArrayList<>(values.size());
199
- for (int index = 0; index < values.size(); index += 1) {
200
- if (values.getType(index) != ReadableType.Map) {
201
- return null;
202
- }
203
- ReadableMap value = values.getMap(index);
204
- FatalRecordStore.Frame frame = readFrame(value);
205
- if (frame == null) {
206
- return null;
207
- }
208
- frames.add(frame);
209
- }
210
- return new FatalRecordStore.Record(
211
- schemaVersion,
212
- input.getString("id"),
213
- input.getString("timestamp"),
214
- input.getString("errorName"),
215
- frames,
216
- droppedRecords,
217
- corruptRecords);
218
- }
219
-
220
- private static FatalRecordStore.Frame readFrame(ReadableMap input) {
221
- if (input == null
222
- || !hasExactKeys(input, FRAME_KEYS)
223
- || !hasType(input, "filename", ReadableType.String)
224
- || !hasType(input, "line", ReadableType.Number)
225
- || !hasType(input, "column", ReadableType.Number)) {
183
+ Integer threshold = integer(input, "anrThresholdMs");
184
+ String clientKey = input.getString("clientKey");
185
+ if (threshold == null || clientKey == null || clientKey.trim().isEmpty()) {
226
186
  return null;
227
187
  }
228
- Integer line = integer(input, "line");
229
- Integer column = integer(input, "column");
230
- String filename = input.getString("filename");
231
- if (line == null || column == null || filename == null) {
188
+ try {
189
+ return new AndroidDiagnosticsInput(
190
+ clientKey,
191
+ new AndroidNativeDiagnostics.Configuration(
192
+ input.getString("projectId"),
193
+ input.getString("release"),
194
+ input.getString("environment"),
195
+ input.getString("service"),
196
+ android.os.Build.VERSION.RELEASE,
197
+ android.os.Build.MODEL,
198
+ androidArchitecture(),
199
+ threshold));
200
+ } catch (IllegalArgumentException error) {
232
201
  return null;
233
202
  }
234
- if (filename.startsWith("/")
235
- && filename.indexOf('/', 1) < 0
236
- && filename.length() > 1) {
237
- filename = filename.substring(1);
238
- }
239
- return new FatalRecordStore.Frame(filename, line, column);
240
203
  }
241
204
 
242
205
  private static boolean hasType(ReadableMap map, String key, ReadableType type) {
243
206
  return map.hasKey(key) && !map.isNull(key) && map.getType(key) == type;
244
207
  }
245
208
 
209
+ private static String androidArchitecture() {
210
+ String[] values = android.os.Process.is64Bit()
211
+ ? android.os.Build.SUPPORTED_64_BIT_ABIS
212
+ : android.os.Build.SUPPORTED_32_BIT_ABIS;
213
+ String value = values.length == 0
214
+ ? ""
215
+ : values[0];
216
+ return "arm64-v8a".equals(value)
217
+ ? "arm64"
218
+ : "armeabi-v7a".equals(value) ? "arm" : value;
219
+ }
220
+
246
221
  private static boolean hasExactKeys(ReadableMap map, Set<String> expected) {
247
222
  Set<String> observed = new HashSet<>();
248
223
  ReadableMapKeySetIterator iterator = map.keySetIterator();
@@ -253,62 +228,31 @@ final class FatalStoreModuleImpl {
253
228
  }
254
229
 
255
230
  private static Integer integer(ReadableMap map, String key) {
256
- double value = map.getDouble(key);
257
- return Double.isFinite(value)
258
- && value >= 0
259
- && value <= Integer.MAX_VALUE
260
- && value == Math.rint(value)
261
- ? (int) value
262
- : null;
231
+ return integer(map.getDouble(key));
263
232
  }
264
233
 
265
- private static WritableMap resultMap(FatalRecordStore.Result result) {
266
- if (result == null || result.status == null) {
267
- return status("storage_error");
268
- }
269
- WritableMap output = status(result.status);
270
- if (result.recordId != null) {
271
- output.putString("recordId", result.recordId);
272
- }
273
- if (result.droppedRecords > 0) {
274
- output.putInt("droppedRecords", result.droppedRecords);
275
- }
276
- if (result.corruptRecords > 0) {
277
- output.putInt("corruptRecords", result.corruptRecords);
278
- }
279
- if (result.record != null) {
280
- output.putMap("record", recordMap(result.record));
281
- }
234
+ private static WritableMap status(String value) {
235
+ WritableMap output = Arguments.createMap();
236
+ output.putString("status", value);
282
237
  return output;
283
238
  }
284
239
 
285
- private static WritableMap recordMap(FatalRecordStore.Record record) {
286
- WritableMap output = Arguments.createMap();
287
- output.putInt("schemaVersion", record.schemaVersion);
288
- output.putString("id", record.id);
289
- output.putString("timestamp", record.timestamp);
290
- output.putString("errorName", record.errorName);
291
- output.putArray("stackFrames", frameMaps(record.stackFrames));
292
- output.putInt("droppedRecords", record.droppedRecords);
293
- output.putInt("corruptRecords", record.corruptRecords);
240
+ private static WritableMap androidDiagnosticsReceipt(String value, int pending) {
241
+ WritableMap output = status(value);
242
+ output.putInt("pending", pending);
294
243
  return output;
295
244
  }
296
245
 
297
- private static WritableArray frameMaps(List<FatalRecordStore.Frame> frames) {
298
- WritableArray output = Arguments.createArray();
299
- for (FatalRecordStore.Frame frame : frames) {
300
- WritableMap value = Arguments.createMap();
301
- value.putString("filename", frame.filename);
302
- value.putInt("line", frame.line);
303
- value.putInt("column", frame.column);
304
- output.pushMap(value);
305
- }
306
- return output;
246
+ private WritableMap androidDiagnosticsResult(String status) {
247
+ int pending = androidDiagnostics.pending();
248
+ return pending < 0
249
+ ? error("android_diagnostics_storage_failed")
250
+ : androidDiagnosticsReceipt(status, pending);
307
251
  }
308
252
 
309
- private static WritableMap status(String value) {
310
- WritableMap output = Arguments.createMap();
311
- output.putString("status", value);
253
+ private static WritableMap error(String code) {
254
+ WritableMap output = status("error");
255
+ output.putString("code", code);
312
256
  return output;
313
257
  }
314
258
 
@@ -372,4 +316,15 @@ final class FatalStoreModuleImpl {
372
316
  }
373
317
  return output;
374
318
  }
319
+
320
+ private static final class AndroidDiagnosticsInput {
321
+ final String clientKey;
322
+ final AndroidNativeDiagnostics.Configuration configuration;
323
+
324
+ AndroidDiagnosticsInput(
325
+ String clientKey, AndroidNativeDiagnostics.Configuration configuration) {
326
+ this.clientKey = clientKey;
327
+ this.configuration = configuration;
328
+ }
329
+ }
375
330
  }
@@ -22,26 +22,6 @@ final class FatalStoreModule extends NativeLogBrewFatalStoreSpec {
22
22
  return implementation.secureRandomHex(length);
23
23
  }
24
24
 
25
- @Override
26
- public WritableMap writeFatalRecord(ReadableMap record) {
27
- return implementation.writeFatalRecord(record);
28
- }
29
-
30
- @Override
31
- public WritableMap readFatalRecord() {
32
- return implementation.readFatalRecord();
33
- }
34
-
35
- @Override
36
- public WritableMap acknowledgeFatalRecord(String recordId) {
37
- return implementation.acknowledgeFatalRecord(recordId);
38
- }
39
-
40
- @Override
41
- public WritableMap discardFatalRecord() {
42
- return implementation.discardFatalRecord();
43
- }
44
-
45
25
  @Override
46
26
  public WritableMap loadEventRecords(String queueKey) {
47
27
  return implementation.loadEventRecords(queueKey);
@@ -67,4 +47,19 @@ final class FatalStoreModule extends NativeLogBrewFatalStoreSpec {
67
47
  public WritableMap closeEventStore(String queueKey) {
68
48
  return implementation.closeEventStore(queueKey);
69
49
  }
50
+
51
+ @Override
52
+ public WritableMap installAndroidDiagnostics(ReadableMap configuration) {
53
+ return implementation.installAndroidDiagnostics(configuration);
54
+ }
55
+
56
+ @Override
57
+ public WritableMap androidDiagnosticsStatus() {
58
+ return implementation.androidDiagnosticsStatus();
59
+ }
60
+
61
+ @Override
62
+ public WritableMap uninstallAndroidDiagnostics() {
63
+ return implementation.uninstallAndroidDiagnostics();
64
+ }
70
65
  }
@@ -24,26 +24,6 @@ final class FatalStoreModule extends ReactContextBaseJavaModule {
24
24
  return implementation.secureRandomHex(length);
25
25
  }
26
26
 
27
- @ReactMethod(isBlockingSynchronousMethod = true)
28
- public WritableMap writeFatalRecord(ReadableMap record) {
29
- return implementation.writeFatalRecord(record);
30
- }
31
-
32
- @ReactMethod(isBlockingSynchronousMethod = true)
33
- public WritableMap readFatalRecord() {
34
- return implementation.readFatalRecord();
35
- }
36
-
37
- @ReactMethod(isBlockingSynchronousMethod = true)
38
- public WritableMap acknowledgeFatalRecord(String recordId) {
39
- return implementation.acknowledgeFatalRecord(recordId);
40
- }
41
-
42
- @ReactMethod(isBlockingSynchronousMethod = true)
43
- public WritableMap discardFatalRecord() {
44
- return implementation.discardFatalRecord();
45
- }
46
-
47
27
  @ReactMethod(isBlockingSynchronousMethod = true)
48
28
  public WritableMap loadEventRecords(String queueKey) {
49
29
  return implementation.loadEventRecords(queueKey);
@@ -69,4 +49,19 @@ final class FatalStoreModule extends ReactContextBaseJavaModule {
69
49
  public WritableMap closeEventStore(String queueKey) {
70
50
  return implementation.closeEventStore(queueKey);
71
51
  }
52
+
53
+ @ReactMethod(isBlockingSynchronousMethod = true)
54
+ public WritableMap installAndroidDiagnostics(ReadableMap configuration) {
55
+ return implementation.installAndroidDiagnostics(configuration);
56
+ }
57
+
58
+ @ReactMethod(isBlockingSynchronousMethod = true)
59
+ public WritableMap androidDiagnosticsStatus() {
60
+ return implementation.androidDiagnosticsStatus();
61
+ }
62
+
63
+ @ReactMethod(isBlockingSynchronousMethod = true)
64
+ public WritableMap uninstallAndroidDiagnostics() {
65
+ return implementation.uninstallAndroidDiagnostics();
66
+ }
72
67
  }
@@ -0,0 +1,29 @@
1
+ export type LogBrewAndroidNativeDiagnosticsConfiguration = Readonly<{
2
+ anrThresholdMs?: number;
3
+ clientKey: string;
4
+ environment: string;
5
+ fatalHandlerOwnership: "logbrew";
6
+ projectId: string;
7
+ release: string;
8
+ service: string;
9
+ }>;
10
+
11
+ export type LogBrewAndroidNativeDiagnosticsReceipt = Readonly<{
12
+ pending: number;
13
+ status:
14
+ | "already_installed"
15
+ | "installed"
16
+ | "not_installed"
17
+ | "ready"
18
+ | "uninstalled";
19
+ }>;
20
+
21
+ export declare function installLogBrewAndroidNativeDiagnostics(
22
+ configuration: LogBrewAndroidNativeDiagnosticsConfiguration
23
+ ): LogBrewAndroidNativeDiagnosticsReceipt;
24
+
25
+ export declare function getLogBrewAndroidNativeDiagnosticsStatus():
26
+ LogBrewAndroidNativeDiagnosticsReceipt;
27
+
28
+ export declare function uninstallLogBrewAndroidNativeDiagnostics():
29
+ LogBrewAndroidNativeDiagnosticsReceipt;