forked from mirrors/gecko-dev
Bug 1901060 - Privacy Preserving Attribution origin trial and API. r=bbirdsong,mt,webidl,smaug
Differential Revision: https://phabricator.services.mozilla.com/D211093
This commit is contained in:
parent
c650eff9ee
commit
c9f45e36b2
22 changed files with 416 additions and 2 deletions
|
|
@ -21,6 +21,7 @@
|
|||
#include "nsIClassOfService.h"
|
||||
#include "nsIHttpProtocolHandler.h"
|
||||
#include "nsIContentPolicy.h"
|
||||
#include "nsIPrivateAttributionService.h"
|
||||
#include "nsContentPolicyUtils.h"
|
||||
#include "nsISupportsPriority.h"
|
||||
#include "nsIWebProtocolHandlerRegistrar.h"
|
||||
|
|
@ -41,11 +42,13 @@
|
|||
#include "BatteryManager.h"
|
||||
#include "mozilla/dom/CredentialsContainer.h"
|
||||
#include "mozilla/dom/Clipboard.h"
|
||||
#include "mozilla/dom/ContentChild.h"
|
||||
#include "mozilla/dom/FeaturePolicyUtils.h"
|
||||
#include "mozilla/dom/GamepadServiceTest.h"
|
||||
#include "mozilla/dom/MediaCapabilities.h"
|
||||
#include "mozilla/dom/MediaSession.h"
|
||||
#include "mozilla/dom/power/PowerManagerService.h"
|
||||
#include "mozilla/dom/PrivateAttribution.h"
|
||||
#include "mozilla/dom/LockManager.h"
|
||||
#include "mozilla/dom/MIDIAccessManager.h"
|
||||
#include "mozilla/dom/MIDIOptionsBinding.h"
|
||||
|
|
@ -161,6 +164,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(Navigator)
|
|||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mAddonManager)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mWebGpu)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mLocks)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPrivateAttribution)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mUserActivation)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mWakeLock)
|
||||
|
||||
|
|
@ -250,6 +254,8 @@ void Navigator::Invalidate() {
|
|||
mLocks = nullptr;
|
||||
}
|
||||
|
||||
mPrivateAttribution = nullptr;
|
||||
|
||||
mUserActivation = nullptr;
|
||||
|
||||
mSharePromise = nullptr;
|
||||
|
|
@ -2273,6 +2279,13 @@ dom::LockManager* Navigator::Locks() {
|
|||
return mLocks;
|
||||
}
|
||||
|
||||
dom::PrivateAttribution* Navigator::PrivateAttribution() {
|
||||
if (!mPrivateAttribution) {
|
||||
mPrivateAttribution = new dom::PrivateAttribution(GetWindow()->AsGlobal());
|
||||
}
|
||||
return mPrivateAttribution;
|
||||
}
|
||||
|
||||
/* static */
|
||||
bool Navigator::Webdriver() {
|
||||
#ifdef ENABLE_WEBDRIVER
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ class ServiceWorkerContainer;
|
|||
class CredentialsContainer;
|
||||
class Clipboard;
|
||||
class LockManager;
|
||||
class PrivateAttribution;
|
||||
class HTMLMediaElement;
|
||||
class AudioContext;
|
||||
class WakeLockJS;
|
||||
|
|
@ -209,6 +210,7 @@ class Navigator final : public nsISupports, public nsWrapperCache {
|
|||
dom::Clipboard* Clipboard();
|
||||
webgpu::Instance* Gpu();
|
||||
dom::LockManager* Locks();
|
||||
dom::PrivateAttribution* PrivateAttribution();
|
||||
|
||||
static bool Webdriver();
|
||||
|
||||
|
|
@ -300,7 +302,8 @@ class Navigator final : public nsISupports, public nsWrapperCache {
|
|||
RefPtr<AddonManager> mAddonManager;
|
||||
RefPtr<webgpu::Instance> mWebGpu;
|
||||
RefPtr<Promise> mSharePromise; // Web Share API related
|
||||
RefPtr<dom::LockManager> mLocks;
|
||||
RefPtr<LockManager> mLocks;
|
||||
RefPtr<dom::PrivateAttribution> mPrivateAttribution;
|
||||
RefPtr<dom::UserActivation> mUserActivation;
|
||||
RefPtr<dom::WakeLockJS> mWakeLock;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -17,9 +17,11 @@
|
|||
|
||||
#include "chrome/common/process_watcher.h"
|
||||
#include "mozilla/Result.h"
|
||||
#include "mozilla/Services.h"
|
||||
#include "mozilla/XREAppData.h"
|
||||
#include "nsComponentManagerUtils.h"
|
||||
#include "nsIBrowserDOMWindow.h"
|
||||
#include "nsIPrivateAttributionService.h"
|
||||
|
||||
#include "GMPServiceParent.h"
|
||||
#include "HandlerServiceParent.h"
|
||||
|
|
@ -1244,6 +1246,35 @@ mozilla::ipc::IPCResult ContentParent::RecvCreateGMPService() {
|
|||
return IPC_OK();
|
||||
}
|
||||
|
||||
IPCResult ContentParent::RecvAttributionEvent(
|
||||
const nsACString& aHost, PrivateAttributionImpressionType aType,
|
||||
uint32_t aIndex, const nsAString& aAd, const nsACString& aTargetHost) {
|
||||
nsCOMPtr<nsIPrivateAttributionService> pa =
|
||||
components::PrivateAttribution::Service();
|
||||
if (NS_WARN_IF(!pa)) {
|
||||
return IPC_OK();
|
||||
}
|
||||
pa->OnAttributionEvent(aHost, GetEnumString(aType), aIndex, aAd, aTargetHost);
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
IPCResult ContentParent::RecvAttributionConversion(
|
||||
const nsACString& aHost, const nsAString& aTask, uint32_t aHistogramSize,
|
||||
const Maybe<uint32_t>& aLoopbackDays,
|
||||
const Maybe<PrivateAttributionImpressionType>& aImpressionType,
|
||||
const nsTArray<nsString>& aAds, const nsTArray<nsCString>& aSourceHosts) {
|
||||
nsCOMPtr<nsIPrivateAttributionService> pa =
|
||||
components::PrivateAttribution::Service();
|
||||
if (NS_WARN_IF(!pa)) {
|
||||
return IPC_OK();
|
||||
}
|
||||
pa->OnAttributionConversion(
|
||||
aHost, aTask, aHistogramSize, aLoopbackDays.valueOr(0),
|
||||
aImpressionType ? GetEnumString(*aImpressionType) : EmptyCString(), aAds,
|
||||
aSourceHosts);
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
Atomic<bool, mozilla::Relaxed> sContentParentTelemetryEventEnabled(false);
|
||||
|
||||
/*static*/
|
||||
|
|
|
|||
|
|
@ -443,6 +443,15 @@ class ContentParent final : public PContentParent,
|
|||
return PContentParent::RecvPHalConstructor(aActor);
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult RecvAttributionEvent(
|
||||
const nsACString& aHost, PrivateAttributionImpressionType aType,
|
||||
uint32_t aIndex, const nsAString& aAd, const nsACString& aTargetHost);
|
||||
mozilla::ipc::IPCResult RecvAttributionConversion(
|
||||
const nsACString& aHost, const nsAString& aTask, uint32_t aHistogramSize,
|
||||
const Maybe<uint32_t>& aLoopbackDays,
|
||||
const Maybe<PrivateAttributionImpressionType>& aImpressionType,
|
||||
const nsTArray<nsString>& aAds, const nsTArray<nsCString>& aSourceHosts);
|
||||
|
||||
PHeapSnapshotTempFileHelperParent* AllocPHeapSnapshotTempFileHelperParent();
|
||||
|
||||
PRemoteSpellcheckEngineParent* AllocPRemoteSpellcheckEngineParent();
|
||||
|
|
|
|||
|
|
@ -160,6 +160,7 @@ using mozilla::PerfStats::MetricMask from "mozilla/PerfStats.h";
|
|||
[RefCounted] using class nsIX509Cert from "nsIX509Cert.h";
|
||||
using nsIDNSService::ResolverMode from "nsIDNSService.h";
|
||||
using mozilla::dom::UserActivation::Modifiers from "mozilla/dom/UserActivation.h";
|
||||
using mozilla::dom::PrivateAttributionImpressionType from "mozilla/dom/PrivateAttributionIPCUtils.h";
|
||||
|
||||
union ChromeRegistryItem
|
||||
{
|
||||
|
|
@ -1970,6 +1971,17 @@ parent:
|
|||
// test document before taking the snapshot and starting e.g. IPC fuzzing.
|
||||
async SignalFuzzingReady();
|
||||
#endif
|
||||
|
||||
async AttributionEvent(nsCString aSourceHost,
|
||||
PrivateAttributionImpressionType aType,
|
||||
uint32_t aIndex, nsString aAd, nsCString aTargetHost);
|
||||
|
||||
async AttributionConversion(nsCString aSourceHost, nsString aTask,
|
||||
uint32_t aHistogramSize,
|
||||
uint32_t? aLoopbackDays,
|
||||
PrivateAttributionImpressionType? aImpressionType,
|
||||
nsString[] aAds,
|
||||
nsCString[] aImpressionSourceHosts);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -74,6 +74,7 @@ DIRS += [
|
|||
"audiochannel",
|
||||
"broadcastchannel",
|
||||
"messagechannel",
|
||||
"privateattribution",
|
||||
"promise",
|
||||
"smil",
|
||||
"streams",
|
||||
|
|
|
|||
|
|
@ -212,6 +212,8 @@ static int32_t PrefState(OriginTrial aTrial) {
|
|||
return StaticPrefs::dom_origin_trials_test_trial_state();
|
||||
case OriginTrial::CoepCredentialless:
|
||||
return StaticPrefs::dom_origin_trials_coep_credentialless_state();
|
||||
case OriginTrial::PrivateAttribution:
|
||||
return StaticPrefs::dom_origin_trials_private_attribution_state();
|
||||
case OriginTrial::MAX:
|
||||
MOZ_ASSERT_UNREACHABLE("Unknown trial!");
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ pub enum OriginTrial {
|
|||
// NOTE(emilio): 0 is reserved for WebIDL usage.
|
||||
TestTrial = 1,
|
||||
CoepCredentialless = 2,
|
||||
PrivateAttribution = 3,
|
||||
|
||||
MAX,
|
||||
}
|
||||
|
|
@ -19,6 +20,7 @@ impl OriginTrial {
|
|||
Some(match s {
|
||||
"TestTrial" => Self::TestTrial,
|
||||
"CoepCredentialless" => Self::CoepCredentialless,
|
||||
"PrivateAttribution" => Self::PrivateAttribution,
|
||||
_ => return None,
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,9 +13,11 @@ support-files = [
|
|||
# verification fails, expectedly.
|
||||
skip-if = [
|
||||
"!debug",
|
||||
"xorigin", # AudioWorklet requires secure context
|
||||
"xorigin",
|
||||
]
|
||||
|
||||
# We want to test that trials are exposed in worklets, and AudioWorklet
|
||||
# requires secure context.
|
||||
scheme = "https"
|
||||
|
||||
["test_expired_token.html"]
|
||||
|
|
|
|||
|
|
@ -3,11 +3,15 @@
|
|||
<meta http-equiv="origin-trial" content="AyGdETIKWLLqe+chG57f74gZcjYSfbdYAapEq7DA49E6CmaYaPmaoXh/4tAe5XJJJdwwpFVal7hz/irC+Wvp1HgAAABLeyJvcmlnaW4iOiJodHRwczovL2V4YW1wbGUuY29tIiwiZmVhdHVyZSI6IlRlc3RUcmlhbCIsImV4cGlyeSI6MzI1MDM2ODAwMDB9">
|
||||
<!-- Created with: mktoken --origin 'https://example.com' --feature CoepCredentialless --expiry 'Wed, 01 Jan 3000 01:00:00 +0100' --sign test-keys/test-ecdsa.pkcs8 -->
|
||||
<meta http-equiv="origin-trial" content="Az+DK2Kczk8Xz1cAlD+TkvPZmuM2uJZ2CFefbp2hLuCU9FbUqxWTyQ2tEYr50r0syKELcOZLAPaABw8aYTLHn5YAAABUeyJvcmlnaW4iOiJodHRwczovL2V4YW1wbGUuY29tIiwiZmVhdHVyZSI6IkNvZXBDcmVkZW50aWFsbGVzcyIsImV4cGlyeSI6MzI1MDM2ODAwMDB9">
|
||||
<!-- Created with: mktoken --origin 'https://example.com' --feature PrivateAttribution --expiry 'Wed, 01 Jan 3000 01:00:00 +0100' --sign test-keys/test-ecdsa.pkcs8 -->
|
||||
<meta http-equiv="origin-trial" content="A39jvTkkSoAueJadvVP6xeapNZVQLJgqbI6hwQc3kIYm0O96hc8WjpRwFVOnI+gN9zAQbQLEJEcibsRVAxQJ0bIAAABUeyJvcmlnaW4iOiJodHRwczovL2V4YW1wbGUuY29tIiwiZmVhdHVyZSI6IlByaXZhdGVBdHRyaWJ1dGlvbiIsImV4cGlyeSI6MzI1MDM2ODAwMDB9">
|
||||
<script src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script src="common.js"></script>
|
||||
<script>
|
||||
assertTestTrialActive(true);
|
||||
add_task(function() {
|
||||
ok(!!SpecialPowers.DOMWindowUtils.isCoepCredentialless(), "CoepCredentialless trial works.");
|
||||
ok(navigator.privateAttribution, "PrivateAttribution trial works.");
|
||||
ok('PrivateAttribution' in window, "PrivateAttribution trial works.");
|
||||
});
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -3,4 +3,8 @@
|
|||
<script src="common.js"></script>
|
||||
<script>
|
||||
assertTestTrialActive(false);
|
||||
add_task(function() {
|
||||
ok(!navigator.privateAttribution, "PrivateAttribution trial disabled.");
|
||||
ok(!('PrivateAttribution' in window), "PrivateAttribution trial disabled.");
|
||||
});
|
||||
</script>
|
||||
|
|
|
|||
123
dom/privateattribution/PrivateAttribution.cpp
Normal file
123
dom/privateattribution/PrivateAttribution.cpp
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et cindent: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "PrivateAttribution.h"
|
||||
#include "mozilla/dom/BindingUtils.h"
|
||||
#include "mozilla/dom/ContentChild.h"
|
||||
#include "mozilla/dom/PrivateAttributionBinding.h"
|
||||
#include "mozilla/Components.h"
|
||||
#include "nsIGlobalObject.h"
|
||||
#include "nsIPrivateAttributionService.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
#include "nsURLHelper.h"
|
||||
|
||||
namespace mozilla::dom {
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(PrivateAttribution, mOwner)
|
||||
|
||||
PrivateAttribution::PrivateAttribution(nsIGlobalObject* aGlobal)
|
||||
: mOwner(aGlobal) {
|
||||
MOZ_ASSERT(aGlobal);
|
||||
}
|
||||
|
||||
JSObject* PrivateAttribution::WrapObject(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aGivenProto) {
|
||||
return PrivateAttribution_Binding::Wrap(aCx, this, aGivenProto);
|
||||
}
|
||||
|
||||
PrivateAttribution::~PrivateAttribution() = default;
|
||||
|
||||
bool PrivateAttribution::GetSourceHost(nsACString& aSourceHost,
|
||||
ErrorResult& aRv) {
|
||||
MOZ_ASSERT(mOwner);
|
||||
nsIPrincipal* prin = mOwner->PrincipalOrNull();
|
||||
if (!prin || NS_FAILED(prin->GetHost(aSourceHost))) {
|
||||
aRv.ThrowInvalidStateError("Couldn't get source host");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
[[nodiscard]] static bool ValidateHost(const nsACString& aHost,
|
||||
ErrorResult& aRv) {
|
||||
if (!net_IsValidHostName(aHost)) {
|
||||
aRv.ThrowSyntaxError(aHost + " is not a valid host name"_ns);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void PrivateAttribution::SaveImpression(
|
||||
const PrivateAttributionImpressionOptions& aOptions, ErrorResult& aRv) {
|
||||
nsAutoCString source;
|
||||
if (!GetSourceHost(source, aRv)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ValidateHost(aOptions.mTarget, aRv)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (XRE_IsParentProcess()) {
|
||||
nsCOMPtr<nsIPrivateAttributionService> pa =
|
||||
components::PrivateAttribution::Service();
|
||||
if (NS_WARN_IF(!pa)) {
|
||||
return;
|
||||
}
|
||||
pa->OnAttributionEvent(source, GetEnumString(aOptions.mType),
|
||||
aOptions.mIndex, aOptions.mAd, aOptions.mTarget);
|
||||
return;
|
||||
}
|
||||
|
||||
auto* content = ContentChild::GetSingleton();
|
||||
if (NS_WARN_IF(!content)) {
|
||||
return;
|
||||
}
|
||||
content->SendAttributionEvent(source, aOptions.mType, aOptions.mIndex,
|
||||
aOptions.mAd, aOptions.mTarget);
|
||||
}
|
||||
|
||||
void PrivateAttribution::MeasureConversion(
|
||||
const PrivateAttributionConversionOptions& aOptions, ErrorResult& aRv) {
|
||||
nsAutoCString source;
|
||||
if (!GetSourceHost(source, aRv)) {
|
||||
return;
|
||||
}
|
||||
for (const nsACString& host : aOptions.mSources) {
|
||||
if (!ValidateHost(host, aRv)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (XRE_IsParentProcess()) {
|
||||
nsCOMPtr<nsIPrivateAttributionService> pa =
|
||||
components::PrivateAttribution::Service();
|
||||
if (NS_WARN_IF(!pa)) {
|
||||
return;
|
||||
}
|
||||
pa->OnAttributionConversion(
|
||||
source, aOptions.mTask, aOptions.mHistogramSize,
|
||||
aOptions.mLookbackDays.WasPassed() ? aOptions.mLookbackDays.Value() : 0,
|
||||
aOptions.mImpression.WasPassed()
|
||||
? GetEnumString(aOptions.mImpression.Value())
|
||||
: EmptyCString(),
|
||||
aOptions.mAds, aOptions.mSources);
|
||||
return;
|
||||
}
|
||||
|
||||
auto* content = ContentChild::GetSingleton();
|
||||
if (NS_WARN_IF(!content)) {
|
||||
return;
|
||||
}
|
||||
content->SendAttributionConversion(
|
||||
source, aOptions.mTask, aOptions.mHistogramSize,
|
||||
aOptions.mLookbackDays.WasPassed() ? Some(aOptions.mLookbackDays.Value())
|
||||
: Nothing(),
|
||||
aOptions.mImpression.WasPassed() ? Some(aOptions.mImpression.Value())
|
||||
: Nothing(),
|
||||
aOptions.mAds, aOptions.mSources);
|
||||
}
|
||||
|
||||
} // namespace mozilla::dom
|
||||
48
dom/privateattribution/PrivateAttribution.h
Normal file
48
dom/privateattribution/PrivateAttribution.h
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et cindent: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_dom_PrivateAttribution_h
|
||||
#define mozilla_dom_PrivateAttribution_h
|
||||
|
||||
#include "nsWrapperCache.h"
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
class nsIGlobalObject;
|
||||
namespace mozilla {
|
||||
class ErrorResult;
|
||||
}
|
||||
|
||||
namespace mozilla::dom {
|
||||
|
||||
struct PrivateAttributionImpressionOptions;
|
||||
struct PrivateAttributionConversionOptions;
|
||||
|
||||
class PrivateAttribution final : public nsWrapperCache {
|
||||
public:
|
||||
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(PrivateAttribution)
|
||||
NS_DECL_CYCLE_COLLECTION_NATIVE_WRAPPERCACHE_CLASS(PrivateAttribution)
|
||||
|
||||
explicit PrivateAttribution(nsIGlobalObject* aGlobal);
|
||||
static already_AddRefed<PrivateAttribution> Create(nsIGlobalObject& aGlobal);
|
||||
|
||||
nsIGlobalObject* GetParentObject() const { return mOwner; }
|
||||
JSObject* WrapObject(JSContext*, JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
void SaveImpression(const PrivateAttributionImpressionOptions&, ErrorResult&);
|
||||
void MeasureConversion(const PrivateAttributionConversionOptions&,
|
||||
ErrorResult&);
|
||||
|
||||
private:
|
||||
[[nodiscard]] bool GetSourceHost(nsACString&, ErrorResult&);
|
||||
|
||||
~PrivateAttribution();
|
||||
|
||||
nsCOMPtr<nsIGlobalObject> mOwner;
|
||||
};
|
||||
|
||||
} // namespace mozilla::dom
|
||||
|
||||
#endif // mozilla_dom_PrivateAttribution_h
|
||||
22
dom/privateattribution/PrivateAttributionIPCUtils.h
Normal file
22
dom/privateattribution/PrivateAttributionIPCUtils.h
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_dom_PrivateAttributionIPCUtils_h
|
||||
#define mozilla_dom_PrivateAttributionIPCUtils_h
|
||||
|
||||
#include "mozilla/dom/PrivateAttributionBinding.h"
|
||||
#include "mozilla/dom/BindingIPCUtils.h"
|
||||
|
||||
namespace IPC {
|
||||
|
||||
template <>
|
||||
struct ParamTraits<mozilla::dom::PrivateAttributionImpressionType>
|
||||
: public mozilla::dom::WebIDLEnumSerializer<
|
||||
mozilla::dom::PrivateAttributionImpressionType> {};
|
||||
|
||||
} // namespace IPC
|
||||
|
||||
#endif
|
||||
31
dom/privateattribution/PrivateAttributionService.sys.mjs
Normal file
31
dom/privateattribution/PrivateAttributionService.sys.mjs
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
/* vim: set ts=2 sw=2 sts=2 et tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export class PrivateAttributionService {
|
||||
onAttributionEvent(sourceHost, type, index, ad, targetHost) {
|
||||
dump(
|
||||
`onAttributionEvent(${sourceHost}, ${type}, ${index}, ${ad}, ${targetHost})\n`
|
||||
);
|
||||
}
|
||||
|
||||
onAttributionConversion(
|
||||
sourceHost,
|
||||
task,
|
||||
histogramSize,
|
||||
loopbackDays,
|
||||
impressionType,
|
||||
ads,
|
||||
sourceHosts
|
||||
) {
|
||||
dump(
|
||||
`onAttributionConversion(${sourceHost}, ${task}, ${histogramSize}, ${loopbackDays}, ${impressionType}, ${ads}, ${sourceHosts})\n`
|
||||
);
|
||||
}
|
||||
|
||||
QueryInterface = ChromeUtils.generateQI([Ci.nsIPrivateAttributionService]);
|
||||
}
|
||||
15
dom/privateattribution/components.conf
Normal file
15
dom/privateattribution/components.conf
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# vim: set filetype=python:
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
Classes = [
|
||||
{
|
||||
'cid': '{57d16147-1deb-46ac-8f1c-1140b5e1ddfd}',
|
||||
'name': 'PrivateAttribution',
|
||||
'contract_ids': ['@mozilla.org/private-attribution;1'],
|
||||
'esModule': 'resource://gre/modules/PrivateAttributionService.sys.mjs',
|
||||
'constructor': 'PrivateAttributionService',
|
||||
},
|
||||
]
|
||||
35
dom/privateattribution/moz.build
Normal file
35
dom/privateattribution/moz.build
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# vim: set filetype=python:
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
with Files("**"):
|
||||
BUG_COMPONENT = ("Core", "DOM: Core & HTML")
|
||||
|
||||
EXPORTS.mozilla.dom += [
|
||||
"PrivateAttribution.h",
|
||||
"PrivateAttributionIPCUtils.h",
|
||||
]
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
"PrivateAttribution.cpp",
|
||||
]
|
||||
|
||||
XPIDL_SOURCES += [
|
||||
"nsIPrivateAttributionService.idl",
|
||||
]
|
||||
|
||||
XPIDL_MODULE = "privateattribution"
|
||||
|
||||
XPCOM_MANIFESTS += [
|
||||
"components.conf",
|
||||
]
|
||||
|
||||
EXTRA_JS_MODULES += [
|
||||
"PrivateAttributionService.sys.mjs",
|
||||
]
|
||||
|
||||
include("/ipc/chromium/chromium-config.mozbuild")
|
||||
|
||||
FINAL_LIBRARY = "xul"
|
||||
14
dom/privateattribution/nsIPrivateAttributionService.idl
Normal file
14
dom/privateattribution/nsIPrivateAttributionService.idl
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
[scriptable, uuid(c7e7fc54-4133-4191-bd40-cc2b77fd21bc)]
|
||||
interface nsIPrivateAttributionService : nsISupports
|
||||
{
|
||||
void onAttributionEvent(in ACString sourceHost, in ACString type, in uint32_t index, in AString ad, in ACString targetHost);
|
||||
void onAttributionConversion(in ACString sourceHost, in AString task, in uint32_t histogramSize, in uint32_t loopbackDays, in ACString impressionType, in Array<AString> ads, in Array<ACString> sourceHosts);
|
||||
};
|
||||
|
|
@ -394,3 +394,9 @@ partial interface Navigator {
|
|||
[SameObject, Pref="dom.screenwakelock.enabled"]
|
||||
readonly attribute WakeLock wakeLock;
|
||||
};
|
||||
|
||||
[SecureContext]
|
||||
partial interface Navigator {
|
||||
[SameObject, Trial="PrivateAttribution"]
|
||||
readonly attribute PrivateAttribution privateAttribution;
|
||||
};
|
||||
|
|
|
|||
29
dom/webidl/PrivateAttribution.webidl
Normal file
29
dom/webidl/PrivateAttribution.webidl
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
enum PrivateAttributionImpressionType { "view", "click" };
|
||||
|
||||
dictionary PrivateAttributionImpressionOptions {
|
||||
PrivateAttributionImpressionType type = "view";
|
||||
required unsigned long index;
|
||||
required DOMString ad;
|
||||
required UTF8String target;
|
||||
};
|
||||
|
||||
dictionary PrivateAttributionConversionOptions {
|
||||
required DOMString task;
|
||||
required unsigned long histogramSize;
|
||||
|
||||
unsigned long lookbackDays;
|
||||
PrivateAttributionImpressionType impression;
|
||||
sequence<DOMString> ads = [];
|
||||
sequence<UTF8String> sources = [];
|
||||
};
|
||||
|
||||
[Trial="PrivateAttribution", SecureContext, Exposed=Window]
|
||||
interface PrivateAttribution {
|
||||
[Throws] undefined saveImpression(PrivateAttributionImpressionOptions options);
|
||||
[Throws] undefined measureConversion(PrivateAttributionConversionOptions options);
|
||||
};
|
||||
|
|
@ -804,6 +804,7 @@ WEBIDL_FILES = [
|
|||
"PluginArray.webidl",
|
||||
"PointerEvent.webidl",
|
||||
"PopoverInvokerElement.webidl",
|
||||
"PrivateAttribution.webidl",
|
||||
"ProcessingInstruction.webidl",
|
||||
"Promise.webidl",
|
||||
"PushEvent.webidl",
|
||||
|
|
|
|||
|
|
@ -3216,6 +3216,13 @@
|
|||
value: 0
|
||||
mirror: always
|
||||
|
||||
# Origin trial state for Private Attribution
|
||||
# 0: normal, 1: always-enabled, 2: always-disabled
|
||||
- name: dom.origin-trials.private-attribution.state
|
||||
type: RelaxedAtomicInt32
|
||||
value: 0
|
||||
mirror: always
|
||||
|
||||
# Is support for Window.paintWorklet enabled?
|
||||
- name: dom.paintWorklet.enabled
|
||||
type: bool
|
||||
|
|
|
|||
Loading…
Reference in a new issue