Skip to content

Commit e856a09

Browse files
committed
Enrich os, user and app context
1 parent 74cbd44 commit e856a09

File tree

4 files changed

+104
-49
lines changed

4 files changed

+104
-49
lines changed

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

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
44
import static android.content.Context.ACTIVITY_SERVICE;
5+
import static android.content.pm.PackageInfo.REQUESTED_PERMISSION_GRANTED;
56

67
import android.annotation.SuppressLint;
78
import android.app.ActivityManager;
@@ -15,6 +16,7 @@
1516
import android.util.DisplayMetrics;
1617
import io.sentry.ILogger;
1718
import io.sentry.SentryLevel;
19+
import io.sentry.protocol.App;
1820
import java.io.BufferedReader;
1921
import java.io.File;
2022
import java.io.FileReader;
@@ -343,4 +345,37 @@ static boolean isForegroundImportance(final @NotNull Context context) {
343345
return null;
344346
}
345347
}
348+
349+
// we perform an if-check for that, but lint fails to recognize
350+
@SuppressLint("NewApi")
351+
static void setAppPackageInfo(
352+
final @NotNull PackageInfo packageInfo,
353+
final @NotNull BuildInfoProvider buildInfoProvider,
354+
final @NotNull App app) {
355+
app.setAppIdentifier(packageInfo.packageName);
356+
app.setAppVersion(packageInfo.versionName);
357+
app.setAppBuild(ContextUtils.getVersionCode(packageInfo, buildInfoProvider));
358+
359+
if (buildInfoProvider.getSdkInfoVersion() >= Build.VERSION_CODES.JELLY_BEAN) {
360+
final Map<String, String> permissions = new HashMap<>();
361+
final String[] requestedPermissions = packageInfo.requestedPermissions;
362+
final int[] requestedPermissionsFlags = packageInfo.requestedPermissionsFlags;
363+
364+
if (requestedPermissions != null
365+
&& requestedPermissions.length > 0
366+
&& requestedPermissionsFlags != null
367+
&& requestedPermissionsFlags.length > 0) {
368+
for (int i = 0; i < requestedPermissions.length; i++) {
369+
String permission = requestedPermissions[i];
370+
permission = permission.substring(permission.lastIndexOf('.') + 1);
371+
372+
final boolean granted =
373+
(requestedPermissionsFlags[i] & REQUESTED_PERMISSION_GRANTED)
374+
== REQUESTED_PERMISSION_GRANTED;
375+
permissions.put(permission, granted ? "granted" : "not_granted");
376+
}
377+
}
378+
app.setPermissions(permissions);
379+
}
380+
}
346381
}

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

Lines changed: 1 addition & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,8 @@
11
package io.sentry.android.core;
22

3-
import static android.content.pm.PackageInfo.REQUESTED_PERMISSION_GRANTED;
4-
5-
import android.annotation.SuppressLint;
63
import android.content.Context;
74
import android.content.pm.PackageInfo;
85
import android.content.pm.PackageManager;
9-
import android.os.Build;
106
import io.sentry.DateUtils;
117
import io.sentry.EventProcessor;
128
import io.sentry.Hint;
@@ -21,7 +17,6 @@
2117
import io.sentry.protocol.User;
2218
import io.sentry.util.HintUtils;
2319
import io.sentry.util.Objects;
24-
import java.util.HashMap;
2520
import java.util.Locale;
2621
import java.util.Map;
2722
import java.util.concurrent.ExecutorService;
@@ -185,7 +180,7 @@ private void setPackageInfo(final @NotNull SentryBaseEvent event, final @NotNull
185180
String versionCode = ContextUtils.getVersionCode(packageInfo, buildInfoProvider);
186181

187182
setDist(event, versionCode);
188-
setAppPackageInfo(app, packageInfo);
183+
ContextUtils.setAppPackageInfo(packageInfo, buildInfoProvider, app);
189184
}
190185
}
191186

@@ -210,35 +205,6 @@ private void setAppExtras(final @NotNull App app, final @NotNull Hint hint) {
210205
}
211206
}
212207

213-
@SuppressLint("NewApi") // we perform an if-check for that, but lint fails to recognize
214-
private void setAppPackageInfo(final @NotNull App app, final @NotNull PackageInfo packageInfo) {
215-
app.setAppIdentifier(packageInfo.packageName);
216-
app.setAppVersion(packageInfo.versionName);
217-
app.setAppBuild(ContextUtils.getVersionCode(packageInfo, buildInfoProvider));
218-
219-
if (buildInfoProvider.getSdkInfoVersion() >= Build.VERSION_CODES.JELLY_BEAN) {
220-
final Map<String, String> permissions = new HashMap<>();
221-
final String[] requestedPermissions = packageInfo.requestedPermissions;
222-
final int[] requestedPermissionsFlags = packageInfo.requestedPermissionsFlags;
223-
224-
if (requestedPermissions != null
225-
&& requestedPermissions.length > 0
226-
&& requestedPermissionsFlags != null
227-
&& requestedPermissionsFlags.length > 0) {
228-
for (int i = 0; i < requestedPermissions.length; i++) {
229-
String permission = requestedPermissions[i];
230-
permission = permission.substring(permission.lastIndexOf('.') + 1);
231-
232-
final boolean granted =
233-
(requestedPermissionsFlags[i] & REQUESTED_PERMISSION_GRANTED)
234-
== REQUESTED_PERMISSION_GRANTED;
235-
permissions.put(permission, granted ? "granted" : "not_granted");
236-
}
237-
}
238-
app.setPermissions(permissions);
239-
}
240-
}
241-
242208
/**
243209
* Sets the default user which contains only the userId.
244210
*

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

Lines changed: 37 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
package io.sentry.android.core;
22

33
import android.content.Context;
4+
import android.content.pm.PackageInfo;
5+
import android.content.pm.PackageManager;
6+
import io.sentry.DateUtils;
47
import io.sentry.HubAdapter;
58
import io.sentry.ILogger;
69
import io.sentry.ObjectWriter;
710
import io.sentry.Scope;
811
import io.sentry.SentryLevel;
12+
import io.sentry.protocol.App;
913
import io.sentry.protocol.Device;
1014
import io.sentry.protocol.User;
1115
import io.sentry.util.MapObjectWriter;
@@ -40,22 +44,41 @@ public static Map<String, Object> serializeScope(
4044
final @NotNull ILogger logger = options.getLogger();
4145
final @NotNull ObjectWriter writer = new MapObjectWriter(data);
4246

43-
final @NotNull DeviceInfoUtil deviceInfoUtil = DeviceInfoUtil.getInstance(context, options);
44-
final @NotNull Device deviceInfo = deviceInfoUtil.collectDeviceInformation(false, false);
45-
scope.getContexts().setDevice(deviceInfo);
46-
scope.getContexts().setOperatingSystem(deviceInfoUtil.getOperatingSystem());
47+
try {
4748

48-
@Nullable User user = scope.getUser();
49-
if (user == null) {
50-
user = new User();
51-
user.setId(Installation.id(context));
52-
}
53-
if (user.getId() == null) {
54-
user.setId(Installation.id(context));
55-
}
56-
scope.setUser(user);
49+
final @NotNull DeviceInfoUtil deviceInfoUtil = DeviceInfoUtil.getInstance(context, options);
50+
final @NotNull Device deviceInfo = deviceInfoUtil.collectDeviceInformation(false, false);
51+
scope.getContexts().setDevice(deviceInfo);
52+
scope.getContexts().setOperatingSystem(deviceInfoUtil.getOperatingSystem());
53+
54+
// user
55+
@Nullable User user = scope.getUser();
56+
if (user == null) {
57+
user = new User();
58+
scope.setUser(user);
59+
}
60+
if (user.getId() == null) {
61+
user.setId(Installation.id(context));
62+
}
63+
64+
// app context
65+
@Nullable App app = scope.getContexts().getApp();
66+
if (app == null) {
67+
app = new App();
68+
app.setAppName(ContextUtils.getApplicationName(context, options.getLogger()));
69+
app.setAppStartTime(DateUtils.toUtilDate(AppStartState.getInstance().getAppStartTime()));
70+
71+
final @NotNull BuildInfoProvider buildInfoProvider =
72+
new BuildInfoProvider(options.getLogger());
73+
final @Nullable PackageInfo packageInfo =
74+
ContextUtils.getPackageInfo(
75+
context, PackageManager.GET_PERMISSIONS, options.getLogger(), buildInfoProvider);
76+
if (packageInfo != null) {
77+
ContextUtils.setAppPackageInfo(packageInfo, buildInfoProvider, app);
78+
}
79+
scope.getContexts().setApp(app);
80+
}
5781

58-
try {
5982
writer.name("user").value(logger, scope.getUser());
6083
writer.name("contexts").value(logger, scope.getContexts());
6184
writer.name("tags").value(logger, scope.getTags());

sentry-android-core/src/test/java/io/sentry/android/core/InternalSentrySdkTest.kt

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import org.mockito.kotlin.mock
1717
import org.mockito.kotlin.whenever
1818
import kotlin.test.BeforeTest
1919
import kotlin.test.Test
20+
import kotlin.test.assertEquals
2021
import kotlin.test.assertNotNull
2122
import kotlin.test.assertNull
2223
import kotlin.test.assertTrue
@@ -103,4 +104,34 @@ class InternalSentrySdkTest {
103104
val serializedScope = InternalSentrySdk.serializeScope(context, options, scope)
104105
assertTrue(serializedScope.isEmpty())
105106
}
107+
108+
@Test
109+
fun `serializeScope provides fallback user if none is set`() {
110+
val options = SentryAndroidOptions()
111+
val scope = Scope(options)
112+
scope.user = null
113+
114+
val serializedScope = InternalSentrySdk.serializeScope(context, options, scope)
115+
assertTrue((serializedScope["user"] as Map<*, *>).containsKey("id"))
116+
}
117+
118+
@Test
119+
fun `serializeScope does not override user-id`() {
120+
val options = SentryAndroidOptions()
121+
val scope = Scope(options)
122+
scope.user = User().apply { id = "abc" }
123+
124+
val serializedScope = InternalSentrySdk.serializeScope(context, options, scope)
125+
assertEquals("abc", (serializedScope["user"] as Map<*, *>)["id"])
126+
}
127+
128+
@Test
129+
fun `serializeScope provides fallback app data if none is set`() {
130+
val options = SentryAndroidOptions()
131+
val scope = Scope(options)
132+
scope.setContexts("app", null)
133+
134+
val serializedScope = InternalSentrySdk.serializeScope(context, options, scope)
135+
assertTrue(((serializedScope["contexts"] as Map<*, *>)["app"] as Map<*, *>).containsKey("app_name"))
136+
}
106137
}

0 commit comments

Comments
 (0)