From 0e70dc5d60623a3d6af1087736cd925a921260cd Mon Sep 17 00:00:00 2001 From: Nicolas Chaix Date: Mon, 3 Aug 2026 20:02:02 +0200 Subject: [PATCH 1/2] feat: add showWidget and hideWidget events Update the native SDKs to 2.47.0 and expose the new widget events, mirroring didomi/react-native#186. Native SDKs -> 2.47.0 - iosNativeVersion and androidNativeVersion in package.json, which is the single source of truth for both the XCFramework download and the Android dependency injected at build time. Widget events - New ShowWidgetEvent (widgetId, layerName) and HideWidgetEvent classes, exposed as ShowWidget / HideWidget on DidomiEventListener. - Android: showWidget / hideWidget implementations in EventListenerProxy. AndroidJavaProxy requires every method of the Java interface to be implemented, so both are mandatory with the 2.47.0 SDK. - iOS: DDMEventTypeShowWidget / DDMEventTypeHideWidget mapped to the native values 47 and 48. Values 44 to 46 belong to events not exposed in Unity, so the enum is not contiguous here. - iOS showWidget carries two strings, so it uses a dedicated callback like integrationError. hideWidget has no payload and reuses the generic handler. - Events registered in the sample app. Cross-platform naming: the iOS SDK exposes the property as widgetID and Android as widgetId. Both bridges map it to widgetId so a single C# event class fits both platforms, as done in the React Native PR. Verification - Unity 6000.3.5f1 batchmode compile succeeds with no errors; the new types, the add_/remove_ accessors for both events and the new P/Invoke callback are present in the compiled DidomiAssembly.dll. - Didomi.mm passes clang -fsyntax-only against the real 2.47.0 XCFramework headers with no errors or warnings, confirming onShowWidget, onHideWidget and the widgetID property. - EventListenerProxy implements all 46 methods of the 2.47.0 DidomiEventListener Java interface, verified against the published AAR. Not covered by automated tests: end-to-end delivery needs a web-rendered notice that actually serves a widget, and the existing suites are on-device integration tests with no API to trigger one. Same limitation as the React Native and Flutter PRs, so this is worth a manual check against a widget-serving notice before release. --- source/Assets/Plugins/Didomi/IOS/Didomi.mm | 19 ++++++++- .../Plugins/Didomi/Resources/package.json | 4 +- .../Scripts/Android/EventListenerProxy.cs | 32 +++++++++++++++ .../Scripts/Events/DidomiEventListener.cs | 20 ++++++++++ .../Didomi/Scripts/Events/HideWidgetEvent.cs | 8 ++++ .../Scripts/Events/HideWidgetEvent.cs.meta | 11 +++++ .../Didomi/Scripts/Events/ShowWidgetEvent.cs | 40 +++++++++++++++++++ .../Scripts/Events/ShowWidgetEvent.cs.meta | 11 +++++ .../Didomi/Scripts/IOS/DDMEventType.cs | 4 ++ .../Didomi/Scripts/IOS/DidomiFramework.cs | 24 ++++++++++- source/Assets/Scripts/DidomiSample/DemoGUI.cs | 12 ++++++ 11 files changed, 180 insertions(+), 5 deletions(-) create mode 100644 source/Assets/Plugins/Didomi/Scripts/Events/HideWidgetEvent.cs create mode 100644 source/Assets/Plugins/Didomi/Scripts/Events/HideWidgetEvent.cs.meta create mode 100644 source/Assets/Plugins/Didomi/Scripts/Events/ShowWidgetEvent.cs create mode 100644 source/Assets/Plugins/Didomi/Scripts/Events/ShowWidgetEvent.cs.meta diff --git a/source/Assets/Plugins/Didomi/IOS/Didomi.mm b/source/Assets/Plugins/Didomi/IOS/Didomi.mm index 5e44710..6797e64 100644 --- a/source/Assets/Plugins/Didomi/IOS/Didomi.mm +++ b/source/Assets/Plugins/Didomi/IOS/Didomi.mm @@ -834,7 +834,7 @@ void removeSyncAcknowledgedCallback(int eventIndex) { syncAcknowledgedCallbacks[@(eventIndex)] = nil; } -void addEventListener( void (*event_listener_handler) (int, char *), void (*sync_ready_event_listener_handler) (int, char *, int, int), void (*integration_error_event_listener_handler) (int, char *, char *)) +void addEventListener( void (*event_listener_handler) (int, char *), void (*sync_ready_event_listener_handler) (int, char *, int, int), void (*integration_error_event_listener_handler) (int, char *, char *), void (*show_widget_event_listener_handler) (int, char *, char *)) { if(eventListener==nil) @@ -1107,6 +1107,23 @@ void addEventListener( void (*event_listener_handler) (int, char *), void (*sync }; + // The iOS SDK exposes the property as `widgetID` while the Android SDK uses `widgetId`. + // It is mapped to `widgetId` on the C# side so that both platforms share the same event class. + eventListener.onShowWidget = ^(DDMShowWidgetEvent * event){ + + char * widgetId = convertNSStringToCString([event widgetID]); + char * layerName = convertNSStringToCString([event layerName]); + + show_widget_event_listener_handler(DDMEventTypeShowWidget, widgetId, layerName); + + }; + + eventListener.onHideWidget = ^(DDMHideWidgetEvent * event){ + + event_listener_handler(DDMEventTypeHideWidget, NULL); + + }; + [[Didomi shared] addEventListenerWithListener:eventListener]; } diff --git a/source/Assets/Plugins/Didomi/Resources/package.json b/source/Assets/Plugins/Didomi/Resources/package.json index 3828538..b871595 100644 --- a/source/Assets/Plugins/Didomi/Resources/package.json +++ b/source/Assets/Plugins/Didomi/Resources/package.json @@ -3,8 +3,8 @@ "displayName": "Native Didomi", "agentName": "Didomi Unity SDK", "version": "2.28.0", - "iosNativeVersion": "2.46.0", - "androidNativeVersion": "2.46.0", + "iosNativeVersion": "2.47.0", + "androidNativeVersion": "2.47.0", "androidxAppCompatVersion": "1.6.1", "description": "Unity plugin helps you to use native Didomi functionality on Android and iOS." } diff --git a/source/Assets/Plugins/Didomi/Scripts/Android/EventListenerProxy.cs b/source/Assets/Plugins/Didomi/Scripts/Android/EventListenerProxy.cs index 7da60c9..bdd0fae 100644 --- a/source/Assets/Plugins/Didomi/Scripts/Android/EventListenerProxy.cs +++ b/source/Assets/Plugins/Didomi/Scripts/Android/EventListenerProxy.cs @@ -323,6 +323,20 @@ public void integrationError(AndroidJavaObject @event) // An error occurred during integration process } + public void showWidget(AndroidJavaObject @event) + { + var ShowWidgetEvent = ConvertToShowWidgetEvent(@event); + + _eventListener.OnShowWidget(ShowWidgetEvent); + // A widget is being shown + } + + public void hideWidget(AndroidJavaObject @event) + { + _eventListener.OnHideWidget(new HideWidgetEvent()); + // A widget is being hidden + } + private static ErrorEvent ConvertToErrorEvent(AndroidJavaObject @event) { var errorMessage = GetErrorMessage(@event); @@ -455,6 +469,14 @@ private static IntegrationErrorEvent ConvertToIntegrationErrorEvent(AndroidJavaO return new IntegrationErrorEvent(integrationName, reason); } + private static ShowWidgetEvent ConvertToShowWidgetEvent(AndroidJavaObject @event) + { + var widgetId = GetWidgetId(@event); + var layerName = GetLayerName(@event); + + return new ShowWidgetEvent(widgetId, layerName); + } + private static string GetPurposeId(AndroidJavaObject @event) { return AndroidObjectMapper.GetMethodStringValue(@event, "getPurposeId"); @@ -514,5 +536,15 @@ private static string GetIntegrationName(AndroidJavaObject @event) { return AndroidObjectMapper.GetMethodStringValue(@event, "getIntegrationName"); } + + private static string GetWidgetId(AndroidJavaObject @event) + { + return AndroidObjectMapper.GetMethodStringValue(@event, "getWidgetId"); + } + + private static string GetLayerName(AndroidJavaObject @event) + { + return AndroidObjectMapper.GetMethodStringValue(@event, "getLayerName"); + } } } diff --git a/source/Assets/Plugins/Didomi/Scripts/Events/DidomiEventListener.cs b/source/Assets/Plugins/Didomi/Scripts/Events/DidomiEventListener.cs index b2ac956..aec2828 100644 --- a/source/Assets/Plugins/Didomi/Scripts/Events/DidomiEventListener.cs +++ b/source/Assets/Plugins/Didomi/Scripts/Events/DidomiEventListener.cs @@ -190,6 +190,14 @@ public class DidomiEventListener /// An error occurred in the Didomi SDK integration /// public event EventHandler IntegrationError; + /// + /// A widget has been displayed + /// + public event EventHandler ShowWidget; + /// + /// A widget has been hidden + /// + public event EventHandler HideWidget; public DidomiEventListener() { } @@ -454,5 +462,17 @@ public void OnIntegrationError(IntegrationErrorEvent @event) IntegrationError?.Invoke(this, @event); // An error occurred during Didomi SDK integration } + + public void OnShowWidget(ShowWidgetEvent @event) + { + ShowWidget?.Invoke(this, @event); + // A widget is being shown + } + + public void OnHideWidget(HideWidgetEvent @event) + { + HideWidget?.Invoke(this, @event); + // A widget is being hidden + } } } diff --git a/source/Assets/Plugins/Didomi/Scripts/Events/HideWidgetEvent.cs b/source/Assets/Plugins/Didomi/Scripts/Events/HideWidgetEvent.cs new file mode 100644 index 0000000..8f7982b --- /dev/null +++ b/source/Assets/Plugins/Didomi/Scripts/Events/HideWidgetEvent.cs @@ -0,0 +1,8 @@ +namespace IO.Didomi.SDK.Events +{ + /// + /// A widget has been hidden + /// + public class HideWidgetEvent : Event { + } +} diff --git a/source/Assets/Plugins/Didomi/Scripts/Events/HideWidgetEvent.cs.meta b/source/Assets/Plugins/Didomi/Scripts/Events/HideWidgetEvent.cs.meta new file mode 100644 index 0000000..f126c78 --- /dev/null +++ b/source/Assets/Plugins/Didomi/Scripts/Events/HideWidgetEvent.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f552304fd86a4c96b56c2ee56496d87b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/source/Assets/Plugins/Didomi/Scripts/Events/ShowWidgetEvent.cs b/source/Assets/Plugins/Didomi/Scripts/Events/ShowWidgetEvent.cs new file mode 100644 index 0000000..afe7293 --- /dev/null +++ b/source/Assets/Plugins/Didomi/Scripts/Events/ShowWidgetEvent.cs @@ -0,0 +1,40 @@ +namespace IO.Didomi.SDK.Events +{ + /// + /// A widget has been displayed + /// + public class ShowWidgetEvent : Event + { + private string widgetId; + private string layerName; + + public ShowWidgetEvent( + string widgetId, + string layerName + ) + { + this.widgetId = widgetId; + this.layerName = layerName; + } + + /// + /// Identifier of the widget that was displayed, as resolved by the Rules Engine. + /// Null if unknown. + /// + /// + public string getWidgetId() + { + return widgetId; + } + + /// + /// Name of the layer at which the widget was displayed. + /// Null if unknown or default. + /// + /// + public string getLayerName() + { + return layerName; + } + } +} diff --git a/source/Assets/Plugins/Didomi/Scripts/Events/ShowWidgetEvent.cs.meta b/source/Assets/Plugins/Didomi/Scripts/Events/ShowWidgetEvent.cs.meta new file mode 100644 index 0000000..dc88bc6 --- /dev/null +++ b/source/Assets/Plugins/Didomi/Scripts/Events/ShowWidgetEvent.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7a8832ed095b48a89b129ef8916d8fc1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/source/Assets/Plugins/Didomi/Scripts/IOS/DDMEventType.cs b/source/Assets/Plugins/Didomi/Scripts/IOS/DDMEventType.cs index 1ad570a..a73be0c 100644 --- a/source/Assets/Plugins/Didomi/Scripts/IOS/DDMEventType.cs +++ b/source/Assets/Plugins/Didomi/Scripts/IOS/DDMEventType.cs @@ -51,6 +51,10 @@ public enum DDMEventType DDMEventTypeDCSSignatureReady = 41, DDMEventTypeDCSSignatureError = 42, DDMEventTypeIntegrationError = 43, + // Values 44 to 46 are used by events that are not exposed in the Unity SDK + // (ConsentChangedWithObject, OnConsentUIReady, OnConsentUIFinished). + DDMEventTypeShowWidget = 47, + DDMEventTypeHideWidget = 48, DDMEventTypeError = 1000, }; } diff --git a/source/Assets/Plugins/Didomi/Scripts/IOS/DidomiFramework.cs b/source/Assets/Plugins/Didomi/Scripts/IOS/DidomiFramework.cs index 97d83af..72ea630 100644 --- a/source/Assets/Plugins/Didomi/Scripts/IOS/DidomiFramework.cs +++ b/source/Assets/Plugins/Didomi/Scripts/IOS/DidomiFramework.cs @@ -463,9 +463,11 @@ static void CallOnReady() public delegate void OnIntegrationErrorEventListenerDelegate(int eventType, string integrationName, string reason); + public delegate void OnShowWidgetEventListenerDelegate(int eventType, string widgetId, string layerName); + #if (UNITY_IOS || UNITY_TVOS) && !UNITY_EDITOR [DllImport("__Internal")] - private static extern void addEventListener(OnEventListenerDelegate eventListenerDelegate, OnSyncReadyEventListenerDelegate syncReadyEventListenerDelegate, OnIntegrationErrorEventListenerDelegate integrationErrorEventListenerDelegate); + private static extern void addEventListener(OnEventListenerDelegate eventListenerDelegate, OnSyncReadyEventListenerDelegate syncReadyEventListenerDelegate, OnIntegrationErrorEventListenerDelegate integrationErrorEventListenerDelegate, OnShowWidgetEventListenerDelegate showWidgetEventListenerDelegate); [DllImport("__Internal")] private static extern int syncAcknowledgedCallback(int callbackIndex); @@ -478,7 +480,7 @@ public static void AddEventListener(DidomiEventListener eventListener) { eventListenerInner = eventListener; #if (UNITY_IOS || UNITY_TVOS) && !UNITY_EDITOR - addEventListener(CallOnEventListenerDelegate, CallOnSyncReadyEventListenerDelegate, CallOnIntegrationErrorEventListenerDelegate); + addEventListener(CallOnEventListenerDelegate, CallOnSyncReadyEventListenerDelegate, CallOnIntegrationErrorEventListenerDelegate, CallOnShowWidgetEventListenerDelegate); #endif } @@ -616,6 +618,9 @@ static void CallOnEventListenerDelegate(int eventType, string argument) case DDMEventType.DDMEventTypeDCSSignatureReady: eventListenerInner.OnDcsSignatureReady(new DcsSignatureReadyEvent()); break; + case DDMEventType.DDMEventTypeHideWidget: + eventListenerInner.OnHideWidget(new HideWidgetEvent()); + break; default: break; } @@ -663,6 +668,21 @@ static void CallOnIntegrationErrorEventListenerDelegate(int eventType, string in } } + [AOT.MonoPInvokeCallback(typeof(OnShowWidgetEventListenerDelegate))] + static void CallOnShowWidgetEventListenerDelegate(int eventType, string widgetId, string layerName) + { + DDMEventType eventTypeEnum = (DDMEventType)eventType; + switch (eventTypeEnum) + { + case DDMEventType.DDMEventTypeShowWidget: + eventListenerInner.OnShowWidget(new ShowWidgetEvent( + widgetId, + layerName + )); + break; + } + } + public delegate void OnVendorStatusListenerDelegate(string vendorStatus); #if (UNITY_IOS || UNITY_TVOS) && !UNITY_EDITOR diff --git a/source/Assets/Scripts/DidomiSample/DemoGUI.cs b/source/Assets/Scripts/DidomiSample/DemoGUI.cs index 1919645..ce502e4 100644 --- a/source/Assets/Scripts/DidomiSample/DemoGUI.cs +++ b/source/Assets/Scripts/DidomiSample/DemoGUI.cs @@ -792,6 +792,8 @@ private void RegisterEventHandlers() eventListener.SyncError += EventListener_SyncError; eventListener.LanguageUpdated += EventListener_LanguageUpdated; eventListener.LanguageUpdateFailed += EventListener_LanguageUpdateFailed; + eventListener.ShowWidget += EventListener_ShowWidget; + eventListener.HideWidget += EventListener_HideWidget; Didomi.GetInstance().AddEventListener(eventListener); } @@ -958,6 +960,16 @@ private void EventListener_LanguageUpdateFailed(object sender, LanguageUpdateFai message += "\nEvent: LanguageUpdateFailed, Reason=" + e.getReason(); } + private void EventListener_ShowWidget(object sender, ShowWidgetEvent e) + { + message += "\nEvent: ShowWidget, WidgetId=" + e.getWidgetId() + ", LayerName=" + e.getLayerName(); + } + + private void EventListener_HideWidget(object sender, HideWidgetEvent e) + { + message += "\nEvent: HideWidget"; + } + private void VendorStatusListener_VendorStatusChanged(object sender, CurrentUserStatus.VendorStatus status) { message += "\nEvent: VendorStatusChanged, VendorId=" + status.Id + ", Enabled=" + status.Enabled; From 796f6d0acd9f497f63223d7f023738d721c789d7 Mon Sep 17 00:00:00 2001 From: Nicolas Chaix Date: Mon, 3 Aug 2026 20:09:18 +0200 Subject: [PATCH 2/2] increment bridge version --- source/Assets/Plugins/Didomi/Resources/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/Assets/Plugins/Didomi/Resources/package.json b/source/Assets/Plugins/Didomi/Resources/package.json index b871595..9167c6e 100644 --- a/source/Assets/Plugins/Didomi/Resources/package.json +++ b/source/Assets/Plugins/Didomi/Resources/package.json @@ -2,7 +2,7 @@ "name": "com.didomi.unityplugin", "displayName": "Native Didomi", "agentName": "Didomi Unity SDK", - "version": "2.28.0", + "version": "2.29.0", "iosNativeVersion": "2.47.0", "androidNativeVersion": "2.47.0", "androidxAppCompatVersion": "1.6.1",