diff --git a/android/res/layout/bookmark_payment_layout.xml b/android/res/layout/bookmark_payment_layout.xml index fe13c7282b..f10e7d3ab3 100644 --- a/android/res/layout/bookmark_payment_layout.xml +++ b/android/res/layout/bookmark_payment_layout.xml @@ -8,13 +8,14 @@ tools:showIn="@layout/fragment_bookmark_payment"> + android:textAllCaps="true" + tools:ignore="HardcodedText"/> +public interface BookmarkDownloadController extends Detachable, Savable { void downloadBookmark(@NonNull String url) throws MalformedURLException; + void retryDownloadBookmark() throws MalformedURLException; } diff --git a/android/src/com/mapswithme/maps/bookmarks/BookmarksCatalogFragment.java b/android/src/com/mapswithme/maps/bookmarks/BookmarksCatalogFragment.java index 0a868a9982..dd94140ed5 100644 --- a/android/src/com/mapswithme/maps/bookmarks/BookmarksCatalogFragment.java +++ b/android/src/com/mapswithme/maps/bookmarks/BookmarksCatalogFragment.java @@ -2,6 +2,7 @@ package com.mapswithme.maps.bookmarks; import android.annotation.SuppressLint; import android.annotation.TargetApi; +import android.app.Activity; import android.content.Intent; import android.net.http.SslError; import android.os.Build; @@ -87,16 +88,15 @@ public class BookmarksCatalogFragment extends BaseWebViewMwmFragment mAuthorizer = new Authorizer(this); mController = new DefaultBookmarkDownloadController(mAuthorizer, new CatalogListenerDecorator(this)); - mFailedPurchaseController = PurchaseFactory.createFailedBookmarkPurchaseController(); - mFailedPurchaseController.initialize(getActivity()); - mPurchaseChecker = new FailedBookmarkPurchaseChecker(); + if (savedInstanceState != null) + mController.onRestore(savedInstanceState); } @Override public void onStart() { super.onStart(); - mController.attach(getActivity()); + mController.attach(this); mFailedPurchaseController.addCallback(mPurchaseChecker); } @@ -113,6 +113,7 @@ public class BookmarksCatalogFragment extends BaseWebViewMwmFragment { super.onDestroyView(); mWebViewClient.clear(); + mFailedPurchaseController.destroy(); } @Nullable @@ -120,6 +121,9 @@ public class BookmarksCatalogFragment extends BaseWebViewMwmFragment public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + mFailedPurchaseController = PurchaseFactory.createFailedBookmarkPurchaseController(); + mFailedPurchaseController.initialize(getActivity()); + mPurchaseChecker = new FailedBookmarkPurchaseChecker(); View root = inflater.inflate(R.layout.fragment_bookmarks_catalog, container, false); mWebView = root.findViewById(getWebViewResId()); mRetryBtn = root.findViewById(R.id.retry_btn); @@ -179,6 +183,18 @@ public class BookmarksCatalogFragment extends BaseWebViewMwmFragment } } + private void retryBookmarkDownload() + { + try + { + mController.retryDownloadBookmark(); + } + catch (MalformedURLException e) + { + LOGGER.e(TAG, "Failed to retry bookmark downloading"); + } + } + @Override public void onTargetFragmentResult(int resultCode, @Nullable Intent data) { @@ -191,6 +207,23 @@ public class BookmarksCatalogFragment extends BaseWebViewMwmFragment return isAdded(); } + @Override + public void onActivityResult(int requestCode, int resultCode, Intent data) + { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == Activity.RESULT_OK && requestCode == REQ_CODE_PAY_BOOKMARK) + { + retryBookmarkDownload(); + } + } + + @Override + public void onSaveInstanceState(Bundle outState) + { + super.onSaveInstanceState(outState); + mController.onSave(outState); + } + private static class WebViewBookmarksCatalogClient extends WebViewClient { private final Logger LOGGER = LoggerFactory.INSTANCE.getLogger(LoggerFactory.Type.MISC); diff --git a/android/src/com/mapswithme/maps/bookmarks/DefaultBookmarkDownloadController.java b/android/src/com/mapswithme/maps/bookmarks/DefaultBookmarkDownloadController.java index 6bf79b9b6d..ce2388cb32 100644 --- a/android/src/com/mapswithme/maps/bookmarks/DefaultBookmarkDownloadController.java +++ b/android/src/com/mapswithme/maps/bookmarks/DefaultBookmarkDownloadController.java @@ -1,11 +1,13 @@ package com.mapswithme.maps.bookmarks; +import android.app.Application; import android.content.Context; import android.net.Uri; +import android.os.Bundle; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.v4.app.DialogFragment; -import android.support.v4.app.FragmentActivity; +import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.text.TextUtils; import android.widget.Toast; @@ -26,6 +28,7 @@ class DefaultBookmarkDownloadController implements BookmarkDownloadController, { private static final Logger LOGGER = LoggerFactory.INSTANCE.getLogger(LoggerFactory.Type.MISC); private static final String TAG = DefaultBookmarkDownloadController.class.getSimpleName(); + private static final String EXTRA_DOWNLOAD_URL = "extra_download_url"; @NonNull private final BookmarkDownloadReceiver mDownloadCompleteReceiver = new BookmarkDownloadReceiver(); @NonNull @@ -35,7 +38,10 @@ class DefaultBookmarkDownloadController implements BookmarkDownloadController, @NonNull private final BookmarkManager.BookmarksCatalogListener mCatalogListener; @Nullable - private FragmentActivity mActivity; + private Fragment mFragment; + @SuppressWarnings("NullableProblems") + @NonNull + private Application mApplication; DefaultBookmarkDownloadController(@NonNull Authorizer authorizer, @NonNull BookmarkManager.BookmarksCatalogListener catalogListener) @@ -47,43 +53,52 @@ class DefaultBookmarkDownloadController implements BookmarkDownloadController, @Override public void downloadBookmark(@NonNull String url) throws MalformedURLException { - downloadBookmarkInternal(getActivityOrThrow(), url); + downloadBookmarkInternal(mApplication, url); mDownloadUrl = url; } @Override - public void attach(@NonNull FragmentActivity activity) + public void retryDownloadBookmark() throws MalformedURLException { - if (mActivity != null) + if (mDownloadUrl == null) + throw new IllegalStateException("Download url must be non-null at this point"); + downloadBookmarkInternal(mApplication, mDownloadUrl); + } + + @Override + public void attach(@NonNull Fragment fragment) + { + if (mFragment != null) throw new AssertionError("Already attached! Call detach."); - mActivity = activity; + mFragment = fragment; + mApplication = mFragment.getActivity().getApplication(); mAuthorizer.attach(this); mDownloadCompleteReceiver.attach(this); - mDownloadCompleteReceiver.register(getActivityOrThrow().getApplication()); + mDownloadCompleteReceiver.register(getFragmentOrThrow().getActivity().getApplication()); BookmarkManager.INSTANCE.addCatalogListener(mCatalogListener); } @Override public void detach() { - if (mActivity == null) + if (mFragment == null) throw new AssertionError("Already detached! Call attach."); mAuthorizer.detach(); mDownloadCompleteReceiver.detach(); - mDownloadCompleteReceiver.unregister(getActivityOrThrow().getApplication()); + mDownloadCompleteReceiver.unregister(getFragmentOrThrow().getActivity().getApplication()); BookmarkManager.INSTANCE.removeCatalogListener(mCatalogListener); - mActivity = null; + mFragment = null; } @NonNull - FragmentActivity getActivityOrThrow() + Fragment getFragmentOrThrow() { - if (mActivity == null) + if (mFragment == null) throw new IllegalStateException("Call this method only when controller is attached!"); - return mActivity; + return mFragment; } private static void downloadBookmarkInternal(@NonNull Context context, @NonNull String url) @@ -112,8 +127,8 @@ class DefaultBookmarkDownloadController implements BookmarkDownloadController, throw new IllegalStateException("Download url must be non-null if payment required!"); PaymentData data = parsePaymentData(mDownloadUrl); - BookmarkPaymentActivity.start(getActivityOrThrow(), data, - BookmarksCatalogFragment.REQ_CODE_PAY_BOOKMARK); + BookmarkPaymentActivity.startForResult(getFragmentOrThrow(), data, + BookmarksCatalogFragment.REQ_CODE_PAY_BOOKMARK); } @NonNull @@ -129,7 +144,7 @@ class DefaultBookmarkDownloadController implements BookmarkDownloadController, hideProgress(); if (!success) { - Toast.makeText(getActivityOrThrow(), R.string.profile_authorization_error, + Toast.makeText(getFragmentOrThrow().getContext(), R.string.profile_authorization_error, Toast.LENGTH_LONG).show(); return; } @@ -139,7 +154,7 @@ class DefaultBookmarkDownloadController implements BookmarkDownloadController, try { - downloadBookmarkInternal(getActivityOrThrow(), mDownloadUrl); + downloadBookmarkInternal(mApplication, mDownloadUrl); } catch (MalformedURLException e) { @@ -149,18 +164,17 @@ class DefaultBookmarkDownloadController implements BookmarkDownloadController, private void showProgress() { - String message = getActivityOrThrow().getString(R.string.please_wait); + String message = getFragmentOrThrow().getString(R.string.please_wait); ProgressDialogFragment dialog = ProgressDialogFragment.newInstance(message, false, true); - getActivityOrThrow().getSupportFragmentManager() + getFragmentOrThrow().getActivity().getSupportFragmentManager() .beginTransaction() .add(dialog, dialog.getClass().getCanonicalName()) .commitAllowingStateLoss(); } - private void hideProgress() { - FragmentManager fm = getActivityOrThrow().getSupportFragmentManager(); + FragmentManager fm = getFragmentOrThrow().getActivity().getSupportFragmentManager(); String tag = ProgressDialogFragment.class.getCanonicalName(); DialogFragment frag = (DialogFragment) fm.findFragmentByTag(tag); if (frag != null) @@ -185,12 +199,24 @@ class DefaultBookmarkDownloadController implements BookmarkDownloadController, // Do nothing by default. } + @Override + public void onSave(@NonNull Bundle outState) + { + outState.putString(EXTRA_DOWNLOAD_URL, mDownloadUrl); + } + + @Override + public void onRestore(@NonNull Bundle inState) + { + mDownloadUrl = inState.getString(EXTRA_DOWNLOAD_URL); + } + private static class BookmarkPaymentDataParser implements PaymentDataParser { private final static String SERVER_ID = "id"; private final static String PRODUCT_ID = "tier"; private final static String NAME = "name"; - private final static String IMG_URL = "img"; + private final static String IMG_URL = "img_url"; private final static String AUTHOR_NAME = "author_name"; @NonNull diff --git a/android/src/com/mapswithme/maps/purchase/AdsRemovalPurchaseDialog.java b/android/src/com/mapswithme/maps/purchase/AdsRemovalPurchaseDialog.java index fe05c79bfa..4914dce206 100644 --- a/android/src/com/mapswithme/maps/purchase/AdsRemovalPurchaseDialog.java +++ b/android/src/com/mapswithme/maps/purchase/AdsRemovalPurchaseDialog.java @@ -319,7 +319,7 @@ public class AdsRemovalPurchaseDialog extends BaseMwmDialogFragment @Override public void onAlertDialogNegativeClick(int requestCode, int which) { - + // Do nothing by default. } @Override @@ -347,10 +347,8 @@ public class AdsRemovalPurchaseDialog extends BaseMwmDialogFragment mProductDetails = new ProductDetails[Period.values().length]; for (SkuDetails sku: details) { - float price = sku.getPriceAmountMicros() / 1000000; - String currencyCode = sku.getPriceCurrencyCode(); Period period = Period.valueOf(sku.getSubscriptionPeriod()); - mProductDetails[period.ordinal()] = new ProductDetails(sku.getSku(), price, currencyCode); + mProductDetails[period.ordinal()] = PurchaseUtils.toProductDetails(sku); } } diff --git a/android/src/com/mapswithme/maps/purchase/BookmarkPaymentActivity.java b/android/src/com/mapswithme/maps/purchase/BookmarkPaymentActivity.java index be7f0f7f64..7086bd3ec7 100644 --- a/android/src/com/mapswithme/maps/purchase/BookmarkPaymentActivity.java +++ b/android/src/com/mapswithme/maps/purchase/BookmarkPaymentActivity.java @@ -1,6 +1,5 @@ package com.mapswithme.maps.purchase; -import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.support.annotation.NonNull; @@ -11,14 +10,14 @@ import com.mapswithme.maps.bookmarks.data.PaymentData; public class BookmarkPaymentActivity extends BaseMwmFragmentActivity { - public static void start(@NonNull Activity activity, @NonNull PaymentData paymentData, - int requestCode) + public static void startForResult(@NonNull Fragment fragment, @NonNull PaymentData paymentData, + int requestCode) { - Intent intent = new Intent(activity, BookmarkPaymentActivity.class); + Intent intent = new Intent(fragment.getActivity(), BookmarkPaymentActivity.class); Bundle args = new Bundle(); args.putParcelable(BookmarkPaymentFragment.ARG_PAYMENT_DATA, paymentData); intent.putExtras(args); - activity.startActivityForResult(intent, requestCode); + fragment.startActivityForResult(intent, requestCode); } @Override diff --git a/android/src/com/mapswithme/maps/purchase/BookmarkPaymentFragment.java b/android/src/com/mapswithme/maps/purchase/BookmarkPaymentFragment.java index 5b71e5590c..3ad641b6b0 100644 --- a/android/src/com/mapswithme/maps/purchase/BookmarkPaymentFragment.java +++ b/android/src/com/mapswithme/maps/purchase/BookmarkPaymentFragment.java @@ -1,34 +1,44 @@ package com.mapswithme.maps.purchase; +import android.app.Activity; import android.os.Bundle; import android.support.annotation.NonNull; import android.support.annotation.Nullable; -import android.support.v4.app.DialogFragment; -import android.support.v4.app.FragmentManager; +import android.text.TextUtils; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; import com.android.billingclient.api.SkuDetails; +import com.bumptech.glide.Glide; import com.mapswithme.maps.Framework; import com.mapswithme.maps.PrivateVariables; import com.mapswithme.maps.R; import com.mapswithme.maps.base.BaseMwmFragment; -import com.mapswithme.maps.bookmarks.data.PaymentData; -import com.mapswithme.maps.dialog.ProgressDialogFragment; import com.mapswithme.maps.base.Detachable; +import com.mapswithme.maps.bookmarks.data.PaymentData; +import com.mapswithme.maps.dialog.AlertDialogCallback; +import com.mapswithme.util.Utils; import com.mapswithme.util.log.Logger; import com.mapswithme.util.log.LoggerFactory; +import java.util.Collections; import java.util.List; public class BookmarkPaymentFragment extends BaseMwmFragment - implements PurchaseStateActivator + implements AlertDialogCallback, PurchaseStateActivator { static final String ARG_PAYMENT_DATA = "arg_payment_data"; private static final Logger LOGGER = LoggerFactory.INSTANCE.getLogger(LoggerFactory.Type.MISC); private static final String TAG = BookmarkPaymentFragment.class.getSimpleName(); private static final String EXTRA_CURRENT_STATE = "extra_current_state"; + private static final String EXTRA_PRODUCT_DETAILS = "extra_product_details"; + private static final String EXTRA_VALIDATION_RESULT = "extra_validation_result"; + final static int REQ_CODE_PRODUCT_DETAILS_FAILURE = 1; + final static int REQ_CODE_PAYMENT_FAILURE = 2; + final static int REQ_CODE_START_TRANSACTION_FAILURE = 3; @SuppressWarnings("NullableProblems") @NonNull @@ -38,6 +48,9 @@ public class BookmarkPaymentFragment extends BaseMwmFragment @SuppressWarnings("NullableProblems") @NonNull private PaymentData mPaymentData; + @Nullable + private ProductDetails mProductDetails; + private boolean mValidationResult; @NonNull private BookmarkPaymentState mState = BookmarkPaymentState.NONE; @@ -54,9 +67,6 @@ public class BookmarkPaymentFragment extends BaseMwmFragment throw new IllegalStateException("Payment data must be provided for payment fragment!"); mPaymentData = paymentData; - mPurchaseController = PurchaseFactory.createBookmarkPurchaseController(mPaymentData.getProductId(), - mPaymentData.getServerId()); - mPurchaseController.initialize(getActivity()); } @Nullable @@ -64,8 +74,14 @@ public class BookmarkPaymentFragment extends BaseMwmFragment public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + mPurchaseController = PurchaseFactory.createBookmarkPurchaseController(mPaymentData.getProductId(), + mPaymentData.getServerId()); + mPurchaseController.initialize(getActivity()); View root = inflater.inflate(R.layout.fragment_bookmark_payment, container, false); - // TODO: implementation coming soon. + TextView buyButton = root.findViewById(R.id.buy_btn); + buyButton.setOnClickListener(v -> startPurchaseTransaction()); + TextView cancelButton = root.findViewById(R.id.cancel_btn); + cancelButton.setOnClickListener(v -> getActivity().finish()); return root; } @@ -74,17 +90,34 @@ public class BookmarkPaymentFragment extends BaseMwmFragment { super.onViewCreated(view, savedInstanceState); LOGGER.d(TAG, "onViewCreated savedInstanceState = " + savedInstanceState); + setInitialPaymentData(); + loadImage(); if (savedInstanceState != null) { + mProductDetails = savedInstanceState.getParcelable(EXTRA_PRODUCT_DETAILS); + if (mProductDetails != null) + updateProductDetails(); + mValidationResult = savedInstanceState.getBoolean(EXTRA_VALIDATION_RESULT); BookmarkPaymentState savedState = BookmarkPaymentState.values()[savedInstanceState.getInt(EXTRA_CURRENT_STATE)]; activateState(savedState); return; } + + activateState(BookmarkPaymentState.PRODUCT_DETAILS_LOADING); + mPurchaseController.queryPurchaseDetails(); + } + + @Override + public void onDestroyView() + { + super.onDestroyView(); + mPurchaseController.destroy(); } private void startPurchaseTransaction() { + activateState(BookmarkPaymentState.TRANSACTION_STARTING); Framework.nativeStartPurchaseTransaction(mPaymentData.getServerId(), PrivateVariables.bookmarksVendor()); } @@ -118,13 +151,7 @@ public class BookmarkPaymentFragment extends BaseMwmFragment super.onSaveInstanceState(outState); LOGGER.d(TAG, "onSaveInstanceState"); outState.putInt(EXTRA_CURRENT_STATE, mState.ordinal()); - } - - @Override - public void onDestroy() - { - super.onDestroy(); - mPurchaseController.destroy(); + outState.putParcelable(EXTRA_PRODUCT_DETAILS, mProductDetails); } @Override @@ -138,29 +165,99 @@ public class BookmarkPaymentFragment extends BaseMwmFragment mState.activate(this); } - void showProgress() + private void loadImage() { - String message = getString(R.string.please_wait); - ProgressDialogFragment dialog = ProgressDialogFragment.newInstance(message, false, true); - getActivity().getSupportFragmentManager() - .beginTransaction() - .add(dialog, dialog.getClass().getCanonicalName()) - .commitAllowingStateLoss(); + if (TextUtils.isEmpty(mPaymentData.getImgUrl())) + return; + + ImageView imageView = getViewOrThrow().findViewById(R.id.image); + Glide.with(imageView.getContext()) + .load(mPaymentData.getImgUrl()) + .centerCrop() + .into(imageView); } - void hideProgress() + private void setInitialPaymentData() { - FragmentManager fm = getActivity().getSupportFragmentManager(); - String tag = ProgressDialogFragment.class.getCanonicalName(); - DialogFragment frag = (DialogFragment) fm.findFragmentByTag(tag); - if (frag != null) - frag.dismissAllowingStateLoss(); + TextView name = getViewOrThrow().findViewById(R.id.product_catalog_name); + name.setText(mPaymentData.getName()); + TextView author = getViewOrThrow().findViewById(R.id.author_name); + author.setText(mPaymentData.getAuthorName()); + } + + private void handleProductDetails(@NonNull List details) + { + if (details.isEmpty()) + return; + + SkuDetails skuDetails = details.get(0); + mProductDetails = PurchaseUtils.toProductDetails(skuDetails); + } + + private void handleValidationResult(boolean validationResult) + { + mValidationResult = validationResult; + } + + @Override + public void onAlertDialogPositiveClick(int requestCode, int which) + { + handleErrorDialogEvent(requestCode); + } + + @Override + public void onAlertDialogNegativeClick(int requestCode, int which) + { + // Do nothing by default. + } + + @Override + public void onAlertDialogCancel(int requestCode) + { + handleErrorDialogEvent(requestCode); + } + + private void handleErrorDialogEvent(int requestCode) + { + switch (requestCode) + { + case REQ_CODE_PRODUCT_DETAILS_FAILURE: + getActivity().finish(); + break; + case REQ_CODE_START_TRANSACTION_FAILURE: + case REQ_CODE_PAYMENT_FAILURE: + activateState(BookmarkPaymentState.PRODUCT_DETAILS_LOADED); + break; + } + } + + public void updateProductDetails() + { + if (mProductDetails == null) + throw new AssertionError("Product details must be obtained at this moment!"); + + TextView buyButton = getViewOrThrow().findViewById(R.id.buy_btn); + String price = Utils.formatCurrencyString(mProductDetails.getPrice(), mProductDetails.getCurrencyCode()); + buyButton.setText(getString(R.string.buy_btn, price)); + TextView storeName = getViewOrThrow().findViewById(R.id.product_store_name); + storeName.setText(mProductDetails.getTitle()); + } + + public void finishValidation() + { + if (mValidationResult) + getActivity().setResult(Activity.RESULT_OK); + getActivity().finish(); } private static class BookmarkPurchaseCallback extends StatefulPurchaseCallback implements PurchaseCallback, Detachable, Framework.StartTransactionListener { + @Nullable + private List mPendingDetails; + private Boolean mPendingValidationResult; + @Override public void onStartTransaction(boolean success, @NonNull String serverId, @NonNull String vendorId) @@ -172,12 +269,18 @@ public class BookmarkPaymentFragment extends BaseMwmFragment } activateStateSafely(BookmarkPaymentState.TRANSACTION_STARTED); + if (getUiObject() != null) + getUiObject().launchBillingFlow(); } @Override public void onProductDetailsLoaded(@NonNull List details) { - // TODO: store details and activate corresponding state. + if (getUiObject() == null) + mPendingDetails = Collections.unmodifiableList(details); + else + getUiObject().handleProductDetails(details); + activateStateSafely(BookmarkPaymentState.PRODUCT_DETAILS_LOADED); } @Override @@ -207,8 +310,28 @@ public class BookmarkPaymentFragment extends BaseMwmFragment @Override public void onValidationFinish(boolean success) { - // TODO: store validation result. + if (getUiObject() == null) + mPendingValidationResult = success; + else + getUiObject().handleValidationResult(success); + activateStateSafely(BookmarkPaymentState.VALIDATION_FINISH); } + + @Override + void onAttach(@NonNull BookmarkPaymentFragment uiObject) + { + if (mPendingDetails != null) + { + uiObject.handleProductDetails(mPendingDetails); + mPendingDetails = null; + } + + if (mPendingValidationResult != null) + { + uiObject.handleValidationResult(mPendingValidationResult); + mPendingValidationResult = null; + } + } } } diff --git a/android/src/com/mapswithme/maps/purchase/BookmarkPaymentState.java b/android/src/com/mapswithme/maps/purchase/BookmarkPaymentState.java index 372b537cde..8b735e6ea7 100644 --- a/android/src/com/mapswithme/maps/purchase/BookmarkPaymentState.java +++ b/android/src/com/mapswithme/maps/purchase/BookmarkPaymentState.java @@ -4,6 +4,7 @@ import android.support.annotation.NonNull; import com.mapswithme.maps.R; import com.mapswithme.maps.dialog.AlertDialog; +import com.mapswithme.util.UiUtils; enum BookmarkPaymentState { @@ -15,12 +16,29 @@ enum BookmarkPaymentState throw new UnsupportedOperationException("This state can't be used!"); } }, + PRODUCT_DETAILS_LOADING + { + @Override + void activate(@NonNull BookmarkPaymentFragment fragment) + { + showProgress(fragment); + } + }, + PRODUCT_DETAILS_LOADED + { + @Override + void activate(@NonNull BookmarkPaymentFragment fragment) + { + hideProgress(fragment); + fragment.updateProductDetails(); + } + }, TRANSACTION_STARTING { @Override void activate(@NonNull BookmarkPaymentFragment fragment) { - fragment.showProgress(); + showProgress(fragment); } }, TRANSACTION_FAILURE @@ -28,8 +46,9 @@ enum BookmarkPaymentState @Override void activate(@NonNull BookmarkPaymentFragment fragment) { - fragment.hideProgress(); + UiUtils.hide(fragment.getViewOrThrow(), R.id.progress); AlertDialog alertDialog = new AlertDialog.Builder() + .setReqCode(BookmarkPaymentFragment.REQ_CODE_START_TRANSACTION_FAILURE) .setTitleId(R.string.error_server_title) .setMessageId(R.string.error_server_message) .setPositiveBtnId(R.string.ok) @@ -42,8 +61,7 @@ enum BookmarkPaymentState @Override void activate(@NonNull BookmarkPaymentFragment fragment) { - fragment.hideProgress(); - fragment.launchBillingFlow(); + hideProgress(fragment); } }, PAYMENT_FAILURE @@ -52,6 +70,7 @@ enum BookmarkPaymentState void activate(@NonNull BookmarkPaymentFragment fragment) { AlertDialog alertDialog = new AlertDialog.Builder() + .setReqCode(BookmarkPaymentFragment.REQ_CODE_PAYMENT_FAILURE) .setTitleId(R.string.bookmarks_convert_error_title) .setMessageId(R.string.purchase_error_subtitle) .setPositiveBtnId(R.string.back) @@ -64,7 +83,7 @@ enum BookmarkPaymentState @Override void activate(@NonNull BookmarkPaymentFragment fragment) { - fragment.showProgress(); + showProgress(fragment); } }, VALIDATION_FINISH @@ -72,7 +91,8 @@ enum BookmarkPaymentState @Override void activate(@NonNull BookmarkPaymentFragment fragment) { - fragment.hideProgress(); + hideProgress(fragment); + fragment.finishValidation(); } }, PRODUCT_DETAILS_FAILURE @@ -81,6 +101,7 @@ enum BookmarkPaymentState void activate(@NonNull BookmarkPaymentFragment fragment) { AlertDialog alertDialog = new AlertDialog.Builder() + .setReqCode(BookmarkPaymentFragment.REQ_CODE_PRODUCT_DETAILS_FAILURE) .setTitleId(R.string.bookmarks_convert_error_title) .setMessageId(R.string.discovery_button_other_error_message) .setPositiveBtnId(R.string.ok) @@ -89,5 +110,17 @@ enum BookmarkPaymentState } }; + private static void showProgress(@NonNull BookmarkPaymentFragment fragment) + { + UiUtils.show(fragment.getViewOrThrow(), R.id.progress); + UiUtils.hide(fragment.getViewOrThrow(), R.id.buy_btn); + } + + private static void hideProgress(@NonNull BookmarkPaymentFragment fragment) + { + UiUtils.hide(fragment.getViewOrThrow(), R.id.progress); + UiUtils.show(fragment.getViewOrThrow(), R.id.buy_btn); + } + abstract void activate(@NonNull BookmarkPaymentFragment fragment); } diff --git a/android/src/com/mapswithme/maps/purchase/BookmarkPurchaseController.java b/android/src/com/mapswithme/maps/purchase/BookmarkPurchaseController.java index 7beaad1b9b..197a7791a2 100644 --- a/android/src/com/mapswithme/maps/purchase/BookmarkPurchaseController.java +++ b/android/src/com/mapswithme/maps/purchase/BookmarkPurchaseController.java @@ -72,7 +72,7 @@ class BookmarkPurchaseController extends AbstractPurchaseController details) { if (getUiCallback() != null) - getUiCallback().onProductDetailsFailure(); + getUiCallback().onProductDetailsLoaded(details); } @Override diff --git a/android/src/com/mapswithme/maps/purchase/ProductDetails.java b/android/src/com/mapswithme/maps/purchase/ProductDetails.java index 51f7f473e3..865467842d 100644 --- a/android/src/com/mapswithme/maps/purchase/ProductDetails.java +++ b/android/src/com/mapswithme/maps/purchase/ProductDetails.java @@ -11,17 +11,21 @@ class ProductDetails implements Parcelable private final float mPrice; @NonNull private final String mCurrencyCode; + @NonNull + private final String mTitle; - ProductDetails(@NonNull String productId, float price, @NonNull String currencyCode) + ProductDetails(@NonNull String productId, float price, @NonNull String currencyCode, @NonNull + String title) { mProductId = productId; mPrice = price; mCurrencyCode = currencyCode; + mTitle = title; } private ProductDetails(Parcel in) { - this(in.readString(), in.readFloat(), in.readString()); + this(in.readString(), in.readFloat(), in.readString(), in.readString()); } float getPrice() @@ -41,6 +45,12 @@ class ProductDetails implements Parcelable return mProductId; } + @NonNull + public String getTitle() + { + return mTitle; + } + public static final Creator CREATOR = new Creator() { @Override @@ -68,5 +78,6 @@ class ProductDetails implements Parcelable dest.writeString(mProductId); dest.writeFloat(mPrice); dest.writeString(mCurrencyCode); + dest.writeString(mTitle); } } diff --git a/android/src/com/mapswithme/maps/purchase/PurchaseUtils.java b/android/src/com/mapswithme/maps/purchase/PurchaseUtils.java index 2ceb3926b2..4cc8eaf786 100644 --- a/android/src/com/mapswithme/maps/purchase/PurchaseUtils.java +++ b/android/src/com/mapswithme/maps/purchase/PurchaseUtils.java @@ -3,6 +3,7 @@ package com.mapswithme.maps.purchase; import android.support.annotation.NonNull; import com.android.billingclient.api.Purchase; +import com.android.billingclient.api.SkuDetails; import org.json.JSONException; class PurchaseUtils @@ -24,4 +25,12 @@ class PurchaseUtils throw new IllegalArgumentException("Failed to parse purchase token!"); } } + + @NonNull + static ProductDetails toProductDetails(@NonNull SkuDetails skuDetails) + { + float price = skuDetails.getPriceAmountMicros() / 1000000; + String currencyCode = skuDetails.getPriceCurrencyCode(); + return new ProductDetails(skuDetails.getSku(), price, currencyCode, skuDetails.getTitle()); + } }