expo-ads 0.1.0 → 0.1.1

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 (55) hide show
  1. package/.prettierrc +8 -8
  2. package/CHANGELOG.md +11 -11
  3. package/LICENSE +21 -21
  4. package/README.md +44 -44
  5. package/android/build.gradle +33 -33
  6. package/android/src/main/AndroidManifest.xml +25 -22
  7. package/android/src/main/java/expo/modules/ads/google/GoogleAdsModule.kt +17 -17
  8. package/android/src/main/java/expo/modules/ads/meta/MetaAdsInitializer.kt +107 -107
  9. package/android/src/main/java/expo/modules/ads/meta/MetaAdsModule.kt +93 -40
  10. package/android/src/main/java/expo/modules/ads/meta/MetaBannerAdSize.kt +26 -0
  11. package/android/src/main/java/expo/modules/ads/meta/MetaBannerAdView.kt +127 -0
  12. package/build/google/ExpoAdsGoogleModule.js.map +1 -1
  13. package/build/google/index.js.map +1 -1
  14. package/build/meta/ExpoAdsMetaModule.d.ts +34 -0
  15. package/build/meta/ExpoAdsMetaModule.d.ts.map +1 -1
  16. package/build/meta/ExpoAdsMetaModule.js.map +1 -1
  17. package/build/meta/ads/BannerAd.d.ts +16 -0
  18. package/build/meta/ads/BannerAd.d.ts.map +1 -0
  19. package/build/meta/ads/BannerAd.js +37 -0
  20. package/build/meta/ads/BannerAd.js.map +1 -0
  21. package/build/meta/ads/MetaBannerAdSize.d.ts +24 -0
  22. package/build/meta/ads/MetaBannerAdSize.d.ts.map +1 -0
  23. package/build/meta/ads/MetaBannerAdSize.js +25 -0
  24. package/build/meta/ads/MetaBannerAdSize.js.map +1 -0
  25. package/build/meta/index.d.ts +4 -0
  26. package/build/meta/index.d.ts.map +1 -1
  27. package/build/meta/index.js +2 -0
  28. package/build/meta/index.js.map +1 -1
  29. package/build/meta/specs/components/ExpoAdsMetaBannerViewNativeComponent.d.ts +27 -0
  30. package/build/meta/specs/components/ExpoAdsMetaBannerViewNativeComponent.d.ts.map +1 -0
  31. package/build/meta/specs/components/ExpoAdsMetaBannerViewNativeComponent.js +5 -0
  32. package/build/meta/specs/components/ExpoAdsMetaBannerViewNativeComponent.js.map +1 -0
  33. package/build/meta/types/MetaAdError.d.ts +29 -0
  34. package/build/meta/types/MetaAdError.d.ts.map +1 -0
  35. package/build/meta/types/MetaAdError.js +2 -0
  36. package/build/meta/types/MetaAdError.js.map +1 -0
  37. package/build/meta/types/MetaBannerAdProps.d.ts +63 -0
  38. package/build/meta/types/MetaBannerAdProps.d.ts.map +1 -0
  39. package/build/meta/types/MetaBannerAdProps.js +2 -0
  40. package/build/meta/types/MetaBannerAdProps.js.map +1 -0
  41. package/eslint.config.cjs +5 -5
  42. package/expo-module.config.json +13 -13
  43. package/ios/Expo-ads.podspec +23 -23
  44. package/ios/Expo-adsModule.swift +7 -7
  45. package/package.json +4 -2
  46. package/src/google/ExpoAdsGoogleModule.ts +6 -6
  47. package/src/google/index.ts +5 -5
  48. package/src/meta/ExpoAdsMetaModule.ts +44 -7
  49. package/src/meta/ads/BannerAd.tsx +63 -0
  50. package/src/meta/ads/MetaBannerAdSize.tsx +25 -0
  51. package/src/meta/index.ts +12 -3
  52. package/src/meta/specs/components/ExpoAdsMetaBannerViewNativeComponent.ts +32 -0
  53. package/src/meta/types/MetaAdError.ts +31 -0
  54. package/src/meta/types/MetaBannerAdProps.ts +65 -0
  55. package/tsconfig.json +28 -28
package/.prettierrc CHANGED
@@ -1,8 +1,8 @@
1
- {
2
- "printWidth": 100,
3
- "tabWidth": 2,
4
- "singleQuote": true,
5
- "bracketSameLine": true,
6
- "trailingComma": "es5",
7
- "jsxSingleQuote": false,
8
- }
1
+ {
2
+ "printWidth": 100,
3
+ "tabWidth": 2,
4
+ "singleQuote": true,
5
+ "bracketSameLine": true,
6
+ "trailingComma": "es5",
7
+ "jsxSingleQuote": false,
8
+ }
package/CHANGELOG.md CHANGED
@@ -1,11 +1,11 @@
1
- # Changelog
2
-
3
- ## Unpublished
4
-
5
- ### 🛠 Breaking changes
6
-
7
- ### 🎉 New features
8
-
9
- ### 🐛 Bug fixes
10
-
11
- ### 💡 Others
1
+ # Changelog
2
+
3
+ ## Unpublished
4
+
5
+ ### 🛠 Breaking changes
6
+
7
+ ### 🎉 New features
8
+
9
+ ### 🐛 Bug fixes
10
+
11
+ ### 💡 Others
package/LICENSE CHANGED
@@ -1,21 +1,21 @@
1
- The MIT License (MIT)
2
-
3
- Copyright (c) 2015-present 650 Industries, Inc. (aka Expo)
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015-present 650 Industries, Inc. (aka Expo)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,44 +1,44 @@
1
- # Expo Ads
2
-
3
- > 🚧 **This package is currently under construction.**
4
-
5
- **Expo Ads** is a React Native / Expo native module for integrating mobile advertising networks into Expo applications.
6
-
7
- ## Status
8
-
9
- **⚠️ Work in Progress**
10
-
11
- This package is currently under active development. APIs, features, configuration, and implementation details may change without notice.
12
-
13
- **Not recommended for production use yet.**
14
-
15
- ## Planned Ad Networks
16
-
17
- - Google Mobile Ads
18
- - Meta Audience Network
19
-
20
- <!-- ## Planned Features
21
-
22
- - Google Mobile Ads initialization
23
- - Meta Audience Network initialization
24
- - Banner Ads
25
- - Interstitial Ads
26
- - Rewarded Ads
27
- - Native Ads
28
- - Expo config plugin support
29
- - Android support
30
- - iOS support
31
- - TypeScript API
32
- - Expo/EAS Build compatibility
33
-
34
- ## Installation
35
-
36
- Installation instructions will be provided once the package reaches a stable release.
37
-
38
- ## Development
39
-
40
- This package is currently being developed and tested locally with Expo and React Native. -->
41
-
42
- ## License
43
-
44
- MIT
1
+ # Expo Ads
2
+
3
+ > 🚧 **This package is currently under construction.**
4
+
5
+ **Expo Ads** is a React Native / Expo native module for integrating mobile advertising networks into Expo applications.
6
+
7
+ ## Status
8
+
9
+ **⚠️ Work in Progress**
10
+
11
+ This package is currently under active development. APIs, features, configuration, and implementation details may change without notice.
12
+
13
+ **Not recommended for production use yet.**
14
+
15
+ ## Planned Ad Networks
16
+
17
+ - Google Mobile Ads
18
+ - Meta Audience Network
19
+
20
+ <!-- ## Planned Features
21
+
22
+ - Google Mobile Ads initialization
23
+ - Meta Audience Network initialization
24
+ - Banner Ads
25
+ - Interstitial Ads
26
+ - Rewarded Ads
27
+ - Native Ads
28
+ - Expo config plugin support
29
+ - Android support
30
+ - iOS support
31
+ - TypeScript API
32
+ - Expo/EAS Build compatibility
33
+
34
+ ## Installation
35
+
36
+ Installation instructions will be provided once the package reaches a stable release.
37
+
38
+ ## Development
39
+
40
+ This package is currently being developed and tested locally with Expo and React Native. -->
41
+
42
+ ## License
43
+
44
+ MIT
@@ -1,34 +1,34 @@
1
- import groovy.json.JsonSlurper
2
-
3
- plugins {
4
- id 'com.android.library'
5
- id 'expo-module-gradle-plugin'
6
- }
7
-
8
- group = 'expo.modules.ads'
9
- version = '0.1.0'
10
-
11
- def packageJson = new JsonSlurper().parseText(file("${projectDir}/../package.json").text)
12
-
13
- def metaAudienceNetworkVersion = packageJson.sdkVersions.android.metaAudienceNetwork
14
- def playServicesAdsIdentifierVersion = packageJson.sdkVersions.android.playServicesAdsIdentifier
15
- def playServicesBasementVersion = packageJson.sdkVersions.android.playServicesBasement
16
-
17
- android {
18
- namespace "expo.modules.ads"
19
- defaultConfig {
20
- versionCode 1
21
- versionName "0.1.0"
22
- }
23
- lintOptions {
24
- abortOnError false
25
- }
26
- }
27
-
28
-
29
-
30
- dependencies {
31
- implementation("com.facebook.android:audience-network-sdk:${metaAudienceNetworkVersion}")
32
- implementation("com.google.android.gms:play-services-ads-identifier:${playServicesAdsIdentifierVersion}")
33
- implementation("com.google.android.gms:play-services-basement:${playServicesBasementVersion}")
1
+ import groovy.json.JsonSlurper
2
+
3
+ plugins {
4
+ id 'com.android.library'
5
+ id 'expo-module-gradle-plugin'
6
+ }
7
+
8
+ group = 'expo.modules.ads'
9
+ version = '0.1.1'
10
+
11
+ def packageJson = new JsonSlurper().parseText(file("${projectDir}/../package.json").text)
12
+
13
+ def metaAudienceNetworkVersion = packageJson.sdkVersions.android.metaAudienceNetwork
14
+ def playServicesAdsIdentifierVersion = packageJson.sdkVersions.android.playServicesAdsIdentifier
15
+ def playServicesBasementVersion = packageJson.sdkVersions.android.playServicesBasement
16
+
17
+ android {
18
+ namespace "expo.modules.ads"
19
+ defaultConfig {
20
+ versionCode 1
21
+ versionName "0.1.1"
22
+ }
23
+ lintOptions {
24
+ abortOnError false
25
+ }
26
+ }
27
+
28
+
29
+
30
+ dependencies {
31
+ implementation("com.facebook.android:audience-network-sdk:${metaAudienceNetworkVersion}")
32
+ implementation("com.google.android.gms:play-services-ads-identifier:${playServicesAdsIdentifierVersion}")
33
+ implementation("com.google.android.gms:play-services-basement:${playServicesBasementVersion}")
34
34
  }
@@ -1,23 +1,26 @@
1
- <?xml version="1.0" encoding="utf-8"?>
2
- <manifest xmlns:android="http://schemas.android.com/apk/res/android"
3
- package="expo.modules.meta">
4
-
5
- <uses-permission android:name="android.permission.INTERNET" />
6
- <uses-permission android:name="android.permission.WAKE_LOCK" />
7
- <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
8
-
9
- <application>
10
- <meta-data
11
- android:name="com.google.android.gms.ads.APPLICATION_ID"
12
- android:value="${appJSONGoogleMobileAdsAppID}"/>
13
- <meta-data
14
- android:name="com.google.android.gms.ads.DELAY_APP_MEASUREMENT_INIT"
15
- android:value="${appJSONGoogleMobileAdsDelayAppMeasurementInit}"/>
16
- <meta-data
17
- android:name="com.google.android.gms.ads.flag.OPTIMIZE_INITIALIZATION"
18
- android:value="${appJSONGoogleMobileAdsOptimizeInitialization}"/>
19
- <meta-data
20
- android:name="com.google.android.gms.ads.flag.OPTIMIZE_AD_LOADING"
21
- android:value="${appJSONGoogleMobileAdsOptimizeAdLoading}"/>
22
- </application>
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android">
3
+
4
+ <uses-permission android:name="android.permission.INTERNET" />
5
+ <uses-permission android:name="android.permission.WAKE_LOCK" />
6
+ <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
7
+
8
+ <application>
9
+ <meta-data
10
+ android:name="com.google.android.gms.ads.APPLICATION_ID"
11
+ android:value="${appJSONGoogleMobileAdsAppID}" />
12
+
13
+ <meta-data
14
+ android:name="com.google.android.gms.ads.DELAY_APP_MEASUREMENT_INIT"
15
+ android:value="${appJSONGoogleMobileAdsDelayAppMeasurementInit}" />
16
+
17
+ <meta-data
18
+ android:name="com.google.android.gms.ads.flag.OPTIMIZE_INITIALIZATION"
19
+ android:value="${appJSONGoogleMobileAdsOptimizeInitialization}" />
20
+
21
+ <meta-data
22
+ android:name="com.google.android.gms.ads.flag.OPTIMIZE_AD_LOADING"
23
+ android:value="${appJSONGoogleMobileAdsOptimizeAdLoading}" />
24
+ </application>
25
+
23
26
  </manifest>
@@ -1,17 +1,17 @@
1
- package expo.modules.ads.google
2
-
3
- import expo.modules.kotlin.modules.Module
4
- import expo.modules.kotlin.modules.ModuleDefinition
5
-
6
- /**
7
- * Placeholder module for Google Mobile Ads support.
8
- * Will be filled in once the Meta implementation is complete.
9
- */
10
- class GoogleAdsModule : Module() {
11
- override fun definition() = ModuleDefinition {
12
- Name("ExpoAdsGoogle") // the name JS uses to find this module (import from "expo-ads/google")
13
-
14
- // TODO: implement Google Mobile Ads initialization + functions here,
15
- // mirroring the structure of MetaAdsModule / MetaAdsInitializer.
16
- }
17
- }
1
+ package expo.modules.ads.google
2
+
3
+ import expo.modules.kotlin.modules.Module
4
+ import expo.modules.kotlin.modules.ModuleDefinition
5
+
6
+ /**
7
+ * Placeholder module for Google Mobile Ads support.
8
+ * Will be filled in once the Meta implementation is complete.
9
+ */
10
+ class GoogleAdsModule : Module() {
11
+ override fun definition() = ModuleDefinition {
12
+ Name("ExpoAdsGoogle") // the name JS uses to find this module (import from "expo-ads/google")
13
+
14
+ // TODO: implement Google Mobile Ads initialization + functions here,
15
+ // mirroring the structure of MetaAdsModule / MetaAdsInitializer.
16
+ }
17
+ }
@@ -1,108 +1,108 @@
1
- package expo.modules.ads.meta
2
-
3
- import android.content.Context
4
- import android.content.pm.ApplicationInfo
5
- import android.os.Handler
6
- import android.os.Looper
7
- import android.util.Log
8
- import com.facebook.ads.AdSettings
9
- import com.facebook.ads.AudienceNetworkAds
10
-
11
- object MetaAdsInitializer : AudienceNetworkAds.InitListener {
12
-
13
- const val TAG = "ExpoAdsMeta"
14
-
15
- private enum class State { IDLE, INITIALIZING, READY, FAILED }
16
-
17
- private val lock = Any()
18
- private var state = State.IDLE
19
- private var lastMessage = ""
20
- private val pending = mutableListOf<(Boolean, String) -> Unit>()
21
-
22
- fun isReady(): Boolean = synchronized(lock) { state == State.READY }
23
-
24
- fun whenReady(context: Context, callback: (success: Boolean, message: String) -> Unit) {
25
- val appContext = context.applicationContext
26
- var startInit = false
27
- var immediate: Pair<Boolean, String>? = null
28
-
29
- synchronized(lock) {
30
- when (state) {
31
- State.READY -> {
32
- Log.d(TAG, "[Init] Already initialized, running callback immediately")
33
- immediate = true to lastMessage
34
- }
35
- State.INITIALIZING -> {
36
- pending.add(callback)
37
- Log.d(TAG, "[Init] Initialization in progress, callback queued (${pending.size} waiting)")
38
- }
39
- State.IDLE -> {
40
- Log.i(TAG, "[Init] First-time initialization requested")
41
- state = State.INITIALIZING
42
- pending.add(callback)
43
- startInit = true
44
- }
45
- State.FAILED -> {
46
- Log.w(TAG, "[Init] Previous initialization failed ($lastMessage), retrying")
47
- state = State.INITIALIZING
48
- pending.add(callback)
49
- startInit = true
50
- }
51
- }
52
- }
53
-
54
- immediate?.let { callback(it.first, it.second); return }
55
-
56
- if (startInit) {
57
- Handler(Looper.getMainLooper()).post { doInitialize(appContext) }
58
- }
59
- }
60
-
61
- private fun doInitialize(context: Context) {
62
- try {
63
- if (AudienceNetworkAds.isInitialized(context)) {
64
- Log.i(TAG, "[Init] SDK reports it is already initialized (skipping initialize())")
65
- finish(true, "Already initialized")
66
- return
67
- }
68
-
69
- val isDebuggable = (context.applicationInfo.flags and ApplicationInfo.FLAG_DEBUGGABLE) != 0
70
- if (isDebuggable) {
71
- AdSettings.turnOnSDKDebugger(context)
72
- Log.d(TAG, "[Debug] SDK debugger ENABLED (debuggable build)")
73
- } else {
74
- Log.d(TAG, "[Debug] SDK debugger NOT set (release build)")
75
- }
76
-
77
- Log.i(TAG, "[Init] Calling AudienceNetworkAds.initialize()")
78
- AudienceNetworkAds
79
- .buildInitSettings(context)
80
- .withInitListener(this)
81
- .initialize()
82
- } catch (e: Exception) {
83
- Log.e(TAG, "[Init] initialize() threw an exception: ${e.message}", e)
84
- finish(false, e.message ?: "Unknown exception during initialize")
85
- }
86
- }
87
-
88
- override fun onInitialized(result: AudienceNetworkAds.InitResult) {
89
- if (result.isSuccess) {
90
- Log.i(TAG, "[Init] SUCCESS: ${result.message}")
91
- } else {
92
- Log.e(TAG, "[Init] FAILED: ${result.message}")
93
- }
94
- finish(result.isSuccess, result.message)
95
- }
96
-
97
- private fun finish(success: Boolean, message: String) {
98
- val callbacks: List<(Boolean, String) -> Unit>
99
- synchronized(lock) {
100
- state = if (success) State.READY else State.FAILED
101
- lastMessage = message
102
- callbacks = pending.toList()
103
- pending.clear()
104
- }
105
- Log.d(TAG, "[Init] Notifying ${callbacks.size} waiting callback(s), success=$success")
106
- callbacks.forEach { it(success, message) }
107
- }
1
+ package expo.modules.ads.meta
2
+
3
+ import android.content.Context
4
+ import android.content.pm.ApplicationInfo
5
+ import android.os.Handler
6
+ import android.os.Looper
7
+ import android.util.Log
8
+ import com.facebook.ads.AdSettings
9
+ import com.facebook.ads.AudienceNetworkAds
10
+
11
+ object MetaAdsInitializer : AudienceNetworkAds.InitListener {
12
+
13
+ const val TAG = "ExpoAdsMeta"
14
+
15
+ private enum class State { IDLE, INITIALIZING, READY, FAILED }
16
+
17
+ private val lock = Any()
18
+ private var state = State.IDLE
19
+ private var lastMessage = ""
20
+ private val pending = mutableListOf<(Boolean, String) -> Unit>()
21
+
22
+ fun isReady(): Boolean = synchronized(lock) { state == State.READY }
23
+
24
+ fun whenReady(context: Context, callback: (success: Boolean, message: String) -> Unit) {
25
+ val appContext = context.applicationContext
26
+ var startInit = false
27
+ var immediate: Pair<Boolean, String>? = null
28
+
29
+ synchronized(lock) {
30
+ when (state) {
31
+ State.READY -> {
32
+ Log.d(TAG, "[Init] Already initialized, running callback immediately")
33
+ immediate = true to lastMessage
34
+ }
35
+ State.INITIALIZING -> {
36
+ pending.add(callback)
37
+ Log.d(TAG, "[Init] Initialization in progress, callback queued (${pending.size} waiting)")
38
+ }
39
+ State.IDLE -> {
40
+ Log.i(TAG, "[Init] First-time initialization requested")
41
+ state = State.INITIALIZING
42
+ pending.add(callback)
43
+ startInit = true
44
+ }
45
+ State.FAILED -> {
46
+ Log.w(TAG, "[Init] Previous initialization failed ($lastMessage), retrying")
47
+ state = State.INITIALIZING
48
+ pending.add(callback)
49
+ startInit = true
50
+ }
51
+ }
52
+ }
53
+
54
+ immediate?.let { callback(it.first, it.second); return }
55
+
56
+ if (startInit) {
57
+ Handler(Looper.getMainLooper()).post { doInitialize(appContext) }
58
+ }
59
+ }
60
+
61
+ private fun doInitialize(context: Context) {
62
+ try {
63
+ if (AudienceNetworkAds.isInitialized(context)) {
64
+ Log.i(TAG, "[Init] SDK reports it is already initialized (skipping initialize())")
65
+ finish(true, "Already initialized")
66
+ return
67
+ }
68
+
69
+ val isDebuggable = (context.applicationInfo.flags and ApplicationInfo.FLAG_DEBUGGABLE) != 0
70
+ if (isDebuggable) {
71
+ AdSettings.turnOnSDKDebugger(context)
72
+ Log.d(TAG, "[Debug] SDK debugger ENABLED (debuggable build)")
73
+ } else {
74
+ Log.d(TAG, "[Debug] SDK debugger NOT set (release build)")
75
+ }
76
+
77
+ Log.i(TAG, "[Init] Calling AudienceNetworkAds.initialize()")
78
+ AudienceNetworkAds
79
+ .buildInitSettings(context)
80
+ .withInitListener(this)
81
+ .initialize()
82
+ } catch (e: Exception) {
83
+ Log.e(TAG, "[Init] initialize() threw an exception: ${e.message}", e)
84
+ finish(false, e.message ?: "Unknown exception during initialize")
85
+ }
86
+ }
87
+
88
+ override fun onInitialized(result: AudienceNetworkAds.InitResult) {
89
+ if (result.isSuccess) {
90
+ Log.i(TAG, "[Init] SUCCESS: ${result.message}")
91
+ } else {
92
+ Log.e(TAG, "[Init] FAILED: ${result.message}")
93
+ }
94
+ finish(result.isSuccess, result.message)
95
+ }
96
+
97
+ private fun finish(success: Boolean, message: String) {
98
+ val callbacks: List<(Boolean, String) -> Unit>
99
+ synchronized(lock) {
100
+ state = if (success) State.READY else State.FAILED
101
+ lastMessage = message
102
+ callbacks = pending.toList()
103
+ pending.clear()
104
+ }
105
+ Log.d(TAG, "[Init] Notifying ${callbacks.size} waiting callback(s), success=$success")
106
+ callbacks.forEach { it(success, message) }
107
+ }
108
108
  }