[android] Implemented JNI for getting/posting UGCUpdate object

This commit is contained in:
Александр Зацепин 2017-10-06 13:58:34 +03:00 committed by Arsentiy Milchakov
parent fa55fcec30
commit cba112f8e7
8 changed files with 151 additions and 19 deletions

View file

@ -588,6 +588,11 @@ void Framework::RequestUGC(FeatureID const & fid, ugc::Api::UGCCallback const &
m_work.GetUGCApi()->GetUGC(fid, ugcCallback);
}
void Framework::SetUGCUpdate(FeatureID const & fid, ugc::UGCUpdate const & ugc)
{
m_work.GetUGCApi()->SetUGCUpdate(fid, ugc);
}
uint64_t Framework::GetRentNearby(JNIEnv * env, jobject policy, ms::LatLon const & latlon,
cian::Api::RentNearbyCallback const & onSuccess,
cian::Api::ErrorCallback const & onError)

View file

@ -201,6 +201,7 @@ namespace android
viator::GetTop5ProductsCallback const & callback);
void RequestUGC(FeatureID const & fid, ugc::Api::UGCCallback const & ugcCallback);
void SetUGCUpdate(FeatureID const & fid, ugc::UGCUpdate const & ugc);
uint64_t GetRentNearby(JNIEnv * env, jobject policy, ms::LatLon const & latlon,
cian::Api::RentNearbyCallback const & onSuccess,

View file

@ -57,11 +57,38 @@ private:
class JavaBridge
{
public:
void OnResult(JNIEnv * env, ugc::UGC const & ugc)
void OnResult(JNIEnv * env, ugc::UGC const & ugc, ugc::UGCUpdate const & ugcUpdate)
{
Init(env);
jni::TScopedLocalRef result(env, ToJavaUGC(env, ugc));
env->CallStaticVoidMethod(m_ugcClass, m_onResult, result.get());
jni::TScopedLocalRef ugcResult(env, ToJavaUGC(env, ugc));
jni::TScopedLocalRef ugcUpdateResult(env, ToJavaUGCUpdate(env, ugcUpdate));
env->CallStaticVoidMethod(m_ugcClass, m_onResult, ugcResult.get(), ugcUpdateResult.get());
}
ugc::UGCUpdate ToNativeUGCUpdate(JNIEnv * env, jobject ugcUpdate)
{
Init(env);
jobjectArray jratings = static_cast<jobjectArray>(env->GetObjectField(ugcUpdate, m_ratingArrayFieldId));
int const length = env->GetArrayLength(jratings);
std::vector<ugc::RatingRecord> records(length);
for (int i = 0; i < length; i++)
{
jobject jrating = env->GetObjectArrayElement(jratings, i);
jstring name = static_cast<jstring>(env->GetObjectField(jrating, m_ratingNameFieldId));
ugc::TranslationKey key(jni::ToNativeString(env, name));
jfloat value = env->GetFloatField(jrating, m_ratingValueFieldId);
auto const ratingValue = static_cast<float>(value);
ugc::RatingRecord record(key, ratingValue);
records.push_back(record);
}
jstring jtext = static_cast<jstring>(env->GetObjectField(ugcUpdate, m_ratingTextFieldId));
// TODO: use lang parameter correctly.
ugc::Text text(jni::ToNativeString(env, jtext), 1);
return ugc::UGCUpdate(records, text, std::chrono::system_clock::now());
}
private:
@ -76,6 +103,16 @@ private:
return result;
}
jobject ToJavaUGCUpdate(JNIEnv * env, ugc::UGCUpdate const & ugcUpdate)
{
jni::TScopedLocalObjectArrayRef ratings(env, ToJavaRatings(env, ugcUpdate.m_ratings));
jni::TScopedLocalRef text(env, jni::ToJavaString(env, ugcUpdate.m_text.m_text));
jobject result = env->NewObject(m_ugcUpdateClass, m_ugcUpdateCtor, ratings.get(), text.get());
ASSERT(result, ());
return result;
}
jobjectArray ToJavaRatings(JNIEnv * env, std::vector<ugc::RatingRecord> const & ratings)
{
size_t const n = ratings.size();
@ -128,7 +165,7 @@ private:
env, m_ugcClass,
"([Lcom/mapswithme/maps/ugc/UGC$Rating;F[Lcom/mapswithme/maps/ugc/UGC$Review;)V");
m_onResult = jni::GetStaticMethodID(env, m_ugcClass, "onUGCReceived",
"(Lcom/mapswithme/maps/ugc/UGC;)V");
"(Lcom/mapswithme/maps/ugc/UGC;Lcom/mapswithme/maps/ugc/UGCUpdate;)V");
m_ratingClass = jni::GetGlobalClassRef(env, "com/mapswithme/maps/ugc/UGC$Rating");
m_ratingCtor = jni::GetConstructorID(env, m_ratingClass, "(Ljava/lang/String;F)V");
@ -137,6 +174,13 @@ private:
m_reviewCtor =
jni::GetConstructorID(env, m_reviewClass, "(Ljava/lang/String;Ljava/lang/String;J)V");
m_ugcUpdateClass = jni::GetGlobalClassRef(env, "com/mapswithme/maps/ugc/UGCUpdate");
m_ugcUpdateCtor = jni::GetConstructorID(
env, m_ugcUpdateClass, "([Lcom/mapswithme/maps/ugc/UGC$Rating;Ljava/lang/String;)V");
m_ratingArrayFieldId = env->GetFieldID(m_ugcUpdateClass, "mRatings", "[Lcom/mapswithme/maps/ugc/UGC$Rating;");
m_ratingTextFieldId = env->GetFieldID(m_ugcUpdateClass, "mText", "Ljava/lang/String;");
m_ratingNameFieldId = env->GetFieldID(m_ratingClass, "mName", "Ljava/lang/String;");
m_ratingValueFieldId = env->GetFieldID(m_ratingClass, "mValue", "F");
m_initialized = true;
}
@ -144,6 +188,14 @@ private:
jclass m_ugcClass;
jmethodID m_ugcCtor;
jclass m_ugcUpdateClass;
jmethodID m_ugcUpdateCtor;
jfieldID m_ratingArrayFieldId;
jfieldID m_ratingTextFieldId;
jfieldID m_ratingNameFieldId;
jfieldID m_ratingValueFieldId;
jmethodID m_onResult;
jclass m_ratingClass;
@ -155,13 +207,23 @@ private:
} // namespace
extern "C" {
JNIEXPORT void JNICALL Java_com_mapswithme_maps_ugc_UGC_requestUGC(JNIEnv * env, jclass /* clazz */,
JNIEXPORT
void JNICALL Java_com_mapswithme_maps_ugc_UGC_requestUGC(JNIEnv * env, jclass /* clazz */,
jobject featureId)
{
auto const fid = g_builder.Build(env, featureId);
g_framework->RequestUGC(fid, [&](ugc::UGC const & ugc, ugc::UGCUpdate const & update) {
JNIEnv * e = jni::GetEnv();
g_bridge.OnResult(e, ugc);
g_bridge.OnResult(e, ugc, update);
});
}
JNIEXPORT
void JNICALL Java_com_mapswithme_maps_ugc_UGC_setUGCUpdate(JNIEnv * env, jclass /* clazz */,
jobject featureId, jobject ugcUpdate)
{
auto const fid = g_builder.Build(env, featureId);
ugc::UGCUpdate update = g_bridge.ToNativeUGCUpdate(env, ugcUpdate);
g_framework->SetUGCUpdate(fid, update);
}
}

View file

@ -79,12 +79,14 @@ public class UGC implements Serializable
mListener = listener;
}
public static native void requestUGC(FeatureId fid);
public static native void requestUGC(@NonNull FeatureId fid);
public static void onUGCReceived(@NonNull UGC ugc)
public static native void setUGCUpdate(@NonNull FeatureId fid, UGCUpdate update);
public static void onUGCReceived(@NonNull UGC ugc, @NonNull UGCUpdate ugcUpdate)
{
if (mListener != null)
mListener.onUGCReceived(ugc);
mListener.onUGCReceived(ugc, ugcUpdate);
}
public static class Rating implements Serializable
@ -151,6 +153,6 @@ public class UGC implements Serializable
public interface UGCListener
{
void onUGCReceived(@NonNull UGC ugc);
void onUGCReceived(@NonNull UGC ugc, @NonNull UGCUpdate ugcUpdate);
}
}

View file

@ -49,7 +49,7 @@ public class UGCController implements View.OnClickListener, UGC.UGCListener
return;
UGCEditorActivity.start((Activity) mPlacePage.getContext(), mMapObject.getTitle(),
mMapObject.getFeatureId().getFeatureIndex(),
mMapObject.getFeatureId(),
mUgc, UGC.RATING_HORRIBLE);
}
};
@ -58,6 +58,8 @@ public class UGCController implements View.OnClickListener, UGC.UGCListener
private MapObject mMapObject;
@Nullable
private UGC mUgc;
@Nullable
private UGCUpdate mUGCUpdate;
public UGCController(@NonNull final PlacePageView placePage)
{
@ -167,9 +169,10 @@ public class UGCController implements View.OnClickListener, UGC.UGCListener
}
@Override
public void onUGCReceived(@NonNull UGC ugc)
public void onUGCReceived(@NonNull UGC ugc, @NonNull UGCUpdate ugcUpdate)
{
mUgc = ugc;
mUGCUpdate = ugcUpdate;
if (ugc.getReviews() != null)
mUGCReviewAdapter.setItems(ugc.getReviews());
mUGCRatingRecordsAdapter.setItems(ugc.getRatings());
@ -184,7 +187,7 @@ public class UGCController implements View.OnClickListener, UGC.UGCListener
return;
UGCEditorActivity.start((Activity) mPlacePage.getContext(), mMapObject.getTitle(),
mMapObject.getFeatureId().getFeatureIndex(),
mMapObject.getFeatureId(),
mUgc, rating);
}
}

View file

@ -7,20 +7,21 @@ import android.support.annotation.StyleRes;
import android.support.v4.app.Fragment;
import com.mapswithme.maps.base.BaseMwmFragmentActivity;
import com.mapswithme.maps.bookmarks.data.FeatureId;
import com.mapswithme.util.ThemeUtils;
public class UGCEditorActivity extends BaseMwmFragmentActivity
{
private static final String EXTRA_FEATURE_INDEX = "extra_feature_index";
static final String EXTRA_FEATURE_ID = "extra_feautre_id";
static final String EXTRA_UGC = "extra_ugc";
static final String EXTRA_TITLE = "extra_title";
static final String EXTRA_AVG_RATING = "extra_avg_rating";
public static void start(@NonNull Activity activity, @NonNull String title,
int featureIndex, @NonNull UGC ugc, @UGC.UGCRating int rating)
@NonNull FeatureId featureId, @NonNull UGC ugc, @UGC.UGCRating int rating)
{
final Intent i = new Intent(activity, UGCEditorActivity.class);
i.putExtra(EXTRA_FEATURE_INDEX, featureIndex);
i.putExtra(EXTRA_FEATURE_ID, featureId);
i.putExtra(EXTRA_UGC, ugc);
i.putExtra(EXTRA_TITLE, title);
i.putExtra(EXTRA_AVG_RATING, rating);

View file

@ -12,6 +12,7 @@ import android.view.ViewGroup;
import com.mapswithme.maps.R;
import com.mapswithme.maps.auth.BaseMwmAuthorizationFragment;
import com.mapswithme.maps.bookmarks.data.FeatureId;
import com.mapswithme.util.log.Logger;
import com.mapswithme.util.log.LoggerFactory;
@ -24,6 +25,8 @@ public class UGCEditorFragment extends BaseMwmAuthorizationFragment
private static final String TAG = UGCEditorFragment.class.getSimpleName();
@NonNull
private final UGCRatingAdapter mUGCRatingAdapter = new UGCRatingAdapter();
//TODO: field just for testing.
private List<UGC.Rating> mRatings;
@Nullable
@Override
@ -40,10 +43,10 @@ public class UGCEditorFragment extends BaseMwmAuthorizationFragment
//TODO: use parcelable instead of serializable
Intent intent = getActivity().getIntent();
UGC ugc = (UGC) intent.getSerializableExtra(UGCEditorActivity.EXTRA_UGC);
List<UGC.Rating> avgRatings = new ArrayList<>(ugc.getRatings());
for (UGC.Rating rating: avgRatings)
mRatings = new ArrayList<>(ugc.getRatings());
for (UGC.Rating rating: mRatings)
rating.setValue(getActivity().getIntent().getIntExtra(UGCEditorActivity.EXTRA_AVG_RATING, 3));
mUGCRatingAdapter.setItems(avgRatings);
mUGCRatingAdapter.setItems(mRatings);
return root;
}
@ -56,6 +59,18 @@ public class UGCEditorFragment extends BaseMwmAuthorizationFragment
mToolbarController.setTitle(intent.getStringExtra(UGCEditorActivity.EXTRA_TITLE));
}
@Override
protected void onSubmitButtonClick()
{
super.onSubmitButtonClick();
UGC.Rating[] ratings = new UGC.Rating[mRatings.size()];
for (int i = 0; i < ratings.length; i++)
ratings[i] = mRatings.get(i);
//TODO: just for testing
UGCUpdate update = new UGCUpdate(ratings, "Test text");
UGC.setUGCUpdate((FeatureId) getActivity().getIntent().getParcelableExtra(UGCEditorActivity.EXTRA_FEATURE_ID), update);
}
@Override
protected void onPreSocialAuthentication()
{

View file

@ -0,0 +1,43 @@
package com.mapswithme.maps.ugc;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.annotation.Nullable;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class UGCUpdate
{
@Nullable
private final UGC.Rating[] mRatings;
@Nullable
private String mText;
public UGCUpdate(@Nullable UGC.Rating[] ratings, @Nullable String text)
{
mRatings = ratings;
mText = text;
}
public void setText(@Nullable String text)
{
mText = text;
}
@Nullable
public String getText()
{
return mText;
}
@Nullable
public List<UGC.Rating> getRatings()
{
if (mRatings == null)
return null;
return Collections.synchronizedList(Arrays.asList(mRatings));
}
}