Skip to content

Commit 3932951

Browse files
authored
Add additional platform signals to UserAgent. (#2112)
* Add additional platform signals to UserAgent. * Address review comments. * Replace spaces in user agent values. * Address review comment.
1 parent da18188 commit 3932951

File tree

6 files changed

+348
-13
lines changed

6 files changed

+348
-13
lines changed

firebase-common/src/androidTest/java/com/google/firebase/FirebaseAppTest.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -142,8 +142,15 @@ public void testInitializeApp_shouldPublishVersionForFirebaseCommon() {
142142

143143
// After sorting the user agents are expected to be {"fire-android/", "fire-auth/x.y.z",
144144
// "fire-core/x.y.z", "test-component/1.2.3"}
145-
assertThat(actualUserAgent[0]).contains("fire-android");
146-
assertThat(actualUserAgent[1]).contains("fire-core");
145+
assertThat(actualUserAgent[0]).contains("android-installer");
146+
assertThat(actualUserAgent[1]).contains("android-min-sdk/14");
147+
assertThat(actualUserAgent[2]).contains("android-platform");
148+
assertThat(actualUserAgent[3]).contains("android-target-sdk");
149+
assertThat(actualUserAgent[4]).contains("device-brand");
150+
assertThat(actualUserAgent[5]).contains("device-model");
151+
assertThat(actualUserAgent[6]).contains("device-name");
152+
assertThat(actualUserAgent[7]).contains("fire-android");
153+
assertThat(actualUserAgent[8]).contains("fire-core");
147154
}
148155

149156
@Test

firebase-common/src/main/java/com/google/firebase/FirebaseApp.java

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,7 @@
4747
import com.google.firebase.components.ComponentRuntime;
4848
import com.google.firebase.components.Lazy;
4949
import com.google.firebase.events.Publisher;
50-
import com.google.firebase.heartbeatinfo.DefaultHeartBeatInfo;
5150
import com.google.firebase.internal.DataCollectionConfigStorage;
52-
import com.google.firebase.platforminfo.DefaultUserAgentPublisher;
53-
import com.google.firebase.platforminfo.KotlinDetector;
54-
import com.google.firebase.platforminfo.LibraryVersionComponent;
5551
import java.nio.charset.Charset;
5652
import java.util.ArrayList;
5753
import java.util.Collections;
@@ -419,20 +415,15 @@ protected FirebaseApp(Context applicationContext, String name, FirebaseOptions o
419415
List<ComponentRegistrar> registrars =
420416
ComponentDiscovery.forContext(applicationContext, ComponentDiscoveryService.class)
421417
.discover();
418+
registrars.add(new FirebaseCommonRegistrar());
422419

423-
String kotlinVersion = KotlinDetector.detectVersion();
424420
componentRuntime =
425421
new ComponentRuntime(
426422
UI_EXECUTOR,
427423
registrars,
428424
Component.of(applicationContext, Context.class),
429425
Component.of(this, FirebaseApp.class),
430-
Component.of(options, FirebaseOptions.class),
431-
LibraryVersionComponent.create(FIREBASE_ANDROID, ""),
432-
LibraryVersionComponent.create(FIREBASE_COMMON, BuildConfig.VERSION_NAME),
433-
kotlinVersion != null ? LibraryVersionComponent.create(KOTLIN, kotlinVersion) : null,
434-
DefaultUserAgentPublisher.component(),
435-
DefaultHeartBeatInfo.component());
426+
Component.of(options, FirebaseOptions.class));
436427

437428
dataCollectionConfigStorage =
438429
new Lazy<>(
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
// Copyright 2020 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;
16+
17+
import android.content.pm.ApplicationInfo;
18+
import android.content.pm.PackageManager;
19+
import android.os.Build;
20+
import com.google.firebase.components.Component;
21+
import com.google.firebase.components.ComponentRegistrar;
22+
import com.google.firebase.heartbeatinfo.DefaultHeartBeatInfo;
23+
import com.google.firebase.platforminfo.DefaultUserAgentPublisher;
24+
import com.google.firebase.platforminfo.KotlinDetector;
25+
import com.google.firebase.platforminfo.LibraryVersionComponent;
26+
import java.util.ArrayList;
27+
import java.util.List;
28+
29+
/** @hide */
30+
public class FirebaseCommonRegistrar implements ComponentRegistrar {
31+
private static final String FIREBASE_ANDROID = "fire-android";
32+
private static final String FIREBASE_COMMON = "fire-core";
33+
private static final String DEVICE_NAME = "device-name";
34+
private static final String DEVICE_MODEL = "device-model";
35+
private static final String DEVICE_BRAND = "device-brand";
36+
private static final String TARGET_SDK = "android-target-sdk";
37+
private static final String MIN_SDK = "android-min-sdk";
38+
private static final String ANDROID_PLATFORM = "android-platform";
39+
private static final String ANDROID_INSTALLER = "android-installer";
40+
private static final String KOTLIN = "kotlin";
41+
42+
@Override
43+
public List<Component<?>> getComponents() {
44+
List<Component<?>> result = new ArrayList<>();
45+
result.add(DefaultUserAgentPublisher.component());
46+
result.add(DefaultHeartBeatInfo.component());
47+
result.add(
48+
LibraryVersionComponent.create(FIREBASE_ANDROID, String.valueOf(Build.VERSION.SDK_INT)));
49+
result.add(LibraryVersionComponent.create(FIREBASE_COMMON, BuildConfig.VERSION_NAME));
50+
result.add(LibraryVersionComponent.create(DEVICE_NAME, safeValue(Build.PRODUCT)));
51+
result.add(LibraryVersionComponent.create(DEVICE_MODEL, safeValue(Build.DEVICE)));
52+
result.add(LibraryVersionComponent.create(DEVICE_BRAND, safeValue(Build.BRAND)));
53+
result.add(
54+
LibraryVersionComponent.fromContext(
55+
TARGET_SDK,
56+
ctx -> {
57+
ApplicationInfo info = ctx.getApplicationInfo();
58+
if (info != null) {
59+
return String.valueOf(info.targetSdkVersion);
60+
}
61+
return "";
62+
}));
63+
result.add(
64+
LibraryVersionComponent.fromContext(
65+
MIN_SDK,
66+
ctx -> {
67+
ApplicationInfo info = ctx.getApplicationInfo();
68+
if (info != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
69+
return String.valueOf(info.minSdkVersion);
70+
}
71+
return "";
72+
}));
73+
result.add(
74+
LibraryVersionComponent.fromContext(
75+
ANDROID_PLATFORM,
76+
ctx -> {
77+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN
78+
&& ctx.getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEVISION)) {
79+
return "tv";
80+
}
81+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH
82+
&& ctx.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH)) {
83+
return "watch";
84+
}
85+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
86+
&& ctx.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) {
87+
return "auto";
88+
}
89+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O
90+
&& ctx.getPackageManager().hasSystemFeature(PackageManager.FEATURE_EMBEDDED)) {
91+
return "embedded";
92+
}
93+
return "";
94+
}));
95+
result.add(
96+
LibraryVersionComponent.fromContext(
97+
ANDROID_INSTALLER,
98+
ctx -> {
99+
String installer =
100+
ctx.getPackageManager().getInstallerPackageName(ctx.getPackageName());
101+
return (installer != null) ? safeValue(installer) : "";
102+
}));
103+
104+
String kotlinVersion = KotlinDetector.detectVersion();
105+
if (kotlinVersion != null) {
106+
result.add(LibraryVersionComponent.create(KOTLIN, kotlinVersion));
107+
}
108+
return result;
109+
}
110+
111+
private static String safeValue(String value) {
112+
return value.replace(' ', '_').replace('/', '_');
113+
}
114+
}

firebase-common/src/main/java/com/google/firebase/platforminfo/LibraryVersionComponent.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,27 @@
1414

1515
package com.google.firebase.platforminfo;
1616

17+
import android.content.Context;
1718
import com.google.firebase.components.Component;
19+
import com.google.firebase.components.Dependency;
1820

1921
/** Factory to create a component that publishes the version of an SDK */
2022
public class LibraryVersionComponent {
2123
private LibraryVersionComponent() {}
2224

25+
public interface VersionExtractor<T> {
26+
String extract(T context);
27+
}
28+
2329
/** Creates a component that publishes SDK versions */
2430
public static Component<?> create(String sdkName, String version) {
2531
return Component.intoSet(LibraryVersion.create(sdkName, version), LibraryVersion.class);
2632
}
33+
34+
public static Component<?> fromContext(String sdkName, VersionExtractor<Context> extractor) {
35+
return Component.intoSetBuilder(LibraryVersion.class)
36+
.add(Dependency.required(Context.class))
37+
.factory(c -> LibraryVersion.create(sdkName, extractor.extract(c.get(Context.class))))
38+
.build();
39+
}
2740
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Copyright 2020 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;
16+
17+
import androidx.test.core.app.ApplicationProvider;
18+
import java.util.function.Consumer;
19+
20+
public final class FirebaseAppTestUtil {
21+
private FirebaseAppTestUtil() {}
22+
23+
public static void withApp(String name, FirebaseOptions options, Consumer<FirebaseApp> callable) {
24+
FirebaseApp app =
25+
FirebaseApp.initializeApp(ApplicationProvider.getApplicationContext(), options, name);
26+
try {
27+
callable.accept(app);
28+
} finally {
29+
app.delete();
30+
}
31+
}
32+
}

0 commit comments

Comments
 (0)