Skip to content

Commit 04a9e0c

Browse files
authored
Migrate firebase-crashlytics SDK to FIS (#1760)
Migrate firebase-crashlytics SDK to FIS
1 parent be99c93 commit 04a9e0c

File tree

11 files changed

+84
-42
lines changed

11 files changed

+84
-42
lines changed

firebase-crashlytics/firebase-crashlytics.gradle

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -62,11 +62,8 @@ dependencies {
6262
implementation project(':transport:transport-api')
6363
implementation project(':transport:transport-runtime')
6464
implementation project(':transport:transport-backend-cct')
65-
implementation ('com.google.firebase:firebase-iid:20.1.5') {
66-
exclude group: "com.google.firebase", module: "firebase-common"
67-
exclude group: "com.google.firebase", module: "firebase-components"
68-
}
69-
implementation 'com.google.firebase:firebase-iid-interop:17.0.0'
65+
implementation project(':firebase-installations-interop')
66+
runtimeOnly project(':firebase-installations')
7067
implementation 'com.google.firebase:firebase-measurement-connector:18.0.0'
7168
implementation "com.google.android.gms:play-services-tasks:17.0.0"
7269

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

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,11 @@
1515
package com.google.firebase.crashlytics.internal.common;
1616

1717
import static org.mockito.Mockito.mock;
18+
import static org.mockito.Mockito.when;
1819

20+
import com.google.android.gms.tasks.Tasks;
1921
import com.google.firebase.crashlytics.internal.CrashlyticsTestCase;
20-
import com.google.firebase.iid.internal.FirebaseInstanceIdInternal;
22+
import com.google.firebase.installations.FirebaseInstallationsApi;
2123

2224
public class CLSUUIDTest extends CrashlyticsTestCase {
2325

@@ -26,8 +28,9 @@ public class CLSUUIDTest extends CrashlyticsTestCase {
2628

2729
protected void setUp() throws Exception {
2830
super.setUp();
29-
FirebaseInstanceIdInternal instanceIdMock = mock(FirebaseInstanceIdInternal.class);
30-
idManager = new IdManager(getContext(), getContext().getPackageName(), instanceIdMock);
31+
FirebaseInstallationsApi installationsApiMock = mock(FirebaseInstallationsApi.class);
32+
when(installationsApiMock.getId()).thenReturn(Tasks.forResult("instanceId"));
33+
idManager = new IdManager(getContext(), getContext().getPackageName(), installationsApiMock);
3134
uuid = new CLSUUID(idManager);
3235
}
3336

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

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,10 @@
2525
import android.content.pm.PackageManager;
2626
import android.content.res.Resources;
2727
import android.util.Log;
28+
import com.google.android.gms.tasks.Tasks;
2829
import com.google.firebase.crashlytics.internal.CrashlyticsTestCase;
2930
import com.google.firebase.crashlytics.internal.Logger;
30-
import com.google.firebase.iid.internal.FirebaseInstanceIdInternal;
31+
import com.google.firebase.installations.FirebaseInstallationsApi;
3132
import java.io.File;
3233
import java.io.FilenameFilter;
3334
import java.io.IOException;
@@ -352,9 +353,10 @@ public void testCapFileCount() throws Exception {
352353

353354
private File createEmptyClsFile(File dir) throws IOException {
354355
final Context context = getContext();
355-
FirebaseInstanceIdInternal instanceIdMock = mock(FirebaseInstanceIdInternal.class);
356+
FirebaseInstallationsApi installationsApiMock = mock(FirebaseInstallationsApi.class);
357+
when(installationsApiMock.getId()).thenReturn(Tasks.forResult("instanceId"));
356358
final CLSUUID id =
357-
new CLSUUID(new IdManager(context, context.getPackageName(), instanceIdMock));
359+
new CLSUUID(new IdManager(context, context.getPackageName(), installationsApiMock));
358360
final File f = new File(dir, id.toString() + ".cls");
359361
f.createNewFile();
360362
return f;

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@
5858
import com.google.firebase.crashlytics.internal.settings.model.SessionSettingsData;
5959
import com.google.firebase.crashlytics.internal.settings.model.SettingsData;
6060
import com.google.firebase.crashlytics.internal.unity.UnityVersionProvider;
61-
import com.google.firebase.iid.internal.FirebaseInstanceIdInternal;
61+
import com.google.firebase.installations.FirebaseInstallationsApi;
6262
import java.io.File;
6363
import java.io.FileFilter;
6464
import java.io.FileInputStream;
@@ -99,8 +99,9 @@ protected void setUp() throws Exception {
9999

100100
testContext = getContext();
101101

102-
FirebaseInstanceIdInternal instanceIdMock = mock(FirebaseInstanceIdInternal.class);
103-
idManager = new IdManager(testContext, testContext.getPackageName(), instanceIdMock);
102+
FirebaseInstallationsApi installationsApiMock = mock(FirebaseInstallationsApi.class);
103+
when(installationsApiMock.getId()).thenReturn(Tasks.forResult("instanceId"));
104+
idManager = new IdManager(testContext, testContext.getPackageName(), installationsApiMock);
104105

105106
BatteryIntentProvider.returnNull = false;
106107

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
import com.google.firebase.crashlytics.internal.settings.SettingsController;
3737
import com.google.firebase.crashlytics.internal.settings.TestSettingsData;
3838
import com.google.firebase.crashlytics.internal.settings.model.SettingsData;
39-
import com.google.firebase.iid.internal.FirebaseInstanceIdInternal;
39+
import com.google.firebase.installations.FirebaseInstallationsApi;
4040
import java.io.File;
4141
import java.io.IOException;
4242
import java.util.concurrent.ExecutorService;
@@ -94,8 +94,9 @@ public CoreBuilder(Context context, FirebaseOptions firebaseOptions) {
9494
when(app.getApplicationContext()).thenReturn(context);
9595
when(app.getOptions()).thenReturn(firebaseOptions);
9696

97-
FirebaseInstanceIdInternal instanceIdMock = mock(FirebaseInstanceIdInternal.class);
98-
idManager = new IdManager(context, context.getPackageName(), instanceIdMock);
97+
FirebaseInstallationsApi installationsApiMock = mock(FirebaseInstallationsApi.class);
98+
when(installationsApiMock.getId()).thenReturn(Tasks.forResult("instanceId"));
99+
idManager = new IdManager(context, context.getPackageName(), installationsApiMock);
99100

100101
nativeComponent = new MissingNativeComponent();
101102

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
import com.google.firebase.crashlytics.internal.settings.SettingsController;
3939
import com.google.firebase.crashlytics.internal.settings.TestSettingsData;
4040
import com.google.firebase.crashlytics.internal.settings.model.SettingsData;
41-
import com.google.firebase.iid.internal.FirebaseInstanceIdInternal;
41+
import com.google.firebase.installations.FirebaseInstallationsApi;
4242
import java.io.File;
4343
import java.io.FileFilter;
4444
import java.io.IOException;
@@ -681,13 +681,14 @@ CrashlyticsCore build(Context context) {
681681
FirebaseApp app = mock(FirebaseApp.class);
682682
when(app.getApplicationContext()).thenReturn(context);
683683
when(app.getOptions()).thenReturn(testFirebaseOptions);
684-
FirebaseInstanceIdInternal instanceIdMock = mock(FirebaseInstanceIdInternal.class);
684+
FirebaseInstallationsApi installationsApiMock = mock(FirebaseInstallationsApi.class);
685+
when(installationsApiMock.getId()).thenReturn(Tasks.forResult("instanceId"));
685686
BreadcrumbSource breadcrumbSource =
686687
this.breadcrumbSource == null ? new DisabledBreadcrumbSource() : this.breadcrumbSource;
687688
final CrashlyticsCore crashlyticsCore =
688689
new CrashlyticsCore(
689690
app,
690-
new IdManager(context, "unused", instanceIdMock),
691+
new IdManager(context, "unused", installationsApiMock),
691692
nativeComponent,
692693
arbiter,
693694
breadcrumbSource,

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

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,11 @@
2121
import android.content.Context;
2222
import androidx.test.core.app.ApplicationProvider;
2323
import androidx.test.runner.AndroidJUnit4;
24+
import com.google.android.gms.tasks.Tasks;
2425
import com.google.firebase.crashlytics.internal.model.CrashlyticsReport;
2526
import com.google.firebase.crashlytics.internal.model.CrashlyticsReport.Session.Event.Application.Execution;
2627
import com.google.firebase.crashlytics.internal.stacktrace.StackTraceTrimmingStrategy;
27-
import com.google.firebase.iid.internal.FirebaseInstanceIdInternal;
28+
import com.google.firebase.installations.FirebaseInstallationsApi;
2829
import java.util.List;
2930
import org.junit.Before;
3031
import org.junit.Test;
@@ -43,16 +44,17 @@ public class CrashlyticsReportDataCaptureTest {
4344

4445
@Mock private StackTraceTrimmingStrategy stackTraceTrimmingStrategy;
4546

46-
@Mock private FirebaseInstanceIdInternal instanceIdMock;
47+
@Mock private FirebaseInstallationsApi installationsApiMock;
4748

4849
@Before
4950
public void setUp() throws Exception {
5051
MockitoAnnotations.initMocks(this);
51-
when(instanceIdMock.getId()).thenReturn("installId");
52+
when(installationsApiMock.getId()).thenReturn(Tasks.forResult("installId"));
5253
when(stackTraceTrimmingStrategy.getTrimmedStackTrace(any(StackTraceElement[].class)))
5354
.thenAnswer(i -> i.getArguments()[0]);
5455
final Context context = ApplicationProvider.getApplicationContext();
55-
final IdManager idManager = new IdManager(context, context.getPackageName(), instanceIdMock);
56+
final IdManager idManager =
57+
new IdManager(context, context.getPackageName(), installationsApiMock);
5658
final AppData appData = AppData.create(context, idManager, "googleAppId", "buildId");
5759
dataCapture =
5860
new CrashlyticsReportDataCapture(context, idManager, appData, stackTraceTrimmingStrategy);

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

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,10 @@
1818
import static org.mockito.Mockito.when;
1919

2020
import android.content.SharedPreferences;
21+
import com.google.android.gms.tasks.Tasks;
2122
import com.google.firebase.crashlytics.internal.CrashlyticsTestCase;
22-
import com.google.firebase.iid.internal.FirebaseInstanceIdInternal;
23+
import com.google.firebase.installations.FirebaseInstallationsApi;
24+
import java.util.concurrent.TimeoutException;
2325

2426
public class IdManagerTest extends CrashlyticsTestCase {
2527

@@ -56,8 +58,8 @@ private void clearPrefs() {
5658
}
5759

5860
private IdManager createIdManager(String instanceId) {
59-
FirebaseInstanceIdInternal iid = mock(FirebaseInstanceIdInternal.class);
60-
when(iid.getId()).thenReturn(instanceId);
61+
FirebaseInstallationsApi iid = mock(FirebaseInstallationsApi.class);
62+
when(iid.getId()).thenReturn(Tasks.forResult(instanceId));
6163
return new IdManager(getContext(), getContext().getPackageName(), iid);
6264
}
6365

@@ -75,6 +77,23 @@ public void testCreateUUID() {
7577
assertEquals(installId, idManager.getCrashlyticsInstallId());
7678
}
7779

80+
public void testGetIdExceptionalCase_doesNotRotateInstallId() {
81+
FirebaseInstallationsApi fis = mock(FirebaseInstallationsApi.class);
82+
final String expectedInstallId = "expectedInstallId";
83+
when(fis.getId())
84+
.thenReturn(Tasks.forException(new TimeoutException("Fetching id timed out.")));
85+
prefs
86+
.edit()
87+
.putString(IdManager.PREFKEY_INSTALLATION_UUID, expectedInstallId)
88+
.putString(IdManager.PREFKEY_FIREBASE_IID, "firebase-iid")
89+
.apply();
90+
91+
final IdManager idManager = new IdManager(getContext(), getContext().getPackageName(), fis);
92+
final String actualInstallId = idManager.getCrashlyticsInstallId();
93+
assertNotNull(actualInstallId);
94+
assertEquals(expectedInstallId, actualInstallId);
95+
}
96+
7897
public void testInstanceIdChanges() {
7998
// Set up the initial state with a valid iid and uuid.
8099
final String oldUuid = "old_uuid";

firebase-crashlytics/src/main/java/com/google/firebase/crashlytics/CrashlyticsRegistrar.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
import com.google.firebase.components.ComponentRegistrar;
2222
import com.google.firebase.components.Dependency;
2323
import com.google.firebase.crashlytics.internal.CrashlyticsNativeComponent;
24-
import com.google.firebase.iid.internal.FirebaseInstanceIdInternal;
24+
import com.google.firebase.installations.FirebaseInstallationsApi;
2525
import com.google.firebase.platforminfo.LibraryVersionComponent;
2626
import java.util.Arrays;
2727
import java.util.List;
@@ -33,7 +33,7 @@ public List<Component<?>> getComponents() {
3333
return Arrays.asList(
3434
Component.builder(FirebaseCrashlytics.class)
3535
.add(Dependency.required(FirebaseApp.class))
36-
.add(Dependency.requiredProvider(FirebaseInstanceIdInternal.class))
36+
.add(Dependency.required(FirebaseInstallationsApi.class))
3737
.add(Dependency.optional(AnalyticsConnector.class))
3838
.add(Dependency.optional(CrashlyticsNativeComponent.class))
3939
.factory(this::buildCrashlytics)
@@ -49,9 +49,9 @@ private FirebaseCrashlytics buildCrashlytics(ComponentContainer container) {
4949

5050
AnalyticsConnector analyticsConnector = container.get(AnalyticsConnector.class);
5151

52-
FirebaseInstanceIdInternal instanceId =
53-
container.getProvider(FirebaseInstanceIdInternal.class).get();
52+
FirebaseInstallationsApi firebaseInstallations = container.get(FirebaseInstallationsApi.class);
5453

55-
return FirebaseCrashlytics.init(app, instanceId, nativeComponent, analyticsConnector);
54+
return FirebaseCrashlytics.init(
55+
app, firebaseInstallations, nativeComponent, analyticsConnector);
5656
}
5757
}

firebase-crashlytics/src/main/java/com/google/firebase/crashlytics/FirebaseCrashlytics.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
import com.google.firebase.crashlytics.internal.common.ExecutorUtils;
3939
import com.google.firebase.crashlytics.internal.common.IdManager;
4040
import com.google.firebase.crashlytics.internal.settings.SettingsController;
41-
import com.google.firebase.iid.internal.FirebaseInstanceIdInternal;
41+
import com.google.firebase.installations.FirebaseInstallationsApi;
4242
import java.util.concurrent.Callable;
4343
import java.util.concurrent.ExecutorService;
4444
import java.util.concurrent.TimeUnit;
@@ -60,13 +60,13 @@ public class FirebaseCrashlytics {
6060

6161
static @Nullable FirebaseCrashlytics init(
6262
@NonNull FirebaseApp app,
63-
@NonNull FirebaseInstanceIdInternal instanceId,
63+
@NonNull FirebaseInstallationsApi firebaseInstallationsApi,
6464
@Nullable CrashlyticsNativeComponent nativeComponent,
6565
@Nullable AnalyticsConnector analyticsConnector) {
6666
Context context = app.getApplicationContext();
6767
// Set up the IdManager.
6868
final String appIdentifier = context.getPackageName();
69-
final IdManager idManager = new IdManager(context, appIdentifier, instanceId);
69+
final IdManager idManager = new IdManager(context, appIdentifier, firebaseInstallationsApi);
7070

7171
final DataCollectionArbiter arbiter = new DataCollectionArbiter(app);
7272

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

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,15 @@
1818
import android.content.SharedPreferences;
1919
import android.os.Build;
2020
import androidx.annotation.NonNull;
21+
import com.google.android.gms.tasks.Task;
2122
import com.google.firebase.crashlytics.internal.Logger;
22-
import com.google.firebase.iid.internal.FirebaseInstanceIdInternal;
23+
import com.google.firebase.installations.FirebaseInstallationsApi;
2324
import java.util.Locale;
2425
import java.util.UUID;
2526
import java.util.regex.Pattern;
2627

2728
public class IdManager implements InstallIdProvider {
29+
2830
public static final String DEFAULT_VERSION_NAME = "0.0";
2931

3032
static final String PREFKEY_ADVERTISING_ID = "crashlytics.advertising.id";
@@ -41,8 +43,8 @@ public class IdManager implements InstallIdProvider {
4143
private final Context appContext;
4244
private final String appIdentifier;
4345

44-
// The FirebaseInstanceIdInternal encapsulates a Firebase-wide install id
45-
private final FirebaseInstanceIdInternal firebaseInstallId;
46+
// The FirebaseInstallationsApi encapsulates a Firebase-wide install id
47+
private final FirebaseInstallationsApi firebaseInstallationsApi;
4648
// Crashlytics maintains a Crashlytics-specific install id, used in the crash processing backend
4749
private String crashlyticsInstallId;
4850

@@ -54,7 +56,7 @@ public class IdManager implements InstallIdProvider {
5456
* null
5557
*/
5658
public IdManager(
57-
Context appContext, String appIdentifier, FirebaseInstanceIdInternal firebaseInstallId) {
59+
Context appContext, String appIdentifier, FirebaseInstallationsApi firebaseInstallationsApi) {
5860
if (appContext == null) {
5961
throw new IllegalArgumentException("appContext must not be null");
6062
}
@@ -63,7 +65,7 @@ public IdManager(
6365
}
6466
this.appContext = appContext;
6567
this.appIdentifier = appIdentifier;
66-
this.firebaseInstallId = firebaseInstallId;
68+
this.firebaseInstallationsApi = firebaseInstallationsApi;
6769

6870
installerPackageNameProvider = new InstallerPackageNameProvider();
6971
}
@@ -99,11 +101,25 @@ public synchronized String getCrashlyticsInstallId() {
99101

100102
// Crashlytics rotates the Crashlytics-specific IID if the Firebase IID ("FID") is reset.
101103
// This way, Crashlytics privacy controls are consistent with the rest of Firebase.
102-
final String currentFid = firebaseInstallId.getId();
104+
Task<String> currentFidTask = firebaseInstallationsApi.getId();
105+
String currentFid = null;
103106
final String cachedFid = prefs.getString(PREFKEY_FIREBASE_IID, null);
104107

108+
try {
109+
currentFid = Utils.awaitEvenIfOnMainThread(currentFidTask);
110+
} catch (Exception e) {
111+
Logger.getLogger().d("Failed to retrieve installation id", e);
112+
113+
// this avoids rotating the identifier in the case that there was an exception which is likely
114+
// to succeed in a future invocation
115+
if (cachedFid != null) {
116+
currentFid = cachedFid;
117+
}
118+
}
119+
105120
if (cachedFid == null) {
106-
// This must be either 1) a new installation or 2) an upgrade from the legacy Crashlytics SDK.
121+
// This must be either 1) a new installation or 2) an upgrade from the legacy
122+
// Crashlytics SDK.
107123
// If it is a legacy upgrade, we'll migrate the legacy ID to the new pref store.
108124
final SharedPreferences legacyPrefs = CommonUtils.getLegacySharedPrefs(appContext);
109125
final String legacyId = legacyPrefs.getString(PREFKEY_LEGACY_INSTALLATION_UUID, null);

0 commit comments

Comments
 (0)