com.azerion.bluestack 3.4.1 → 6.0.0-beta.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.
- package/CHANGELOG.md +95 -0
- package/CLAUDE.md +157 -0
- package/CLAUDE.md.meta +7 -0
- package/Editor/Android/AndroidDependencyParser.cs +5 -2
- package/Editor/BlueStackAssetPostProcessor.cs +5 -2
- package/Editor/BlueStackDependenciesSource.xml +9 -9
- package/Editor/BlueStackSettings.cs +8 -0
- package/Editor/BlueStackSettingsEditor.cs +70 -19
- package/Editor/BlueStackVersionExporter.cs +214 -0
- package/Editor/BlueStackVersionExporter.cs.meta +2 -0
- package/Editor/Prefabs/AdPrefabs/Banners/Banner.prefab +53 -17
- package/Editor/Prefabs/AdPrefabs/Banners/DynamicBanner.prefab +49 -12
- package/Editor/Prefabs/AdPrefabs/Banners/DynamicLeaderboard.prefab +417 -0
- package/Editor/Prefabs/AdPrefabs/Banners/DynamicLeaderboard.prefab.meta +8 -0
- package/Editor/Prefabs/AdPrefabs/Banners/FullBanner.prefab +53 -17
- package/Editor/Prefabs/AdPrefabs/Banners/LargeBanner.prefab +53 -17
- package/Editor/Prefabs/AdPrefabs/Banners/Leaderboard.prefab +53 -17
- package/Editor/Prefabs/AdPrefabs/Banners/MediumRectangle.prefab +53 -17
- package/Editor/iOS/{BlueStackBuildPostProcess.cs → IOSBuildPostProcess.cs} +1 -1
- package/Example/Scripts/AnchoredBannerExample.cs +179 -0
- package/Example/Scripts/AnchoredBannerExample.cs.meta +2 -0
- package/Example/Scripts/BannerAnchor.cs +75 -0
- package/Example/Scripts/BannerAnchor.cs.meta +2 -0
- package/Example/Scripts/NativeAdManager.cs +24 -27
- package/Example/Scripts/SmallNativeAdManager.cs +24 -27
- package/Plugins/Android/bluestack-unity-android-bridge-600.aar +0 -0
- package/Plugins/Android/bluestack-unity-android-bridge-600.aar.meta +2 -0
- package/Plugins/iOS/BSUBanner.h +35 -16
- package/Plugins/iOS/BSUBanner.swift +435 -55
- package/Plugins/iOS/BSUInitializer.h +5 -4
- package/Plugins/iOS/BSUInitializer.swift +30 -58
- package/Plugins/iOS/BSUInterface.h +63 -48
- package/Plugins/iOS/BSUInterface.m +161 -135
- package/Plugins/iOS/BSUInterstitialAd.h +9 -7
- package/Plugins/iOS/BSUInterstitialAd.swift +57 -30
- package/Plugins/iOS/BSULogger.h +22 -0
- package/Plugins/iOS/{BSURewardedVideoAd.h.meta → BSULogger.h.meta} +5 -5
- package/Plugins/iOS/BSULogger.swift +60 -0
- package/Plugins/iOS/{BSURewardedVideoAd.swift.meta → BSULogger.swift.meta} +5 -5
- package/Plugins/iOS/BSUNativeAd.h +2 -2
- package/Plugins/iOS/BSUNativeAd.swift +16 -15
- package/Plugins/iOS/BSUPluginUtil.h +11 -1
- package/Plugins/iOS/BSUPluginUtil.swift +24 -0
- package/Plugins/iOS/BSURequestOptions.h +13 -5
- package/Plugins/iOS/BSURequestOptions.swift +46 -42
- package/Plugins/iOS/BSURewardedAd.h +34 -0
- package/Plugins/iOS/BSURewardedAd.h.meta +2 -0
- package/Plugins/iOS/BSURewardedAd.swift +136 -0
- package/Plugins/iOS/BSURewardedAd.swift.meta +2 -0
- package/Plugins/iOS/BSUTypes.h +25 -23
- package/Plugins/iOS/BSUTypes.swift +24 -22
- package/Plugins/iOS/MaskView.swift +24 -0
- package/Plugins/iOS/MaskView.swift.meta +2 -0
- package/README.md +58 -31
- package/Runtime/API/AdSize.cs +34 -6
- package/Runtime/API/AdapterStatus.cs +14 -1
- package/Runtime/API/Banner/AdMaskHandler.cs +176 -0
- package/Runtime/API/Banner/AdMaskHandler.cs.meta +2 -0
- package/Runtime/API/Banner/AdPlacementHandler.cs +329 -0
- package/Runtime/API/Banner/AdPlacementHandler.cs.meta +11 -0
- package/Runtime/API/Banner/AdPosition.cs +13 -1
- package/Runtime/API/Banner/BannerAd.cs +362 -27
- package/Runtime/API/Banner/PreferredBannerSize.cs +27 -0
- package/Runtime/API/Banner/PreferredBannerSize.cs.meta +2 -0
- package/Runtime/API/BlueStackAds.cs +66 -36
- package/Runtime/API/BlueStackError.cs +12 -1
- package/Runtime/API/InitializationStatus.cs +25 -0
- package/Runtime/API/InterstitialAd.cs +64 -19
- package/Runtime/API/NativeAd/NativeAd.cs +45 -17
- package/Runtime/API/NativeAd/NativeAdEventArgs.cs +6 -2
- package/Runtime/API/NativeAd/NativeAdInteractionHandler.cs +21 -6
- package/Runtime/API/NativeAd/NativeAdLoader.cs +29 -3
- package/Runtime/API/NativeAd/NativeAdObject.cs +7 -23
- package/Runtime/API/NativeAd/NativeAdType.cs +11 -1
- package/Runtime/API/NativeAd/NativeAssetInfo.cs +23 -1
- package/Runtime/API/RequestOptions/Gender.cs +15 -0
- package/Runtime/API/RequestOptions/Location.cs +52 -0
- package/Runtime/API/RequestOptions/RequestOptions.cs +66 -0
- package/{Plugins/iOS/BSUBanner.swift.wip.meta → Runtime/API/RequestOptions.meta} +2 -1
- package/Runtime/API/Rewarded/Reward.cs +15 -2
- package/Runtime/API/Rewarded/RewardedAd.cs +129 -0
- package/Runtime/API/Rewarded/RewardedItem.cs +15 -2
- package/Runtime/API/SDKInitializationStatus.cs +6 -1
- package/Runtime/Common/AdsMainThreadDispatcher.cs +70 -0
- package/Runtime/Common/BlueStackLogger.cs +126 -0
- package/Runtime/Common/BlueStackLogger.cs.meta +2 -0
- package/Runtime/Common/BlueStackSdkInfo.cs +10 -0
- package/Runtime/Common/BlueStackSdkInfo.cs.meta +2 -0
- package/Runtime/Common/NativeAd/NativeUtils.cs +4 -4
- package/Runtime/Internal/IBannerAdClient.cs +21 -9
- package/Runtime/Internal/IBlueStackClient.cs +8 -3
- package/Runtime/Internal/IClientsFactory.cs +1 -3
- package/Runtime/Internal/IInterstitialAdClient.cs +8 -6
- package/Runtime/Internal/IRewardedAdClient.cs +23 -0
- package/Runtime/Internal/NativeAd/INativeAdClient.cs +1 -1
- package/Runtime/Platforms/Android/AndroidJavaObjectFactory.cs +6 -6
- package/Runtime/Platforms/Android/BannerAdClient.cs +80 -31
- package/Runtime/Platforms/Android/BlueStackClient.cs +40 -162
- package/Runtime/Platforms/Android/BlueStackNativeClassNames.cs +8 -16
- package/Runtime/Platforms/Android/ClientsFactory.cs +2 -13
- package/Runtime/Platforms/Android/InitializationStatusClient.cs +57 -5
- package/Runtime/Platforms/Android/InterstitialAdClient.cs +34 -14
- package/Runtime/Platforms/Android/NativeAdClient.cs +14 -12
- package/Runtime/Platforms/Android/RequestOptionsClient.cs +76 -0
- package/Runtime/Platforms/Android/RequestOptionsClient.cs.meta +2 -0
- package/Runtime/Platforms/Android/RewardedAdClient.cs +129 -0
- package/Runtime/Platforms/Unity/AdBehaviour.cs +0 -3
- package/Runtime/Platforms/Unity/AdvertisementManager.cs +6 -6
- package/Runtime/Platforms/Unity/BannerAdClient.cs +299 -121
- package/Runtime/Platforms/Unity/BaseAdClient.cs +3 -2
- package/Runtime/Platforms/Unity/BlueStackClient.cs +53 -4
- package/Runtime/Platforms/Unity/ClientsFactory.cs +2 -7
- package/Runtime/Platforms/Unity/InterstitialAdClient.cs +23 -13
- package/Runtime/Platforms/Unity/NativeAdClient.cs +3 -5
- package/Runtime/Platforms/Unity/{RewardedVideoAdClient.cs → RewardedAdClient.cs} +29 -19
- package/Runtime/Platforms/Unity/RewardedTimer.cs +2 -1
- package/Runtime/Platforms/iOS/BannerAdClient.cs +106 -29
- package/Runtime/Platforms/iOS/BlueStackClient.cs +31 -37
- package/Runtime/Platforms/iOS/ClientsFactory.cs +2 -13
- package/Runtime/Platforms/iOS/Externs.cs +75 -66
- package/Runtime/Platforms/iOS/InitializationStatusClient.cs +18 -28
- package/Runtime/Platforms/iOS/InterstitialAdClient.cs +147 -57
- package/Runtime/Platforms/iOS/NativeAdClient.cs +16 -3
- package/Runtime/Platforms/iOS/RequestOptionsClient.cs +40 -0
- package/Runtime/Platforms/iOS/RequestOptionsClient.cs.meta +2 -0
- package/Runtime/Platforms/iOS/RewardedAdClient.cs +262 -0
- package/Runtime/Platforms/iOS/Utils.cs +1 -9
- package/Runtime/Utilities/AndroidEntryChecker.cs +5 -4
- package/Runtime/Utilities/CoordinateConverter.cs +338 -0
- package/Runtime/Utilities/CoordinateConverter.cs.meta +11 -0
- package/package.json +2 -2
- package/Plugins/Android/bluestack-unity-android-bridge-5.4.0.aar +0 -0
- package/Plugins/Android/bluestack-unity-android-bridge-5.4.0.aar.meta +0 -2
- package/Plugins/iOS/BSUBanner.swift.wip +0 -303
- package/Plugins/iOS/BSURewardedVideoAd.h +0 -32
- package/Plugins/iOS/BSURewardedVideoAd.swift +0 -108
- package/Plugins/iOS/BSUSettings.h +0 -18
- package/Plugins/iOS/BSUSettings.h.meta +0 -27
- package/Plugins/iOS/BSUSettings.swift +0 -13
- package/Plugins/iOS/BSUSettings.swift.meta +0 -37
- package/Runtime/API/AdaptersInitializationStatus.cs +0 -20
- package/Runtime/API/Preference/Gender.cs +0 -9
- package/Runtime/API/Preference/Location.cs +0 -29
- package/Runtime/API/Preference/Preference.cs +0 -58
- package/Runtime/API/Preference.meta +0 -3
- package/Runtime/API/Rewarded/RewardedVideoAd.cs +0 -82
- package/Runtime/API/Settings.cs +0 -12
- package/Runtime/API/Settings.cs.meta +0 -3
- package/Runtime/Common/NativeAd/AdsEventExecutor.cs +0 -83
- package/Runtime/Internal/IPreferenceClient.cs +0 -15
- package/Runtime/Internal/IPreferenceClient.cs.meta +0 -3
- package/Runtime/Internal/IRewardedVideoAdClient.cs +0 -21
- package/Runtime/Platforms/Android/PreferenceClient.cs +0 -85
- package/Runtime/Platforms/Android/PreferenceClient.cs.meta +0 -3
- package/Runtime/Platforms/Android/RewardedVideoAdClient.cs +0 -110
- package/Runtime/Platforms/Unity/PreferenceClient.cs +0 -65
- package/Runtime/Platforms/Unity/PreferenceClient.cs.meta +0 -3
- package/Runtime/Platforms/iOS/PreferenceClient.cs +0 -69
- package/Runtime/Platforms/iOS/PreferenceClient.cs.meta +0 -3
- package/Runtime/Platforms/iOS/RewardedVideoAdClient.cs +0 -174
- /package/Editor/iOS/{BlueStackBuildPostProcess.cs.meta → IOSBuildPostProcess.cs.meta} +0 -0
- /package/Runtime/API/{AdaptersInitializationStatus.cs.meta → InitializationStatus.cs.meta} +0 -0
- /package/Runtime/API/{Preference → RequestOptions}/Gender.cs.meta +0 -0
- /package/Runtime/API/{Preference → RequestOptions}/Location.cs.meta +0 -0
- /package/Runtime/API/{Preference/Preference.cs.meta → RequestOptions/RequestOptions.cs.meta} +0 -0
- /package/Runtime/API/Rewarded/{RewardedVideoAd.cs.meta → RewardedAd.cs.meta} +0 -0
- /package/Runtime/Common/{NativeAd/AdsEventExecutor.cs.meta → AdsMainThreadDispatcher.cs.meta} +0 -0
- /package/Runtime/Internal/{IRewardedVideoAdClient.cs.meta → IRewardedAdClient.cs.meta} +0 -0
- /package/Runtime/Platforms/Android/{RewardedVideoAdClient.cs.meta → RewardedAdClient.cs.meta} +0 -0
- /package/Runtime/Platforms/Unity/{RewardedVideoAdClient.cs.meta → RewardedAdClient.cs.meta} +0 -0
- /package/Runtime/Platforms/iOS/{RewardedVideoAdClient.cs.meta → RewardedAdClient.cs.meta} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,100 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [6.0.0-beta.1] - 2026-06-10
|
|
4
|
+
|
|
5
|
+
### Native SDK upgrades
|
|
6
|
+
|
|
7
|
+
- Android: BlueStack Core SDK upgraded to 6.0.1
|
|
8
|
+
- Android: In-App Bidding mediation adapter upgraded to 6.0.0.1
|
|
9
|
+
- Android: Google Mobile Ads mediation adapter upgraded to 6.0.0.1
|
|
10
|
+
- Android: Equativ mediation adapter upgraded to 6.0.0.2
|
|
11
|
+
- iOS: BlueStack Core SDK upgraded to 6.0.0
|
|
12
|
+
- iOS: In-App Bidding mediation adapter upgraded to 6.0.2
|
|
13
|
+
- iOS: Google Mobile Ads mediation adapter upgraded to 6.0.0
|
|
14
|
+
- iOS: Equativ mediation adapter upgraded to 6.0.0
|
|
15
|
+
|
|
16
|
+
### Added
|
|
17
|
+
|
|
18
|
+
- `BlueStackAds.SetDebugMode(bool)` for toggling native SDK debug logging at any time, plus
|
|
19
|
+
`BlueStackAds.IsDebugModeEnabled` to read the cached state.
|
|
20
|
+
- `BlueStackAds.IsInitialized` property to check native-side readiness.
|
|
21
|
+
- `InterstitialAd.IsReady` and `RewardedAd.IsReady` properties.
|
|
22
|
+
- `BannerAd` anchor-based positioning — new constructor
|
|
23
|
+
`BannerAd(string placementId, AdSize adSize, Transform anchor, Camera camera = null)`. The banner
|
|
24
|
+
follows the anchor's screen position automatically via the new `AdPlacementHandler` component.
|
|
25
|
+
The anchor's screen-space position is treated as the banner's **top-left corner** (matching
|
|
26
|
+
native iOS / Android frame placement).
|
|
27
|
+
- `BannerAd` custom screen-space position constructor — `BannerAd(string placementId, AdSize adSize, Vector2 position)`.
|
|
28
|
+
The `position` is the banner's **top-left corner** in Unity pixels (bottom-left origin).
|
|
29
|
+
- Optional `useSafeArea` parameter on `BannerAd(string, AdSize, AdPosition, bool useSafeArea = true)`
|
|
30
|
+
to opt out of safe-area insets for sticky Top/Bottom banners. Custom-positioned banners always
|
|
31
|
+
ignore the safe area.
|
|
32
|
+
- Banner masking — `BannerAd.SetMask(RectTransform, Camera)` / `BannerAd.RemoveMask()` clip the banner
|
|
33
|
+
to a UI region. The mask follows the `RectTransform` as it animates or resizes.
|
|
34
|
+
- `BannerAd.OnAdResized` event delivers a `PreferredBannerSize` (`Width`, `Height`) whenever the SDK
|
|
35
|
+
reports a post-load size change.
|
|
36
|
+
- `BannerAd.OnAdLoaded` payload changed to `PreferredBannerSize` carrying the SDK-preferred dimensions
|
|
37
|
+
(was `EventArgs`).
|
|
38
|
+
- `RewardedAd.OnAdRewardEarned` (renamed from `OnRewardEarned`) delivers a `RewardedItem`.
|
|
39
|
+
- `UpdateInterval` and `ForceUpdate` API added to `AdMaskHandler` and `AdPlacementHandler`
|
|
40
|
+
|
|
41
|
+
### Changed
|
|
42
|
+
|
|
43
|
+
- **Breaking** — `BlueStackAds.Initialize` signature simplified:
|
|
44
|
+
- Before: `Initialize(string appId, Settings settings, Action<SDKInitializationStatus> sdkCallback, Action<IInitializationStatusClient> adaptersCallback)`
|
|
45
|
+
- After: `Initialize(string appId, Action<InitializationStatus> initializationCompleteAction = null)`
|
|
46
|
+
- The `Settings`-based debug toggle is replaced by `BlueStackAds.SetDebugMode(bool)`.
|
|
47
|
+
- The separate success/fail `SDKInitializationStatus` callback is removed. The single completion
|
|
48
|
+
callback now delivers `InitializationStatus.AdapterStatusMap` (per-adapter `AdapterStatus`).
|
|
49
|
+
- The initialization callback is now consistently dispatched to the Unity main thread on both
|
|
50
|
+
iOS and Android.
|
|
51
|
+
- **Breaking** — `RewardedVideoAd` class renamed to `RewardedAd`.
|
|
52
|
+
- **Breaking** — Banner event names renamed:
|
|
53
|
+
- `OnBannerDidLoad` → `OnAdLoaded` (payload changed to `PreferredBannerSize`)
|
|
54
|
+
- `OnBannerDidFailed` → `OnAdFailedToLoad`
|
|
55
|
+
- `OnBannerDisplay` → `OnAdDisplayed`
|
|
56
|
+
- `OnBannerHide` → `OnAdHidden`
|
|
57
|
+
- `OnBannerDidRefresh` → `OnAdRefreshed`
|
|
58
|
+
- `OnBannerDidFailToRefresh` → `OnAdFailedToRefresh`
|
|
59
|
+
- **Breaking** — Interstitial event names renamed:
|
|
60
|
+
- `OnInterstitialDidLoaded` → `OnAdLoaded`
|
|
61
|
+
- `OnInterstitialDidFail` → `OnAdFailedToLoad`
|
|
62
|
+
- `OnInterstitialClicked` → `OnAdClicked`
|
|
63
|
+
- `OnInterstitialDidShown` → `OnAdDisplayed`
|
|
64
|
+
- `OnInterstitialDisappear` → `OnAdDismissed`
|
|
65
|
+
- **Breaking** — Rewarded event names renamed:
|
|
66
|
+
- `OnRewardedVideoAdLoaded` → `OnAdLoaded`
|
|
67
|
+
- `OnRewardedVideoAdError` → `OnAdFailedToLoad`
|
|
68
|
+
- `OnRewardedVideoAdAppeared` → `OnAdDisplayed`
|
|
69
|
+
- `OnRewardedVideoAdClicked` → `OnAdClicked`
|
|
70
|
+
- `OnRewardedVideoAdClosed` → `OnAdDismissed`
|
|
71
|
+
- `OnUserRewardEarned` → `OnAdRewardEarned`
|
|
72
|
+
- To display banner ads, `BannerAd.Show()` must be called after the ad has been loaded.
|
|
73
|
+
- **Breaking** — `BannerAd` constructors now take `AdSize` as a mandatory second parameter, and
|
|
74
|
+
`BannerAd.Load` no longer takes one:
|
|
75
|
+
- Before: `new BannerAd(placementId, adPosition); bannerAd.Load(adSize);`
|
|
76
|
+
- After: `new BannerAd(placementId, adSize, adPosition); bannerAd.Load();`
|
|
77
|
+
- Applies to all three constructor shapes (`AdPosition`, `Vector2`, `Transform` anchor).
|
|
78
|
+
- `BannerAd.Load(AdSize)` and `BannerAd.Load(AdSize, Preference)` are replaced by parameterless
|
|
79
|
+
`Load()` and `Load(Preference)` — the ad size is now fixed for the lifetime of the `BannerAd`.
|
|
80
|
+
- **Breaking** — `Preference` class renamed to `RequestOptions` and made **immutable**.
|
|
81
|
+
- Mutable `Set*` builder methods are replaced by a single optional-named-args constructor:
|
|
82
|
+
`new RequestOptions(age: 25, gender: Gender.Male, location: ..., consentFlag: 1,
|
|
83
|
+
language: "en", keyword: "...", contentUrl: "...")`.
|
|
84
|
+
- A single `RequestOptions` instance is safe to reuse across multiple `Load(...)` calls.
|
|
85
|
+
- **Breaking** — `Location` made immutable:
|
|
86
|
+
- Constructor now `new Location(double latitude, double longitude, string provider = NONE_PROVIDER)`
|
|
87
|
+
instead of `new Location(provider)` + mutable `Latitude` / `Longitude` setters.
|
|
88
|
+
- `getProvider()` method replaced by a `Provider` get-only property.
|
|
89
|
+
|
|
90
|
+
### Removed
|
|
91
|
+
|
|
92
|
+
- **Breaking** — `Settings` parameter removed from `BlueStackAds.Initialize`. Use `BlueStackAds.SetDebugMode(bool)` instead of
|
|
93
|
+
`new Settings(isDebugModeEnabled: ...)`.
|
|
94
|
+
- **Breaking** — `Preference.Destroy()` removed — the new immutable `RequestOptions` holds no
|
|
95
|
+
native resources on the Unity side; the native intermediate is constructed and released inside
|
|
96
|
+
each `Load(...)` call.
|
|
97
|
+
|
|
3
98
|
## [3.4.1] - 2026-02-27
|
|
4
99
|
|
|
5
100
|
### Changed
|
package/CLAUDE.md
ADDED
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## What This Is
|
|
6
|
+
|
|
7
|
+
`com.azerion.bluestack` — a Unity UPM package (v6.0.0) that wraps the native BlueStack ad SDK for iOS and Android. It exposes a cross-platform C# API for banner, interstitial, rewarded, and native ad formats.
|
|
8
|
+
- **package project repo**: `/Users/moinhasan/Development/Azerdev/bluestack/unity/bluestack-sdk-unity`
|
|
9
|
+
- **UPM package directory**: `/Users/moinhasan/Development/Azerdev/bluestack/unity/bluestack-sdk-unity/plugin`
|
|
10
|
+
|
|
11
|
+
**Related repos worked on alongside this package:**
|
|
12
|
+
- **Demo/test app**: `/Users/moinhasan/Development/Azerdev/bluestack/unity/bluestack-demo-unity`
|
|
13
|
+
- **Android native bridge source**: `/Users/moinhasan/Development/Azerdev/bluestack/unity/bluestack-sdk-unity/android-bridge`
|
|
14
|
+
- **Public Documentation**: `/Users/moinhasan/Development/Azerdev/bluestack/bluestack-app`
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## Build Commands
|
|
19
|
+
|
|
20
|
+
### Rebuild Android Bridge AAR
|
|
21
|
+
|
|
22
|
+
After changing any Kotlin source in `android-bridge/`, rebuild and deploy the AAR:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
cd /Users/moinhasan/Development/Azerdev/bluestack/unity/bluestack-sdk-unity/android-bridge
|
|
26
|
+
./gradlew mkBlueStackSdk
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Output goes to `plugin/Plugins/Android/bluestack-unity-android-bridge-{version}.aar`. The version is set in `android-bridge/build.gradle` ext block.
|
|
30
|
+
|
|
31
|
+
### iOS Bridge
|
|
32
|
+
|
|
33
|
+
No build step — Swift/Objective-C files in `Plugins/iOS/` are compiled by Xcode during Unity iOS export. After exporting from Unity, run `pod install` in the generated Xcode project.
|
|
34
|
+
|
|
35
|
+
### Run SDK Tests
|
|
36
|
+
|
|
37
|
+
Use **Unity Test Runner** (`Window > General > Test Runner`):
|
|
38
|
+
- `Tests/Runtime/` — `Azerion.BlueStack.Tests` assembly
|
|
39
|
+
- `Tests/Editor/` — `Azerion.BlueStack.Editor.Tests` assembly
|
|
40
|
+
|
|
41
|
+
Moq is available at `Plugins/Moq/` for mocking interfaces in tests.
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## Architecture
|
|
46
|
+
|
|
47
|
+
### Layer Stack
|
|
48
|
+
|
|
49
|
+
```
|
|
50
|
+
Developer code
|
|
51
|
+
↓
|
|
52
|
+
API layer Runtime/API/ Public classes (BannerAd, InterstitialAd, …)
|
|
53
|
+
↓
|
|
54
|
+
Interfaces Runtime/Internal/ IBannerAdClient, IInterstitialAdClient, …
|
|
55
|
+
↓
|
|
56
|
+
Platform clients Runtime/Platforms/
|
|
57
|
+
Android/ AndroidJavaProxy-based wrappers
|
|
58
|
+
iOS/ P/Invoke wrappers
|
|
59
|
+
Unity/ Editor stubs (simulate ads in Play mode)
|
|
60
|
+
↓
|
|
61
|
+
Native bridge
|
|
62
|
+
Plugins/Android/*.aar Kotlin — com.azerion.bluestack.unity.*
|
|
63
|
+
Plugins/iOS/*.swift/.m Swift/Obj-C — BSU* classes
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Factory Pattern — Platform Selection
|
|
67
|
+
|
|
68
|
+
`BlueStackAds.GetClientsFactory()` (in `Runtime/API/BlueStackAds.cs`) selects the platform factory at runtime:
|
|
69
|
+
|
|
70
|
+
```
|
|
71
|
+
Application.platform == Android → Platforms.Android.ClientsFactory
|
|
72
|
+
Application.platform == iPhone → Platforms.iOS.ClientsFactory
|
|
73
|
+
anything else (Editor) → Platforms.Unity.ClientsFactory (loaded via Activator.CreateInstance)
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
The Unity editor factory uses reflection so its assembly (`Azerion.BlueStack.Editor`) doesn't need to be referenced from the runtime assembly. All platform clients implement `IClientsFactory` and create the six client interfaces: `IBlueStackClient`, `IBannerAdClient`, `IInterstitialAdClient`, `IRewardedVideoAdClient`, `INativeAdClient`, `IPreferenceClient`.
|
|
77
|
+
|
|
78
|
+
### Main Thread Dispatcher
|
|
79
|
+
|
|
80
|
+
`BlueStackMainThreadDispatcher` (`Runtime/Common/`) is a `DontDestroyOnLoad` MonoBehaviour. Native SDK callbacks arrive on native threads; they must be marshalled to Unity's main thread before firing C# events.
|
|
81
|
+
|
|
82
|
+
- Call `BlueStackMainThreadDispatcher.ExecuteInUpdate(action)` from any thread
|
|
83
|
+
- Actions are drained in `Update()` under a lock
|
|
84
|
+
- Initialised once by `BlueStackAds.Initialize()`
|
|
85
|
+
|
|
86
|
+
### Android Platform Client Pattern
|
|
87
|
+
|
|
88
|
+
- Client classes extend `AndroidJavaProxy`, passing the matching Java interface name to the base constructor (e.g. `UnityBannerAdListenerClassName`)
|
|
89
|
+
- The Java bridge calls back into C# by invoking the proxy's methods on the Unity thread
|
|
90
|
+
- All outbound calls to Java go through `AndroidJavaObjectFactory.Instance.RunOnUiThread(() => _unityBannerAd.Call("methodName", args))` — Android SDK requires UI thread
|
|
91
|
+
- Java class names are centralised in `BlueStackNativeClassNames.cs`
|
|
92
|
+
|
|
93
|
+
### iOS Platform Client Pattern
|
|
94
|
+
|
|
95
|
+
- All native function declarations live in `Runtime/Platforms/iOS/Externs.cs` as `[DllImport("__Internal")]`
|
|
96
|
+
- Function naming: `BSU<AdFormat><Action>` (e.g. `BSULoadBannerAd`, `BSUShowRewardedAd`, `BSUDestroyInterstitialAd`)
|
|
97
|
+
- Callbacks from native → C# use typed `delegate` definitions + `[AOT.MonoPInvokeCallback(typeof(DelegateType))]` on `static` methods
|
|
98
|
+
- `GCHandle.Alloc(this)` pins the client instance; `GCHandle.ToIntPtr()` is passed to native as the "client ref" opaque pointer, recovered in callbacks via `GCHandle.FromIntPtr().Target`
|
|
99
|
+
- Native objects are kept alive in `BSUObjectCache` (Swift) until `BSURelease(ptr)` is called
|
|
100
|
+
|
|
101
|
+
### iOS Native Bridge (Plugins/iOS/)
|
|
102
|
+
|
|
103
|
+
- `BSUInterface.m` — all `extern "C"` entry points; the only file that crosses the C↔Swift boundary
|
|
104
|
+
- `BSU<Format>.swift` — Swift classes implementing BlueStack iOS SDK delegates (e.g. `BSUBanner: NSObject, BannerViewDelegate`)
|
|
105
|
+
- `BSU<Format>.h` — Objective-C headers exposing Swift classes to C
|
|
106
|
+
- `BSUTypes.h` / `BSUTypes.swift` — opaque pointer `typedef`s (`BSUTypeBannerClientRef`, etc.) shared across all files
|
|
107
|
+
- `BSUObjectCache.swift` — thread-safe singleton (serial dispatch queue); keys objects by memory address string; objects are released by `BSURelease()`
|
|
108
|
+
- `MaskView.swift` — `MTKView` subclass for banner clipping/masking
|
|
109
|
+
- `UnityFramework.modulemap` — module map so Unity's Xcode build can import the bridge headers
|
|
110
|
+
|
|
111
|
+
Banner positioning strategy in `BSUBanner.swift`:
|
|
112
|
+
- Preset positions (top/bottom): `NSLayoutConstraint` Auto Layout anchored to safe area
|
|
113
|
+
- Custom positions: frame-based with `CATransaction.disableActions` to avoid implicit animations
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## Key Files
|
|
118
|
+
|
|
119
|
+
| File | Purpose |
|
|
120
|
+
|---|---|
|
|
121
|
+
| `Runtime/API/BlueStackAds.cs` | SDK entry point; factory selection |
|
|
122
|
+
| `Runtime/Internal/IClientsFactory.cs` | Interface every platform factory must implement |
|
|
123
|
+
| `Runtime/Platforms/Android/BlueStackNativeClassNames.cs` | All Java class name constants |
|
|
124
|
+
| `Runtime/Platforms/Android/AndroidJavaObjectFactory.cs` | UI thread runner + Java object creation |
|
|
125
|
+
| `Runtime/Platforms/iOS/Externs.cs` | Every `[DllImport]` declaration |
|
|
126
|
+
| `Runtime/Common/BlueStackMainThreadDispatcher.cs` | Thread-safe callback queue |
|
|
127
|
+
| `Plugins/iOS/BSUInterface.m` | C entry points for all P/Invoke calls |
|
|
128
|
+
| `Plugins/iOS/BSUTypes.h` | Shared opaque pointer typedefs |
|
|
129
|
+
| `Plugins/iOS/BSUObjectCache.swift` | Native object lifetime management |
|
|
130
|
+
| `Editor/BlueStackSettingsEditor.cs` | `Azerion > BlueStack > Settings` menu |
|
|
131
|
+
| `package.json` | UPM manifest (version bump here) |
|
|
132
|
+
| `CHANGELOG.md` | Version history |
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## Adding a New Ad Format
|
|
137
|
+
|
|
138
|
+
Follow the existing pattern — each format has the same set of files:
|
|
139
|
+
|
|
140
|
+
1. `Runtime/API/<Format>.cs` — public API class, holds `IFormatClient` reference
|
|
141
|
+
2. `Runtime/Internal/IFormatClient.cs` — interface with Load/Show/Destroy + events
|
|
142
|
+
3. `Runtime/Platforms/Android/<Format>Client.cs` — extends `AndroidJavaProxy`, calls `_unityAd.Call(...)` on UI thread
|
|
143
|
+
4. `Runtime/Platforms/iOS/<Format>Client.cs` — `IntPtr` holder + delegate types + `[MonoPInvokeCallback]` statics
|
|
144
|
+
5. `Runtime/Platforms/Unity/<Format>Client.cs` — Editor stub
|
|
145
|
+
6. Add `Create<Format>Client()` to all three `ClientsFactory.cs` files and to `IClientsFactory`
|
|
146
|
+
7. `Plugins/iOS/BSU<Format>.swift` + `BSU<Format>.h` — Swift delegate implementation
|
|
147
|
+
8. Add `extern "C"` functions to `BSUInterface.m` and declare in `Externs.cs`
|
|
148
|
+
9. Android: add `Unity<Format>Ad.kt` + listener interface to `android-bridge`, rebuild AAR
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
## Editor Tooling
|
|
153
|
+
|
|
154
|
+
- **Settings window**: `Azerion > BlueStack > Settings` — configures AdMob App IDs and mediation networks; writes `Assets/Resources/BlueStackSettings.asset` into the consuming project
|
|
155
|
+
- **Dependency management**: `Editor/BlueStackDependenciesSource.xml` declares native dependencies; EDM4U (`com.google.external-dependency-manager`) resolves them into Android Gradle and iOS Podfile
|
|
156
|
+
- **Post-build hooks**: `Editor/Android/AndroidBuildPostProcess.cs` and `Editor/iOS/BlueStackBuildPostProcess.cs` run after Unity builds to patch Xcode project / Gradle config
|
|
157
|
+
- **Asset post-processor**: `BlueStackAssetPostProcessor.cs` syncs dependency metadata when SDK version changes
|
package/CLAUDE.md.meta
ADDED
|
@@ -48,12 +48,15 @@ namespace Azerion.BlueStack.Editor.Android
|
|
|
48
48
|
{
|
|
49
49
|
var aliasAttribute = androidPackageNode.Attributes?["alias"];
|
|
50
50
|
var specAttribute = androidPackageNode.Attributes?["spec"];
|
|
51
|
-
var versionAttribute = androidPackageNode.Attributes?["version"];
|
|
52
51
|
var alias = aliasAttribute != null ? aliasAttribute.Value : specAttribute?.Value;
|
|
53
52
|
var name = specAttribute?.Value;
|
|
54
|
-
var version = versionAttribute?.Value;
|
|
55
53
|
if (name == null)
|
|
56
54
|
continue;
|
|
55
|
+
// Extract "version" from the spec "group:artifact:version"
|
|
56
|
+
var lastColon = name.LastIndexOf(':');
|
|
57
|
+
var version = lastColon >= 0 && lastColon < name.Length - 1
|
|
58
|
+
? name.Substring(lastColon + 1)
|
|
59
|
+
: null;
|
|
57
60
|
bool active = activeNames != null && activeNames.Contains(name);
|
|
58
61
|
dependencies.Add(
|
|
59
62
|
new BlueStackDependency(alias, name, version, androidPackageNode, active)
|
|
@@ -7,8 +7,11 @@ namespace Azerion.BlueStack.Editor
|
|
|
7
7
|
static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets,
|
|
8
8
|
string[] movedFromAssetPaths, bool didDomainReload)
|
|
9
9
|
{
|
|
10
|
-
//
|
|
11
|
-
//
|
|
10
|
+
// Required when updating the SDK: sync dependencies when the project loads in the Unity Editor.
|
|
11
|
+
// Only run on a domain reload (project load / script recompile / SDK update).
|
|
12
|
+
if (!didDomainReload)
|
|
13
|
+
return;
|
|
14
|
+
|
|
12
15
|
BlueStackSettingsEditor.Initialize();
|
|
13
16
|
}
|
|
14
17
|
}
|
|
@@ -1,27 +1,27 @@
|
|
|
1
|
-
<dependencies version="
|
|
1
|
+
<dependencies version="6.0.0-beta.1">
|
|
2
2
|
<androidPackages>
|
|
3
|
-
<androidPackage alias="BlueStack" spec="com.azerion:bluestack-sdk-core:
|
|
3
|
+
<androidPackage alias="BlueStack" spec="com.azerion:bluestack-sdk-core:6.0.1">
|
|
4
4
|
<repositories>
|
|
5
5
|
<repository>https://packagecloud.io/smartadserver/android/maven2</repository>
|
|
6
6
|
<repository>https://s01.oss.sonatype.org/content/repositories/snapshots/</repository>
|
|
7
7
|
</repositories>
|
|
8
8
|
</androidPackage>
|
|
9
|
-
<androidPackage alias="In-App Bidding" spec="com.azerion:bluestack-mediation-bidding:
|
|
9
|
+
<androidPackage alias="In-App Bidding" spec="com.azerion:bluestack-mediation-bidding:6.0.0.1">
|
|
10
10
|
<repositories>
|
|
11
11
|
<repository>https://packagecloud.io/smartadserver/android/maven2</repository>
|
|
12
12
|
</repositories>
|
|
13
13
|
</androidPackage>
|
|
14
|
-
<androidPackage alias="Google Mobile Ads" spec="com.azerion:bluestack-mediation-google:
|
|
15
|
-
<androidPackage alias="Equativ" spec="com.azerion:bluestack-mediation-equativ:
|
|
14
|
+
<androidPackage alias="Google Mobile Ads" spec="com.azerion:bluestack-mediation-google:6.0.0.1"/>
|
|
15
|
+
<androidPackage alias="Equativ" spec="com.azerion:bluestack-mediation-equativ:6.0.0.2">
|
|
16
16
|
<repositories>
|
|
17
17
|
<repository>https://packagecloud.io/smartadserver/android/maven2</repository>
|
|
18
18
|
</repositories>
|
|
19
19
|
</androidPackage>
|
|
20
20
|
</androidPackages>
|
|
21
21
|
<iosPods>
|
|
22
|
-
<iosPod alias="BlueStack" name="BlueStack-SDK" version="
|
|
23
|
-
<iosPod alias="In-App Bidding" name="BlueStackBiddingAdapter" version="
|
|
24
|
-
<iosPod alias="Google Mobile Ads" name="BlueStackGoogleAdapter" version="
|
|
25
|
-
<iosPod alias="Equativ" name="BlueStackEquativAdapter" version="
|
|
22
|
+
<iosPod alias="BlueStack" name="BlueStack-SDK" version="6.0.0" bitcodeEnabled="false" addToAllTargets="false"/>
|
|
23
|
+
<iosPod alias="In-App Bidding" name="BlueStackBiddingAdapter" version="6.0.2" bitcodeEnabled="false" addToAllTargets="false"/>
|
|
24
|
+
<iosPod alias="Google Mobile Ads" name="BlueStackGoogleAdapter" version="6.0.0" bitcodeEnabled="false" addToAllTargets="false"/>
|
|
25
|
+
<iosPod alias="Equativ" name="BlueStackEquativAdapter" version="6.0.0" bitcodeEnabled="false" addToAllTargets="false"/>
|
|
26
26
|
</iosPods>
|
|
27
27
|
</dependencies>
|
|
@@ -8,6 +8,14 @@ namespace Azerion.BlueStack.Editor
|
|
|
8
8
|
private static BlueStackSettings instance;
|
|
9
9
|
private const string BlueStackSettingsFile = "BlueStackSettings";
|
|
10
10
|
|
|
11
|
+
[SerializeField]
|
|
12
|
+
private string version;
|
|
13
|
+
public string Version
|
|
14
|
+
{
|
|
15
|
+
get => Instance.version;
|
|
16
|
+
set => Instance.version = value;
|
|
17
|
+
}
|
|
18
|
+
|
|
11
19
|
[SerializeField]
|
|
12
20
|
private string admobAppIdAndroid;
|
|
13
21
|
public string AdmobAppIdAndroid
|
|
@@ -53,8 +53,6 @@ namespace Azerion.BlueStack.Editor
|
|
|
53
53
|
BlueStackSettingsFileExtension
|
|
54
54
|
);
|
|
55
55
|
AssetDatabase.CreateAsset(BlueStackSettings.Instance, assetPathWithExtension);
|
|
56
|
-
AssetDatabase.SaveAssets();
|
|
57
|
-
|
|
58
56
|
return true;
|
|
59
57
|
}
|
|
60
58
|
catch (Exception e)
|
|
@@ -72,35 +70,88 @@ namespace Azerion.BlueStack.Editor
|
|
|
72
70
|
}
|
|
73
71
|
}
|
|
74
72
|
|
|
75
|
-
// This is Required when updating the SDK.
|
|
76
|
-
// Initialize and Sync dependencies when project loaded in Unity Editor.
|
|
77
|
-
// This logic is now moved to OnPostprocessAllAssets of BlueStackAssetPostProcessor
|
|
78
|
-
// [InitializeOnLoadMethod]
|
|
79
|
-
// static void OnProjectLoadedInEditor()
|
|
80
|
-
// {
|
|
81
|
-
// Initialize();
|
|
82
|
-
// }
|
|
83
|
-
|
|
84
73
|
void OnEnable()
|
|
85
74
|
{
|
|
86
|
-
|
|
75
|
+
// Only refresh the in-memory lists for display.
|
|
76
|
+
// PackageNode is a live XmlNode and BlueStackDependency uses auto-properties, so Unity
|
|
77
|
+
// serializes none of this into the asset, the lists must be rebuilt from XML each load.
|
|
78
|
+
|
|
79
|
+
LoadDependenciesIntoMemory();
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
private static void LoadDependenciesIntoMemory()
|
|
83
|
+
{
|
|
84
|
+
if (!DoesBlueStackSettingsExist())
|
|
85
|
+
return;
|
|
86
|
+
|
|
87
|
+
BlueStackSettings.Instance.AndroidDependencies =
|
|
88
|
+
DependencyProvider.GetBlueStackDependencies(new AndroidDependencyParser());
|
|
89
|
+
BlueStackSettings.Instance.IOSDependencies =
|
|
90
|
+
DependencyProvider.GetBlueStackDependencies(new IOSDependencyParser());
|
|
87
91
|
}
|
|
88
92
|
|
|
93
|
+
private static bool _isInitializing;
|
|
94
|
+
|
|
95
|
+
// The XML sync + persist happens once on domain reload from BlueStackAssetPostProcessor.
|
|
89
96
|
public static void Initialize()
|
|
90
97
|
{
|
|
98
|
+
// re-entrancy guard
|
|
99
|
+
if (_isInitializing)
|
|
100
|
+
return;
|
|
101
|
+
|
|
91
102
|
if (!DoesBlueStackSettingsExist())
|
|
92
103
|
return;
|
|
93
104
|
|
|
94
|
-
|
|
95
|
-
|
|
105
|
+
_isInitializing = true;
|
|
106
|
+
try
|
|
107
|
+
{
|
|
108
|
+
DependencyProvider.SyncDependenciesXMLs();
|
|
109
|
+
|
|
110
|
+
var androidDependencies = DependencyProvider.GetBlueStackDependencies(new AndroidDependencyParser());
|
|
111
|
+
var iOSDependencies = DependencyProvider.GetBlueStackDependencies(new IOSDependencyParser());
|
|
112
|
+
|
|
113
|
+
var packageInfo = UnityEditor.PackageManager.PackageInfo.FindForAssetPath(
|
|
114
|
+
"Packages/com.azerion.bluestack");
|
|
115
|
+
var version = packageInfo != null ? packageInfo.version : BlueStackSettings.Instance.Version;
|
|
96
116
|
|
|
97
|
-
|
|
117
|
+
// Only persist when something actually changed. Re-saving an unchanged asset
|
|
118
|
+
// re-triggers OnPostprocessAllAssets and causes an infinite import loop.
|
|
119
|
+
bool changed =
|
|
120
|
+
BlueStackSettings.Instance.Version != version
|
|
121
|
+
|| !DependenciesEqual(BlueStackSettings.Instance.AndroidDependencies, androidDependencies)
|
|
122
|
+
|| !DependenciesEqual(BlueStackSettings.Instance.IOSDependencies, iOSDependencies);
|
|
98
123
|
|
|
99
|
-
|
|
100
|
-
|
|
124
|
+
BlueStackSettings.Instance.AndroidDependencies = androidDependencies;
|
|
125
|
+
BlueStackSettings.Instance.IOSDependencies = iOSDependencies;
|
|
126
|
+
BlueStackSettings.Instance.Version = version;
|
|
127
|
+
|
|
128
|
+
if (changed)
|
|
129
|
+
{
|
|
130
|
+
EditorUtility.SetDirty(BlueStackSettings.Instance);
|
|
131
|
+
AssetDatabase.SaveAssets();
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
finally
|
|
135
|
+
{
|
|
136
|
+
_isInitializing = false;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
101
139
|
|
|
102
|
-
|
|
103
|
-
|
|
140
|
+
// Compares dependency lists by the fields that get persisted in the asset.
|
|
141
|
+
private static bool DependenciesEqual(
|
|
142
|
+
List<BlueStackDependency> a,
|
|
143
|
+
List<BlueStackDependency> b)
|
|
144
|
+
{
|
|
145
|
+
if (a == null || b == null)
|
|
146
|
+
return ReferenceEquals(a, b);
|
|
147
|
+
if (a.Count != b.Count)
|
|
148
|
+
return false;
|
|
149
|
+
for (int i = 0; i < a.Count; i++)
|
|
150
|
+
{
|
|
151
|
+
if (a[i].Name != b[i].Name || a[i].Active != b[i].Active)
|
|
152
|
+
return false;
|
|
153
|
+
}
|
|
154
|
+
return true;
|
|
104
155
|
}
|
|
105
156
|
|
|
106
157
|
public override void OnInspectorGUI()
|