Skip to content

Commit 435481d

Browse files
wilhuffa-maurice
authored andcommitted
Convert WriteBatch to the new JNI framework
PiperOrigin-RevId: 329805287
1 parent a88486e commit 435481d

File tree

3 files changed

+61
-85
lines changed

3 files changed

+61
-85
lines changed

firestore/src/android/firestore_android.cc

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,6 @@ bool FirestoreInternal::Initialize(App* app) {
172172
QuerySnapshotInternal::Initialize(app) &&
173173
TimestampInternal::Initialize(app) &&
174174
TransactionInternal::Initialize(app) && Wrapper::Initialize(app) &&
175-
WriteBatchInternal::Initialize(app) &&
176175
// Initialize those embedded Firestore internal classes.
177176
InitializeEmbeddedClasses(app))) {
178177
ReleaseClasses(app);
@@ -205,6 +204,7 @@ bool FirestoreInternal::Initialize(App* app) {
205204
SettingsInternal::Initialize(loader);
206205
SnapshotMetadataInternal::Initialize(loader);
207206
SourceInternal::Initialize(loader);
207+
WriteBatchInternal::Initialize(loader);
208208
if (!loader.ok()) {
209209
ReleaseClasses(app);
210210
return false;
@@ -261,7 +261,6 @@ void FirestoreInternal::ReleaseClasses(App* app) {
261261
TimestampInternal::Terminate(app);
262262
TransactionInternal::Terminate(app);
263263
Wrapper::Terminate(app);
264-
WriteBatchInternal::Terminate(app);
265264
}
266265

267266
/* static */

firestore/src/android/write_batch_android.cc

Lines changed: 37 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,12 @@
11
#include "firestore/src/android/write_batch_android.h"
22

3-
#include <jni.h>
4-
5-
#include <utility>
6-
7-
#include "app/src/util_android.h"
83
#include "firestore/src/android/document_reference_android.h"
94
#include "firestore/src/android/field_path_android.h"
105
#include "firestore/src/android/field_value_android.h"
116
#include "firestore/src/android/set_options_android.h"
12-
#include "firestore/src/android/util_android.h"
137
#include "firestore/src/jni/env.h"
148
#include "firestore/src/jni/hash_map.h"
9+
#include "firestore/src/jni/loader.h"
1510

1611
namespace firebase {
1712
namespace firestore {
@@ -20,33 +15,35 @@ namespace {
2015
using jni::Env;
2116
using jni::HashMap;
2217
using jni::Local;
18+
using jni::Method;
2319
using jni::Object;
2420

21+
constexpr char kClassName[] =
22+
PROGUARD_KEEP_CLASS "com/google/firebase/firestore/WriteBatch";
23+
Method<Object> kSet(
24+
"set",
25+
"(Lcom/google/firebase/firestore/DocumentReference;Ljava/lang/Object;"
26+
"Lcom/google/firebase/firestore/SetOptions;)"
27+
"Lcom/google/firebase/firestore/WriteBatch;");
28+
Method<Object> kUpdate(
29+
"update",
30+
"(Lcom/google/firebase/firestore/DocumentReference;Ljava/util/Map;)"
31+
"Lcom/google/firebase/firestore/WriteBatch;");
32+
Method<Object> kUpdateVarargs(
33+
"update",
34+
"(Lcom/google/firebase/firestore/DocumentReference;"
35+
"Lcom/google/firebase/firestore/FieldPath;Ljava/lang/Object;"
36+
"[Ljava/lang/Object;)Lcom/google/firebase/firestore/WriteBatch;");
37+
Method<Object> kDelete("delete",
38+
"(Lcom/google/firebase/firestore/DocumentReference;)"
39+
"Lcom/google/firebase/firestore/WriteBatch;");
40+
Method<Object> kCommit("commit", "()Lcom/google/android/gms/tasks/Task;");
41+
2542
} // namespace
2643

27-
// clang-format off
28-
#define WRITE_BATCH_METHODS(X) \
29-
X(Set, "set", \
30-
"(Lcom/google/firebase/firestore/DocumentReference;Ljava/lang/Object;" \
31-
"Lcom/google/firebase/firestore/SetOptions;)" \
32-
"Lcom/google/firebase/firestore/WriteBatch;"), \
33-
X(Update, "update", \
34-
"(Lcom/google/firebase/firestore/DocumentReference;Ljava/util/Map;)" \
35-
"Lcom/google/firebase/firestore/WriteBatch;"), \
36-
X(UpdateVarargs, "update", \
37-
"(Lcom/google/firebase/firestore/DocumentReference;" \
38-
"Lcom/google/firebase/firestore/FieldPath;Ljava/lang/Object;" \
39-
"[Ljava/lang/Object;)Lcom/google/firebase/firestore/WriteBatch;"), \
40-
X(Delete, "delete", "(Lcom/google/firebase/firestore/DocumentReference;)" \
41-
"Lcom/google/firebase/firestore/WriteBatch;"), \
42-
X(Commit, "commit", "()Lcom/google/android/gms/tasks/Task;")
43-
// clang-format on
44-
45-
METHOD_LOOKUP_DECLARATION(write_batch, WRITE_BATCH_METHODS)
46-
METHOD_LOOKUP_DEFINITION(write_batch,
47-
PROGUARD_KEEP_CLASS
48-
"com/google/firebase/firestore/WriteBatch",
49-
WRITE_BATCH_METHODS)
44+
void WriteBatchInternal::Initialize(jni::Loader& loader) {
45+
loader.LoadClass(kClassName, kSet, kUpdate, kUpdateVarargs, kDelete, kCommit);
46+
}
5047

5148
void WriteBatchInternal::Set(const DocumentReference& document,
5249
const MapFieldValue& data,
@@ -55,19 +52,15 @@ void WriteBatchInternal::Set(const DocumentReference& document,
5552
Local<HashMap> java_data = MakeJavaMap(env, data);
5653
Local<Object> java_options = SetOptionsInternal::Create(env, options);
5754

58-
// Returned value is just Java `this` and can be ignored.
59-
env.Call<Object>(obj_, write_batch::GetMethodId(write_batch::kSet),
60-
document.internal_->ToJava(), java_data, java_options);
55+
env.Call(obj_, kSet, ToJni(document), java_data, java_options);
6156
}
6257

6358
void WriteBatchInternal::Update(const DocumentReference& document,
6459
const MapFieldValue& data) {
6560
Env env = GetEnv();
6661
Local<HashMap> java_data = MakeJavaMap(env, data);
6762

68-
// Returned value is just Java `this` and can be ignored.
69-
env.Call<Object>(obj_, write_batch::GetMethodId(write_batch::kUpdate),
70-
document.internal_->ToJava(), java_data);
63+
env.Call(obj_, kUpdate, ToJni(document), java_data);
7164
}
7265

7366
void WriteBatchInternal::Update(const DocumentReference& document,
@@ -80,47 +73,23 @@ void WriteBatchInternal::Update(const DocumentReference& document,
8073
Env env = GetEnv();
8174
UpdateFieldPathArgs args = MakeUpdateFieldPathArgs(env, data);
8275

83-
// Returned value is just Java `this` and can be ignored.
84-
env.Call<Object>(obj_, write_batch::GetMethodId(write_batch::kUpdateVarargs),
85-
document.internal_->ToJava(), args.first_field,
86-
args.first_value, args.varargs);
76+
env.Call(obj_, kUpdateVarargs, ToJni(document), args.first_field,
77+
args.first_value, args.varargs);
8778
}
8879

8980
void WriteBatchInternal::Delete(const DocumentReference& document) {
90-
JNIEnv* env = firestore_->app()->GetJNIEnv();
91-
92-
env->CallObjectMethod(obj_, write_batch::GetMethodId(write_batch::kDelete),
93-
document.internal_->java_object());
94-
CheckAndClearJniExceptions(env);
81+
Env env = GetEnv();
82+
env.Call(obj_, kDelete, ToJni(document));
9583
}
9684

9785
Future<void> WriteBatchInternal::Commit() {
98-
JNIEnv* env = firestore_->app()->GetJNIEnv();
99-
jobject task = env->CallObjectMethod(
100-
obj_, write_batch::GetMethodId(write_batch::kCommit));
101-
CheckAndClearJniExceptions(env);
102-
103-
auto promise = promises_.MakePromise<void>();
104-
promise.RegisterForTask(WriteBatchFn::kCommit, task);
105-
env->DeleteLocalRef(task);
106-
CheckAndClearJniExceptions(env);
107-
return promise.GetFuture();
108-
}
109-
110-
/* static */
111-
bool WriteBatchInternal::Initialize(App* app) {
112-
JNIEnv* env = app->GetJNIEnv();
113-
jobject activity = app->activity();
114-
bool result = write_batch::CacheMethodIds(env, activity);
115-
util::CheckAndClearJniExceptions(env);
116-
return result;
86+
Env env = GetEnv();
87+
Local<Object> task = env.Call(obj_, kCommit);
88+
return promises_.NewFuture<void>(env, AsyncFn::kCommit, task);
11789
}
11890

119-
/* static */
120-
void WriteBatchInternal::Terminate(App* app) {
121-
JNIEnv* env = app->GetJNIEnv();
122-
write_batch::ReleaseClass(env);
123-
util::CheckAndClearJniExceptions(env);
91+
jni::Object WriteBatchInternal::ToJni(const DocumentReference& reference) {
92+
return reference.internal_ ? reference.internal_->ToJava() : jni::Object();
12493
}
12594

12695
} // namespace firestore

firestore/src/android/write_batch_android.h

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,21 @@
1010
namespace firebase {
1111
namespace firestore {
1212

13-
// Each API of WriteBatch that returns a Future needs to define an enum value
14-
// here. For example, a Future-returning method Foo() relies on the enum value
15-
// kFoo. The enum values are used to identify and manage Future in the Firestore
16-
// Future manager.
17-
enum class WriteBatchFn {
18-
kCommit = 0,
19-
kCount, // Must be the last enum value.
20-
};
21-
2213
class WriteBatchInternal : public Wrapper {
2314
public:
2415
using ApiType = WriteBatch;
2516

17+
// Each API of WriteBatch that returns a Future needs to define an enum value
18+
// here. For example, a Future-returning method Foo() relies on the enum value
19+
// kFoo. The enum values are used to identify and manage Future in the
20+
// Firestore Future manager.
21+
enum class AsyncFn {
22+
kCommit = 0,
23+
kCount, // Must be the last enum value.
24+
};
25+
26+
static void Initialize(jni::Loader& loader);
27+
2628
WriteBatchInternal(FirestoreInternal* firestore, jobject object)
2729
: Wrapper(firestore, object), promises_(firestore) {}
2830

@@ -38,12 +40,18 @@ class WriteBatchInternal : public Wrapper {
3840
Future<void> Commit();
3941

4042
private:
41-
friend class FirestoreInternal;
42-
43-
static bool Initialize(App* app);
44-
static void Terminate(App* app);
45-
46-
PromiseFactory<WriteBatchFn> promises_;
43+
/**
44+
* Converts a public DocumentReference to a non-owning proxy for its backing
45+
* Java object. The Java object is owned by the DocumentReference.
46+
*
47+
* Note: this method is not visible to `Env`, so this must still be invoked
48+
* manually for arguments passed to `Env` methods.
49+
*/
50+
// TODO(mcg): Move this out of WriteBatchInternal
51+
// This needs to be here now because of existing friend relationships.
52+
static jni::Object ToJni(const DocumentReference& reference);
53+
54+
PromiseFactory<AsyncFn> promises_;
4755
};
4856

4957
} // namespace firestore

0 commit comments

Comments
 (0)