Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
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
32 changes: 26 additions & 6 deletions src/Packages/Audience/Runtime/Unity/AudienceUnityHooks.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#nullable enable

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using Immutable.Audience.Unity.Mobile;
Expand Down Expand Up @@ -31,12 +32,33 @@ private static void Install()
_persistentDataPath = Application.persistentDataPath;
ImmutableAudience.DefaultPersistentDataPathProvider = () => Application.persistentDataPath;

// Set before the collectors below run so a collector failure logs via Debug.Log, not Console.WriteLine.
if (Log.Writer == null) Log.Writer = Debug.Log;

// Captured once on main thread; ReadOnlyDictionary blocks downstream mutation.
IReadOnlyDictionary<string, object> launchProps =
new ReadOnlyDictionary<string, object>(DeviceCollector.CollectGameLaunchProperties());
IReadOnlyDictionary<string, object> contextProps =
new ReadOnlyDictionary<string, object>(DeviceCollector.CollectContext());
// Each collector is isolated so one throwing can't block the other's provider or abort Install().
IReadOnlyDictionary<string, object> launchProps;
try
{
launchProps = new ReadOnlyDictionary<string, object>(DeviceCollector.CollectGameLaunchProperties());
}
catch (Exception ex)
{
Log.Warn(AudienceLogs.LaunchPropertiesCollectionFailed(ex));
launchProps = new ReadOnlyDictionary<string, object>(new Dictionary<string, object>());
}
ImmutableAudience.LaunchContextProvider = () => launchProps;

IReadOnlyDictionary<string, object> contextProps;
try
{
contextProps = new ReadOnlyDictionary<string, object>(DeviceCollector.CollectContext());
}
catch (Exception ex)
{
Log.Warn(AudienceLogs.ContextCollectionFailed(ex));
contextProps = new ReadOnlyDictionary<string, object>(new Dictionary<string, object>());
}
ImmutableAudience.ContextProvider = () => contextProps;

#if UNITY_IOS && !UNITY_EDITOR && AUDIENCE_MOBILE_ATTRIBUTION
Expand All @@ -58,8 +80,6 @@ private static void Install()
#endif

UnityLifecycleBridge.EnsureExists();

if (Log.Writer == null) Log.Writer = Debug.Log;
}

// Warms the install referrer cache for the next launch and returns
Expand Down
30 changes: 20 additions & 10 deletions src/Packages/Audience/Runtime/Unity/DeviceCollector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,18 +32,28 @@ internal static Dictionary<string, object> CollectContext()

private static string? TryResolveScreenString()
{
var resolution = Screen.currentResolution;
int width = resolution.width;
int height = resolution.height;

if (width <= 0 || height <= 0)
// Can throw before a window/graphics device exists this early in boot;
// isolated so a failure here doesn't cost CollectContext()'s other fields.
try
{
width = Screen.width;
height = Screen.height;
var resolution = Screen.currentResolution;
int width = resolution.width;
int height = resolution.height;

if (width <= 0 || height <= 0)
{
width = Screen.width;
height = Screen.height;
}

if (width <= 0 || height <= 0) return null;
return $"{width}x{height}";
}
catch (Exception ex)
{
Log.Warn(AudienceLogs.ScreenResolutionReadFailed(ex));
return null;
}

if (width <= 0 || height <= 0) return null;
return $"{width}x{height}";
}

internal static Dictionary<string, object> CollectGameLaunchProperties(
Expand Down
14 changes: 14 additions & 0 deletions src/Packages/Audience/Runtime/Utility/Log.cs
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,20 @@ internal static string IdentityLoadOrGenerateFailed(Exception ex) =>
$"Identity file read/write failed. {ex.GetType().Name}: {ex.Message}. " +
"Events will ship without identity fields this session.";

// ---- Install-time device/context collection ----

internal static string LaunchPropertiesCollectionFailed(Exception ex) =>
$"CollectGameLaunchProperties threw {ex.GetType().Name}: {ex.Message} during Install(). " +
"game_launch will ship without auto-detected Unity context this session.";

internal static string ContextCollectionFailed(Exception ex) =>
$"CollectContext threw {ex.GetType().Name}: {ex.Message} during Install(). " +
"All events will ship without locale/screen/timezone/userAgent this session.";

internal static string ScreenResolutionReadFailed(Exception ex) =>
$"Screen resolution read threw {ex.GetType().Name}: {ex.Message}. " +
"Continuing without a screen field.";

// ---- Steam auto-detection ----

internal static string SteamPlatformDetectionFailed(Exception ex) =>
Expand Down
Loading