Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Enrich os, user and app context
  • Loading branch information
markushi committed Jul 12, 2023
commit e856a09651ab94efd47d76e3e91189a488ef06a8
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
import static android.content.Context.ACTIVITY_SERVICE;
import static android.content.pm.PackageInfo.REQUESTED_PERMISSION_GRANTED;

import android.annotation.SuppressLint;
import android.app.ActivityManager;
Expand All @@ -15,6 +16,7 @@
import android.util.DisplayMetrics;
import io.sentry.ILogger;
import io.sentry.SentryLevel;
import io.sentry.protocol.App;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
Expand Down Expand Up @@ -343,4 +345,37 @@ static boolean isForegroundImportance(final @NotNull Context context) {
return null;
}
}

// we perform an if-check for that, but lint fails to recognize
@SuppressLint("NewApi")
static void setAppPackageInfo(
final @NotNull PackageInfo packageInfo,
final @NotNull BuildInfoProvider buildInfoProvider,
final @NotNull App app) {
app.setAppIdentifier(packageInfo.packageName);
app.setAppVersion(packageInfo.versionName);
app.setAppBuild(ContextUtils.getVersionCode(packageInfo, buildInfoProvider));

if (buildInfoProvider.getSdkInfoVersion() >= Build.VERSION_CODES.JELLY_BEAN) {
final Map<String, String> permissions = new HashMap<>();
final String[] requestedPermissions = packageInfo.requestedPermissions;
final int[] requestedPermissionsFlags = packageInfo.requestedPermissionsFlags;

if (requestedPermissions != null
&& requestedPermissions.length > 0
&& requestedPermissionsFlags != null
&& requestedPermissionsFlags.length > 0) {
for (int i = 0; i < requestedPermissions.length; i++) {
String permission = requestedPermissions[i];
permission = permission.substring(permission.lastIndexOf('.') + 1);

final boolean granted =
(requestedPermissionsFlags[i] & REQUESTED_PERMISSION_GRANTED)
== REQUESTED_PERMISSION_GRANTED;
permissions.put(permission, granted ? "granted" : "not_granted");
}
}
app.setPermissions(permissions);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
package io.sentry.android.core;

import static android.content.pm.PackageInfo.REQUESTED_PERMISSION_GRANTED;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Build;
import io.sentry.DateUtils;
import io.sentry.EventProcessor;
import io.sentry.Hint;
Expand All @@ -21,7 +17,6 @@
import io.sentry.protocol.User;
import io.sentry.util.HintUtils;
import io.sentry.util.Objects;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.ExecutorService;
Expand Down Expand Up @@ -185,7 +180,7 @@ private void setPackageInfo(final @NotNull SentryBaseEvent event, final @NotNull
String versionCode = ContextUtils.getVersionCode(packageInfo, buildInfoProvider);

setDist(event, versionCode);
setAppPackageInfo(app, packageInfo);
ContextUtils.setAppPackageInfo(packageInfo, buildInfoProvider, app);
}
}

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

@SuppressLint("NewApi") // we perform an if-check for that, but lint fails to recognize
private void setAppPackageInfo(final @NotNull App app, final @NotNull PackageInfo packageInfo) {
app.setAppIdentifier(packageInfo.packageName);
app.setAppVersion(packageInfo.versionName);
app.setAppBuild(ContextUtils.getVersionCode(packageInfo, buildInfoProvider));

if (buildInfoProvider.getSdkInfoVersion() >= Build.VERSION_CODES.JELLY_BEAN) {
final Map<String, String> permissions = new HashMap<>();
final String[] requestedPermissions = packageInfo.requestedPermissions;
final int[] requestedPermissionsFlags = packageInfo.requestedPermissionsFlags;

if (requestedPermissions != null
&& requestedPermissions.length > 0
&& requestedPermissionsFlags != null
&& requestedPermissionsFlags.length > 0) {
for (int i = 0; i < requestedPermissions.length; i++) {
String permission = requestedPermissions[i];
permission = permission.substring(permission.lastIndexOf('.') + 1);

final boolean granted =
(requestedPermissionsFlags[i] & REQUESTED_PERMISSION_GRANTED)
== REQUESTED_PERMISSION_GRANTED;
permissions.put(permission, granted ? "granted" : "not_granted");
}
}
app.setPermissions(permissions);
}
}

/**
* Sets the default user which contains only the userId.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
package io.sentry.android.core;

import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import io.sentry.DateUtils;
import io.sentry.HubAdapter;
import io.sentry.ILogger;
import io.sentry.ObjectWriter;
import io.sentry.Scope;
import io.sentry.SentryLevel;
import io.sentry.protocol.App;
import io.sentry.protocol.Device;
import io.sentry.protocol.User;
import io.sentry.util.MapObjectWriter;
Expand Down Expand Up @@ -40,22 +44,41 @@ public static Map<String, Object> serializeScope(
final @NotNull ILogger logger = options.getLogger();
final @NotNull ObjectWriter writer = new MapObjectWriter(data);

final @NotNull DeviceInfoUtil deviceInfoUtil = DeviceInfoUtil.getInstance(context, options);
final @NotNull Device deviceInfo = deviceInfoUtil.collectDeviceInformation(false, false);
scope.getContexts().setDevice(deviceInfo);
scope.getContexts().setOperatingSystem(deviceInfoUtil.getOperatingSystem());
try {

@Nullable User user = scope.getUser();
if (user == null) {
user = new User();
user.setId(Installation.id(context));
}
if (user.getId() == null) {
user.setId(Installation.id(context));
}
scope.setUser(user);
final @NotNull DeviceInfoUtil deviceInfoUtil = DeviceInfoUtil.getInstance(context, options);
final @NotNull Device deviceInfo = deviceInfoUtil.collectDeviceInformation(false, false);
scope.getContexts().setDevice(deviceInfo);
scope.getContexts().setOperatingSystem(deviceInfoUtil.getOperatingSystem());

// user
@Nullable User user = scope.getUser();
if (user == null) {
user = new User();
scope.setUser(user);
}
if (user.getId() == null) {
user.setId(Installation.id(context));
}

// app context
@Nullable App app = scope.getContexts().getApp();
if (app == null) {
app = new App();
app.setAppName(ContextUtils.getApplicationName(context, options.getLogger()));
app.setAppStartTime(DateUtils.toUtilDate(AppStartState.getInstance().getAppStartTime()));

final @NotNull BuildInfoProvider buildInfoProvider =
new BuildInfoProvider(options.getLogger());
final @Nullable PackageInfo packageInfo =
ContextUtils.getPackageInfo(
context, PackageManager.GET_PERMISSIONS, options.getLogger(), buildInfoProvider);
if (packageInfo != null) {
ContextUtils.setAppPackageInfo(packageInfo, buildInfoProvider, app);
}
scope.getContexts().setApp(app);
}

try {
writer.name("user").value(logger, scope.getUser());
writer.name("contexts").value(logger, scope.getContexts());
writer.name("tags").value(logger, scope.getTags());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import org.mockito.kotlin.mock
import org.mockito.kotlin.whenever
import kotlin.test.BeforeTest
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertNotNull
import kotlin.test.assertNull
import kotlin.test.assertTrue
Expand Down Expand Up @@ -103,4 +104,34 @@ class InternalSentrySdkTest {
val serializedScope = InternalSentrySdk.serializeScope(context, options, scope)
assertTrue(serializedScope.isEmpty())
}

@Test
fun `serializeScope provides fallback user if none is set`() {
val options = SentryAndroidOptions()
val scope = Scope(options)
scope.user = null

val serializedScope = InternalSentrySdk.serializeScope(context, options, scope)
assertTrue((serializedScope["user"] as Map<*, *>).containsKey("id"))
}

@Test
fun `serializeScope does not override user-id`() {
val options = SentryAndroidOptions()
val scope = Scope(options)
scope.user = User().apply { id = "abc" }

val serializedScope = InternalSentrySdk.serializeScope(context, options, scope)
assertEquals("abc", (serializedScope["user"] as Map<*, *>)["id"])
}

@Test
fun `serializeScope provides fallback app data if none is set`() {
val options = SentryAndroidOptions()
val scope = Scope(options)
scope.setContexts("app", null)

val serializedScope = InternalSentrySdk.serializeScope(context, options, scope)
assertTrue(((serializedScope["contexts"] as Map<*, *>)["app"] as Map<*, *>).containsKey("app_name"))
}
}