MaxSdkBase.cs 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Globalization;
  5. using System.Linq;
  6. using System.Text;
  7. using AppLovinMax.ThirdParty.MiniJson;
  8. using AppLovinMax.Internal;
  9. using UnityEngine;
  10. #if UNITY_IOS && !UNITY_EDITOR
  11. using System.Runtime.InteropServices;
  12. #endif
  13. public abstract class MaxSdkBase
  14. {
  15. /// <summary>
  16. /// This enum represents the user's geography used to determine the type of consent flow shown to the user.
  17. /// </summary>
  18. public enum ConsentFlowUserGeography
  19. {
  20. /// <summary>
  21. /// User's geography is unknown.
  22. /// </summary>
  23. Unknown,
  24. /// <summary>
  25. /// The user is in GDPR region.
  26. /// </summary>
  27. Gdpr,
  28. /// <summary>
  29. /// The user is in a non-GDPR region.
  30. /// </summary>
  31. Other
  32. }
  33. #if UNITY_EDITOR || UNITY_IPHONE || UNITY_IOS
  34. /// <summary>
  35. /// App tracking status values. Primarily used in conjunction with iOS14's AppTrackingTransparency.framework.
  36. /// </summary>
  37. public enum AppTrackingStatus
  38. {
  39. /// <summary>
  40. /// Device is on &lt; iOS14, AppTrackingTransparency.framework is not available.
  41. /// </summary>
  42. Unavailable,
  43. /// <summary>
  44. /// The value returned if a user has not yet received an authorization request to authorize access to app-related data that can be used for tracking the user or the device.
  45. /// </summary>
  46. NotDetermined,
  47. /// <summary>
  48. /// The value returned if authorization to access app-related data that can be used for tracking the user or the device is restricted.
  49. /// </summary>
  50. Restricted,
  51. /// <summary>
  52. /// The value returned if the user denies authorization to access app-related data that can be used for tracking the user or the device.
  53. /// </summary>
  54. Denied,
  55. /// <summary>
  56. /// The value returned if the user authorizes access to app-related data that can be used for tracking the user or the device.
  57. /// </summary>
  58. Authorized,
  59. }
  60. #endif
  61. /// <summary>
  62. /// An enum describing the adapter's initialization status.
  63. /// </summary>
  64. public enum InitializationStatus
  65. {
  66. /// <summary>
  67. /// The adapter is not initialized. Note: networks need to be enabled for an ad unit id to be initialized.
  68. /// </summary>
  69. NotInitialized = -4,
  70. /// <summary>
  71. /// The 3rd-party SDK does not have an initialization callback with status.
  72. /// </summary>
  73. DoesNotApply = -3,
  74. /// <summary>
  75. /// The 3rd-party SDK is currently initializing.
  76. /// </summary>
  77. Initializing = -2,
  78. /// <summary>
  79. /// The 3rd-party SDK explicitly initialized, but without a status.
  80. /// </summary>
  81. InitializedUnknown = -1,
  82. /// <summary>
  83. /// The 3rd-party SDK initialization failed.
  84. /// </summary>
  85. InitializedFailure = 0,
  86. /// <summary>
  87. /// The 3rd-party SDK initialization was successful.
  88. /// </summary>
  89. InitializedSuccess = 1
  90. }
  91. public enum AdViewPosition
  92. {
  93. TopLeft,
  94. TopCenter,
  95. TopRight,
  96. Centered,
  97. CenterLeft,
  98. CenterRight,
  99. BottomLeft,
  100. BottomCenter,
  101. BottomRight
  102. }
  103. public enum BannerPosition
  104. {
  105. TopLeft,
  106. TopCenter,
  107. TopRight,
  108. Centered,
  109. CenterLeft,
  110. CenterRight,
  111. BottomLeft,
  112. BottomCenter,
  113. BottomRight
  114. }
  115. public class SdkConfiguration
  116. {
  117. /// <summary>
  118. /// Whether or not the SDK has been initialized successfully.
  119. /// </summary>
  120. public bool IsSuccessfullyInitialized { get; private set; }
  121. /// <summary>
  122. /// Get the country code for this user.
  123. /// </summary>
  124. public string CountryCode { get; private set; }
  125. #if UNITY_EDITOR || UNITY_IPHONE || UNITY_IOS
  126. /// <summary>
  127. /// App tracking status values. Primarily used in conjunction with iOS14's AppTrackingTransparency.framework.
  128. /// </summary>
  129. public AppTrackingStatus AppTrackingStatus { get; private set; }
  130. #endif
  131. public bool IsTestModeEnabled { get; private set; }
  132. /// <summary>
  133. /// Get the user's geography used to determine the type of consent flow shown to the user.
  134. /// If no such determination could be made, <see cref="MaxSdkBase.ConsentFlowUserGeography.Unknown"/> will be returned.
  135. /// </summary>
  136. public ConsentFlowUserGeography ConsentFlowUserGeography { get; private set; }
  137. [Obsolete("This API has been deprecated and will be removed in a future release.")]
  138. public ConsentDialogState ConsentDialogState { get; private set; }
  139. #if UNITY_EDITOR || !(UNITY_ANDROID || UNITY_IPHONE || UNITY_IOS)
  140. public static SdkConfiguration CreateEmpty()
  141. {
  142. var sdkConfiguration = new SdkConfiguration();
  143. sdkConfiguration.IsSuccessfullyInitialized = true;
  144. #pragma warning disable 0618
  145. sdkConfiguration.ConsentDialogState = ConsentDialogState.Unknown;
  146. #pragma warning restore 0618
  147. #if UNITY_EDITOR
  148. sdkConfiguration.AppTrackingStatus = AppTrackingStatus.Authorized;
  149. #endif
  150. sdkConfiguration.CountryCode = TryGetCountryCode();
  151. sdkConfiguration.IsTestModeEnabled = false;
  152. return sdkConfiguration;
  153. }
  154. private static string TryGetCountryCode()
  155. {
  156. try
  157. {
  158. return RegionInfo.CurrentRegion.TwoLetterISORegionName;
  159. }
  160. #pragma warning disable 0168
  161. catch (Exception ignored)
  162. #pragma warning restore 0168
  163. {
  164. // Ignored
  165. }
  166. return "US";
  167. }
  168. #endif
  169. public static SdkConfiguration Create(IDictionary<string, object> eventProps)
  170. {
  171. var sdkConfiguration = new SdkConfiguration();
  172. sdkConfiguration.IsSuccessfullyInitialized = MaxSdkUtils.GetBoolFromDictionary(eventProps, "isSuccessfullyInitialized");
  173. sdkConfiguration.CountryCode = MaxSdkUtils.GetStringFromDictionary(eventProps, "countryCode", "");
  174. sdkConfiguration.IsTestModeEnabled = MaxSdkUtils.GetBoolFromDictionary(eventProps, "isTestModeEnabled");
  175. var consentFlowUserGeographyStr = MaxSdkUtils.GetStringFromDictionary(eventProps, "consentFlowUserGeography", "");
  176. if ("1".Equals(consentFlowUserGeographyStr))
  177. {
  178. sdkConfiguration.ConsentFlowUserGeography = ConsentFlowUserGeography.Gdpr;
  179. }
  180. else if ("2".Equals(consentFlowUserGeographyStr))
  181. {
  182. sdkConfiguration.ConsentFlowUserGeography = ConsentFlowUserGeography.Other;
  183. }
  184. else
  185. {
  186. sdkConfiguration.ConsentFlowUserGeography = ConsentFlowUserGeography.Unknown;
  187. }
  188. #pragma warning disable 0618
  189. var consentDialogStateStr = MaxSdkUtils.GetStringFromDictionary(eventProps, "consentDialogState", "");
  190. if ("1".Equals(consentDialogStateStr))
  191. {
  192. sdkConfiguration.ConsentDialogState = ConsentDialogState.Applies;
  193. }
  194. else if ("2".Equals(consentDialogStateStr))
  195. {
  196. sdkConfiguration.ConsentDialogState = ConsentDialogState.DoesNotApply;
  197. }
  198. else
  199. {
  200. sdkConfiguration.ConsentDialogState = ConsentDialogState.Unknown;
  201. }
  202. #pragma warning restore 0618
  203. #if UNITY_IPHONE || UNITY_IOS
  204. var appTrackingStatusStr = MaxSdkUtils.GetStringFromDictionary(eventProps, "appTrackingStatus", "-1");
  205. if ("-1".Equals(appTrackingStatusStr))
  206. {
  207. sdkConfiguration.AppTrackingStatus = AppTrackingStatus.Unavailable;
  208. }
  209. else if ("0".Equals(appTrackingStatusStr))
  210. {
  211. sdkConfiguration.AppTrackingStatus = AppTrackingStatus.NotDetermined;
  212. }
  213. else if ("1".Equals(appTrackingStatusStr))
  214. {
  215. sdkConfiguration.AppTrackingStatus = AppTrackingStatus.Restricted;
  216. }
  217. else if ("2".Equals(appTrackingStatusStr))
  218. {
  219. sdkConfiguration.AppTrackingStatus = AppTrackingStatus.Denied;
  220. }
  221. else // "3" is authorized
  222. {
  223. sdkConfiguration.AppTrackingStatus = AppTrackingStatus.Authorized;
  224. }
  225. #endif
  226. return sdkConfiguration;
  227. }
  228. }
  229. public struct Reward
  230. {
  231. public string Label;
  232. public int Amount;
  233. public override string ToString()
  234. {
  235. return "Reward: " + Amount + " " + Label;
  236. }
  237. public bool IsValid()
  238. {
  239. return !string.IsNullOrEmpty(Label) && Amount > 0;
  240. }
  241. }
  242. /**
  243. * This enum contains various error codes that the SDK can return when a MAX ad fails to load or display.
  244. */
  245. public enum ErrorCode
  246. {
  247. /// <summary>
  248. /// This error code represents an error that could not be categorized into one of the other defined errors. See the message field in the error object for more details.
  249. /// </summary>
  250. Unspecified = -1,
  251. /// <summary>
  252. /// This error code indicates that MAX returned no eligible ads from any mediated networks for this app/device.
  253. /// </summary>
  254. NoFill = 204,
  255. /// <summary>
  256. /// This error code indicates that MAX returned eligible ads from mediated networks, but all ads failed to load. See the adLoadFailureInfo field in the error object for more details.
  257. /// </summary>
  258. AdLoadFailed = -5001,
  259. /// <summary>
  260. /// This error code represents an error that was encountered when showing an ad.
  261. /// </summary>
  262. AdDisplayFailed = -4205,
  263. /// <summary>
  264. /// This error code indicates that the ad request failed due to a generic network error. See the message field in the error object for more details.
  265. /// </summary>
  266. NetworkError = -1000,
  267. /// <summary>
  268. /// This error code indicates that the ad request timed out due to a slow internet connection.
  269. /// </summary>
  270. NetworkTimeout = -1001,
  271. /// <summary>
  272. /// This error code indicates that the ad request failed because the device is not connected to the internet.
  273. /// </summary>
  274. NoNetwork = -1009,
  275. /// <summary>
  276. /// This error code indicates that you attempted to show a fullscreen ad while another fullscreen ad is still showing.
  277. /// </summary>
  278. FullscreenAdAlreadyShowing = -23,
  279. /// <summary>
  280. /// This error code indicates you are attempting to show a fullscreen ad before the one has been loaded.
  281. /// </summary>
  282. FullscreenAdNotReady = -24,
  283. #if UNITY_IOS || UNITY_IPHONE
  284. /// <summary>
  285. /// This error code indicates you attempted to present a fullscreen ad from an invalid view controller.
  286. /// </summary>
  287. FullscreenAdInvalidViewController = -25,
  288. #endif
  289. /// <summary>
  290. /// This error code indicates you are attempting to load a fullscreen ad while another fullscreen ad is already loading.
  291. /// </summary>
  292. FullscreenAdAlreadyLoading = -26,
  293. /// <summary>
  294. /// This error code indicates you are attempting to load a fullscreen ad while another fullscreen ad is still showing.
  295. /// </summary>
  296. FullscreenAdLoadWhileShowing = -27,
  297. #if UNITY_ANDROID
  298. /// <summary>
  299. /// This error code indicates that the SDK failed to display an ad because the user has the "Don't Keep Activities" developer setting enabled.
  300. /// </summary>
  301. DontKeepActivitiesEnabled = -5602,
  302. #endif
  303. /// <summary>
  304. /// This error code indicates that the SDK failed to load an ad because the publisher provided an invalid ad unit identifier.
  305. /// Possible reasons for an invalid ad unit identifier:
  306. /// 1. Ad unit identifier is malformed or does not exist
  307. /// 2. Ad unit is disabled
  308. /// 3. Ad unit is not associated with the current app's package name
  309. /// 4. Ad unit was created within the last 30-60 minutes
  310. /// </summary>
  311. InvalidAdUnitId = -5603
  312. }
  313. /**
  314. * This enum contains possible states of an ad in the waterfall the adapter response info could represent.
  315. */
  316. public enum MaxAdLoadState
  317. {
  318. /// <summary>
  319. /// The AppLovin Max SDK did not attempt to load an ad from this network in the waterfall because an ad higher
  320. /// in the waterfall loaded successfully.
  321. /// </summary>
  322. AdLoadNotAttempted,
  323. /// <summary>
  324. /// An ad successfully loaded from this network.
  325. /// </summary>
  326. AdLoaded,
  327. /// <summary>
  328. /// An ad failed to load from this network.
  329. /// </summary>
  330. FailedToLoad
  331. }
  332. public class AdInfo
  333. {
  334. public string AdUnitIdentifier { get; private set; }
  335. public string AdFormat { get; private set; }
  336. public string NetworkName { get; private set; }
  337. public string NetworkPlacement { get; private set; }
  338. public string Placement { get; private set; }
  339. public string CreativeIdentifier { get; private set; }
  340. public double Revenue { get; private set; }
  341. public string RevenuePrecision { get; private set; }
  342. public WaterfallInfo WaterfallInfo { get; private set; }
  343. public long LatencyMillis { get; private set; }
  344. public string DspName { get; private set; }
  345. public AdInfo(IDictionary<string, object> adInfoDictionary)
  346. {
  347. AdUnitIdentifier = MaxSdkUtils.GetStringFromDictionary(adInfoDictionary, "adUnitId");
  348. AdFormat = MaxSdkUtils.GetStringFromDictionary(adInfoDictionary, "adFormat");
  349. NetworkName = MaxSdkUtils.GetStringFromDictionary(adInfoDictionary, "networkName");
  350. NetworkPlacement = MaxSdkUtils.GetStringFromDictionary(adInfoDictionary, "networkPlacement");
  351. CreativeIdentifier = MaxSdkUtils.GetStringFromDictionary(adInfoDictionary, "creativeId");
  352. Placement = MaxSdkUtils.GetStringFromDictionary(adInfoDictionary, "placement");
  353. Revenue = MaxSdkUtils.GetDoubleFromDictionary(adInfoDictionary, "revenue", -1);
  354. RevenuePrecision = MaxSdkUtils.GetStringFromDictionary(adInfoDictionary, "revenuePrecision");
  355. WaterfallInfo = new WaterfallInfo(MaxSdkUtils.GetDictionaryFromDictionary(adInfoDictionary, "waterfallInfo", new Dictionary<string, object>()));
  356. LatencyMillis = MaxSdkUtils.GetLongFromDictionary(adInfoDictionary, "latencyMillis");
  357. DspName = MaxSdkUtils.GetStringFromDictionary(adInfoDictionary, "dspName");
  358. }
  359. public override string ToString()
  360. {
  361. return "[AdInfo adUnitIdentifier: " + AdUnitIdentifier +
  362. ", adFormat: " + AdFormat +
  363. ", networkName: " + NetworkName +
  364. ", networkPlacement: " + NetworkPlacement +
  365. ", creativeIdentifier: " + CreativeIdentifier +
  366. ", placement: " + Placement +
  367. ", revenue: " + Revenue +
  368. ", revenuePrecision: " + RevenuePrecision +
  369. ", latency: " + LatencyMillis +
  370. ", dspName: " + DspName + "]";
  371. }
  372. }
  373. /// <summary>
  374. /// Returns information about the ad response in a waterfall.
  375. /// </summary>
  376. public class WaterfallInfo
  377. {
  378. public String Name { get; private set; }
  379. public String TestName { get; private set; }
  380. public List<NetworkResponseInfo> NetworkResponses { get; private set; }
  381. public long LatencyMillis { get; private set; }
  382. public WaterfallInfo(IDictionary<string, object> waterfallInfoDict)
  383. {
  384. Name = MaxSdkUtils.GetStringFromDictionary(waterfallInfoDict, "name");
  385. TestName = MaxSdkUtils.GetStringFromDictionary(waterfallInfoDict, "testName");
  386. var networkResponsesList = MaxSdkUtils.GetListFromDictionary(waterfallInfoDict, "networkResponses", new List<object>());
  387. NetworkResponses = new List<NetworkResponseInfo>();
  388. foreach (var networkResponseObject in networkResponsesList)
  389. {
  390. var networkResponseDict = networkResponseObject as Dictionary<string, object>;
  391. if (networkResponseDict == null) continue;
  392. var networkResponse = new NetworkResponseInfo(networkResponseDict);
  393. NetworkResponses.Add(networkResponse);
  394. }
  395. LatencyMillis = MaxSdkUtils.GetLongFromDictionary(waterfallInfoDict, "latencyMillis");
  396. }
  397. public override string ToString()
  398. {
  399. return "[MediatedNetworkInfo: name = " + Name +
  400. ", testName = " + TestName +
  401. ", latency = " + LatencyMillis +
  402. ", networkResponse = " + string.Join(", ", NetworkResponses.Select(networkResponseInfo => networkResponseInfo.ToString()).ToArray()) + "]";
  403. }
  404. }
  405. public class NetworkResponseInfo
  406. {
  407. public MaxAdLoadState AdLoadState { get; private set; }
  408. public MediatedNetworkInfo MediatedNetwork { get; private set; }
  409. public Dictionary<string, object> Credentials { get; private set; }
  410. public bool IsBidding { get; private set; }
  411. public long LatencyMillis { get; private set; }
  412. public ErrorInfo Error { get; private set; }
  413. public NetworkResponseInfo(IDictionary<string, object> networkResponseInfoDict)
  414. {
  415. var mediatedNetworkInfoDict = MaxSdkUtils.GetDictionaryFromDictionary(networkResponseInfoDict, "mediatedNetwork");
  416. MediatedNetwork = mediatedNetworkInfoDict != null ? new MediatedNetworkInfo(mediatedNetworkInfoDict) : null;
  417. Credentials = MaxSdkUtils.GetDictionaryFromDictionary(networkResponseInfoDict, "credentials", new Dictionary<string, object>());
  418. IsBidding = MaxSdkUtils.GetBoolFromDictionary(networkResponseInfoDict, "isBidding");
  419. LatencyMillis = MaxSdkUtils.GetLongFromDictionary(networkResponseInfoDict, "latencyMillis");
  420. AdLoadState = (MaxAdLoadState) MaxSdkUtils.GetIntFromDictionary(networkResponseInfoDict, "adLoadState");
  421. var errorInfoDict = MaxSdkUtils.GetDictionaryFromDictionary(networkResponseInfoDict, "error");
  422. Error = errorInfoDict != null ? new ErrorInfo(errorInfoDict) : null;
  423. }
  424. public override string ToString()
  425. {
  426. var stringBuilder = new StringBuilder("[NetworkResponseInfo: adLoadState = ").Append(AdLoadState);
  427. stringBuilder.Append(", mediatedNetwork = ").Append(MediatedNetwork);
  428. stringBuilder.Append(", credentials = ").Append(string.Join(", ", Credentials.Select(keyValuePair => keyValuePair.ToString()).ToArray()));
  429. switch (AdLoadState)
  430. {
  431. case MaxAdLoadState.FailedToLoad:
  432. stringBuilder.Append(", error = ").Append(Error);
  433. break;
  434. case MaxAdLoadState.AdLoaded:
  435. stringBuilder.Append(", latency = ").Append(LatencyMillis);
  436. break;
  437. }
  438. return stringBuilder.Append("]").ToString();
  439. }
  440. }
  441. public class MediatedNetworkInfo
  442. {
  443. public string Name { get; private set; }
  444. public string AdapterClassName { get; private set; }
  445. public string AdapterVersion { get; private set; }
  446. public string SdkVersion { get; private set; }
  447. public InitializationStatus InitializationStatus { get; private set; }
  448. public MediatedNetworkInfo(IDictionary<string, object> mediatedNetworkDictionary)
  449. {
  450. // NOTE: Unity Editor creates empty string
  451. Name = MaxSdkUtils.GetStringFromDictionary(mediatedNetworkDictionary, "name", "");
  452. AdapterClassName = MaxSdkUtils.GetStringFromDictionary(mediatedNetworkDictionary, "adapterClassName", "");
  453. AdapterVersion = MaxSdkUtils.GetStringFromDictionary(mediatedNetworkDictionary, "adapterVersion", "");
  454. SdkVersion = MaxSdkUtils.GetStringFromDictionary(mediatedNetworkDictionary, "sdkVersion", "");
  455. var initializationStatusInt = MaxSdkUtils.GetIntFromDictionary(mediatedNetworkDictionary, "initializationStatus", (int) InitializationStatus.NotInitialized);
  456. InitializationStatus = InitializationStatusFromCode(initializationStatusInt);
  457. }
  458. public override string ToString()
  459. {
  460. return "[MediatedNetworkInfo name: " + Name +
  461. ", adapterClassName: " + AdapterClassName +
  462. ", adapterVersion: " + AdapterVersion +
  463. ", sdkVersion: " + SdkVersion +
  464. ", initializationStatus: " + InitializationStatus + "]";
  465. }
  466. private static InitializationStatus InitializationStatusFromCode(int code)
  467. {
  468. if (Enum.IsDefined(typeof(InitializationStatus), code))
  469. {
  470. return (InitializationStatus) code;
  471. }
  472. else
  473. {
  474. return InitializationStatus.NotInitialized;
  475. }
  476. }
  477. }
  478. public class ErrorInfo
  479. {
  480. public ErrorCode Code { get; private set; }
  481. public string Message { get; private set; }
  482. public int MediatedNetworkErrorCode { get; private set; }
  483. public string MediatedNetworkErrorMessage { get; private set; }
  484. public string AdLoadFailureInfo { get; private set; }
  485. public WaterfallInfo WaterfallInfo { get; private set; }
  486. public long LatencyMillis { get; private set; }
  487. public ErrorInfo(IDictionary<string, object> errorInfoDictionary)
  488. {
  489. Code = (ErrorCode) MaxSdkUtils.GetIntFromDictionary(errorInfoDictionary, "errorCode", -1);
  490. Message = MaxSdkUtils.GetStringFromDictionary(errorInfoDictionary, "errorMessage", "");
  491. MediatedNetworkErrorCode = MaxSdkUtils.GetIntFromDictionary(errorInfoDictionary, "mediatedNetworkErrorCode", (int) ErrorCode.Unspecified);
  492. MediatedNetworkErrorMessage = MaxSdkUtils.GetStringFromDictionary(errorInfoDictionary, "mediatedNetworkErrorMessage", "");
  493. AdLoadFailureInfo = MaxSdkUtils.GetStringFromDictionary(errorInfoDictionary, "adLoadFailureInfo", "");
  494. WaterfallInfo = new WaterfallInfo(MaxSdkUtils.GetDictionaryFromDictionary(errorInfoDictionary, "waterfallInfo", new Dictionary<string, object>()));
  495. LatencyMillis = MaxSdkUtils.GetLongFromDictionary(errorInfoDictionary, "latencyMillis");
  496. }
  497. public override string ToString()
  498. {
  499. var stringbuilder = new StringBuilder("[ErrorInfo code: ").Append(Code);
  500. stringbuilder.Append(", message: ").Append(Message);
  501. if (Code == ErrorCode.AdDisplayFailed)
  502. {
  503. stringbuilder.Append(", mediatedNetworkCode: ").Append(MediatedNetworkErrorCode);
  504. stringbuilder.Append(", mediatedNetworkMessage: ").Append(MediatedNetworkErrorMessage);
  505. }
  506. stringbuilder.Append(", latency: ").Append(LatencyMillis);
  507. return stringbuilder.Append(", adLoadFailureInfo: ").Append(AdLoadFailureInfo).Append("]").ToString();
  508. }
  509. }
  510. /// <summary>
  511. /// Inset values for the safe area on the screen used to render banner ads.
  512. /// </summary>
  513. public class SafeAreaInsets
  514. {
  515. public int Left { get; private set; }
  516. public int Top { get; private set; }
  517. public int Right { get; private set; }
  518. public int Bottom { get; private set; }
  519. /// <summary>
  520. /// Creates a new instance of <see cref="SafeAreaInsets"/>.
  521. /// </summary>
  522. /// <param name="insets">An integer array with insets values in the order of left, top, right, and bottom</param>
  523. internal SafeAreaInsets(int[] insets)
  524. {
  525. Left = insets[0];
  526. Top = insets[1];
  527. Right = insets[2];
  528. Bottom = insets[3];
  529. }
  530. public override string ToString()
  531. {
  532. return "[SafeAreaInsets: Left: " + Left +
  533. ", Top: " + Top +
  534. ", Right: " + Right +
  535. ", Bottom: " + Bottom + "]";
  536. }
  537. }
  538. /// <summary>
  539. /// Determines whether ad events raised by the AppLovin's Unity plugin should be invoked on the Unity main thread.
  540. /// </summary>
  541. public static bool? InvokeEventsOnUnityMainThread { get; set; }
  542. /// <summary>
  543. /// The CMP service, which provides direct APIs for interfacing with the Google-certified CMP installed, if any.
  544. /// </summary>
  545. public static MaxCmpService CmpService
  546. {
  547. get { return MaxCmpService.Instance; }
  548. }
  549. internal static bool DisableAllLogs
  550. {
  551. get; private set;
  552. }
  553. protected static void ValidateAdUnitIdentifier(string adUnitIdentifier, string debugPurpose)
  554. {
  555. if (string.IsNullOrEmpty(adUnitIdentifier))
  556. {
  557. MaxSdkLogger.UserError("No MAX Ads Ad Unit ID specified for: " + debugPurpose);
  558. }
  559. }
  560. // Allocate the MaxEventExecutor singleton which handles pushing callbacks from the background to the main thread.
  561. protected static void InitializeEventExecutor()
  562. {
  563. MaxEventExecutor.InitializeIfNeeded();
  564. }
  565. /// <summary>
  566. /// Generates serialized Unity meta data to be passed to the SDK.
  567. /// </summary>
  568. /// <returns>Serialized Unity meta data.</returns>
  569. protected static string GenerateMetaData()
  570. {
  571. var metaData = new Dictionary<string, string>(2);
  572. metaData.Add("UnityVersion", Application.unityVersion);
  573. return Json.Serialize(metaData);
  574. }
  575. /// <summary>
  576. /// Parses the prop string provided to a <see cref="Rect"/>.
  577. /// </summary>
  578. /// <param name="rectPropString">A prop string representing a Rect</param>
  579. /// <returns>A <see cref="Rect"/> the prop string represents.</returns>
  580. protected static Rect GetRectFromString(string rectPropString)
  581. {
  582. var rectDict = Json.Deserialize(rectPropString) as Dictionary<string, object>;
  583. var originX = MaxSdkUtils.GetFloatFromDictionary(rectDict, "origin_x", 0);
  584. var originY = MaxSdkUtils.GetFloatFromDictionary(rectDict, "origin_y", 0);
  585. var width = MaxSdkUtils.GetFloatFromDictionary(rectDict, "width", 0);
  586. var height = MaxSdkUtils.GetFloatFromDictionary(rectDict, "height", 0);
  587. return new Rect(originX, originY, width, height);
  588. }
  589. protected static void HandleExtraParameter(string key, string value)
  590. {
  591. bool disableAllLogs;
  592. if ("disable_all_logs".Equals(key) && bool.TryParse(value, out disableAllLogs))
  593. {
  594. DisableAllLogs = disableAllLogs;
  595. }
  596. }
  597. /// <summary>
  598. /// Handles forwarding callbacks from native to C#.
  599. /// </summary>
  600. /// <param name="propsStr">A prop string with the event data</param>
  601. protected static void HandleBackgroundCallback(string propsStr)
  602. {
  603. try
  604. {
  605. MaxSdkCallbacks.ForwardEvent(propsStr);
  606. }
  607. catch (Exception exception)
  608. {
  609. var eventProps = Json.Deserialize(propsStr) as Dictionary<string, object>;
  610. if (eventProps == null) return;
  611. var eventName = MaxSdkUtils.GetStringFromDictionary(eventProps, "name", "");
  612. MaxSdkLogger.UserError("Unable to notify ad delegate due to an error in the publisher callback '" + eventName + "' due to exception: " + exception.Message);
  613. MaxSdkLogger.LogException(exception);
  614. }
  615. }
  616. protected static string SerializeLocalExtraParameterValue(object value)
  617. {
  618. if (!(value.GetType().IsPrimitive || value is string || value is IList || value is IDictionary))
  619. {
  620. MaxSdkLogger.UserError("Local extra parameters must be an IList, IDictionary, string, or a primitive type");
  621. return "";
  622. }
  623. Dictionary<string, object> data = new Dictionary<string, object>
  624. {
  625. {"value", value}
  626. };
  627. return Json.Serialize(data);
  628. }
  629. [Obsolete("This API has been deprecated and will be removed in a future release.")]
  630. public enum ConsentDialogState
  631. {
  632. Unknown,
  633. Applies,
  634. DoesNotApply
  635. }
  636. }
  637. /// <summary>
  638. /// An extension class for <see cref="MaxSdkBase.BannerPosition"/> and <see cref="MaxSdkBase.AdViewPosition"/> enums.
  639. /// </summary>
  640. internal static class AdPositionExtenstion
  641. {
  642. public static string ToSnakeCaseString(this MaxSdkBase.BannerPosition position)
  643. {
  644. if (position == MaxSdkBase.BannerPosition.TopLeft)
  645. {
  646. return "top_left";
  647. }
  648. else if (position == MaxSdkBase.BannerPosition.TopCenter)
  649. {
  650. return "top_center";
  651. }
  652. else if (position == MaxSdkBase.BannerPosition.TopRight)
  653. {
  654. return "top_right";
  655. }
  656. else if (position == MaxSdkBase.BannerPosition.Centered)
  657. {
  658. return "centered";
  659. }
  660. else if (position == MaxSdkBase.BannerPosition.CenterLeft)
  661. {
  662. return "center_left";
  663. }
  664. else if (position == MaxSdkBase.BannerPosition.CenterRight)
  665. {
  666. return "center_right";
  667. }
  668. else if (position == MaxSdkBase.BannerPosition.BottomLeft)
  669. {
  670. return "bottom_left";
  671. }
  672. else if (position == MaxSdkBase.BannerPosition.BottomCenter)
  673. {
  674. return "bottom_center";
  675. }
  676. else // position == MaxSdkBase.BannerPosition.BottomRight
  677. {
  678. return "bottom_right";
  679. }
  680. }
  681. public static string ToSnakeCaseString(this MaxSdkBase.AdViewPosition position)
  682. {
  683. if (position == MaxSdkBase.AdViewPosition.TopLeft)
  684. {
  685. return "top_left";
  686. }
  687. else if (position == MaxSdkBase.AdViewPosition.TopCenter)
  688. {
  689. return "top_center";
  690. }
  691. else if (position == MaxSdkBase.AdViewPosition.TopRight)
  692. {
  693. return "top_right";
  694. }
  695. else if (position == MaxSdkBase.AdViewPosition.Centered)
  696. {
  697. return "centered";
  698. }
  699. else if (position == MaxSdkBase.AdViewPosition.CenterLeft)
  700. {
  701. return "center_left";
  702. }
  703. else if (position == MaxSdkBase.AdViewPosition.CenterRight)
  704. {
  705. return "center_right";
  706. }
  707. else if (position == MaxSdkBase.AdViewPosition.BottomLeft)
  708. {
  709. return "bottom_left";
  710. }
  711. else if (position == MaxSdkBase.AdViewPosition.BottomCenter)
  712. {
  713. return "bottom_center";
  714. }
  715. else // position == MaxSdkBase.AdViewPosition.BottomRight
  716. {
  717. return "bottom_right";
  718. }
  719. }
  720. }