Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FXIOS-11121 #24248 [Sponsored tiles] Ensure we send to both places for telemetry #24257

Merged
merged 6 commits into from
Jan 21, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion firefox-ios/Client/AdjustTelemetryHelper.swift
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
// telemetry.record(network: network)
// }
//
// gleanWrapper.submitPing()
// gleanWrapper.submit(GleanMetrics.Pings.shared.firstSession)
// }
//}
// swiftlint:enable comment_spacing file_header
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ final class TopSiteState: Hashable, Equatable {
// Only sending sponsored tile impressions for now
guard let tile = site as? SponsoredTile else { return }

SponsoredTileTelemetry.sendImpressionTelemetry(tile: tile, position: position)
DefaultSponsoredTileTelemetry().sendImpressionTelemetry(tile: tile, position: position)
}

func getTelemetrySiteType() -> String {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,25 +12,30 @@ protocol UnifiedAdsCallbackTelemetry {
}

final class DefaultUnifiedAdsCallbackTelemetry: UnifiedAdsCallbackTelemetry {
private var networking: ContileNetworking
private var logger: Logger
private let networking: ContileNetworking
private let logger: Logger
private let sponsoredTileTelemetry: SponsoredTileTelemetry

init(
networking: ContileNetworking = DefaultContileNetwork(with: NetworkUtils.defaultURLSession()),
logger: Logger = DefaultLogger.shared
logger: Logger = DefaultLogger.shared,
sponsoredTileTelemetry: SponsoredTileTelemetry = DefaultSponsoredTileTelemetry()
) {
self.networking = networking
self.logger = logger
self.sponsoredTileTelemetry = sponsoredTileTelemetry
}

func sendImpressionTelemetry(tile: SponsoredTile, position: Int) {
let impressionURL = tile.impressionURL
sendTelemetry(urlString: impressionURL, position: position)
sendLegacyImpressionTelemetry(tile: tile, position: position)
}

func sendClickTelemetry(tile: SponsoredTile, position: Int) {
let clickURL = tile.clickURL
sendTelemetry(urlString: clickURL, position: position)
sendLegacyClickTelemetry(tile: tile, position: position)
}

private func sendTelemetry(urlString: String, position: Int) {
Expand Down Expand Up @@ -67,4 +72,16 @@ final class DefaultUnifiedAdsCallbackTelemetry: UnifiedAdsCallbackTelemetry {
}
}
}

// MARK: Legacy telemetry
// FXIOS-11121 While we are migrating to the new Unified Ads telemetry system, we should
// keep sending the legacy telemetry Glean pings

private func sendLegacyImpressionTelemetry(tile: SponsoredTile, position: Int) {
sponsoredTileTelemetry.sendImpressionTelemetry(tile: tile, position: position, isUnifiedAdsEnabled: true)
}

private func sendLegacyClickTelemetry(tile: SponsoredTile, position: Int) {
sponsoredTileTelemetry.sendClickTelemetry(tile: tile, position: position, isUnifiedAdsEnabled: true)
}
}
11 changes: 0 additions & 11 deletions firefox-ios/Client/Frontend/Home/TopSites/TopSite.swift
Original file line number Diff line number Diff line change
Expand Up @@ -52,17 +52,6 @@ final class TopSite: FeatureFlaggable {

// MARK: Telemetry

func impressionTracking(position: Int, unifiedAdsTelemetry: UnifiedAdsCallbackTelemetry) {
// Only sending sponsored tile impressions for now
guard let tile = site as? SponsoredTile else { return }

if featureFlags.isFeatureEnabled(.unifiedAds, checking: .buildOnly) {
unifiedAdsTelemetry.sendImpressionTelemetry(tile: tile, position: position)
} else {
SponsoredTileTelemetry.sendImpressionTelemetry(tile: tile, position: position)
}
}

func getTelemetrySiteType() -> String {
if isPinned && isGoogleGUID {
return "google"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,13 @@ class TopSitesViewModel {
private let googleTopSiteManager: GoogleTopSiteManager
private var wallpaperManager: WallpaperManager
private let unifiedAdsTelemetry: UnifiedAdsCallbackTelemetry
private let sponsoredTileTelemetry: SponsoredTileTelemetry

init(profile: Profile,
isZeroSearch: Bool = false,
theme: Theme,
wallpaperManager: WallpaperManager,
sponsoredTileTelemetry: SponsoredTileTelemetry = DefaultSponsoredTileTelemetry(),
unifiedAdsTelemetry: UnifiedAdsCallbackTelemetry = DefaultUnifiedAdsCallbackTelemetry()) {
self.profile = profile
self.isZeroSearch = isZeroSearch
Expand All @@ -52,6 +54,7 @@ class TopSitesViewModel {
topSitesDataAdaptor = adaptor
self.wallpaperManager = wallpaperManager
self.unifiedAdsTelemetry = unifiedAdsTelemetry
self.sponsoredTileTelemetry = sponsoredTileTelemetry
adaptor.delegate = self
}

Expand All @@ -64,7 +67,15 @@ class TopSitesViewModel {

func sendImpressionTelemetry(_ homeTopSite: TopSite, position: Int) {
guard !hasSentImpressionForTile(homeTopSite) else { return }
homeTopSite.impressionTracking(position: position, unifiedAdsTelemetry: unifiedAdsTelemetry)

// Only sending sponsored tile impressions for now
guard let tile = homeTopSite.site as? SponsoredTile else { return }

if featureFlags.isFeatureEnabled(.unifiedAds, checking: .buildOnly) {
unifiedAdsTelemetry.sendImpressionTelemetry(tile: tile, position: position)
} else {
sponsoredTileTelemetry.sendImpressionTelemetry(tile: tile, position: position)
}
}

private func topSitePressTracking(homeTopSite: TopSite, position: Int) {
Expand Down Expand Up @@ -95,7 +106,7 @@ class TopSitesViewModel {
if featureFlags.isFeatureEnabled(.unifiedAds, checking: .buildOnly) {
unifiedAdsTelemetry.sendClickTelemetry(tile: tile, position: position)
} else {
SponsoredTileTelemetry.sendClickTelemetry(tile: tile, position: position)
sponsoredTileTelemetry.sendClickTelemetry(tile: tile, position: position)
}
}
}
Expand Down
20 changes: 15 additions & 5 deletions firefox-ios/Client/Telemetry/GleanWrapper.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import Glean
protocol GleanWrapper {
func handleDeeplinkUrl(url: URL)
func setUpload(isEnabled: Bool)
func submitPing()

// MARK: Glean Metrics

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

func incrementNumerator(for metric: RateMetricType, amount: Int32)
func incrementDenominator(for metric: RateMetricType, amount: Int32)
Expand All @@ -31,6 +31,10 @@ protocol GleanWrapper {
timerId: GleanTimerId)
func stopAndAccumulateTiming(for metric: TimingDistributionMetricType,
timerId: GleanTimerId)

// MARK: Pings

func submit<ReasonCodesEnum>(ping: Ping<ReasonCodesEnum>) where ReasonCodesEnum: ReasonCodes
}

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

func submitPing() {
GleanMetrics.Pings.shared.firstSession.submit()
}

// MARK: Glean Metrics

func recordEvent<ExtraObject>(for metric: EventMetricType<ExtraObject>,
Expand Down Expand Up @@ -88,6 +88,10 @@ struct DefaultGleanWrapper: GleanWrapper {
metric.set(value)
}

func recordUrl(for metric: UrlMetricType, value: String) {
metric.set(value)
}

// MARK: RateMetricType

func incrementNumerator(for metric: RateMetricType, amount: Int32) {
Expand All @@ -113,4 +117,10 @@ struct DefaultGleanWrapper: GleanWrapper {
timerId: GleanTimerId) {
metric.stopAndAccumulate(timerId)
}

// MARK: Pings

func submit<ReasonCodesEnum>(ping: Ping<ReasonCodesEnum>) where ReasonCodesEnum: ReasonCodes {
ping.submit()
}
}
86 changes: 71 additions & 15 deletions firefox-ios/Client/Telemetry/SponsoredTileTelemetry.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,33 +7,89 @@ import Glean

// Telemetry for the Sponsored tiles located in the Top sites on the Firefox home page
// Using Pings to send the telemetry events
struct SponsoredTileTelemetry {
protocol SponsoredTileTelemetry {
func sendImpressionTelemetry(tile: SponsoredTile,
position: Int,
isUnifiedAdsEnabled: Bool)
func sendClickTelemetry(tile: SponsoredTile,
position: Int,
isUnifiedAdsEnabled: Bool)
}

extension SponsoredTileTelemetry {
func sendImpressionTelemetry(tile: SponsoredTile,
position: Int,
isUnifiedAdsEnabled: Bool = false) {
sendImpressionTelemetry(tile: tile, position: position, isUnifiedAdsEnabled: isUnifiedAdsEnabled)
}

func sendClickTelemetry(tile: SponsoredTile,
position: Int,
isUnifiedAdsEnabled: Bool = false) {
sendClickTelemetry(tile: tile, position: position, isUnifiedAdsEnabled: isUnifiedAdsEnabled)
}
}

struct DefaultSponsoredTileTelemetry: SponsoredTileTelemetry {
// Source is only new tab at the moment, more source could be added later
static let source = "newtab"
private let gleanWrapper: GleanWrapper

init(gleanWrapper: GleanWrapper = DefaultGleanWrapper()) {
self.gleanWrapper = gleanWrapper
}

static func sendImpressionTelemetry(tile: SponsoredTile, position: Int) {
/// Send Sponsored tile impression telemetry with Glean Pings
/// - Parameters:
/// - tile: The sponsored tile
/// - position: The position of the sponsored tile in the top sites collection view
/// - isUnifiedAdsEnabled: Whether the unified ads is enabled, if enabled some information isn't set on the ping
func sendImpressionTelemetry(tile: SponsoredTile,
position: Int,
isUnifiedAdsEnabled: Bool = false) {
let extra = GleanMetrics.TopSites.ContileImpressionExtra(
position: Int32(position),
source: SponsoredTileTelemetry.source
source: DefaultSponsoredTileTelemetry.source
)
GleanMetrics.TopSites.contileImpression.record(extra)
gleanWrapper.recordEvent(for: GleanMetrics.TopSites.contileImpression, extras: extra)

GleanMetrics.TopSites.contileTileId.set(Int64(tile.tileId))
GleanMetrics.TopSites.contileAdvertiser.set(tile.title)
GleanMetrics.TopSites.contileReportingUrl.set(tile.impressionURL)
GleanMetrics.Pings.shared.topsitesImpression.submit()
// Some information isn't set on the ping when unified ads is enabled
if !isUnifiedAdsEnabled {
gleanWrapper.recordQuantity(for: GleanMetrics.TopSites.contileTileId,
value: Int64(tile.tileId))
gleanWrapper.recordUrl(for: GleanMetrics.TopSites.contileReportingUrl,
value: tile.impressionURL)
}

gleanWrapper.recordString(for: GleanMetrics.TopSites.contileAdvertiser,
value: tile.title)
gleanWrapper.submit(ping: GleanMetrics.Pings.shared.topsitesImpression)
}

static func sendClickTelemetry(tile: SponsoredTile, position: Int) {
/// Send Sponsored tile click telemetry with Glean Pings
/// - Parameters:
/// - tile: The sponsored tile
/// - position: The position of the sponsored tile in the top sites collection view
/// - isUnifiedAdsEnabled: Whether the unified ads is enabled, if enabled some information isn't set on the ping
func sendClickTelemetry(tile: SponsoredTile,
position: Int,
isUnifiedAdsEnabled: Bool = false) {
let extra = GleanMetrics.TopSites.ContileClickExtra(
position: Int32(position),
source: SponsoredTileTelemetry.source
source: DefaultSponsoredTileTelemetry.source
)
GleanMetrics.TopSites.contileClick.record(extra)
gleanWrapper.recordEvent(for: GleanMetrics.TopSites.contileClick, extras: extra)

// Some information isn't set on the ping when unified ads is enabled
if !isUnifiedAdsEnabled {
gleanWrapper.recordQuantity(for: GleanMetrics.TopSites.contileTileId,
value: Int64(tile.tileId))
gleanWrapper.recordUrl(for: GleanMetrics.TopSites.contileReportingUrl,
value: tile.clickURL)
}

GleanMetrics.TopSites.contileTileId.set(Int64(tile.tileId))
GleanMetrics.TopSites.contileAdvertiser.set(tile.title)
GleanMetrics.TopSites.contileReportingUrl.set(tile.clickURL)
GleanMetrics.Pings.shared.topsitesImpression.submit()
gleanWrapper.recordString(for: GleanMetrics.TopSites.contileAdvertiser,
value: tile.title)
gleanWrapper.submit(ping: GleanMetrics.Pings.shared.topsitesImpression)
}
}
Loading