com.amanotes.gdk 0.2.64 → 0.2.65-2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/Editor/Extra/SDKVersionTracking.AirTable.cs +73 -0
  3. package/Editor/Extra/SDKVersionTracking.AirTable.cs.meta +3 -0
  4. package/Editor/Extra/SDKVersionTracking.cs +232 -0
  5. package/Editor/Extra/SDKVersionTracking.cs.meta +11 -0
  6. package/Extra/AmaGDKInstaller.unitypackage +0 -0
  7. package/Extra/CheckDiskSpace.unitypackage +0 -0
  8. package/Extra/ForceUpdate.unitypackage +0 -0
  9. package/Extra/GoogleCMP.unitypackage +0 -0
  10. package/Extra/GoogleCMP.unitypackage.meta +7 -0
  11. package/Extra/PostProcessor.unitypackage +0 -0
  12. package/Extra/SDKVersionTracking.unitypackage +0 -0
  13. package/Packages/AmaGDKConfig.unitypackage +0 -0
  14. package/Packages/AmaGDKExample.unitypackage +0 -0
  15. package/Packages/AmaGDKTest.unitypackage +0 -0
  16. package/Packages/AppsFlyerAdapter.PurchaseConnector.unitypackage +0 -0
  17. package/Packages/AppsFlyerAdapter.unitypackage +0 -0
  18. package/Packages/FirebaseAnalyticsAdapter.unitypackage +0 -0
  19. package/Packages/FirebaseRemoteConfigAdapter.unitypackage +0 -0
  20. package/Packages/IronSourceAdapter.unitypackage +0 -0
  21. package/Packages/RevenueCatAdapter.unitypackage +0 -0
  22. package/Packages/SqliteAnalyticsAdapter.unitypackage +0 -0
  23. package/Runtime/AmaGDK.Adapters.cs +1 -1
  24. package/Runtime/AmaGDK.Ads.cs +29 -2
  25. package/Runtime/AmaGDK.Analytics.cs +2 -2
  26. package/Runtime/AmaGDK.Mono.cs +111 -0
  27. package/Runtime/AmaGDK.Mono.cs.meta +3 -0
  28. package/Runtime/AmaGDK.RemoteConfig.cs +3 -4
  29. package/Runtime/AmaGDK.Singleton.cs +27 -0
  30. package/Runtime/AmaGDK.Singleton.cs.meta +3 -0
  31. package/Runtime/AmaGDK.UserProfile.cs +1 -2
  32. package/Runtime/AmaGDK.cs +10 -54
  33. package/Runtime/Core/GDKRoutine.cs +61 -0
  34. package/Runtime/Core/GDKRoutine.cs.meta +3 -0
  35. package/Runtime/Core/GDKUnityCallback.cs +141 -0
  36. package/Runtime/Core/GDKUnityCallback.cs.meta +3 -0
  37. package/Runtime/Core.meta +8 -0
  38. package/Runtime/Internal/AmaGDK.Internal.cs +5 -9
  39. package/Runtime/Internal/AmaGDK.Utils.cs +63 -80
  40. package/Runtime/Internal/ForceQuitMonitor.cs +111 -0
  41. package/Runtime/Internal/ForceQuitMonitor.cs.meta +3 -0
  42. package/Runtime/Klavar/Attributes/AccumulatedCountAttribute.cs +0 -1
  43. package/Runtime/Klavar/Attributes/MinMaxAttribute.cs +86 -79
  44. package/Runtime/Klavar/Attributes/MinMaxLengthAttribute.cs +47 -26
  45. package/Runtime/Klavar/Attributes/NotNullAttribute.cs +1 -1
  46. package/Runtime/Klavar/Attributes/RegexPatternAttribute.cs +10 -7
  47. package/Runtime/Klavar/Attributes/ToStringAttribute.cs +1 -1
  48. package/Runtime/Klavar/KlavarContainer.cs +21 -5
  49. package/Runtime/Klavar/KlavarEvent.cs +4 -1
  50. package/Runtime/Utils/GDKUtils.cs +35 -0
  51. package/Runtime/Utils/GDKUtils.cs.meta +3 -0
  52. package/Runtime/Utils.meta +8 -0
  53. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.2.66 - 2024-06-13]
4
+ - [Fix] Missing Google CMP in package release
5
+
6
+ ## [0.2.65 - 2024-06-13]
7
+ - [Dev] Add GDKRoutine
8
+ - [Dev] Add option to preload banners
9
+ - [Fix] Handle GoogleCMP callback in main-thread
10
+ - Also: Ensure Logging.LogError is thead-safe
11
+ - [Fix] Manage banner status so not to request banner load multiple times
12
+ - [Add] GDKUnityCallback with thread-safe
13
+ - [Feature] Add fullads_impression & videoads_impression events for better fill rate tracking
14
+ - [Klavar] Improve parameter validation
15
+
3
16
  ## [0.2.64 - 2024-06-06]
4
17
  - [Dev] Log gdk_init
5
18
  - [Fix] map_user_id must contain FRB, AF, [GAID, IDFA]
@@ -0,0 +1,73 @@
1
+ using System.Collections.Generic;
2
+ using System.Net.Http;
3
+ using System.Text;
4
+ using System.Threading.Tasks;
5
+ using Amanotes.Core.Internal;
6
+ using UnityEditor;
7
+ using UnityEditor.Callbacks;
8
+ using UnityEngine;
9
+
10
+ namespace Amanotes.Editor
11
+ {
12
+ public partial class SDKVersionTracking
13
+ {
14
+ private const string AUTH_TOKEN = "pat1CmLr9XozLt6ZE";
15
+ private const string URL = "https://gdk.amanotes.io/gdkVersionTracking";
16
+
17
+ [PostProcessBuild(999)]
18
+ public static void OnPostProcessBuild(BuildTarget target, string pathToBuiltProject)
19
+ {
20
+ var rawData = AllVersions;
21
+ rawData["UnityVersion"] = Application.unityVersion;
22
+ #if UNITY_ANDROID
23
+ rawData["Platform"] = "Android";
24
+ rawData["Permissions"] = GetAllAndroidPermissions();
25
+ rawData["APILevel"] = (int)PlayerSettings.Android.targetSdkVersion;
26
+ #elif UNITY_IOS
27
+ rawData["SKAdNetwork"] = GetSkAdNetworkCount($"{pathToBuiltProject}/Info.plist");
28
+ rawData["Platform"] = "iOS";
29
+ #endif
30
+
31
+ var buildInfo = new Dictionary<string, object>
32
+ {
33
+ {"GameName", Application.productName},
34
+ {"BuildVersion", PlayerSettings.bundleVersion},
35
+ {"BuildNumber", GetBuildNumber()},
36
+ {"BuildTime", GetBuildTime()},
37
+ {"AppId", PlayerSettings.applicationIdentifier },
38
+ {"RawData", rawData }
39
+ };
40
+ string json = JsonUtils.DictionaryToJson(buildInfo, false, false);
41
+ SendDataToAirTable(json);
42
+ }
43
+
44
+ private static async Task SendDataToAirTable(string payload)
45
+ {
46
+ Debug.Log("AmaGDK | [SDKVersionTracking]: SendDataToAirTable ");
47
+ try
48
+ {
49
+ var client = new HttpClient();
50
+ var request = new HttpRequestMessage(HttpMethod.Post, URL);
51
+ request.Headers.Add("Authorization", AUTH_TOKEN);
52
+ request.Content = new StringContent(payload, Encoding.UTF8, "application/json");
53
+
54
+ var response = await client.SendAsync(request);
55
+ if (response.IsSuccessStatusCode)
56
+ {
57
+ string responseData = await response.Content.ReadAsStringAsync();
58
+ Debug.Log("AmaGDK | [SDKVersionTracking]: done " + responseData);
59
+ }
60
+ else
61
+ {
62
+ Debug.LogError("AmaGDK | [SDKVersionTracking] Error: " + response.StatusCode);
63
+ string errorData = await response.Content.ReadAsStringAsync();
64
+ Debug.LogError("AmaGDK | [SDKVersionTracking] Error Response: " + errorData);
65
+ }
66
+ }
67
+ catch (HttpRequestException e)
68
+ {
69
+ Debug.LogError("AmaGDK | [SDKVersionTracking] Request Exception: " + e.Message);
70
+ }
71
+ }
72
+ }
73
+ }
@@ -0,0 +1,3 @@
1
+ fileFormatVersion: 2
2
+ guid: 53147bd64d3f47109e84b17644c5b1c2
3
+ timeCreated: 1718186649
@@ -0,0 +1,232 @@
1
+ using System;
2
+ using System.Collections.Generic;
3
+ using System.IO;
4
+ using System.Linq;
5
+ using System.Text;
6
+ using System.Xml;
7
+ using UnityEditor;
8
+ using UnityEditor.Build;
9
+ using UnityEditor.Build.Reporting;
10
+ using UnityEngine;
11
+
12
+ #if UNITY_IOS
13
+ using UnityEditor.iOS.Xcode;
14
+ #endif
15
+
16
+ namespace Amanotes.Editor
17
+ {
18
+ public partial class SDKVersionTracking
19
+ {
20
+ private static Func<Dictionary<string, object>> _getExtraSDKVersion;
21
+ public static void SetSDKVersionHook(Func<Dictionary<string, object>> hook)
22
+ {
23
+ _getExtraSDKVersion = hook;
24
+ }
25
+
26
+ }
27
+ public partial class SDKVersionTracking : IPreprocessBuildWithReport
28
+ {
29
+ public static Dictionary<string, object> AllVersions
30
+ {
31
+ get
32
+ {
33
+ return _dicThirdPartyVersion
34
+ .Concat(_dicExtraVersion)
35
+ .Concat(_dicIronSourceAdapterVersion)
36
+ .ToDictionary(x => x.Key, x => x.Value);
37
+ }
38
+ }
39
+
40
+ private const int MAX_VERSION_KEY_LENGTH = 30;
41
+ private static Dictionary<string, object> _dicThirdPartyVersion = new Dictionary<string, object>();
42
+ private static Dictionary<string, object> _dicExtraVersion = new Dictionary<string, object>();
43
+ private static Dictionary<string, object> _dicIronSourceAdapterVersion = new Dictionary<string, object>();
44
+
45
+ private static string GetBuildNumber()
46
+ {
47
+ #if UNITY_ANDROID
48
+ return PlayerSettings.Android.bundleVersionCode.ToString();
49
+ #elif UNITY_IOS
50
+ return PlayerSettings.iOS.buildNumber;
51
+ #else
52
+ return string.Empty;
53
+ #endif
54
+ }
55
+
56
+ private static string GetBuildTime()
57
+ {
58
+ return DateTime.Now.ToString("dd/MM/yyyy HH:mm");
59
+ }
60
+
61
+ public static int GetSkAdNetworkCount(string infoPlistPath)
62
+ {
63
+ int count = 0;
64
+ #if UNITY_IOS
65
+ if (!File.Exists(infoPlistPath))
66
+ {
67
+ Debug.LogWarning($"AmaGDK | [SDKVersionTracking] InfoPlist file is not exist!\n{infoPlistPath}\n");
68
+ return count;
69
+ }
70
+
71
+ PlistDocument plist = new PlistDocument();
72
+ plist.ReadFromString(File.ReadAllText(infoPlistPath));
73
+ PlistElementDict rootDict = plist.root;
74
+ if (!rootDict.values.ContainsKey("SKAdNetworkItems"))
75
+ return count;
76
+
77
+ count = rootDict.values["SKAdNetworkItems"].AsArray().values.Count;
78
+ return count;
79
+ #else
80
+ return count;
81
+ #endif
82
+ }
83
+
84
+ public static List<string> GetAllAndroidPermissions()
85
+ {
86
+ #if UNITY_ANDROID
87
+ StringBuilder permissions = new StringBuilder();
88
+ string projectPath = Application.dataPath.Substring(0, Application.dataPath.Length - "Assets".Length);
89
+
90
+ List<string> manifestPaths = new List<string>();
91
+ GetAllManifestPaths(projectPath, manifestPaths);
92
+
93
+ HashSet<string> uniquePermissions = new HashSet<string>();
94
+
95
+ HashSet<string> removePermission = new HashSet<string>();
96
+
97
+ foreach (var path in manifestPaths)
98
+ {
99
+ XmlDocument xmlDoc = GetXML(path);
100
+ var permissionNodes = xmlDoc.SelectNodes("manifest/uses-permission");
101
+
102
+ if (permissionNodes == null)
103
+ continue;
104
+
105
+ foreach (XmlNode node in permissionNodes)
106
+ {
107
+ if (node.Attributes == null)
108
+ continue;
109
+ if(node.Attributes["android:name"] == null)
110
+ continue;
111
+
112
+ string permissionName = node.Attributes["android:name"].Value;
113
+
114
+ XmlAttribute attribute = node.Attributes["tools:node"];
115
+
116
+ if (attribute != null && attribute.Value.Trim().Equals("remove")) removePermission.Add(permissionName);
117
+
118
+ uniquePermissions.Add(permissionName);
119
+ }
120
+ }
121
+
122
+ uniquePermissions.ExceptWith(removePermission);
123
+
124
+ List<string> permissionList = uniquePermissions.ToList();
125
+ permissionList.Sort();
126
+ return permissionList;
127
+ #else
128
+ return new List<string>();
129
+ #endif
130
+ }
131
+
132
+ private static void GetAllManifestPaths(string directory, List<string> manifestPaths)
133
+ {
134
+ string[] manifestFiles = Directory.GetFiles(directory, "AndroidManifest.xml", SearchOption.AllDirectories);
135
+ manifestPaths.AddRange(manifestFiles);
136
+ }
137
+
138
+ private static XmlDocument GetXML(string path)
139
+ {
140
+ XmlDocument xmlDoc = new XmlDocument();
141
+ try
142
+ {
143
+ if (File.Exists(path))
144
+ {
145
+ xmlDoc.LoadXml(File.ReadAllText(path));
146
+ }
147
+ }
148
+ catch (Exception exception)
149
+ {
150
+ Debug.LogError("Can't parse xml: " + path + "\n" + exception.Message);
151
+ }
152
+ return xmlDoc;
153
+ }
154
+
155
+ private static void AppendVersion(StringBuilder sb, string sectionName, Dictionary<string,object> dict)
156
+ {
157
+ if (dict == null || dict.Count == 0) return;
158
+ AppendVersion(sb, sectionName, dict
159
+ .Where(kvp=>kvp.Value != null)
160
+ .Select(kvp=> (kvp.Key, kvp.Value))
161
+ .OrderBy(kvp=>kvp.Key)
162
+ );
163
+ }
164
+
165
+ private static void AppendVersion(StringBuilder sb, string sectionName, IEnumerable<(string, object)> list)
166
+ {
167
+ if (list == null) return;
168
+ sb.Append($"\n// {sectionName}\n");
169
+ sb.Append("//----------------------------------------------------\n");
170
+
171
+ foreach ((string key, object value) in list)
172
+ {
173
+ sb.Append($"{key, -MAX_VERSION_KEY_LENGTH}\t=\t{value.ToString().Replace("'", "")}\n");
174
+ }
175
+ }
176
+
177
+ public static List<(string, object)> GetBuildInfo()
178
+ {
179
+ return new List<(string, object)>()
180
+ {
181
+ ("Version", Application.version),
182
+ ("BuildNumber", GetBuildNumber()),
183
+ ("BuildTime", GetBuildTime()),
184
+ ("UnityVersion", Application.unityVersion)
185
+ #if UNITY_ANDROID
186
+ ,("API Level", (int)PlayerSettings.Android.targetSdkVersion)
187
+ #endif
188
+ };
189
+ }
190
+
191
+ private static void WriteToStreamingAssets()
192
+ {
193
+ try
194
+ {
195
+ StringBuilder sb = new StringBuilder();
196
+ sb.Append("// Automatically generated by AmaGDK after every build\n");
197
+
198
+ AppendVersion(sb, "BUILD INFO", GetBuildInfo());
199
+ AppendVersion(sb, "THIRD PARTY", _dicThirdPartyVersion);
200
+ AppendVersion(sb, "IS ADAPTER", _dicIronSourceAdapterVersion);
201
+ AppendVersion(sb, "EXTRA", _dicExtraVersion);
202
+
203
+ string folderPath = Application.streamingAssetsPath;
204
+ string filePath = Path.Combine(folderPath, "SDKVersion.txt");
205
+
206
+ if (!Directory.Exists(folderPath))
207
+ {
208
+ Directory.CreateDirectory(folderPath);
209
+ }
210
+
211
+ File.WriteAllText(filePath, sb.ToString());
212
+ Debug.Log("AmaGDK | [SDKVersionTracking] The third-party version logs have been written to: " + filePath);
213
+ AssetDatabase.Refresh();
214
+ }
215
+ catch (Exception e)
216
+ {
217
+ Debug.LogError("AmaGDK | [SDKVersionTracking] Exception encountered while logging local third-party versions: " + e);
218
+ }
219
+ }
220
+
221
+ public int callbackOrder { get; }
222
+ public void OnPreprocessBuild(BuildReport report)
223
+ {
224
+ _dicThirdPartyVersion = AmaGDKExtra.GetThirdPartyVersions();
225
+ _dicIronSourceAdapterVersion = AmaGDKExtra.GetIronSourceAdapterVersions();
226
+ _dicExtraVersion = _getExtraSDKVersion?.Invoke() ?? _dicExtraVersion;
227
+
228
+ WriteToStreamingAssets();
229
+ }
230
+
231
+ }
232
+ }
@@ -0,0 +1,11 @@
1
+ fileFormatVersion: 2
2
+ guid: 5d8af764a90804bf98634a5939bffb90
3
+ MonoImporter:
4
+ externalObjects: {}
5
+ serializedVersion: 2
6
+ defaultReferences: []
7
+ executionOrder: 0
8
+ icon: {instanceID: 0}
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant:
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,7 @@
1
+ fileFormatVersion: 2
2
+ guid: 4e220bd58ce0646bcbbb209dc8451d25
3
+ DefaultImporter:
4
+ externalObjects: {}
5
+ userData:
6
+ assetBundleName:
7
+ assetBundleVariant:
Binary file
Binary file
Binary file
Binary file
@@ -66,7 +66,7 @@ namespace Amanotes.Core.Internal
66
66
 
67
67
  adapter.adapterId = id;
68
68
  adapter.adapterVersion = version;
69
- GDKUtils.RegisterUnityCallbacks(adapter);
69
+ GDKUtils.AddUnityCallbacks(adapter);
70
70
  adapterMap.Add(id, adapter);
71
71
  return true;
72
72
  }
@@ -275,7 +275,7 @@ namespace Amanotes.Core
275
275
 
276
276
  if (Config.ad.enableInterstitial) _adapter.interstitial.StartLoadAd();
277
277
  if (Config.ad.enableRewarded) _adapter.rewardVideo.StartLoadAd();
278
-
278
+ if (Config.ad.preloadBanner) PreloadBanner();
279
279
  if (_isBannerShowing)
280
280
  {
281
281
  _isBannerShowing = false;
@@ -323,6 +323,30 @@ namespace Amanotes.Core
323
323
 
324
324
  [NonSerialized] private static bool _isBannerShowing = false;
325
325
 
326
+ public static void PreloadBanner()
327
+ {
328
+ if (!_config.ad.enableBanner)
329
+ {
330
+ LogWarning($"Banner not enabled! {_config.ad.enableBanner}");
331
+ return;
332
+ }
333
+
334
+ if (_adapter == null)
335
+ {
336
+ LogWarning($"Adapter is null!");
337
+ return;
338
+ }
339
+
340
+ if (_isBannerShowing)
341
+ {
342
+ LogWarning($"Banner is showing!");
343
+ return;
344
+ }
345
+
346
+ _adapter.ShowBanner();
347
+ _adapter.HideBanner();
348
+ }
349
+
326
350
  public static void ShowBanner()
327
351
  {
328
352
  if (!_config.ad.enableBanner)
@@ -426,6 +450,9 @@ namespace Amanotes.Core.Internal
426
450
  [Tooltip("Before showing an ad: set Time.timeScale to 0\nAfter the ad is closed: restore the previously saved Time.timeScale")]
427
451
  public bool autoTimeScale = true;
428
452
 
453
+ [Tooltip("Preload banner right when Ad module init (default = false)")]
454
+ public bool preloadBanner = false;
455
+
429
456
  [Header("EDITOR")]
430
457
  [Tooltip("Only applicable in Editor\n0 = 0% success\n1 = 100% success")]
431
458
  [Range(0f, 1f)] public float rewardAdShowSuccessRate = 1;
@@ -444,7 +471,7 @@ namespace Amanotes.Core.Internal
444
471
  // APIs
445
472
  internal protected abstract AdLogic interstitial { get; }
446
473
  internal protected abstract AdLogic rewardVideo { get; }
447
-
474
+
448
475
  public abstract void ShowBanner();
449
476
  public abstract void HideBanner();
450
477
 
@@ -343,8 +343,7 @@ namespace Amanotes.Core
343
343
  // All adapters should be ready now!
344
344
 
345
345
  // TODO: Refactor Resolve Early Calls
346
- onFrameUpdate -= ProcessEventQueue;
347
- onFrameUpdate += ProcessEventQueue;
346
+ GDKUtils.OnFrameUpdate(ProcessEventQueue);
348
347
  }
349
348
 
350
349
  internal static EventParams PrepareEvent(string eventName)
@@ -440,6 +439,7 @@ namespace Amanotes.Core
440
439
  m.LogEvent(eventNameToSend, eventParams.parameters);
441
440
  inUseAdapterIDs?.Add(m.adapterId);
442
441
  }
442
+ ForceQuit.OnLogEvent(eventNameToSend, eventParams.parameters);
443
443
 
444
444
  return (eventNameToSend, inUseAdapterIDs);
445
445
  }
@@ -0,0 +1,111 @@
1
+ using Amanotes.Core.Internal;
2
+ using System;
3
+ using System.Collections;
4
+ using System.Collections.Generic;
5
+ using System.Threading;
6
+ using UnityEngine;
7
+
8
+ namespace Amanotes.Core
9
+ {
10
+ public partial class AmaGDK
11
+ {
12
+ internal static int mainThreadId = -1;
13
+ internal static readonly GDKUnityCallback unityCallbacks = new GDKUnityCallback();
14
+
15
+ internal static float realtimeSinceStartup;
16
+ internal static float time;
17
+
18
+ private void Update()
19
+ {
20
+ if (!isReady) return;
21
+
22
+ time = Time.time;
23
+ realtimeSinceStartup = Time.realtimeSinceStartup;
24
+
25
+ var cb = unityCallbacks;
26
+ cb.Invoke(ref cb.OnFrameUpdate);
27
+ cb.Invoke(ref cb.DoOnceNextFrame);
28
+ }
29
+
30
+ private void OnApplicationPause(bool pauseStatus)
31
+ {
32
+ var cb = unityCallbacks;
33
+ cb.Invoke(ref cb.OnApplicationPause, pauseStatus);
34
+ }
35
+
36
+ private void OnApplicationFocus(bool hasFocus)
37
+ {
38
+ var cb = unityCallbacks;
39
+ cb.Invoke(ref cb.OnApplicationFocus, hasFocus);
40
+ }
41
+
42
+ private void OnApplicationQuit()
43
+ {
44
+ var cb = unityCallbacks;
45
+ cb.Invoke(ref cb.OnApplicationQuit);
46
+ }
47
+ }
48
+ }
49
+
50
+ namespace Amanotes.Core.Internal
51
+ {
52
+
53
+
54
+ public static partial class GDKUtils
55
+ {
56
+ public static bool isOnMainThread => Thread.CurrentThread.ManagedThreadId == AmaGDK.mainThreadId;
57
+ public static void DoOnMainThread(Action action)
58
+ {
59
+ if (isOnMainThread)
60
+ {
61
+ SafeInvoke(action);
62
+ return;
63
+ }
64
+
65
+ DoOnceNextFrame(action);
66
+ }
67
+
68
+ public static void OnFrameUpdate(Action action)
69
+ {
70
+ var cb = AmaGDK.unityCallbacks;
71
+ cb.AddCallback(ref cb.OnFrameUpdate, action);
72
+ }
73
+
74
+ public static void DoOnceNextFrame(Action action)
75
+ {
76
+ var cb = AmaGDK.unityCallbacks;
77
+ cb.AddCallback(ref cb.DoOnceNextFrame, action);
78
+ }
79
+
80
+ public static void DelayCall(float seconds, Action action)
81
+ {
82
+ DoOnMainThread(() => AmaGDK._instance.StartCoroutine(DelayCallRoutine(seconds, action)));
83
+ }
84
+
85
+ public static IEnumerator Timeout(float timeoutInSecs, Func<bool> completeCheckFunc)
86
+ {
87
+ float time = Time.realtimeSinceStartup;
88
+ while (completeCheckFunc() == false)
89
+ {
90
+ yield return null;
91
+ if (Time.realtimeSinceStartup - time > timeoutInSecs) yield break;
92
+ }
93
+ }
94
+
95
+ private static IEnumerator DelayCallRoutine(float seconds, Action callback)
96
+ {
97
+ yield return new WaitForSecondsRealtime(seconds);
98
+ callback();
99
+ }
100
+
101
+ public static void AddUnityCallbacks<T>(T observer)
102
+ {
103
+ AmaGDK.unityCallbacks.AddObserver(observer);
104
+ }
105
+
106
+ public static void RemoveUnityCallbacks<T>(T observer)
107
+ {
108
+ AmaGDK.unityCallbacks.RemoveObserver(observer);
109
+ }
110
+ }
111
+ }
@@ -0,0 +1,3 @@
1
+ fileFormatVersion: 2
2
+ guid: 66a09cd9d2b8423e885352a8441c6468
3
+ timeCreated: 1718074317
@@ -39,9 +39,8 @@ namespace Amanotes.Core
39
39
  {
40
40
  get
41
41
  {
42
- if (_cacheExisted == null)
43
- _cacheExisted = GDKFileUtils.Exist(fileName);
44
- return _cacheExisted.GetValueOrDefault();
42
+ _cacheExisted ??= GDKFileUtils.Exist(fileName);
43
+ return _cacheExisted.Value;
45
44
  }
46
45
  }
47
46
 
@@ -195,7 +194,7 @@ namespace Amanotes.Core
195
194
  }
196
195
 
197
196
  _fetchState = FetchState.Fetch;
198
- adapter.FetchConfig(HasCache, (isSuccess, result) =>
197
+ adapter.FetchConfig(!HasCache, (isSuccess, result) =>
199
198
  {
200
199
  if (!isSuccess)
201
200
  {
@@ -0,0 +1,27 @@
1
+
2
+ using System.Threading;
3
+ using static Amanotes.Core.Internal.Logging;
4
+ using static Amanotes.Core.Internal.Messsage;
5
+
6
+ namespace Amanotes.Core
7
+ {
8
+ public partial class AmaGDK
9
+ {
10
+ internal static AmaGDK _instance;
11
+
12
+ private void Awake()
13
+ {
14
+ if (_instance != null)
15
+ {
16
+ LogWarning(MULTIPLE_INSTANCE);
17
+ Destroy(this);
18
+ return;
19
+ }
20
+
21
+ _instance = this;
22
+ mainThreadId = Thread.CurrentThread.ManagedThreadId;
23
+ DontDestroyOnLoad(this);
24
+ StartCoroutine(InitRoutine());
25
+ }
26
+ }
27
+ }
@@ -0,0 +1,3 @@
1
+ fileFormatVersion: 2
2
+ guid: 059e9f9cfffd44639fc660df9537fa37
3
+ timeCreated: 1718081104
@@ -326,8 +326,7 @@ namespace Amanotes.Core
326
326
  // Always get the latest advertising id
327
327
  GetAdvertisingId();
328
328
  Logging.Log($"[UserProfile] user_id: {_userId}");
329
- onFrameUpdate -= SaveIfDirty;
330
- onFrameUpdate += SaveIfDirty;
329
+ GDKUtils.OnFrameUpdate(SaveIfDirty);
331
330
 
332
331
  var adsId = Application.platform == RuntimePlatform.Android ? GAId : IDFA;
333
332
  var delay = string.IsNullOrEmpty(AppsFlyerId)