MaxSdkBase.cs 31 KB

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