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());
+ }
}