Skip to content

Commit f2fb455

Browse files
authored
Merge pull request #735 from immutable/feat/sdk-296-android-device-collector
feat(audience-sdk): extend DeviceCollector with Android-specific signals (SDK-296)
2 parents ffc2a52 + 540ae01 commit f2fb455

4 files changed

Lines changed: 101 additions & 0 deletions

File tree

src/Packages/Audience/Runtime/Unity/DeviceCollector.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,9 @@ internal static Dictionary<string, object> CollectGameLaunchProperties()
6666
var dpi = (int)Screen.dpi;
6767
if (dpi > 0) props["screenDpi"] = dpi;
6868

69+
if (Application.platform == RuntimePlatform.Android)
70+
props["androidId"] = Truncate(SystemInfo.deviceUniqueIdentifier, 256);
71+
6972
return props;
7073
}
7174

src/Packages/Audience/Tests/Audience.Tests.csproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,9 @@
2222
-->
2323
<ItemGroup>
2424
<Compile Remove="Editor/**/*.cs" />
25+
<!-- DeviceCollectorTests references Immutable.Audience.Unity which wraps
26+
UnityEngine APIs unavailable in the headless dotnet build. These tests
27+
run inside the Unity Test Framework via the asmdef instead. -->
28+
<Compile Remove="Runtime/Unity/**/*.cs" />
2529
</ItemGroup>
2630
</Project>
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
#nullable enable
2+
3+
using System.Collections.Generic;
4+
using NUnit.Framework;
5+
using Immutable.Audience.Unity;
6+
7+
namespace Immutable.Audience.Tests
8+
{
9+
[TestFixture]
10+
internal class DeviceCollectorTests
11+
{
12+
// -----------------------------------------------------------------
13+
// CollectContext
14+
// -----------------------------------------------------------------
15+
16+
[Test]
17+
public void CollectContext_AlwaysContainsUserAgent()
18+
{
19+
var ctx = DeviceCollector.CollectContext();
20+
Assert.IsTrue(ctx.ContainsKey("userAgent"), "userAgent must always be present");
21+
Assert.IsNotNull(ctx["userAgent"]);
22+
}
23+
24+
[Test]
25+
public void CollectContext_UserAgent_DoesNotExceed256Chars()
26+
{
27+
var ctx = DeviceCollector.CollectContext();
28+
Assert.LessOrEqual(ctx["userAgent"].ToString()!.Length, 256);
29+
}
30+
31+
[Test]
32+
public void CollectContext_KnownStringKeys_AreWithin256Chars()
33+
{
34+
var ctx = DeviceCollector.CollectContext();
35+
foreach (var key in new[] { "userAgent", "timezone", "locale", "screen" })
36+
{
37+
if (!ctx.TryGetValue(key, out var val)) continue;
38+
Assert.LessOrEqual(val.ToString()!.Length, 256,
39+
$"context[{key}] exceeds 256 chars");
40+
}
41+
}
42+
43+
// -----------------------------------------------------------------
44+
// CollectGameLaunchProperties
45+
// -----------------------------------------------------------------
46+
47+
[Test]
48+
public void CollectGameLaunchProperties_AlwaysContainsCrossPlatformFields()
49+
{
50+
var props = DeviceCollector.CollectGameLaunchProperties();
51+
foreach (var key in new[] {
52+
"platform", "version", "buildGuid", "unityVersion",
53+
"osFamily", "deviceModel", "gpu", "gpuVendor",
54+
"cpu", "cpuCores", "ramMb" })
55+
{
56+
Assert.IsTrue(props.ContainsKey(key), $"expected key '{key}' to be present");
57+
}
58+
}
59+
60+
[Test]
61+
public void CollectGameLaunchProperties_StringFields_DoNotExceed256Chars()
62+
{
63+
var props = DeviceCollector.CollectGameLaunchProperties();
64+
foreach (var key in new[] {
65+
"platform", "version", "buildGuid", "unityVersion",
66+
"osFamily", "deviceModel", "gpu", "gpuVendor", "cpu" })
67+
{
68+
if (!props.TryGetValue(key, out var val) || val is not string s) continue;
69+
Assert.LessOrEqual(s.Length, 256, $"props[{key}] exceeds 256 chars");
70+
}
71+
}
72+
73+
[Test]
74+
public void CollectGameLaunchProperties_NonAndroid_DoesNotContainAndroidId()
75+
{
76+
// Regression guard: androidId must only appear on Android. Running
77+
// tests on Editor/Standalone should never populate this field.
78+
var props = DeviceCollector.CollectGameLaunchProperties();
79+
Assert.IsFalse(props.ContainsKey("androidId"),
80+
"androidId must not be present on non-Android platforms");
81+
}
82+
83+
[Test]
84+
public void CollectGameLaunchProperties_ScreenDpi_AbsentWhenZero()
85+
{
86+
// Screen.dpi returns 0 on some Linux WMs; the implementation
87+
// must omit the key rather than forwarding a zero value.
88+
var props = DeviceCollector.CollectGameLaunchProperties();
89+
if (props.TryGetValue("screenDpi", out var dpi))
90+
Assert.Greater((int)dpi, 0, "screenDpi must not be 0 when present");
91+
}
92+
}
93+
}

src/Packages/Audience/Tests/Runtime/com.immutable.audience.tests.asmdef

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
"rootNamespace": "Immutable.Audience.Tests",
44
"references": [
55
"Immutable.Audience.Runtime",
6+
"Immutable.Audience.Unity",
67
"UnityEngine.TestRunner",
78
"UnityEditor.TestRunner"
89
],

0 commit comments

Comments
 (0)