Skip to content

Commit

Permalink
Don't crash when purchases is disconnected mid-operation.
Browse files Browse the repository at this point in the history
  • Loading branch information
justin-espedal committed Jun 29, 2019
1 parent ef508d5 commit cb37312
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 3 deletions.
14 changes: 13 additions & 1 deletion dependencies/android/src/com/stencyl/android/AndroidBilling.java
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,12 @@ public static void release()
public boolean onActivityResult(int requestCode, int resultCode, Intent data) {
if (inAppPurchaseHelper != null) {

return !inAppPurchaseHelper.handleActivityResult (requestCode, resultCode, data);
try {
return !inAppPurchaseHelper.handleActivityResult (requestCode, resultCode, data);
} catch (IllegalStateException e) {
Log.i("Purchases","Failed to handle activity result. " + e.getMessage());
return true;
}
}

return super.onActivityResult (requestCode, resultCode, data);
Expand Down Expand Up @@ -144,6 +149,11 @@ public void run() {
mPurchaseFinishedListener.onIabPurchaseFinished(
new IabResult(IabHelper.BILLING_RESPONSE_RESULT_ERROR, null),
null);
} catch (IllegalStateException e) {
Log.e("Purchases", "Failed to launch purchase flow.", e);
mPurchaseFinishedListener.onIabPurchaseFinished(
new IabResult(IabHelper.BILLING_RESPONSE_RESULT_ERROR, null),
null);
}
}
});
Expand All @@ -167,6 +177,8 @@ public static void consume(final String purchaseJson, final String itemType, fin
AndroidBilling.inAppPurchaseHelper.consumeAsync(purchase, mConsumeFinishedListener);
} catch (IabAsyncInProgressException e) {
Log.i("Purchases","Error consuming. Another async operation in progress.");
} catch (IllegalStateException e) {
Log.e("Purchases","Error consuming.", e);
}
}

Expand Down
22 changes: 20 additions & 2 deletions dependencies/android/src/com/stencyl/android/util/IabHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -434,6 +434,7 @@ public void launchPurchaseFlow(Activity act, String sku, String itemType, List<S
throws IabAsyncInProgressException {
checkNotDisposed();
checkSetupDone("launchPurchaseFlow");
checkServiceConnected("launchPurchaseFlow");
flagStartAsync("launchPurchaseFlow");
IabResult result;

Expand Down Expand Up @@ -520,6 +521,7 @@ public boolean handleActivityResult(int requestCode, int resultCode, Intent data

checkNotDisposed();
checkSetupDone("handleActivityResult");
checkServiceConnected("handleActivityResult");

// end of async purchase operation that started on launchPurchaseFlow
flagEndAsync();
Expand Down Expand Up @@ -619,6 +621,7 @@ public Inventory queryInventory(boolean querySkuDetails, List<String> moreItemSk
List<String> moreSubsSkus) throws IabException {
checkNotDisposed();
checkSetupDone("queryInventory");
checkServiceConnected("queryInventory");
try {
Inventory inv = new Inventory();
int r = queryPurchases(inv, ITEM_TYPE_INAPP);
Expand Down Expand Up @@ -689,6 +692,7 @@ public void queryInventoryAsync(final boolean querySkuDetails, final List<String
final Handler handler = new Handler();
checkNotDisposed();
checkSetupDone("queryInventory");
checkServiceConnected("queryInventory");
flagStartAsync("refresh inventory");
(new Thread(new Runnable() {
public void run() {
Expand Down Expand Up @@ -733,6 +737,7 @@ public void queryInventoryAsync(QueryInventoryFinishedListener listener)
void consume(Purchase itemInfo) throws IabException {
checkNotDisposed();
checkSetupDone("consume");
checkServiceConnected("consume");

if (!itemInfo.mItemType.equals(ITEM_TYPE_INAPP)) {
throw new IabException(IABHELPER_INVALID_CONSUMPTION,
Expand Down Expand Up @@ -802,6 +807,7 @@ public void consumeAsync(Purchase purchase, OnConsumeFinishedListener listener)
throws IabAsyncInProgressException {
checkNotDisposed();
checkSetupDone("consume");
checkServiceConnected("consume");
List<Purchase> purchases = new ArrayList<Purchase>();
purchases.add(purchase);
consumeAsyncInternal(purchases, listener, null);
Expand All @@ -816,6 +822,7 @@ public void consumeAsync(List<Purchase> purchases, OnConsumeMultiFinishedListene
throws IabAsyncInProgressException {
checkNotDisposed();
checkSetupDone("consume");
checkServiceConnected("consume");
consumeAsyncInternal(purchases, null, listener);
}

Expand Down Expand Up @@ -862,6 +869,15 @@ void checkSetupDone(String operation) {
}
}

// Checks that Billing service is connected; if not, throws an exception.
private void checkServiceConnected(String operation) {
if (mService == null) {
logError("IabHelper.mService is null. Service not connected: " + operation);
throw new IllegalStateException("Billing service is disconnected: " + operation);
}

}

// Workaround to bug where sometimes response codes come as Long instead of Integer
int getResponseCodeFromBundle(Bundle b) {
Object o = b.get(RESPONSE_CODE);
Expand Down Expand Up @@ -937,6 +953,7 @@ int queryPurchases(Inventory inv, String itemType) throws JSONException, RemoteE
// Query purchases
logDebug("Querying owned items, item type: " + itemType);
logDebug("Package name: " + mContext.getPackageName());
checkServiceConnected("queryPurchases");
boolean verificationFailed = false;
String continueToken = null;

Expand Down Expand Up @@ -970,7 +987,7 @@ int queryPurchases(Inventory inv, String itemType) throws JSONException, RemoteE
String signature = signatureList.get(i);
String sku = ownedSkus.get(i);
if(sku.equals("android.test.purchased")){
signature = "android.test.purchased";
signature = "android.test.purchased";
}
if (Security.verifyPurchase(mSignatureBase64, purchaseData, signature)) {
logDebug("Sku is owned: " + sku);
Expand All @@ -985,7 +1002,7 @@ int queryPurchases(Inventory inv, String itemType) throws JSONException, RemoteE
inv.addPurchase(purchase);
}
else {
if(!sku.equals("android.test.purchased")){
if(!sku.equals("android.test.purchased")){
logWarn("Purchase signature verification **FAILED**. Not adding item.");
logDebug(" Purchase data: " + purchaseData);
logDebug(" Signature: " + signature);
Expand All @@ -1004,6 +1021,7 @@ int queryPurchases(Inventory inv, String itemType) throws JSONException, RemoteE
int querySkuDetails(String itemType, Inventory inv, List<String> moreSkus)
throws RemoteException, JSONException {
logDebug("Querying SKU details.");
checkServiceConnected("querySkuDetails");
ArrayList<String> skuList = new ArrayList<String>();
skuList.addAll(inv.getAllOwnedSkus(itemType));
if (moreSkus != null) {
Expand Down

0 comments on commit cb37312

Please sign in to comment.