diff options
author | Konstantin Käfer <mail@kkaefer.com> | 2017-04-12 18:23:42 +0200 |
---|---|---|
committer | Konstantin Käfer <mail@kkaefer.com> | 2017-04-25 17:56:46 +0200 |
commit | 52e71bbd1a66729afb634c15401528e8fa674e70 (patch) | |
tree | e0a8aa3531ec80af54c5fb414295d9f6f7339fa1 | |
parent | ea8ec38df156c6683c886253dbb1f6bc828686ff (diff) | |
download | qtlocation-mapboxgl-52e71bbd1a66729afb634c15401528e8fa674e70.tar.gz |
[android] move java/lang/* and java/util/* to high level jni.hpp
38 files changed, 396 insertions, 304 deletions
diff --git a/platform/android/config.cmake b/platform/android/config.cmake index 7c10ba96f8..0e1bd5ffe6 100644 --- a/platform/android/config.cmake +++ b/platform/android/config.cmake @@ -180,7 +180,7 @@ add_library(mbgl-android STATIC platform/android/src/native_map_view.hpp # Java core classes - platform/android/src/java/util.cpp + platform/android/src/java/lang.hpp platform/android/src/java/util.hpp # Graphics @@ -250,10 +250,11 @@ add_library(mbgl-android STATIC platform/android/src/offline/offline_region_status.hpp # Main jni bindings + platform/android/src/jni/binding.cpp + platform/android/src/jni/binding.hpp platform/android/src/attach_env.cpp platform/android/src/attach_env.hpp - platform/android/src/java_types.cpp - platform/android/src/java_types.hpp + platform/android/src/java/lang.hpp # Main entry point platform/android/src/jni.hpp diff --git a/platform/android/src/annotation/multi_point.hpp b/platform/android/src/annotation/multi_point.hpp index e1152dfd60..0f68ed3892 100644 --- a/platform/android/src/annotation/multi_point.hpp +++ b/platform/android/src/annotation/multi_point.hpp @@ -4,6 +4,7 @@ #include <jni/jni.hpp> #include "../geometry/lat_lng.hpp" +#include "../java/lang.hpp" #include "../java/util.hpp" namespace mbgl { @@ -14,9 +15,10 @@ class MultiPoint : protected mbgl::util::noncopyable { protected: template <class Geometry> - static Geometry toGeometry(JNIEnv& env, jni::Object<java::util::List> pointsList) { + static Geometry toGeometry(JNIEnv& env, java::util::List pointsList) { NullCheck(env, &pointsList); - auto jarray = java::util::List::toArray<LatLng>(env, pointsList); + auto jarray = + (jni::Array<jni::Object<LatLng>>)java::util::List_toArray::Call(env, pointsList); NullCheck(env, &jarray); std::size_t size = jarray.Length(env); diff --git a/platform/android/src/annotation/polygon.cpp b/platform/android/src/annotation/polygon.cpp index fbd849432a..1836fa11d7 100644 --- a/platform/android/src/annotation/polygon.cpp +++ b/platform/android/src/annotation/polygon.cpp @@ -13,7 +13,7 @@ mbgl::FillAnnotation Polygon::toAnnotation(jni::JNIEnv& env, jni::Object<Polygon mbgl::Polygon<double> geometry { MultiPoint::toGeometry<mbgl::LinearRing<double>>(env, points) }; - auto jHoleListsArray = java::util::List::toArray<java::util::List>(env, holes); + auto jHoleListsArray = (jni::Array<java::util::List>)java::util::List_toArray::Call(env, holes); std::size_t jHoleListsSize = jHoleListsArray.Length(env); for (std::size_t i = 0; i < jHoleListsSize; i++) { auto jHoleList = jHoleListsArray.Get(env, i); @@ -33,13 +33,13 @@ mbgl::FillAnnotation Polygon::toAnnotation(jni::JNIEnv& env, jni::Object<Polygon return annotation; } -jni::Object<java::util::List> Polygon::getPoints(jni::JNIEnv& env, jni::Object<Polygon> polygon) { - static auto field = Polygon::javaClass.GetField<jni::Object<java::util::List>>(env, "points"); +java::util::List Polygon::getPoints(jni::JNIEnv& env, jni::Object<Polygon> polygon) { + static auto field = Polygon::javaClass.GetField<java::util::List>(env, "points"); return polygon.Get(env, field); } -jni::Object<java::util::List> Polygon::getHoles(jni::JNIEnv& env, jni::Object<Polygon> polygon) { - static auto field = Polygon::javaClass.GetField<jni::Object<java::util::List>>(env, "holes"); +java::util::List Polygon::getHoles(jni::JNIEnv& env, jni::Object<Polygon> polygon) { + static auto field = Polygon::javaClass.GetField<java::util::List>(env, "holes"); return polygon.Get(env, field); } diff --git a/platform/android/src/annotation/polygon.hpp b/platform/android/src/annotation/polygon.hpp index a98b2822cf..e660b858fa 100644 --- a/platform/android/src/annotation/polygon.hpp +++ b/platform/android/src/annotation/polygon.hpp @@ -8,7 +8,7 @@ #include "multi_point.hpp" #include "../geometry/lat_lng.hpp" -#include "../java/util.hpp" +#include "../java/lang.hpp" namespace mbgl { namespace android { @@ -26,9 +26,9 @@ public: private: - static jni::Object<java::util::List> getPoints(jni::JNIEnv&, jni::Object<Polygon>); + static java::util::List getPoints(jni::JNIEnv&, jni::Object<Polygon>); - static jni::Object<java::util::List> getHoles(jni::JNIEnv&, jni::Object<Polygon>); + static java::util::List getHoles(jni::JNIEnv&, jni::Object<Polygon>); static float getOpacity(jni::JNIEnv&, jni::Object<Polygon>); diff --git a/platform/android/src/annotation/polyline.cpp b/platform/android/src/annotation/polyline.cpp index 3723dc1871..06910e9d63 100644 --- a/platform/android/src/annotation/polyline.cpp +++ b/platform/android/src/annotation/polyline.cpp @@ -20,8 +20,8 @@ mbgl::LineAnnotation Polyline::toAnnotation(jni::JNIEnv& env, jni::Object<Polyli return annotation; } -jni::Object<java::util::List> Polyline::getPoints(jni::JNIEnv& env, jni::Object<Polyline> polyline) { - static auto field = Polyline::javaClass.GetField<jni::Object<java::util::List>>(env, "points"); +java::util::List Polyline::getPoints(jni::JNIEnv& env, jni::Object<Polyline> polyline) { + static auto field = Polyline::javaClass.GetField<java::util::List>(env, "points"); return polyline.Get(env, field); } diff --git a/platform/android/src/annotation/polyline.hpp b/platform/android/src/annotation/polyline.hpp index bcc616a5f7..2ad3a90797 100644 --- a/platform/android/src/annotation/polyline.hpp +++ b/platform/android/src/annotation/polyline.hpp @@ -26,7 +26,7 @@ public: private: - static jni::Object<java::util::List> getPoints(jni::JNIEnv&, jni::Object<Polyline>); + static java::util::List getPoints(jni::JNIEnv&, jni::Object<Polyline>); static float getOpacity(jni::JNIEnv&, jni::Object<Polyline>); diff --git a/platform/android/src/conversion/constant.hpp b/platform/android/src/conversion/constant.hpp index 2a0b710f73..eefd197bc8 100644 --- a/platform/android/src/conversion/constant.hpp +++ b/platform/android/src/conversion/constant.hpp @@ -2,8 +2,9 @@ #include "conversion.hpp" +#include "../java/lang.hpp" + #include <mbgl/util/optional.hpp> -#include <jni/jni.hpp> #include <string> #include <array> diff --git a/platform/android/src/geojson/feature_collection.cpp b/platform/android/src/geojson/feature_collection.cpp index 2f156532ae..7ba5c2995a 100644 --- a/platform/android/src/geojson/feature_collection.cpp +++ b/platform/android/src/geojson/feature_collection.cpp @@ -8,7 +8,7 @@ namespace geojson { mbgl::FeatureCollection FeatureCollection::convert(jni::JNIEnv& env, jni::Object<FeatureCollection> jCollection) { auto jFeatureList = FeatureCollection::getFeatures(env, jCollection); - auto jFeatures = java::util::List::toArray<Feature>(env, jFeatureList); + auto jFeatures = (jni::Array<jni::Object<Feature>>)java::util::List_toArray::Call(env, jFeatureList); auto size = size_t(jFeatures.Length(env)); auto collection = mbgl::FeatureCollection(); @@ -23,8 +23,8 @@ mbgl::FeatureCollection FeatureCollection::convert(jni::JNIEnv& env, jni::Object return collection; } -jni::Object<java::util::List> FeatureCollection::getFeatures(jni::JNIEnv& env, jni::Object<FeatureCollection> jCollection) { - static auto method = FeatureCollection::javaClass.GetMethod<jni::Object<java::util::List> ()>(env, "getFeatures"); +java::util::List FeatureCollection::getFeatures(jni::JNIEnv& env, jni::Object<FeatureCollection> jCollection) { + static auto method = FeatureCollection::javaClass.GetMethod<java::util::List ()>(env, "getFeatures"); return jCollection.Call(env, method); } diff --git a/platform/android/src/geojson/feature_collection.hpp b/platform/android/src/geojson/feature_collection.hpp index 8e9717e82b..64cf48af97 100644 --- a/platform/android/src/geojson/feature_collection.hpp +++ b/platform/android/src/geojson/feature_collection.hpp @@ -5,8 +5,6 @@ #include <mbgl/util/geojson.hpp> #include <mbgl/util/noncopyable.hpp> -#include <jni/jni.hpp> - namespace mbgl { namespace android { namespace geojson { @@ -17,7 +15,7 @@ public: static mbgl::FeatureCollection convert(jni::JNIEnv&, jni::Object<FeatureCollection>); - static jni::Object<java::util::List> getFeatures(jni::JNIEnv&, jni::Object<FeatureCollection>); + static java::util::List getFeatures(jni::JNIEnv&, jni::Object<FeatureCollection>); static jni::Class<FeatureCollection> javaClass; diff --git a/platform/android/src/geojson/line_string.cpp b/platform/android/src/geojson/line_string.cpp index d0719f2538..6d08b75fbe 100644 --- a/platform/android/src/geojson/line_string.cpp +++ b/platform/android/src/geojson/line_string.cpp @@ -18,11 +18,11 @@ mapbox::geojson::line_string LineString::convert(jni::JNIEnv &env, jni::Object<L return lineString; } -mapbox::geojson::line_string LineString::convert(jni::JNIEnv &env, jni::Object<java::util::List/*<Position>*/> jPositionList) { +mapbox::geojson::line_string LineString::convert(jni::JNIEnv &env, java::util::List /* <Position> */ jPositionList) { mapbox::geojson::line_string lineString; if (jPositionList) { - auto jPositionArray = java::util::List::toArray<Position>(env, jPositionList); + auto jPositionArray = (jni::Array<jni::Object<Position>>)java::util::List_toArray::Call(env, jPositionList); auto size = jPositionArray.Length(env); for (std::size_t i = 0; i < size; i++) { @@ -37,8 +37,8 @@ mapbox::geojson::line_string LineString::convert(jni::JNIEnv &env, jni::Object<j return lineString; } -jni::Object<java::util::List> LineString::getCoordinates(jni::JNIEnv &env, jni::Object<LineString> jLineString) { - static auto method = LineString::javaClass.GetMethod<jni::Object<java::util::List> ()>(env, "getCoordinates"); +java::util::List LineString::getCoordinates(jni::JNIEnv &env, jni::Object<LineString> jLineString) { + static auto method = LineString::javaClass.GetMethod<java::util::List ()>(env, "getCoordinates"); return jLineString.Call(env, method); } diff --git a/platform/android/src/geojson/line_string.hpp b/platform/android/src/geojson/line_string.hpp index d3be68d0a5..55a39e28e1 100644 --- a/platform/android/src/geojson/line_string.hpp +++ b/platform/android/src/geojson/line_string.hpp @@ -20,9 +20,9 @@ public: static mapbox::geojson::line_string convert(jni::JNIEnv&, jni::Object<LineString>); - static mapbox::geojson::line_string convert(jni::JNIEnv&, jni::Object<java::util::List/*<Position>*/>); + static mapbox::geojson::line_string convert(jni::JNIEnv&, java::util::List /* <Position> */); - static jni::Object<java::util::List> getCoordinates(jni::JNIEnv&, jni::Object<LineString>); + static java::util::List getCoordinates(jni::JNIEnv&, jni::Object<LineString>); static jni::Class<LineString> javaClass; diff --git a/platform/android/src/geojson/multi_line_string.cpp b/platform/android/src/geojson/multi_line_string.cpp index b676144bf5..3c87383558 100644 --- a/platform/android/src/geojson/multi_line_string.cpp +++ b/platform/android/src/geojson/multi_line_string.cpp @@ -18,11 +18,11 @@ mapbox::geojson::multi_line_string MultiLineString::convert(jni::JNIEnv &env, jn return multiLineString; } -mapbox::geojson::multi_line_string MultiLineString::convert(jni::JNIEnv &env, jni::Object<java::util::List/*<java::util::List<Position>>*/> jPositionListsList) { +mapbox::geojson::multi_line_string MultiLineString::convert(jni::JNIEnv &env, java::util::List /* java::util::List<Position> */ jPositionListsList) { mapbox::geojson::multi_line_string multiLineString; if (jPositionListsList) { - auto jPositionListsArray = java::util::List::toArray<java::util::List>(env, jPositionListsList); + auto jPositionListsArray = (jni::Array<java::util::List>)java::util::List_toArray::Call(env, jPositionListsList); auto size = jPositionListsArray.Length(env); multiLineString.reserve(size); @@ -39,8 +39,8 @@ mapbox::geojson::multi_line_string MultiLineString::convert(jni::JNIEnv &env, jn return multiLineString; } -jni::Object<java::util::List> MultiLineString::getCoordinates(jni::JNIEnv &env, jni::Object<MultiLineString> jLineString) { - static auto method = MultiLineString::javaClass.GetMethod<jni::Object<java::util::List> ()>(env, "getCoordinates"); +java::util::List MultiLineString::getCoordinates(jni::JNIEnv &env, jni::Object<MultiLineString> jLineString) { + static auto method = MultiLineString::javaClass.GetMethod<java::util::List ()>(env, "getCoordinates"); return jLineString.Call(env, method); } diff --git a/platform/android/src/geojson/multi_line_string.hpp b/platform/android/src/geojson/multi_line_string.hpp index af33fe72d6..09d11336c9 100644 --- a/platform/android/src/geojson/multi_line_string.hpp +++ b/platform/android/src/geojson/multi_line_string.hpp @@ -19,9 +19,9 @@ public: static mapbox::geojson::multi_line_string convert(jni::JNIEnv&, jni::Object<MultiLineString>); - static mapbox::geojson::multi_line_string convert(jni::JNIEnv&, jni::Object<java::util::List/*<java::util::List<Position>>*/>); + static mapbox::geojson::multi_line_string convert(jni::JNIEnv&, java::util::List /* java::util::List<Position> */); - static jni::Object<java::util::List> getCoordinates(jni::JNIEnv&, jni::Object<MultiLineString>); + static java::util::List getCoordinates(jni::JNIEnv&, jni::Object<MultiLineString>); static jni::Class<MultiLineString> javaClass; diff --git a/platform/android/src/geojson/multi_point.cpp b/platform/android/src/geojson/multi_point.cpp index f3acdb1ea6..bac522ade9 100644 --- a/platform/android/src/geojson/multi_point.cpp +++ b/platform/android/src/geojson/multi_point.cpp @@ -20,8 +20,8 @@ mapbox::geojson::multi_point MultiPoint::convert(jni::JNIEnv &env, jni::Object<M return multiPoint; } -jni::Object<java::util::List> MultiPoint::getCoordinates(jni::JNIEnv &env, jni::Object<MultiPoint> jMultiPoint) { - static auto method = MultiPoint::javaClass.GetMethod<jni::Object<java::util::List> ()>(env, "getCoordinates"); +java::util::List MultiPoint::getCoordinates(jni::JNIEnv &env, jni::Object<MultiPoint> jMultiPoint) { + static auto method = MultiPoint::javaClass.GetMethod<java::util::List ()>(env, "getCoordinates"); return jMultiPoint.Call(env, method); } diff --git a/platform/android/src/geojson/multi_point.hpp b/platform/android/src/geojson/multi_point.hpp index 7a698287eb..c536179128 100644 --- a/platform/android/src/geojson/multi_point.hpp +++ b/platform/android/src/geojson/multi_point.hpp @@ -19,7 +19,7 @@ public: static mapbox::geojson::multi_point convert(jni::JNIEnv&, jni::Object<MultiPoint>); - static jni::Object<java::util::List> getCoordinates(jni::JNIEnv&, jni::Object<MultiPoint>); + static java::util::List getCoordinates(jni::JNIEnv&, jni::Object<MultiPoint>); static jni::Class<MultiPoint> javaClass; diff --git a/platform/android/src/geojson/multi_polygon.cpp b/platform/android/src/geojson/multi_polygon.cpp index a55884a110..3375f2ae77 100644 --- a/platform/android/src/geojson/multi_polygon.cpp +++ b/platform/android/src/geojson/multi_polygon.cpp @@ -11,7 +11,7 @@ mapbox::geojson::multi_polygon MultiPolygon::convert(jni::JNIEnv &env, jni::Obje if (jMultiPolygon) { auto jPositionListsListList = MultiPolygon::getCoordinates(env, jMultiPolygon); - auto jPositionListsListArray = java::util::List::toArray<java::util::List>(env, jPositionListsListList); + auto jPositionListsListArray = (jni::Array<java::util::List>)java::util::List_toArray::Call(env, jPositionListsListList); auto size = jPositionListsListArray.Length(env); multiPolygon.reserve(size); @@ -29,8 +29,8 @@ mapbox::geojson::multi_polygon MultiPolygon::convert(jni::JNIEnv &env, jni::Obje return multiPolygon; } -jni::Object<java::util::List> MultiPolygon::getCoordinates(jni::JNIEnv &env, jni::Object<MultiPolygon> jPolygon) { - static auto method = MultiPolygon::javaClass.GetMethod<jni::Object<java::util::List> ()>(env, "getCoordinates"); +java::util::List MultiPolygon::getCoordinates(jni::JNIEnv &env, jni::Object<MultiPolygon> jPolygon) { + static auto method = MultiPolygon::javaClass.GetMethod<java::util::List ()>(env, "getCoordinates"); return jPolygon.Call(env, method); } diff --git a/platform/android/src/geojson/multi_polygon.hpp b/platform/android/src/geojson/multi_polygon.hpp index 1f144cffd2..a2f94405af 100644 --- a/platform/android/src/geojson/multi_polygon.hpp +++ b/platform/android/src/geojson/multi_polygon.hpp @@ -19,7 +19,7 @@ public: static mapbox::geojson::multi_polygon convert(jni::JNIEnv&, jni::Object<MultiPolygon>); - static jni::Object<java::util::List> getCoordinates(jni::JNIEnv&, jni::Object<MultiPolygon>); + static java::util::List getCoordinates(jni::JNIEnv&, jni::Object<MultiPolygon>); static jni::Class<MultiPolygon> javaClass; diff --git a/platform/android/src/geojson/polygon.cpp b/platform/android/src/geojson/polygon.cpp index ef00f9df3f..cb01a8fa84 100644 --- a/platform/android/src/geojson/polygon.cpp +++ b/platform/android/src/geojson/polygon.cpp @@ -20,7 +20,7 @@ mapbox::geojson::polygon Polygon::convert(jni::JNIEnv &env, jni::Object<Polygon> return polygon; } -mapbox::geojson::polygon Polygon::convert(jni::JNIEnv &env, jni::Object<java::util::List/*<java::util::List<Position>>*/> jPositionListsList) { +mapbox::geojson::polygon Polygon::convert(jni::JNIEnv &env, java::util::List /* java::util::List<Position> */ jPositionListsList) { mapbox::geojson::polygon polygon; if (jPositionListsList) { @@ -35,8 +35,8 @@ mapbox::geojson::polygon Polygon::convert(jni::JNIEnv &env, jni::Object<java::ut } -jni::Object<java::util::List> Polygon::getCoordinates(jni::JNIEnv &env, jni::Object<Polygon> jPolygon) { - static auto method = Polygon::javaClass.GetMethod<jni::Object<java::util::List> ()>(env, "getCoordinates"); +java::util::List Polygon::getCoordinates(jni::JNIEnv &env, jni::Object<Polygon> jPolygon) { + static auto method = Polygon::javaClass.GetMethod<java::util::List ()>(env, "getCoordinates"); return jPolygon.Call(env, method); } diff --git a/platform/android/src/geojson/polygon.hpp b/platform/android/src/geojson/polygon.hpp index e5362cedf1..cc98268196 100644 --- a/platform/android/src/geojson/polygon.hpp +++ b/platform/android/src/geojson/polygon.hpp @@ -19,9 +19,9 @@ public: static mapbox::geojson::polygon convert(jni::JNIEnv &, jni::Object<Polygon>); - static mapbox::geojson::polygon convert(jni::JNIEnv&, jni::Object<java::util::List/*<java::util::List<Position>>*/>); + static mapbox::geojson::polygon convert(jni::JNIEnv&, java::util::List /* java::util::List<Position> */); - static jni::Object<java::util::List> getCoordinates(jni::JNIEnv&, jni::Object<Polygon>); + static java::util::List getCoordinates(jni::JNIEnv&, jni::Object<Polygon>); static jni::Class<Polygon> javaClass; diff --git a/platform/android/src/gson/json_object.cpp b/platform/android/src/gson/json_object.cpp index a704dae9dd..a8a71fb1d7 100644 --- a/platform/android/src/gson/json_object.cpp +++ b/platform/android/src/gson/json_object.cpp @@ -12,18 +12,18 @@ namespace gson { template <typename F> // void (jni::String, jni::Object<gson::JsonElement>) static void iterateEntrySet(jni::JNIEnv& env, jni::Object<JsonObject> jsonObject, F callback) { // Get Set<Map.Entry<String, JsonElement>> - static auto method = JsonObject::javaClass.GetMethod<jni::Object<java::util::Set> ()>(env, "entrySet"); + static auto method = JsonObject::javaClass.GetMethod<java::util::Set ()>(env, "entrySet"); auto entrySet = jsonObject.Call(env, method); - jni::Array<jni::Object<java::util::Map::Entry>> entryArray = java::util::Set::toArray<java::util::Map::Entry>(env, entrySet); + auto entryArray = (jni::Array<java::util::MapEntry>)java::util::Set_toArray::Call(env, entrySet); size_t size = entryArray.Length(env); for (size_t i = 0; i < size; i++) { auto entry = entryArray.Get(env, i); if (entry) { // Convert - auto jKey = java::util::Map::Entry::getKey<jni::ObjectTag>(env, entry); + auto jKey = java::util::MapEntry_getKey::Call(env, entry); auto jKeyString = jni::String(reinterpret_cast<jni::jstring*>(jKey.Get())); - auto jValue = java::util::Map::Entry::getValue<gson::JsonElement>(env, entry); + auto jValue = (jni::Object<gson::JsonElement>)java::util::MapEntry_getValue::Call(env, entry); // Callback callback(jKeyString, jValue); diff --git a/platform/android/src/java/lang.hpp b/platform/android/src/java/lang.hpp index dcf81a9d0c..d098e87530 100644 --- a/platform/android/src/java/lang.hpp +++ b/platform/android/src/java/lang.hpp @@ -1,19 +1,63 @@ #pragma once +#include "../jni/binding.hpp" + namespace mbgl { namespace android { namespace java { namespace lang { -class Float { -public: - static constexpr auto Name() { return "java/lang/Float"; }; -}; +using ObjectTag = jni::ObjectTag; // == "java/lang/Object" +using Object = jni::Object<>; // == jni::Object<jni::ObjectTag> + +using StringTag = jni::StringTag; // == "java/lang/String" +using String = jni::String; // == jni::Object<jni::StringTag> + +struct ObjectArrayTag { static constexpr auto Name() { return "[Ljava/lang/Object;"; } }; +using ObjectArray = jni::Object<ObjectArrayTag>; + +struct BooleanTag { static constexpr auto Name() { return "java/lang/Boolean"; } }; +using Boolean = jni::Object<BooleanTag>; +using Boolean_constructor = binding::Constructor<BooleanTag, jni::jboolean>; +struct Boolean_booleanValueTag { static constexpr auto Name() { return "booleanValue"; } }; +using Boolean_booleanValue = binding::Method<BooleanTag, Boolean_booleanValueTag, jni::jboolean(void)>; +template <typename T> +auto MakeAnything(jni::ThingToMake<Boolean>, jni::JNIEnv& env, T value) { + return jni::Make<Boolean>(env, Boolean_constructor(), jni::jboolean(value)); +} + +struct FloatTag { static constexpr auto Name() { return "java/lang/Float"; } }; +using Float = jni::Object<FloatTag>; +using Float_constructor = binding::Constructor<FloatTag, jni::jfloat>; +template <typename T> +auto MakeAnything(jni::ThingToMake<Float>, jni::JNIEnv& env, T value) { + return jni::Make<Float>(env, Float_constructor(), jni::jfloat(value)); +} + +struct DoubleTag { static constexpr auto Name() { return "java/lang/Double"; } }; +using Double = jni::Object<DoubleTag>; +using Double_constructor = binding::Constructor<DoubleTag, jni::jdouble>; +template <typename T> +auto MakeAnything(jni::ThingToMake<Double>, jni::JNIEnv& env, T value) { + return jni::Make<Double>(env, Double_constructor(), jni::jdouble(value)); +} + +struct LongTag { static constexpr auto Name() { return "java/lang/Long"; } }; +using Long = jni::Object<LongTag>; +using Long_constructor = binding::Constructor<LongTag, jni::jlong>; +template <typename T> +auto MakeAnything(jni::ThingToMake<Long>, jni::JNIEnv& env, T value) { + return jni::Make<Long>(env, Long_constructor(), jni::jlong(value)); +} -class Number { -public: - static constexpr auto Name() { return "java/lang/Number"; }; -}; +struct NumberTag { static constexpr auto Name() { return "java/lang/Number"; } }; +using Number = jni::Object<NumberTag>; +struct Number_floatValueTag { static constexpr auto Name() { return "floatValue"; } }; +using Number_floatValue = binding::Method<NumberTag, Number_floatValueTag, jni::jfloat(void)>; +struct Number_doubleValueTag { static constexpr auto Name() { return "doubleValue"; } }; +using Number_doubleValue = binding::Method<NumberTag, Number_doubleValueTag, jni::jdouble(void)>; +struct Number_longValueTag { static constexpr auto Name() { return "longValue"; } }; +using Number_longValue = binding::Method<NumberTag, Number_longValueTag, jni::jlong(void)>; } // namespace lang } // namespace java diff --git a/platform/android/src/java/util.cpp b/platform/android/src/java/util.cpp deleted file mode 100644 index effd2ae0d0..0000000000 --- a/platform/android/src/java/util.cpp +++ /dev/null @@ -1,24 +0,0 @@ -#include "util.hpp" - -namespace mbgl { -namespace android { -namespace java { -namespace util { - -jni::Class<List> List::javaClass; -jni::Class<Set> Set::javaClass; -jni::Class<Map> Map::javaClass; -jni::Class<Map::Entry> Map::Entry::javaClass; - -void registerNative(jni::JNIEnv& env) { - List::javaClass = *jni::Class<List>::Find(env).NewGlobalRef(env).release(); - Set::javaClass = *jni::Class<Set>::Find(env).NewGlobalRef(env).release(); - Map::javaClass = *jni::Class<Map>::Find(env).NewGlobalRef(env).release(); - Map::Entry::javaClass = *jni::Class<Map::Entry>::Find(env).NewGlobalRef(env).release(); -} - - -} // namespace util -} // namespace java -} // namespace android -} // namespace mbgl
\ No newline at end of file diff --git a/platform/android/src/java/util.hpp b/platform/android/src/java/util.hpp index dedb8ac348..373f52f889 100644 --- a/platform/android/src/java/util.hpp +++ b/platform/android/src/java/util.hpp @@ -1,73 +1,35 @@ #pragma once -#include <mbgl/util/noncopyable.hpp> +#include "lang.hpp" -#include <jni/jni.hpp> +#include <mbgl/util/noncopyable.hpp> namespace mbgl { namespace android { namespace java { namespace util { -class List : private mbgl::util::noncopyable { -public: - - static constexpr auto Name() { return "java/util/List"; }; - - template<class T> - static jni::Array<jni::Object<T>> toArray(jni::JNIEnv& env, jni::Object<List> list) { - static auto toArray = List::javaClass.GetMethod<jni::Array<jni::Object<>> ()>(env, "toArray"); - return (jni::Array<jni::Object<T>>) list.Call(env, toArray); - }; - - static jni::Class<List> javaClass; - -}; - -class Set : private mbgl::util::noncopyable { -public: - - static constexpr auto Name() { return "java/util/Set"; }; - - template<class T> - static jni::Array<jni::Object<T>> toArray(jni::JNIEnv& env, jni::Object<Set> list) { - static auto toArray = Set::javaClass.GetMethod<jni::Array<jni::Object<>> ()>(env, "toArray"); - return (jni::Array<jni::Object<T>>) list.Call(env, toArray); - }; - - static jni::Class<Set> javaClass; - -}; - -class Map : private mbgl::util::noncopyable { -public: - - class Entry : private mbgl::util::noncopyable { - public: - static constexpr auto Name() { return "java/util/Map$Entry"; }; - - template <class T> - static jni::Object<T> getKey(jni::JNIEnv& env, jni::Object<Entry> entry) { - static auto method = Entry::javaClass.GetMethod<jni::Object<> ()>(env, "getKey"); - return (jni::Object<T>) entry.Call(env, method); - } - - template <class T> - static jni::Object<T> getValue(jni::JNIEnv& env, jni::Object<Entry> entry) { - static auto method = Entry::javaClass.GetMethod<jni::Object<> ()>(env, "getValue"); - return (jni::Object<T>) entry.Call(env, method).Get(); - } - - static jni::Class<Entry> javaClass; - }; - - static constexpr auto Name() { return "java/util/Map"; }; - - static jni::Class<Map> javaClass; -}; - -void registerNative(jni::JNIEnv&); - +struct ListTag { static constexpr auto Name() { return "java/util/List"; } }; +using List = jni::Object<ListTag>; +struct List_toArrayTag { static constexpr auto Name() { return "toArray"; } }; +using List_toArray = binding::Method<ListTag, List_toArrayTag, jni::Array<jni::Object<>>(void)>; + +struct MapTag { static constexpr auto Name() { return "java/util/Map"; } }; +using Map = jni::Object<MapTag>; +struct Map_getTag { static constexpr auto Name() { return "get"; } }; +using Map_get = binding::Method<MapTag, Map_getTag, jni::Object<>(jni::Object<>)>; + +struct MapEntryTag { static constexpr auto Name() { return "java/util/Map$Entry"; }; }; +using MapEntry = jni::Object<MapEntryTag>; +struct MapEntry_getKeyTag { static constexpr auto Name() { return "getKey"; } }; +using MapEntry_getKey = binding::Method<MapEntryTag, MapEntry_getKeyTag, jni::Object<>(void)>; +struct MapEntry_getValueTag { static constexpr auto Name() { return "getValue"; } }; +using MapEntry_getValue = binding::Method<MapEntryTag, MapEntry_getValueTag, jni::Object<>(void)>; + +struct SetTag { static constexpr auto Name() { return "java/util/Set"; } }; +using Set = jni::Object<SetTag>; +struct Set_toArrayTag { static constexpr auto Name() { return "toArray"; } }; +using Set_toArray = binding::Method<SetTag, Set_toArrayTag, jni::Array<jni::Object<>>(void)>; } // namespace util } // namespace java diff --git a/platform/android/src/java_types.cpp b/platform/android/src/java_types.cpp deleted file mode 100644 index dd165470cf..0000000000 --- a/platform/android/src/java_types.cpp +++ /dev/null @@ -1,41 +0,0 @@ -#include "java_types.hpp" - -namespace mbgl { -namespace android { -namespace java { - - jni::jclass* ObjectArray::jclass; - - jni::jclass* String::jclass; - - jni::jclass* Boolean::jclass; - jni::jmethodID* Boolean::booleanValueMethodId; - - jni::jclass* Number::jclass; - jni::jmethodID* Number::floatValueMethodId; - jni::jmethodID* Number::doubleValueMethodId; - jni::jmethodID* Number::longValueMethodId; - - jni::jclass* Map::jclass; - jni::jmethodID* Map::getMethodId; - - void registerNatives(JNIEnv& env) { - ObjectArray::jclass = jni::NewGlobalRef(env, &jni::FindClass(env, "[Ljava/lang/Object;")).release(); - - String::jclass = jni::NewGlobalRef(env, &jni::FindClass(env, "java/lang/String")).release(); - - Boolean::jclass = jni::NewGlobalRef(env, &jni::FindClass(env, "java/lang/Boolean")).release(); - Boolean::booleanValueMethodId = &jni::GetMethodID(env, *Boolean::jclass, "booleanValue", "()Z"); - - Number::jclass = jni::NewGlobalRef(env, &jni::FindClass(env, "java/lang/Number")).release(); - Number::floatValueMethodId = &jni::GetMethodID(env, *Number::jclass, "floatValue", "()F"); - Number::doubleValueMethodId = &jni::GetMethodID(env, *Number::jclass, "doubleValue", "()D"); - Number::longValueMethodId = &jni::GetMethodID(env, *Number::jclass, "longValue", "()J"); - - Map::jclass = jni::NewGlobalRef(env, &jni::FindClass(env, "java/util/Map")).release(); - Map::getMethodId = &jni::GetMethodID(env, *Map::jclass, "get", "(Ljava/lang/Object;)Ljava/lang/Object;"); - } - -} -} -} diff --git a/platform/android/src/java_types.hpp b/platform/android/src/java_types.hpp deleted file mode 100644 index edec5cb550..0000000000 --- a/platform/android/src/java_types.hpp +++ /dev/null @@ -1,37 +0,0 @@ -#pragma once - -#include <jni/jni.hpp> - -namespace mbgl { -namespace android { -namespace java { - - struct ObjectArray { - static jni::jclass* jclass; - }; - - struct String { - static jni::jclass* jclass; - }; - - struct Boolean { - static jni::jclass* jclass; - static jni::jmethodID* booleanValueMethodId; - }; - - struct Number { - static jni::jclass* jclass; - static jni::jmethodID* floatValueMethodId; - static jni::jmethodID* doubleValueMethodId; - static jni::jmethodID* longValueMethodId; - }; - - struct Map { - static jni::jclass* jclass; - static jni::jmethodID* getMethodId; - }; - - void registerNatives(JNIEnv&); -} -} -} diff --git a/platform/android/src/jni.cpp b/platform/android/src/jni.cpp index 53691acb39..f7929540dd 100755 --- a/platform/android/src/jni.cpp +++ b/platform/android/src/jni.cpp @@ -30,7 +30,7 @@ #include "gson/json_element.hpp" #include "gson/json_object.hpp" #include "gson/json_primitive.hpp" -#include "java_types.hpp" +#include "java/lang.hpp" #include "native_map_view.hpp" #include "offline/offline_manager.hpp" #include "offline/offline_region.hpp" @@ -101,13 +101,22 @@ void registerNatives(JavaVM *vm) { jni::JNIEnv& env = jni::GetEnv(*vm, jni::jni_version_1_6); +#ifndef NDEBUG + // Register all JNI classes and methods that we'd normally load lazily when they're needed. + // This is enabled in Debug builds to quickly discover invalid class names that otherwise + // would produce a runtime error when they're registered but can't be found. + try { + binding::RegisterNative(env); + } catch (jni::PendingJavaException& ex) { + jni::ExceptionDescribe(env); + } +#endif + // For the DefaultFileSource static mbgl::util::RunLoop mainRunLoop; FileSource::registerNative(env); // Basic types - java::registerNatives(env); - java::util::registerNative(env); PointF::registerNative(env); RectF::registerNative(env); diff --git a/platform/android/src/jni/binding.cpp b/platform/android/src/jni/binding.cpp new file mode 100644 index 0000000000..56e91fcabd --- /dev/null +++ b/platform/android/src/jni/binding.cpp @@ -0,0 +1,31 @@ +#include "binding.hpp" + +#include <vector> + +namespace mbgl { +namespace android { +namespace binding { + +#ifndef NDEBUG + +using RegisterNativeFunctions = std::vector<void (*)(jni::JNIEnv&)>; +RegisterNativeFunctions& registerNativeFunctions() { + static RegisterNativeFunctions fns; + return fns; +} + +void RegisterNative(void (*registerNative)(jni::JNIEnv&)) { + registerNativeFunctions().push_back(registerNative); +} + +void RegisterNative(jni::JNIEnv& env) { + for (auto fn : registerNativeFunctions()) { + fn(env); + } +} + +#endif + +} // namespace binding +} // namespace android +} // namespace mbgl diff --git a/platform/android/src/jni/binding.hpp b/platform/android/src/jni/binding.hpp new file mode 100644 index 0000000000..9ee5a0b676 --- /dev/null +++ b/platform/android/src/jni/binding.hpp @@ -0,0 +1,144 @@ +#pragma once + +#include <jni/jni.hpp> + +namespace mbgl { +namespace android { +namespace binding { + +#ifndef NDEBUG + +void RegisterNative(void (*)(jni::JNIEnv&)); +void RegisterNative(jni::JNIEnv&); + +// This class acts as a catch-all class for static initialization of JNI classes/methods. +// The Class, Constructor, StaticMethod, and Method classes below have a reference to the +// static member in this class. Since this class is templated, referencing it will trigger a +// concrete instantiation of the static member named "Invoke". The template definition below +// initializes an object of this class, and passes a function pointer (in the form of a lambda) to +// the constructor, which adds this function pointer to an internal vector of function pointers. +// Static initialization means that all Classes/Constructors/StaticMethods/Methods that are used +// *somewhere* in this code (and thus trigger the template instantiation) will get initialized +// during program startup (before main), albeit in an unknown order. +// We collect these so that a Debug build can forcibly trigger a call to every referenced entity. +// This is useful for verifying that all referenced Classes/Constructors/StaticMethods/Methods can +// be found through JNI lookups at program startup. +// Release builds do not build such a cache (see the #ifdef). All JNI lookups happen lazily in that +// case. +template <class Type> +struct Register { + Register(void (*registerNative)(jni::JNIEnv&)) { + RegisterNative(registerNative); + } + static Register Invoke; +}; + +template <class Type> +Register<Type> Register<Type>::Invoke{ [](jni::JNIEnv& env) { Type::Get(env); } }; + +#endif + +// This class acts as a static cache for obtaining the Java Class object. The only template +// parameter is a Tag that must have a `static constexpr auto Name()` function that returns a +// `const char*` of the class name (e.g. "java/lang/Boolean"). +template <class ClassTag> +struct Class { + static auto Get(jni::JNIEnv& env) { +#ifndef NDEBUG + (void)Register<Class>::Invoke; // Leave this here. See documentation above. +#endif + static auto javaClass = jni::Class<ClassTag>::Find(env).NewGlobalRef(env); + return *javaClass; + } +}; + +// This class acts as a static cache for obtaining a constructor methods of a Java class. After +// the ClassTag (see above), it expects the argument list of the constructor, or nothing if the +// class' constructor doesn't take an argument. +template <class ClassTag, class... Args> +struct Constructor { + static auto Get(jni::JNIEnv& env) { +#ifndef NDEBUG + (void)Register<Constructor>::Invoke; // Leave this here. See documentation above. +#endif + static const auto javaConstructor = + Class<ClassTag>::Get(env).template GetConstructor<Args...>(env); + return javaConstructor; + } +}; + +// This class acts as a static cache for obtaining a static method of a Java class. After +// the ClassTag (see above), it expects a StaticMethodTag which returns the name of the static +// method as a string, identical to how the ClassTag works. Then, it expects the function signature +// R(Args...) of the static method. +// It also provides a static Call() function that allows invoking the static method. +template <class ClassTag, class StaticMethodTag, class> +struct StaticMethod; + +template <class ClassTag, class StaticMethodTag, class R, class... Args> +struct StaticMethod<ClassTag, StaticMethodTag, R(Args...)> { + static auto Get(jni::JNIEnv& env) { +#ifndef NDEBUG + (void)Register<StaticMethod>::Invoke; // Leave this here. See documentation above. +#endif + static const auto javaStaticMethod = + Class<ClassTag>::Get(env).template GetStaticMethod<R(Args...)>(env, + StaticMethodTag::Name()); + return javaStaticMethod; + } + + template <class... Params> + static auto Call(jni::JNIEnv& env, Params&&... params) { + Class<ClassTag>::Get(env).Call(env, Get(env), std::forward<Params>(params)...); + } +}; + +// This class acts as a static cache for obtaining a method of a Java class. After the ClassTag (see +// above), it expects a MethodTag which returns the name of the method as a string, identical to how +// the ClassTag works. Then, it expects the function signature R(Args...) of the method. +// It also provides a static Call() function that allows invoking the method when providing an +// instance of the class. +template <class ClassTag, class MethodTag, class> +struct Method; + +template <class ClassTag, class MethodTag, class R, class... Args> +struct Method<ClassTag, MethodTag, R(Args...)> { + static auto Get(jni::JNIEnv& env) { +#ifndef NDEBUG + (void)Register<Method>::Invoke; // Leave this here. See documentation above. +#endif + static const auto javaMethod = + Class<ClassTag>::Get(env).template GetMethod<R(Args...)>(env, MethodTag::Name()); + return javaMethod; + } + + template <class... Params> + static auto Call(jni::JNIEnv& env, jni::Object<ClassTag> obj, Params&&... params) { + return obj.Call(env, Get(env), std::forward<Params>(params)...); + } +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +} // namespace binding +} // namespace android +} // namespace mbgl + +template <class ClassTag, class... Args> +auto MakeAnything(jni::ThingToMake<jni::Object<ClassTag>>, + jni::JNIEnv& env, + mbgl::android::binding::Constructor<ClassTag, Args...>, + Args&&... args) { + return mbgl::android::binding::Class<ClassTag>::Get(env).New( + env, mbgl::android::binding::Constructor<ClassTag, Args...>::Get(env), + std::forward<Args>(args)...); +} + +template <class ClassTag> +auto MakeAnything(jni::ThingToMake<jni::Array<jni::Object<ClassTag>>>, + jni::JNIEnv& env, + jni::jsize length, + const jni::Object<ClassTag>& initialElement = jni::Object<ClassTag>()) { + return jni::Array<jni::Object<ClassTag>>::New( + env, length, mbgl::android::binding::Class<ClassTag>::Get(env), initialElement); +} diff --git a/platform/android/src/style/conversion/filter.hpp b/platform/android/src/style/conversion/filter.hpp index 1f0abcf3a4..bcc518089e 100644 --- a/platform/android/src/style/conversion/filter.hpp +++ b/platform/android/src/style/conversion/filter.hpp @@ -16,7 +16,7 @@ namespace conversion { inline optional<mbgl::style::Filter> toFilter(jni::JNIEnv& env, jni::Array<jni::Object<>> jfilter) { mbgl::optional<mbgl::style::Filter> filter; if (jfilter) { - Value filterValue(env, jfilter); + Value filterValue(env, jni::Object<>(jfilter.Get())); mbgl::style::conversion::Error error; auto converted = mbgl::style::conversion::convert<mbgl::style::Filter>(filterValue, error); if (!converted) { diff --git a/platform/android/src/style/conversion/function.hpp b/platform/android/src/style/conversion/function.hpp index ad01a7afc2..4b48a17e8b 100644 --- a/platform/android/src/style/conversion/function.hpp +++ b/platform/android/src/style/conversion/function.hpp @@ -80,7 +80,7 @@ jni::Array<jni::Object<Stop>> toFunctionStopJavaArray(jni::JNIEnv& env, std::map for (auto const& zoomLevelMap : value) { size_t i = 0; for (auto const& stop: zoomLevelMap.second) { - auto zoom = jni::Object<java::lang::Number>(*convert<jni::jobject*>(env, zoomLevelMap.first)); + auto zoom = java::lang::Number(*convert<jni::jobject*>(env, zoomLevelMap.first)); auto in = jni::Object<>(*convert<jni::jobject*, I>(env, stop.first)); auto out = jni::Object<>(*convert<jni::jobject*, O>(env, stop.second)); auto compositeValue = Stop::CompositeValue::New(env, zoom, in); @@ -139,11 +139,11 @@ public: } jni::jobject* operator()(const mbgl::style::ExponentialStops<T> &value) const { - return ExponentialStops::New(env, jni::Object<java::lang::Float>(*convert<jni::jobject*>(env, value.base)), toFunctionStopJavaArray(env, value.stops)).Get(); + return ExponentialStops::New(env, java::lang::Float(*convert<jni::jobject*>(env, value.base)), toFunctionStopJavaArray(env, value.stops)).Get(); } jni::jobject* operator()(const mbgl::style::CompositeExponentialStops<T> &value) const { - return ExponentialStops::New(env, jni::Object<java::lang::Float>(*convert<jni::jobject*>(env, value.base)), toFunctionStopJavaArray(env, value.stops)).Get(); + return ExponentialStops::New(env, java::lang::Float(*convert<jni::jobject*>(env, value.base)), toFunctionStopJavaArray(env, value.stops)).Get(); } jni::jobject* operator()(const mbgl::style::IdentityStops<T> &) const { diff --git a/platform/android/src/style/functions/exponential_stops.cpp b/platform/android/src/style/functions/exponential_stops.cpp index 6390a0ec35..47a0f62caf 100644 --- a/platform/android/src/style/functions/exponential_stops.cpp +++ b/platform/android/src/style/functions/exponential_stops.cpp @@ -3,8 +3,8 @@ namespace mbgl { namespace android { -jni::Object<ExponentialStops> ExponentialStops::New(jni::JNIEnv& env, jni::Object<java::lang::Float> base, jni::Array<jni::Object<Stop>> stops) { - static auto constructor = ExponentialStops::javaClass.GetConstructor<jni::Object<java::lang::Float>, jni::Array<jni::Object<Stop>>>(env); +jni::Object<ExponentialStops> ExponentialStops::New(jni::JNIEnv& env, java::lang::Float base, jni::Array<jni::Object<Stop>> stops) { + static auto constructor = ExponentialStops::javaClass.GetConstructor<java::lang::Float, jni::Array<jni::Object<Stop>>>(env); return ExponentialStops::javaClass.New(env, constructor, base, stops); } diff --git a/platform/android/src/style/functions/exponential_stops.hpp b/platform/android/src/style/functions/exponential_stops.hpp index 391d723cef..01197547c2 100644 --- a/platform/android/src/style/functions/exponential_stops.hpp +++ b/platform/android/src/style/functions/exponential_stops.hpp @@ -13,7 +13,7 @@ class ExponentialStops : private mbgl::util::noncopyable { public: static constexpr auto Name() { return "com/mapbox/mapboxsdk/style/functions/stops/ExponentialStops"; }; - static jni::Object<ExponentialStops> New(jni::JNIEnv&, jni::Object<java::lang::Float>, jni::Array<jni::Object<Stop>>); + static jni::Object<ExponentialStops> New(jni::JNIEnv&, java::lang::Float, jni::Array<jni::Object<Stop>>); static jni::Class<ExponentialStops> javaClass; diff --git a/platform/android/src/style/functions/stop.cpp b/platform/android/src/style/functions/stop.cpp index f9ed4b7368..157512d149 100644 --- a/platform/android/src/style/functions/stop.cpp +++ b/platform/android/src/style/functions/stop.cpp @@ -3,8 +3,8 @@ namespace mbgl { namespace android { -jni::Object<Stop::CompositeValue> Stop::CompositeValue::New(jni::JNIEnv& env, jni::Object<java::lang::Number> zoom, jni::Object<> value) { - static auto constructor = Stop::CompositeValue::javaClass.GetConstructor<jni::Object<java::lang::Number>, jni::Object<>>(env); +jni::Object<Stop::CompositeValue> Stop::CompositeValue::New(jni::JNIEnv& env, java::lang::Number zoom, jni::Object<> value) { + static auto constructor = Stop::CompositeValue::javaClass.GetConstructor<java::lang::Number, jni::Object<>>(env); return Stop::CompositeValue::javaClass.New(env, constructor, zoom, value); } diff --git a/platform/android/src/style/functions/stop.hpp b/platform/android/src/style/functions/stop.hpp index 7c697db65d..3881b590bb 100644 --- a/platform/android/src/style/functions/stop.hpp +++ b/platform/android/src/style/functions/stop.hpp @@ -26,7 +26,7 @@ public: public: static constexpr auto Name() { return "com/mapbox/mapboxsdk/style/functions/stops/Stop$CompositeValue"; }; - static jni::Object<Stop::CompositeValue> New(jni::JNIEnv&, jni::Object<java::lang::Number>, jni::Object<>); + static jni::Object<Stop::CompositeValue> New(jni::JNIEnv&, java::lang::Number, jni::Object<>); static jni::Class<Stop::CompositeValue> javaClass; }; diff --git a/platform/android/src/style/layers/layer.cpp b/platform/android/src/style/layers/layer.cpp index 58c0c5ee84..7e9fd41443 100644 --- a/platform/android/src/style/layers/layer.cpp +++ b/platform/android/src/style/layers/layer.cpp @@ -102,7 +102,7 @@ namespace android { using namespace mbgl::style; using namespace mbgl::style::conversion; - Value wrapped(env, jfilter); + Value wrapped(env, jni::Object<>(jfilter.Get())); Filter filter; Error error; diff --git a/platform/android/src/style/sources/geojson_source.cpp b/platform/android/src/style/sources/geojson_source.cpp index c201cdade1..844272f18f 100644 --- a/platform/android/src/style/sources/geojson_source.cpp +++ b/platform/android/src/style/sources/geojson_source.cpp @@ -52,7 +52,7 @@ namespace android { // Convert the jni object Error error; - optional<GeoJSON> converted = convert<GeoJSON>(Value(env, json), error); + optional<GeoJSON> converted = convert<GeoJSON>(Value(env, jni::Object<>(json)), error); if(!converted) { mbgl::Log::Error(mbgl::Event::JNI, "Error setting geo json: " + error.message); return; diff --git a/platform/android/src/style/value.cpp b/platform/android/src/style/value.cpp index e1cd81d7fd..59fbac11f1 100644 --- a/platform/android/src/style/value.cpp +++ b/platform/android/src/style/value.cpp @@ -1,90 +1,93 @@ #include "value.hpp" -#include "../java_types.hpp" +#include "../java/lang.hpp" +#include "../java/util.hpp" namespace mbgl { namespace android { - class ObjectDeleter { - public: - ObjectDeleter() = default; - ObjectDeleter(JNIEnv& e) : env(e) {} +class ObjectDeleter { +public: + ObjectDeleter() = default; + ObjectDeleter(JNIEnv& e) : env(e) { + } - void operator()(jni::jobject* p) const { - if (p) { - jni::DeleteLocalRef(env, p); - } + void operator()(jni::jobject* p) const { + if (p) { + jni::DeleteLocalRef(env, p); } + } - private: - JNIEnv& env; - }; - - // Instance +private: + JNIEnv& env; +}; - Value::Value(jni::JNIEnv& _env, jni::jobject* _value) : env(_env), value(_value, ObjectDeleter(env)) {} +// Instance - Value::~Value() = default; +Value::Value(jni::JNIEnv& env_, jni::Object<> value_) : env(env_), value(value_) { +} - bool Value::isNull() const { - return value == nullptr; - } +Value::~Value() = default; - bool Value::isArray() const { - return jni::IsInstanceOf(env, value.get(), *java::ObjectArray::jclass); - } +bool Value::isNull() const { + return value; +} - bool Value::isObject() const { - return jni::IsInstanceOf(env, value.get(), *java::Map::jclass);; - } +bool Value::isArray() const { + return value.IsInstanceOf(env, binding::Class<java::lang::ObjectArrayTag>::Get(env)); +} - bool Value::isString() const { - return jni::IsInstanceOf(env, value.get(), *java::String::jclass); - } +bool Value::isObject() const { + return value.IsInstanceOf(env, binding::Class<java::util::MapTag>::Get(env)); +} - bool Value::isBool() const { - return jni::IsInstanceOf(env, value.get(), *java::Boolean::jclass); - } +bool Value::isString() const { + return value.IsInstanceOf(env, binding::Class<java::lang::StringTag>::Get(env)); +} - bool Value::isNumber() const { - return jni::IsInstanceOf(env, value.get(), *java::Number::jclass); - } +bool Value::isBool() const { + return value.IsInstanceOf(env, binding::Class<java::lang::BooleanTag>::Get(env)); +} - std::string Value::toString() const { - jni::jstring* string = reinterpret_cast<jni::jstring*>(value.get()); - return jni::Make<std::string>(env, jni::String(string)); - } +bool Value::isNumber() const { + return value.IsInstanceOf(env, binding::Class<java::lang::NumberTag>::Get(env)); +} - float Value::toFloat() const { - return jni::CallMethod<jni::jfloat>(env, value.get(), *java::Number::floatValueMethodId); - } +std::string Value::toString() const { + return jni::Make<std::string>(env, jni::String(reinterpret_cast<jni::jstring*>(value.Get()))); +} - double Value::toDouble() const { - return jni::CallMethod<jni::jdouble>(env, value.get(), *java::Number::doubleValueMethodId); - } +float Value::toFloat() const { + return java::lang::Number_floatValue::Call(env, java::lang::Number(value.Get())); +} - long Value::toLong() const { - return jni::CallMethod<jni::jlong>(env, value.get(), *java::Number::longValueMethodId); - } +double Value::toDouble() const { + return java::lang::Number_doubleValue::Call(env, java::lang::Number(value.Get())); +} - bool Value::toBool() const { - return jni::CallMethod<jni::jboolean>(env, value.get(), *java::Boolean::booleanValueMethodId); - } +long Value::toLong() const { + return java::lang::Number_longValue::Call(env, java::lang::Number(value.Get())); +} - Value Value::get(const char* key) const { - jni::jobject* member = jni::CallMethod<jni::jobject*>(env, value.get(), *java::Map::getMethodId, jni::Make<jni::String>(env, std::string(key)).Get()); - return Value(env, member); - } +bool Value::toBool() const { + return java::lang::Boolean_booleanValue::Call(env, java::lang::Boolean(value.Get())); +} - int Value::getLength() const { - auto array = (jni::jarray<jni::jobject>*) value.get(); - return jni::GetArrayLength(env, *array); - } +Value Value::get(const char* key) const { + return { env, java::util::Map_get::Call(env, java::util::Map(value.Get()), + java::lang::Object(jni::Make<jni::String>(env, key))) }; +} - Value Value::get(const int index) const { - auto array = (jni::jarray<jni::jobject>*) value.get(); - return Value(env, jni::GetObjectArrayElement(env, *array, index)); - } +int Value::getLength() const { + return jni::Array<jni::Object<>>(reinterpret_cast<jni::jarray<jni::jobject>*>(value.Get())) + .Length(env); } + +Value Value::get(const int index) const { + return { env, + jni::Array<jni::Object<>>(reinterpret_cast<jni::jarray<jni::jobject>*>(value.Get())) + .Get(env, index) }; } +} // namespace android +} // namespace mbgl diff --git a/platform/android/src/style/value.hpp b/platform/android/src/style/value.hpp index 7464bae832..04e938e854 100644 --- a/platform/android/src/style/value.hpp +++ b/platform/android/src/style/value.hpp @@ -9,8 +9,7 @@ namespace android { class Value { public: - - Value(jni::JNIEnv&, jni::jobject*); + Value(jni::JNIEnv&, jni::Object<>); virtual ~Value(); bool isNull() const; @@ -30,8 +29,8 @@ public: Value get(const int index ) const; jni::JNIEnv& env; - std::shared_ptr<jni::jobject> value; + jni::Object<> value; }; -} -} +} // namespace android +} // namespace mbgl |