Skip to content

Commit a87e484

Browse files
bruno-garciamarandanetoSwatinem
authored
sync Java to C (#937)
* sync Java to C * Update sentry-android-ndk/src/main/java/io/sentry/android/ndk/NdkScopeObserver.java Co-authored-by: Manoel Aranda Neto <5731772+marandaneto@users.noreply.github.com> * Update sentry-android-ndk/src/main/jni/sentry.c * Update sentry-android-ndk/src/main/jni/sentry.c Co-authored-by: Arpad Borsos <arpad.borsos@sentry.io> * spotless * draft * draft crumbs data * refactor * Update sentry-android-ndk/src/main/java/io/sentry/android/ndk/NdkScopeObserver.java * add options for scope sync and sync breadcrumb data * java docs * Apply suggestions from code review * add tests * add tests Co-authored-by: Manoel Aranda Neto <5731772+marandaneto@users.noreply.github.com> Co-authored-by: Arpad Borsos <arpad.borsos@sentry.io> Co-authored-by: Manoel Aranda Neto <marandaneto@gmail.com>
1 parent 77ee2aa commit a87e484

22 files changed

Lines changed: 792 additions & 24 deletions

File tree

sentry-android-core/src/main/java/io/sentry/android/core/ManifestMetadataReader.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ final class ManifestMetadataReader {
2828

2929
static final String AUTO_INIT = "io.sentry.auto-init";
3030
static final String NDK_ENABLE = "io.sentry.ndk.enable";
31+
static final String NDK_SCOPE_SYNC_ENABLE = "io.sentry.ndk.scope-sync.enable";
3132
static final String RELEASE = "io.sentry.release";
3233
static final String ENVIRONMENT = "io.sentry.environment";
3334
static final String SESSION_TRACKING_ENABLE = "io.sentry.session-tracking.enable";
@@ -127,6 +128,11 @@ static void applyMetadata(
127128
options.getLogger().log(SentryLevel.DEBUG, "NDK read: %s", ndk);
128129
options.setEnableNdk(ndk);
129130

131+
final boolean ndkScopeSync =
132+
metadata.getBoolean(NDK_SCOPE_SYNC_ENABLE, options.isEnableScopeSync());
133+
options.getLogger().log(SentryLevel.DEBUG, "ndkScopeSync read: %s", ndkScopeSync);
134+
options.setEnableScopeSync(ndkScopeSync);
135+
130136
final String release = metadata.getString(RELEASE, options.getRelease());
131137
options.getLogger().log(SentryLevel.DEBUG, "release read: %s", release);
132138
options.setRelease(release);

sentry-android-ndk/build.gradle.kts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,12 @@ plugins {
1010
id(Config.QualityPlugins.gradleVersions)
1111
}
1212

13+
var sentryNativeSrc: String = "sentry-native"
14+
1315
android {
1416
compileSdkVersion(Config.Android.compileSdkVersion)
1517

16-
val sentryNativeSrc = if (File("${project.projectDir}/sentry-native-local").exists()) {
18+
sentryNativeSrc = if (File("${project.projectDir}/sentry-native-local").exists()) {
1719
"sentry-native-local"
1820
} else {
1921
"sentry-native"
@@ -106,12 +108,14 @@ dependencies {
106108

107109
testImplementation(kotlin(Config.kotlinStdLib, KotlinCompilerVersion.VERSION))
108110
testImplementation(Config.TestLibs.kotlinTestJunit)
111+
112+
testImplementation(Config.TestLibs.mockitoKotlin)
109113
}
110114

111115
val initNative = tasks.register<Exec>("initNative") {
112116
logger.log(LogLevel.LIFECYCLE, "Initializing git submodules")
113117
commandLine("git", "submodule", "update", "--init", "--recursive")
114-
outputs.dir("${project.projectDir}/sentry-native")
118+
outputs.dir("${project.projectDir}/$sentryNativeSrc")
115119
}
116120

117121
tasks.named("preBuild") {
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package io.sentry.android.ndk;
2+
3+
interface INativeScope {
4+
void setTag(String key, String value);
5+
6+
void removeTag(String key);
7+
8+
void setExtra(String key, String value);
9+
10+
void removeExtra(String key);
11+
12+
void setUser(String id, String email, String ipAddress, String username);
13+
14+
void removeUser();
15+
16+
void addBreadcrumb(
17+
String level, String message, String category, String type, String timestamp, String data);
18+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package io.sentry.android.ndk;
2+
3+
final class NativeScope implements INativeScope {
4+
@Override
5+
public void setTag(String key, String value) {
6+
nativeSetTag(key, value);
7+
}
8+
9+
@Override
10+
public void removeTag(String key) {
11+
nativeRemoveTag(key);
12+
}
13+
14+
@Override
15+
public void setExtra(String key, String value) {
16+
nativeSetExtra(key, value);
17+
}
18+
19+
@Override
20+
public void removeExtra(String key) {
21+
nativeRemoveExtra(key);
22+
}
23+
24+
@Override
25+
public void setUser(String id, String email, String ipAddress, String username) {
26+
nativeSetUser(id, email, ipAddress, username);
27+
}
28+
29+
@Override
30+
public void removeUser() {
31+
nativeRemoveUser();
32+
}
33+
34+
@Override
35+
public void addBreadcrumb(
36+
String level, String message, String category, String type, String timestamp, String data) {
37+
nativeAddBreadcrumb(level, message, category, type, timestamp, data);
38+
}
39+
40+
public static native void nativeSetTag(String key, String value);
41+
42+
public static native void nativeRemoveTag(String key);
43+
44+
public static native void nativeSetExtra(String key, String value);
45+
46+
public static native void nativeRemoveExtra(String key);
47+
48+
public static native void nativeSetUser(
49+
String id, String email, String ipAddress, String username);
50+
51+
public static native void nativeRemoveUser();
52+
53+
public static native void nativeAddBreadcrumb(
54+
String level, String message, String category, String type, String timestamp, String data);
55+
}
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
package io.sentry.android.ndk;
2+
3+
import io.sentry.Breadcrumb;
4+
import io.sentry.DateUtils;
5+
import io.sentry.IScopeObserver;
6+
import io.sentry.SentryLevel;
7+
import io.sentry.SentryOptions;
8+
import io.sentry.protocol.User;
9+
import io.sentry.util.Objects;
10+
import java.util.Locale;
11+
import java.util.Map;
12+
import org.jetbrains.annotations.ApiStatus;
13+
import org.jetbrains.annotations.NotNull;
14+
import org.jetbrains.annotations.Nullable;
15+
16+
@ApiStatus.Internal
17+
public final class NdkScopeObserver implements IScopeObserver {
18+
19+
private final @NotNull SentryOptions options;
20+
private final @NotNull INativeScope nativeScope;
21+
22+
public NdkScopeObserver(final @NotNull SentryOptions options) {
23+
this(options, new NativeScope());
24+
}
25+
26+
NdkScopeObserver(final @NotNull SentryOptions options, final @NotNull INativeScope nativeScope) {
27+
this.options = Objects.requireNonNull(options, "The SentryOptions object is required.");
28+
this.nativeScope = Objects.requireNonNull(nativeScope, "The NativeScope object is required.");
29+
}
30+
31+
@Override
32+
public void setUser(final @Nullable User user) {
33+
try {
34+
if (user == null) {
35+
// remove user if its null
36+
nativeScope.removeUser();
37+
} else {
38+
nativeScope.setUser(user.getId(), user.getEmail(), user.getIpAddress(), user.getUsername());
39+
}
40+
} catch (Throwable e) {
41+
options.getLogger().log(SentryLevel.ERROR, e, "Scope sync setUser has an error.");
42+
}
43+
}
44+
45+
@Override
46+
public void addBreadcrumb(final @NotNull Breadcrumb crumb) {
47+
try {
48+
String level = null;
49+
if (crumb.getLevel() != null) {
50+
level = crumb.getLevel().name().toLowerCase(Locale.ROOT);
51+
}
52+
final String timestamp = DateUtils.getTimestamp(crumb.getTimestamp());
53+
54+
String data = null;
55+
try {
56+
final Map<String, Object> dataRef = crumb.getData();
57+
if (!dataRef.isEmpty()) {
58+
data = options.getSerializer().serialize(dataRef);
59+
}
60+
} catch (Exception e) {
61+
options.getLogger().log(SentryLevel.ERROR, e, "Breadcrumb data is not serializable.");
62+
}
63+
64+
nativeScope.addBreadcrumb(
65+
level, crumb.getMessage(), crumb.getCategory(), crumb.getType(), timestamp, data);
66+
} catch (Throwable e) {
67+
options.getLogger().log(SentryLevel.ERROR, e, "Scope sync addBreadcrumb has an error.");
68+
}
69+
}
70+
71+
@Override
72+
public void setTag(final @NotNull String key, final @NotNull String value) {
73+
try {
74+
nativeScope.setTag(key, value);
75+
} catch (Throwable e) {
76+
options.getLogger().log(SentryLevel.ERROR, e, "Scope sync setTag(%s) has an error.", key);
77+
}
78+
}
79+
80+
@Override
81+
public void removeTag(final @NotNull String key) {
82+
try {
83+
nativeScope.removeTag(key);
84+
} catch (Throwable e) {
85+
options.getLogger().log(SentryLevel.ERROR, e, "Scope sync removeTag(%s) has an error.", key);
86+
}
87+
}
88+
89+
@Override
90+
public void setExtra(final @NotNull String key, final @NotNull String value) {
91+
try {
92+
nativeScope.setExtra(key, value);
93+
} catch (Throwable e) {
94+
options.getLogger().log(SentryLevel.ERROR, e, "Scope sync setExtra(%s) has an error.", key);
95+
}
96+
}
97+
98+
@Override
99+
public void removeExtra(final @NotNull String key) {
100+
try {
101+
nativeScope.removeExtra(key);
102+
} catch (Throwable e) {
103+
options
104+
.getLogger()
105+
.log(SentryLevel.ERROR, e, "Scope sync removeExtra(%s) has an error.", key);
106+
}
107+
}
108+
}

sentry-android-ndk/src/main/java/io/sentry/android/ndk/SentryNdk.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,5 +25,6 @@ private SentryNdk() {}
2525
public static void init(@NotNull final SentryOptions options) {
2626
SentryNdkUtil.addPackage(options.getSdkVersion());
2727
initSentryNative(options);
28+
options.addScopeObserver(new NdkScopeObserver(options));
2829
}
2930
}

0 commit comments

Comments
 (0)