int queryPurchases(Inventory inv, String itemType) throws JSONException, RemoteException { // Query purchases logDebug("Querying owned items, item type: " + itemType); logDebug("Package name: " + mContext.getPackageName()); boolean verificationFailed = false; String continueToken = null; do { logDebug("Calling getPurchases with continuation token: " + continueToken); Bundle ownedItems = mService.getPurchases(3, mContext.getPackageName(), itemType, continueToken); int response = getResponseCodeFromBundle(ownedItems); logDebug("Owned items response: " + String.valueOf(response)); if (response != BILLING_RESPONSE_RESULT_OK) { logDebug("getPurchases() failed: " + getResponseDesc(response)); return response; } if (!ownedItems.containsKey(RESPONSE_INAPP_ITEM_LIST) || !ownedItems.containsKey(RESPONSE_INAPP_PURCHASE_DATA_LIST) || !ownedItems.containsKey(RESPONSE_INAPP_SIGNATURE_LIST)) { logError("Bundle returned from getPurchases() doesn't contain required fields."); return IABHELPER_BAD_RESPONSE; } ArrayList<String> ownedSkus = ownedItems.getStringArrayList(RESPONSE_INAPP_ITEM_LIST); ArrayList<String> purchaseDataList = ownedItems.getStringArrayList(RESPONSE_INAPP_PURCHASE_DATA_LIST); ArrayList<String> signatureList = ownedItems.getStringArrayList(RESPONSE_INAPP_SIGNATURE_LIST); for (int i = 0; i < purchaseDataList.size(); ++i) { String purchaseData = purchaseDataList.get(i); String signature = signatureList.get(i); String sku = ownedSkus.get(i); if (Security.verifyPurchase(mSignatureBase64, purchaseData, signature)) { logDebug("Sku is owned: " + sku); Purchase purchase = new Purchase(itemType, purchaseData, signature); if (TextUtils.isEmpty(purchase.getToken())) { logWarn("BUG: empty/null token!"); logDebug("Purchase data: " + purchaseData); } // Record ownership and token inv.addPurchase(purchase); } else { logWarn("Purchase signature verification **FAILED**. Not adding item."); logDebug(" Purchase data: " + purchaseData); logDebug(" Signature: " + signature); verificationFailed = true; } } continueToken = ownedItems.getString(INAPP_CONTINUATION_TOKEN); logDebug("Continuation token: " + continueToken); } while (!TextUtils.isEmpty(continueToken)); return verificationFailed ? IABHELPER_VERIFICATION_FAILED : BILLING_RESPONSE_RESULT_OK; }
@Test public void testGetPurchase() throws Exception { Inventory inventory = new Inventory(); Purchase p = mock(Purchase.class); when(p.getSku()).thenReturn("sku1"); inventory.addPurchase(p); assertThat(inventory.getPurchase("sku1")).isSameAs(p); }
@Test public void testGetAllOwnedSkus() throws Exception { Inventory inventory = new Inventory(); Purchase p1 = mock(Purchase.class); when(p1.getSku()).thenReturn("sku1"); Purchase p2 = mock(Purchase.class); when(p2.getSku()).thenReturn("sku2"); inventory.addPurchase(p1); inventory.addPurchase(p2); assertThat(inventory.getAllOwnedSkus()).containsOnly("sku1", "sku2"); }
@Test public void testGetAllOwnedSkusForItemType() throws Exception { Inventory inventory = new Inventory(); Purchase p1 = mock(Purchase.class); when(p1.getItemType()).thenReturn(ItemType.INAPP); when(p1.getSku()).thenReturn("sku_inapp"); Purchase p2 = mock(Purchase.class); when(p2.getItemType()).thenReturn(ItemType.SUBS); when(p2.getSku()).thenReturn("sku_sub"); inventory.addPurchase(p1); inventory.addPurchase(p2); assertThat(inventory.getAllOwnedSkus(ItemType.SUBS)).containsExactly("sku_sub"); }
int queryPurchases(Inventory inv) throws JSONException, RemoteException { boolean verificationFailed = false; String continueToken = null; do { Bundle ownedItems = connection.getPurchases(continueToken); int response = getResponseCodeFromBundle(ownedItems); if (response != BILLING_RESPONSE_RESULT_OK) { return response; } if (!ownedItems.containsKey(RESPONSE_INAPP_ITEM_LIST) || !ownedItems.containsKey(RESPONSE_INAPP_PURCHASE_DATA_LIST) || !ownedItems.containsKey(RESPONSE_INAPP_SIGNATURE_LIST)) { return HELPER_BAD_RESPONSE; } ArrayList<String> purchaseDataList = ownedItems.getStringArrayList(RESPONSE_INAPP_PURCHASE_DATA_LIST); ArrayList<String> signatureList = ownedItems.getStringArrayList(RESPONSE_INAPP_SIGNATURE_LIST); for (int i = 0; i < purchaseDataList.size(); ++i) { String purchaseData = purchaseDataList.get(i); String signature = signatureList.get(i); if (security.verifyPurchase(purchaseData, signature)) { Purchase purchase = new Purchase(purchaseData, signature); inv.addPurchase(purchase); } else { verificationFailed = true; } } continueToken = ownedItems.getString(INAPP_CONTINUATION_TOKEN); } while (!TextUtils.isEmpty(continueToken)); return verificationFailed ? HELPER_VERIFICATION_FAILED : BILLING_RESPONSE_RESULT_OK; }
@Test public void testAddPurchase() throws Exception { Inventory inventory = new Inventory(); inventory.addPurchase(mock(Purchase.class)); assertThat(inventory.getAllPurchases()).hasSize(1); }