Skip to content

Commit 37167c1

Browse files
authored
Merge 3ee8545 into 57aaf39
2 parents 57aaf39 + 3ee8545 commit 37167c1

File tree

5 files changed

+48
-66
lines changed

5 files changed

+48
-66
lines changed

firebase-crashlytics/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
* [feature] Added the `isCrashlyticsCollectionEnabled` API to check if Crashlytics collection is enabled.
33
([Github #5919](//github.com/firebase/firebase-android-sdk/issues/5919))
44
* [fixed] Ensure that on-demand fatal events are never processed on the main thread.
5+
* [changed] Internal changes to the way session IDs are generated.
56

67

78
# 19.0.3

firebase-crashlytics/src/androidTest/java/com/google/firebase/crashlytics/internal/common/CLSUUIDTest.java

Lines changed: 25 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -14,63 +14,41 @@
1414

1515
package com.google.firebase.crashlytics.internal.common;
1616

17-
import static org.mockito.Mockito.mock;
18-
import static org.mockito.Mockito.when;
17+
import static com.google.common.truth.Truth.assertThat;
1918

20-
import com.google.android.gms.tasks.Tasks;
21-
import com.google.firebase.crashlytics.internal.CrashlyticsTestCase;
22-
import com.google.firebase.installations.FirebaseInstallationsApi;
19+
import java.util.ArrayList;
20+
import org.junit.Test;
2321

24-
public class CLSUUIDTest extends CrashlyticsTestCase {
25-
26-
private IdManager idManager;
27-
private CLSUUID uuid;
28-
29-
protected void setUp() throws Exception {
30-
super.setUp();
31-
FirebaseInstallationsApi installationsApiMock = mock(FirebaseInstallationsApi.class);
32-
when(installationsApiMock.getId()).thenReturn(Tasks.forResult("instanceId"));
33-
idManager =
34-
new IdManager(
35-
getContext(),
36-
getContext().getPackageName(),
37-
installationsApiMock,
38-
DataCollectionArbiterTest.MOCK_ARBITER_ENABLED);
39-
uuid = new CLSUUID(idManager);
40-
}
41-
42-
protected void tearDown() throws Exception {
43-
super.tearDown();
44-
uuid = null;
45-
}
22+
public class CLSUUIDTest {
4623

4724
/** Basic test of the CLSUUID string value. */
48-
public void testToString() {
49-
final String s = uuid.toString();
50-
assertNotNull("The uuid string value should not be null", s);
51-
assertEquals("The uuid string value should be 32 chars long", 32, s.length());
25+
@Test
26+
public void getSessionId() {
27+
String sessionId = new CLSUUID().getSessionId();
28+
assertThat(sessionId).isNotNull(); // The session id should not be null
29+
assertThat(sessionId).hasLength(32); // The session id should be 32 chars long
5230
}
5331

5432
/** Test that we don't get duplicate CLSUUID string values in a set of 100 uuid generated. */
55-
public void testOrder() {
56-
final String[] uuids = new String[100];
57-
CLSUUID uuid = null;
33+
@Test
34+
public void sessionIdsInOrder() {
35+
ArrayList<String> sessionIds = new ArrayList<>();
5836

59-
// Put 100 CLSUUID string values into an array.
37+
// Put 100 CLSUUID string values into a list.
6038
for (int i = 0; i < 100; i++) {
61-
uuid = new CLSUUID(idManager);
62-
uuids[i] = uuid.toString();
39+
sessionIds.add(new CLSUUID().getSessionId());
6340
}
6441

65-
// Assert that the other 99 CLSUUIDs don't match the current index in the loop.
66-
for (int i = 0; i < uuids.length; i++) {
67-
final String uuidAtIndex = uuids[i];
68-
for (int j = 0; j < uuids.length; j++) {
69-
if (i != j) {
70-
assertFalse(
71-
"We shouldn't have the same uuid at another index.", uuidAtIndex.equals(uuids[j]));
72-
}
73-
}
74-
}
42+
assertThat(sessionIds).isInOrder();
43+
assertThat(sessionIds).containsNoDuplicates();
44+
}
45+
46+
/** Test that we pad session ids properly. */
47+
@Test
48+
public void sessionIdsArePadded() {
49+
String sessionId1 = new CLSUUID().getSessionId();
50+
String sessionId2 = new CLSUUID().getSessionId();
51+
52+
assertThat(sessionId1.substring(20)).isEqualTo(sessionId2.substring(20));
7553
}
7654
}

firebase-crashlytics/src/main/java/com/google/firebase/crashlytics/internal/common/CLSUUID.java

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -18,44 +18,46 @@
1818
import java.nio.ByteOrder;
1919
import java.util.Date;
2020
import java.util.Locale;
21+
import java.util.UUID;
2122
import java.util.concurrent.atomic.AtomicLong;
2223

2324
/**
2425
* A UUID whose lexicographical ordering is equivalent to a temporal ordering. Uniqueness is based
25-
* on timestamp, sequence identifier, processId, and a hash of the application installation
26-
* identifier.
27-
*
28-
* <p>Applications which generate colliding app installation identifiers are at risk of creating
29-
* colliding CLSUUIDs.
26+
* on timestamp, sequence identifier, processId, and a random hash.
3027
*/
3128
class CLSUUID {
32-
private static final AtomicLong _sequenceNumber = new AtomicLong(0);
3329

34-
private static String _clsId;
30+
// Padding to ensure the id is long enough, has only valid hex characters, and increase entropy.
31+
private static final String ID_SHA =
32+
CommonUtils.sha1(UUID.randomUUID().toString() + System.currentTimeMillis());
3533

36-
CLSUUID(IdManager idManager) {
37-
final byte[] bytes = new byte[10];
34+
private static final AtomicLong sequenceNumber = new AtomicLong(0);
35+
private final String sessionId;
36+
37+
CLSUUID() {
38+
byte[] bytes = new byte[10];
3839

3940
this.populateTime(bytes);
4041
this.populateSequenceNumber(bytes);
4142
this.populatePID(bytes);
4243

43-
// sha1 it to ensure the string is long enough, has only valid hex characters, and to
44-
// increase entropy.
45-
final String idSha = CommonUtils.sha1(idManager.getInstallIds().getCrashlyticsInstallId());
46-
final String timeSeqPid = CommonUtils.hexify(bytes);
44+
String timeSeqPid = CommonUtils.hexify(bytes);
4745

48-
_clsId =
46+
sessionId =
4947
String.format(
5048
Locale.US,
5149
"%s%s%s%s",
5250
timeSeqPid.substring(0, 12),
5351
timeSeqPid.substring(12, 16),
5452
timeSeqPid.subSequence(16, 20),
55-
idSha.substring(0, 12))
53+
ID_SHA.substring(0, 12))
5654
.toUpperCase(Locale.US);
5755
}
5856

57+
public String getSessionId() {
58+
return sessionId;
59+
}
60+
5961
private void populateTime(byte[] bytes) {
6062
final Date date = new Date();
6163
final long time = date.getTime();
@@ -73,7 +75,7 @@ private void populateTime(byte[] bytes) {
7375
}
7476

7577
private void populateSequenceNumber(byte[] bytes) {
76-
final byte[] sequenceBytes = convertLongToTwoByteBuffer(_sequenceNumber.incrementAndGet());
78+
byte[] sequenceBytes = convertLongToTwoByteBuffer(sequenceNumber.incrementAndGet());
7779
bytes[6] = sequenceBytes[0];
7880
bytes[7] = sequenceBytes[1];
7981
}
@@ -103,7 +105,8 @@ private static byte[] convertLongToTwoByteBuffer(long value) {
103105
return buf.array();
104106
}
105107

108+
@Override
106109
public String toString() {
107-
return _clsId;
110+
return sessionId;
108111
}
109112
}

firebase-crashlytics/src/main/java/com/google/firebase/crashlytics/internal/common/CrashlyticsController.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ public Task<Void> call() throws Exception {
222222

223223
doWriteAppExceptionMarker(timestampMillis);
224224
doCloseSessions(settingsProvider);
225-
doOpenSession(new CLSUUID(idManager).toString(), isOnDemand);
225+
doOpenSession(new CLSUUID().getSessionId(), isOnDemand);
226226

227227
// If automatic data collection is disabled, we'll need to wait until the next run
228228
// of the app.

firebase-crashlytics/src/main/java/com/google/firebase/crashlytics/internal/common/CrashlyticsCore.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ public boolean onPreExecute(AppData appData, SettingsProvider settingsProvider)
150150
throw new IllegalStateException(MISSING_BUILD_ID_MSG);
151151
}
152152

153-
final String sessionIdentifier = new CLSUUID(idManager).toString();
153+
String sessionIdentifier = new CLSUUID().getSessionId();
154154
try {
155155
crashMarker = new CrashlyticsFileMarker(CRASH_MARKER_FILE_NAME, fileStore);
156156
initializationMarker = new CrashlyticsFileMarker(INITIALIZATION_MARKER_FILE_NAME, fileStore);

0 commit comments

Comments
 (0)