CppCheckout

This commit is contained in:
serso 2016-02-06 11:17:29 +01:00
parent dbf4c14d42
commit 5d30d57d8f
8 changed files with 123 additions and 66 deletions

View File

@ -57,8 +57,6 @@ import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
/** /**
@ -81,8 +79,6 @@ public final class App {
return tag + "/" + subTag; return tag + "/" + subTag;
} }
@Nonnull
private static final Products products = Products.create().add(ProductTypes.IN_APP, Arrays.asList("ad_free"));
@Nonnull @Nonnull
private static Languages languages; private static Languages languages;
@Nonnull @Nonnull
@ -93,8 +89,6 @@ public final class App {
private static SharedPreferences preferences; private static SharedPreferences preferences;
@Nonnull @Nonnull
private static volatile Ga ga; private static volatile Ga ga;
@Nonnull
private static volatile Billing billing;
@Nullable @Nullable
private static Boolean lg = null; private static Boolean lg = null;
@Nullable @Nullable
@ -109,15 +103,6 @@ public final class App {
private static Bus bus; private static Bus bus;
@Nonnull @Nonnull
private static Display display; private static Display display;
@Nonnull
private static final Executor background = Executors.newFixedThreadPool(5, new ThreadFactory() {
@NonNull
private final AtomicInteger counter = new AtomicInteger();
@Override
public Thread newThread(@Nonnull Runnable r) {
return new Thread(r, "Background #" + counter.getAndIncrement());
}
});
private App() { private App() {
throw new AssertionError(); throw new AssertionError();
@ -129,23 +114,6 @@ public final class App {
App.preferences = PreferenceManager.getDefaultSharedPreferences(application); App.preferences = PreferenceManager.getDefaultSharedPreferences(application);
App.uiThreadExecutor = application.uiThread; App.uiThreadExecutor = application.uiThread;
App.ga = new Ga(application, preferences); App.ga = new Ga(application, preferences);
App.billing = new Billing(application, new Billing.DefaultConfiguration() {
@Nonnull
@Override
public String getPublicKey() {
return CalculatorSecurity.getPK();
}
@Nullable
@Override
public Inventory getFallbackInventory(@Nonnull Checkout checkout, @Nonnull Executor onLoadExecutor) {
if (RobotmediaDatabase.exists(billing.getContext())) {
return new RobotmediaInventory(checkout, onLoadExecutor);
} else {
return null;
}
}
});
App.screenMetrics = new ScreenMetrics(application); App.screenMetrics = new ScreenMetrics(application);
App.languages = languages; App.languages = languages;
App.languages.init(); App.languages.init();
@ -185,16 +153,6 @@ public final class App {
return ga; return ga;
} }
@Nonnull
public static Billing getBilling() {
return billing;
}
@Nonnull
public static Products getProducts() {
return products;
}
public static boolean isLargeScreen() { public static boolean isLargeScreen() {
return Views.isLayoutSizeAtLeast(Configuration.SCREENLAYOUT_SIZE_LARGE, App.getApplication().getResources().getConfiguration()); return Views.isLayoutSizeAtLeast(Configuration.SCREENLAYOUT_SIZE_LARGE, App.getApplication().getResources().getConfiguration());
} }

View File

@ -9,6 +9,8 @@ import org.solovyev.android.calculator.history.BaseHistoryFragment;
import org.solovyev.android.calculator.history.EditHistoryFragment; import org.solovyev.android.calculator.history.EditHistoryFragment;
import org.solovyev.android.calculator.onscreen.CalculatorOnscreenService; import org.solovyev.android.calculator.onscreen.CalculatorOnscreenService;
import org.solovyev.android.calculator.operators.OperatorsFragment; import org.solovyev.android.calculator.operators.OperatorsFragment;
import org.solovyev.android.calculator.preferences.PreferencesActivity;
import org.solovyev.android.calculator.preferences.PurchaseDialogActivity;
import org.solovyev.android.calculator.variables.EditVariableFragment; import org.solovyev.android.calculator.variables.EditVariableFragment;
import org.solovyev.android.calculator.variables.VariablesFragment; import org.solovyev.android.calculator.variables.VariablesFragment;
@ -20,6 +22,7 @@ public interface AppComponent {
void inject(CalculatorApplication application); void inject(CalculatorApplication application);
void inject(EditorFragment fragment); void inject(EditorFragment fragment);
void inject(BaseUi ui); void inject(BaseUi ui);
void inject(FragmentUi ui);
void inject(CalculatorOnscreenService service); void inject(CalculatorOnscreenService service);
void inject(BaseHistoryFragment fragment); void inject(BaseHistoryFragment fragment);
void inject(BaseDialogFragment fragment); void inject(BaseDialogFragment fragment);
@ -35,4 +38,6 @@ public interface AppComponent {
void inject(CalculatorReceiver receiver); void inject(CalculatorReceiver receiver);
void inject(DisplayFragment fragment); void inject(DisplayFragment fragment);
void inject(KeyboardFragment fragment); void inject(KeyboardFragment fragment);
void inject(PurchaseDialogActivity activity);
void inject(PreferencesActivity activity);
} }

View File

@ -12,10 +12,13 @@ import dagger.Module;
import dagger.Provides; import dagger.Provides;
import jscl.JsclMathEngine; import jscl.JsclMathEngine;
import org.solovyev.android.UiThreadExecutor; import org.solovyev.android.UiThreadExecutor;
import org.solovyev.android.checkout.*;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.inject.Named; import javax.inject.Named;
import javax.inject.Singleton; import javax.inject.Singleton;
import java.util.Collections;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory; import java.util.concurrent.ThreadFactory;
@ -108,6 +111,34 @@ public class AppModule {
return JsclMathEngine.getInstance(); return JsclMathEngine.getInstance();
} }
@Provides
@Singleton
Billing provideBilling() {
return new Billing(application, new Billing.DefaultConfiguration() {
@Nonnull
@Override
public String getPublicKey() {
return CalculatorSecurity.getPK();
}
@Nullable
@Override
public Inventory getFallbackInventory(@Nonnull Checkout checkout, @Nonnull Executor onLoadExecutor) {
if (RobotmediaDatabase.exists(application)) {
return new RobotmediaInventory(checkout, onLoadExecutor);
} else {
return null;
}
}
});
}
@Singleton
@Provides
Products provideProducts() {
return Products.create().add(ProductTypes.IN_APP, Collections.singletonList("ad_free"));
}
private static class AppBus extends Bus { private static class AppBus extends Bus {
@NonNull @NonNull

View File

@ -133,7 +133,7 @@ public abstract class BaseUi implements SharedPreferences.OnSharedPreferenceChan
ActivityLauncher launcher; ActivityLauncher launcher;
protected void onCreate(@Nonnull Activity activity) { protected void onCreate(@Nonnull Activity activity) {
cast(activity.getApplication()).getComponent().inject(this); inject(cast(activity.getApplication()).getComponent());
layout = Preferences.Gui.layout.getPreferenceNoError(preferences); layout = Preferences.Gui.layout.getPreferenceNoError(preferences);
theme = Preferences.Gui.theme.getPreferenceNoError(preferences); theme = Preferences.Gui.theme.getPreferenceNoError(preferences);
@ -148,6 +148,10 @@ public abstract class BaseUi implements SharedPreferences.OnSharedPreferenceChan
} }
} }
protected void inject(@Nonnull AppComponent component) {
component.inject(this);
}
@Nonnull @Nonnull
public Preferences.Gui.Theme getTheme() { public Preferences.Gui.Theme getTheme() {
return theme; return theme;

View File

@ -28,19 +28,17 @@ import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.TextView; import android.widget.TextView;
import org.solovyev.android.checkout.ActivityCheckout; import org.solovyev.android.checkout.CppCheckout;
import org.solovyev.android.checkout.Checkout;
import org.solovyev.android.checkout.Inventory; import org.solovyev.android.checkout.Inventory;
import org.solovyev.android.checkout.ProductTypes; import org.solovyev.android.checkout.ProductTypes;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import javax.inject.Inject;
import java.util.Locale; import java.util.Locale;
public class FragmentUi extends BaseUi { public class FragmentUi extends BaseUi {
private ActivityCheckout checkout;
@Nullable @Nullable
private AdView adView; private AdView adView;
@ -53,6 +51,9 @@ public class FragmentUi extends BaseUi {
@Nullable @Nullable
private Boolean adFree = null; private Boolean adFree = null;
@Inject
CppCheckout checkout;
public FragmentUi(int layoutId) { public FragmentUi(int layoutId) {
this.layoutId = layoutId; this.layoutId = layoutId;
} }
@ -86,7 +87,6 @@ public class FragmentUi extends BaseUi {
public void onCreate(@Nonnull Fragment fragment) { public void onCreate(@Nonnull Fragment fragment) {
final FragmentActivity activity = fragment.getActivity(); final FragmentActivity activity = fragment.getActivity();
super.onCreate(activity); super.onCreate(activity);
checkout = Checkout.forActivity(activity, App.getBilling(), App.getProducts());
if (listenersOnCreate) { if (listenersOnCreate) {
if (fragment instanceof CalculatorEventListener) { if (fragment instanceof CalculatorEventListener) {
@ -97,6 +97,12 @@ public class FragmentUi extends BaseUi {
checkout.start(); checkout.start();
} }
@Override
protected void inject(@Nonnull AppComponent component) {
super.inject(component);
component.inject(this);
}
public void onResume(@Nonnull Fragment fragment) { public void onResume(@Nonnull Fragment fragment) {
if (adView != null) { if (adView != null) {
adView.resume(); adView.resume();

View File

@ -7,16 +7,14 @@ import android.os.Bundle;
import android.support.annotation.StringRes; import android.support.annotation.StringRes;
import android.support.annotation.XmlRes; import android.support.annotation.XmlRes;
import android.util.SparseArray; import android.util.SparseArray;
import org.solovyev.android.calculator.*;
import org.solovyev.android.calculator.ActivityUi;
import org.solovyev.android.calculator.App;
import org.solovyev.android.calculator.BaseActivity;
import org.solovyev.android.calculator.Preferences;
import org.solovyev.android.calculator.R;
import org.solovyev.android.checkout.ActivityCheckout; import org.solovyev.android.checkout.ActivityCheckout;
import org.solovyev.android.checkout.Billing;
import org.solovyev.android.checkout.Checkout; import org.solovyev.android.checkout.Checkout;
import org.solovyev.android.checkout.Products;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.inject.Inject;
import static android.support.v7.app.ActionBar.NAVIGATION_MODE_STANDARD; import static android.support.v7.app.ActionBar.NAVIGATION_MODE_STANDARD;
@ -38,10 +36,14 @@ public class PreferencesActivity extends BaseActivity implements SharedPreferenc
preferences.append(R.xml.preferences_widget, new PrefDef("screen-widget", R.string.prefs_widget_title)); preferences.append(R.xml.preferences_widget, new PrefDef("screen-widget", R.string.prefs_widget_title));
} }
@Nonnull ActivityCheckout checkout;
private final ActivityCheckout checkout = Checkout.forActivity(this, App.getBilling(), App.getProducts());
private boolean paused = true; private boolean paused = true;
@Inject
Billing billing;
@Inject
Products products;
public PreferencesActivity() { public PreferencesActivity() {
super(R.layout.main_empty); super(R.layout.main_empty);
} }
@ -90,9 +92,16 @@ public class PreferencesActivity extends BaseActivity implements SharedPreferenc
getSupportActionBar().setNavigationMode(NAVIGATION_MODE_STANDARD); getSupportActionBar().setNavigationMode(NAVIGATION_MODE_STANDARD);
checkout = Checkout.forActivity(this, billing, products);
checkout.start(); checkout.start();
} }
@Override
protected void inject(@Nonnull AppComponent component) {
super.inject(component);
component.inject(this);
}
@Override @Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
if (!paused) { if (!paused) {

View File

@ -30,28 +30,20 @@ import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.TextView; import android.widget.TextView;
import butterknife.Bind; import butterknife.Bind;
import butterknife.ButterKnife; import butterknife.ButterKnife;
import org.solovyev.android.calculator.*; import org.solovyev.android.calculator.*;
import org.solovyev.android.checkout.ActivityCheckout; import org.solovyev.android.checkout.*;
import org.solovyev.android.checkout.BillingRequests;
import org.solovyev.android.checkout.Checkout;
import org.solovyev.android.checkout.ProductTypes;
import org.solovyev.android.checkout.Purchase;
import org.solovyev.android.checkout.RequestListener;
import org.solovyev.android.fragments.FragmentUtils; import org.solovyev.android.fragments.FragmentUtils;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import javax.inject.Inject;
import static org.solovyev.android.calculator.FragmentTab.purchase_dialog; import static org.solovyev.android.calculator.FragmentTab.purchase_dialog;
public class PurchaseDialogActivity extends BaseActivity { public class PurchaseDialogActivity extends BaseActivity {
@Nonnull
private final ActivityCheckout checkout = Checkout.forActivity(this, App.getBilling(), App.getProducts());
@Nonnull @Nonnull
private final RequestListener<Purchase> purchaseListener = new RequestListener<Purchase>() { private final RequestListener<Purchase> purchaseListener = new RequestListener<Purchase>() {
@Override @Override
@ -65,6 +57,12 @@ public class PurchaseDialogActivity extends BaseActivity {
} }
}; };
@Inject
Billing billing;
@Inject
Products products;
ActivityCheckout checkout;
public PurchaseDialogActivity() { public PurchaseDialogActivity() {
super(R.layout.cpp_dialog); super(R.layout.cpp_dialog);
} }
@ -75,10 +73,17 @@ public class PurchaseDialogActivity extends BaseActivity {
FragmentUtils.createFragment(this, PurchaseDialogFragment.class, R.id.dialog_layout, "purchase-dialog"); FragmentUtils.createFragment(this, PurchaseDialogFragment.class, R.id.dialog_layout, "purchase-dialog");
checkout = Checkout.forActivity(this, billing, products);
checkout.start(); checkout.start();
checkout.createPurchaseFlow(purchaseListener); checkout.createPurchaseFlow(purchaseListener);
} }
@Override
protected void inject(@Nonnull AppComponent component) {
super.inject(component);
component.inject(this);
}
@Override @Override
protected void onStart() { protected void onStart() {
super.onStart(); super.onStart();

View File

@ -0,0 +1,39 @@
package org.solovyev.android.checkout;
import android.support.annotation.NonNull;
import javax.inject.Inject;
import javax.inject.Singleton;
/**
* App-wide {@link Checkout} which counts how many times it has been started.
*/
@Singleton
public class CppCheckout extends Checkout {
private int started = 0;
@Inject
public CppCheckout(@NonNull Billing billing, @NonNull Products products) {
super(null, billing, products);
}
@Override
public void stop() {
Check.isMainThread();
Check.isTrue(started > 0, "Must be started first");
started--;
if (started == 0) {
super.stop();
}
started = Math.max(0, started);
}
@Override
public void start(Listener listener) {
Check.isMainThread();
started++;
if (started == 1) {
super.start(listener);
}
}
}