diff --git a/android/AndroidManifest.xml b/android/AndroidManifest.xml
index 5090439493..6cb92c1580 100644
--- a/android/AndroidManifest.xml
+++ b/android/AndroidManifest.xml
@@ -447,6 +447,7 @@
android:label="@string/ugc_route_tags_screen_label">
+
+
+
+
+
+
diff --git a/android/src/com/mapswithme/maps/bookmarks/BookmarksCatalogFragment.java b/android/src/com/mapswithme/maps/bookmarks/BookmarksCatalogFragment.java
index 8439dd132d..22e5dfcf7f 100644
--- a/android/src/com/mapswithme/maps/bookmarks/BookmarksCatalogFragment.java
+++ b/android/src/com/mapswithme/maps/bookmarks/BookmarksCatalogFragment.java
@@ -39,6 +39,7 @@ public class BookmarksCatalogFragment extends BaseWebViewMwmFragment
implements TargetFragmentCallback
{
public static final String EXTRA_BOOKMARKS_CATALOG_URL = "bookmarks_catalog_url";
+ static final int REQ_CODE_PAY_BOOKMARK = 1;
private static final Logger LOGGER = LoggerFactory.INSTANCE.getLogger(LoggerFactory.Type.MISC);
private static final String TAG = BookmarksCatalogFragment.class.getSimpleName();
@@ -156,7 +157,7 @@ public class BookmarksCatalogFragment extends BaseWebViewMwmFragment
}
catch (MalformedURLException e)
{
- LOGGER.e(TAG, "Failed to download bookmark, url: " + url, e);
+ LOGGER.e(TAG, "Failed to download bookmark, url: " + url);
return false;
}
}
diff --git a/android/src/com/mapswithme/maps/bookmarks/DefaultBookmarkDownloadController.java b/android/src/com/mapswithme/maps/bookmarks/DefaultBookmarkDownloadController.java
index 16b567605b..733b21471e 100644
--- a/android/src/com/mapswithme/maps/bookmarks/DefaultBookmarkDownloadController.java
+++ b/android/src/com/mapswithme/maps/bookmarks/DefaultBookmarkDownloadController.java
@@ -12,6 +12,7 @@ import com.mapswithme.maps.R;
import com.mapswithme.maps.auth.Authorizer;
import com.mapswithme.maps.bookmarks.data.BookmarkManager;
import com.mapswithme.maps.bookmarks.data.PaymentData;
+import com.mapswithme.maps.purchase.BookmarkPaymentActivity;
import com.mapswithme.util.log.Logger;
import com.mapswithme.util.log.LoggerFactory;
@@ -66,11 +67,11 @@ class DefaultBookmarkDownloadController implements BookmarkDownloadController,
if (mActivity == null)
throw new AssertionError("Already detached! Call attach.");
- mActivity = null;
mAuthorizer.detach();
mDownloadCompleteReceiver.detach();
mDownloadCompleteReceiver.unregister(getActivityOrThrow().getApplication());
BookmarkManager.INSTANCE.removeCatalogListener(mCatalogListener);
+ mActivity = null;
}
@NonNull
@@ -108,9 +109,8 @@ class DefaultBookmarkDownloadController implements BookmarkDownloadController,
throw new IllegalStateException("Download url must be non-null if payment required!");
PaymentData data = parsePaymentData(mDownloadUrl);
- //TODO: pass data and show payment UI.
- Toast.makeText(getActivityOrThrow(), "Payment required. Ui coming soon!",
- Toast.LENGTH_SHORT).show();
+ BookmarkPaymentActivity.start(getActivityOrThrow(), data,
+ BookmarksCatalogFragment.REQ_CODE_PAY_BOOKMARK);
}
@NonNull
diff --git a/android/src/com/mapswithme/maps/bookmarks/data/PaymentData.java b/android/src/com/mapswithme/maps/bookmarks/data/PaymentData.java
index b6328c1a3a..c9148b8013 100644
--- a/android/src/com/mapswithme/maps/bookmarks/data/PaymentData.java
+++ b/android/src/com/mapswithme/maps/bookmarks/data/PaymentData.java
@@ -1,9 +1,11 @@
package com.mapswithme.maps.bookmarks.data;
+import android.os.Parcel;
+import android.os.Parcelable;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
-public class PaymentData
+public class PaymentData implements Parcelable
{
@NonNull
private final String mServerId;
@@ -26,6 +28,30 @@ public class PaymentData
mAuthorName = authorName;
}
+ private PaymentData(Parcel in)
+ {
+ mServerId = in.readString();
+ mProductId = in.readString();
+ mName = in.readString();
+ mImgUrl = in.readString();
+ mAuthorName = in.readString();
+ }
+
+ public static final Creator CREATOR = new Creator()
+ {
+ @Override
+ public PaymentData createFromParcel(Parcel in)
+ {
+ return new PaymentData(in);
+ }
+
+ @Override
+ public PaymentData[] newArray(int size)
+ {
+ return new PaymentData[size];
+ }
+ };
+
@NonNull
public String getServerId()
{
@@ -55,4 +81,20 @@ public class PaymentData
{
return mAuthorName;
}
+
+ @Override
+ public int describeContents()
+ {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags)
+ {
+ dest.writeString(mServerId);
+ dest.writeString(mProductId);
+ dest.writeString(mName);
+ dest.writeString(mImgUrl);
+ dest.writeString(mAuthorName);
+ }
}
diff --git a/android/src/com/mapswithme/maps/purchase/AbstractPurchaseController.java b/android/src/com/mapswithme/maps/purchase/AbstractPurchaseController.java
index 468b578ab5..0273960a4f 100644
--- a/android/src/com/mapswithme/maps/purchase/AbstractPurchaseController.java
+++ b/android/src/com/mapswithme/maps/purchase/AbstractPurchaseController.java
@@ -4,6 +4,13 @@ import android.app.Activity;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
+import com.android.billingclient.api.Purchase;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
abstract class AbstractPurchaseController implements PurchaseController
{
@NonNull
@@ -12,12 +19,16 @@ abstract class AbstractPurchaseController implements PurchaseC
private final BillingManager mBillingManager;
@Nullable
private UiCallback mUiCallback;
+ @NonNull
+ private final List mProductIds;
AbstractPurchaseController(@NonNull PurchaseValidator validator,
- @NonNull BillingManager billingManager)
+ @NonNull BillingManager billingManager,
+ @NonNull String... productIds)
{
mValidator = validator;
mBillingManager = billingManager;
+ mProductIds = Collections.unmodifiableList(Arrays.asList(productIds));
}
@Override
@@ -78,6 +89,38 @@ abstract class AbstractPurchaseController implements PurchaseC
return mBillingManager;
}
+ @SuppressWarnings("AssignmentOrReturnOfFieldWithMutableType")
+ @NonNull
+ public List getProductIds()
+ {
+ return mProductIds;
+ }
+
+ @NonNull
+ final List filterByProductIds(@NonNull List purchases)
+ {
+ List result = new ArrayList<>();
+ for (Purchase purchase: purchases)
+ {
+ if (getProductIds().contains(purchase.getSku()))
+ result.add(purchase);
+ }
+
+ return Collections.unmodifiableList(result);
+ }
+
+ @Nullable
+ final Purchase findTargetPurchase(@NonNull List purchases)
+ {
+ for (Purchase purchase: purchases)
+ {
+ if (getProductIds().contains(purchase.getSku()))
+ return purchase;
+ }
+
+ return null;
+ }
+
abstract void onInitialize(@NonNull Activity activity);
abstract void onDestroy();
diff --git a/android/src/com/mapswithme/maps/purchase/AdsRemovalPurchaseController.java b/android/src/com/mapswithme/maps/purchase/AdsRemovalPurchaseController.java
index f19be166d1..076b77bf94 100644
--- a/android/src/com/mapswithme/maps/purchase/AdsRemovalPurchaseController.java
+++ b/android/src/com/mapswithme/maps/purchase/AdsRemovalPurchaseController.java
@@ -2,7 +2,6 @@ package com.mapswithme.maps.purchase;
import android.app.Activity;
import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
import android.text.TextUtils;
import com.android.billingclient.api.BillingClient;
@@ -15,8 +14,6 @@ import com.mapswithme.util.log.Logger;
import com.mapswithme.util.log.LoggerFactory;
import com.mapswithme.util.statistics.Statistics;
-import java.util.Arrays;
-import java.util.Collections;
import java.util.List;
class AdsRemovalPurchaseController extends AbstractPurchaseController mProductIds;
AdsRemovalPurchaseController(@NonNull PurchaseValidator validator,
@NonNull BillingManager billingManager,
@NonNull String... productIds)
{
super(validator, billingManager);
- mProductIds = Collections.unmodifiableList(Arrays.asList(productIds));
}
@Override
@@ -57,7 +51,7 @@ class AdsRemovalPurchaseController extends AbstractPurchaseController purchases)
{
- for (Purchase purchase : purchases)
+ for (Purchase purchase : filterByProductIds(purchases))
{
LOGGER.i(TAG, "Validating purchase '" + purchase.getSku() + "' on backend server...");
validatePurchase(purchase.getOriginalJson());
@@ -173,16 +167,5 @@ class AdsRemovalPurchaseController extends AbstractPurchaseController purchases)
- {
- for (Purchase purchase: purchases)
- {
- if (mProductIds.contains(purchase.getSku()))
- return purchase;
- }
-
- return null;
- }
}
}
diff --git a/android/src/com/mapswithme/maps/purchase/BookmarkPaymentActivity.java b/android/src/com/mapswithme/maps/purchase/BookmarkPaymentActivity.java
new file mode 100644
index 0000000000..be7f0f7f64
--- /dev/null
+++ b/android/src/com/mapswithme/maps/purchase/BookmarkPaymentActivity.java
@@ -0,0 +1,29 @@
+package com.mapswithme.maps.purchase;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.support.annotation.NonNull;
+import android.support.v4.app.Fragment;
+
+import com.mapswithme.maps.base.BaseMwmFragmentActivity;
+import com.mapswithme.maps.bookmarks.data.PaymentData;
+
+public class BookmarkPaymentActivity extends BaseMwmFragmentActivity
+{
+ public static void start(@NonNull Activity activity, @NonNull PaymentData paymentData,
+ int requestCode)
+ {
+ Intent intent = new Intent(activity, BookmarkPaymentActivity.class);
+ Bundle args = new Bundle();
+ args.putParcelable(BookmarkPaymentFragment.ARG_PAYMENT_DATA, paymentData);
+ intent.putExtras(args);
+ activity.startActivityForResult(intent, requestCode);
+ }
+
+ @Override
+ protected Class extends Fragment> getFragmentClass()
+ {
+ return BookmarkPaymentFragment.class;
+ }
+}
diff --git a/android/src/com/mapswithme/maps/purchase/BookmarkPaymentFragment.java b/android/src/com/mapswithme/maps/purchase/BookmarkPaymentFragment.java
new file mode 100644
index 0000000000..69f92c9451
--- /dev/null
+++ b/android/src/com/mapswithme/maps/purchase/BookmarkPaymentFragment.java
@@ -0,0 +1,82 @@
+package com.mapswithme.maps.purchase;
+
+import android.os.Bundle;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import com.mapswithme.maps.R;
+import com.mapswithme.maps.base.BaseMwmFragment;
+import com.mapswithme.maps.bookmarks.data.PaymentData;
+
+public class BookmarkPaymentFragment extends BaseMwmFragment
+{
+ static final String ARG_PAYMENT_DATA = "arg_payment_data";
+ @SuppressWarnings("NullableProblems")
+ @NonNull
+ private PurchaseController mPurchaseController;
+ @NonNull
+ private BookmarkPurchaseCallback mPurchaseCallback = new BookmarkPurchaseCallbackImpl();
+ @SuppressWarnings("NullableProblems")
+ @NonNull
+ private PaymentData mPaymentData;
+ @Override
+ public void onCreate(@Nullable Bundle savedInstanceState)
+ {
+ super.onCreate(savedInstanceState);
+ Bundle args = getArguments();
+ if (args == null)
+ throw new IllegalStateException("Args must be provided for payment fragment!");
+
+ PaymentData paymentData = args.getParcelable(ARG_PAYMENT_DATA);
+ if (paymentData == null)
+ throw new IllegalStateException("Payment data must be provided for payment fragment!");
+
+ mPaymentData = paymentData;
+ mPurchaseController = PurchaseFactory.createBookmarkPurchaseController(mPaymentData.getProductId());
+ mPurchaseController.initialize(getActivity());
+ }
+
+ @Nullable
+ @Override
+ public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable
+ Bundle savedInstanceState)
+ {
+ View root = inflater.inflate(R.layout.fragment_bookmark_payment, container, false);
+ // TODO: temporary launch of billing flow.
+ root.findViewById(R.id.buy_inapp).setOnClickListener(v -> mPurchaseController.launchPurchaseFlow(mPaymentData.getProductId()));
+ root.findViewById(R.id.query_inapps).setOnClickListener(v -> mPurchaseController.queryPurchaseDetails());
+ root.findViewById(R.id.consume_apps).setOnClickListener(v -> {
+
+ });
+ return root;
+ }
+
+ @Override
+ public void onStart()
+ {
+ super.onStart();
+ mPurchaseController.addCallback(mPurchaseCallback);
+ }
+
+ @Override
+ public void onStop()
+ {
+ super.onStop();
+ mPurchaseController.removeCallback();
+ }
+
+ @Override
+ public void onDestroy()
+ {
+ super.onDestroy();
+ mPurchaseController.destroy();
+ }
+
+ private static class BookmarkPurchaseCallbackImpl implements BookmarkPurchaseCallback
+ {
+ // TODO: coming soon.
+ }
+}
diff --git a/android/src/com/mapswithme/maps/purchase/BookmarkPurchaseController.java b/android/src/com/mapswithme/maps/purchase/BookmarkPurchaseController.java
index e616ac6af1..54cc888ccc 100644
--- a/android/src/com/mapswithme/maps/purchase/BookmarkPurchaseController.java
+++ b/android/src/com/mapswithme/maps/purchase/BookmarkPurchaseController.java
@@ -3,26 +3,35 @@ package com.mapswithme.maps.purchase;
import android.app.Activity;
import android.support.annotation.NonNull;
+import com.android.billingclient.api.Purchase;
+import com.android.billingclient.api.SkuDetails;
+
+import java.util.List;
+
class BookmarkPurchaseController extends AbstractPurchaseController
{
+ @NonNull
+ private final PlayStoreBillingCallback mBillingCallback = new PlayStoreBillingCallbackImpl();
+
BookmarkPurchaseController(@NonNull PurchaseValidator validator,
@NonNull BillingManager billingManager,
@NonNull String... productIds)
{
- super(validator, billingManager);
- // TODO: coming soon.
+ super(validator, billingManager, productIds);
}
@Override
void onInitialize(@NonNull Activity activity)
{
+ getBillingManager().addCallback(mBillingCallback);
// TODO: coming soon.
}
@Override
void onDestroy()
{
+ getBillingManager().removeCallback(mBillingCallback);
// TODO: coming soon.
}
@@ -31,4 +40,43 @@ class BookmarkPurchaseController extends AbstractPurchaseController details)
+ {
+
+ }
+
+ @Override
+ public void onPurchaseSuccessful(@NonNull List purchases)
+ {
+ }
+
+ @Override
+ public void onPurchaseFailure(int error)
+ {
+
+ }
+
+ @Override
+ public void onPurchaseDetailsFailure()
+ {
+
+ }
+
+ @Override
+ public void onStoreConnectionFailed()
+ {
+
+ }
+
+ @Override
+ public void onPurchasesLoaded(@NonNull List purchases)
+ {
+
+ }
+ }
}