@Nonnull private Inventory.Products loadProducts(@Nonnull Inventory.Request request, @Nonnull SQLiteDatabase db) { final Inventory.Products result = new Inventory.Products(); for (String productId : ProductTypes.ALL) { final Inventory.Product product = new Inventory.Product(productId, true); final List<String> skus = request.getSkus(productId); if (!skus.isEmpty()) { product.setPurchases(loadPurchases(skus, db)); } else { Billing.warning("There are no SKUs for \"" + product.id + "\" product. No purchase information will be loaded"); } result.add(product); } return result; }
@Override public void onLoaded(@Nonnull Inventory.Products products) { mLoaded = true; // update the list final Inventory.Product product = products.get(SUBSCRIPTION); mSkus.clear(); for (Purchase purchase : product.getPurchases()) { if (purchase.state != Purchase.State.PURCHASED) { continue; } final Sku sku = product.getSku(purchase.sku); if (sku != null) { mSkus.add(sku); } } // keep checked status if possible & do initial restore if needed final boolean checkedChanged = updateCheckedSkus(); notifyDataSetChanged(); if (checkedChanged) { mListener.onCheckedChanged(); } }
public void onDone(@Nonnull Products products) { synchronized (mLock) { mProducts.merge(products); onDone(); } }
@Test public void testShouldLoadPurchases() throws Exception { populatePurchases(); populateSkus(); final TestCallback listener = new TestCallback(); mCheckout.start(); mInventory.load(mRequest, listener); Tests.waitWhileLoading(mInventory); final boolean complete = shouldVerifyPurchaseCompletely(); final Inventory.Product inApp = listener.mProducts.get(IN_APP); final List<Purchase> actualInApps = inApp.getPurchases(); assertEquals(4, actualInApps.size()); verifyPurchase(actualInApps.get(0), 4, EXPIRED, complete, false); verifyPurchase(actualInApps.get(1), 3, REFUNDED, complete, false); verifyPurchase(actualInApps.get(2), 2, CANCELLED, complete, false); verifyPurchase(actualInApps.get(3), 1, PURCHASED, complete, false); final Inventory.Product sub = listener.mProducts.get(SUBSCRIPTION); final List<Purchase> actualSubs = sub.getPurchases(); assertEquals(4, actualSubs.size()); verifyPurchase(actualSubs.get(0), 4, EXPIRED, complete, true); verifyPurchase(actualSubs.get(1), 3, REFUNDED, complete, true); verifyPurchase(actualSubs.get(2), 2, CANCELLED, complete, true); verifyPurchase(actualSubs.get(3), 1, PURCHASED, complete, true); }
@Test public void testShouldLoadPurchasesWhenProductsBecameSupported() throws Exception { when(mService.isBillingSupported(eq(3), anyString(), eq(IN_APP))).thenReturn(BILLING_UNAVAILABLE); when(mService.isBillingSupported(eq(3), anyString(), eq(SUBSCRIPTION))).thenReturn(BILLING_UNAVAILABLE); when(mService.getPurchases(anyInt(), anyString(), anyString(), isNull(String.class))).thenReturn(newPurchasesBundle(0, false)); mCheckout.start(); final AwaitingCallback c1 = new AwaitingCallback(); mCheckout.loadInventory(Inventory.Request.create().loadAllPurchases(), c1); c1.waitWhileLoading(); assertFalse(c1.mProducts.get(IN_APP).supported); assertFalse(c1.mProducts.get(SUBSCRIPTION).supported); assertTrue(c1.mProducts.get(IN_APP).getPurchases().isEmpty()); when(mService.isBillingSupported(eq(3), anyString(), eq(IN_APP))).thenReturn(OK); when(mService.isBillingSupported(eq(3), anyString(), eq(SUBSCRIPTION))).thenReturn(OK); final AwaitingCallback c2 = new AwaitingCallback(); mCheckout.loadInventory(Inventory.Request.create().loadAllPurchases(), c2); c2.waitWhileLoading(); assertTrue(c2.mProducts.get(IN_APP).supported); assertTrue(c2.mProducts.get(SUBSCRIPTION).supported); assertTrue(c2.mProducts.get(IN_APP).getPurchases().size() == 1); }
@Test public void testShouldReadTransactions() throws Exception { mDb.insert(newTransaction(0)); mDb.insert(newTransaction(1)); mDb.insert(newTransaction(2)); mDb.insert(newTransaction(3)); mDb.insert(newTransaction(4)); mDb.insert(newTransaction(5)); final RobotmediaInventory inventory = new RobotmediaInventory(mCheckout, sameThreadExecutor(), sameThreadExecutor()); final CountDownCallback l = new CountDownCallback(); inventory.load(mRequest, l); final Inventory.Products products = l.waitProducts(); final Inventory.Product product = products.get(IN_APP); assertTrue(product.supported); final List<Purchase> purchases = product.getPurchases(); assertEquals(5, purchases.size()); verifyPurchase(purchases, 0); verifyPurchase(purchases, 1); verifyPurchase(purchases, 2); verifyPurchase(purchases, 3); verifyPurchase(purchases, 4); }
@Test public void testIsLoadedWithEmptySkusList() throws Exception { populatePurchases(); populateSkus(); final Inventory.Request request = Inventory.Request.create() .loadAllPurchases() .loadSkus(IN_APP, "in_app_01") .loadSkus(SUBSCRIPTION, "sub_01"); final Checkout checkout = Checkout.forApplication(mBilling); final CheckoutInventory inventory = new CheckoutInventory(checkout); final TestCallback listener = new TestCallback(); checkout.start(); inventory.load(request, listener); Tests.waitWhileLoading(inventory); final Inventory.Product app = listener.mProducts.get(IN_APP); Assert.assertTrue(app.getSkus().isEmpty()); Assert.assertFalse(app.getPurchases().isEmpty()); final Inventory.Product sub = listener.mProducts.get(SUBSCRIPTION); Assert.assertTrue(sub.getSkus().isEmpty()); Assert.assertFalse(sub.getPurchases().isEmpty()); }
@Override public void onReady(@Nonnull BillingRequests requests, @Nonnull String productId, boolean billingSupported) { final Product product = new Product(productId, billingSupported); synchronized (mLock) { countDown(); mProducts.add(product); if (!mTask.isCancelled() && product.supported && mTask.getRequest().shouldLoadPurchases(productId)) { loadPurchases(requests, product); } else { countDown(1); } if (!mTask.isCancelled() && product.supported && mTask.getRequest().shouldLoadSkus(productId)) { loadSkus(requests, product); } else { countDown(1); } } }
@Override public void onLoaded(@Nonnull Inventory.Products products) { final Inventory.Product product = products.get(ProductTypes.IN_APP); if (!product.supported) { // billing is not supported, user can't purchase anything. Don't show ads in this // case return; } if (product.isPurchased(AD_FREE)) { return; } showAd(); } }
@Before public void setUp() throws Exception { mProducts = new Inventory.Products(); }
@Override public void onLoaded(@Nonnull Inventory.Products products) { final Inventory.Product product = products.get(SUBSCRIPTION); setNotifyOnChange(false); clear(); for (Sku sku : product.getSkus()) { if (!product.isPurchased(sku)) { add(new SkuItem(sku)); } } notifyDataSetChanged(); } }
@Override public void onLoaded(@Nonnull Inventory.Products products) { final Inventory.Product product = products.get(SUBSCRIPTION); setNotifyOnChange(false); clear(); for (Sku sku : product.getSkus()) { if (!product.isPurchased(sku)) { add(new SkuItem(sku)); } } notifyDataSetChanged(); } }
@Test public void testShouldReadEmptyList() throws Exception { final RobotmediaInventory inventory = new RobotmediaInventory(mCheckout, sameThreadExecutor(), sameThreadExecutor()); final CountDownCallback l = new CountDownCallback(); inventory.load(mRequest, l); final Inventory.Products products = l.waitProducts(); final Inventory.Product product = products.get(IN_APP); assertTrue(product.supported); final List<Purchase> purchases = product.getPurchases(); assertEquals(0, purchases.size()); }
@Test public void testShouldLoadSkus() throws Exception { populateSkus(); mCheckout.start(); final TestCallback c1 = new TestCallback(); mInventory.load(Inventory.Request.create().loadSkus(SUBSCRIPTION, asList("subX", "sub2", "sub3")), c1); final TestCallback c2 = new TestCallback(); mInventory.load(Inventory.Request.create().loadSkus(IN_APP, asList("1", "2", "5")), c2); Tests.waitWhileLoading(mInventory); assertEquals(0, c1.mProducts.get(SUBSCRIPTION).getSkus().size()); assertEquals(2, c2.mProducts.get(IN_APP).getSkus().size()); }
@Test public void testShouldCreateEmptyProductsIfError() throws Exception { mDb.close(); RuntimeEnvironment.application.deleteDatabase(RobotmediaDatabase.NAME); final RobotmediaInventory inventory = new RobotmediaInventory(mCheckout, sameThreadExecutor(), sameThreadExecutor()); final CountDownCallback l = new CountDownCallback(); inventory.load(mRequest, l); final Inventory.Products products = l.waitProducts(); final Inventory.Product product = products.get(IN_APP); assertNotNull(product); assertTrue(product.getPurchases().isEmpty()); }
@Test public void testShouldLoadSkus() throws Exception { populateSkus(); mCheckout.start(); final TestCallback c1 = new TestCallback(); mInventory.load(Inventory.Request.create().loadSkus(SUBSCRIPTION, asList("subX", "sub2", "sub3")), c1); final TestCallback c2 = new TestCallback(); mInventory.load(Inventory.Request.create().loadSkus(IN_APP, asList("1", "2", "5")), c2); Tests.waitWhileLoading(mInventory); assertEquals(2, c1.mProducts.get(SUBSCRIPTION).getSkus().size()); assertEquals(2, c2.mProducts.get(IN_APP).getSkus().size()); }
public boolean onMaybeDone(@Nonnull Products products) { synchronized (mLock) { mProducts.merge(products); if (!existsUnsupported()) { onDone(); return true; } return false; } }
@Nonnull static Inventory.Products toInventoryProducts(@Nonnull Collection<String> products) { final Inventory.Products result = new Inventory.Products(); for (String productId : products) { result.add(new Inventory.Product(productId, true)); } return result; }
@Test public void testShouldAddProduct() throws Exception { mProducts.add(new Inventory.Product(ProductTypes.IN_APP, true)); mProducts.add(new Inventory.Product(ProductTypes.SUBSCRIPTION, true)); assertEquals(2, mProducts.size()); assertEquals(ProductTypes.IN_APP, mProducts.get(ProductTypes.IN_APP).id); assertEquals(ProductTypes.SUBSCRIPTION, mProducts.get(ProductTypes.SUBSCRIPTION).id); }
@Override public void onLoaded(@Nonnull Inventory.Products products) { final Inventory.Product product = products.get(ProductTypes.IN_APP); if (!product.supported) { return; } mPurchase = product.getPurchaseInState(AD_FREE, Purchase.State.PURCHASED); onPurchaseChanged(); mBuyConsume.setEnabled(true); } }