Skip to content

Commit 999680a

Browse files
authored
FXIOS-11121 #24248 [Sponsored tiles] Ensure we send to both places for telemetry (#24257)
* Ensure we send to both places for telemetry * Add tests, remove static from SponsoredTileTelemetry todo so * Fix * Remove savedEvent and replace with SavedEvents * Add event check on array * Adjust for latest main
1 parent b478956 commit 999680a

14 files changed

+274
-140
lines changed

firefox-ios/Client/AdjustTelemetryHelper.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@
5454
// telemetry.record(network: network)
5555
// }
5656
//
57-
// gleanWrapper.submitPing()
57+
// gleanWrapper.submit(GleanMetrics.Pings.shared.firstSession)
5858
// }
5959
//}
6060
// swiftlint:enable comment_spacing file_header

firefox-ios/Client/Frontend/Home/Homepage Rebuild/TopSites/TopSiteState.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ final class TopSiteState: Hashable, Equatable {
5454
// Only sending sponsored tile impressions for now
5555
guard let tile = site as? SponsoredTile else { return }
5656

57-
SponsoredTileTelemetry.sendImpressionTelemetry(tile: tile, position: position)
57+
DefaultSponsoredTileTelemetry().sendImpressionTelemetry(tile: tile, position: position)
5858
}
5959

6060
func getTelemetrySiteType() -> String {

firefox-ios/Client/Frontend/Home/TopSites/DataManagement/UnifiedAds/UnifiedAdsCallbackTelemetry.swift

+20-3
Original file line numberDiff line numberDiff line change
@@ -12,25 +12,30 @@ protocol UnifiedAdsCallbackTelemetry {
1212
}
1313

1414
final class DefaultUnifiedAdsCallbackTelemetry: UnifiedAdsCallbackTelemetry {
15-
private var networking: ContileNetworking
16-
private var logger: Logger
15+
private let networking: ContileNetworking
16+
private let logger: Logger
17+
private let sponsoredTileTelemetry: SponsoredTileTelemetry
1718

1819
init(
1920
networking: ContileNetworking = DefaultContileNetwork(with: NetworkUtils.defaultURLSession()),
20-
logger: Logger = DefaultLogger.shared
21+
logger: Logger = DefaultLogger.shared,
22+
sponsoredTileTelemetry: SponsoredTileTelemetry = DefaultSponsoredTileTelemetry()
2123
) {
2224
self.networking = networking
2325
self.logger = logger
26+
self.sponsoredTileTelemetry = sponsoredTileTelemetry
2427
}
2528

2629
func sendImpressionTelemetry(tile: SponsoredTile, position: Int) {
2730
let impressionURL = tile.impressionURL
2831
sendTelemetry(urlString: impressionURL, position: position)
32+
sendLegacyImpressionTelemetry(tile: tile, position: position)
2933
}
3034

3135
func sendClickTelemetry(tile: SponsoredTile, position: Int) {
3236
let clickURL = tile.clickURL
3337
sendTelemetry(urlString: clickURL, position: position)
38+
sendLegacyClickTelemetry(tile: tile, position: position)
3439
}
3540

3641
private func sendTelemetry(urlString: String, position: Int) {
@@ -67,4 +72,16 @@ final class DefaultUnifiedAdsCallbackTelemetry: UnifiedAdsCallbackTelemetry {
6772
}
6873
}
6974
}
75+
76+
// MARK: Legacy telemetry
77+
// FXIOS-11121 While we are migrating to the new Unified Ads telemetry system, we should
78+
// keep sending the legacy telemetry Glean pings
79+
80+
private func sendLegacyImpressionTelemetry(tile: SponsoredTile, position: Int) {
81+
sponsoredTileTelemetry.sendImpressionTelemetry(tile: tile, position: position, isUnifiedAdsEnabled: true)
82+
}
83+
84+
private func sendLegacyClickTelemetry(tile: SponsoredTile, position: Int) {
85+
sponsoredTileTelemetry.sendClickTelemetry(tile: tile, position: position, isUnifiedAdsEnabled: true)
86+
}
7087
}

firefox-ios/Client/Frontend/Home/TopSites/TopSite.swift

-11
Original file line numberDiff line numberDiff line change
@@ -52,17 +52,6 @@ final class TopSite: FeatureFlaggable {
5252

5353
// MARK: Telemetry
5454

55-
func impressionTracking(position: Int, unifiedAdsTelemetry: UnifiedAdsCallbackTelemetry) {
56-
// Only sending sponsored tile impressions for now
57-
guard let tile = site as? SponsoredTile else { return }
58-
59-
if featureFlags.isFeatureEnabled(.unifiedAds, checking: .buildOnly) {
60-
unifiedAdsTelemetry.sendImpressionTelemetry(tile: tile, position: position)
61-
} else {
62-
SponsoredTileTelemetry.sendImpressionTelemetry(tile: tile, position: position)
63-
}
64-
}
65-
6655
func getTelemetrySiteType() -> String {
6756
if isPinned && isGoogleGUID {
6857
return "google"

firefox-ios/Client/Frontend/Home/TopSites/TopSitesViewModel.swift

+13-2
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,13 @@ class TopSitesViewModel {
3333
private let googleTopSiteManager: GoogleTopSiteManager
3434
private var wallpaperManager: WallpaperManager
3535
private let unifiedAdsTelemetry: UnifiedAdsCallbackTelemetry
36+
private let sponsoredTileTelemetry: SponsoredTileTelemetry
3637

3738
init(profile: Profile,
3839
isZeroSearch: Bool = false,
3940
theme: Theme,
4041
wallpaperManager: WallpaperManager,
42+
sponsoredTileTelemetry: SponsoredTileTelemetry = DefaultSponsoredTileTelemetry(),
4143
unifiedAdsTelemetry: UnifiedAdsCallbackTelemetry = DefaultUnifiedAdsCallbackTelemetry()) {
4244
self.profile = profile
4345
self.isZeroSearch = isZeroSearch
@@ -52,6 +54,7 @@ class TopSitesViewModel {
5254
topSitesDataAdaptor = adaptor
5355
self.wallpaperManager = wallpaperManager
5456
self.unifiedAdsTelemetry = unifiedAdsTelemetry
57+
self.sponsoredTileTelemetry = sponsoredTileTelemetry
5558
adaptor.delegate = self
5659
}
5760

@@ -64,7 +67,15 @@ class TopSitesViewModel {
6467

6568
func sendImpressionTelemetry(_ homeTopSite: TopSite, position: Int) {
6669
guard !hasSentImpressionForTile(homeTopSite) else { return }
67-
homeTopSite.impressionTracking(position: position, unifiedAdsTelemetry: unifiedAdsTelemetry)
70+
71+
// Only sending sponsored tile impressions for now
72+
guard let tile = homeTopSite.site as? SponsoredTile else { return }
73+
74+
if featureFlags.isFeatureEnabled(.unifiedAds, checking: .buildOnly) {
75+
unifiedAdsTelemetry.sendImpressionTelemetry(tile: tile, position: position)
76+
} else {
77+
sponsoredTileTelemetry.sendImpressionTelemetry(tile: tile, position: position)
78+
}
6879
}
6980

7081
private func topSitePressTracking(homeTopSite: TopSite, position: Int) {
@@ -95,7 +106,7 @@ class TopSitesViewModel {
95106
if featureFlags.isFeatureEnabled(.unifiedAds, checking: .buildOnly) {
96107
unifiedAdsTelemetry.sendClickTelemetry(tile: tile, position: position)
97108
} else {
98-
SponsoredTileTelemetry.sendClickTelemetry(tile: tile, position: position)
109+
sponsoredTileTelemetry.sendClickTelemetry(tile: tile, position: position)
99110
}
100111
}
101112
}

firefox-ios/Client/Telemetry/GleanWrapper.swift

+15-5
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import Glean
88
protocol GleanWrapper {
99
func handleDeeplinkUrl(url: URL)
1010
func setUpload(isEnabled: Bool)
11-
func submitPing()
1211

1312
// MARK: Glean Metrics
1413

@@ -20,6 +19,7 @@ protocol GleanWrapper {
2019
func recordLabel(for metric: LabeledMetricType<CounterMetricType>, label: String)
2120
func setBoolean(for metric: BooleanMetricType, value: Bool)
2221
func recordQuantity(for metric: QuantityMetricType, value: Int64)
22+
func recordUrl(for metric: UrlMetricType, value: String)
2323

2424
func incrementNumerator(for metric: RateMetricType, amount: Int32)
2525
func incrementDenominator(for metric: RateMetricType, amount: Int32)
@@ -31,6 +31,10 @@ protocol GleanWrapper {
3131
timerId: GleanTimerId)
3232
func stopAndAccumulateTiming(for metric: TimingDistributionMetricType,
3333
timerId: GleanTimerId)
34+
35+
// MARK: Pings
36+
37+
func submit<ReasonCodesEnum>(ping: Ping<ReasonCodesEnum>) where ReasonCodesEnum: ReasonCodes
3438
}
3539

3640
/// Glean wrapper to abstract Glean from our application
@@ -49,10 +53,6 @@ struct DefaultGleanWrapper: GleanWrapper {
4953
glean.setCollectionEnabled(isEnabled)
5054
}
5155

52-
func submitPing() {
53-
GleanMetrics.Pings.shared.firstSession.submit()
54-
}
55-
5656
// MARK: Glean Metrics
5757

5858
func recordEvent<ExtraObject>(for metric: EventMetricType<ExtraObject>,
@@ -88,6 +88,10 @@ struct DefaultGleanWrapper: GleanWrapper {
8888
metric.set(value)
8989
}
9090

91+
func recordUrl(for metric: UrlMetricType, value: String) {
92+
metric.set(value)
93+
}
94+
9195
// MARK: RateMetricType
9296

9397
func incrementNumerator(for metric: RateMetricType, amount: Int32) {
@@ -113,4 +117,10 @@ struct DefaultGleanWrapper: GleanWrapper {
113117
timerId: GleanTimerId) {
114118
metric.stopAndAccumulate(timerId)
115119
}
120+
121+
// MARK: Pings
122+
123+
func submit<ReasonCodesEnum>(ping: Ping<ReasonCodesEnum>) where ReasonCodesEnum: ReasonCodes {
124+
ping.submit()
125+
}
116126
}

firefox-ios/Client/Telemetry/SponsoredTileTelemetry.swift

+71-15
Original file line numberDiff line numberDiff line change
@@ -7,33 +7,89 @@ import Glean
77

88
// Telemetry for the Sponsored tiles located in the Top sites on the Firefox home page
99
// Using Pings to send the telemetry events
10-
struct SponsoredTileTelemetry {
10+
protocol SponsoredTileTelemetry {
11+
func sendImpressionTelemetry(tile: SponsoredTile,
12+
position: Int,
13+
isUnifiedAdsEnabled: Bool)
14+
func sendClickTelemetry(tile: SponsoredTile,
15+
position: Int,
16+
isUnifiedAdsEnabled: Bool)
17+
}
18+
19+
extension SponsoredTileTelemetry {
20+
func sendImpressionTelemetry(tile: SponsoredTile,
21+
position: Int,
22+
isUnifiedAdsEnabled: Bool = false) {
23+
sendImpressionTelemetry(tile: tile, position: position, isUnifiedAdsEnabled: isUnifiedAdsEnabled)
24+
}
25+
26+
func sendClickTelemetry(tile: SponsoredTile,
27+
position: Int,
28+
isUnifiedAdsEnabled: Bool = false) {
29+
sendClickTelemetry(tile: tile, position: position, isUnifiedAdsEnabled: isUnifiedAdsEnabled)
30+
}
31+
}
32+
33+
struct DefaultSponsoredTileTelemetry: SponsoredTileTelemetry {
1134
// Source is only new tab at the moment, more source could be added later
1235
static let source = "newtab"
36+
private let gleanWrapper: GleanWrapper
37+
38+
init(gleanWrapper: GleanWrapper = DefaultGleanWrapper()) {
39+
self.gleanWrapper = gleanWrapper
40+
}
1341

14-
static func sendImpressionTelemetry(tile: SponsoredTile, position: Int) {
42+
/// Send Sponsored tile impression telemetry with Glean Pings
43+
/// - Parameters:
44+
/// - tile: The sponsored tile
45+
/// - position: The position of the sponsored tile in the top sites collection view
46+
/// - isUnifiedAdsEnabled: Whether the unified ads is enabled, if enabled some information isn't set on the ping
47+
func sendImpressionTelemetry(tile: SponsoredTile,
48+
position: Int,
49+
isUnifiedAdsEnabled: Bool = false) {
1550
let extra = GleanMetrics.TopSites.ContileImpressionExtra(
1651
position: Int32(position),
17-
source: SponsoredTileTelemetry.source
52+
source: DefaultSponsoredTileTelemetry.source
1853
)
19-
GleanMetrics.TopSites.contileImpression.record(extra)
54+
gleanWrapper.recordEvent(for: GleanMetrics.TopSites.contileImpression, extras: extra)
2055

21-
GleanMetrics.TopSites.contileTileId.set(Int64(tile.tileId))
22-
GleanMetrics.TopSites.contileAdvertiser.set(tile.title)
23-
GleanMetrics.TopSites.contileReportingUrl.set(tile.impressionURL)
24-
GleanMetrics.Pings.shared.topsitesImpression.submit()
56+
// Some information isn't set on the ping when unified ads is enabled
57+
if !isUnifiedAdsEnabled {
58+
gleanWrapper.recordQuantity(for: GleanMetrics.TopSites.contileTileId,
59+
value: Int64(tile.tileId))
60+
gleanWrapper.recordUrl(for: GleanMetrics.TopSites.contileReportingUrl,
61+
value: tile.impressionURL)
62+
}
63+
64+
gleanWrapper.recordString(for: GleanMetrics.TopSites.contileAdvertiser,
65+
value: tile.title)
66+
gleanWrapper.submit(ping: GleanMetrics.Pings.shared.topsitesImpression)
2567
}
2668

27-
static func sendClickTelemetry(tile: SponsoredTile, position: Int) {
69+
/// Send Sponsored tile click telemetry with Glean Pings
70+
/// - Parameters:
71+
/// - tile: The sponsored tile
72+
/// - position: The position of the sponsored tile in the top sites collection view
73+
/// - isUnifiedAdsEnabled: Whether the unified ads is enabled, if enabled some information isn't set on the ping
74+
func sendClickTelemetry(tile: SponsoredTile,
75+
position: Int,
76+
isUnifiedAdsEnabled: Bool = false) {
2877
let extra = GleanMetrics.TopSites.ContileClickExtra(
2978
position: Int32(position),
30-
source: SponsoredTileTelemetry.source
79+
source: DefaultSponsoredTileTelemetry.source
3180
)
32-
GleanMetrics.TopSites.contileClick.record(extra)
81+
gleanWrapper.recordEvent(for: GleanMetrics.TopSites.contileClick, extras: extra)
82+
83+
// Some information isn't set on the ping when unified ads is enabled
84+
if !isUnifiedAdsEnabled {
85+
gleanWrapper.recordQuantity(for: GleanMetrics.TopSites.contileTileId,
86+
value: Int64(tile.tileId))
87+
gleanWrapper.recordUrl(for: GleanMetrics.TopSites.contileReportingUrl,
88+
value: tile.clickURL)
89+
}
3390

34-
GleanMetrics.TopSites.contileTileId.set(Int64(tile.tileId))
35-
GleanMetrics.TopSites.contileAdvertiser.set(tile.title)
36-
GleanMetrics.TopSites.contileReportingUrl.set(tile.clickURL)
37-
GleanMetrics.Pings.shared.topsitesImpression.submit()
91+
gleanWrapper.recordString(for: GleanMetrics.TopSites.contileAdvertiser,
92+
value: tile.title)
93+
gleanWrapper.submit(ping: GleanMetrics.Pings.shared.topsitesImpression)
3894
}
3995
}

0 commit comments

Comments
 (0)