From ef8c2bf736b5eda3e7b6d6ca0faa0084ec0a03bf Mon Sep 17 00:00:00 2001 From: "r.kuznetsov" Date: Tue, 16 Oct 2018 14:26:24 +0300 Subject: [PATCH] Added start transaction method --- android/jni/com/mapswithme/maps/Framework.cpp | 48 +++++++++++++ .../src/com/mapswithme/maps/Framework.java | 11 +++ .../Core/Subscriptions/MWMPurchaseManager.mm | 3 +- map/purchase.cpp | 67 +++++++++++++++++-- map/purchase.hpp | 10 ++- 5 files changed, 130 insertions(+), 9 deletions(-) diff --git a/android/jni/com/mapswithme/maps/Framework.cpp b/android/jni/com/mapswithme/maps/Framework.cpp index 2fb8caccc4..3728101e06 100644 --- a/android/jni/com/mapswithme/maps/Framework.cpp +++ b/android/jni/com/mapswithme/maps/Framework.cpp @@ -735,6 +735,21 @@ void CallPurchaseValidationListener(shared_ptr listener, Purchase::Vali receiptData.get()); } +void CallStartPurchaseTransactionListener(shared_ptr listener, bool success, + std::string const & serverId, + std::string const & vendorId) +{ + JNIEnv * env = jni::GetEnv(); + jmethodID const methodId = jni::GetMethodID(env, *listener, "onStartTransaction", + "(ZLjava/lang/String;Ljava/lang/String;)V"); + + jni::TScopedLocalRef const serverIdStr(env, jni::ToJavaString(env, serverId)); + jni::TScopedLocalRef const vendorIdStr(env, jni::ToJavaString(env, vendorId)); + + env->CallVoidMethod(*listener, methodId, static_cast(success), + serverIdStr.get(), vendorIdStr.get()); +} + /// @name JNI EXPORTS //@{ JNIEXPORT jstring JNICALL @@ -1783,6 +1798,20 @@ Java_com_mapswithme_maps_Framework_nativeValidatePurchase(JNIEnv * env, jclass, purchase->Validate(info, frm()->GetUser().GetAccessToken()); } +JNIEXPORT void JNICALL +Java_com_mapswithme_maps_Framework_nativeStartPurchaseTransaction(JNIEnv * env, jclass, + jstring serverId, + jstring vendorId) +{ + auto const & purchase = frm()->GetPurchase(); + if (purchase == nullptr) + return; + + purchase->StartTransaction(jni::ToNativeString(env, serverId), + jni::ToNativeString(env, vendorId), + frm()->GetUser().GetAccessToken()); +} + JNIEXPORT void JNICALL Java_com_mapswithme_maps_Framework_nativeSetPurchaseValidationListener(JNIEnv *, jclass, jobject listener) @@ -1802,6 +1831,25 @@ Java_com_mapswithme_maps_Framework_nativeSetPurchaseValidationListener(JNIEnv *, } } +JNIEXPORT void JNICALL +Java_com_mapswithme_maps_Framework_nativeStartPurchaseTransactionListener(JNIEnv *, jclass, + jobject listener) +{ + auto const & purchase = frm()->GetPurchase(); + if (purchase == nullptr) + return; + + if (listener != nullptr) + { + purchase->SetStartTransactionCallback(bind(&CallStartPurchaseTransactionListener, + jni::make_global_ref(listener), _1, _2, _3)); + } + else + { + purchase->SetStartTransactionCallback(nullptr); + } +} + JNIEXPORT jboolean JNICALL Java_com_mapswithme_maps_Framework_nativeHasActiveRemoveAdsSubscription(JNIEnv *, jclass) { diff --git a/android/src/com/mapswithme/maps/Framework.java b/android/src/com/mapswithme/maps/Framework.java index 742758c0bd..8f3f17d63a 100644 --- a/android/src/com/mapswithme/maps/Framework.java +++ b/android/src/com/mapswithme/maps/Framework.java @@ -150,6 +150,12 @@ public class Framework @NonNull String vendorId, @NonNull String purchaseToken); } + @SuppressWarnings("unused") + public interface StartTransactionListener + { + void onStartTransaction(boolean success, @NonNull String serverId, @NonNull String vendorId); + } + public static class Params3dMode { public boolean enabled; @@ -479,6 +485,11 @@ public class Framework public static native void nativeMakeCrash(); + public static native void nativeStartPurchaseTransaction(@NonNull String serverId, + @NonNull String vendorId); + public static native void nativeStartPurchaseTransactionListener(@Nullable + StartTransactionListener listener); + public static native void nativeValidatePurchase(@NonNull String serverId, @NonNull String vendorId, @NonNull String purchaseData); diff --git a/iphone/Maps/Core/Subscriptions/MWMPurchaseManager.mm b/iphone/Maps/Core/Subscriptions/MWMPurchaseManager.mm index b3f746e12b..13dcdaaada 100644 --- a/iphone/Maps/Core/Subscriptions/MWMPurchaseManager.mm +++ b/iphone/Maps/Core/Subscriptions/MWMPurchaseManager.mm @@ -91,7 +91,8 @@ vi.m_receiptData = [receiptData base64EncodedStringWithOptions:0].UTF8String; vi.m_serverId = self.serverId.UTF8String; vi.m_vendorId = ADS_REMOVAL_VENDOR; - GetFramework().GetPurchase()->Validate(vi, {} /* accessToken */); + auto const accessToken = GetFramework().GetUser().GetAccessToken(); + GetFramework().GetPurchase()->Validate(vi, accessToken); } - (void)validReceipt diff --git a/map/purchase.cpp b/map/purchase.cpp index 792a897166..4f86bbfa99 100644 --- a/map/purchase.cpp +++ b/map/purchase.cpp @@ -55,6 +55,13 @@ std::string ValidationUrl() return kServerUrl + "registrar/register"; } +std::string StartTransactionUrl() +{ + if (kServerUrl.empty()) + return {}; + return kServerUrl + "registrar/start_transaction"; +} + struct ReceiptData { ReceiptData(std::string const & data, std::string const & type) @@ -121,6 +128,12 @@ void Purchase::SetValidationCallback(ValidationCallback && callback) m_validationCallback = std::move(callback); } +void Purchase::SetStartTransactionCallback(StartTransactionCallback && callback) +{ + CHECK_THREAD_CHECKER(m_threadChecker, ()); + m_startTransactionCallback = std::move(callback); +} + bool Purchase::IsSubscriptionActive(SubscriptionType type) const { switch (type) @@ -170,12 +183,39 @@ void Purchase::Validate(ValidationInfo const & validationInfo, std::string const GetPlatform().RunTask(Platform::Thread::Network, [this, url, validationInfo, accessToken]() { - ValidateImpl(url, validationInfo, accessToken, 0 /* attemptIndex */, kFirstWaitingTimeInSec); + ValidateImpl(url, validationInfo, accessToken, false /* startTransaction */, + 0 /* attemptIndex */, kFirstWaitingTimeInSec); + }); +} + +void Purchase::StartTransaction(std::string const & serverId, std::string const & vendorId, + std::string const & accessToken) +{ + CHECK_THREAD_CHECKER(m_threadChecker, ()); + + ValidationInfo info; + info.m_serverId = serverId; + info.m_vendorId = vendorId; + + std::string const url = StartTransactionUrl(); + auto const status = GetPlatform().ConnectionStatus(); + if (url.empty() || status == Platform::EConnectionType::CONNECTION_NONE) + { + if (m_startTransactionCallback) + m_startTransactionCallback(false /* success */, serverId, vendorId); + return; + } + + GetPlatform().RunTask(Platform::Thread::Network, [this, url, info, accessToken]() + { + ValidateImpl(url, info, accessToken, true /* startTransaction */, + 0 /* attemptIndex */, kFirstWaitingTimeInSec); }); } void Purchase::ValidateImpl(std::string const & url, ValidationInfo const & validationInfo, - std::string const & accessToken, uint8_t attemptIndex, uint32_t waitingTimeInSeconds) + std::string const & accessToken, bool startTransaction, + uint8_t attemptIndex, uint32_t waitingTimeInSeconds) { platform::HttpClient request(url); request.SetRawHeader("Accept", "application/json"); @@ -232,17 +272,30 @@ void Purchase::ValidateImpl(std::string const & url, ValidationInfo const & vali ++attemptIndex; waitingTimeInSeconds *= kWaitingTimeScaleFactor; GetPlatform().RunDelayedTask(Platform::Thread::Network, delayTime, - [this, url, validationInfo, accessToken, attemptIndex, waitingTimeInSeconds]() + [this, url, validationInfo, accessToken, startTransaction, + attemptIndex, waitingTimeInSeconds]() { - ValidateImpl(url, validationInfo, accessToken, attemptIndex, waitingTimeInSeconds); + ValidateImpl(url, validationInfo, accessToken, startTransaction, + attemptIndex, waitingTimeInSeconds); }); } else { - GetPlatform().RunTask(Platform::Thread::Gui, [this, code, validationInfo]() + GetPlatform().RunTask(Platform::Thread::Gui, [this, code, startTransaction, validationInfo]() { - if (m_validationCallback) - m_validationCallback(code, validationInfo); + if (startTransaction) + { + if (m_startTransactionCallback) + { + m_startTransactionCallback(code == ValidationCode::Verified /* success */, + validationInfo.m_serverId, validationInfo.m_vendorId); + } + } + else + { + if (m_validationCallback) + m_validationCallback(code, validationInfo); + } }); } } diff --git a/map/purchase.hpp b/map/purchase.hpp index 1d31ef5614..b7e94e10b0 100644 --- a/map/purchase.hpp +++ b/map/purchase.hpp @@ -46,13 +46,20 @@ public: }; using ValidationCallback = std::function; + using StartTransactionCallback = std::function; void SetValidationCallback(ValidationCallback && callback); void Validate(ValidationInfo const & validationInfo, std::string const & accessToken); + void SetStartTransactionCallback(StartTransactionCallback && callback); + void StartTransaction(std::string const & serverId, std::string const & vendorId, + std::string const & accessToken); + private: void ValidateImpl(std::string const & url, ValidationInfo const & validationInfo, - std::string const & accessToken, uint8_t attemptIndex, uint32_t waitingTimeInSeconds); + std::string const & accessToken, bool startTransaction, + uint8_t attemptIndex, uint32_t waitingTimeInSeconds); struct RemoveAdsSubscriptionData { @@ -64,6 +71,7 @@ private: std::vector m_listeners; ValidationCallback m_validationCallback; + StartTransactionCallback m_startTransactionCallback; ThreadChecker m_threadChecker; };