AdMob.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304
  1. /******************************************************************************/
  2. #include "stdafx.h"
  3. #if IOS
  4. #include "../../../ThirdPartyLibs/begin.h"
  5. #include "../../../ThirdPartyLibs/AdMob/GADAdSize.h"
  6. #include "../../../ThirdPartyLibs/AdMob/GADBannerView.h"
  7. #include "../../../ThirdPartyLibs/AdMob/GADBannerViewDelegate.h"
  8. #include "../../../ThirdPartyLibs/AdMob/GADInterstitial.h"
  9. #include "../../../ThirdPartyLibs/AdMob/GADInterstitialDelegate.h"
  10. #include "../../../ThirdPartyLibs/AdMob/GADRequest.h"
  11. #include "../../../ThirdPartyLibs/AdMob/GADRequestError.h"
  12. #include "../../../ThirdPartyLibs/end.h"
  13. #include "../Platforms/iOS/iOS.h"
  14. static Bool InterstitialLoaded, InterstitialShow, BannerVisible;
  15. static Str8 InterstitialUnitID;
  16. @interface EsenthelBannerView : GADBannerView<GADBannerViewDelegate>
  17. {
  18. }
  19. -(void)adViewDidReceiveAd:(GADBannerView*)bannerView;
  20. -(void)adView:(GADBannerView*)view didFailToReceiveAdWithError:(GADRequestError*)error;
  21. @end
  22. @implementation EsenthelBannerView
  23. -(void)adViewDidReceiveAd:(GADBannerView*)bannerView {AdMob._banner_state=AdMobClass::DONE ; AdMob._banner_size=Round(Vec2(bannerView.frame.size.width, bannerView.frame.size.height)*ScreenScale); if(BannerVisible)AdMob.bannerShow();}
  24. -(void)adView:(GADBannerView*)view didFailToReceiveAdWithError:(GADRequestError*)error {AdMob._banner_state=AdMobClass::ERROR;}
  25. @end
  26. @interface EsenthelInterstitial : NSObject<GADInterstitialDelegate>
  27. {
  28. }
  29. -(void)interstitialDidReceiveAd:(GADInterstitial*)interstitial;
  30. -(void)interstitial:(GADInterstitial*)interstitial didFailToReceiveAdWithError:(GADRequestError*)error;
  31. -(void)interstitialDidDismissScreen:(GADInterstitial*)interstitial;
  32. -(void)interstitialWillDismissScreen:(GADInterstitial *)interstitial;
  33. @end
  34. @implementation EsenthelInterstitial
  35. -(void)interstitialDidReceiveAd:(GADInterstitial*)interstitial {AdMob._fs_state=AdMobClass::DONE ; InterstitialLoaded=true; if(InterstitialShow){InterstitialShow=false; AdMob.fsShow();}}
  36. -(void)interstitial:(GADInterstitial*)interstitial didFailToReceiveAdWithError:(GADRequestError*)error {AdMob._fs_state=AdMobClass::ERROR;}
  37. -(void)interstitialDidDismissScreen:(GADInterstitial*)interstitial
  38. {
  39. AdMob.fsCreate(InterstitialUnitID); // when ad is closed, it cannot be displayed again, so reload another one
  40. if(ViewController)[ViewController.view layoutSubviews]; // if the device is rotated when view is displayed, then the render buffers don't get resized automatically, so do it manually
  41. }
  42. -(void)interstitialWillDismissScreen:(GADInterstitial*)interstitial {}
  43. @end
  44. #endif
  45. namespace EE{
  46. /******************************************************************************/
  47. AdMobClass AdMob;
  48. #if IOS
  49. static GADRequest *Request;
  50. static EsenthelBannerView *Banner;
  51. static GADInterstitial *Interstitial;
  52. static EsenthelInterstitial *InterstitialDelegate;
  53. static void ResizeAd()
  54. {
  55. VecI2 old=AdMob.bannerPos(); AdMob._banner_pos.x^=1; // change to force set
  56. AdMob.bannerPos(old.x, old.y);
  57. }
  58. #endif
  59. /******************************************************************************/
  60. AdMobClass::~AdMobClass()
  61. {
  62. #if IOS
  63. fsDel(); // release 'Interstitial'
  64. bannerDel(); // release 'Banner'
  65. [InterstitialDelegate release]; InterstitialDelegate=null; // release after interstitial because it's using it
  66. #endif
  67. }
  68. AdMobClass::AdMobClass()
  69. {
  70. _banner_state=_fs_state=NONE;
  71. _banner_pos.set(0, 1);
  72. _banner_size.zero();
  73. #if IOS
  74. Request=[GADRequest request];
  75. InterstitialDelegate=[[EsenthelInterstitial alloc] init];
  76. #endif
  77. }
  78. AdMobClass& AdMobClass::testMode(Bool on)
  79. {
  80. #if ANDROID
  81. JNI jni;
  82. if(jni && ActivityClass)
  83. if(JMethodID setAdRequest=jni->GetStaticMethodID(ActivityClass, "setAdRequest", "(Z)V"))
  84. jni->CallStaticVoidMethod(ActivityClass, setAdRequest, jboolean(on));
  85. #elif IOS
  86. Request.testDevices=nil;
  87. if(on)
  88. if(NSClassFromString(@"ASIdentifierManager"))
  89. if(NSString *device_id=[[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString])
  90. {
  91. Str8 dev_id =AppleString(device_id);
  92. UID dev_id_md5=MD5Mem(dev_id(), dev_id.length());
  93. dev_id =TextHexMem(&dev_id_md5, SIZE(dev_id_md5));
  94. REPAO(dev_id._d)=CaseDown(dev_id._d[i]); // AdMob expects case down
  95. if(NSStringAuto str=dev_id)Request.testDevices=[NSArray arrayWithObjects: str, nil];
  96. }
  97. #endif
  98. return T;
  99. }
  100. /******************************************************************************/
  101. AdMobClass& AdMobClass::bannerDel()
  102. {
  103. #if ANDROID
  104. JNI jni;
  105. if(jni && ActivityClass && Activity)
  106. if(JMethodID adDel=jni->GetMethodID(ActivityClass, "adDel", "(Z)V"))
  107. jni->CallVoidMethod(Activity, adDel, jboolean(true));
  108. #elif IOS
  109. if(Banner)
  110. {
  111. Banner.delegate=nil;
  112. [Banner release];
  113. Banner=null;
  114. }
  115. #endif
  116. _banner_state=NONE;
  117. _banner_size.zero();
  118. return T;
  119. }
  120. AdMobClass& AdMobClass::fsDel()
  121. {
  122. #if ANDROID
  123. JNI jni;
  124. if(jni && ActivityClass && Activity)
  125. if(JMethodID adDel=jni->GetMethodID(ActivityClass, "adDel", "(Z)V"))
  126. jni->CallVoidMethod(Activity, adDel, jboolean(false));
  127. #elif IOS
  128. if(Interstitial)
  129. {
  130. Interstitial.delegate=nil;
  131. [Interstitial release];
  132. Interstitial=null;
  133. InterstitialLoaded=false;
  134. }
  135. #endif
  136. _fs_state=NONE;
  137. return T;
  138. }
  139. /******************************************************************************/
  140. AdMobClass& AdMobClass::bannerCreate(C Str8 &unit_id, BANNER_TYPE type)
  141. {
  142. if(unit_id.is())
  143. {
  144. #if ANDROID
  145. _banner_state=LOADING;
  146. _banner_size .zero();
  147. JNI jni;
  148. if(jni && ActivityClass && Activity)
  149. if(JMethodID adCreate=jni->GetMethodID(ActivityClass, "adCreate", "(Ljava/lang/String;I)V"))
  150. if(JString j_unit_id=unit_id)
  151. jni->CallVoidMethod(Activity, adCreate, j_unit_id(), jint(type));
  152. #elif IOS
  153. const GADAdSize *size=null;
  154. switch(type)
  155. {
  156. case BANNER : size=&kGADAdSizeBanner ; break;
  157. case MEDIUM_RECTANGLE: size=&kGADAdSizeMediumRectangle; break;
  158. case FULL_BANNER : size=&kGADAdSizeFullBanner ; break;
  159. case LEADERBOARD : size=&kGADAdSizeLeaderboard ; break;
  160. case SMART_BANNER : size=&((DirToAxis(App.orientation())==AXIS_X) ? kGADAdSizeSmartBannerLandscape : kGADAdSizeSmartBannerPortrait); break;
  161. }
  162. if(size)
  163. {
  164. bannerDel();
  165. if(Request && ViewController)
  166. {
  167. _banner_state=LOADING;
  168. ResizeAdPtr=ResizeAd;
  169. Banner=[[EsenthelBannerView alloc] initWithAdSize:*size];
  170. Banner.adUnitID=NSStringAuto(unit_id);
  171. Banner.rootViewController=ViewController;
  172. [Banner setDelegate:Banner];
  173. [Banner loadRequest:Request];
  174. }
  175. }
  176. #endif
  177. }
  178. return T;
  179. }
  180. AdMobClass& AdMobClass::fsCreate(C Str8 &unit_id)
  181. {
  182. if(unit_id.is())
  183. {
  184. #if ANDROID
  185. _fs_state=LOADING;
  186. JNI jni;
  187. if(jni && ActivityClass && Activity)
  188. if(JMethodID adCreate=jni->GetMethodID(ActivityClass, "adCreate", "(Ljava/lang/String;I)V"))
  189. if(JString j_unit_id=unit_id)
  190. jni->CallVoidMethod(Activity, adCreate, j_unit_id(), jint(INTERSTITIAL));
  191. #elif IOS
  192. fsDel();
  193. if(Request)
  194. if(NSStringAuto str=unit_id)
  195. {
  196. InterstitialUnitID=unit_id;
  197. _fs_state=LOADING;
  198. Interstitial=[[GADInterstitial alloc] initWithAdUnitID:str];
  199. [Interstitial setDelegate:InterstitialDelegate];
  200. [Interstitial loadRequest:Request];
  201. }
  202. #endif
  203. }
  204. return T;
  205. }
  206. /******************************************************************************/
  207. AdMobClass& AdMobClass::bannerVisible(Bool visible)
  208. {
  209. #if ANDROID
  210. JNI jni;
  211. if(jni && ActivityClass && Activity)
  212. if(JMethodID adVisible=jni->GetMethodID(ActivityClass, "adVisible", "(ZZ)V"))
  213. jni->CallVoidMethod(Activity, adVisible, jboolean(true), jboolean(visible));
  214. #elif IOS
  215. BannerVisible=visible;
  216. if(ViewController && Banner)
  217. {
  218. if(visible)
  219. {
  220. [ViewController.view addSubview:Banner];
  221. }else
  222. {
  223. [Banner removeFromSuperview];
  224. }
  225. }
  226. #endif
  227. return T;
  228. }
  229. AdMobClass& AdMobClass::fsVisible(Bool visible)
  230. {
  231. #if ANDROID
  232. JNI jni;
  233. if(jni && ActivityClass && Activity)
  234. if(JMethodID adVisible=jni->GetMethodID(ActivityClass, "adVisible", "(ZZ)V"))
  235. jni->CallVoidMethod(Activity, adVisible, jboolean(false), jboolean(visible));
  236. #elif IOS
  237. if(visible)
  238. {
  239. if(Interstitial && InterstitialLoaded && ViewController)
  240. {
  241. InterstitialLoaded=false; // can't reuse again
  242. [Interstitial presentFromRootViewController:ViewController];
  243. }else InterstitialShow=true;
  244. }else
  245. {
  246. InterstitialShow=false;
  247. // there's no method to hide
  248. }
  249. #endif
  250. return T;
  251. }
  252. AdMobClass& AdMobClass::bannerShow() {return bannerVisible(true );}
  253. AdMobClass& AdMobClass::bannerHide() {return bannerVisible(false);}
  254. AdMobClass& AdMobClass::fsShow() {return fsVisible(true );}
  255. AdMobClass& AdMobClass::fsHide() {return fsVisible(false);}
  256. /******************************************************************************/
  257. AdMobClass& AdMobClass::bannerPos(Int x, Int y)
  258. {
  259. if(_banner_pos.x!=x || _banner_pos.y!=y)
  260. {
  261. _banner_pos.set(x, y);
  262. #if ANDROID
  263. JNI jni;
  264. if(jni && ActivityClass && Activity)
  265. if(JMethodID adPos=jni->GetMethodID(ActivityClass, "adPos", "(II)V"))
  266. jni->CallVoidMethod(Activity, adPos, jint(x), jint(y));
  267. #elif IOS
  268. if(Banner)
  269. {
  270. CGRect rect=Banner.frame;
  271. Vec2 res =Vec2(D.resW(), D.resH())/ScreenScale,
  272. size(rect.size.width, rect.size.height),
  273. pos ((x<0) ? 0 : (x>0) ? res.x-size.x : (res.x-size.x)*0.5f,
  274. (y>0) ? 0 : (y<0) ? res.y-size.y : (res.y-size.y)*0.5f);
  275. Banner.frame=CGRectMake(pos.x, pos.y, size.x, size.y);
  276. }
  277. #endif
  278. }
  279. return T;
  280. }
  281. /******************************************************************************/
  282. } // namespace EE
  283. /******************************************************************************/
  284. #if ANDROID
  285. extern "C" JNIEXPORT void JNICALL Java_com_esenthel_Native_adState(JNIEnv *env, jclass clazz, jboolean banner, jint state)
  286. {
  287. (banner ? AdMob._banner_state : AdMob._fs_state)=AdMobClass::STATE(state);
  288. }
  289. extern "C" JNIEXPORT void JNICALL Java_com_esenthel_Native_bannerSize(JNIEnv *env, jclass clazz, jint width, jint height)
  290. {
  291. AdMob._banner_size.set(width, height);
  292. }
  293. #endif
  294. /******************************************************************************/