forked from organicmaps/organicmaps-tmp
Added local experts JNI
This commit is contained in:
parent
0241aedd3d
commit
500cefe59f
7 changed files with 251 additions and 33 deletions
|
@ -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 \
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
54
android/src/com/mapswithme/maps/locals/Locals.java
Normal file
54
android/src/com/mapswithme/maps/locals/Locals.java
Normal file
|
@ -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);
|
||||
}
|
||||
}
|
48
android/src/com/mapswithme/maps/locals/LocalsError.java
Normal file
48
android/src/com/mapswithme/maps/locals/LocalsError.java
Normal file
|
@ -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 +
|
||||
'}';
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue