Skip to content

Commit a72cf60

Browse files
committed
Merge branch 'floc-master' of github.com:firebase/firebase-android-sdk into arete-floc
2 parents b381889 + a7b5684 commit a72cf60

File tree

17 files changed

+265
-207
lines changed

17 files changed

+265
-207
lines changed

buildSrc/src/main/groovy/com/google/firebase/gradle/plugins/measurement/coverage/GenerateMeasurementsTask.groovy

Lines changed: 28 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,12 @@
1515

1616
package com.google.firebase.gradle.plugins.measurement.coverage
1717

18+
import groovy.json.JsonOutput
19+
import java.text.SimpleDateFormat
1820
import org.gradle.api.DefaultTask
19-
import org.gradle.api.Project
2021
import org.gradle.api.tasks.OutputFile
2122
import org.gradle.api.tasks.TaskAction
23+
import com.google.firebase.gradle.plugins.FirebaseLibraryExtension
2224
import org.gradle.testing.jacoco.tasks.JacocoReport
2325

2426

@@ -38,6 +40,8 @@ public class GenerateMeasurementsTask extends DefaultTask {
3840

3941
assert project.tasks.withType(JacocoReport).size() == 1 : 'Found multiple tasks which generate coverage reports.'
4042
coverageTaskName = project.tasks.withType(JacocoReport)[0].name
43+
44+
dependsOn(findAllProductCoverageTasks())
4145
}
4246

4347
@TaskAction
@@ -50,7 +54,11 @@ public class GenerateMeasurementsTask extends DefaultTask {
5054
}
5155
}
5256

53-
private def getCoveragePercentFromReport(_project) {
57+
// This method was called in a closure in `generateJson` method. At runtime,
58+
// the closure is bound to a synthetic child class of this class generated
59+
// by Gradle.
60+
// Need to mark as protected or public to be callable within the closure.
61+
protected def getCoverageForProject(_project) {
5462
def path = "${_project.jacoco.reportsDir}/${coverageTaskName}/${coverageTaskName}.xml"
5563
try {
5664
def report = parser.parse(path)
@@ -68,63 +76,34 @@ public class GenerateMeasurementsTask extends DefaultTask {
6876
}
6977
}
7078

71-
private def trimProjectPathLeadingColon(path) {
72-
return path.startsWith(':') ? path.drop(1) : path
79+
private def findAllFirebaseProductProjects() {
80+
return project.rootProject.allprojects.findAll {
81+
it.extensions.findByType(FirebaseLibraryExtension) != null
82+
}
83+
}
84+
85+
private def findAllProductCoverageTasks() {
86+
return findAllFirebaseProductProjects().collect {
87+
it.tasks.withType(JacocoReport)
88+
}.flatten()
7389
}
7490

7591
private def generateJson(pullRequestNumber) {
76-
def coverages = [:]
77-
78-
// TODO(yifany@): Consolidate mappings with apksize and iOS.
79-
def sdkMap = [
80-
'firebase-common': 0,
81-
'firebase-common-ktx': 1,
82-
'firebase-database': 2,
83-
'firebase-database-collection': 3,
84-
'firebase-firestore': 4,
85-
'firebase-firestore-ktx': 5,
86-
'firebase-functions': 6,
87-
'firebase-inappmessaging-display': 7,
88-
'firebase-storage': 8,
89-
'firebase-datatransport': 9,
90-
91-
// 'firebase-common-ktx' and 'firebase-firestore-ktx' has been
92-
// made a subproject of their corresponding java projects in PR
93-
// #409 and #426. Old mappings are kept for backward
94-
// compatibility reason.
95-
'firebase-common:ktx': 10,
96-
'firebase-firestore:ktx': 11
97-
]
98-
99-
for (Project p: project.rootProject.subprojects) {
100-
def name = trimProjectPathLeadingColon(p.path)
101-
if (name.startsWith('firebase')) {
102-
def percent = getCoveragePercentFromReport(p)
103-
if (sdkMap.containsKey(name)) {
104-
coverages[sdkMap[name]] = percent
105-
} else {
106-
project.logger.warn("Find SDK with name: $name not defined in the SDK to ID mapping.")
107-
}
108-
}
109-
}
92+
def now = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())
93+
def projects = findAllFirebaseProductProjects()
11094

111-
def replacements = coverages.collect {
112-
"[$pullRequestNumber, $it.key, $it.value]"
113-
}.join(", ")
95+
def replacements = projects.collect {
96+
[ it.path, pullRequestNumber, getCoverageForProject(it), now ]
97+
}
11498

11599
// TODO(yifany@): Better way of formatting json. No hard code names.
116100
def json = """
117101
{
118102
tables: [
119103
{
120-
table_name: "PullRequests",
121-
column_names: ["pull_request_id"],
122-
replace_measurements: [[$pullRequestNumber]],
123-
},
124-
{
125-
table_name: "Coverage2",
126-
column_names: ["pull_request_id", "sdk_id", "coverage_percent"],
127-
replace_measurements: [$replacements],
104+
table_name: "AndroidCodeCoverage",
105+
column_names: ["product_name", "pull_request_id", "coverage_total", "collection_time"],
106+
replace_measurements: ${JsonOutput.toJson(replacements)},
128107
},
129108
],
130109
}

buildSrc/src/test/groovy/com/google/firebase/gradle/plugins/measurement/apksize/ApkSizeTestProject.groovy

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@ class ApkSizeTestProject extends ExternalResource {
157157

158158
Files.createDirectories(dest)
159159
FileUtils.copyDirectory(src.toFile(), dest.toFile())
160+
FileUtils.deleteDirectory(dest.resolve("coverage").toFile())
160161
}
161162

162163
/** Creates the fake project files for the temporary project. */

firebase-firestore/CHANGELOG.md

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,24 @@
11
# Unreleased
2+
- [changed] Instead of failing silently, Firestore now crashes the client app
3+
if it fails to load SSL Ciphers. To avoid these crashes, you must bundle
4+
Conscrypt to support non-GMSCore devices on Android KitKat or JellyBean (see
5+
https://github.com/grpc/grpc-java/blob/master/SECURITY.md#tls-on-android).
6+
7+
# 20.1.0
28
- [changed] SSL and gRPC initialization now happens on a separate thread, which
39
reduces the time taken to produce the first query result.
4-
- [fixed] Updated gRPC to 1.21.0. A bug in the prior version would occasionally
5-
cause a crash if a network state change occurred concurrently with an RPC.
6-
(#428)
710
- [feature] Added `clearPersistence()`, which clears the persistent storage
811
including pending writes and cached documents. This is intended to help
912
write reliable tests (https://github.com/firebase/firebase-js-sdk/issues/449).
1013

14+
# 20.0.0
15+
- [changed] Migrated from the Android Support Libraries to the Jetpack
16+
(AndroidX) Libraries.
17+
18+
# 19.0.2
19+
- [fixed] Updated gRPC to 1.21.0. A bug in the prior version would occasionally
20+
cause a crash if a network state change occurred concurrently with an RPC.
21+
(#428)
1122

1223
# 19.0.1
1324
- [fixed] Fixed an issue that prevented schema migrations for clients with

firebase-firestore/src/main/java/com/google/firebase/firestore/DocumentSnapshot.java

Lines changed: 64 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,10 @@
2424
import com.google.firebase.firestore.model.DocumentKey;
2525
import com.google.firebase.firestore.model.value.ArrayValue;
2626
import com.google.firebase.firestore.model.value.FieldValue;
27-
import com.google.firebase.firestore.model.value.FieldValueOptions;
2827
import com.google.firebase.firestore.model.value.ObjectValue;
2928
import com.google.firebase.firestore.model.value.ReferenceValue;
29+
import com.google.firebase.firestore.model.value.ServerTimestampValue;
30+
import com.google.firebase.firestore.model.value.TimestampValue;
3031
import com.google.firebase.firestore.util.CustomClassMapper;
3132
import com.google.firebase.firestore.util.Logger;
3233
import java.util.ArrayList;
@@ -80,6 +81,18 @@ public enum ServerTimestampBehavior {
8081
static final ServerTimestampBehavior DEFAULT = ServerTimestampBehavior.NONE;
8182
}
8283

84+
/** Holds settings that define field value deserialization options. */
85+
static class FieldValueOptions {
86+
final ServerTimestampBehavior serverTimestampBehavior;
87+
final boolean timestampsInSnapshotsEnabled;
88+
89+
private FieldValueOptions(
90+
ServerTimestampBehavior serverTimestampBehavior, boolean timestampsInSnapshotsEnabled) {
91+
this.serverTimestampBehavior = serverTimestampBehavior;
92+
this.timestampsInSnapshotsEnabled = timestampsInSnapshotsEnabled;
93+
}
94+
}
95+
8396
private final FirebaseFirestore firestore;
8497

8598
private final DocumentKey key;
@@ -165,7 +178,7 @@ public Map<String, Object> getData(@NonNull ServerTimestampBehavior serverTimest
165178
? null
166179
: convertObject(
167180
doc.getData(),
168-
FieldValueOptions.create(
181+
new FieldValueOptions(
169182
serverTimestampBehavior,
170183
firestore.getFirestoreSettings().areTimestampsInSnapshotsEnabled()));
171184
}
@@ -286,7 +299,7 @@ public Object get(
286299
serverTimestampBehavior, "Provided serverTimestampBehavior value must not be null.");
287300
return getInternal(
288301
fieldPath.getInternalPath(),
289-
FieldValueOptions.create(
302+
new FieldValueOptions(
290303
serverTimestampBehavior,
291304
firestore.getFirestoreSettings().areTimestampsInSnapshotsEnabled()));
292305
}
@@ -449,7 +462,7 @@ public Date getDate(
449462
Object maybeDate =
450463
getInternal(
451464
FieldPath.fromDotSeparatedPath(field).getInternalPath(),
452-
FieldValueOptions.create(
465+
new FieldValueOptions(
453466
serverTimestampBehavior, /*timestampsInSnapshotsEnabled=*/ false));
454467
return castTypedValue(maybeDate, field, Date.class);
455468
}
@@ -492,8 +505,7 @@ public Timestamp getTimestamp(
492505
Object maybeTimestamp =
493506
getInternal(
494507
FieldPath.fromDotSeparatedPath(field).getInternalPath(),
495-
FieldValueOptions.create(
496-
serverTimestampBehavior, /*timestampsInSnapshotsEnabled=*/ true));
508+
new FieldValueOptions(serverTimestampBehavior, /*timestampsInSnapshotsEnabled=*/ true));
497509
return castTypedValue(maybeTimestamp, field, Timestamp.class);
498510
}
499511

@@ -571,29 +583,56 @@ private Object convertValue(FieldValue value, FieldValueOptions options) {
571583
} else if (value instanceof ArrayValue) {
572584
return convertArray((ArrayValue) value, options);
573585
} else if (value instanceof ReferenceValue) {
574-
ReferenceValue referenceValue = (ReferenceValue) value;
575-
DocumentKey key = (DocumentKey) referenceValue.value(options);
576-
DatabaseId refDatabase = ((ReferenceValue) value).getDatabaseId();
577-
DatabaseId database = this.firestore.getDatabaseId();
578-
if (!refDatabase.equals(database)) {
579-
// TODO: Somehow support foreign references.
580-
Logger.warn(
581-
"DocumentSnapshot",
582-
"Document %s contains a document reference within a different database "
583-
+ "(%s/%s) which is not supported. It will be treated as a reference in "
584-
+ "the current database (%s/%s) instead.",
585-
key.getPath(),
586-
refDatabase.getProjectId(),
587-
refDatabase.getDatabaseId(),
588-
database.getProjectId(),
589-
database.getDatabaseId());
590-
}
591-
return new DocumentReference(key, firestore);
586+
return convertReference((ReferenceValue) value);
587+
} else if (value instanceof TimestampValue) {
588+
return convertTimestamp((TimestampValue) value, options);
589+
} else if (value instanceof ServerTimestampValue) {
590+
return convertServerTimestamp((ServerTimestampValue) value, options);
591+
} else {
592+
return value.value();
593+
}
594+
}
595+
596+
private Object convertServerTimestamp(ServerTimestampValue value, FieldValueOptions options) {
597+
switch (options.serverTimestampBehavior) {
598+
case PREVIOUS:
599+
return value.getPreviousValue();
600+
case ESTIMATE:
601+
return value.getLocalWriteTime();
602+
default:
603+
return value.value();
604+
}
605+
}
606+
607+
private Object convertTimestamp(TimestampValue value, FieldValueOptions options) {
608+
Timestamp timestamp = value.value();
609+
if (options.timestampsInSnapshotsEnabled) {
610+
return timestamp;
592611
} else {
593-
return value.value(options);
612+
return timestamp.toDate();
594613
}
595614
}
596615

616+
private Object convertReference(ReferenceValue value) {
617+
DocumentKey key = value.value();
618+
DatabaseId refDatabase = value.getDatabaseId();
619+
DatabaseId database = this.firestore.getDatabaseId();
620+
if (!refDatabase.equals(database)) {
621+
// TODO: Somehow support foreign references.
622+
Logger.warn(
623+
"DocumentSnapshot",
624+
"Document %s contains a document reference within a different database "
625+
+ "(%s/%s) which is not supported. It will be treated as a reference in "
626+
+ "the current database (%s/%s) instead.",
627+
key.getPath(),
628+
refDatabase.getProjectId(),
629+
refDatabase.getDatabaseId(),
630+
database.getProjectId(),
631+
database.getDatabaseId());
632+
}
633+
return new DocumentReference(key, firestore);
634+
}
635+
597636
private Map<String, Object> convertObject(ObjectValue objectValue, FieldValueOptions options) {
598637
Map<String, Object> result = new HashMap<>();
599638
for (Map.Entry<String, FieldValue> entry : objectValue.getInternalValue()) {

firebase-firestore/src/main/java/com/google/firebase/firestore/model/value/ArrayValue.java

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -70,16 +70,6 @@ public List<Object> value() {
7070
return res;
7171
}
7272

73-
@Override
74-
public List<Object> value(FieldValueOptions options) {
75-
// Recursively convert the array into the value that users will see in document snapshots.
76-
List<Object> res = new ArrayList<>(internalValue.size());
77-
for (FieldValue v : internalValue) {
78-
res.add(v.value(options));
79-
}
80-
return res;
81-
}
82-
8373
public List<FieldValue> getInternalValue() {
8474
return internalValue;
8575
}

firebase-firestore/src/main/java/com/google/firebase/firestore/model/value/FieldValue.java

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -63,15 +63,6 @@ public abstract class FieldValue implements Comparable<FieldValue> {
6363
@Nullable
6464
public abstract Object value();
6565

66-
/**
67-
* Converts a FieldValue into the value that users will see in document snapshots using the
68-
* provided deserialization options.
69-
*/
70-
@Nullable
71-
public Object value(FieldValueOptions options) {
72-
return value();
73-
}
74-
7566
@Override
7667
public abstract boolean equals(Object o);
7768

firebase-firestore/src/main/java/com/google/firebase/firestore/model/value/FieldValueOptions.java

Lines changed: 0 additions & 66 deletions
This file was deleted.

0 commit comments

Comments
 (0)