com.amanotes.gdk 0.2.66 → 0.2.68

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 +19 -0
  2. package/Editor/Extra/GDKAutoUpdateAdapter.cs +67 -0
  3. package/Editor/Extra/GDKAutoUpdateAdapter.cs.meta +11 -0
  4. package/Extra/AmaGDKInstaller.unitypackage +0 -0
  5. package/Extra/CheckDiskSpace.unitypackage +0 -0
  6. package/Extra/ForceUpdate.unitypackage +0 -0
  7. package/Extra/GoogleCMP.unitypackage +0 -0
  8. package/Extra/LegacyGDKUpdateHelper.unitypackage +0 -0
  9. package/Extra/LegacyGDKUpdateHelper.unitypackage.meta +7 -0
  10. package/Extra/PostProcessor.unitypackage +0 -0
  11. package/Packages/AmaGDKConfig.unitypackage +0 -0
  12. package/Packages/AmaGDKExample.unitypackage +0 -0
  13. package/Packages/AmaGDKTest.unitypackage +0 -0
  14. package/Packages/AppsFlyerAdapter.PurchaseConnector.unitypackage +0 -0
  15. package/Packages/AppsFlyerAdapter.unitypackage +0 -0
  16. package/Packages/FirebaseAnalyticsAdapter.unitypackage +0 -0
  17. package/Packages/FirebaseRemoteConfigAdapter.unitypackage +0 -0
  18. package/Packages/IronSourceAdapter.unitypackage +0 -0
  19. package/Packages/RevenueCatAdapter.unitypackage +0 -0
  20. package/Packages/SqliteAnalyticsAdapter.unitypackage +0 -0
  21. package/Runtime/Ad/AdExtension.cs +111 -0
  22. package/Runtime/Ad/AdExtension.cs.meta +3 -0
  23. package/Runtime/Ad/AdLogic.cs +530 -0
  24. package/Runtime/Ad/AdLogic.cs.meta +3 -0
  25. package/Runtime/Ad/AdModuleConfig.cs +39 -0
  26. package/Runtime/Ad/AdModuleConfig.cs.meta +3 -0
  27. package/Runtime/Ad/AdShowContext.cs +43 -0
  28. package/Runtime/Ad/AdShowContext.cs.meta +3 -0
  29. package/Runtime/Ad/AmaGDK.Ads.cs +383 -0
  30. package/Runtime/Ad.meta +8 -0
  31. package/Runtime/AmaGDK.Analytics.cs +20 -1
  32. package/Runtime/AmaGDK.Device.cs +105 -0
  33. package/Runtime/AmaGDK.Device.cs.meta +3 -0
  34. package/Runtime/AmaGDK.Mono.cs +0 -1
  35. package/Runtime/AmaGDK.cs +6 -2
  36. package/Runtime/AudioToolkit/AmaGDK.Audio.cs +16 -0
  37. package/Runtime/AudioToolkit/Plugins/Android/GDKAudioDeviceDetector.java +1 -1
  38. package/Runtime/Fps/AmaFPS.Utils.cs +44 -0
  39. package/Runtime/Fps/AmaFPS.Utils.cs.meta +3 -0
  40. package/Runtime/Fps/AmaFPS.cs +197 -0
  41. package/Runtime/Fps/AmaFPS.cs.meta +11 -0
  42. package/Runtime/Fps/AmaFPSVisualizer.cs +246 -0
  43. package/Runtime/Fps/AmaFPSVisualizer.cs.meta +11 -0
  44. package/Runtime/Fps/BollingerBands.cs +99 -0
  45. package/Runtime/Fps/BollingerBands.cs.meta +11 -0
  46. package/Runtime/Fps/FPSVisualizer.prefab +406 -0
  47. package/Runtime/Fps/FPSVisualizer.prefab.meta +7 -0
  48. package/Runtime/Fps/FrameRecorder.cs +172 -0
  49. package/Runtime/Fps/FrameRecorder.cs.meta +3 -0
  50. package/Runtime/Fps.meta +8 -0
  51. package/package.json +1 -1
  52. package/Runtime/AmaGDK.Ads.cs +0 -1077
  53. /package/Runtime/{AmaGDK.Ads.cs.meta → Ad/AmaGDK.Ads.cs.meta} +0 -0
@@ -0,0 +1,383 @@
1
+ using System;
2
+ using System.Collections;
3
+ using System.Collections.Generic;
4
+ using UnityEngine;
5
+ using Amanotes.Core.Internal;
6
+
7
+ using static Amanotes.Core.Internal.Logging;
8
+ using static Amanotes.Core.AmaGDK;
9
+
10
+ namespace Amanotes.Core
11
+ {
12
+ public partial class AmaGDK // Ads module
13
+ {
14
+ partial class Event
15
+ {
16
+ public const string INTER_REQUEST = nameof(INTER_REQUEST);
17
+ public const string INTER_SHOW_CALLED = nameof(INTER_SHOW_CALLED);
18
+ public const string INTER_SHOW_READY = nameof(INTER_SHOW_READY);
19
+ public const string INTER_SHOW_NOT_READY = nameof(INTER_SHOW_NOT_READY); // reason: string
20
+ public const string INTER_SHOW_BEGIN = nameof(INTER_SHOW_BEGIN); // always call result: true / false
21
+ public const string INTER_SHOW_END = nameof(INTER_SHOW_END); // always call result: true / false
22
+
23
+ public const string REWARD_REQUEST = nameof(REWARD_REQUEST);
24
+ public const string REWARD_VIDEO_SHOW_CALLED = nameof(REWARD_VIDEO_SHOW_CALLED);
25
+ public const string REWARD_VIDEO_SHOW_READY = nameof(REWARD_VIDEO_SHOW_READY);
26
+ public const string REWARD_VIDEO_SHOW_NOT_READY = nameof(REWARD_VIDEO_SHOW_NOT_READY); // reason: string
27
+ // public const string REWARD_VIDEO_REWARD_GRANTED = nameof(REWARD_VIDEO_REWARD_GRANTED);
28
+ public const string REWARD_VIDEO_SHOW_BEGIN = nameof(REWARD_VIDEO_SHOW_BEGIN); // always call result: true / false
29
+ public const string REWARD_VIDEO_SHOW_END = nameof(REWARD_VIDEO_SHOW_END); // always call result: true / false
30
+
31
+ public const string BANNER_SHOW = nameof(BANNER_SHOW);
32
+ }
33
+
34
+
35
+ [Serializable]
36
+ internal class AdStat
37
+ {
38
+ // per session
39
+ internal float prevCallTime;
40
+ internal float currentCallTime;
41
+ internal int callCount;
42
+
43
+ internal float lastSuccessTime;
44
+ internal int success;
45
+ internal int failed;
46
+
47
+ // persistent
48
+ public int successTotal;
49
+ public int failedTotal;
50
+ }
51
+
52
+ [Serializable]
53
+ internal class AdsData : IJsonFile
54
+ {
55
+ public AdStat interstitial = new AdStat();
56
+ public AdStat reward = new AdStat();
57
+
58
+ internal AdStat GetStat(AdType adType)
59
+ {
60
+ return adType == AdType.Interstitial ? interstitial : reward;
61
+ }
62
+
63
+ internal int ShowCallCount(AdType adType)
64
+ {
65
+ return GetStat(adType).callCount;
66
+ }
67
+
68
+ internal int TimeSinceLastShowCalled(AdType adType)
69
+ {
70
+ AdStat stat = GetStat(adType);
71
+ AdShowContext context = Ads.context;
72
+
73
+ // Right inside XXX_ShowCalled() callbacks
74
+ if (context != null && context.adType == adType)
75
+ {
76
+ if (stat.callCount == 1) return 0; // first call
77
+ return (int)(stat.currentCallTime - stat.prevCallTime);
78
+ }
79
+
80
+ if (stat.callCount == 0) return 0; // not yet called
81
+ return (int)(Time.realtimeSinceStartup - stat.prevCallTime);
82
+ }
83
+
84
+ internal int TimeSinceLastShowSuccess(AdType adType)
85
+ {
86
+ return (int)(Time.realtimeSinceStartup - GetStat(adType).lastSuccessTime);
87
+ }
88
+
89
+ internal void Save()
90
+ {
91
+ this.SaveJsonToFile();
92
+ }
93
+ }
94
+
95
+ [Serializable]
96
+ public class AdAdapterConfig
97
+ {
98
+
99
+ }
100
+
101
+ public partial class Ads
102
+ {
103
+ public static bool allowAdRequest = true;
104
+
105
+ // internal use
106
+ internal static readonly AdsData localData = new AdsData().LoadJsonFromFile();
107
+
108
+ internal protected static AdShowContext context;
109
+ internal protected static AdAdapter _adapter;
110
+ internal protected static float _savedVolume = -1;
111
+ internal protected static float _savedTimeScale = -1;
112
+
113
+ public static void OnInter_Request(Action callback)
114
+ {
115
+ dispatcher.AddListener(Event.INTER_REQUEST, callback);
116
+ }
117
+
118
+ public static void OnInter_ShowCalled(Action callback)
119
+ {
120
+ dispatcher.AddListener(Event.INTER_SHOW_CALLED, callback);
121
+ }
122
+
123
+ public static void OnReward_ShowCalled(Action callback)
124
+ {
125
+ dispatcher.AddListener(Event.REWARD_VIDEO_SHOW_CALLED, callback);
126
+ }
127
+
128
+ public static void OnInter_ShowReady(Action callback)
129
+ {
130
+ dispatcher.AddListener(Event.INTER_SHOW_READY, callback);
131
+ }
132
+
133
+ public static void OnReward_ShowReady(Action callback)
134
+ {
135
+ dispatcher.AddListener(Event.REWARD_VIDEO_SHOW_READY, callback);
136
+ }
137
+
138
+ public static void OnInter_ShowNotReady(Action<AdShowReadyStatus> callback)
139
+ {
140
+ dispatcher.AddListener(Event.INTER_SHOW_NOT_READY, callback);
141
+ }
142
+
143
+ public static void OnReward_ShowNotReady(Action<AdShowReadyStatus> callback)
144
+ {
145
+ dispatcher.AddListener(Event.REWARD_VIDEO_SHOW_NOT_READY, callback);
146
+ }
147
+ }
148
+
149
+ public partial class Ads // Public
150
+ {
151
+ internal static bool InitModule()
152
+ {
153
+ _adapter = Adapter2.GetAdapter<AdAdapter>();
154
+ return _adapter == null;
155
+ }
156
+
157
+ internal static void StartModule()
158
+ {
159
+ if (_adapter == null) return;
160
+
161
+ if (Config.ad.enableInterstitial) _adapter.interstitial.StartLoadAd();
162
+ if (Config.ad.enableRewarded) _adapter.rewardVideo.StartLoadAd();
163
+ if (Config.ad.preloadBanner) PreloadBanner();
164
+ if (_isBannerShowing)
165
+ {
166
+ _isBannerShowing = false;
167
+ ShowBanner();
168
+ }
169
+ }
170
+
171
+ public static bool HasInterstitial => _adapter?.interstitial.hasAd ?? false;
172
+ public static bool HasRewardedVideo => _adapter?.rewardVideo.hasAd ?? false;
173
+ public static bool IsBannerShowing => _isBannerShowing;
174
+ public static bool IsAdShowing => context != null;
175
+
176
+ private static bool ClearPrevContext()
177
+ {
178
+ if (context == null) return true;
179
+ float duration = Time.realtimeSinceStartup - context.showCallAt;
180
+ LogWarning($"[AD] ShowRequest IGNORED as another ad is showing (elapsedTime: {duration:n2}s):\n" + JsonUtility.ToJson(context, true));
181
+ return false;
182
+ }
183
+
184
+ public static IAdCallback ShowInterstitial(string placementName = null, Dictionary<string, object> userData = null)
185
+ {
186
+ if (_adapter == null) return null;
187
+ if (!ClearPrevContext()) return null;
188
+
189
+ context = new AdShowContext(AdType.Interstitial, placementName, userData);
190
+ _adapter.interstitial.StartShowAd();
191
+ return context;
192
+ }
193
+
194
+ public static bool IsInterstitialShowing => (context != null) && (context.adType == AdType.Interstitial);
195
+
196
+ public static IAdCallback ShowRewardedVideo(string placementName = null, Dictionary<string, object> userData = null)
197
+ {
198
+ if (_adapter == null) return null;
199
+ if (!ClearPrevContext()) return null;
200
+
201
+ context = new AdShowContext(AdType.VideoReward, placementName, userData);
202
+ _adapter.rewardVideo.StartShowAd();
203
+ return context;
204
+ }
205
+
206
+ public static bool IsRewardedVideoShowing => (context != null) && (context.adType == AdType.VideoReward);
207
+
208
+
209
+ [NonSerialized] private static bool _isBannerShowing = false;
210
+
211
+ public static void PreloadBanner()
212
+ {
213
+ if (!_config.ad.enableBanner)
214
+ {
215
+ LogWarning($"Banner not enabled! {_config.ad.enableBanner}");
216
+ return;
217
+ }
218
+
219
+ if (_adapter == null)
220
+ {
221
+ LogWarning($"Adapter is null!");
222
+ return;
223
+ }
224
+
225
+ if (_isBannerShowing)
226
+ {
227
+ LogWarning($"Banner is showing!");
228
+ return;
229
+ }
230
+
231
+ _adapter.ShowBanner();
232
+ _adapter.HideBanner();
233
+ }
234
+
235
+ public static void ShowBanner()
236
+ {
237
+ if (!_config.ad.enableBanner)
238
+ {
239
+ LogWarning($"Banner not enabled! {_config.ad.enableBanner}");
240
+ return;
241
+ }
242
+
243
+ if (_isBannerShowing)
244
+ {
245
+ LogWarning($"Banner is showing!");
246
+ return;
247
+ }
248
+
249
+ _isBannerShowing = true;
250
+
251
+ if (_adapter == null)
252
+ {
253
+ LogWarning($"Adapter is null!");
254
+ return;
255
+ }
256
+
257
+ dispatcher.Dispatch(Event.BANNER_SHOW);
258
+ _adapter.ShowBanner();
259
+ }
260
+
261
+ public static void HideBanner()
262
+ {
263
+ if (!_config.ad.enableBanner) return;
264
+ if (!_isBannerShowing) return;
265
+ _isBannerShowing = false;
266
+ if (_adapter == null) return;
267
+ _adapter.HideBanner();
268
+ }
269
+
270
+ public static void StopWaitForAd()
271
+ {
272
+ if (_adapter == null) return;
273
+ if (context == null)
274
+ return;
275
+
276
+ if (context.adType == AdType.Interstitial)
277
+ _adapter.interstitial.StopShowAd();
278
+ else
279
+ _adapter.rewardVideo.StopShowAd();
280
+ }
281
+
282
+ /// <summary>
283
+ /// Capping for interstitial ad
284
+ /// - Time since last interstitial show success > interstitialCappingTime
285
+ /// - Time since last rewardedVideo show success > rewardVideoCappingTime (for interstitial)
286
+ /// </summary>
287
+ /// <param name="interstitialCappingTime"></param>
288
+ /// <param name="rewardedVideoCappingTime"></param>
289
+ /// <returns></returns>
290
+ public static bool IsCapped(float interstitialCappingTime = 0, float rewardedVideoCappingTime = 0)
291
+ {
292
+ bool interCapped = (interstitialCappingTime > 0) && TimeSinceLastInterstitialSucceed < interstitialCappingTime;
293
+ bool rewardCapped = (rewardedVideoCappingTime > 0) && TimeSinceLastVideoRewardSucceed < rewardedVideoCappingTime;
294
+ return interCapped || rewardCapped;
295
+ }
296
+
297
+ public static int TimeSinceLastInterstitialSucceed => localData.TimeSinceLastShowSuccess(AdType.Interstitial);
298
+ public static int TimeSinceLastVideoRewardSucceed => localData.TimeSinceLastShowSuccess(AdType.VideoReward);
299
+ public static int TimeSinceLastAdSucceed => Math.Min(TimeSinceLastInterstitialSucceed, TimeSinceLastVideoRewardSucceed);
300
+ public static int TimeSinceLastInterstitialShowCalled => localData.TimeSinceLastShowCalled(AdType.Interstitial);
301
+ public static int TimeSinceLastVideoRewardShowCalled => localData.TimeSinceLastShowCalled(AdType.VideoReward);
302
+
303
+ public static int InterstitialShowCalledInSession => localData.ShowCallCount(AdType.Interstitial);
304
+ public static int RewardVideoShowCalledInSession => localData.ShowCallCount(AdType.VideoReward);
305
+
306
+ public static void SetUserId(string userId)
307
+ {
308
+ if (_adapter == null) return;
309
+ _adapter.SetUserId(userId);
310
+ }
311
+ }
312
+ }
313
+ }
314
+
315
+ namespace Amanotes.Core.Internal
316
+ {
317
+ [Serializable] public abstract class AdAdapter : Adapter2
318
+ {
319
+ protected AdShowContext context => Ads.context;
320
+ protected AdModuleConfig moduleConfig => Config.ad;
321
+
322
+ // APIs
323
+ internal protected abstract AdLogic interstitial { get; }
324
+ internal protected abstract AdLogic rewardVideo { get; }
325
+
326
+ public abstract void ShowBanner();
327
+ public abstract void HideBanner();
328
+
329
+ // Internally used
330
+ internal protected abstract void SetUserId(string userId);
331
+ }
332
+
333
+ public interface IAdCallback { }
334
+
335
+ public enum LoadAdsState
336
+ {
337
+ None,
338
+ Requesting,
339
+ Ready
340
+ }
341
+
342
+ public enum ShowAdsState
343
+ {
344
+ None,
345
+ ShowCalled,
346
+ WaitForAd,
347
+ Showing,
348
+ ShowFail,
349
+ ShowSuccess
350
+ }
351
+
352
+ [Flags]
353
+ public enum AdCallback
354
+ {
355
+ None = 0,
356
+ ShowCalled = 1,
357
+ ShowReadyStatus = 2,
358
+ Open = 4,
359
+ Reward = 8,
360
+ Click = 16,
361
+ Cancel = 32,
362
+ Close = 64,
363
+ Success = 128,
364
+ Fail = 256
365
+ }
366
+
367
+ public enum AdType
368
+ {
369
+ Interstitial,
370
+ VideoReward,
371
+ Banner
372
+ }
373
+
374
+ public enum AdShowReadyStatus
375
+ {
376
+ None,
377
+ Wifi3GDisabled,
378
+ NoInternet,
379
+ WaitForAd,
380
+ TimeOut,
381
+ Ready,
382
+ }
383
+ }
@@ -0,0 +1,8 @@
1
+ fileFormatVersion: 2
2
+ guid: c4fea83c1210e4247bbd31b37deeb971
3
+ folderAsset: yes
4
+ DefaultImporter:
5
+ externalObjects: {}
6
+ userData:
7
+ assetBundleName:
8
+ assetBundleVariant:
@@ -122,6 +122,19 @@ namespace Amanotes.Core
122
122
  return result;
123
123
  }
124
124
 
125
+ public static void FlushEventDetails()
126
+ {
127
+ if (Config.analytics.autoFlushEventDetail)
128
+ {
129
+ LogWarning("[Analytics] This function FlushEventDetails() is not supposed to be called manually!");
130
+ return;
131
+ }
132
+
133
+ if (!localData._dirty) return;
134
+ localData._dirty = false;
135
+ localData.SaveJsonToFile();
136
+ }
137
+
125
138
  public static IEventParamsBuilder LogFunnelEvent(string eventName, string signature = "")
126
139
  {
127
140
  return LogEvent(eventName).SetAsFunnel(signature);
@@ -293,7 +306,7 @@ namespace Amanotes.Core
293
306
  internal static readonly ConcurrentQueue<EventParams> eventQueue = new ConcurrentQueue<EventParams>();
294
307
  internal static readonly List<AnalyticsAdapter> listAdapters = new List<AnalyticsAdapter>();
295
308
  internal static readonly AnalyticsData localData = new AnalyticsData().LoadJsonFromFile().BuildCache();
296
- internal static readonly SessionStat sessionStat = _config.analytics.enableEventStat ? new SessionStat() : null;
309
+ internal static SessionStat sessionStat;
297
310
  internal static readonly GDKPool<StringBuilder> sbPool = new GDKPool<StringBuilder>(3);
298
311
  internal static readonly GDKPool<EventParams> epPool = new GDKPool<EventParams>(1);
299
312
 
@@ -341,6 +354,10 @@ namespace Amanotes.Core
341
354
 
342
355
  internal static void InitModule()
343
356
  {
357
+ if (Config.analytics.enableEventStat)
358
+ {
359
+ sessionStat = new SessionStat();
360
+ }
344
361
  listAdapters.Clear();
345
362
  listAdapters.AddRange(Adapter2.GetAllAdapter<AnalyticsAdapter>());
346
363
  }
@@ -806,6 +823,7 @@ namespace Amanotes.Core
806
823
 
807
824
  internal void SaveIfDirty()
808
825
  {
826
+ if (!Config.analytics.autoFlushEventDetail) return;
809
827
  if (!_dirty) return;
810
828
  _dirty = false;
811
829
  this.SaveJsonToFile();
@@ -1106,6 +1124,7 @@ namespace Amanotes.Core.Internal
1106
1124
  [HideInNormalInspector] public bool checkMigrationIntegrity = true;
1107
1125
  [HideInNormalInspector] public bool migrateAccumulatedCount = true;
1108
1126
  [HideInNormalInspector] public bool enableEventStat;
1127
+ [HideInNormalInspector] public bool autoFlushEventDetail = true;
1109
1128
  [HideInInspector] public List<string> immediatelyLoggedEvents = new List<string>()
1110
1129
  {
1111
1130
  "ad_impression",
@@ -0,0 +1,105 @@
1
+ using System;
2
+ using System.Text;
3
+ using Amanotes.Core.Internal;
4
+ using UnityEngine;
5
+
6
+ namespace Amanotes.Core
7
+ {
8
+ public partial class AmaGDK
9
+ {
10
+ public static GDKDevice Device = new GDKDevice();
11
+
12
+ public partial class UserProfile
13
+ {
14
+ public GDKDevice.QualitySetting QualitySetting
15
+ {
16
+ get => _qualitySetting;
17
+ set
18
+ {
19
+ _qualitySetting = value;
20
+ _dirty = true;
21
+ }
22
+ }
23
+
24
+ [SerializeField]
25
+ private GDKDevice.QualitySetting _qualitySetting;
26
+ }
27
+ }
28
+ }
29
+
30
+ namespace Amanotes.Core.Internal
31
+ {
32
+ public class GDKDevice
33
+ {
34
+ public enum DeviceSpec
35
+ {
36
+ Low,
37
+ Mid,
38
+ High
39
+ }
40
+
41
+ public enum QualitySetting
42
+ {
43
+ Auto,
44
+ Low,
45
+ Mid,
46
+ High
47
+ }
48
+
49
+ public DeviceSpec GetDeviceSpec()
50
+ {
51
+ DeviceSpec result;
52
+ switch (AmaGDK.User.QualitySetting)
53
+ {
54
+ case QualitySetting.Low:
55
+ result = DeviceSpec.Low;
56
+ break;
57
+ case QualitySetting.Mid:
58
+ result = DeviceSpec.Mid;
59
+ break;
60
+ case QualitySetting.High:
61
+ result = DeviceSpec.High; break;
62
+ case QualitySetting.Auto:
63
+ default:
64
+ result = GetDevicePerformanceSpec();
65
+ break;
66
+ }
67
+
68
+ if (AmaGDK.Config.common.logLevel == LogLevel.Verbose)
69
+ {
70
+ var stringBuilder = new StringBuilder();
71
+ stringBuilder.Append("Device info:");
72
+ stringBuilder.AppendLine("DeviceSpec: " + result);
73
+ stringBuilder.AppendLine("systemMemorySize: " + SystemInfo.systemMemorySize);
74
+ stringBuilder.AppendLine("processorCount: " + SystemInfo.processorCount);
75
+ stringBuilder.AppendLine("processorFrequency: " + SystemInfo.processorFrequency);
76
+ stringBuilder.AppendLine("graphicsMemorySize: " + SystemInfo.graphicsMemorySize);
77
+
78
+ Logging.Log(stringBuilder.ToString());
79
+ }
80
+ return result;
81
+ }
82
+
83
+ // Sentry device classify: https://github.com/getsentry/sentry/discussions/44422#discussioncomment-5149936
84
+ // Telegram android device classify: https://github.com/DrKLO/Telegram/blob/bab9943ee0d90f537adace746ab4ed76f422dd03/TMessagesProj/src/main/java/org/telegram/messenger/SharedConfig.java#L1372-L1453
85
+ // Telegram iOS device performance: https://github.com/TelegramMessenger/Telegram-iOS/blob/a568e2d878977417d1f40a9454d084e133bbc8ca/submodules/Display/Source/DeviceMetrics.swift#L9
86
+ private DeviceSpec GetDevicePerformanceSpec()
87
+ {
88
+ int memorySize = SystemInfo.systemMemorySize;
89
+ int cpuCount = SystemInfo.processorCount;
90
+ int cpuFrequency = SystemInfo.processorFrequency;
91
+ if (Application.platform == RuntimePlatform.IPhonePlayer)
92
+ {
93
+ if (cpuFrequency < 2000) return DeviceSpec.Low;
94
+ return cpuFrequency < 3000 ? DeviceSpec.Mid : DeviceSpec.High;
95
+ }
96
+ if (Application.platform == RuntimePlatform.Android)
97
+ {
98
+ if (cpuCount < 8 || memorySize < 4 * 1024 || cpuFrequency < 2000) return DeviceSpec.Low;
99
+ if (cpuFrequency < 2500 || memorySize < 6 * 1024) return DeviceSpec.Mid;
100
+ return DeviceSpec.High;
101
+ }
102
+ return DeviceSpec.Mid;
103
+ }
104
+ }
105
+ }
@@ -0,0 +1,3 @@
1
+ fileFormatVersion: 2
2
+ guid: bdf9f8e2af1d4796b769c4edbf8c1d00
3
+ timeCreated: 1719388266
@@ -19,7 +19,6 @@ namespace Amanotes.Core
19
19
  {
20
20
  time = Time.time;
21
21
  realtimeSinceStartup = Time.realtimeSinceStartup;
22
-
23
22
  var cb = unityCallbacks;
24
23
  cb.Invoke(ref cb.OnFrameUpdate);
25
24
  cb.Invoke(ref cb.DoOnceNextFrame);
package/Runtime/AmaGDK.cs CHANGED
@@ -17,7 +17,7 @@ namespace Amanotes.Core
17
17
  {
18
18
  public partial class AmaGDK : MonoBehaviour
19
19
  {
20
- public const string VERSION = "0.2.66";
20
+ public const string VERSION = "0.2.68";
21
21
 
22
22
  internal static Status _status = Status.None;
23
23
  private static ConfigAsset _config = null;
@@ -104,7 +104,11 @@ namespace Amanotes.Core
104
104
  Ads.InitModule();
105
105
  IAP.InitModule();
106
106
  RemoteConfig.InitModule();
107
- Audio.InitModule();
107
+
108
+ if (Config.enableAudioModule)
109
+ {
110
+ Audio.InitModule();
111
+ }
108
112
  }
109
113
  Profiler.EndSample();
110
114
  }
@@ -4,6 +4,15 @@ using System.Collections;
4
4
  using System.Text;
5
5
  using Amanotes.Core.Internal;
6
6
 
7
+ namespace Amanotes.Core.Internal
8
+ {
9
+ public partial class ConfigAsset
10
+ {
11
+ [SerializeField]
12
+ public bool enableAudioModule;
13
+ }
14
+ }
15
+
7
16
  namespace Amanotes.Core
8
17
  {
9
18
  public partial class AmaGDK
@@ -40,6 +49,8 @@ namespace Amanotes.Core
40
49
  /// </remarks>
41
50
  public static void SetOnAudioDeviceChangeCallback(Action<AudioDeviceInfo> onAudioDeviceChange)
42
51
  {
52
+ GDKUtils.ThrowIf(!Config.enableAudioModule, "Audio Module is disabled, Please enable it in the AmaGDKConfig");
53
+
43
54
  if (onAudioDeviceChange == null)
44
55
  {
45
56
  Logging.LogWarning("Cannot add a null callback!");
@@ -51,6 +62,8 @@ namespace Amanotes.Core
51
62
 
52
63
  public static void SetOnAudioInterruptedCallback(Action beginCallback, Action endCallback)
53
64
  {
65
+ GDKUtils.ThrowIf(!Config.enableAudioModule, "Audio Module is disabled, Please enable it in the AmaGDKConfig");
66
+
54
67
  if (beginCallback != null)
55
68
  {
56
69
  dispatcher.AddListener(Event.GDK_AUDIO_INTERRUPT_BEGIN, beginCallback);
@@ -129,6 +142,8 @@ namespace Amanotes.Core
129
142
  {
130
143
  public static bool IsConnectingBluetoothHeadset()
131
144
  {
145
+ GDKUtils.ThrowIf(!Config.enableAudioModule, "Audio Module is disabled, Please enable it in the AmaGDKConfig");
146
+
132
147
  return DeviceInfo != null
133
148
  && (DeviceInfo.RawType == "AVAudioSessionPortBluetoothA2DP"
134
149
  || DeviceInfo.RawType == "TYPE_BLUETOOTH_A2DP"
@@ -146,6 +161,7 @@ namespace Amanotes.Core
146
161
 
147
162
  public static bool IsRecordingWithMicrophone()
148
163
  {
164
+ GDKUtils.ThrowIf(!Config.enableAudioModule, "Audio Module is disabled, Please enable it in the AmaGDKConfig");
149
165
  #if UNITY_IOS
150
166
  string currentAudioInputs = GetCurrentRouteInputs();
151
167
  return string.IsNullOrWhiteSpace(currentAudioInputs) == false;
@@ -243,7 +243,7 @@ public class GDKAudioDeviceDetector
243
243
 
244
244
  private static String toTypeString(int AudioDeviceType)
245
245
  {
246
- return DEVICE_TYPE_MAP.getOrDefault(AudioDeviceType, "TYPE_UNKNOWN");
246
+ return DEVICE_TYPE_MAP.containsKey(AudioDeviceType) ? DEVICE_TYPE_MAP.get(AudioDeviceType) : "TYPE_UNKNOWN";
247
247
  }
248
248
 
249
249
  // API For Version before M
@@ -0,0 +1,44 @@
1
+ using System.Collections.Generic;
2
+ using static Amanotes.Core.Internal.Logging;
3
+ using UnityEngine;
4
+ namespace Amanotes.Core
5
+ {
6
+ public partial class AmaFPS
7
+ {
8
+ internal class Utils
9
+ {
10
+ internal static void InjectUserData(Dictionary<string, object> dictionary, Dictionary<string, object> userData)
11
+ {
12
+ if (userData == null || userData.Count == 0) return;
13
+
14
+ foreach (var kvp in userData)
15
+ {
16
+ if (dictionary.ContainsKey(kvp.Key))
17
+ {
18
+ Log("Duplicated key: " + kvp.Key);
19
+ continue;
20
+ }
21
+
22
+ dictionary.Add(kvp.Key, kvp.Value);
23
+ }
24
+ }
25
+ internal static void InjectDeviceInfo(Dictionary<string, object> dictionary)
26
+ {
27
+ var resolution = Screen.currentResolution;
28
+ dictionary.Add("system_memory_size", SystemInfo.systemMemorySize);
29
+ dictionary.Add("graphics_memory_size", SystemInfo.graphicsMemorySize);
30
+ dictionary.Add("graphics_device_type", SystemInfo.graphicsDeviceType);
31
+ dictionary.Add("graphics_shader_level", SystemInfo.graphicsShaderLevel);
32
+ dictionary.Add("processor_count", SystemInfo.processorCount);
33
+ dictionary.Add("processor_frequency", SystemInfo.processorFrequency);
34
+ dictionary.Add("screen_width", resolution.width);
35
+ dictionary.Add("screen_height", resolution.height);
36
+ dictionary.Add("screen_refresh_rate", resolution.refreshRate);
37
+ }
38
+ internal static void InjectDeviceStatus(Dictionary<string, object> dictionary)
39
+ {
40
+ dictionary.Add("battery_level", Mathf.RoundToInt(SystemInfo.batteryLevel * 100));
41
+ }
42
+ }
43
+ }
44
+ }