Skip to content

Commit 4171a3b

Browse files
authored
Prevent capturing of Network Info unless Perf is installed (#10717)
1 parent 66f23d5 commit 4171a3b

File tree

3 files changed

+105
-11
lines changed

3 files changed

+105
-11
lines changed

FirebaseSessions/Sources/FirebaseSessions.swift

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ private enum GoogleDataTransportConfig {
176176
// turn off the Sessions SDK when we disabled it.
177177
self.settings.updateSettings()
178178

179-
self.addEventDataCollectionState(event: event)
179+
self.addSubscriberFields(event: event)
180180

181181
guard sessionInfo.shouldDispatchEvents else {
182182
loggedEventCallback(.failure(.SessionSamplingError))
@@ -206,10 +206,13 @@ private enum GoogleDataTransportConfig {
206206
return false
207207
}
208208

209-
func addEventDataCollectionState(event: SessionStartEvent) {
209+
func addSubscriberFields(event: SessionStartEvent) {
210210
subscribers.forEach { subscriber in
211211
event.set(subscriber: subscriber.sessionsSubscriberName,
212212
isDataCollectionEnabled: subscriber.isDataCollectionEnabled)
213+
214+
event.setRestrictedFields(subscriber: subscriber.sessionsSubscriberName,
215+
appInfo: self.appInfo)
213216
}
214217
}
215218

FirebaseSessions/Sources/SessionStartEvent.swift

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,12 +57,15 @@ class SessionStartEvent: NSObject, GDTCOREventDataObject {
5757
proto.application_info.which_platform_info = FIRSESGetAppleApplicationInfoTag()
5858
proto.application_info.apple_app_info
5959
.bundle_short_version = makeProtoString(appInfo.appDisplayVersion)
60+
proto.application_info.apple_app_info.os_name = convertOSName(osName: appInfo.osName)
61+
62+
// Set network info to base values but don't fill them in with the real
63+
// value because these are only tracked when Performance is installed
64+
proto.application_info.apple_app_info.mcc_mnc = makeProtoString("")
6065
proto.application_info.apple_app_info.network_connection_info
61-
.network_type = convertNetworkType(networkType: appInfo.networkInfo.networkType)
66+
.network_type = convertNetworkType(networkType: .none)
6267
proto.application_info.apple_app_info.network_connection_info
63-
.mobile_subtype = convertMobileSubtype(mobileSubtype: appInfo.networkInfo.mobileSubtype)
64-
proto.application_info.apple_app_info.os_name = convertOSName(osName: appInfo.osName)
65-
proto.application_info.apple_app_info.mcc_mnc = makeProtoString(appInfo.mccMNC)
68+
.mobile_subtype = convertMobileSubtype(mobileSubtype: "")
6669

6770
proto.session_data.data_collection_status
6871
.crashlytics = firebase_appquality_sessions_DataCollectionState_COLLECTION_SDK_NOT_INSTALLED
@@ -91,6 +94,21 @@ class SessionStartEvent: NSObject, GDTCOREventDataObject {
9194
}
9295
}
9396

97+
/// This method should be called for every subscribed Subscriber. This is for cases where
98+
/// fields should only be collected if a specific SDK is installed.
99+
func setRestrictedFields(subscriber: SessionsSubscriberName, appInfo: ApplicationInfoProtocol) {
100+
switch subscriber {
101+
case .Performance:
102+
proto.application_info.apple_app_info.mcc_mnc = makeProtoString(appInfo.mccMNC)
103+
proto.application_info.apple_app_info.network_connection_info
104+
.network_type = convertNetworkType(networkType: appInfo.networkInfo.networkType)
105+
proto.application_info.apple_app_info.network_connection_info
106+
.mobile_subtype = convertMobileSubtype(mobileSubtype: appInfo.networkInfo.mobileSubtype)
107+
default:
108+
break
109+
}
110+
}
111+
94112
// MARK: - GDTCOREventDataObject
95113

96114
func transportBytes() -> Data {

FirebaseSessions/Tests/Unit/SessionStartEventTests.swift

Lines changed: 78 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -105,11 +105,6 @@ class SessionStartEventTests: XCTestCase {
105105
expected: MockApplicationInfo.testDeviceModel,
106106
fieldName: "device_model"
107107
)
108-
assertEqualProtoString(
109-
proto.application_info.apple_app_info.mcc_mnc,
110-
expected: MockApplicationInfo.testMCCMNC,
111-
fieldName: "mcc_mnc"
112-
)
113108

114109
// Ensure we convert the test OS name into the enum.
115110
XCTAssertEqual(
@@ -215,6 +210,75 @@ class SessionStartEventTests: XCTestCase {
215210
}
216211
}
217212

213+
func test_newtworkInfo_onlyPresentWhenPerformanceInstalled() {
214+
let mockNetworkInfo = MockNetworkInfo()
215+
mockNetworkInfo.networkType = .mobile
216+
// Mobile Subtypes are always empty on non-iOS platforms, and
217+
// Performance doesn't support those platforms anyways
218+
#if os(iOS) && !targetEnvironment(macCatalyst)
219+
mockNetworkInfo.mobileSubtype = CTRadioAccessTechnologyHSUPA
220+
#else
221+
mockNetworkInfo.mobileSubtype = ""
222+
#endif
223+
appInfo.networkInfo = mockNetworkInfo
224+
225+
let sessionInfo = SessionInfo(
226+
sessionId: "session_id",
227+
previousSessionId: "previous_session_id",
228+
dispatchEvents: true
229+
)
230+
let event = SessionStartEvent(sessionInfo: sessionInfo, appInfo: appInfo, time: time)
231+
232+
// These fields will not be filled in when Crashlytics is installed
233+
event.setRestrictedFields(subscriber: .Crashlytics, appInfo: appInfo)
234+
235+
// Expect empty because Crashlytics is installed, but not Perf
236+
testProtoAndDecodedProto(sessionEvent: event) { proto in
237+
XCTAssertEqual(
238+
event.proto.application_info.apple_app_info.network_connection_info.network_type,
239+
firebase_appquality_sessions_NetworkConnectionInfo_NetworkType_DUMMY
240+
)
241+
XCTAssertEqual(
242+
event.proto.application_info.apple_app_info.network_connection_info.mobile_subtype,
243+
firebase_appquality_sessions_NetworkConnectionInfo_MobileSubtype_UNKNOWN_MOBILE_SUBTYPE
244+
)
245+
assertEqualProtoString(
246+
proto.application_info.apple_app_info.mcc_mnc,
247+
expected: "",
248+
fieldName: "mcc_mnc"
249+
)
250+
}
251+
252+
// These fields will only be filled in when the Perf SDK is installed
253+
event.setRestrictedFields(subscriber: .Performance, appInfo: appInfo)
254+
255+
// Now the field should be set with the real thing
256+
testProtoAndDecodedProto(sessionEvent: event) { proto in
257+
XCTAssertEqual(
258+
event.proto.application_info.apple_app_info.network_connection_info.network_type,
259+
firebase_appquality_sessions_NetworkConnectionInfo_NetworkType_MOBILE
260+
)
261+
// Mobile Subtypes are always empty on non-iOS platforms, and
262+
// Performance doesn't support those platforms anyways
263+
#if os(iOS) && !targetEnvironment(macCatalyst)
264+
XCTAssertEqual(
265+
event.proto.application_info.apple_app_info.network_connection_info.mobile_subtype,
266+
firebase_appquality_sessions_NetworkConnectionInfo_MobileSubtype_HSUPA
267+
)
268+
#else
269+
XCTAssertEqual(
270+
event.proto.application_info.apple_app_info.network_connection_info.mobile_subtype,
271+
firebase_appquality_sessions_NetworkConnectionInfo_MobileSubtype_UNKNOWN_MOBILE_SUBTYPE
272+
)
273+
#endif
274+
assertEqualProtoString(
275+
proto.application_info.apple_app_info.mcc_mnc,
276+
expected: MockApplicationInfo.testMCCMNC,
277+
fieldName: "mcc_mnc"
278+
)
279+
}
280+
}
281+
218282
func test_convertNetworkType_convertsCorrectly() {
219283
let expectations: [(
220284
given: GULNetworkType,
@@ -249,6 +313,9 @@ class SessionStartEventTests: XCTestCase {
249313
)
250314
let event = SessionStartEvent(sessionInfo: sessionInfo, appInfo: appInfo, time: time)
251315

316+
// These fields will only be filled in when the Perf SDK is installed
317+
event.setRestrictedFields(subscriber: .Performance, appInfo: appInfo)
318+
252319
testProtoAndDecodedProto(sessionEvent: event) { proto in
253320
XCTAssertEqual(
254321
event.proto.application_info.apple_app_info.network_connection_info.network_type,
@@ -331,6 +398,9 @@ class SessionStartEventTests: XCTestCase {
331398
)
332399
let event = SessionStartEvent(sessionInfo: sessionInfo, appInfo: appInfo, time: time)
333400

401+
// These fields will only be filled in when the Perf SDK is installed
402+
event.setRestrictedFields(subscriber: .Performance, appInfo: appInfo)
403+
334404
testProtoAndDecodedProto(sessionEvent: event) { proto in
335405
XCTAssertEqual(
336406
event.proto.application_info.apple_app_info.network_connection_info.mobile_subtype,
@@ -422,6 +492,9 @@ class SessionStartEventTests: XCTestCase {
422492
)
423493
let event = SessionStartEvent(sessionInfo: sessionInfo, appInfo: appInfo, time: time)
424494

495+
// These fields will only be filled in when the Perf SDK is installed
496+
event.setRestrictedFields(subscriber: .Performance, appInfo: appInfo)
497+
425498
testProtoAndDecodedProto(sessionEvent: event) { proto in
426499
XCTAssertEqual(
427500
event.proto.application_info.apple_app_info.network_connection_info.mobile_subtype,

0 commit comments

Comments
 (0)