diff --git a/android/src/com/mapswithme/maps/MwmActivity.java b/android/src/com/mapswithme/maps/MwmActivity.java index 6d9a0dae34..af9262445e 100644 --- a/android/src/com/mapswithme/maps/MwmActivity.java +++ b/android/src/com/mapswithme/maps/MwmActivity.java @@ -72,8 +72,9 @@ import com.mapswithme.maps.maplayer.subway.SubwayManager; import com.mapswithme.maps.maplayer.traffic.OnTrafficLayerToggleListener; import com.mapswithme.maps.maplayer.traffic.TrafficManager; import com.mapswithme.maps.maplayer.traffic.widget.TrafficButton; -import com.mapswithme.maps.purchase.BillingFactory; -import com.mapswithme.maps.purchase.BillingManager; +import com.mapswithme.maps.purchase.PurchaseFactory; +import com.mapswithme.maps.purchase.PurchaseController; +import com.mapswithme.maps.purchase.PurchaseControllerProvider; import com.mapswithme.maps.routing.NavigationController; import com.mapswithme.maps.routing.RoutePointInfo; import com.mapswithme.maps.routing.RoutingBottomMenuListener; @@ -146,7 +147,8 @@ public class MwmActivity extends BaseMwmFragmentActivity FloatingSearchToolbarController.SearchToolbarListener, OnTrafficLayerToggleListener, OnSubwayLayerToggleListener, - BookmarkManager.BookmarksCatalogListener + BookmarkManager.BookmarksCatalogListener, + PurchaseControllerProvider { private static final Logger LOGGER = LoggerFactory.INSTANCE.getLogger(LoggerFactory.Type.MISC); private static final String TAG = MwmActivity.class.getSimpleName(); @@ -232,7 +234,7 @@ public class MwmActivity extends BaseMwmFragmentActivity private PlacePageTracker mPlacePageTracker; @SuppressWarnings("NullableProblems") @NonNull - private BillingManager mBillingManager; + private PurchaseController mPurchaseController; @NonNull private final OnClickListener mOnMyPositionClickListener = new CurrentPositionClickListener(); @@ -551,7 +553,7 @@ public class MwmActivity extends BaseMwmFragmentActivity SharingHelper.INSTANCE.initialize(); - mBillingManager = BillingFactory.ADS_REMOVAL.createBillingManager(this, "android.test.purchased"); + mPurchaseController = PurchaseFactory.ADS_REMOVAL.createPurchaseController(this, "ads.removal.monthly.test"); //TODO: uncomment after correct visible rect calculation. //mVisibleRectMeasurer = new VisibleRectMeasurer(new VisibleRectListener() { @@ -1346,7 +1348,6 @@ public class MwmActivity extends BaseMwmFragmentActivity protected void onStart() { super.onStart(); - mBillingManager.initialize(); SearchEngine.INSTANCE.addListener(this); Framework.nativeSetMapObjectListener(this); BookmarkManager.INSTANCE.addLoadingListener(this); @@ -1358,13 +1359,13 @@ public class MwmActivity extends BaseMwmFragmentActivity if (mNavigationController != null) TrafficManager.INSTANCE.attach(mNavigationController); mPlacePage.onActivityStarted(); + mPurchaseController.start(this); } @Override protected void onStop() { super.onStop(); - mBillingManager.destroy(); SearchEngine.INSTANCE.removeListener(this); Framework.nativeRemoveMapObjectListener(); BookmarkManager.INSTANCE.removeLoadingListener(this); @@ -1374,6 +1375,7 @@ public class MwmActivity extends BaseMwmFragmentActivity TrafficManager.INSTANCE.detachAll(); mToggleMapLayerController.detachCore(); mPlacePage.onActivityStopped(); + mPurchaseController.stop(); } @Override @@ -1877,6 +1879,13 @@ public class MwmActivity extends BaseMwmFragmentActivity }); } + @NonNull + @Override + public PurchaseController getPurchaseController() + { + return mPurchaseController; + } + private void adjustMenuLineFrameVisibility(@Nullable final Runnable completion) { final RoutingController controller = RoutingController.get(); diff --git a/android/src/com/mapswithme/maps/MwmApplication.java b/android/src/com/mapswithme/maps/MwmApplication.java index 0a041a6149..7555e746f9 100644 --- a/android/src/com/mapswithme/maps/MwmApplication.java +++ b/android/src/com/mapswithme/maps/MwmApplication.java @@ -27,8 +27,6 @@ import com.mapswithme.maps.location.LocationHelper; import com.mapswithme.maps.location.TrackRecorder; import com.mapswithme.maps.maplayer.subway.SubwayManager; import com.mapswithme.maps.maplayer.traffic.TrafficManager; -import com.mapswithme.maps.purchase.BillingFactory; -import com.mapswithme.maps.purchase.PurchaseValidator; import com.mapswithme.maps.routing.RoutingController; import com.mapswithme.maps.scheduling.ConnectivityJobScheduler; import com.mapswithme.maps.scheduling.ConnectivityListener; @@ -76,8 +74,6 @@ public class MwmApplication extends Application @SuppressWarnings("NullableProblems") @NonNull private PushwooshHelper mPushwooshHelper; - @NonNull - private final PurchaseValidator mPurchaseValidator = BillingFactory.ADS_REMOVAL.createPurchaseManager(); private boolean mFrameworkInitialized; private boolean mPlatformInitialized; @@ -285,7 +281,6 @@ public class MwmApplication extends Application RoutingController.get().initialize(); TrafficManager.INSTANCE.initialize(); SubwayManager.from(this).initialize(); - mPurchaseValidator.initialize(); mFrameworkInitialized = true; } @@ -425,12 +420,6 @@ public class MwmApplication extends Application MyTracker.initTracker(); } - @NonNull - public PurchaseValidator getPurchaseValidator() - { - return mPurchaseValidator; - } - public static void onUpgrade() { Counters.resetAppSessionCounters(); diff --git a/android/src/com/mapswithme/maps/purchase/AbstractPurchaseController.java b/android/src/com/mapswithme/maps/purchase/AbstractPurchaseController.java new file mode 100644 index 0000000000..c38a605a2d --- /dev/null +++ b/android/src/com/mapswithme/maps/purchase/AbstractPurchaseController.java @@ -0,0 +1,69 @@ +package com.mapswithme.maps.purchase; + +import android.app.Activity; +import android.support.annotation.NonNull; + +abstract class AbstractPurchaseController implements PurchaseController +{ + @NonNull + private final PurchaseValidator mValidator; + @NonNull + private final BillingManager mBillingManager; + + AbstractPurchaseController(@NonNull PurchaseValidator validator, + @NonNull BillingManager billingManager) + { + mValidator = validator; + mBillingManager = billingManager; + } + + @Override + public final void start(@NonNull Activity activity) + { + mValidator.initialize(); + mBillingManager.initialize(activity); + onStart(activity); + } + + @Override + public final void stop() + { + mValidator.destroy(); + mBillingManager.destroy(); + onStop(); + } + + @Override + public boolean isPurchaseDone() + { + return mValidator.hasActivePurchase(); + } + + @Override + public boolean isPurchaseSupported() + { + return mBillingManager.isBillingSupported(); + } + + @Override + public void launchPurchaseFlow(@NonNull String productId) + { + mBillingManager.launchBillingFlowForProduct(productId); + } + + @NonNull + PurchaseValidator getValidator() + { + return mValidator; + } + + @NonNull + BillingManager getBillingManager() + { + return mBillingManager; + } + + abstract void onStart(@NonNull Activity activity); + + abstract void onStop(); +} diff --git a/android/src/com/mapswithme/maps/purchase/AdPurchaseController.java b/android/src/com/mapswithme/maps/purchase/AdPurchaseController.java new file mode 100644 index 0000000000..12eab57789 --- /dev/null +++ b/android/src/com/mapswithme/maps/purchase/AdPurchaseController.java @@ -0,0 +1,39 @@ +package com.mapswithme.maps.purchase; + +import android.app.Activity; +import android.support.annotation.NonNull; + +class AdPurchaseController extends AbstractPurchaseController +{ + @NonNull + private final AdValidationCallback mValidationCallback; + + AdPurchaseController(@NonNull PurchaseValidator validator, + @NonNull BillingManager billingManager) + { + super(validator, billingManager); + mValidationCallback = new StubAdValidationCallback(); + } + + @Override + void onStart(@NonNull Activity activity) + { + getValidator().addCallback(mValidationCallback); + } + + @Override + void onStop() + { + getValidator().removeCallback(mValidationCallback); + } + + private static class StubAdValidationCallback implements AdValidationCallback + { + + @Override + public void onValidate(@NonNull AdValidationStatus status) + { + // Do nothing by default. + } + } +} diff --git a/android/src/com/mapswithme/maps/purchase/AdSubscriptionValidator.java b/android/src/com/mapswithme/maps/purchase/AdSubscriptionValidator.java index d4386685d4..a4b00ac9ce 100644 --- a/android/src/com/mapswithme/maps/purchase/AdSubscriptionValidator.java +++ b/android/src/com/mapswithme/maps/purchase/AdSubscriptionValidator.java @@ -13,6 +13,12 @@ class AdSubscriptionValidator implements PurchaseValidator Framework.nativeSetSubscriptionValidationListener(this); } + @Override + public void destroy() + { + Framework.nativeSetSubscriptionValidationListener(null); + } + @Override public void validate(@NonNull String purchaseToken) { @@ -20,9 +26,9 @@ class AdSubscriptionValidator implements PurchaseValidator } @Override - public void hasActivePurchase() + public boolean hasActivePurchase() { - Framework.nativeHasActiveSubscription(); + return Framework.nativeHasActiveSubscription(); } @Override diff --git a/android/src/com/mapswithme/maps/purchase/BillingFactory.java b/android/src/com/mapswithme/maps/purchase/BillingFactory.java deleted file mode 100644 index 715bc33388..0000000000 --- a/android/src/com/mapswithme/maps/purchase/BillingFactory.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.mapswithme.maps.purchase; - -import android.app.Activity; -import android.support.annotation.NonNull; - -import com.android.billingclient.api.BillingClient; - -public enum BillingFactory -{ - ADS_REMOVAL - { - @NonNull - @Override - public PurchaseValidator createPurchaseManager() - { - return new AdSubscriptionValidator(); - } - - @NonNull - @Override - public BillingManager createBillingManager(@NonNull Activity activity, - @NonNull String... productIds) - { - return new PlayStoreBillingManager(activity, BillingClient.SkuType.SUBS, productIds); - } - }; - - @NonNull - public abstract PurchaseValidator createPurchaseManager(); - - @NonNull - public abstract BillingManager createBillingManager(@NonNull Activity activity, - @NonNull String... productIds); -} diff --git a/android/src/com/mapswithme/maps/purchase/BillingManager.java b/android/src/com/mapswithme/maps/purchase/BillingManager.java index 74b01a24fe..cbbe625feb 100644 --- a/android/src/com/mapswithme/maps/purchase/BillingManager.java +++ b/android/src/com/mapswithme/maps/purchase/BillingManager.java @@ -1,5 +1,6 @@ package com.mapswithme.maps.purchase; +import android.app.Activity; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.annotation.UiThread; @@ -12,7 +13,7 @@ public interface BillingManager /** * Initializes the current billing manager. */ - void initialize(); + void initialize(@NonNull Activity context); /** * Destroys the billing manager. diff --git a/android/src/com/mapswithme/maps/purchase/PlayStoreBillingManager.java b/android/src/com/mapswithme/maps/purchase/PlayStoreBillingManager.java index 698d0c12aa..a5829e93ae 100644 --- a/android/src/com/mapswithme/maps/purchase/PlayStoreBillingManager.java +++ b/android/src/com/mapswithme/maps/purchase/PlayStoreBillingManager.java @@ -25,8 +25,8 @@ public class PlayStoreBillingManager implements BillingManager mPendingRequests = new ArrayList<>(); - PlayStoreBillingManager(@NonNull Activity activity, - @NonNull @BillingClient.SkuType String productType, + PlayStoreBillingManager(@NonNull @BillingClient.SkuType String productType, @NonNull String... productIds) { - mActivity = activity; mProductIds = Collections.unmodifiableList(Arrays.asList(productIds)); mProductType = productType; } @Override - public void initialize() + public void initialize(@NonNull Activity context) { LOGGER.i(TAG, "Creating play store billing client..."); + mActivity = context; mBillingClient = BillingClient.newBuilder(mActivity).setListener(this).build(); mConnection = new PlayStoreBillingConnection(mBillingClient, this); mConnection.open(); @@ -63,6 +62,7 @@ public class PlayStoreBillingManager implements BillingManager createPurchaseValidator() + { + return new AdSubscriptionValidator(); + } + + @NonNull + @Override + public BillingManager createBillingManager + (@NonNull Activity activity, @NonNull String... productIds) + { + return new PlayStoreBillingManager(BillingClient.SkuType.SUBS, productIds); + } + + @Override + public PurchaseController createPurchaseController(@NonNull Activity activity, + @NonNull String... productIds) + { + BillingManager billingManager + = createBillingManager(activity, productIds); + PurchaseValidator validator = createPurchaseValidator(); + return new AdPurchaseController(validator, billingManager); + } + }; + + @NonNull + public abstract PurchaseValidator createPurchaseValidator(); + + @NonNull + public abstract BillingManager createBillingManager(@NonNull Activity activity, + @NonNull String... productIds); + + public abstract PurchaseController createPurchaseController(@NonNull Activity activity, + @NonNull String... productIds); +} diff --git a/android/src/com/mapswithme/maps/purchase/PurchaseValidator.java b/android/src/com/mapswithme/maps/purchase/PurchaseValidator.java index 1588ff2ae3..300265d78f 100644 --- a/android/src/com/mapswithme/maps/purchase/PurchaseValidator.java +++ b/android/src/com/mapswithme/maps/purchase/PurchaseValidator.java @@ -9,13 +9,18 @@ import android.support.annotation.NonNull; * one-to-one. If you need to validate different purchases you have to create different * implementations of this interface. */ -public interface PurchaseValidator +interface PurchaseValidator { /** - * Initializes validator for further work. + * Initializes the validator for further work. */ void initialize(); + /** + * Destroys this validator. + */ + void destroy(); + /** * Validates the purchase with specified token. * @@ -26,7 +31,7 @@ public interface PurchaseValidator /** * Indicates whether the app has active purchase or not. */ - void hasActivePurchase(); + boolean hasActivePurchase(); /** * Ads observer of validation.