IAP command pointer to products list function to avoid crash on multiple calls products list

This commit is contained in:
Denis Dyukorev 2020-02-15 15:00:15 +03:00
parent 8d9ea79d7d
commit d6cc6f55f9
5 changed files with 28 additions and 28 deletions

View File

@ -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");

View File

@ -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);
}

View File

@ -35,6 +35,7 @@ public class IapAmazon implements PurchasingListener {
public static final String TAG = "iap";
private HashMap<RequestId, IListProductsListener> listProductsListeners;
private HashMap<RequestId, Long> listProductsCommandPtrs;
private HashMap<RequestId, IPurchaseListener> 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<String> skuSet = new HashSet<String>();
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<String, Product> 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);
}
}
}

View File

@ -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<String> skuList = new ArrayList<String>();
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);
}
}
}));

View File

@ -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);