Skip to content

Commit 782ec2a

Browse files
wilhuffa-maurice
authored andcommitted
Convert ListenerRegistration to the new JNI framework
PiperOrigin-RevId: 333539837
1 parent f2105db commit 782ec2a

File tree

6 files changed

+60
-58
lines changed

6 files changed

+60
-58
lines changed

firestore/src/android/document_reference_android.cc

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -176,8 +176,7 @@ ListenerRegistration DocumentReferenceInternal::AddSnapshotListener(
176176

177177
if (!env.ok() || !java_registration) return {};
178178
return ListenerRegistration(new ListenerRegistrationInternal(
179-
firestore_, listener, passing_listener_ownership,
180-
java_registration.get()));
179+
firestore_, listener, passing_listener_ownership, java_registration));
181180
}
182181

183182
Class DocumentReferenceInternal::GetClass() { return Class(clazz); }

firestore/src/android/firestore_android.cc

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,6 @@ bool FirestoreInternal::Initialize(App* app) {
176176
if (!( // Call Initialize on each Firestore internal class.
177177
FieldValueInternal::Initialize(app) &&
178178
FirebaseFirestoreExceptionInternal::Initialize(app) &&
179-
ListenerRegistrationInternal::Initialize(app) &&
180179
TransactionInternal::Initialize(app) && Wrapper::Initialize(app) &&
181180
// Initialize those embedded Firestore internal classes.
182181
InitializeEmbeddedClasses(app, loader))) {
@@ -204,6 +203,7 @@ bool FirestoreInternal::Initialize(App* app) {
204203
DocumentSnapshotInternal::Initialize(loader);
205204
FieldPathConverter::Initialize(loader);
206205
GeoPointInternal::Initialize(loader);
206+
ListenerRegistrationInternal::Initialize(loader);
207207
MetadataChangesInternal::Initialize(loader);
208208
QueryInternal::Initialize(loader);
209209
QuerySnapshotInternal::Initialize(loader);
@@ -245,7 +245,6 @@ void FirestoreInternal::ReleaseClasses(App* app) {
245245
EventListenerInternal::Terminate(app);
246246
FieldValueInternal::Terminate(app);
247247
FirebaseFirestoreExceptionInternal::Terminate(app);
248-
ListenerRegistrationInternal::Terminate(app);
249248
TransactionInternal::Terminate(app);
250249
Wrapper::Terminate(app);
251250
}
@@ -402,7 +401,7 @@ ListenerRegistration FirestoreInternal::AddSnapshotsInSyncListener(
402401

403402
if (!env.ok() || !java_registration) return {};
404403
return ListenerRegistration(new ListenerRegistrationInternal(
405-
this, listener, passing_listener_ownership, java_registration.get()));
404+
this, listener, passing_listener_ownership, java_registration));
406405
}
407406

408407
#if defined(FIREBASE_USE_STD_FUNCTION)
Lines changed: 31 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,61 +1,68 @@
11
#include "firestore/src/android/listener_registration_android.h"
22

33
#include "app/src/assert.h"
4-
#include "app/src/util_android.h"
4+
#include "firestore/src/android/firestore_android.h"
55
#include "firestore/src/include/firebase/firestore/listener_registration.h"
6+
#include "firestore/src/jni/env.h"
7+
#include "firestore/src/jni/loader.h"
68

79
namespace firebase {
810
namespace firestore {
11+
namespace {
912

10-
#define LISTENER_REGISTRATION_METHODS(X) X(Remove, "remove", "()V")
11-
METHOD_LOOKUP_DECLARATION(listener_registration, LISTENER_REGISTRATION_METHODS)
12-
METHOD_LOOKUP_DEFINITION(listener_registration,
13-
PROGUARD_KEEP_CLASS
14-
"com/google/firebase/firestore/ListenerRegistration",
15-
LISTENER_REGISTRATION_METHODS)
13+
using jni::Env;
14+
using jni::Object;
15+
16+
constexpr char kClassName[] =
17+
PROGUARD_KEEP_CLASS "com/google/firebase/firestore/ListenerRegistration";
18+
19+
jni::Method<void> kRemove("remove", "()V");
20+
21+
} // namespace
22+
23+
void ListenerRegistrationInternal::Initialize(jni::Loader& loader) {
24+
loader.LoadClass(kClassName, kRemove);
25+
}
1626

1727
ListenerRegistrationInternal::ListenerRegistrationInternal(
1828
FirestoreInternal* firestore,
1929
EventListener<DocumentSnapshot>* event_listener, bool owning_event_listener,
20-
jobject listener_registration)
30+
const Object& listener_registration)
2131
: firestore_(firestore),
22-
listener_registration_(
23-
firestore->app()->GetJNIEnv()->NewGlobalRef(listener_registration)),
32+
listener_registration_(listener_registration),
2433
document_event_listener_(event_listener),
2534
owning_event_listener_(owning_event_listener) {
2635
FIREBASE_ASSERT(firestore != nullptr);
2736
FIREBASE_ASSERT(event_listener != nullptr);
28-
FIREBASE_ASSERT(listener_registration != nullptr);
37+
FIREBASE_ASSERT(listener_registration);
2938

3039
firestore->RegisterListenerRegistration(this);
3140
}
3241

3342
ListenerRegistrationInternal::ListenerRegistrationInternal(
3443
FirestoreInternal* firestore, EventListener<QuerySnapshot>* event_listener,
35-
bool owning_event_listener, jobject listener_registration)
44+
bool owning_event_listener, const Object& listener_registration)
3645
: firestore_(firestore),
37-
listener_registration_(
38-
firestore->app()->GetJNIEnv()->NewGlobalRef(listener_registration)),
46+
listener_registration_(listener_registration),
3947
query_event_listener_(event_listener),
4048
owning_event_listener_(owning_event_listener) {
4149
FIREBASE_ASSERT(firestore != nullptr);
4250
FIREBASE_ASSERT(event_listener != nullptr);
43-
FIREBASE_ASSERT(listener_registration != nullptr);
51+
FIREBASE_ASSERT(listener_registration);
4452

4553
firestore->RegisterListenerRegistration(this);
4654
}
4755

4856
ListenerRegistrationInternal::ListenerRegistrationInternal(
4957
FirestoreInternal* firestore, EventListener<void>* event_listener,
50-
bool owning_event_listener, jobject listener_registration)
58+
bool owning_event_listener, const Object& listener_registration)
5159
: firestore_(firestore),
52-
listener_registration_(
53-
firestore->app()->GetJNIEnv()->NewGlobalRef(listener_registration)),
60+
listener_registration_(listener_registration),
5461
void_event_listener_(event_listener),
5562
owning_event_listener_(owning_event_listener) {
5663
FIREBASE_ASSERT(firestore != nullptr);
5764
FIREBASE_ASSERT(event_listener != nullptr);
58-
FIREBASE_ASSERT(listener_registration != nullptr);
65+
FIREBASE_ASSERT(listener_registration);
5966

6067
firestore->RegisterListenerRegistration(this);
6168
}
@@ -64,18 +71,14 @@ ListenerRegistrationInternal::ListenerRegistrationInternal(
6471
// FirestoreInternal will hold the lock and unregister all of them. So we do not
6572
// call UnregisterListenerRegistration explicitly here.
6673
ListenerRegistrationInternal::~ListenerRegistrationInternal() {
67-
if (listener_registration_ == nullptr) {
74+
if (!listener_registration_) {
6875
return;
6976
}
7077

7178
// Remove listener and release java ListenerRegistration object.
72-
JNIEnv* env = firestore_->app()->GetJNIEnv();
73-
env->CallVoidMethod(
74-
listener_registration_,
75-
listener_registration::GetMethodId(listener_registration::kRemove));
76-
env->DeleteGlobalRef(listener_registration_);
77-
util::CheckAndClearJniExceptions(env);
78-
listener_registration_ = nullptr;
79+
Env env = GetEnv();
80+
env.Call(listener_registration_, kRemove);
81+
listener_registration_.clear();
7982

8083
// de-allocate owning EventListener object.
8184
if (owning_event_listener_) {
@@ -85,21 +88,7 @@ ListenerRegistrationInternal::~ListenerRegistrationInternal() {
8588
}
8689
}
8790

88-
/* static */
89-
bool ListenerRegistrationInternal::Initialize(App* app) {
90-
JNIEnv* env = app->GetJNIEnv();
91-
jobject activity = app->activity();
92-
bool result = listener_registration::CacheMethodIds(env, activity);
93-
util::CheckAndClearJniExceptions(env);
94-
return result;
95-
}
96-
97-
/* static */
98-
void ListenerRegistrationInternal::Terminate(App* app) {
99-
JNIEnv* env = app->GetJNIEnv();
100-
listener_registration::ReleaseClass(env);
101-
util::CheckAndClearJniExceptions(env);
102-
}
91+
jni::Env ListenerRegistrationInternal::GetEnv() { return firestore_->GetEnv(); }
10392

10493
} // namespace firestore
10594
} // namespace firebase

firestore/src/android/listener_registration_android.h

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
#ifndef FIREBASE_FIRESTORE_CLIENT_CPP_SRC_ANDROID_LISTENER_REGISTRATION_ANDROID_H_
22
#define FIREBASE_FIRESTORE_CLIENT_CPP_SRC_ANDROID_LISTENER_REGISTRATION_ANDROID_H_
33

4-
#include <jni.h>
54
#include "firestore/src/android/firestore_android.h"
65
#include "firestore/src/include/firebase/firestore/document_snapshot.h"
76
#include "firestore/src/include/firebase/firestore/event_listener.h"
87
#include "firestore/src/include/firebase/firestore/query_snapshot.h"
8+
#include "firestore/src/jni/jni_fwd.h"
9+
#include "firestore/src/jni/object.h"
10+
#include "firestore/src/jni/ownership.h"
911

1012
namespace firebase {
1113
namespace firestore {
@@ -22,21 +24,23 @@ class ListenerRegistrationInternal {
2224
public:
2325
using ApiType = ListenerRegistration;
2426

27+
static void Initialize(jni::Loader& loader);
28+
2529
// Global references will be created from the jobjects. The caller is
2630
// responsible for cleaning up any local references to jobjects after the
2731
// constructor returns.
2832
ListenerRegistrationInternal(FirestoreInternal* firestore,
2933
EventListener<DocumentSnapshot>* event_listener,
3034
bool owning_event_listener,
31-
jobject listener_registration);
35+
const jni::Object& listener_registration);
3236
ListenerRegistrationInternal(FirestoreInternal* firestore,
3337
EventListener<QuerySnapshot>* event_listener,
3438
bool owning_event_listener,
35-
jobject listener_registration);
39+
const jni::Object& listener_registration);
3640
ListenerRegistrationInternal(FirestoreInternal* firestore,
3741
EventListener<void>* event_listener,
3842
bool owning_event_listener,
39-
jobject listener_registration);
43+
const jni::Object& listener_registration);
4044

4145
// Delete the default one to make the ownership more obvious i.e.
4246
// FirestoreInternal owns each instance and forbid anyone else to make copy.
@@ -57,13 +61,11 @@ class ListenerRegistrationInternal {
5761

5862
private:
5963
friend class DocumentReferenceInternal;
60-
friend class FirestoreInternal;
6164

62-
static bool Initialize(App* app);
63-
static void Terminate(App* app);
65+
jni::Env GetEnv();
6466

6567
FirestoreInternal* firestore_ = nullptr; // not owning
66-
jobject listener_registration_ = nullptr;
68+
jni::Global<jni::Object> listener_registration_;
6769

6870
// May own it, see owning_event_listener_. If user pass in an EventListener
6971
// directly, then the registration does not own it. If user pass in a lambda,

firestore/src/android/query_android.cc

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -294,10 +294,8 @@ ListenerRegistration QueryInternal::AddSnapshotListener(
294294
java_metadata, java_listener);
295295

296296
if (!env.ok()) return {};
297-
298297
return ListenerRegistration(new ListenerRegistrationInternal(
299-
firestore_, listener, passing_listener_ownership,
300-
java_registration.get()));
298+
firestore_, listener, passing_listener_ownership, java_registration));
301299
}
302300

303301
Local<Array<Object>> QueryInternal::ConvertFieldValues(

firestore/src/jni/ownership.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,13 @@ class Local : public T {
104104
return static_cast<jni_type>(result);
105105
}
106106

107+
void clear() {
108+
if (env_ && T::object_) {
109+
env_->DeleteLocalRef(T::object_);
110+
T::object_ = nullptr;
111+
}
112+
}
113+
107114
JNIEnv* env() const { return env_; }
108115

109116
private:
@@ -226,6 +233,14 @@ class Global : public T {
226233
return static_cast<jni_type>(result);
227234
}
228235

236+
void clear() {
237+
if (T::object_) {
238+
JNIEnv* env = GetEnv();
239+
env->DeleteGlobalRef(T::object_);
240+
T::object_ = nullptr;
241+
}
242+
}
243+
229244
private:
230245
JNIEnv* EnsureEnv(JNIEnv* other = nullptr) {
231246
if (other != nullptr) {

0 commit comments

Comments
 (0)