Skip to content

Commit a0c292a

Browse files
wilhuffa-maurice
authored andcommitted
Convert GeoPoint to the new JNI framework
PiperOrigin-RevId: 333116446
1 parent 3babeb6 commit a0c292a

File tree

5 files changed

+58
-86
lines changed

5 files changed

+58
-86
lines changed

firestore/src/android/field_value_android.cc

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -131,10 +131,9 @@ FieldValueInternal::FieldValueInternal(DocumentReference value)
131131

132132
FieldValueInternal::FieldValueInternal(GeoPoint value)
133133
: cached_type_(Type::kGeoPoint) {
134-
JNIEnv* env = firestore_->app()->GetJNIEnv();
135-
jobject obj = GeoPointInternal::GeoPointToJavaGeoPoint(env, value);
136-
obj_ = env->NewGlobalRef(obj);
137-
env->DeleteLocalRef(obj);
134+
Env env = GetEnv();
135+
Local<GeoPointInternal> obj = GeoPointInternal::Create(env, value);
136+
obj_ = env.get()->NewGlobalRef(obj.get());
138137
}
139138

140139
FieldValueInternal::FieldValueInternal(std::vector<FieldValue> value)
@@ -209,7 +208,7 @@ Type FieldValueInternal::type() const {
209208
cached_type_ = Type::kReference;
210209
return Type::kReference;
211210
}
212-
if (env->IsInstanceOf(obj_, GeoPointInternal::GetClass())) {
211+
if (env->IsInstanceOf(obj_, GeoPointInternal::GetClass().get())) {
213212
cached_type_ = Type::kGeoPoint;
214213
return Type::kGeoPoint;
215214
}
@@ -371,17 +370,17 @@ DocumentReference FieldValueInternal::reference_value() const {
371370
}
372371

373372
GeoPoint FieldValueInternal::geo_point_value() const {
374-
JNIEnv* env = firestore_->app()->GetJNIEnv();
373+
Env env = GetEnv();
375374

376375
// Make sure this instance is of correct type.
377376
if (cached_type_ == Type::kNull) {
378-
FIREBASE_ASSERT(env->IsInstanceOf(obj_, GeoPointInternal::GetClass()));
377+
FIREBASE_ASSERT(env.IsInstanceOf(obj_, GeoPointInternal::GetClass()));
379378
cached_type_ = Type::kGeoPoint;
380379
} else {
381380
FIREBASE_ASSERT(cached_type_ == Type::kGeoPoint);
382381
}
383382

384-
return GeoPointInternal::JavaGeoPointToGeoPoint(env, obj_);
383+
return GeoPointInternal(obj_).ToPublic(env);
385384
}
386385

387386
std::vector<FieldValue> FieldValueInternal::array_value() const {

firestore/src/android/firestore_android.cc

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,6 @@ bool FirestoreInternal::Initialize(App* app) {
166166
// Call Initialize on each Firestore internal class.
167167
FieldValueInternal::Initialize(app) &&
168168
FirebaseFirestoreExceptionInternal::Initialize(app) &&
169-
GeoPointInternal::Initialize(app) &&
170169
ListenerRegistrationInternal::Initialize(app) &&
171170
QueryInternal::Initialize(app) &&
172171
TransactionInternal::Initialize(app) && Wrapper::Initialize(app) &&
@@ -196,6 +195,7 @@ bool FirestoreInternal::Initialize(App* app) {
196195
DocumentReferenceInternal::Initialize(loader);
197196
DocumentSnapshotInternal::Initialize(loader);
198197
FieldPathConverter::Initialize(loader);
198+
GeoPointInternal::Initialize(loader);
199199
MetadataChangesInternal::Initialize(loader);
200200
QuerySnapshotInternal::Initialize(loader);
201201
ServerTimestampBehaviorInternal::Initialize(loader);
@@ -254,7 +254,6 @@ void FirestoreInternal::ReleaseClasses(App* app) {
254254
EventListenerInternal::Terminate(app);
255255
FieldValueInternal::Terminate(app);
256256
FirebaseFirestoreExceptionInternal::Terminate(app);
257-
GeoPointInternal::Terminate(app);
258257
ListenerRegistrationInternal::Terminate(app);
259258
QueryInternal::Terminate(app);
260259
TransactionInternal::Terminate(app);

firestore/src/android/geo_point_android.cc

Lines changed: 27 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,65 +1,44 @@
11
#include "firestore/src/android/geo_point_android.h"
22

3-
#include <stdint.h>
4-
5-
#include "app/src/util_android.h"
6-
#include "firestore/src/android/util_android.h"
3+
#include "firestore/src/jni/env.h"
4+
#include "firestore/src/jni/loader.h"
75

86
namespace firebase {
97
namespace firestore {
8+
namespace {
109

11-
// clang-format off
12-
#define GEO_POINT_METHODS(X) \
13-
X(Constructor, "<init>", "(DD)V", util::kMethodTypeInstance), \
14-
X(GetLatitude, "getLatitude", "()D"), \
15-
X(GetLongitude, "getLongitude", "()D")
16-
// clang-format on
10+
using jni::Class;
11+
using jni::Constructor;
12+
using jni::Env;
13+
using jni::Local;
14+
using jni::Method;
1715

18-
METHOD_LOOKUP_DECLARATION(geo_point, GEO_POINT_METHODS)
19-
METHOD_LOOKUP_DEFINITION(geo_point,
20-
PROGUARD_KEEP_CLASS
21-
"com/google/firebase/firestore/GeoPoint",
22-
GEO_POINT_METHODS)
16+
constexpr char kClassName[] =
17+
PROGUARD_KEEP_CLASS "com/google/firebase/firestore/GeoPoint";
18+
Constructor<GeoPointInternal> kConstructor("(DD)V");
19+
Method<double> kGetLatitude("getLatitude", "()D");
20+
Method<double> kGetLongitude("getLongitude", "()D");
2321

24-
/* static */
25-
jobject GeoPointInternal::GeoPointToJavaGeoPoint(JNIEnv* env,
26-
const GeoPoint& point) {
27-
jobject result = env->NewObject(
28-
geo_point::GetClass(), geo_point::GetMethodId(geo_point::kConstructor),
29-
static_cast<jdouble>(point.latitude()),
30-
static_cast<jdouble>(point.longitude()));
31-
CheckAndClearJniExceptions(env);
32-
return result;
33-
}
22+
jclass g_clazz = nullptr;
3423

35-
/* static */
36-
GeoPoint GeoPointInternal::JavaGeoPointToGeoPoint(JNIEnv* env, jobject obj) {
37-
jdouble latitude = env->CallDoubleMethod(
38-
obj, geo_point::GetMethodId(geo_point::kGetLatitude));
39-
jdouble longitude = env->CallDoubleMethod(
40-
obj, geo_point::GetMethodId(geo_point::kGetLongitude));
41-
CheckAndClearJniExceptions(env);
42-
return GeoPoint{static_cast<double>(latitude),
43-
static_cast<double>(longitude)};
24+
} // namespace
25+
26+
void GeoPointInternal::Initialize(jni::Loader& loader) {
27+
g_clazz =
28+
loader.LoadClass(kClassName, kConstructor, kGetLatitude, kGetLongitude);
4429
}
4530

46-
/* static */
47-
jclass GeoPointInternal::GetClass() { return geo_point::GetClass(); }
31+
Class GeoPointInternal::GetClass() { return Class(g_clazz); }
4832

49-
/* static */
50-
bool GeoPointInternal::Initialize(App* app) {
51-
JNIEnv* env = app->GetJNIEnv();
52-
jobject activity = app->activity();
53-
bool result = geo_point::CacheMethodIds(env, activity);
54-
util::CheckAndClearJniExceptions(env);
55-
return result;
33+
Local<GeoPointInternal> GeoPointInternal::Create(Env& env,
34+
const GeoPoint& point) {
35+
return env.New(kConstructor, point.latitude(), point.longitude());
5636
}
5737

58-
/* static */
59-
void GeoPointInternal::Terminate(App* app) {
60-
JNIEnv* env = app->GetJNIEnv();
61-
geo_point::ReleaseClass(env);
62-
util::CheckAndClearJniExceptions(env);
38+
GeoPoint GeoPointInternal::ToPublic(Env& env) const {
39+
double latitude = env.Call(*this, kGetLatitude);
40+
double longitude = env.Call(*this, kGetLongitude);
41+
return GeoPoint(latitude, longitude);
6342
}
6443

6544
} // namespace firestore

firestore/src/android/geo_point_android.h

Lines changed: 12 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,30 @@
11
#ifndef FIREBASE_FIRESTORE_CLIENT_CPP_SRC_ANDROID_GEO_POINT_ANDROID_H_
22
#define FIREBASE_FIRESTORE_CLIENT_CPP_SRC_ANDROID_GEO_POINT_ANDROID_H_
33

4-
#include <jni.h>
5-
6-
#include "app/src/include/firebase/app.h"
4+
#include "firestore/src/jni/jni_fwd.h"
5+
#include "firestore/src/jni/object.h"
76
#include "firebase/firestore/geo_point.h"
87

98
namespace firebase {
109
namespace firestore {
1110

12-
// This is the non-wrapper Android implementation of GeoPoint. Since GeoPoint
13-
// has most methods inlined, we use it directly instead of wrapping around a
14-
// Java GeoPoint object. We still need the helper functions to convert between
15-
// the two types. In addition, we also need proper initializer and terminator
16-
// for the Java class cache/uncache.
17-
class GeoPointInternal {
11+
/** A C++ proxy for a Java `GeoPoint`. */
12+
class GeoPointInternal : public jni::Object {
1813
public:
1914
using ApiType = GeoPoint;
2015

21-
// Convert a C++ GeoPoint into a Java GeoPoint.
22-
static jobject GeoPointToJavaGeoPoint(JNIEnv* env, const GeoPoint& point);
16+
using jni::Object::Object;
2317

24-
// Convert a Java GeoPoint into a C++ GeoPoint.
25-
static GeoPoint JavaGeoPointToGeoPoint(JNIEnv* env, jobject obj);
18+
static void Initialize(jni::Loader& loader);
2619

27-
// Gets the class object of Java GeoPoint class.
28-
static jclass GetClass();
20+
static jni::Class GetClass();
2921

30-
private:
31-
friend class FirestoreInternal;
22+
/** Creates a C++ proxy for a Java `GeoPoint` object. */
23+
static jni::Local<GeoPointInternal> Create(jni::Env& env,
24+
const GeoPoint& point);
3225

33-
static bool Initialize(App* app);
34-
static void Terminate(App* app);
26+
/** Converts a Java GeoPoint to a public C++ GeoPoint. */
27+
GeoPoint ToPublic(jni::Env& env) const;
3528
};
3629

3730
} // namespace firestore
Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,26 @@
11
#include "firestore/src/android/geo_point_android.h"
22

3-
#include <jni.h>
4-
3+
#include "firestore/src/jni/env.h"
54
#include "firestore/src/tests/firestore_integration_test.h"
6-
#include "testing/base/public/gmock.h"
75
#include "gtest/gtest.h"
86
#include "firebase/firestore/geo_point.h"
97

108
namespace firebase {
119
namespace firestore {
10+
namespace {
11+
12+
using jni::Env;
1213

13-
TEST_F(FirestoreIntegrationTest, Converter) {
14-
JNIEnv* env = app()->GetJNIEnv();
14+
using GeoPointTest = FirestoreIntegrationTest;
1515

16-
const GeoPoint point{12.0, 34.0};
17-
jobject java_point = GeoPointInternal::GeoPointToJavaGeoPoint(env, point);
18-
EXPECT_EQ(point, GeoPointInternal::JavaGeoPointToGeoPoint(env, java_point));
16+
TEST_F(GeoPointTest, Converts) {
17+
Env env;
1918

20-
env->DeleteLocalRef(java_point);
19+
GeoPoint point{12.0, 34.0};
20+
auto java_point = GeoPointInternal::Create(env, point);
21+
EXPECT_EQ(point, java_point.ToPublic(env));
2122
}
2223

24+
} // namespace
2325
} // namespace firestore
2426
} // namespace firebase

0 commit comments

Comments
 (0)