Skip to content

Commit

Permalink
Final fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
britzl committed Jun 28, 2024
1 parent f1846d7 commit 3b8ec2b
Show file tree
Hide file tree
Showing 8 changed files with 525 additions and 270 deletions.
36 changes: 34 additions & 2 deletions extension-admob/src/admob.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ static const char DEFOLD_USERAGENT[] = "defold-3.4.1";
static int Lua_Initialize(lua_State* L)
{
DM_LUA_STACK_CHECK(L, 0);
Initialize(DEFOLD_USERAGENT);
Initialize();
return 0;
}

Expand All @@ -29,6 +29,24 @@ static int Lua_SetCallback(lua_State* L)
return 0;
}

static int Lua_LoadAppOpen(lua_State* L)
{
DM_LUA_STACK_CHECK(L, 0);
if (lua_type(L, 1) != LUA_TSTRING) {
return DM_LUA_ERROR("Expected string, got %s. Wrong type for App Open Ad UnitId variable '%s'.", luaL_typename(L, 1), lua_tostring(L, 1));
}
const char* unitId_lua = luaL_checkstring(L, 1);
LoadAppOpen(unitId_lua);
return 0;
}

static int Lua_ShowAppOpen(lua_State* L)
{
DM_LUA_STACK_CHECK(L, 0);
ShowAppOpen();
return 0;
}

static int Lua_LoadInterstitial(lua_State* L)
{
DM_LUA_STACK_CHECK(L, 0);
Expand Down Expand Up @@ -155,6 +173,14 @@ static int Lua_IsBannerLoaded(lua_State* L)
return 1;
}

static int Lua_IsAppOpenLoaded(lua_State* L)
{
DM_LUA_STACK_CHECK(L, 1);
bool is_loaded = IsAppOpenLoaded();
lua_pushboolean(L, is_loaded);
return 1;
}

static int Lua_SetPrivacySettings(lua_State* L)
{
DM_LUA_STACK_CHECK(L, 0);
Expand Down Expand Up @@ -189,6 +215,8 @@ static const luaL_reg Module_methods[] =
{
{"initialize", Lua_Initialize},
{"set_callback", Lua_SetCallback},
{"load_appopen", Lua_LoadAppOpen},
{"show_appopen", Lua_ShowAppOpen},
{"load_interstitial", Lua_LoadInterstitial},
{"show_interstitial", Lua_ShowInterstitial},
{"load_rewarded", Lua_LoadRewarded},
Expand All @@ -203,6 +231,7 @@ static const luaL_reg Module_methods[] =
{"is_interstitial_loaded", Lua_IsInterstitialLoaded},
{"is_rewarded_interstitial_loaded", Lua_IsRewardedInterstitialLoaded},
{"is_banner_loaded", Lua_IsBannerLoaded},
{"is_appopen_loaded", Lua_IsAppOpenLoaded},
{"set_privacy_settings", Lua_SetPrivacySettings},
{"request_idfa", Lua_RequestIDFA},
{"show_ad_inspector", Lua_ShowAdInspector},
Expand All @@ -225,6 +254,7 @@ static void LuaInit(lua_State* L)
SETCONSTANT(MSG_INITIALIZATION)
SETCONSTANT(MSG_IDFA)
SETCONSTANT(MSG_REWARDED_INTERSTITIAL)
SETCONSTANT(MSG_APPOPEN)

SETCONSTANT(EVENT_CLOSED)
SETCONSTANT(EVENT_FAILED_TO_SHOW)
Expand Down Expand Up @@ -280,13 +310,15 @@ static void LuaInit(lua_State* L)

static dmExtension::Result AppInitializeAdmob(dmExtension::AppParams* params)
{
dmLogInfo("AppInitializeAdmob");
return dmExtension::RESULT_OK;
}

static dmExtension::Result InitializeAdmob(dmExtension::Params* params)
{
dmLogInfo("InitializeAdmob");
LuaInit(params->m_L);
Initialize_Ext(params);
Initialize_Ext(params, DEFOLD_USERAGENT);
InitializeCallback();
return dmExtension::RESULT_OK;
}
Expand Down
35 changes: 29 additions & 6 deletions extension-admob/src/admob_android.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ struct Admob
jobject m_AdmobJNI;

jmethodID m_Initialize;
jmethodID m_LoadAppOpen;
jmethodID m_ShowAppOpen;
jmethodID m_LoadInterstitial;
jmethodID m_ShowInterstitial;
jmethodID m_LoadRewarded;
Expand All @@ -29,6 +31,7 @@ struct Admob
jmethodID m_DestroyBanner;
jmethodID m_ShowBanner;
jmethodID m_HideBanner;
jmethodID m_IsAppOpenLoaded;
jmethodID m_IsRewardedLoaded;
jmethodID m_IsInterstitialLoaded;
jmethodID m_IsRewardedInterstitialLoaded;
Expand Down Expand Up @@ -98,7 +101,9 @@ static void CallVoidMethodBool(jobject instance, jmethodID method, bool cbool)

static void InitJNIMethods(JNIEnv* env, jclass cls)
{
g_admob.m_Initialize = env->GetMethodID(cls, "initialize", "(Ljava/lang/String;)V");
g_admob.m_Initialize = env->GetMethodID(cls, "initialize", "()V");
g_admob.m_LoadAppOpen = env->GetMethodID(cls, "loadAppOpen", "(Ljava/lang/String;)V");
g_admob.m_ShowAppOpen = env->GetMethodID(cls, "showAppOpen", "()V");
g_admob.m_LoadInterstitial = env->GetMethodID(cls, "loadInterstitial", "(Ljava/lang/String;)V");
g_admob.m_ShowInterstitial = env->GetMethodID(cls, "showInterstitial", "()V");
g_admob.m_LoadRewarded = env->GetMethodID(cls, "loadRewarded", "(Ljava/lang/String;)V");
Expand All @@ -114,14 +119,15 @@ static void InitJNIMethods(JNIEnv* env, jclass cls)
g_admob.m_ShowAdInspector = env->GetMethodID(cls, "showAdInspector", "()V");
g_admob.m_UpdateBannerLayout= env->GetMethodID(cls, "updateBannerLayout", "()V");

g_admob.m_IsAppOpenLoaded = env->GetMethodID(cls, "isAppOpenLoaded", "()Z");
g_admob.m_IsRewardedLoaded = env->GetMethodID(cls, "isRewardedLoaded", "()Z");
g_admob.m_IsInterstitialLoaded = env->GetMethodID(cls, "isInterstitialLoaded", "()Z");
g_admob.m_IsRewardedInterstitialLoaded = env->GetMethodID(cls, "isRewardedInterstitialLoaded", "()Z");
g_admob.m_IsBannerLoaded = env->GetMethodID(cls, "isBannerLoaded", "()Z");
g_admob.m_SetMaxAdContentRating = env->GetMethodID(cls, "setMaxAdContentRating", "(I)V");
}

void Initialize_Ext(dmExtension::Params* params)
void Initialize_Ext(dmExtension::Params* params, const char* defoldUserAgent)
{
dmAndroid::ThreadAttacher threadAttacher;
JNIEnv* env = threadAttacher.GetEnv();
Expand All @@ -131,18 +137,35 @@ void Initialize_Ext(dmExtension::Params* params)

const char* appOpenAdUnitId = dmConfigFile::GetString(params->m_ConfigFile, "admob.app_open_android", 0);
jstring jappOpenAdUnitId = env->NewStringUTF(appOpenAdUnitId);
jmethodID jni_constructor = env->GetMethodID(cls, "<init>", "(Landroid/app/Activity;Ljava/lang/String;)V");
g_admob.m_AdmobJNI = env->NewGlobalRef(env->NewObject(cls, jni_constructor, threadAttacher.GetActivity()->clazz, jappOpenAdUnitId));
jstring jdefoldUserAgent = env->NewStringUTF(defoldUserAgent);
jmethodID jni_constructor = env->GetMethodID(cls, "<init>", "(Landroid/app/Activity;Ljava/lang/String;Ljava/lang/String;)V");
g_admob.m_AdmobJNI = env->NewGlobalRef(env->NewObject(cls, jni_constructor, threadAttacher.GetActivity()->clazz, jappOpenAdUnitId, jdefoldUserAgent));
env->DeleteLocalRef(jappOpenAdUnitId);
env->DeleteLocalRef(jdefoldUserAgent);
}

void Finalize_Ext()
{
}

void Initialize(const char* defoldUserAgent)
void Initialize()
{
CallVoidMethodChar(g_admob.m_AdmobJNI, g_admob.m_Initialize, defoldUserAgent);
CallVoidMethodChar(g_admob.m_AdmobJNI, g_admob.m_Initialize);
}

void LoadAppOpen(const char* unitId)
{
CallVoidMethodChar(g_admob.m_AdmobJNI, g_admob.m_LoadAppOpen, unitId);
}

void ShowAppOpen()
{
CallVoidMethod(g_admob.m_AdmobJNI, g_admob.m_ShowAppOpen);
}

bool IsAppOpenLoaded()
{
return CallBoolMethod(g_admob.m_AdmobJNI, g_admob.m_IsAppOpenLoaded);
}

void LoadInterstitial(const char* unitId)
Expand Down
3 changes: 2 additions & 1 deletion extension-admob/src/admob_callback_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ enum MessageId
MSG_BANNER = 3,
MSG_INITIALIZATION = 4,
MSG_IDFA = 5,
MSG_REWARDED_INTERSTITIAL = 6
MSG_REWARDED_INTERSTITIAL = 6,
MSG_APPOPEN = 7
};

enum MessageEvent
Expand Down
142 changes: 77 additions & 65 deletions extension-admob/src/admob_ios.mm
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,6 @@
#endif

@interface AdmobExtAppOpenAdDelegate : NSObject<GADFullScreenContentDelegate>
@property(nonatomic, strong) GADAppOpenAd *appOpenAd;
@property(nonatomic, assign) char *appOpenAdId;
@property(nonatomic, assign) BOOL isLoadingAd;
@property(nonatomic, assign) BOOL isShowingAd;
@end

@interface AdmobExtInterstitialAdDelegate : NSObject<GADFullScreenContentDelegate>
Expand Down Expand Up @@ -97,8 +93,7 @@ void SendSimpleMessage(MessageId msg, MessageEvent event, NSString *key_2, int v
SendSimpleMessage(msg, dict);
}

void Initialize(const char* defoldUserAgent) {
m_DefoldUserAgent = defoldUserAgent;
void Initialize() {
[[GADMobileAds sharedInstance]
startWithCompletionHandler:^(GADInitializationStatus *_Nonnull status) {
SendSimpleMessage(MSG_INITIALIZATION, EVENT_COMPLETE);
Expand All @@ -116,6 +111,55 @@ void Initialize(const char* defoldUserAgent) {
// App Open ADS

static AdmobExtAppOpenAdDelegate *admobExtAppOpenAdDelegate;
static GADAppOpenAd *appOpenAd;
static char *appOpenAdId;
static bool isLoadingAppOpenAd;
static bool isShowingAppOpenAd;

void LoadAppOpen(const char* unitId) {
// Do not load ad if there is an unused ad or one is already loading.
if (isLoadingAppOpenAd || IsAppOpenLoaded()) {
return;
}
appOpenAdId = (char*)unitId;
isLoadingAppOpenAd = true;

[GADAppOpenAd loadWithAdUnitID:[NSString stringWithUTF8String: unitId]
request:[GADRequest request]
completionHandler:^(GADAppOpenAd *_Nullable ad, NSError *_Nullable error) {
isLoadingAppOpenAd = false;
if (error) {
NSLog(@"Failed to load app open ad: %@", error);
SendSimpleMessage(MSG_APPOPEN, EVENT_FAILED_TO_LOAD, @"code", [error code],
@"error", [NSString stringWithFormat:@"Error domain: \"%@\". %@", [error domain], [error localizedDescription]]);
return;
}
appOpenAd = ad;
appOpenAd.fullScreenContentDelegate = admobExtAppOpenAdDelegate;
SendSimpleMessage(MSG_APPOPEN, EVENT_LOADED);
}];
}

bool IsAppOpenLoaded() {
return appOpenAd != nil;
}

void ShowAppOpen() {
// If the app open ad is already showing, do not show the ad again.
if (isShowingAppOpenAd) {
NSLog(@"The app open ad is already showing.");
return;
}

if (!IsAppOpenLoaded()) {
NSLog(@"The app open ad is not ready yet.");
LoadAppOpen(appOpenAdId);
return;
}
isShowingAppOpenAd = true;
[appOpenAd presentFromRootViewController:nil];
}


//--------------------------------------------------
// Interstitial ADS
Expand Down Expand Up @@ -453,7 +497,9 @@ void DestroyBanner() {

//--------------------------------------------------

void Initialize_Ext(dmExtension::Params* params) {
void Initialize_Ext(dmExtension::Params* params, const char* defoldUserAgent) {
m_DefoldUserAgent = defoldUserAgent;

UIWindow* window = dmGraphics::GetNativeiOSUIWindow();
uiViewController = window.rootViewController;

Expand All @@ -464,7 +510,8 @@ void Initialize_Ext(dmExtension::Params* params) {
admobExtAppOpenAdDelegate = [[AdmobExtAppOpenAdDelegate alloc] init];
admobAppDelegate = [[AdMobAppDelegate alloc] init];

admobExtAppOpenAdDelegate.appOpenAdId = (char*)dmConfigFile::GetString(params->m_ConfigFile, "admob.app_open_ios", 0);
appOpenAdId = (char*)dmConfigFile::GetString(params->m_ConfigFile, "admob.app_open_ios", 0);
LoadAppOpen(appOpenAdId);

dmExtension::RegisteriOSUIApplicationDelegate(admobAppDelegate);
dmExtension::RegisteriOSUIApplicationDelegate(admobExtAppOpenAdDelegate);
Expand Down Expand Up @@ -519,6 +566,7 @@ void ShowAdInspector() {
}

void ActivateApp() {
ShowAppOpen();
}

void SetMaxAdContentRating(MaxAdRating max_ad_rating) {
Expand All @@ -542,71 +590,31 @@ void SetMaxAdContentRating(MaxAdRating max_ad_rating) {

@implementation AdmobExtAppOpenAdDelegate

- (void)loadAd {
// Do not load ad if there is an unused ad or one is already loading.
if (self.isLoadingAd || [self isAdAvailable]) {
return;
}
self.isLoadingAd = YES;

[GADAppOpenAd loadWithAdUnitID:[NSString stringWithUTF8String: self.appOpenAdId]
request:[GADRequest request]
completionHandler:^(GADAppOpenAd *_Nullable appOpenAd, NSError *_Nullable error) {
self.isLoadingAd = NO;
if (error) {
NSLog(@"Failed to load app open ad: %@", error);
return;
}
self.appOpenAd = appOpenAd;
self.appOpenAd.fullScreenContentDelegate = self;
}];
}

- (void)showAdIfAvailable {
// If the app open ad is already showing, do not show the ad again.
if (self.isShowingAd) {
return;
}

// If the app open ad is not available yet but is supposed to show, load a
// new ad.
if (![self isAdAvailable]) {
[self loadAd];
return;
}

self.isShowingAd = YES;
[self.appOpenAd presentFromRootViewController:nil];
}

- (BOOL)isAdAvailable {
// Check if ad exists and can be shown.
return self.appOpenAd != nil;
- (void)adWillPresentFullScreenContent:(nonnull id<GADFullScreenPresentingAd>)ad {
dmAdmob::SendSimpleMessage(dmAdmob::MSG_APPOPEN, dmAdmob::EVENT_OPENING);
}

- (void) applicationDidBecomeActive:(UIApplication *)application {
// Show the app open ad when the app is foregrounded.
[self showAdIfAvailable];
- (void)adDidDismissFullScreenContent:(nonnull id<GADFullScreenPresentingAd>)ad {
dmAdmob::appOpenAd = nil;
dmAdmob::isShowingAppOpenAd = false;
dmAdmob::LoadAppOpen(dmAdmob::appOpenAdId);
dmAdmob::SendSimpleMessage(dmAdmob::MSG_APPOPEN, dmAdmob::EVENT_CLOSED);
}

#pragma mark - GADFullScreenContentDelegate methods

- (void)adWillPresentFullScreenContent:(nonnull id<GADFullScreenPresentingAd>)ad {
NSLog(@"App open ad is will be presented.");
- (void)ad:(nonnull id<GADFullScreenPresentingAd>)ad didFailToPresentFullScreenContentWithError:(nonnull NSError *)error {
dmAdmob::appOpenAd = nil;
dmAdmob::isShowingAppOpenAd = false;
dmAdmob::LoadAppOpen(dmAdmob::appOpenAdId);
dmAdmob::SendSimpleMessage(dmAdmob::MSG_APPOPEN, dmAdmob::EVENT_FAILED_TO_SHOW, @"code", [error code],
@"error", [NSString stringWithFormat:@"Error domain: \"%@\". %@", [error domain], [error localizedDescription]]);
}

- (void)adDidDismissFullScreenContent:(nonnull id<GADFullScreenPresentingAd>)ad {
self.appOpenAd = nil;
self.isShowingAd = NO;
// Reload an ad.
[self loadAd];
- (void)adDidRecordImpression:(id)ad {
dmAdmob::SendSimpleMessage(dmAdmob::MSG_APPOPEN, dmAdmob::EVENT_IMPRESSION_RECORDED);
}

- (void)ad:(nonnull id<GADFullScreenPresentingAd>)ad didFailToPresentFullScreenContentWithError:(nonnull NSError *)error {
self.appOpenAd = nil;
self.isShowingAd = NO;
// Reload an ad.
[self loadAd];
- (void)adDidRecordClick:(id)ad {
dmAdmob::SendSimpleMessage(dmAdmob::MSG_APPOPEN, dmAdmob::EVENT_CLICKED);
}

@end
Expand Down Expand Up @@ -749,6 +757,10 @@ - (void)orientationDidChange:(NSNotification *)notification {
[self performSelector:@selector(UpdatePosition) withObject:nil afterDelay:0.1];
}

- (void) applicationDidBecomeActive:(UIApplication *)application {
dmAdmob::ShowAppOpen();
}

- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIDeviceOrientationDidChangeNotification object:nil];
[super dealloc];
Expand Down
Loading

0 comments on commit 3b8ec2b

Please sign in to comment.