From aa9ffe22cba16fcb1f5d1fd1c9781db7ad9626cb Mon Sep 17 00:00:00 2001 From: powerivq Date: Thu, 12 Feb 2026 13:59:33 -0800 Subject: [PATCH] Remove attribution reporting api from ads --- extensions/amp-a4a/0.1/amp-a4a.js | 7 +- extensions/amp-a4a/0.1/secure-frame.js | 6 - extensions/amp-a4a/0.1/test/test-amp-a4a.js | 85 ------ extensions/amp-ad-exit/0.1/amp-ad-exit.js | 79 +----- .../amp-ad-exit/0.1/test/test-amp-ad-exit.js | 258 +----------------- .../0.1/amp-ad-network-adsense-impl.js | 16 +- .../0.1/amp-ad-network-doubleclick-impl.js | 13 - .../amp-analytics/0.1/test/test-transport.js | 44 +-- extensions/amp-analytics/0.1/transport.js | 9 - src/experiments/attribution-reporting.js | 11 - src/pixel.js | 94 +------ src/utils/privacy-sandbox-utils.js | 28 -- test/unit/builtins/test-amp-pixel.js | 64 +---- testing/helpers/service.js | 3 +- .../anchor_attribution_reporting.html | 19 -- .../anchor_attribution_reporting.out | 20 -- 16 files changed, 22 insertions(+), 734 deletions(-) delete mode 100644 src/experiments/attribution-reporting.js delete mode 100644 src/utils/privacy-sandbox-utils.js delete mode 100644 validator/testdata/amp4ads_feature_tests/anchor_attribution_reporting.html delete mode 100644 validator/testdata/amp4ads_feature_tests/anchor_attribution_reporting.out diff --git a/extensions/amp-a4a/0.1/amp-a4a.js b/extensions/amp-a4a/0.1/amp-a4a.js index 2466ab21c711..b3bd4e13c079 100644 --- a/extensions/amp-a4a/0.1/amp-a4a.js +++ b/extensions/amp-a4a/0.1/amp-a4a.js @@ -28,7 +28,6 @@ import {triggerAnalyticsEvent} from '#utils/analytics'; import {DomTransformStream} from '#utils/dom-transform-stream'; import {listenOnce} from '#utils/event-helper'; import {dev, devAssert, logHashParam, user, userAssert} from '#utils/log'; -import {isAttributionReportingAllowed} from '#utils/privacy-sandbox-utils'; import {canSetCookie, getCookie} from 'src/cookies'; @@ -2071,11 +2070,7 @@ export class AmpA4A extends AMP.BaseElement { // Block synchronous XHR in ad. These are very rare, but super bad for UX // as they block the UI thread for the arbitrary amount of time until the // request completes. - let featurePolicies = "sync-xhr 'none';"; - - if (isAttributionReportingAllowed(this.win.document)) { - featurePolicies += "attribution-reporting 'src';"; - } + const featurePolicies = "sync-xhr 'none';"; mergedAttributes['allow'] = featurePolicies; diff --git a/extensions/amp-a4a/0.1/secure-frame.js b/extensions/amp-a4a/0.1/secure-frame.js index 4e119bcf4edc..4dc092dabade 100644 --- a/extensions/amp-a4a/0.1/secure-frame.js +++ b/extensions/amp-a4a/0.1/secure-frame.js @@ -1,7 +1,5 @@ import {createElementWithAttributes, escapeHtml} from '#core/dom'; -import {isAttributionReportingAllowed} from '#utils/privacy-sandbox-utils'; - import {getFieSafeScriptSrcs} from '../../../src/friendly-iframe-embed'; // If making changes also change ALLOWED_FONT_REGEX in head-validation.js @@ -85,9 +83,5 @@ export function createSecureFrame(win, title, height, width) { }) ); - if (isAttributionReportingAllowed(document)) { - iframe.setAttribute('allow', `attribution-reporting 'src'`); - } - return iframe; } diff --git a/extensions/amp-a4a/0.1/test/test-amp-a4a.js b/extensions/amp-a4a/0.1/test/test-amp-a4a.js index 2db3a73ada7b..de0de8430580 100644 --- a/extensions/amp-a4a/0.1/test/test-amp-a4a.js +++ b/extensions/amp-a4a/0.1/test/test-amp-a4a.js @@ -20,7 +20,6 @@ import {installRealTimeConfigServiceForDoc} from '#service/real-time-config/real import * as analytics from '#utils/analytics'; import {dev, user} from '#utils/log'; -import * as privacySandboxUtils from '#utils/privacy-sandbox-utils'; import {macroTask} from '#testing/helpers'; import {createIframePromise} from '#testing/iframe'; @@ -921,34 +920,6 @@ describes.realWin('amp-a4a', {amp: true}, (env) => { verifyCachedContentIframeRender(a4aElement, TEST_URL, true); expect(a4a.iframe.getAttribute('allow')).to.include("sync-xhr 'none';"); }); - - it('should set feature policy for attribution-reporting when supported', async () => { - env.sandbox - .stub(privacySandboxUtils, 'isAttributionReportingAllowed') - .returns(true); - a4a.sandboxHTMLCreativeFrame = () => true; - a4a.onLayoutMeasure(); - await a4a.layoutCallback(); - verifyCachedContentIframeRender(a4aElement, TEST_URL, true); - expect(a4a.iframe.getAttribute('allow')).to.include("sync-xhr 'none';"); - expect(a4a.iframe.getAttribute('allow')).to.include( - "attribution-reporting 'src';" - ); - }); - - it('should not set feature policy for attribution-reporting when not supported', async () => { - env.sandbox - .stub(privacySandboxUtils, 'isAttributionReportingAllowed') - .returns(false); - a4a.sandboxHTMLCreativeFrame = () => true; - a4a.onLayoutMeasure(); - await a4a.layoutCallback(); - verifyCachedContentIframeRender(a4aElement, TEST_URL, true); - expect(a4a.iframe.getAttribute('allow')).to.include("sync-xhr 'none';"); - expect(a4a.iframe.getAttribute('allow')).to.not.include( - "attribution-reporting 'src';" - ); - }); }); describe('illegal render mode value', () => { @@ -1038,30 +1009,6 @@ describes.realWin('amp-a4a', {amp: true}, (env) => { expect(fetchMock.called('ad')).to.be.true; }); - it('should set feature policy for attribution-reporting when supported', async () => { - env.sandbox - .stub(privacySandboxUtils, 'isAttributionReportingAllowed') - .returns(true); - a4a.sandboxHTMLCreativeFrame = () => false; - a4a.onLayoutMeasure(); - await a4a.layoutCallback(); - verifyNameFrameRender(a4aElement, false /* shouldSandbox */); - expect(a4a.iframe.getAttribute('allow')).to.equal( - "sync-xhr 'none';attribution-reporting 'src';" - ); - }); - - it('should not set feature policy for attribution-reporting when not supported', async () => { - env.sandbox - .stub(privacySandboxUtils, 'isAttributionReportingAllowed') - .returns(false); - a4a.sandboxHTMLCreativeFrame = () => false; - a4a.onLayoutMeasure(); - await a4a.layoutCallback(); - verifyNameFrameRender(a4aElement, false /* shouldSandbox */); - expect(a4a.iframe.getAttribute('allow')).to.equal("sync-xhr 'none';"); - }); - ['', 'client_cache', 'safeframe', 'some_random_thing'].forEach( (headerVal) => { it(`should not attach a NameFrame when header is ${headerVal}`, async () => { @@ -1171,38 +1118,6 @@ describes.realWin('amp-a4a', {amp: true}, (env) => { expect(fetchMock.called('ad')).to.be.true; }); - it('should set feature policy for attribution-reporting when supported', async () => { - env.sandbox - .stub(privacySandboxUtils, 'isAttributionReportingAllowed') - .returns(true); - a4a.sandboxHTMLCreativeFrame = () => false; - a4a.onLayoutMeasure(); - await a4a.layoutCallback(); - verifySafeFrameRender( - a4aElement, - DEFAULT_SAFEFRAME_VERSION, - false /* shouldSandbox */ - ); - expect(a4a.iframe.getAttribute('allow')).to.equal( - "sync-xhr 'none';attribution-reporting 'src';" - ); - }); - - it('should not set feature policy for attribution-reporting when not supported', async () => { - env.sandbox - .stub(privacySandboxUtils, 'isAttributionReportingAllowed') - .returns(false); - a4a.sandboxHTMLCreativeFrame = () => false; - a4a.onLayoutMeasure(); - await a4a.layoutCallback(); - verifySafeFrameRender( - a4aElement, - DEFAULT_SAFEFRAME_VERSION, - false /* shouldSandbox */ - ); - expect(a4a.iframe.getAttribute('allow')).to.equal("sync-xhr 'none';"); - }); - ['', 'client_cache', 'nameframe', 'some_random_thing'].forEach( (headerVal) => { it(`should not attach a SafeFrame when header is ${headerVal}`, async () => { diff --git a/extensions/amp-ad-exit/0.1/amp-ad-exit.js b/extensions/amp-ad-exit/0.1/amp-ad-exit.js index ed96c1f59160..4bf702dc8e4f 100644 --- a/extensions/amp-ad-exit/0.1/amp-ad-exit.js +++ b/extensions/amp-ad-exit/0.1/amp-ad-exit.js @@ -14,10 +14,6 @@ import {Services} from '#service'; import {getData} from '#utils/event-helper'; import {dev, devAssert, user, userAssert} from '#utils/log'; -import { - AttributionReportingStatus, - isAttributionReportingAllowed, -} from '#utils/privacy-sandbox-utils'; import {TransportMode, assertConfig, assertVendor} from './config'; import {makeClickDelaySpec} from './filters/click-delay'; @@ -93,8 +89,7 @@ export class AmpAdExit extends AMP.BaseElement { this.expectedOriginToVendor_ = {}; /** @private @const {boolean} */ - this.isAttributionReportingSupported_ = - this.detectAttributionReportingSupport(); + this.isAttributionReportingSupported_ = false; } /** @@ -191,10 +186,8 @@ export class AmpAdExit extends AMP.BaseElement { getUrlVariableRewriter_(args, event, target) { const substitutionFunctions = { 'ATTRIBUTION_REPORTING_STATUS': () => - getAttributionReportingStatus( - this.isAttributionReportingSupported_, - target - ), + // ARA removed + this.isAttributionReportingSupported_, 'CLICK_X': () => event.clientX, 'CLICK_Y': () => event.clientY, }; @@ -389,17 +382,7 @@ export class AmpAdExit extends AMP.BaseElement { .filter(Boolean), behaviors: target['behaviors'] || {}, }; - if ( - this.isAttributionReportingSupported_ && - target?.behaviors?.browserAdConversion - ) { - this.targets_[name]['windowFeatures'] = - this.getAttributionReportingValues_( - target?.behaviors?.browserAdConversion - ); - } else { - this.targets_[name]['trackingUrls'] = target['trackingUrls'] || []; - } + this.targets_[name]['trackingUrls'] = target['trackingUrls'] || []; // Build a map of {vendor, origin} for 3p custom variables in the config for (const customVar in target['vars']) { @@ -430,37 +413,6 @@ export class AmpAdExit extends AMP.BaseElement { this.init3pResponseListener_(); } - /** - * Determine if `attribution-reporting` is supported by user-agent. Should only return - * true for Chrome 92+. - * @visibleForTesting - * @return {boolean} - */ - detectAttributionReportingSupport() { - return isAttributionReportingAllowed(this.win.document); - } - - /** - * Extracts the keys from the `browserAdConversion` data creates a - * string to be used as the `features` param for the `window.open()` call. - * @param {JsonObject} adConversionData - * @return {?string} - */ - getAttributionReportingValues_(adConversionData) { - if (!adConversionData || !Object.keys(adConversionData)) { - return; - } - - // `noopener` is probably redundant here but left as defense in depth. - // https://groups.google.com/a/chromium.org/g/blink-dev/c/FFX6VkvladY/m/QgaWHK6ZBAAJ - const parts = ['noopener']; - for (const key of Object.keys(adConversionData)) { - const encoded = encodeURIComponent(adConversionData[key]); - parts.push(`${key.toLowerCase()}=${encoded}`); - } - return parts.join(','); - } - /** * Gets the resource ID of the amp-ad element containing this amp-ad-exit tag. * This is a pass-through for the version in service.js, solely because @@ -580,26 +532,3 @@ export class AmpAdExit extends AMP.BaseElement { AMP.extension(TAG, '0.1', (AMP) => { AMP.registerElement(TAG, AmpAdExit); }); - -/** - * Resolves the ATTRIBUTION_REPORTING_STATUS macro to the appropriate value - * based on the given config and browser support. - * @param {boolean} isAttributionReportingSupported - * @param {!NavigationTargetDef} target - * @return {AttributionReportingStatus} - * @visibleForTesting - */ -export function getAttributionReportingStatus( - isAttributionReportingSupported, - target -) { - if ( - target?.behaviors?.browserAdConversion && - isAttributionReportingSupported - ) { - return AttributionReportingStatus.ATTRIBUTION_DATA_PRESENT_AND_POLICY_ENABLED; - } else if (target?.behaviors?.browserAdConversion?.attributionsrc) { - return AttributionReportingStatus.ATTRIBUTION_DATA_PRESENT; - } - return AttributionReportingStatus.ATTRIBUTION_MACRO_PRESENT; -} diff --git a/extensions/amp-ad-exit/0.1/test/test-amp-ad-exit.js b/extensions/amp-ad-exit/0.1/test/test-amp-ad-exit.js index 03c390178661..74bff692a90f 100644 --- a/extensions/amp-ad-exit/0.1/test/test-amp-ad-exit.js +++ b/extensions/amp-ad-exit/0.1/test/test-amp-ad-exit.js @@ -6,7 +6,7 @@ import {installTimerService} from '#service/timer-impl'; import {setParentWindow} from '../../../../src/service-helpers'; import {IFRAME_TRANSPORTS} from '../../../amp-analytics/0.1/iframe-transport-vendors'; -import {AmpAdExit, getAttributionReportingStatus} from '../amp-ad-exit'; +import {AmpAdExit} from '../amp-ad-exit'; import {FilterType} from '../filters/filter'; const TEST_3P_VENDOR = '3p-vendor'; @@ -349,216 +349,6 @@ describes.realWin( ); }); - it('should enable attribution tracking when given `browserAdConversion`', async () => { - env.sandbox - .stub(AmpAdExit.prototype, 'detectAttributionReportingSupport') - .returns(true); - const openStub = env.sandbox.stub(win, 'open').returns(win); - const config = { - targets: { - landingPage: { - finalUrl: 'https://advertiser.example', - behaviors: { - browserAdConversion: { - attributionsrc: 'https://adtech.example', - }, - }, - }, - }, - }; - const el = await makeElementWithConfig(config); - const impl = await el.getImpl(); - - impl.executeAction({ - method: 'exit', - args: {target: 'landingPage'}, - event: makeClickEvent(1001), - satisfiesTrust: () => true, - }); - - expect(openStub).calledWithExactly( - 'https://advertiser.example', - '_blank', - 'noopener,attributionsrc=https%3A%2F%2Fadtech.example' - ); - }); - - it('should handle empty attributionsrc when given `browserAdConversion`', async () => { - env.sandbox - .stub(AmpAdExit.prototype, 'detectAttributionReportingSupport') - .returns(true); - const openStub = env.sandbox.stub(win, 'open').returns(win); - const config = { - targets: { - landingPage: { - finalUrl: 'https://adtech.example', - behaviors: { - browserAdConversion: { - attributionsrc: '', - }, - }, - }, - }, - }; - const el = await makeElementWithConfig(config); - const impl = await el.getImpl(); - - impl.executeAction({ - method: 'exit', - args: {target: 'landingPage'}, - event: makeClickEvent(1001), - satisfiesTrust: () => true, - }); - - expect(openStub).calledWithExactly( - 'https://adtech.example', - '_blank', - 'noopener,attributionsrc=' - ); - }); - - it('should ignore trackingUrls when attribution tracking enabled', async () => { - env.sandbox - .stub(AmpAdExit.prototype, 'detectAttributionReportingSupport') - .returns(true); - const openStub = env.sandbox.stub(win, 'open').returns(win); - const config = { - targets: { - landingPage: { - finalUrl: 'https://advertiser.example', - behaviors: { - browserAdConversion: { - attributionsrc: 'https://adtech.example', - }, - }, - 'trackingUrls': [ - 'http://localhost:8000/tracking?1', - 'http://localhost:8000/tracking?2', - 'http://localhost:8000/tracking?3', - ], - }, - }, - }; - const el = await makeElementWithConfig(config); - const impl = await el.getImpl(); - - impl.executeAction({ - method: 'exit', - args: {target: 'landingPage'}, - event: makeClickEvent(1001), - satisfiesTrust: () => true, - }); - - expect(openStub).calledWithExactly( - 'https://advertiser.example', - '_blank', - 'noopener,attributionsrc=https%3A%2F%2Fadtech.example' - ); - }); - - it('should fallback to tracking URLS when reporting API disabled', async () => { - env.sandbox - .stub(AmpAdExit.prototype, 'detectAttributionReportingSupport') - .returns(false); - const config = { - targets: { - landingPage: { - finalUrl: 'https://adtech.example', - behaviors: { - browserAdConversion: { - attributionsrc: 'https://adtech.example', - }, - }, - 'trackingUrls': [ - 'http://localhost:8000/tracking?1', - 'http://localhost:8000/tracking?2', - 'http://localhost:8000/tracking?3', - ], - }, - }, - }; - - const open = env.sandbox.stub(win, 'open').callsFake(() => { - return {name: 'fakeWin'}; - }); - const sendBeacon = env.sandbox - .stub(win.navigator, 'sendBeacon') - .callsFake(() => true); - const el = await makeElementWithConfig(config); - const impl = await el.getImpl(); - - impl.executeAction({ - method: 'exit', - args: {target: 'landingPage'}, - event: makeClickEvent(1001), - satisfiesTrust: () => true, - }); - - expect(open).to.have.been.calledOnce; - expect(sendBeacon).to.have.been.calledThrice; - expect(sendBeacon).to.have.been.calledWith( - 'http://localhost:8000/tracking?1', - '' - ); - expect(sendBeacon).to.have.been.calledWith( - 'http://localhost:8000/tracking?2', - '' - ); - expect(sendBeacon).to.have.been.calledWith( - 'http://localhost:8000/tracking?3', - '' - ); - }); - - it('should fallback to tracking URLS when no `browserAdConversion` data', async () => { - env.sandbox - .stub(AmpAdExit.prototype, 'detectAttributionReportingSupport') - .returns(true); - const config = { - targets: { - landingPage: { - finalUrl: 'https://adtech.example', - 'trackingUrls': [ - 'http://localhost:8000/tracking?1', - 'http://localhost:8000/tracking?2', - 'http://localhost:8000/tracking?3', - ], - }, - }, - }; - - const open = env.sandbox.stub(win, 'open').callsFake(() => { - return {name: 'fakeWin'}; - }); - const sendBeacon = env.sandbox - .stub(win.navigator, 'sendBeacon') - .callsFake(() => true); - const el = await makeElementWithConfig(config); - const impl = await el.getImpl(); - - impl.executeAction({ - method: 'exit', - args: {target: 'landingPage'}, - event: makeClickEvent(1001), - satisfiesTrust: () => true, - }); - - expect(open).to.have.been.calledOnce; - expect(sendBeacon).to.have.been.calledThrice; - expect(sendBeacon).to.have.been.calledWith( - 'http://localhost:8000/tracking?1', - '' - ); - expect(sendBeacon).to.have.been.calledWith( - 'http://localhost:8000/tracking?2', - '' - ); - expect(sendBeacon).to.have.been.calledWith( - 'http://localhost:8000/tracking?3', - '' - ); - }); - it('should ping tracking URLs with sendBeacon', async () => { const open = env.sandbox.stub(win, 'open').callsFake(() => { return {name: 'fakeWin'}; @@ -1147,51 +937,5 @@ describes.realWin( '' ); }); - - describe('ATTRIBUTION_REPORTING_STATUS macro', () => { - it('should return ATTRIBUTION_DATA_PRESENT_AND_POLICY_ENABLED if browserAdConfig is present and browser supported', () => { - const target = { - behaviors: { - browserAdConversion: { - attributionsrc: 'https://adtech.example', - }, - }, - }; - expect( - getAttributionReportingStatus( - true /* isAttributionReportingSupported*/, - target - ) - ).to.equal(6); - }); - - it('should return ATTRIBUTION_DATA_PRESENT if browserAdConfig is present and no browser support', () => { - const target = { - behaviors: { - browserAdConversion: { - attributionsrc: 'https://adtech.example', - }, - }, - }; - expect( - getAttributionReportingStatus( - false /* isAttributionReportingSupported*/, - target - ) - ).to.equal(5); - }); - - it('should return ATTRIBUTION_MACRO_PRESENT if browserAdConfig not present', () => { - const target = { - behaviors: {}, - }; - expect( - getAttributionReportingStatus( - false /* isAttributionReportingSupported*/, - target - ) - ).to.equal(4); - }); - }); } ); diff --git a/extensions/amp-ad-network-adsense-impl/0.1/amp-ad-network-adsense-impl.js b/extensions/amp-ad-network-adsense-impl/0.1/amp-ad-network-adsense-impl.js index adb1eb430186..a10e2670b4b9 100644 --- a/extensions/amp-ad-network-adsense-impl/0.1/amp-ad-network-adsense-impl.js +++ b/extensions/amp-ad-network-adsense-impl/0.1/amp-ad-network-adsense-impl.js @@ -44,7 +44,6 @@ import { getExperimentBranch, randomlySelectUnsetExperiments, } from '#experiments'; -import {AttributionReporting} from '#experiments/attribution-reporting'; import {StoryAdPlacements} from '#experiments/story-ad-placements'; import {StoryAdSegmentExp} from '#experiments/story-ad-progress-segment'; @@ -53,7 +52,6 @@ import {Navigation} from '#service/navigation'; import {getData} from '#utils/event-helper'; import {dev, devAssert, user} from '#utils/log'; -import {isAttributionReportingAllowed} from '#utils/privacy-sandbox-utils'; import {AdsenseSharedState} from './adsense-shared-state'; import {ResponsiveState} from './responsive-state'; @@ -218,19 +216,7 @@ export class AmpAdNetworkAdsenseImpl extends AmpA4A { */ divertExperiments() { const experimentInfoList = - /** @type {!Array} */ ([ - { - experimentId: AttributionReporting.ID, - isTrafficEligible: () => - isAttributionReportingAllowed(this.win.document), - branches: [ - AttributionReporting.ENABLE, - AttributionReporting.DISABLE, - AttributionReporting.ENABLE_NO_ASYNC, - AttributionReporting.DISABLE_NO_ASYNC, - ], - }, - ]); + /** @type {!Array} */ ([]); const setExps = randomlySelectUnsetExperiments( this.win, experimentInfoList diff --git a/extensions/amp-ad-network-doubleclick-impl/0.1/amp-ad-network-doubleclick-impl.js b/extensions/amp-ad-network-doubleclick-impl/0.1/amp-ad-network-doubleclick-impl.js index 241a6ac8902e..9e8abc210ead 100644 --- a/extensions/amp-ad-network-doubleclick-impl/0.1/amp-ad-network-doubleclick-impl.js +++ b/extensions/amp-ad-network-doubleclick-impl/0.1/amp-ad-network-doubleclick-impl.js @@ -69,7 +69,6 @@ import { isExperimentOn, randomlySelectUnsetExperiments, } from '#experiments'; -import {AttributionReporting} from '#experiments/attribution-reporting'; import {StoryAdPlacements} from '#experiments/story-ad-placements'; import {StoryAdSegmentExp} from '#experiments/story-ad-progress-segment'; @@ -78,7 +77,6 @@ import {Navigation} from '#service/navigation'; import {RTC_VENDORS} from '#service/real-time-config/callout-vendors'; import {dev, devAssert, user} from '#utils/log'; -import {isAttributionReportingAllowed} from '#utils/privacy-sandbox-utils'; import { FlexibleAdSlotDataTypeDef, @@ -475,17 +473,6 @@ export class AmpAdNetworkDoubleclickImpl extends AmpA4A { }, branches: Object.values(IDLE_CWV_EXP_BRANCHES), }, - { - experimentId: AttributionReporting.ID, - isTrafficEligible: () => - isAttributionReportingAllowed(this.win.document), - branches: [ - AttributionReporting.ENABLE, - AttributionReporting.DISABLE, - AttributionReporting.ENABLE_NO_ASYNC, - AttributionReporting.DISABLE_NO_ASYNC, - ], - }, ]); const setExps = this.randomlySelectUnsetExperiments_(experimentInfoList); Object.keys(setExps).forEach( diff --git a/extensions/amp-analytics/0.1/test/test-transport.js b/extensions/amp-analytics/0.1/test/test-transport.js index 470094b9d7b5..8a6febb54445 100644 --- a/extensions/amp-analytics/0.1/test/test-transport.js +++ b/extensions/amp-analytics/0.1/test/test-transport.js @@ -11,8 +11,6 @@ import { mockWindowInterface, } from '#testing/helpers/service'; -import * as privacySandboxUtils from 'src/utils/privacy-sandbox-utils'; - import {getMode} from '../../../../src/mode'; import {AmpScriptService} from '../../../amp-script/0.1/amp-script'; import {Transport} from '../transport'; @@ -105,44 +103,6 @@ describes.realWin( expectImagePixel('https://example.test/test', 'no-referrer'); }); - it('carries attributionSrc over to image pixel', () => { - setupStubs(true, true); - env.sandbox - .stub(privacySandboxUtils, 'isAttributionReportingAllowed') - .returns(true); - sendRequest(win, 'https://example.test/test', { - beacon: true, - xhrpost: true, - image: true, - referrerPolicy: 'no-referrer', - attributionsrc: 'https://example.test/attributionsrc', - }); - expectNoBeacon(); - expectNoXhr(); - expectImagePixel( - 'https://example.test/test', - 'no-referrer', - 'https://example.test/attributionsrc' - ); - }); - - it('carries empty attributionSrc over to image pixel', () => { - setupStubs(true, true); - env.sandbox - .stub(privacySandboxUtils, 'isAttributionReportingAllowed') - .returns(true); - sendRequest(win, 'https://example.test/test', { - beacon: true, - xhrpost: true, - image: true, - referrerPolicy: 'no-referrer', - attributionsrc: '', - }); - expectNoBeacon(); - expectNoXhr(); - expectImagePixel('https://example.test/test', 'no-referrer', ''); - }); - it('falls back to xhrpost when enabled and beacon is not available', () => { setupStubs(false, true); sendRequest(win, 'https://example.test/test', { @@ -578,8 +538,8 @@ describes.realWin( expect(sendXhrStub).to.not.be.called; } - function expectImagePixel(url, referrerPolicy, attributionSrc) { - imagePixelVerifier.verifyRequest(url, referrerPolicy, attributionSrc); + function expectImagePixel(url, referrerPolicy) { + imagePixelVerifier.verifyRequest(url, referrerPolicy); expect(Services.urlReplacementsForDoc).to.be.calledWith(ampdoc); } diff --git a/extensions/amp-analytics/0.1/transport.js b/extensions/amp-analytics/0.1/transport.js index 83fca0ae3367..15749a76244d 100644 --- a/extensions/amp-analytics/0.1/transport.js +++ b/extensions/amp-analytics/0.1/transport.js @@ -68,11 +68,6 @@ export class Transport { /** @private {boolean} */ this.isInabox_ = getMode(this.win_).runtime == 'inabox'; - - /** @private {string|undefined} */ - this.attributionSrc_ = /** @type {string|undefined} */ ( - this.options_['attributionsrc'] - ); } /** @@ -141,7 +136,6 @@ export class Transport { getRequest(false), suppressWarnings, /** @type {string|undefined} */ (this.referrerPolicy_), - /** @type {string|undefined} */ (this.attributionSrc_), this.ampdoc_ ); return; @@ -248,7 +242,6 @@ export class Transport { * @param {!RequestDef} request * @param {boolean} suppressWarnings * @param {string|undefined} referrerPolicy - * @param {string|undefined} attributionSrc * @param {!Element|!./service/ampdoc-impl.AmpDoc} elementOrAmpDoc Whether services are provided by an * element. */ @@ -257,7 +250,6 @@ export class Transport { request, suppressWarnings, referrerPolicy, - attributionSrc, elementOrAmpDoc ) { if (!win) { @@ -267,7 +259,6 @@ export class Transport { win, request.url, referrerPolicy, - attributionSrc, elementOrAmpDoc ); loadPromise(image) diff --git a/src/experiments/attribution-reporting.js b/src/experiments/attribution-reporting.js deleted file mode 100644 index 88853a167e19..000000000000 --- a/src/experiments/attribution-reporting.js +++ /dev/null @@ -1,11 +0,0 @@ -/** - * @const - * @type {{[key: string]: string}} - */ -export const AttributionReporting = { - ID: 'attribution-reporting', - DISABLE: '42531928', - ENABLE: '42531929', - DISABLE_NO_ASYNC: '42531930', - ENABLE_NO_ASYNC: '42531931', -}; diff --git a/src/pixel.js b/src/pixel.js index 16ec556ef870..a9b8cef35a0b 100644 --- a/src/pixel.js +++ b/src/pixel.js @@ -5,11 +5,6 @@ import {Services} from '#service'; import {user} from '#utils/log'; -import { - AttributionReportingStatus, - isAttributionReportingAllowed, -} from './utils/privacy-sandbox-utils'; - /** @const {string} */ const TAG = 'pixel'; @@ -17,45 +12,32 @@ const TAG = 'pixel'; * @param {!Window} win * @param {string} src * @param {?string=} referrerPolicy - * @param {string=} attributionSrc * @param {(Element|./service/ampdoc-impl.AmpDoc)=} opt_elementOrAmpDoc Whether services are provided by an * element. * @return {!Element} */ -export function createPixel( - win, - src, - referrerPolicy, - attributionSrc, - opt_elementOrAmpDoc -) { +export function createPixel(win, src, referrerPolicy, opt_elementOrAmpDoc) { // Caller need to verify window is not destroyed when creating pixel if (referrerPolicy && referrerPolicy !== 'no-referrer') { user().error(TAG, 'Unsupported referrerPolicy: %s', referrerPolicy); } return referrerPolicy === 'no-referrer' - ? createNoReferrerPixel(win, src, attributionSrc, opt_elementOrAmpDoc) - : createImagePixel(win, src, false, attributionSrc, opt_elementOrAmpDoc); + ? createNoReferrerPixel(win, src, opt_elementOrAmpDoc) + : createImagePixel(win, src, false, opt_elementOrAmpDoc); } /** * @param {!Window} win * @param {string} src - * @param {string=} attributionSrc + * @param {(Element|./service/ampdoc-impl.AmpDoc)=} opt_elementOrAmpDoc Whether services are provided by an * element. * @return {!Element} */ -function createNoReferrerPixel(win, src, attributionSrc, opt_elementOrAmpDoc) { +function createNoReferrerPixel(win, src, opt_elementOrAmpDoc) { if (isReferrerPolicySupported()) { - return createImagePixel( - win, - src, - true, - attributionSrc, - opt_elementOrAmpDoc - ); + return createImagePixel(win, src, true, opt_elementOrAmpDoc); } else { // if "referrerPolicy" is not supported, use iframe wrapper // to scrub the referrer. @@ -72,7 +54,6 @@ function createNoReferrerPixel(win, src, attributionSrc, opt_elementOrAmpDoc) { iframe.contentWindow, src, undefined, - undefined, opt_elementOrAmpDoc ); }; @@ -85,49 +66,22 @@ function createNoReferrerPixel(win, src, attributionSrc, opt_elementOrAmpDoc) { * @param {!Window} win * @param {string} src * @param {boolean=} noReferrer - * @param {string=} attributionSrc + * @param {(Element|./service/ampdoc-impl.AmpDoc)=} opt_elementOrAmpDoc Whether services are provided by an * element. * @return {!Image} */ -function createImagePixel( - win, - src, - noReferrer = false, - attributionSrc, - opt_elementOrAmpDoc -) { +function createImagePixel(win, src, noReferrer = false, opt_elementOrAmpDoc) { const Image = WindowInterface.getImage(win); const image = new Image(); if (noReferrer) { image.referrerPolicy = 'no-referrer'; } - let attributionReportingStatus = - AttributionReportingStatus.ATTRIBUTION_DATA_UNSPECIFIED; - if (attributionSrc != null) { - if (isAttributionReportingAllowed(win.document)) { - attributionReportingStatus = - AttributionReportingStatus.ATTRIBUTION_DATA_PRESENT_AND_POLICY_ENABLED; - const substituteVariables = - getAttributionReportingStatusUrlVariableRewriter( - win, - attributionReportingStatus, - opt_elementOrAmpDoc - ); - attributionSrc = substituteVariables(attributionSrc); - image.attributionSrc = attributionSrc; - } else { - attributionReportingStatus = - AttributionReportingStatus.ATTRIBUTION_DATA_PRESENT; - } - } - const substituteVariables = getAttributionReportingStatusUrlVariableRewriter( - win, - attributionReportingStatus, - opt_elementOrAmpDoc + const replacements = Services.urlReplacementsForDoc( + opt_elementOrAmpDoc || win.document ); - src = substituteVariables(src); + src = replacements.expandUrlSync(src); image.src = src; return image; } @@ -141,29 +95,3 @@ function createImagePixel( function isReferrerPolicySupported() { return 'referrerPolicy' in Image.prototype; } - -/** - * @param {!Window} win - * @param {string=} status - * @param {(Element|./service/ampdoc-impl.AmpDoc)=} opt_elementOrAmpDoc Whether services are provided by an - * element. - * @return {function(string): string} - */ -function getAttributionReportingStatusUrlVariableRewriter( - win, - status, - opt_elementOrAmpDoc -) { - const substitutionFunctions = { - 'ATTRIBUTION_REPORTING_STATUS': () => status, - }; - const replacements = Services.urlReplacementsForDoc( - opt_elementOrAmpDoc || win.document - ); - const allowlist = { - 'ATTRIBUTION_REPORTING_STATUS': true, - }; - - return (url) => - replacements.expandUrlSync(url, substitutionFunctions, allowlist); -} diff --git a/src/utils/privacy-sandbox-utils.js b/src/utils/privacy-sandbox-utils.js deleted file mode 100644 index b035ca998800..000000000000 --- a/src/utils/privacy-sandbox-utils.js +++ /dev/null @@ -1,28 +0,0 @@ -/** - * Determine if `attribution-reporting` API is available in browser. - * @param {!Document} doc - * @return {boolean} - */ -export function isAttributionReportingAvailable(doc) { - return doc.featurePolicy?.features().includes('attribution-reporting'); -} - -/** - * Determine if `attribution-reporting` API is allowed in current context. - * @param {!Document} doc - * @return {boolean} - */ -export function isAttributionReportingAllowed(doc) { - return doc.featurePolicy?.allowedFeatures().includes('attribution-reporting'); -} - -/** - * Indicates the status of the `attribution-reporting` API. - * @enum - */ -export const AttributionReportingStatus = { - ATTRIBUTION_DATA_UNSPECIFIED: 0, - ATTRIBUTION_MACRO_PRESENT: 4, - ATTRIBUTION_DATA_PRESENT: 5, - ATTRIBUTION_DATA_PRESENT_AND_POLICY_ENABLED: 6, -}; diff --git a/test/unit/builtins/test-amp-pixel.js b/test/unit/builtins/test-amp-pixel.js index a7ee43aae008..266f2de06d7f 100644 --- a/test/unit/builtins/test-amp-pixel.js +++ b/test/unit/builtins/test-amp-pixel.js @@ -2,8 +2,6 @@ import {Services} from '#service'; import {installUrlReplacementsForEmbed} from '#service/url-replacements-impl'; import {VariableSource} from '#service/variable-source'; -import * as privacySandboxUtils from 'src/utils/privacy-sandbox-utils'; - describes.realWin('amp-pixel', {amp: true}, (env) => { const urlErrorRegex = /src attribute must start with/; @@ -40,13 +38,10 @@ describes.realWin('amp-pixel', {amp: true}, (env) => { * @param {string=} opt_attributionsrc * @return {!Promise} */ - function trigger(opt_src, opt_attributionsrc) { + function trigger(opt_src) { if (opt_src != null) { pixel.setAttribute('src', opt_src); } - if (opt_attributionsrc != null) { - pixel.setAttribute('attributionsrc', opt_attributionsrc); - } whenFirstVisibleResolver(); return whenFirstVisiblePromise .then(() => { @@ -140,63 +135,6 @@ describes.realWin('amp-pixel', {amp: true}, (env) => { ); }); }); - - it('should not allow attribution reporting with a non-supporting browser', () => { - env.sandbox - .stub(privacySandboxUtils, 'isAttributionReportingAllowed') - .returns(false); - const attributionSrc = - '//pubads.g.doubleclick.net/activity;dc_iu=1/abc;ord=2'; - pixel.setAttribute( - 'src', - 'https://pubads.g.doubleclick.net/activity;dc_iu=1/abc;ord=1?ars=ATTRIBUTION_REPORTING_STATUS' - ); - return trigger(null, attributionSrc).then((img) => { - // Protocol is resolved to `http:` relative to test server. - expect(img.src).to.equal( - 'https://pubads.g.doubleclick.net/activity;dc_iu=1/abc;ord=1?ars=5' - ); - }); - }); - - it('should allow attribution reporting with empty attributionsrc', () => { - env.sandbox - .stub(privacySandboxUtils, 'isAttributionReportingAllowed') - .returns(true); - const attributionSrc = ''; - pixel.setAttribute( - 'src', - 'https://pubads.g.doubleclick.net/activity;dc_iu=1/abc;ord=1?ars=ATTRIBUTION_REPORTING_STATUS' - ); - return trigger(null, attributionSrc).then((img) => { - // Protocol is resolved to `http:` relative to test server. - expect(img.src).to.equal( - 'https://pubads.g.doubleclick.net/activity;dc_iu=1/abc;ord=1?ars=6' - ); - expect(img.attributionSrc).to.equal(''); - expect(Services.urlReplacementsForDoc).to.be.calledWith(pixel); - }); - }); - - it('should allow attribution reporting with attributionsrc defined', () => { - env.sandbox - .stub(privacySandboxUtils, 'isAttributionReportingAllowed') - .returns(true); - pixel.setAttribute( - 'src', - 'https://pubads.g.doubleclick.net/activity;dc_iu=1/abc;ord=1?ars=ATTRIBUTION_REPORTING_STATUS' - ); - const attributionSrc = - 'https://adtech.example?ars=ATTRIBUTION_REPORTING_STATUS'; - return trigger(null, attributionSrc).then((img) => { - // Protocol is resolved to `http:` relative to test server. - expect(img.src).to.equal( - 'https://pubads.g.doubleclick.net/activity;dc_iu=1/abc;ord=1?ars=6' - ); - expect(img.attributionSrc).to.equal('https://adtech.example?ars=6'); - expect(Services.urlReplacementsForDoc).to.be.calledWith(pixel); - }); - }); }); describes.realWin( diff --git a/testing/helpers/service.js b/testing/helpers/service.js index 350795d60a70..b194d46ee9cc 100644 --- a/testing/helpers/service.js +++ b/testing/helpers/service.js @@ -380,11 +380,10 @@ export class ImagePixelVerifier { return this.imagePixels_.length > 0; } - verifyRequest(url, referrerPolicy, attributionSrc) { + verifyRequest(url, referrerPolicy) { const pixel = this.imagePixels_.shift(); expect(pixel.src).to.equal(url); expect(pixel.referrerPolicy).to.equal(referrerPolicy); - expect(pixel.attributionSrc).to.equal(attributionSrc); } verifyRequestMatch(regex) { diff --git a/validator/testdata/amp4ads_feature_tests/anchor_attribution_reporting.html b/validator/testdata/amp4ads_feature_tests/anchor_attribution_reporting.html deleted file mode 100644 index 4bd80f5d0db3..000000000000 --- a/validator/testdata/amp4ads_feature_tests/anchor_attribution_reporting.html +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - Hello, world. - - - - diff --git a/validator/testdata/amp4ads_feature_tests/anchor_attribution_reporting.out b/validator/testdata/amp4ads_feature_tests/anchor_attribution_reporting.out deleted file mode 100644 index 27f2ec28e7df..000000000000 --- a/validator/testdata/amp4ads_feature_tests/anchor_attribution_reporting.out +++ /dev/null @@ -1,20 +0,0 @@ -PASS -| -| -| -| -| -| -| -| -| -| -| Hello, world. -| -| -| -| \ No newline at end of file