Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorr.kuznetsov <r.kuznetsov@corp.mail.ru>2017-10-24 15:56:56 +0300
committerAleksandr Zatsepin <alexzatsepin@users.noreply.github.com>2017-10-27 11:41:32 +0300
commit500cefe59f84c34318852ac031b46a9a410843db (patch)
treec86b69973c7d8ec3d1de3c4357f8cd47cbb8e046
parent0241aedd3db94379d1b2327606b96971e4de3046 (diff)
Added local experts JNI
-rw-r--r--android/jni/Android.mk1
-rw-r--r--android/jni/com/mapswithme/maps/Framework.cpp14
-rw-r--r--android/jni/com/mapswithme/maps/Framework.hpp6
-rw-r--r--android/jni/com/mapswithme/maps/locals/Locals.cpp106
-rw-r--r--android/src/com/mapswithme/maps/locals/LocalExpert.java55
-rw-r--r--android/src/com/mapswithme/maps/locals/Locals.java54
-rw-r--r--android/src/com/mapswithme/maps/locals/LocalsError.java48
7 files changed, 251 insertions, 33 deletions
diff --git a/android/jni/Android.mk b/android/jni/Android.mk
index 9c3b704346..5a11f9dcb4 100644
--- a/android/jni/Android.mk
+++ b/android/jni/Android.mk
@@ -87,6 +87,7 @@ LOCAL_SRC_FILES := \
com/mapswithme/maps/editor/Editor.cpp \
com/mapswithme/maps/editor/OsmOAuth.cpp \
com/mapswithme/maps/Framework.cpp \
+ com/mapswithme/maps/locals/Locals.cpp \
com/mapswithme/maps/LocationState.cpp \
com/mapswithme/maps/LocationHelper.cpp \
com/mapswithme/maps/MapFragment.cpp \
diff --git a/android/jni/com/mapswithme/maps/Framework.cpp b/android/jni/com/mapswithme/maps/Framework.cpp
index 949eed4c19..ee4b435834 100644
--- a/android/jni/com/mapswithme/maps/Framework.cpp
+++ b/android/jni/com/mapswithme/maps/Framework.cpp
@@ -614,6 +614,20 @@ int Framework::ToDoAfterUpdate() const
return (int) m_work.ToDoAfterUpdate();
}
+uint64_t Framework::GetLocals(JNIEnv * env, jobject policy, double lat, double lon,
+ locals::LocalsSuccessCallback const & successFn,
+ locals::LocalsErrorCallback const & errorFn)
+{
+ auto api = NativeFramework()->GetLocalsApi(ToNativeNetworkPolicy(env, policy));
+ if (api == nullptr)
+ return 0;
+
+ std::string const langStr = languages::GetCurrentNorm();
+ size_t constexpr kResultsOnPage = 5;
+ size_t constexpr kPageNumber = 1;
+ return api->GetLocals(lat, lon, langStr, kResultsOnPage, kPageNumber, successFn, errorFn);
+}
+
void Framework::LogLocalAdsEvent(local_ads::EventType type, double lat, double lon, uint16_t accuracy)
{
auto const & info = g_framework->GetPlacePageInfo();
diff --git a/android/jni/com/mapswithme/maps/Framework.hpp b/android/jni/com/mapswithme/maps/Framework.hpp
index 96b1edd510..f4cd96dc0b 100644
--- a/android/jni/com/mapswithme/maps/Framework.hpp
+++ b/android/jni/com/mapswithme/maps/Framework.hpp
@@ -16,6 +16,8 @@
#include "local_ads/event.hpp"
+#include "partners_api/locals_api.hpp"
+
#include "platform/country_defines.hpp"
#include "platform/location.hpp"
@@ -210,6 +212,10 @@ namespace android
int ToDoAfterUpdate() const;
+ uint64_t GetLocals(JNIEnv * env, jobject policy, double lat, double lon,
+ locals::LocalsSuccessCallback const & successFn,
+ locals::LocalsErrorCallback const & errorFn);
+
void LogLocalAdsEvent(local_ads::EventType event, double lat, double lon, uint16_t accuracy);
};
}
diff --git a/android/jni/com/mapswithme/maps/locals/Locals.cpp b/android/jni/com/mapswithme/maps/locals/Locals.cpp
index 44385223ff..e99f5aa3c0 100644
--- a/android/jni/com/mapswithme/maps/locals/Locals.cpp
+++ b/android/jni/com/mapswithme/maps/locals/Locals.cpp
@@ -1,32 +1,116 @@
+#include "android/jni/com/mapswithme/core/jni_helper.hpp"
#include "android/jni/com/mapswithme/maps/Framework.hpp"
-#include "android/jni/com/mapswithme/core/jni_helper.hpp"
-#include "partners_api/locals_api.hpp"
+#include <string>
+#include <vector>
namespace
{
+jclass g_localsClass = nullptr;
+jobject g_localsInstance;
+jmethodID g_onLocalsReceivedMethod;
+jmethodID g_onLocalsErrorReceivedMethod;
jclass g_localExpertClass;
jmethodID g_localExpertConstructor;
+jclass g_localErrorClass;
+jmethodID g_localErrorConstructor;
+uint64_t g_lastRequestId = 0;
void PrepareClassRefs(JNIEnv * env)
{
- if (g_localExpertClass)
+ if (g_localsClass != nullptr)
return;
-@NonNull int id,
-@NotNull String name,
-@NotNull String country,
-@NotNull String city,
-double rating, int reviewCount, @NonNull double price
- @NonNull String currency, String motto, String about,
- @NonNull String offer, @NonNull String pageUrl, @NonNull String photoUrl
+ g_localsClass = jni::GetGlobalClassRef(env, "com/mapswithme/maps/locals/Locals");
+ static jfieldID const localsInstanceField = jni::GetStaticFieldID(env, g_localsClass, "INSTANCE",
+ "Lcom/mapswithme/maps/locals/Locals;");
+ g_localsInstance = env->GetStaticObjectField(g_localsClass, localsInstanceField);
+ g_onLocalsReceivedMethod = jni::GetMethodID(env, g_localsInstance, "onLocalsReceived",
+ "([Lcom/mapswithme/maps/locals/LocalExpert;)V");
+ g_onLocalsErrorReceivedMethod = jni::GetMethodID(env, g_localsInstance,
+ "onLocalsErrorReceived",
+ "(Lcom/mapswithme/maps/locals/LocalsError;)V");
+ // int id, @NonNull String name, @NonNull String country,
+ // @NonNull String city, double rating, int reviewCount,
+ // double price, @NonNull String currency, @NonNull String motto,
+ // @NonNull String about, @NonNull String offer, @NonNull String pageUrl,
+ // @NonNull String photoUrl
g_localExpertClass = jni::GetGlobalClassRef(env, "com/mapswithme/maps/locals/LocalExpert");
g_localExpertConstructor =
- jni::GetConstructorID(env, g_viatorProductClass,
+ jni::GetConstructorID(env, g_localExpertClass,
"(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;DID"
"Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;"
"Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
+
+ // @ErrorCode int code, @NonNull String message
+ g_localErrorClass = jni::GetGlobalClassRef(env, "com/mapswithme/maps/locals/LocalError");
+ g_localErrorConstructor = jni::GetConstructorID(env, g_localErrorClass,
+ "(ILjava/lang/String;)V");
+}
+
+void OnLocalsSuccess(uint64_t requestId, std::vector<locals::LocalExpert> const & locals,
+ size_t pageNumber, size_t countPerPage, bool hasPreviousPage,
+ bool hasNextPage)
+{
+ if (g_lastRequestId != requestId)
+ return;
+
+ JNIEnv * env = jni::GetEnv();
+
+ auto const localExpertBuilder = [](JNIEnv * env, locals::LocalExpert const & expert)
+ {
+ jni::TScopedLocalRef jName(env, jni::ToJavaString(env, expert.m_name));
+ jni::TScopedLocalRef jCountry(env, jni::ToJavaString(env, expert.m_country));
+ jni::TScopedLocalRef jCity(env, jni::ToJavaString(env, expert.m_city));
+ jni::TScopedLocalRef jCurrency(env, jni::ToJavaString(env, expert.m_currency));
+ jni::TScopedLocalRef jMotto(env, jni::ToJavaString(env, expert.m_motto));
+ jni::TScopedLocalRef jAboutExpert(env, jni::ToJavaString(env, expert.m_aboutExpert));
+ jni::TScopedLocalRef jOfferDescription(env, jni::ToJavaString(env, expert.m_offerDescription));
+ jni::TScopedLocalRef jPageUrl(env, jni::ToJavaString(env, expert.m_pageUrl));
+ jni::TScopedLocalRef jPhotoUrl(env, jni::ToJavaString(env, expert.m_photoUrl));
+
+ return env->NewObject(g_localExpertClass, g_localExpertConstructor,
+ expert.m_id, jName.get(), jCountry.get(), jCity.get(),
+ expert.m_rating, expert.m_reviewCount, expert.m_pricePerHour,
+ jCurrency.get(), jMotto.get(), jAboutExpert.get(),
+ jOfferDescription.get(), jPageUrl.get(), jPhotoUrl.get());
+ };
+
+ jni::TScopedLocalObjectArrayRef jLocals(env, jni::ToJavaArray(env, g_localExpertClass, locals,
+ localExpertBuilder));
+
+ env->CallVoidMethod(g_localsInstance, g_onLocalsReceivedMethod, jLocals.get());
+
+ jni::HandleJavaException(env);
}
+void OnLocalsError(uint64_t requestId, int errorCode, std::string const & errorMessage)
+{
+ if (g_lastRequestId != requestId)
+ return;
+
+ JNIEnv * env = jni::GetEnv();
+
+ jni::TScopedLocalRef errorStr(env, jni::ToJavaString(env, errorMessage));
+ jni::TScopedLocalRef errorObj(env, env->NewObject(g_localErrorClass, g_localErrorConstructor,
+ errorCode, errorStr.get()));
+
+ env->CallVoidMethod(g_localsInstance, g_onLocalsErrorReceivedMethod, errorObj.get());
+
+ jni::HandleJavaException(env);
+}
} // namespace
+
+extern "C" {
+
+JNIEXPORT void JNICALL
+Java_com_mapswithme_maps_locals_Locals_nativeRequestLocals(JNIEnv * env, jclass clazz,
+ jobject policy, jdouble lat,
+ jdouble lon)
+{
+ PrepareClassRefs(env);
+ g_lastRequestId = g_framework->GetLocals(env, policy, lat, lon, &OnLocalsSuccess,
+ &OnLocalsError);
+}
+} // extern "C"
diff --git a/android/src/com/mapswithme/maps/locals/LocalExpert.java b/android/src/com/mapswithme/maps/locals/LocalExpert.java
index bf2eed64f4..964d095352 100644
--- a/android/src/com/mapswithme/maps/locals/LocalExpert.java
+++ b/android/src/com/mapswithme/maps/locals/LocalExpert.java
@@ -5,7 +5,7 @@ import android.os.Parcelable;
import android.support.annotation.NonNull;
-public final class LocalExpert implements Parcelable
+final class LocalExpert implements Parcelable
{
private final int mId;
@NonNull
@@ -104,10 +104,7 @@ public final class LocalExpert implements Parcelable
}
@Override
- public int describeContents()
- {
- return 0;
- }
+ public int describeContents() { return 0; }
int getId() { return mId; }
@@ -122,15 +119,9 @@ public final class LocalExpert implements Parcelable
double getRating() { return mRating; }
- int getReviewCount()
- {
- return mReviewCount;
- }
+ int getReviewCount() { return mReviewCount; }
- double getPrice()
- {
- return mPrice;
- }
+ double getPrice() { return mPrice; }
@NonNull
String getCurrency() { return mCurrency; }
@@ -145,10 +136,7 @@ public final class LocalExpert implements Parcelable
String getOfferDescription() { return mOfferDescription; }
@NonNull
- String getPageUrl()
- {
- return mPageUrl;
- }
+ String getPageUrl() { return mPageUrl;}
@NonNull
String getPhotoUrl() { return mPhotoUrl; }
@@ -162,17 +150,40 @@ public final class LocalExpert implements Parcelable
LocalExpert that = (LocalExpert) o;
if (mId != that.mId) return false;
- if (!mName.equals(that.mName)) return false;
- if (!mCountry.equals(that.mCountry)) return false;
- if (!mCity.equals(that.mCity)) return false;
if (Double.compare(that.mRating, mRating) != 0) return false;
if (mReviewCount != that.mReviewCount) return false;
if (Double.compare(that.mPrice, mPrice) != 0) return false;
+ if (!mName.equals(that.mName)) return false;
+ if (!mCountry.equals(that.mCountry)) return false;
+ if (!mCity.equals(that.mCity)) return false;
if (!mCurrency.equals(that.mCurrency)) return false;
if (!mMotto.equals(that.mMotto)) return false;
if (!mAboutExpert.equals(that.mAboutExpert)) return false;
if (!mOfferDescription.equals(that.mOfferDescription)) return false;
- if (!mPhotoUrl.equals(that.mPhotoUrl)) return false;
- return mPageUrl.equals(that.mPageUrl);
+ if (!mPageUrl.equals(that.mPageUrl)) return false;
+ return mPhotoUrl.equals(that.mPhotoUrl);
+ }
+
+ @Override
+ public int hashCode()
+ {
+ int result;
+ long temp;
+ result = mId;
+ result = 31 * result + mName.hashCode();
+ result = 31 * result + mCountry.hashCode();
+ result = 31 * result + mCity.hashCode();
+ temp = Double.doubleToLongBits(mRating);
+ result = 31 * result + (int) (temp ^ (temp >>> 32));
+ result = 31 * result + mReviewCount;
+ temp = Double.doubleToLongBits(mPrice);
+ result = 31 * result + (int) (temp ^ (temp >>> 32));
+ result = 31 * result + mCurrency.hashCode();
+ result = 31 * result + mMotto.hashCode();
+ result = 31 * result + mAboutExpert.hashCode();
+ result = 31 * result + mOfferDescription.hashCode();
+ result = 31 * result + mPageUrl.hashCode();
+ result = 31 * result + mPhotoUrl.hashCode();
+ return result;
}
}
diff --git a/android/src/com/mapswithme/maps/locals/Locals.java b/android/src/com/mapswithme/maps/locals/Locals.java
new file mode 100644
index 0000000000..f14075e4da
--- /dev/null
+++ b/android/src/com/mapswithme/maps/locals/Locals.java
@@ -0,0 +1,54 @@
+package com.mapswithme.maps.locals;
+
+import android.support.annotation.MainThread;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+
+import com.mapswithme.util.NetworkPolicy;
+import com.mapswithme.util.concurrency.UiThread;
+
+final class Locals
+{
+ public static final Locals INSTANCE = new Locals();
+
+ @Nullable
+ private LocalsListener mListener;
+
+ private Locals() {}
+
+ public void setLocalsListener(@Nullable LocalsListener listener)
+ {
+ mListener = listener;
+ }
+
+ public native void nativeRequestLocals(@NonNull NetworkPolicy policy,
+ double lat, double lon);
+
+ // Called from JNI.
+ @MainThread
+ void onLocalsReceived(@NonNull LocalExpert[] experts)
+ {
+ if (!UiThread.currentThreadIsUi())
+ throw new AssertionError("Must be called from UI thread!");
+
+ if (mListener != null)
+ mListener.onLocalsReceived(experts);
+ }
+
+ // Called from JNI.
+ @MainThread
+ void onLocalsErrorReceived(@NonNull LocalsError error)
+ {
+ if (!UiThread.currentThreadIsUi())
+ throw new AssertionError("Must be called from UI thread!");
+
+ if (mListener != null)
+ mListener.onLocalsErrorReceived(error);
+ }
+
+ public interface LocalsListener
+ {
+ void onLocalsReceived(@NonNull LocalExpert[] experts);
+ void onLocalsErrorReceived(@NonNull LocalsError error);
+ }
+}
diff --git a/android/src/com/mapswithme/maps/locals/LocalsError.java b/android/src/com/mapswithme/maps/locals/LocalsError.java
new file mode 100644
index 0000000000..0ac4f08d24
--- /dev/null
+++ b/android/src/com/mapswithme/maps/locals/LocalsError.java
@@ -0,0 +1,48 @@
+package com.mapswithme.maps.locals;
+
+import android.support.annotation.IntDef;
+import android.support.annotation.NonNull;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+class LocalsError
+{
+ static final int UNKNOWN_ERROR = 0;
+
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({ UNKNOWN_ERROR })
+ @interface ErrorCode {}
+
+ @ErrorCode
+ private final int mCode;
+ @NonNull
+ private final String mMessage;
+
+ public LocalsError(@ErrorCode int code, @NonNull String message)
+ {
+ mCode = code;
+ mMessage = message;
+ }
+
+ @ErrorCode
+ public int getCode()
+ {
+ return mCode;
+ }
+
+ @NonNull
+ public String getMessage()
+ {
+ return mMessage;
+ }
+
+ @Override
+ public String toString()
+ {
+ return "LocalsError{" +
+ "mCode=" + mCode +
+ ", mMessage=" + mMessage +
+ '}';
+ }
+}