MaxCmpService.cs 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. //
  2. // MaxCmpService.cs
  3. // AppLovin User Engagement Unity Plugin
  4. //
  5. // Created by Santosh Bagadi on 10/1/23.
  6. // Copyright © 2023 AppLovin. All rights reserved.
  7. //
  8. using System;
  9. using System.Collections.Generic;
  10. #if UNITY_EDITOR
  11. #elif UNITY_ANDROID
  12. using UnityEngine;
  13. #elif UNITY_IOS
  14. using System.Runtime.InteropServices;
  15. #endif
  16. /// <summary>
  17. /// This class provides direct APIs for interfacing with the Google-certified CMP installed, if any.
  18. /// </summary>
  19. public class MaxCmpService
  20. {
  21. private static readonly MaxCmpService _instance = new MaxCmpService();
  22. private MaxCmpService() { }
  23. private static Action<MaxCmpError> _onCompletedAction;
  24. #if UNITY_EDITOR
  25. #elif UNITY_ANDROID
  26. private static readonly AndroidJavaClass MaxUnityPluginClass = new AndroidJavaClass("com.applovin.mediation.unity.MaxUnityPlugin");
  27. #elif UNITY_IOS
  28. [DllImport("__Internal")]
  29. private static extern void _MaxShowCmpForExistingUser();
  30. [DllImport("__Internal")]
  31. private static extern bool _MaxHasSupportedCmp();
  32. #endif
  33. internal static MaxCmpService Instance
  34. {
  35. get { return _instance; }
  36. }
  37. /// <summary>
  38. /// Shows the CMP flow to an existing user.
  39. /// Note that the user's current consent will be reset before the CMP alert is shown.
  40. /// </summary>
  41. /// <param name="onCompletedAction">Called when the CMP flow finishes showing.</param>
  42. public void ShowCmpForExistingUser(Action<MaxCmpError> onCompletedAction)
  43. {
  44. _onCompletedAction = onCompletedAction;
  45. #if UNITY_EDITOR
  46. var errorProps = new Dictionary<string, object>
  47. {
  48. {"code", (int) MaxCmpError.ErrorCode.FormUnavailable},
  49. {"message", "CMP is not supported in Unity editor"}
  50. };
  51. NotifyCompletedIfNeeded(errorProps);
  52. #elif UNITY_ANDROID
  53. MaxUnityPluginClass.CallStatic("showCmpForExistingUser");
  54. #elif UNITY_IOS
  55. _MaxShowCmpForExistingUser();
  56. #endif
  57. }
  58. /// <summary>
  59. /// Returns <code>true</code> if a supported CMP SDK is detected.
  60. /// </summary>
  61. public bool HasSupportedCmp
  62. {
  63. get
  64. {
  65. #if UNITY_EDITOR
  66. return false;
  67. #elif UNITY_ANDROID
  68. return MaxUnityPluginClass.CallStatic<bool>("hasSupportedCmp");
  69. #elif UNITY_IOS
  70. return _MaxHasSupportedCmp();
  71. #else
  72. return false;
  73. #endif
  74. }
  75. }
  76. internal static void NotifyCompletedIfNeeded(Dictionary<string, object> errorProps)
  77. {
  78. if (_onCompletedAction == null) return;
  79. var error = (errorProps == null) ? null : MaxCmpError.Create(errorProps);
  80. _onCompletedAction(error);
  81. }
  82. }
  83. public class MaxCmpError
  84. {
  85. public enum ErrorCode
  86. {
  87. /// <summary>
  88. /// Indicates that an unspecified error has occurred.
  89. /// </summary>
  90. Unspecified = -1,
  91. /// <summary>
  92. /// Indicates that the CMP has not been integrated correctly.
  93. /// </summary>
  94. IntegrationError = 1,
  95. /// <summary>
  96. /// Indicates that the CMP form is unavailable.
  97. /// </summary>
  98. FormUnavailable = 2,
  99. /// <summary>
  100. /// Indicates that the CMP form is not required.
  101. /// </summary>
  102. FormNotRequired = 3
  103. }
  104. public static MaxCmpError Create(IDictionary<string, object> error)
  105. {
  106. return new MaxCmpError()
  107. {
  108. Code = GetCode(MaxSdkUtils.GetIntFromDictionary(error, "code")),
  109. Message = MaxSdkUtils.GetStringFromDictionary(error, "message"),
  110. CmpCode = MaxSdkUtils.GetIntFromDictionary(error, "cmpCode", -1),
  111. CmpMessage = MaxSdkUtils.GetStringFromDictionary(error, "cmpMessage")
  112. };
  113. }
  114. private static ErrorCode GetCode(int code)
  115. {
  116. switch (code)
  117. {
  118. case 1:
  119. return ErrorCode.IntegrationError;
  120. case 2:
  121. return ErrorCode.FormUnavailable;
  122. case 3:
  123. return ErrorCode.FormNotRequired;
  124. default:
  125. return ErrorCode.Unspecified;
  126. }
  127. }
  128. private MaxCmpError() { }
  129. /// <summary>
  130. /// The error code for this error.
  131. /// </summary>
  132. public ErrorCode Code { get; private set; }
  133. /// <summary>
  134. /// The error message for this error.
  135. /// </summary>
  136. public string Message { get; private set; }
  137. /// <summary>
  138. /// The error code returned by the CMP.
  139. /// </summary>
  140. public int CmpCode { get; private set; }
  141. /// <summary>
  142. /// The error message returned by the CMP.
  143. /// </summary>
  144. public string CmpMessage { get; private set; }
  145. }