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.
- package/CHANGELOG.md +19 -0
- package/Editor/Extra/GDKAutoUpdateAdapter.cs +67 -0
- package/Editor/Extra/GDKAutoUpdateAdapter.cs.meta +11 -0
- package/Extra/AmaGDKInstaller.unitypackage +0 -0
- package/Extra/CheckDiskSpace.unitypackage +0 -0
- package/Extra/ForceUpdate.unitypackage +0 -0
- package/Extra/GoogleCMP.unitypackage +0 -0
- package/Extra/LegacyGDKUpdateHelper.unitypackage +0 -0
- package/Extra/LegacyGDKUpdateHelper.unitypackage.meta +7 -0
- package/Extra/PostProcessor.unitypackage +0 -0
- package/Packages/AmaGDKConfig.unitypackage +0 -0
- package/Packages/AmaGDKExample.unitypackage +0 -0
- package/Packages/AmaGDKTest.unitypackage +0 -0
- package/Packages/AppsFlyerAdapter.PurchaseConnector.unitypackage +0 -0
- package/Packages/AppsFlyerAdapter.unitypackage +0 -0
- package/Packages/FirebaseAnalyticsAdapter.unitypackage +0 -0
- package/Packages/FirebaseRemoteConfigAdapter.unitypackage +0 -0
- package/Packages/IronSourceAdapter.unitypackage +0 -0
- package/Packages/RevenueCatAdapter.unitypackage +0 -0
- package/Packages/SqliteAnalyticsAdapter.unitypackage +0 -0
- package/Runtime/Ad/AdExtension.cs +111 -0
- package/Runtime/Ad/AdExtension.cs.meta +3 -0
- package/Runtime/Ad/AdLogic.cs +530 -0
- package/Runtime/Ad/AdLogic.cs.meta +3 -0
- package/Runtime/Ad/AdModuleConfig.cs +39 -0
- package/Runtime/Ad/AdModuleConfig.cs.meta +3 -0
- package/Runtime/Ad/AdShowContext.cs +43 -0
- package/Runtime/Ad/AdShowContext.cs.meta +3 -0
- package/Runtime/Ad/AmaGDK.Ads.cs +383 -0
- package/Runtime/Ad.meta +8 -0
- package/Runtime/AmaGDK.Analytics.cs +20 -1
- package/Runtime/AmaGDK.Device.cs +105 -0
- package/Runtime/AmaGDK.Device.cs.meta +3 -0
- package/Runtime/AmaGDK.Mono.cs +0 -1
- package/Runtime/AmaGDK.cs +6 -2
- package/Runtime/AudioToolkit/AmaGDK.Audio.cs +16 -0
- package/Runtime/AudioToolkit/Plugins/Android/GDKAudioDeviceDetector.java +1 -1
- package/Runtime/Fps/AmaFPS.Utils.cs +44 -0
- package/Runtime/Fps/AmaFPS.Utils.cs.meta +3 -0
- package/Runtime/Fps/AmaFPS.cs +197 -0
- package/Runtime/Fps/AmaFPS.cs.meta +11 -0
- package/Runtime/Fps/AmaFPSVisualizer.cs +246 -0
- package/Runtime/Fps/AmaFPSVisualizer.cs.meta +11 -0
- package/Runtime/Fps/BollingerBands.cs +99 -0
- package/Runtime/Fps/BollingerBands.cs.meta +11 -0
- package/Runtime/Fps/FPSVisualizer.prefab +406 -0
- package/Runtime/Fps/FPSVisualizer.prefab.meta +7 -0
- package/Runtime/Fps/FrameRecorder.cs +172 -0
- package/Runtime/Fps/FrameRecorder.cs.meta +3 -0
- package/Runtime/Fps.meta +8 -0
- package/package.json +1 -1
- package/Runtime/AmaGDK.Ads.cs +0 -1077
- /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
|
+
}
|
package/Runtime/Ad.meta
ADDED
|
@@ -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
|
|
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
|
+
}
|
package/Runtime/AmaGDK.Mono.cs
CHANGED
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.
|
|
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
|
-
|
|
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.
|
|
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
|
+
}
|