From 79870ded6ae86d49d5b716d53585afa41d219a36 Mon Sep 17 00:00:00 2001 From: zhangbin Date: Mon, 22 Apr 2013 10:38:14 +0800 Subject: [PATCH] Add ads protocol. --- plugin/protocols/include/ProtocolAds.h | 103 ++++++++++++ .../protocols/platform/android/PluginUtils.h | 43 +++-- .../platform/android/ProtocolAds.cpp | 157 ++++++++++++++++++ plugin/protocols/proj.android/jni/Android.mk | 1 + .../src/org/cocos2dx/plugin/InterfaceAds.java | 103 ++++++++++++ 5 files changed, 393 insertions(+), 14 deletions(-) create mode 100644 plugin/protocols/include/ProtocolAds.h create mode 100644 plugin/protocols/platform/android/ProtocolAds.cpp create mode 100644 plugin/protocols/proj.android/src/org/cocos2dx/plugin/InterfaceAds.java diff --git a/plugin/protocols/include/ProtocolAds.h b/plugin/protocols/include/ProtocolAds.h new file mode 100644 index 0000000000..31d4427e3b --- /dev/null +++ b/plugin/protocols/include/ProtocolAds.h @@ -0,0 +1,103 @@ +#ifndef __CCX_PROTOCOL_ADS_H__ +#define __CCX_PROTOCOL_ADS_H__ + +#include "PluginProtocol.h" +#include +#include + +namespace cocos2d { namespace plugin { + +typedef std::map TAppInfo; + +class AdListener +{ +public: + typedef enum + { + eUnknownError = 0, + eNetworkError, + } EAdErrorCode; + + virtual void onReceiveAd() {} + virtual void onPresentScreen() {} + virtual void onFailedToReceiveAd(EAdErrorCode code, const char* msg) {} + virtual void onDismissScreen() {} +}; + +class ProtocolAds : public PluginProtocol +{ +public: + + typedef enum { + ePosTop = 0, + ePosTopLeft, + ePosTopRight, + ePosBottom, + ePosBottomLeft, + ePosBottomRight, + } EBannerPos; + + /** + @brief plugin initialization + */ + virtual bool init(); + + /** + @brief initialize the application info + @param appInfo This parameter is the info of aplication, + different plugin have different format + @warning Must invoke this interface before other interfaces. + And invoked only once. + */ + virtual void initAppInfo(TAppInfo appInfo); + + /** + @brief show banner ads at specified position + @param pos The position where the banner view be shown + @param sizeEnum The size of the banner view. + In different plugin, it's have different mean. + Pay attention to the subclass definition + */ + virtual void showBannerAd(EBannerPos pos, int sizeEnum); + + /** + @brief hide the banner ads view + */ + virtual void hideBannerAd(); + + /** + @brief Set whether needs to output logs to console. + @param debug If true debug mode enabled, or debug mode disabled. + */ + virtual void setDebugMode(bool debug); + + /** + @brief set the Ads listener + */ + static void setAdListener(AdListener* pListener) + { + m_pListener = pListener; + } + + // For the callbak methods + static void receiveAd(); + static void presentScreen(); + static void failedToReceiveAd(AdListener::EAdErrorCode code, const char* msg); + static void dismissScreen(); + + virtual const char* getPluginVersion() { return "ProtocolAds, v0.1.01 , subclass should override this interface!"; }; + virtual const char* getSDKVersion(); + virtual const char* getPluginName() = 0; + +protected: + ProtocolAds(); +public: + virtual ~ProtocolAds(); + +protected: + static AdListener* m_pListener; +}; + +}} // namespace cocos2d { namespace plugin { + +#endif /* __CCX_PROTOCOL_ADS_H__ */ diff --git a/plugin/protocols/platform/android/PluginUtils.h b/plugin/protocols/platform/android/PluginUtils.h index 0758817c04..0cfdfb435a 100644 --- a/plugin/protocols/platform/android/PluginUtils.h +++ b/plugin/protocols/platform/android/PluginUtils.h @@ -15,9 +15,9 @@ namespace cocos2d { namespace plugin { class PluginUtils { public: - static jobject createJavaMapObject(PluginJniMethodInfo&t, std::map* paramMap); - static bool initJavaPlugin(PluginProtocol* pPlugin, const char* className); - static JNIEnv* getEnv(); + static jobject createJavaMapObject(PluginJniMethodInfo&t, std::map* paramMap); + static bool initJavaPlugin(PluginProtocol* pPlugin, const char* className); + static JNIEnv* getEnv(); static PluginJavaData* getPluginJavaData(PluginProtocol* pKeyObj); static void setPluginJavaData(PluginProtocol* pKeyObj, PluginJavaData* pData); @@ -26,18 +26,33 @@ public: template static void callJavaFunctionWithName_oneBaseType(PluginProtocol* thiz, const char* funcName, const char* paramCode, T param) { - return_if_fails(funcName != NULL && strlen(funcName) > 0); - return_if_fails(paramCode != NULL && strlen(paramCode) > 0); + return_if_fails(funcName != NULL && strlen(funcName) > 0); + return_if_fails(paramCode != NULL && strlen(paramCode) > 0); PluginJavaData* pData = PluginUtils::getPluginJavaData(thiz); - PluginJniMethodInfo t; - if (PluginJniHelper::getMethodInfo(t - , pData->jclassName.c_str() - , funcName - , paramCode)) - { - t.env->CallVoidMethod(pData->jobj, t.methodID, param); - t.env->DeleteLocalRef(t.classID); - } + PluginJniMethodInfo t; + if (PluginJniHelper::getMethodInfo(t + , pData->jclassName.c_str() + , funcName + , paramCode)) + { + t.env->CallVoidMethod(pData->jobj, t.methodID, param); + t.env->DeleteLocalRef(t.classID); + } + } + + static void callJavaFunctionWithName(PluginProtocol* thiz, const char* funcName) + { + return_if_fails(funcName != NULL && strlen(funcName) > 0); + PluginJavaData* pData = PluginUtils::getPluginJavaData(thiz); + PluginJniMethodInfo t; + if (PluginJniHelper::getMethodInfo(t + , pData->jclassName.c_str() + , funcName + , "()V")) + { + t.env->CallVoidMethod(pData->jobj, t.methodID); + t.env->DeleteLocalRef(t.classID); + } } }; diff --git a/plugin/protocols/platform/android/ProtocolAds.cpp b/plugin/protocols/platform/android/ProtocolAds.cpp new file mode 100644 index 0000000000..9fc750ea17 --- /dev/null +++ b/plugin/protocols/platform/android/ProtocolAds.cpp @@ -0,0 +1,157 @@ +#include "ProtocolAds.h" +#include "PluginJniHelper.h" +#include +#include "PluginUtils.h" +#include "PluginJavaData.h" + +#if 1 +#define LOG_TAG "ProtocolAds" +#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__) +#else +#define LOGD(...) +#endif + +namespace cocos2d { namespace plugin { + +extern "C" { + JNIEXPORT void JNICALL Java_org_cocos2dx_plugin_InterfaceAds_nativeReceiveAd(JNIEnv* env, jobject thiz) { + ProtocolAds::receiveAd(); + } + + JNIEXPORT void JNICALL Java_org_cocos2dx_plugin_InterfaceAds_nativePresentScreen(JNIEnv* env, jobject thiz) { + ProtocolAds::presentScreen(); + } + + JNIEXPORT void JNICALL Java_org_cocos2dx_plugin_InterfaceAds_nativeFailedToReceiveAd(JNIEnv* env, jobject thiz, jint ret, jstring msg) { + std::string strMsg = PluginJniHelper::jstring2string(msg); + ProtocolAds::failedToReceiveAd((AdListener::EAdErrorCode) ret, strMsg.c_str()); + } + + JNIEXPORT void JNICALL Java_org_cocos2dx_plugin_InterfaceAds_nativeDismissScreen(JNIEnv* env, jobject thiz) { + ProtocolAds::dismissScreen(); + } +} + +AdListener* ProtocolAds::m_pListener = NULL; + +ProtocolAds::ProtocolAds() +{ +} + +ProtocolAds::~ProtocolAds() +{ + PluginUtils::erasePluginJavaData(this); +} + +bool ProtocolAds::init() +{ + return true; +} + +void ProtocolAds::initAppInfo(TAppInfo appInfo) +{ + if (appInfo.empty()) + { + LOGD("The application info is empty!"); + return; + } + else + { + PluginJavaData* pData = PluginUtils::getPluginJavaData(this); + PluginJniMethodInfo t; + if (PluginJniHelper::getMethodInfo(t + , pData->jclassName.c_str() + , "initAppInfo" + , "(Ljava/util/Hashtable;)V")) + { + // generate the hashtable from map + jobject obj_Map = PluginUtils::createJavaMapObject(t, &appInfo); + + // invoke java method + t.env->CallVoidMethod(pData->jobj, t.methodID, obj_Map); + t.env->DeleteLocalRef(obj_Map); + t.env->DeleteLocalRef(t.classID); + } + } +} + +void ProtocolAds::showBannerAd(EBannerPos pos, int size) +{ + PluginJavaData* pData = PluginUtils::getPluginJavaData(this); + PluginJniMethodInfo t; + + LOGD("Class name : %s", pData->jclassName.c_str()); + if (PluginJniHelper::getMethodInfo(t + , pData->jclassName.c_str() + , "showBannerAd" + , "(II)V")) + { + t.env->CallVoidMethod(pData->jobj, t.methodID, pos, size); + t.env->DeleteLocalRef(t.classID); + } +} + +void ProtocolAds::hideBannerAd() +{ + PluginUtils::callJavaFunctionWithName(this, "hideBannerAd"); +} + +const char* ProtocolAds::getSDKVersion() +{ + std::string verName; + + PluginJavaData* pData = PluginUtils::getPluginJavaData(this); + PluginJniMethodInfo t; + if (PluginJniHelper::getMethodInfo(t + , pData->jclassName.c_str() + , "getSDKVersion" + , "()Ljava/lang/String;")) + { + jstring ret = (jstring)(t.env->CallObjectMethod(pData->jobj, t.methodID)); + verName = PluginJniHelper::jstring2string(ret); + } + return verName.c_str(); +} + +void ProtocolAds::setDebugMode(bool debug) +{ + PluginUtils::callJavaFunctionWithName_oneBaseType(this, "setDebugMode", "(Z)V", debug); +} + +void ProtocolAds::receiveAd() +{ + LOGD("ProtocolAds::receiveAd invoked!"); + if (m_pListener != NULL) + { + m_pListener->onReceiveAd(); + } +} + +void ProtocolAds::presentScreen() +{ + LOGD("ProtocolAds::presentScreen invoked!"); + if (m_pListener != NULL) + { + m_pListener->onPresentScreen(); + } +} + +void ProtocolAds::failedToReceiveAd(AdListener::EAdErrorCode code, const char* msg) +{ + LOGD("ProtocolAds::failedToReceiveAd invoked!"); + if (m_pListener != NULL) + { + m_pListener->onFailedToReceiveAd(code, msg); + } +} + +void ProtocolAds::dismissScreen() +{ + LOGD("ProtocolAds::dismissScreen invoked!"); + if (m_pListener != NULL) + { + m_pListener->onDismissScreen(); + } +} + +}} // namespace cocos2d { namespace plugin { diff --git a/plugin/protocols/proj.android/jni/Android.mk b/plugin/protocols/proj.android/jni/Android.mk index 29ba7e1c5d..9e0ad021e8 100644 --- a/plugin/protocols/proj.android/jni/Android.mk +++ b/plugin/protocols/proj.android/jni/Android.mk @@ -12,6 +12,7 @@ $(addprefix ../../platform/android/, \ PluginUtils.cpp \ ProtocolAnalytics.cpp \ ProtocolIAP.cpp \ + ProtocolAds.cpp \ ) \ ../../PluginManager.cpp \ ../../RegisterPlugin.cpp \ diff --git a/plugin/protocols/proj.android/src/org/cocos2dx/plugin/InterfaceAds.java b/plugin/protocols/proj.android/src/org/cocos2dx/plugin/InterfaceAds.java new file mode 100644 index 0000000000..551a98e5d0 --- /dev/null +++ b/plugin/protocols/proj.android/src/org/cocos2dx/plugin/InterfaceAds.java @@ -0,0 +1,103 @@ +package org.cocos2dx.plugin; + +import java.util.Hashtable; + +import android.content.Context; +import android.view.Gravity; +import android.view.View; +import android.view.WindowManager; + +public class InterfaceAds { + public static final int UNKNOWN_ERROR = 0; + public static final int NETWORK_ERROR = 1; + public static final int REQUESTING_ERROR = 2; + + public static final int POS_TOP = 0; + public static final int POS_TOP_LEFT = 1; + public static final int POS_TOP_RIGHT = 2; + public static final int POS_BOTTOM = 3; + public static final int POS_BOTTOM_LEFT = 4; + public static final int POS_BOTTOM_RIGHT = 5; + + public interface AdsAdapter { + public void initAppInfo(Hashtable appInfo); + public void showBannerAd(int pos, int sizeEnum); + public void hideBannerAd(); + public void setDebugMode(boolean debug); + public String getSDKVersion(); + } + + public static void addAdView(WindowManager mWm, View adView, int pos) { + WindowManager.LayoutParams mLayoutParams = new WindowManager.LayoutParams(); + mLayoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_PANEL; + mLayoutParams.width = WindowManager.LayoutParams.WRAP_CONTENT; + mLayoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT; + mLayoutParams.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; + + switch (pos) { + case POS_TOP: + mLayoutParams.gravity = Gravity.TOP; + break; + case POS_TOP_LEFT: + mLayoutParams.gravity = Gravity.TOP | Gravity.LEFT; + break; + case POS_TOP_RIGHT: + mLayoutParams.gravity = Gravity.TOP | Gravity.RIGHT; + break; + case POS_BOTTOM: + mLayoutParams.gravity = Gravity.BOTTOM; + break; + case POS_BOTTOM_LEFT: + mLayoutParams.gravity = Gravity.BOTTOM | Gravity.LEFT; + break; + case POS_BOTTOM_RIGHT: + mLayoutParams.gravity = Gravity.BOTTOM | Gravity.RIGHT; + break; + default: + break; + } + mWm.addView(adView, mLayoutParams); + } + + public static void receiveAd() { + PluginWrapper.runOnGLThread(new Runnable(){ + @Override + public void run() { + InterfaceAds.nativeReceiveAd(); + } + }); + } + private native static void nativeReceiveAd(); + + public static void presentScreen() { + PluginWrapper.runOnGLThread(new Runnable(){ + @Override + public void run() { + InterfaceAds.nativePresentScreen(); + } + }); + } + private native static void nativePresentScreen(); + + public static void failedToReceiveAd(int code, String msg) { + final int eCode = code; + final String eMsg = msg; + PluginWrapper.runOnGLThread(new Runnable(){ + @Override + public void run() { + InterfaceAds.nativeFailedToReceiveAd(eCode, eMsg); + } + }); + } + private native static void nativeFailedToReceiveAd(int code, String msg); + + public static void dismissScreen() { + PluginWrapper.runOnGLThread(new Runnable(){ + @Override + public void run() { + InterfaceAds.nativeDismissScreen(); + } + }); + } + private native static void nativeDismissScreen(); +}