Skip to content

Commit 593da89

Browse files
davidmotsonDavid Motsonashvili
andauthored
Create native proxy object to check provider on each call and mediate… (#2532)
* Create native proxy object to check provider on each call and mediate between desired return value and default behavior) * 2nd push to fix import * fix tests * fix writeSessionApp * googleJavaFormat * fix typo * typo fix v2 * added tests * add copyright to tests * UJpdate test name * add junitrunner * gJF Co-authored-by: David Motsonashvili <[email protected]>
1 parent 2cc1cc4 commit 593da89

File tree

7 files changed

+182
-20
lines changed

7 files changed

+182
-20
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
// Copyright 2021 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package com.google.firebase.crashlytics.internal;
16+
17+
import static org.mockito.ArgumentMatchers.eq;
18+
19+
import androidx.test.runner.AndroidJUnit4;
20+
import org.junit.Before;
21+
import org.junit.Test;
22+
import org.mockito.Mock;
23+
import org.mockito.Mockito;
24+
import org.mockito.MockitoAnnotations;
25+
26+
@RunWith(AndroidJUnit4.class)
27+
public class ProviderProxyNativeComponentTest {
28+
private static final String TEST_STRING = "abc";
29+
private static final long TEST_LONG = 123;
30+
private static final boolean TEST_BOOLEAN = true;
31+
private static final int TEST_INT = 1234;
32+
33+
@Mock private CrashlyticsNativeComponent component;
34+
35+
@Before
36+
public void setUp() throws Exception {
37+
MockitoAnnotations.initMocks(this);
38+
}
39+
40+
@Test
41+
public void testProviderProxyCallsThroughProvidedValue() {
42+
ProviderProxyNativeComponent proxy = new ProviderProxyNativeComponent(() -> component);
43+
44+
proxy.hasCrashDataForSession(TEST_STRING);
45+
Mockito.verify(component, Mockito.times(1)).hasCrashDataForSession(eq(TEST_STRING));
46+
47+
proxy.openSession(TEST_STRING);
48+
Mockito.verify(component, Mockito.times(1)).openSession(eq(TEST_STRING));
49+
50+
proxy.finalizeSession(TEST_STRING);
51+
Mockito.verify(component, Mockito.times(1)).finalizeSession(eq(TEST_STRING));
52+
53+
proxy.getSessionFileProvider(TEST_STRING);
54+
Mockito.verify(component, Mockito.times(1)).getSessionFileProvider(eq(TEST_STRING));
55+
56+
proxy.writeBeginSession(TEST_STRING, TEST_STRING, TEST_LONG);
57+
Mockito.verify(component, Mockito.times(1))
58+
.writeBeginSession(eq(TEST_STRING), eq(TEST_STRING), eq(TEST_LONG));
59+
60+
proxy.writeSessionApp(
61+
TEST_STRING, TEST_STRING, TEST_STRING, TEST_STRING, TEST_STRING, TEST_INT, TEST_STRING);
62+
Mockito.verify(component, Mockito.times(1))
63+
.writeSessionApp(
64+
eq(TEST_STRING),
65+
eq(TEST_STRING),
66+
eq(TEST_STRING),
67+
eq(TEST_STRING),
68+
eq(TEST_STRING),
69+
eq(TEST_INT),
70+
eq(TEST_STRING));
71+
72+
proxy.writeSessionOs(TEST_STRING, TEST_STRING, TEST_STRING, TEST_BOOLEAN);
73+
Mockito.verify(component, Mockito.times(1))
74+
.writeSessionOs(eq(TEST_STRING), eq(TEST_STRING), eq(TEST_STRING), eq(TEST_BOOLEAN));
75+
76+
proxy.writeSessionDevice(
77+
TEST_STRING,
78+
TEST_INT,
79+
TEST_STRING,
80+
TEST_INT,
81+
TEST_LONG,
82+
TEST_LONG,
83+
TEST_BOOLEAN,
84+
TEST_INT,
85+
TEST_STRING,
86+
TEST_STRING);
87+
Mockito.verify(component, Mockito.times(1))
88+
.writeSessionDevice(
89+
eq(TEST_STRING),
90+
eq(TEST_INT),
91+
eq(TEST_STRING),
92+
eq(TEST_INT),
93+
eq(TEST_LONG),
94+
eq(TEST_LONG),
95+
eq(TEST_BOOLEAN),
96+
eq(TEST_INT),
97+
eq(TEST_STRING),
98+
eq(TEST_STRING));
99+
}
100+
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@
2525
import com.google.firebase.FirebaseApp;
2626
import com.google.firebase.crashlytics.internal.CrashlyticsNativeComponent;
2727
import com.google.firebase.crashlytics.internal.CrashlyticsTestCase;
28-
import com.google.firebase.crashlytics.internal.MissingNativeComponent;
2928
import com.google.firebase.crashlytics.internal.NativeSessionFileProvider;
29+
import com.google.firebase.crashlytics.internal.ProviderProxyNativeComponent;
3030
import com.google.firebase.crashlytics.internal.analytics.AnalyticsEventLogger;
3131
import com.google.firebase.crashlytics.internal.log.LogFileManager;
3232
import com.google.firebase.crashlytics.internal.persistence.FileStore;
@@ -112,7 +112,7 @@ private class ControllerBuilder {
112112

113113
ControllerBuilder() {
114114
dataCollectionArbiter = mockDataCollectionArbiter;
115-
nativeComponent = new MissingNativeComponent();
115+
nativeComponent = new ProviderProxyNativeComponent(() -> null);
116116

117117
unityVersionProvider = mock(UnityVersionProvider.class);
118118
when(unityVersionProvider.getUnityVersion()).thenReturn(null);

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
import com.google.firebase.FirebaseOptions;
2929
import com.google.firebase.crashlytics.internal.CrashlyticsNativeComponent;
3030
import com.google.firebase.crashlytics.internal.CrashlyticsTestCase;
31-
import com.google.firebase.crashlytics.internal.MissingNativeComponent;
31+
import com.google.firebase.crashlytics.internal.ProviderProxyNativeComponent;
3232
import com.google.firebase.crashlytics.internal.analytics.UnavailableAnalyticsEventLogger;
3333
import com.google.firebase.crashlytics.internal.breadcrumbs.DisabledBreadcrumbSource;
3434
import com.google.firebase.crashlytics.internal.persistence.FileStore;
@@ -99,7 +99,7 @@ public CoreBuilder(Context context, FirebaseOptions firebaseOptions) {
9999
when(installationsApiMock.getId()).thenReturn(Tasks.forResult("instanceId"));
100100
idManager = new IdManager(context, context.getPackageName(), installationsApiMock);
101101

102-
nativeComponent = new MissingNativeComponent();
102+
nativeComponent = new ProviderProxyNativeComponent(() -> null);
103103

104104
arbiter = mock(DataCollectionArbiter.class);
105105
when(arbiter.isAutomaticDataCollectionEnabled()).thenReturn(true);

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
import com.google.firebase.crashlytics.BuildConfig;
2929
import com.google.firebase.crashlytics.internal.CrashlyticsNativeComponent;
3030
import com.google.firebase.crashlytics.internal.CrashlyticsTestCase;
31-
import com.google.firebase.crashlytics.internal.MissingNativeComponent;
31+
import com.google.firebase.crashlytics.internal.ProviderProxyNativeComponent;
3232
import com.google.firebase.crashlytics.internal.analytics.UnavailableAnalyticsEventLogger;
3333
import com.google.firebase.crashlytics.internal.breadcrumbs.BreadcrumbHandler;
3434
import com.google.firebase.crashlytics.internal.breadcrumbs.BreadcrumbSource;
@@ -48,7 +48,7 @@ public class CrashlyticsCoreTest extends CrashlyticsTestCase {
4848
private static final String GOOGLE_APP_ID = "google:app:id";
4949

5050
private static final CrashlyticsNativeComponent MISSING_NATIVE_COMPONENT =
51-
new MissingNativeComponent();
51+
new ProviderProxyNativeComponent(() -> null);
5252

5353
private CrashlyticsCore crashlyticsCore;
5454
private BreadcrumbSource mockBreadcrumbSource;

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import com.google.firebase.components.Dependency;
2323
import com.google.firebase.crashlytics.internal.CrashlyticsNativeComponent;
2424
import com.google.firebase.inject.Deferred;
25+
import com.google.firebase.inject.Provider;
2526
import com.google.firebase.installations.FirebaseInstallationsApi;
2627
import com.google.firebase.platforminfo.LibraryVersionComponent;
2728
import java.util.Arrays;
@@ -35,8 +36,8 @@ public List<Component<?>> getComponents() {
3536
Component.builder(FirebaseCrashlytics.class)
3637
.add(Dependency.required(FirebaseApp.class))
3738
.add(Dependency.required(FirebaseInstallationsApi.class))
39+
.add(Dependency.optionalProvider(CrashlyticsNativeComponent.class))
3840
.add(Dependency.deferred(AnalyticsConnector.class))
39-
.add(Dependency.optional(CrashlyticsNativeComponent.class))
4041
.factory(this::buildCrashlytics)
4142
.eagerInDefaultApp()
4243
.build(),
@@ -46,7 +47,8 @@ public List<Component<?>> getComponents() {
4647
private FirebaseCrashlytics buildCrashlytics(ComponentContainer container) {
4748
FirebaseApp app = container.get(FirebaseApp.class);
4849

49-
CrashlyticsNativeComponent nativeComponent = container.get(CrashlyticsNativeComponent.class);
50+
Provider<CrashlyticsNativeComponent> nativeComponent =
51+
container.getProvider(CrashlyticsNativeComponent.class);
5052

5153
Deferred<AnalyticsConnector> analyticsConnector =
5254
container.getDeferred(AnalyticsConnector.class);

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

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
import com.google.firebase.analytics.connector.AnalyticsConnector;
2626
import com.google.firebase.crashlytics.internal.CrashlyticsNativeComponent;
2727
import com.google.firebase.crashlytics.internal.Logger;
28-
import com.google.firebase.crashlytics.internal.MissingNativeComponent;
28+
import com.google.firebase.crashlytics.internal.ProviderProxyNativeComponent;
2929
import com.google.firebase.crashlytics.internal.common.AppData;
3030
import com.google.firebase.crashlytics.internal.common.CommonUtils;
3131
import com.google.firebase.crashlytics.internal.common.CrashlyticsCore;
@@ -37,6 +37,7 @@
3737
import com.google.firebase.crashlytics.internal.unity.ResourceUnityVersionProvider;
3838
import com.google.firebase.crashlytics.internal.unity.UnityVersionProvider;
3939
import com.google.firebase.inject.Deferred;
40+
import com.google.firebase.inject.Provider;
4041
import com.google.firebase.installations.FirebaseInstallationsApi;
4142
import java.util.concurrent.Callable;
4243
import java.util.concurrent.ExecutorService;
@@ -61,8 +62,8 @@ public class FirebaseCrashlytics {
6162
static @Nullable FirebaseCrashlytics init(
6263
@NonNull FirebaseApp app,
6364
@NonNull FirebaseInstallationsApi firebaseInstallationsApi,
64-
@Nullable CrashlyticsNativeComponent nativeComponent,
65-
Deferred<AnalyticsConnector> analyticsConnector) {
65+
@NonNull Provider<CrashlyticsNativeComponent> nativeComponent,
66+
@NonNull Deferred<AnalyticsConnector> analyticsConnector) {
6667
Logger.getLogger().i("Initializing Firebase Crashlytics " + CrashlyticsCore.getVersion());
6768
Context context = app.getApplicationContext();
6869
// Set up the IdManager.
@@ -71,9 +72,8 @@ public class FirebaseCrashlytics {
7172

7273
final DataCollectionArbiter arbiter = new DataCollectionArbiter(app);
7374

74-
if (nativeComponent == null) {
75-
nativeComponent = new MissingNativeComponent();
76-
}
75+
ProviderProxyNativeComponent proxyNativeComponent =
76+
new ProviderProxyNativeComponent(nativeComponent);
7777

7878
// Integration with Firebase Analytics
7979
final AnalyticsDeferredProxy analyticsDeferredProxy =
@@ -85,7 +85,7 @@ public class FirebaseCrashlytics {
8585
new CrashlyticsCore(
8686
app,
8787
idManager,
88-
nativeComponent,
88+
proxyNativeComponent,
8989
arbiter,
9090
analyticsDeferredProxy.getDeferredBreadcrumbSource(),
9191
analyticsDeferredProxy.getAnalyticsEventLogger(),

firebase-crashlytics/src/main/java/com/google/firebase/crashlytics/internal/MissingNativeComponent.java renamed to firebase-crashlytics/src/main/java/com/google/firebase/crashlytics/internal/ProviderProxyNativeComponent.java

Lines changed: 65 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,37 +15,65 @@
1515
package com.google.firebase.crashlytics.internal;
1616

1717
import androidx.annotation.NonNull;
18+
import com.google.firebase.inject.Provider;
1819
import java.io.File;
1920

20-
public final class MissingNativeComponent implements CrashlyticsNativeComponent {
21+
public final class ProviderProxyNativeComponent implements CrashlyticsNativeComponent {
2122

2223
private static final NativeSessionFileProvider MISSING_NATIVE_SESSION_FILE_PROVIDER =
2324
new MissingNativeSessionFileProvider();
2425

26+
private final Provider<CrashlyticsNativeComponent> provider;
27+
28+
public ProviderProxyNativeComponent(Provider<CrashlyticsNativeComponent> provider) {
29+
this.provider = provider;
30+
}
31+
2532
@Override
2633
public boolean hasCrashDataForSession(@NonNull String sessionId) {
34+
CrashlyticsNativeComponent nativeComponent = provider.get();
35+
if (nativeComponent != null) {
36+
return nativeComponent.hasCrashDataForSession(sessionId);
37+
}
2738
return false;
2839
}
2940

3041
@Override
3142
public boolean openSession(@NonNull String sessionId) {
43+
CrashlyticsNativeComponent nativeComponent = provider.get();
44+
if (nativeComponent != null) {
45+
return nativeComponent.openSession(sessionId);
46+
}
3247
return true;
3348
}
3449

3550
@Override
3651
public boolean finalizeSession(@NonNull String sessionId) {
52+
CrashlyticsNativeComponent nativeComponent = provider.get();
53+
if (nativeComponent != null) {
54+
return nativeComponent.finalizeSession(sessionId);
55+
}
3756
return true;
3857
}
3958

4059
@NonNull
4160
@Override
4261
public NativeSessionFileProvider getSessionFileProvider(@NonNull String sessionId) {
62+
CrashlyticsNativeComponent nativeComponent = provider.get();
63+
if (nativeComponent != null) {
64+
return nativeComponent.getSessionFileProvider(sessionId);
65+
}
4366
return MISSING_NATIVE_SESSION_FILE_PROVIDER;
4467
}
4568

4669
@Override
4770
public void writeBeginSession(
48-
@NonNull String sessionId, @NonNull String generator, long startedAtSeconds) {}
71+
@NonNull String sessionId, @NonNull String generator, long startedAtSeconds) {
72+
CrashlyticsNativeComponent nativeComponent = provider.get();
73+
if (nativeComponent != null) {
74+
nativeComponent.writeBeginSession(sessionId, generator, startedAtSeconds);
75+
}
76+
}
4977

5078
@Override
5179
public void writeSessionApp(
@@ -55,14 +83,31 @@ public void writeSessionApp(
5583
@NonNull String versionName,
5684
@NonNull String installUuid,
5785
int deliveryMechanism,
58-
@NonNull String unityVersion) {}
86+
@NonNull String unityVersion) {
87+
CrashlyticsNativeComponent nativeComponent = provider.get();
88+
if (nativeComponent != null) {
89+
nativeComponent.writeSessionApp(
90+
sessionId,
91+
appIdentifier,
92+
versionCode,
93+
versionName,
94+
installUuid,
95+
deliveryMechanism,
96+
unityVersion);
97+
}
98+
}
5999

60100
@Override
61101
public void writeSessionOs(
62102
@NonNull String sessionId,
63103
@NonNull String osRelease,
64104
@NonNull String osCodeName,
65-
boolean isRooted) {}
105+
boolean isRooted) {
106+
CrashlyticsNativeComponent nativeComponent = provider.get();
107+
if (nativeComponent != null) {
108+
nativeComponent.writeSessionOs(sessionId, osRelease, osCodeName, isRooted);
109+
}
110+
}
66111

67112
@Override
68113
public void writeSessionDevice(
@@ -75,7 +120,22 @@ public void writeSessionDevice(
75120
boolean isEmulator,
76121
int state,
77122
@NonNull String manufacturer,
78-
@NonNull String modelClass) {}
123+
@NonNull String modelClass) {
124+
CrashlyticsNativeComponent nativeComponent = provider.get();
125+
if (nativeComponent != null) {
126+
nativeComponent.writeSessionDevice(
127+
sessionId,
128+
arch,
129+
model,
130+
availableProcessors,
131+
totalRam,
132+
diskSpace,
133+
isEmulator,
134+
state,
135+
manufacturer,
136+
modelClass);
137+
}
138+
}
79139

80140
private static final class MissingNativeSessionFileProvider implements NativeSessionFileProvider {
81141

0 commit comments

Comments
 (0)