@Override public void cancel() { Billing.cancel(mListener); } }
void onCheckoutStopped() { Check.isMainThread(); synchronized (mLock) { mCheckoutCount--; if (mCheckoutCount < 0) { mCheckoutCount = 0; warning("Billing#onCheckoutStopped is called more than Billing#onCheckoutStarted"); } if (mCheckoutCount == 0 && mConfiguration.isAutoConnect()) { disconnect(); } } }
@Nullable @Override public Cache getCache() { return newCache(); }
@Nonnull @Override public PurchaseVerifier getPurchaseVerifier() { Billing.warning("Default purchase verification procedure is used, please read https://github.com/serso/android-checkout#purchase-verification"); return newPurchaseVerifier(getPublicKey()); }
@Test public void testStates() throws Exception { final Billing.ServiceConnector connector = mock(Billing.ServiceConnector.class); when(connector.connect()).thenReturn(true); mBilling.setConnector(connector); mBilling.connect(); assertEquals(Billing.State.CONNECTING, mBilling.getState()); mBilling.setService(mock(IInAppBillingService.class), true); assertEquals(Billing.State.CONNECTED, mBilling.getState()); mBilling.disconnect(); assertEquals(Billing.State.DISCONNECTING, mBilling.getState()); mBilling.setService(null, false); assertEquals(Billing.State.DISCONNECTED, mBilling.getState()); }
@Test public void testShouldConnectOnlyIfConnecting() throws Exception { mBilling.setState(Billing.State.CONNECTING); mBilling.setState(Billing.State.FAILED); mBilling.setService(mock(IInAppBillingService.class), true); assertEquals(Billing.State.FAILED, mBilling.getState()); mBilling.setState(Billing.State.CONNECTING); mBilling.setService(mock(IInAppBillingService.class), true); assertEquals(Billing.State.CONNECTED, mBilling.getState()); }
@Test public void testShouldDisconnectServiceIfBillingIsInactive() throws Exception { final Billing.ServiceConnector connector = mock(Billing.ServiceConnector.class); mBilling.setConnector(connector); mBilling.setState(Billing.State.CONNECTING); mBilling.setState(Billing.State.DISCONNECTED); mBilling.setService(mock(IInAppBillingService.class), true); assertEquals(Billing.State.DISCONNECTED, mBilling.getState()); verify(connector, times(1)).disconnect(); }
private int runWhenConnected(@Nonnull Request request, @Nullable Object tag) { return runWhenConnected(request, null, tag); }
@Test public void testShouldRunAllRequests() throws Exception { final int REQUESTS = 100; final int SLEEP = 10; final Billing b = Tests.newBilling(false); b.setMainThread(Tests.sameThreadExecutor()); final AsyncServiceConnector c = new AsyncServiceConnector(b); b.setConnector(c); final CountDownLatch latch = new CountDownLatch(REQUESTS); final RequestListener l = new CountDownListener(latch); for (int i = 0; i < REQUESTS; i++) { if (i % 10 == 0) { if (mRandom.nextBoolean()) { b.connect(); } else { // connector is called directly in order to avoid cancelling the pending // requests c.disconnect(); } } b.runWhenConnected(new SleepingRequest(mRandom.nextInt(SLEEP)), l, null); } b.connect(); assertTrue(latch.await(SLEEP * REQUESTS, TimeUnit.MILLISECONDS)); }
@Test public void testShouldGoToDisconnectedStateFromConnectingIfBillingDies() throws Exception { mBilling.setState(Billing.State.CONNECTING); mBilling.disconnect(); assertEquals(Billing.State.DISCONNECTED, mBilling.getState()); }
@Test public void testShouldAutoDisconnect() throws Exception { final Billing billing = Tests.newBilling(true, true); assertTrue(billing.getState() == Billing.State.INITIAL); billing.onCheckoutStarted(); assertTrue(billing.getState() == Billing.State.CONNECTED); billing.onCheckoutStarted(); assertTrue(billing.getState() == Billing.State.CONNECTED); billing.onCheckoutStopped(); assertTrue(billing.getState() == Billing.State.CONNECTED); billing.onCheckoutStopped(); assertTrue(billing.getState() == Billing.State.DISCONNECTED); }
@Override public void onServiceDisconnected(ComponentName name) { setService(null, false); }
@Test public void testShouldNotifyErrorIfCantConnect() throws Exception { final Billing.ServiceConnector connector = mock(Billing.ServiceConnector.class); when(connector.connect()).thenReturn(false); mBilling.setConnector(connector); final RequestListener<Object> l = mock(RequestListener.class); mBilling.getRequests().isBillingSupported("p", l); verify(l, times(1)).onError(eq(ResponseCodes.SERVICE_NOT_CONNECTED), any(BillingException.class)); verify(l, times(0)).onSuccess(any()); }
static void setService(@Nonnull final Billing billing, @Nonnull final IInAppBillingService service) { if (billing.getState() != Billing.State.INITIAL) { billing.disconnect(); } billing.setConnector(new TestServiceConnector(billing, service)); }
/** * Starts this {@link Checkout} and sends an initial request that checks whether billing is * supported for each product available in the Billing API. * * @param listener initial request listener */ public void start(@Nullable final Listener listener) { Check.isMainThread(); synchronized (mLock) { Check.isFalse(mState == State.STARTED, "Already started"); Check.isNull(mRequests, "Already started"); mState = State.STARTED; mBilling.onCheckoutStarted(); mRequests = mBilling.getRequests(mTag); } whenReady(listener == null ? new EmptyListener() {} : listener); }
@Test public void testShouldCancelRequests() throws Exception { final int REQUESTS = 10; final Billing b = Tests.newBilling(false); final CountDownLatch latch = new CountDownLatch(REQUESTS / 2); final RequestListener l = new CountDownListener(latch); final List<Integer> requestIds = new ArrayList<Integer>(); for (int i = 0; i < REQUESTS; i++) { requestIds.add(b.runWhenConnected(new SleepingRequest(100), l, null)); } Thread.sleep(100 * (REQUESTS / 2 - 1)); for (int i = REQUESTS / 2; i < REQUESTS; i++) { b.cancel(requestIds.get(i)); } assertTrue(latch.await(1, SECONDS)); }
/** * A factory method of {@link BillingRequests}. The constructed object is marked with the given * <var>tag</var>. All methods of {@link RequestListener} used in this {@link BillingRequests} * are called on the main application thread. * * @param tag requests marker * @return requests for the given <var>tag</var> */ @Nonnull public Requests getRequests(@Nullable Object tag) { if (tag == null) { return (Requests) getRequests(); } return (Requests) new RequestsBuilder().withTag(tag).onMainThread().create(); }
<R> int runWhenConnected(@Nonnull Request<R> request, @Nullable RequestListener<R> listener, @Nullable Object tag) { if (listener != null) { if (mCache.hasCache()) { listener = new CachingRequestListener<>(request, listener); } request.setListener(listener); } if (tag != null) { request.setTag(tag); } mPendingRequests.add(onConnectedService(request)); connect(); return request.getId(); }
@Before public void setUp() throws Exception { Billing billing = newBilling(); billing.connect(); mService = ((TestServiceConnector) billing.getConnector()).mService; when(mService.isBillingSupported(eq(3), anyString(), eq(IN_APP))).thenReturn(OK); when(mService.isBillingSupported(eq(3), anyString(), eq(SUBSCRIPTION))).thenReturn(OK); mCheckout = Checkout.forApplication(billing); }
public void onCheckoutStarted() { Check.isMainThread(); synchronized (mLock) { mCheckoutCount++; if (mCheckoutCount > 0 && mConfiguration.isAutoConnect()) { connect(); } } }