@logbrew/react-native 0.1.4 → 0.1.5

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.
@@ -0,0 +1,61 @@
1
+ package co.logbrew.reactnative;
2
+
3
+ import android.system.ErrnoException;
4
+ import android.system.Os;
5
+ import android.system.OsConstants;
6
+ import java.io.File;
7
+ import java.io.FileDescriptor;
8
+
9
+ final class AndroidParentDirectorySync implements FatalRecordStore.ParentDirectorySync {
10
+ @Override
11
+ public FatalRecordStore.ParentDirectorySyncResult sync(File directory) {
12
+ FileDescriptor descriptor;
13
+ try {
14
+ descriptor =
15
+ Os.open(
16
+ directory.getAbsolutePath(),
17
+ OsConstants.O_RDONLY | OsConstants.O_CLOEXEC | OsConstants.O_NOFOLLOW,
18
+ 0);
19
+ } catch (ErrnoException | RuntimeException error) {
20
+ return FatalRecordStore.ParentDirectorySyncResult.FAILED;
21
+ }
22
+
23
+ FatalRecordStore.ParentDirectorySyncResult result;
24
+ try {
25
+ if (!OsConstants.S_ISDIR(Os.fstat(descriptor).st_mode)) {
26
+ result = FatalRecordStore.ParentDirectorySyncResult.FAILED;
27
+ } else {
28
+ result = syncDescriptor(descriptor);
29
+ }
30
+ } catch (ErrnoException | RuntimeException error) {
31
+ result = FatalRecordStore.ParentDirectorySyncResult.FAILED;
32
+ }
33
+
34
+ try {
35
+ Os.close(descriptor);
36
+ } catch (ErrnoException | RuntimeException error) {
37
+ return FatalRecordStore.ParentDirectorySyncResult.FAILED;
38
+ }
39
+ return result;
40
+ }
41
+
42
+ private static FatalRecordStore.ParentDirectorySyncResult syncDescriptor(
43
+ FileDescriptor descriptor) {
44
+ try {
45
+ Os.fsync(descriptor);
46
+ return FatalRecordStore.ParentDirectorySyncResult.SYNCHRONIZED;
47
+ } catch (ErrnoException error) {
48
+ return unsupportedDirectorySync(error.errno)
49
+ ? FatalRecordStore.ParentDirectorySyncResult.UNSUPPORTED
50
+ : FatalRecordStore.ParentDirectorySyncResult.FAILED;
51
+ } catch (RuntimeException error) {
52
+ return FatalRecordStore.ParentDirectorySyncResult.FAILED;
53
+ }
54
+ }
55
+
56
+ private static boolean unsupportedDirectorySync(int errno) {
57
+ return errno == OsConstants.EINVAL
58
+ || errno == OsConstants.ENOTSUP
59
+ || errno == OsConstants.EOPNOTSUPP;
60
+ }
61
+ }
@@ -6,12 +6,9 @@ import java.io.DataInputStream;
6
6
  import java.io.DataOutputStream;
7
7
  import java.io.EOFException;
8
8
  import java.io.File;
9
- import java.io.FileDescriptor;
10
9
  import java.io.FileInputStream;
11
10
  import java.io.FileOutputStream;
12
11
  import java.io.IOException;
13
- import java.lang.reflect.Field;
14
- import java.lang.reflect.Method;
15
12
  import java.nio.charset.StandardCharsets;
16
13
  import java.util.ArrayList;
17
14
  import java.util.Arrays;
@@ -49,15 +46,23 @@ final class FatalRecordStore {
49
46
  "SyntaxError",
50
47
  "TypeError",
51
48
  "URIError")));
49
+ private static final ParentDirectorySync UNSUPPORTED_PARENT_DIRECTORY_SYNC =
50
+ directory -> ParentDirectorySyncResult.UNSUPPORTED;
52
51
 
53
52
  private final File directory;
54
53
  private final File recordFile;
55
54
  private final File temporaryFile;
55
+ private final ParentDirectorySync parentDirectorySync;
56
56
 
57
57
  FatalRecordStore(File directory) {
58
+ this(directory, UNSUPPORTED_PARENT_DIRECTORY_SYNC);
59
+ }
60
+
61
+ FatalRecordStore(File directory, ParentDirectorySync parentDirectorySync) {
58
62
  this.directory = resolveCanonicalParent(directory);
59
63
  this.recordFile = new File(this.directory, RECORD_FILE_NAME);
60
64
  this.temporaryFile = new File(this.directory, TEMP_FILE_NAME);
65
+ this.parentDirectorySync = parentDirectorySync;
61
66
  }
62
67
 
63
68
  synchronized Result write(Record incoming) {
@@ -525,35 +530,17 @@ final class FatalRecordStore {
525
530
  }
526
531
 
527
532
  private boolean syncParentDirectory() {
528
- try {
529
- Class<?> constants = Class.forName("android.system.OsConstants");
530
- int flags =
531
- intField(constants, "O_RDONLY")
532
- | intField(constants, "O_DIRECTORY")
533
- | intField(constants, "O_CLOEXEC");
534
- Class<?> os = Class.forName("android.system.Os");
535
- Method open = os.getMethod("open", String.class, int.class, int.class);
536
- Method fsync = os.getMethod("fsync", FileDescriptor.class);
537
- Method close = os.getMethod("close", FileDescriptor.class);
538
- FileDescriptor descriptor =
539
- (FileDescriptor) open.invoke(null, directory.getAbsolutePath(), flags, 0);
540
- try {
541
- fsync.invoke(null, descriptor);
542
- } finally {
543
- close.invoke(null, descriptor);
544
- }
545
- return true;
546
- } catch (ClassNotFoundException unavailableOutsideAndroid) {
547
- return true;
548
- } catch (ReflectiveOperationException | RuntimeException error) {
549
- return false;
550
- }
533
+ return parentDirectorySync.sync(directory) != ParentDirectorySyncResult.FAILED;
534
+ }
535
+
536
+ interface ParentDirectorySync {
537
+ ParentDirectorySyncResult sync(File directory);
551
538
  }
552
539
 
553
- private static int intField(Class<?> owner, String name)
554
- throws ReflectiveOperationException {
555
- Field field = owner.getField(name);
556
- return field.getInt(null);
540
+ enum ParentDirectorySyncResult {
541
+ SYNCHRONIZED,
542
+ UNSUPPORTED,
543
+ FAILED
557
544
  }
558
545
 
559
546
  static final class Frame {
@@ -35,7 +35,12 @@ final class FatalStoreModuleImpl {
35
35
 
36
36
  FatalStoreModuleImpl(ReactApplicationContext context) {
37
37
  File root = context.getNoBackupFilesDir();
38
- store = root == null ? null : new FatalRecordStore(new File(root, "logbrew-fatal-js"));
38
+ store =
39
+ root == null
40
+ ? null
41
+ : new FatalRecordStore(
42
+ new File(root, "logbrew-fatal-js"),
43
+ new AndroidParentDirectorySync());
39
44
  }
40
45
 
41
46
  WritableMap writeFatalRecord(ReadableMap input) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@logbrew/react-native",
3
- "version": "0.1.4",
3
+ "version": "0.1.5",
4
4
  "description": "React Native screen, error, trace, action, and network timeline helpers for LogBrew.",
5
5
  "type": "module",
6
6
  "main": "./index.cjs",