From d6cc6f55f9d958ef2b0f778e85dbb630dadb947f Mon Sep 17 00:00:00 2001 From: Denis Dyukorev Date: Sat, 15 Feb 2020 15:00:15 +0300 Subject: [PATCH] IAP command pointer to products list function to avoid crash on multiple calls products list --- extension-iap/src/iap_android.cpp | 28 ++++++++----------- .../com/defold/iap/IListProductsListener.java | 2 +- .../src/java/com/defold/iap/IapAmazon.java | 16 +++++++---- .../java/com/defold/iap/IapGooglePlay.java | 8 +++--- .../src/java/com/defold/iap/IapJNI.java | 2 +- 5 files changed, 28 insertions(+), 28 deletions(-) diff --git a/extension-iap/src/iap_android.cpp b/extension-iap/src/iap_android.cpp index 92adf32..136b305 100644 --- a/extension-iap/src/iap_android.cpp +++ b/extension-iap/src/iap_android.cpp @@ -34,7 +34,6 @@ struct IAP bool m_autoFinishTransactions; int m_ProviderId; - dmScript::LuaCallbackInfo* m_ProductCallback; dmScript::LuaCallbackInfo* m_Listener; jobject m_IAP; @@ -61,14 +60,13 @@ static int IAP_List(lua_State* L) return 0; } - if (g_IAP.m_ProductCallback) - dmScript::DestroyCallback(g_IAP.m_ProductCallback); - - g_IAP.m_ProductCallback = dmScript::CreateCallback(L, 2); - JNIEnv* env = Attach(); + IAPCommand* cmd = new IAPCommand; + cmd->m_Callback = dmScript::CreateCallback(L, 2); + cmd->m_Command = IAP_PRODUCT_RESULT; + jstring products = env->NewStringUTF(buf); - env->CallVoidMethod(g_IAP.m_IAP, g_IAP.m_List, products, g_IAP.m_IAPJNI); + env->CallVoidMethod(g_IAP.m_IAP, g_IAP.m_List, products, g_IAP.m_IAPJNI, (jlong)cmd); env->DeleteLocalRef(products); Detach(); @@ -198,7 +196,7 @@ extern "C" { #endif -JNIEXPORT void JNICALL Java_com_defold_iap_IapJNI_onProductsResult__ILjava_lang_String_2(JNIEnv* env, jobject, jint responseCode, jstring productList) +JNIEXPORT void JNICALL Java_com_defold_iap_IapJNI_onProductsResult(JNIEnv* env, jobject, jint responseCode, jstring productList, jlong cmdHandle) { const char* pl = 0; if (productList) @@ -206,16 +204,14 @@ JNIEXPORT void JNICALL Java_com_defold_iap_IapJNI_onProductsResult__ILjava_lang_ pl = env->GetStringUTFChars(productList, 0); } - IAPCommand cmd; - cmd.m_Callback = g_IAP.m_ProductCallback; - cmd.m_Command = IAP_PRODUCT_RESULT; - cmd.m_ResponseCode = responseCode; + IAPCommand* cmd = (IAPCommand*)cmdHandle; + cmd->m_ResponseCode = responseCode; if (pl) { - cmd.m_Data = strdup(pl); + cmd->m_Data = strdup(pl); env->ReleaseStringUTFChars(productList, pl); } - IAP_Queue_Push(&g_IAP.m_CommandQueue, &cmd); + IAP_Queue_Push(&g_IAP.m_CommandQueue, cmd); } JNIEXPORT void JNICALL Java_com_defold_iap_IapJNI_onPurchaseResult__ILjava_lang_String_2(JNIEnv* env, jobject, jint responseCode, jstring purchaseData) @@ -287,8 +283,6 @@ static void HandleProductResult(const IAPCommand* cmd) dmScript::TeardownCallback(cmd->m_Callback); dmScript::DestroyCallback(cmd->m_Callback); - assert(g_IAP.m_ProductCallback == cmd->m_Callback); - g_IAP.m_ProductCallback = 0; assert(top == lua_gettop(L)); } @@ -388,7 +382,7 @@ static dmExtension::Result InitializeIAP(dmExtension::Params* params) jclass iap_jni_class = (jclass)env->CallObjectMethod(cls, find_class, str_class_name); env->DeleteLocalRef(str_class_name); - g_IAP.m_List = env->GetMethodID(iap_class, "listItems", "(Ljava/lang/String;Lcom/defold/iap/IListProductsListener;)V"); + g_IAP.m_List = env->GetMethodID(iap_class, "listItems", "(Ljava/lang/String;Lcom/defold/iap/IListProductsListener;J)V"); g_IAP.m_Buy = env->GetMethodID(iap_class, "buy", "(Ljava/lang/String;Lcom/defold/iap/IPurchaseListener;)V"); g_IAP.m_Restore = env->GetMethodID(iap_class, "restore", "(Lcom/defold/iap/IPurchaseListener;)V"); g_IAP.m_Stop = env->GetMethodID(iap_class, "stop", "()V"); diff --git a/extension-iap/src/java/com/defold/iap/IListProductsListener.java b/extension-iap/src/java/com/defold/iap/IListProductsListener.java index 1a93be4..b4c236e 100644 --- a/extension-iap/src/java/com/defold/iap/IListProductsListener.java +++ b/extension-iap/src/java/com/defold/iap/IListProductsListener.java @@ -1,5 +1,5 @@ package com.defold.iap; public interface IListProductsListener { - public void onProductsResult(int resultCode, String productList); + public void onProductsResult(int resultCode, String productList, long cmdHandle); } diff --git a/extension-iap/src/java/com/defold/iap/IapAmazon.java b/extension-iap/src/java/com/defold/iap/IapAmazon.java index 089dc36..1badbbd 100644 --- a/extension-iap/src/java/com/defold/iap/IapAmazon.java +++ b/extension-iap/src/java/com/defold/iap/IapAmazon.java @@ -35,6 +35,7 @@ public class IapAmazon implements PurchasingListener { public static final String TAG = "iap"; private HashMap listProductsListeners; + private HashMap listProductsCommandPtrs; private HashMap purchaseListeners; private Activity activity; @@ -54,7 +55,7 @@ public class IapAmazon implements PurchasingListener { public void stop() { } - public void listItems(final String skus, final IListProductsListener listener) { + public void listItems(final String skus, final IListProductsListener listener, final long commandPtr) { final Set skuSet = new HashSet(); for (String x : skus.split(",")) { if (x.trim().length() > 0) { @@ -71,6 +72,7 @@ public class IapAmazon implements PurchasingListener { RequestId req = PurchasingService.getProductData(skuSet); if (req != null) { listProductsListeners.put(req, listener); + listProductsCommandPtrs.put(req, commandPtr); } else { Log.e(TAG, "Did not expect a null requestId"); } @@ -150,17 +152,21 @@ public class IapAmazon implements PurchasingListener { public void onProductDataResponse(ProductDataResponse productDataResponse) { RequestId reqId = productDataResponse.getRequestId(); IListProductsListener listener; + long commadPtr = 0; synchronized (this.listProductsListeners) { listener = this.listProductsListeners.get(reqId); + commadPtr = this.listProductsCommandPtrs.get(reqId); + + this.listProductsListeners.remove(reqId); + this.listProductsCommandPtrs.remove(reqId); if (listener == null) { Log.e(TAG, "No listener found for request " + reqId.toString()); return; } - this.listProductsListeners.remove(reqId); } if (productDataResponse.getRequestStatus() != ProductDataResponse.RequestStatus.SUCCESSFUL) { - listener.onProductsResult(IapJNI.BILLING_RESPONSE_RESULT_ERROR, null); + listener.onProductsResult(IapJNI.BILLING_RESPONSE_RESULT_ERROR, null, commadPtr); } else { Map products = productDataResponse.getProductData(); try { @@ -180,9 +186,9 @@ public class IapAmazon implements PurchasingListener { } data.put(key, item); } - listener.onProductsResult(IapJNI.BILLING_RESPONSE_RESULT_OK, data.toString()); + listener.onProductsResult(IapJNI.BILLING_RESPONSE_RESULT_OK, data.toString(), commadPtr); } catch (JSONException e) { - listener.onProductsResult(IapJNI.BILLING_RESPONSE_RESULT_ERROR, null); + listener.onProductsResult(IapJNI.BILLING_RESPONSE_RESULT_ERROR, null, commadPtr); } } } diff --git a/extension-iap/src/java/com/defold/iap/IapGooglePlay.java b/extension-iap/src/java/com/defold/iap/IapGooglePlay.java index 96aa612..2c7463e 100644 --- a/extension-iap/src/java/com/defold/iap/IapGooglePlay.java +++ b/extension-iap/src/java/com/defold/iap/IapGooglePlay.java @@ -238,7 +238,7 @@ public class IapGooglePlay implements Handler.Callback { }); } - public void listItems(final String skus, final IListProductsListener listener) { + public void listItems(final String skus, final IListProductsListener listener, final long commandPtr) { ArrayList skuList = new ArrayList(); for (String x : skus.split(",")) { if (x.trim().length() > 0) { @@ -261,15 +261,15 @@ public class IapGooglePlay implements Handler.Callback { products.put(key, convertProduct(product)); } } - listener.onProductsResult(resultCode, products.toString()); + listener.onProductsResult(resultCode, products.toString(), commandPtr); } catch(JSONException e) { Log.wtf(TAG, "Failed to convert products", e); - listener.onProductsResult(resultCode, null); + listener.onProductsResult(resultCode, null, commandPtr); } } else { - listener.onProductsResult(resultCode, null); + listener.onProductsResult(resultCode, null, commandPtr); } } })); diff --git a/extension-iap/src/java/com/defold/iap/IapJNI.java b/extension-iap/src/java/com/defold/iap/IapJNI.java index f333fb3..7403083 100644 --- a/extension-iap/src/java/com/defold/iap/IapJNI.java +++ b/extension-iap/src/java/com/defold/iap/IapJNI.java @@ -23,7 +23,7 @@ public class IapJNI implements IListProductsListener, IPurchaseListener { } @Override - public native void onProductsResult(int responseCode, String productList); + public native void onProductsResult(int responseCode, String productList, long cmdHandle); @Override public native void onPurchaseResult(int responseCode, String purchaseData);