Skip to content

Commit 5d9e93d

Browse files
authored
Merge de626aa into 0f96fc3
2 parents 0f96fc3 + de626aa commit 5d9e93d

14 files changed

Lines changed: 145 additions & 7 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
- Add time-to-initial-display and time-to-full-display measurements to Activity transactions ([#2611](https://github.com/getsentry/sentry-java/pull/2611))
88
- Read integration list written by sentry gradle plugin from manifest ([#2598](https://github.com/getsentry/sentry-java/pull/2598))
9+
- Provide CPU count/frequency data as device context ([#2622](https://github.com/getsentry/sentry-java/pull/2622))
910

1011
### Fixes
1112

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import io.sentry.SentryLevel;
2929
import io.sentry.android.core.internal.util.AndroidMainThreadChecker;
3030
import io.sentry.android.core.internal.util.ConnectivityChecker;
31+
import io.sentry.android.core.internal.util.CpuInfoUtils;
3132
import io.sentry.android.core.internal.util.DeviceOrientations;
3233
import io.sentry.android.core.internal.util.RootChecker;
3334
import io.sentry.protocol.App;
@@ -43,8 +44,10 @@
4344
import java.io.FileReader;
4445
import java.io.IOException;
4546
import java.util.Calendar;
47+
import java.util.Collections;
4648
import java.util.Date;
4749
import java.util.HashMap;
50+
import java.util.List;
4851
import java.util.Locale;
4952
import java.util.Map;
5053
import java.util.TimeZone;
@@ -355,6 +358,12 @@ private void setArchitectures(final @NotNull Device device) {
355358
device.setLocale(locale.toString()); // eg en_US
356359
}
357360

361+
final @NotNull List<Integer> cpuFrequencies = CpuInfoUtils.getInstance().readMaxFrequencies();
362+
if (!cpuFrequencies.isEmpty()) {
363+
device.setProcessorFrequency(Collections.max(cpuFrequencies).doubleValue());
364+
device.setProcessorCount(cpuFrequencies.size());
365+
}
366+
358367
return device;
359368
}
360369

sentry-android-core/src/main/java/io/sentry/android/core/internal/util/CpuInfoUtils.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,12 @@ String getSystemCpuPath() {
7070
return SYSTEM_CPU_PATH;
7171
}
7272

73+
@TestOnly
74+
public void setCpuMaxFrequencies(List<Integer> frequencies) {
75+
cpuMaxFrequenciesMhz.clear();
76+
cpuMaxFrequenciesMhz.addAll(frequencies);
77+
}
78+
7379
@TestOnly
7480
final void clear() {
7581
cpuMaxFrequenciesMhz.clear();

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

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import io.sentry.android.core.DefaultAndroidEventProcessor.EMULATOR
1717
import io.sentry.android.core.DefaultAndroidEventProcessor.KERNEL_VERSION
1818
import io.sentry.android.core.DefaultAndroidEventProcessor.ROOTED
1919
import io.sentry.android.core.DefaultAndroidEventProcessor.SIDE_LOADED
20+
import io.sentry.android.core.internal.util.CpuInfoUtils
2021
import io.sentry.protocol.OperatingSystem
2122
import io.sentry.protocol.SdkVersion
2223
import io.sentry.protocol.SentryThread
@@ -526,6 +527,29 @@ class DefaultAndroidEventProcessorTest {
526527
}
527528
}
528529

530+
@Test
531+
fun `Event sets no device cpu info when there is none provided`() {
532+
val sut = fixture.getSut(context)
533+
CpuInfoUtils.getInstance().setCpuMaxFrequencies(emptyList())
534+
assertNotNull(sut.process(SentryEvent(), Hint())) {
535+
val device = it.contexts.device!!
536+
assertNull(device.processorCount)
537+
assertNull(device.processorFrequency)
538+
}
539+
}
540+
541+
@Test
542+
fun `Event sets rights device cpu info when there is one provided`() {
543+
val sut = fixture.getSut(context)
544+
CpuInfoUtils.getInstance().setCpuMaxFrequencies(listOf(800, 900))
545+
546+
assertNotNull(sut.process(SentryEvent(), Hint())) {
547+
val device = it.contexts.device!!
548+
assertEquals(2, device.processorCount)
549+
assertEquals(900.0, device.processorFrequency)
550+
}
551+
}
552+
529553
@Test
530554
fun `Events from HybridSDKs don't set main thread and in foreground context`() {
531555
val sut = fixture.getSut(context)

sentry/api/sentry.api

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2750,6 +2750,7 @@ public final class io/sentry/protocol/Device : io/sentry/JsonSerializable, io/se
27502750
public fun getBootTime ()Ljava/util/Date;
27512751
public fun getBrand ()Ljava/lang/String;
27522752
public fun getConnectionType ()Ljava/lang/String;
2753+
public fun getCpuDescription ()Ljava/lang/String;
27532754
public fun getExternalFreeStorage ()Ljava/lang/Long;
27542755
public fun getExternalStorageSize ()Ljava/lang/Long;
27552756
public fun getFamily ()Ljava/lang/String;
@@ -2764,6 +2765,8 @@ public final class io/sentry/protocol/Device : io/sentry/JsonSerializable, io/se
27642765
public fun getModelId ()Ljava/lang/String;
27652766
public fun getName ()Ljava/lang/String;
27662767
public fun getOrientation ()Lio/sentry/protocol/Device$DeviceOrientation;
2768+
public fun getProcessorCount ()Ljava/lang/Integer;
2769+
public fun getProcessorFrequency ()Ljava/lang/Double;
27672770
public fun getScreenDensity ()Ljava/lang/Float;
27682771
public fun getScreenDpi ()Ljava/lang/Integer;
27692772
public fun getScreenHeightPixels ()Ljava/lang/Integer;
@@ -2784,6 +2787,7 @@ public final class io/sentry/protocol/Device : io/sentry/JsonSerializable, io/se
27842787
public fun setBrand (Ljava/lang/String;)V
27852788
public fun setCharging (Ljava/lang/Boolean;)V
27862789
public fun setConnectionType (Ljava/lang/String;)V
2790+
public fun setCpuDescription (Ljava/lang/String;)V
27872791
public fun setExternalFreeStorage (Ljava/lang/Long;)V
27882792
public fun setExternalStorageSize (Ljava/lang/Long;)V
27892793
public fun setFamily (Ljava/lang/String;)V
@@ -2800,6 +2804,8 @@ public final class io/sentry/protocol/Device : io/sentry/JsonSerializable, io/se
28002804
public fun setName (Ljava/lang/String;)V
28012805
public fun setOnline (Ljava/lang/Boolean;)V
28022806
public fun setOrientation (Lio/sentry/protocol/Device$DeviceOrientation;)V
2807+
public fun setProcessorCount (Ljava/lang/Integer;)V
2808+
public fun setProcessorFrequency (Ljava/lang/Double;)V
28032809
public fun setScreenDensity (Ljava/lang/Float;)V
28042810
public fun setScreenDpi (Ljava/lang/Integer;)V
28052811
public fun setScreenHeightPixels (Ljava/lang/Integer;)V
@@ -2839,6 +2845,7 @@ public final class io/sentry/protocol/Device$JsonKeys {
28392845
public static final field BRAND Ljava/lang/String;
28402846
public static final field CHARGING Ljava/lang/String;
28412847
public static final field CONNECTION_TYPE Ljava/lang/String;
2848+
public static final field CPU_DESCRIPTION Ljava/lang/String;
28422849
public static final field EXTERNAL_FREE_STORAGE Ljava/lang/String;
28432850
public static final field EXTERNAL_STORAGE_SIZE Ljava/lang/String;
28442851
public static final field FAMILY Ljava/lang/String;
@@ -2855,6 +2862,8 @@ public final class io/sentry/protocol/Device$JsonKeys {
28552862
public static final field NAME Ljava/lang/String;
28562863
public static final field ONLINE Ljava/lang/String;
28572864
public static final field ORIENTATION Ljava/lang/String;
2865+
public static final field PROCESSOR_COUNT Ljava/lang/String;
2866+
public static final field PROCESSOR_FREQUENCY Ljava/lang/String;
28582867
public static final field SCREEN_DENSITY Ljava/lang/String;
28592868
public static final field SCREEN_DPI Ljava/lang/String;
28602869
public static final field SCREEN_HEIGHT_PIXELS Ljava/lang/String;

sentry/src/main/java/io/sentry/protocol/Device.java

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,19 @@ public final class Device implements JsonUnknown, JsonSerializable {
117117
/** battery's temperature in celsius */
118118
private @Nullable Float batteryTemperature;
119119

120+
/** Optional. Number of "logical processors". For example, 8. */
121+
private @Nullable Integer processorCount;
122+
123+
/**
124+
* Optional. Processor frequency in MHz. Note that the actual CPU frequency might vary depending
125+
* on current load and power conditions, especially on low-powered devices like phones and
126+
* laptops.
127+
*/
128+
private @Nullable Double processorFrequency;
129+
130+
/** Optional. CPU description. For example, Intel(R) Core(TM)2 Quad CPU Q6600 @ 2.40GHz. */
131+
private @Nullable String cpuDescription;
132+
120133
@SuppressWarnings("unused")
121134
private @Nullable Map<String, @NotNull Object> unknown;
122135

@@ -158,6 +171,10 @@ public Device() {}
158171
final TimeZone timezoneRef = device.timezone;
159172
this.timezone = timezoneRef != null ? (TimeZone) timezoneRef.clone() : null;
160173

174+
this.processorCount = device.processorCount;
175+
this.processorFrequency = device.processorFrequency;
176+
this.cpuDescription = device.cpuDescription;
177+
161178
this.unknown = CollectionUtils.newConcurrentHashMap(device.unknown);
162179
}
163180

@@ -403,6 +420,30 @@ public void setBatteryTemperature(final @Nullable Float batteryTemperature) {
403420
this.batteryTemperature = batteryTemperature;
404421
}
405422

423+
public @Nullable Integer getProcessorCount() {
424+
return processorCount;
425+
}
426+
427+
public void setProcessorCount(@Nullable Integer processorCount) {
428+
this.processorCount = processorCount;
429+
}
430+
431+
public @Nullable Double getProcessorFrequency() {
432+
return processorFrequency;
433+
}
434+
435+
public void setProcessorFrequency(@Nullable Double processorFrequency) {
436+
this.processorFrequency = processorFrequency;
437+
}
438+
439+
public @Nullable String getCpuDescription() {
440+
return cpuDescription;
441+
}
442+
443+
public void setCpuDescription(@Nullable String cpuDescription) {
444+
this.cpuDescription = cpuDescription;
445+
}
446+
406447
public enum DeviceOrientation implements JsonSerializable {
407448
PORTRAIT,
408449
LANDSCAPE;
@@ -460,6 +501,9 @@ public static final class JsonKeys {
460501
public static final String CONNECTION_TYPE = "connection_type";
461502
public static final String BATTERY_TEMPERATURE = "battery_temperature";
462503
public static final String LOCALE = "locale";
504+
public static final String PROCESSOR_COUNT = "processor_count";
505+
public static final String CPU_DESCRIPTION = "cpu_description";
506+
public static final String PROCESSOR_FREQUENCY = "processor_frequency";
463507
}
464508

465509
@Override
@@ -559,6 +603,15 @@ public void serialize(@NotNull JsonObjectWriter writer, @NotNull ILogger logger)
559603
if (locale != null) {
560604
writer.name(JsonKeys.LOCALE).value(locale);
561605
}
606+
if (processorCount != null) {
607+
writer.name(JsonKeys.PROCESSOR_COUNT).value(processorCount);
608+
}
609+
if (processorFrequency != null) {
610+
writer.name(JsonKeys.PROCESSOR_FREQUENCY).value(processorFrequency);
611+
}
612+
if (cpuDescription != null) {
613+
writer.name(JsonKeys.CPU_DESCRIPTION).value(cpuDescription);
614+
}
562615
if (unknown != null) {
563616
for (String key : unknown.keySet()) {
564617
Object value = unknown.get(key);
@@ -698,6 +751,15 @@ public static final class Deserializer implements JsonDeserializer<Device> {
698751
case JsonKeys.LOCALE:
699752
device.locale = reader.nextStringOrNull();
700753
break;
754+
case JsonKeys.PROCESSOR_COUNT:
755+
device.processorCount = reader.nextIntegerOrNull();
756+
break;
757+
case JsonKeys.PROCESSOR_FREQUENCY:
758+
device.processorFrequency = reader.nextDoubleOrNull();
759+
break;
760+
case JsonKeys.CPU_DESCRIPTION:
761+
device.cpuDescription = reader.nextStringOrNull();
762+
break;
701763
default:
702764
if (unknown == null) {
703765
unknown = new ConcurrentHashMap<>();

sentry/src/test/java/io/sentry/protocol/DeviceSerializationTest.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,9 @@ class DeviceSerializationTest {
5656
language = "6dd45f60-111d-42d8-9204-0452cc836ad8"
5757
connectionType = "9ceb3a6c-5292-4ed9-8665-5732495e8ed4"
5858
batteryTemperature = 0.14775127f
59+
cpuDescription = "cpu0"
60+
processorCount = 4
61+
processorFrequency = 800.0
5962
}
6063
}
6164
private val fixture = Fixture()

sentry/src/test/java/io/sentry/protocol/DeviceTest.kt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,9 @@ class DeviceTest {
6262
device.connectionType = "connection type"
6363
device.batteryTemperature = 30f
6464
device.locale = "en-US"
65+
device.cpuDescription = "cpu0"
66+
device.processorCount = 4
67+
device.processorFrequency = 800.0
6568
val unknown = mapOf(Pair("unknown", "unknown"))
6669
device.setUnknown(unknown)
6770

@@ -99,7 +102,10 @@ class DeviceTest {
99102
assertEquals("language", clone.language)
100103
assertEquals("connection type", clone.connectionType)
101104
assertEquals(30f, clone.batteryTemperature)
102-
assertEquals("en-US", clone.locale)
105+
assertEquals("cpu0", clone.cpuDescription)
106+
assertEquals(4, clone.processorCount)
107+
assertEquals(800.0, clone.processorFrequency)
108+
device.processorFrequency = 800.0
103109
assertNotNull(clone.unknown) {
104110
assertEquals("unknown", it["unknown"])
105111
}

sentry/src/test/resources/json/contexts.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,10 @@
5959
"id": "e0fa5c8d-83f5-4e70-bc60-1e82ad30e196",
6060
"language": "6dd45f60-111d-42d8-9204-0452cc836ad8",
6161
"connection_type": "9ceb3a6c-5292-4ed9-8665-5732495e8ed4",
62-
"battery_temperature": 0.14775127
62+
"battery_temperature": 0.14775127,
63+
"processor_count": 4,
64+
"processor_frequency": 800.0,
65+
"cpu_description": "cpu0"
6366
},
6467
"gpu":
6568
{

sentry/src/test/resources/json/device.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,5 +36,8 @@
3636
"id": "e0fa5c8d-83f5-4e70-bc60-1e82ad30e196",
3737
"language": "6dd45f60-111d-42d8-9204-0452cc836ad8",
3838
"connection_type": "9ceb3a6c-5292-4ed9-8665-5732495e8ed4",
39-
"battery_temperature": 0.14775127
39+
"battery_temperature": 0.14775127,
40+
"processor_count": 4,
41+
"processor_frequency": 800.0,
42+
"cpu_description": "cpu0"
4043
}

0 commit comments

Comments
 (0)