Skip to content

Commit 2205f6b

Browse files
committed
Add new pixels and remove old one
1 parent c6164f9 commit 2205f6b

File tree

3 files changed

+191
-23
lines changed

3 files changed

+191
-23
lines changed

pir/pir-impl/src/main/java/com/duckduckgo/pir/impl/pixels/PirPixel.kt

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -76,11 +76,6 @@ enum class PirPixel(
7676
type = Count,
7777
),
7878

79-
PIR_INTERNAL_BROKER_OPT_OUT_COMPLETED(
80-
baseName = "pir_internal_opt-out_completed",
81-
type = Count,
82-
),
83-
8479
PIR_INTERNAL_CPU_USAGE(
8580
baseName = "pir_internal_cpu_usage",
8681
type = Count,
@@ -130,6 +125,16 @@ enum class PirPixel(
130125
PIR_INTERNAL_SECURE_STORAGE_UNAVAILABLE(
131126
baseName = "pir_internal_secure-storage_unavailable",
132127
types = setOf(Count, Daily()),
128+
),
129+
130+
PIR_OPTOUT_SUBMIT_SUCCESS(
131+
baseName = "pir_optout_process_submit-success",
132+
types = setOf(Count),
133+
),
134+
135+
PIR_OPTOUT_SUBMIT_FAILURE(
136+
baseName = "pir_optout_process_failure",
137+
types = setOf(Count),
133138
), ;
134139

135140
constructor(

pir/pir-impl/src/main/java/com/duckduckgo/pir/impl/pixels/PirPixelSender.kt

Lines changed: 91 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ import com.duckduckgo.pir.impl.pixels.PirPixel.PIR_EMAIL_CONFIRMATION_LINK_RECEI
2727
import com.duckduckgo.pir.impl.pixels.PirPixel.PIR_EMAIL_CONFIRMATION_MAX_RETRIES_EXCEEDED
2828
import com.duckduckgo.pir.impl.pixels.PirPixel.PIR_EMAIL_CONFIRMATION_RUN_COMPLETED
2929
import com.duckduckgo.pir.impl.pixels.PirPixel.PIR_EMAIL_CONFIRMATION_RUN_STARTED
30-
import com.duckduckgo.pir.impl.pixels.PirPixel.PIR_INTERNAL_BROKER_OPT_OUT_COMPLETED
3130
import com.duckduckgo.pir.impl.pixels.PirPixel.PIR_INTERNAL_BROKER_OPT_OUT_STARTED
3231
import com.duckduckgo.pir.impl.pixels.PirPixel.PIR_INTERNAL_BROKER_SCAN_COMPLETED
3332
import com.duckduckgo.pir.impl.pixels.PirPixel.PIR_INTERNAL_BROKER_SCAN_STARTED
@@ -41,6 +40,8 @@ import com.duckduckgo.pir.impl.pixels.PirPixel.PIR_INTERNAL_SCHEDULED_SCAN_SCHED
4140
import com.duckduckgo.pir.impl.pixels.PirPixel.PIR_INTERNAL_SCHEDULED_SCAN_STARTED
4241
import com.duckduckgo.pir.impl.pixels.PirPixel.PIR_INTERNAL_SECURE_STORAGE_UNAVAILABLE
4342
import com.duckduckgo.pir.impl.pixels.PirPixel.PIR_OPTOUT_STAGE_PENDING_EMAIL_CONFIRMATION
43+
import com.duckduckgo.pir.impl.pixels.PirPixel.PIR_OPTOUT_SUBMIT_FAILURE
44+
import com.duckduckgo.pir.impl.pixels.PirPixel.PIR_OPTOUT_SUBMIT_SUCCESS
4445
import com.squareup.anvil.annotations.ContributesBinding
4546
import logcat.logcat
4647
import javax.inject.Inject
@@ -109,17 +110,49 @@ interface PirPixelSender {
109110
)
110111

111112
/**
112-
* Emits a pixel to signal that an opt-out job for a specific extractedProfile has been completed.
113-
* It could mean that the opt-out for the record was successful or failed.
113+
* Emits a pixel to signal that an opt-out job for a specific extractedProfile has been successfully submitted.
114114
*
115-
* @param brokerName for which the opt-out is for
116-
* @param totalTimeInMillis How long it took to complete the opt-out for the record.
117-
* @param isSuccess - if result was not an error, it is a success.
115+
* @param brokerUrl url of the Broker for which the opt-out is for
116+
* @param parent The parent data broker of the one this opt-out attempt targets
117+
* @param attemptId - Client-generated ID of the opt-out attempt
118+
* @param durationMs - Total duration of the opt-out attempt in milliseconds
119+
* @param tries - The number of tries it took to submit successfully.
120+
* @param emailPattern - Email pattern used during submission, when available else null.
118121
*/
119-
fun reportOptOutCompleted(
120-
brokerName: String,
121-
totalTimeInMillis: Long,
122-
isSuccess: Boolean,
122+
fun reportOptOutSubmitted(
123+
brokerUrl: String,
124+
parent: String,
125+
attemptId: String,
126+
durationMs: Long,
127+
tries: Int,
128+
emailPattern: String?,
129+
)
130+
131+
/**
132+
* Emits a pixel to signal that an opt-out job for a specific extractedProfile has been failed.
133+
*
134+
* @param brokerUrl url of the Broker for which the opt-out is for
135+
* @param parent The parent data broker of the one this opt-out attempt targets
136+
* @param brokerJsonVersion The version of the broker JSON file
137+
* @param attemptId - Client-generated ID of the opt-out attempt
138+
* @param durationMs - Total duration of the opt-out attempt in milliseconds
139+
* @param stage - The stage where the failure occurred
140+
* @param tries - The number of tries it took to submit successfully.
141+
* @param emailPattern - Email pattern used during submission, when available else null.
142+
* @param actionId - Predefined identifier of the broker action that failed
143+
* @param actionType - Type of action that failed
144+
*/
145+
fun reportOptOutFailed(
146+
brokerUrl: String,
147+
parent: String,
148+
brokerJsonVersion: String,
149+
attemptId: String,
150+
durationMs: Long,
151+
stage: PirStage,
152+
tries: Int,
153+
emailPattern: String?,
154+
actionId: String,
155+
actionType: String,
123156
)
124157

125158
/**
@@ -353,17 +386,51 @@ class RealPirPixelSender @Inject constructor(
353386
fire(PIR_INTERNAL_BROKER_OPT_OUT_STARTED, params)
354387
}
355388

356-
override fun reportOptOutCompleted(
357-
brokerName: String,
358-
totalTimeInMillis: Long,
359-
isSuccess: Boolean,
389+
override fun reportOptOutSubmitted(
390+
brokerUrl: String,
391+
parent: String,
392+
attemptId: String,
393+
durationMs: Long,
394+
tries: Int,
395+
emailPattern: String?,
360396
) {
361397
val params = mapOf(
362-
PARAM_KEY_BROKER_NAME to brokerName,
363-
PARAM_KEY_TOTAL_TIME to totalTimeInMillis.toString(),
364-
PARAM_KEY_SUCCESS to isSuccess.toString(),
398+
PARAM_KEY_BROKER to brokerUrl,
399+
PARAM_KEY_PARENT to parent,
400+
PARAM_ATTEMPT_ID to attemptId,
401+
PARAM_DURATION to durationMs.toString(),
402+
PARAM_TRIES to tries.toString(),
403+
PARAM_KEY_PATTERN to (emailPattern ?: ""),
365404
)
366-
fire(PIR_INTERNAL_BROKER_OPT_OUT_COMPLETED, params)
405+
fire(PIR_OPTOUT_SUBMIT_SUCCESS, params)
406+
}
407+
408+
override fun reportOptOutFailed(
409+
brokerUrl: String,
410+
parent: String,
411+
brokerJsonVersion: String,
412+
attemptId: String,
413+
durationMs: Long,
414+
stage: PirStage,
415+
tries: Int,
416+
emailPattern: String?,
417+
actionId: String,
418+
actionType: String,
419+
) {
420+
val params = mapOf(
421+
PARAM_KEY_BROKER to brokerUrl,
422+
PARAM_KEY_PARENT to parent,
423+
PARAM_BROKER_VERSION to brokerJsonVersion,
424+
PARAM_ATTEMPT_ID to attemptId,
425+
PARAM_DURATION to durationMs.toString(),
426+
PARAM_KEY_STAGE to stage.stageName,
427+
PARAM_TRIES to tries.toString(),
428+
PARAM_KEY_PATTERN to (emailPattern ?: ""),
429+
PARAM_ACTION_ID to actionId,
430+
PARAM_KEY_ACTION_TYPE to actionType,
431+
)
432+
433+
fire(PIR_OPTOUT_SUBMIT_FAILURE, params)
367434
}
368435

369436
override fun reportScanStats(totalScanToRun: Int) {
@@ -565,5 +632,11 @@ class RealPirPixelSender @Inject constructor(
565632
private const val PARAM_ATTEMPT_NUMBER = "attempt_number"
566633
private const val PARAM_TOTAL_FETCH = "totalFetchAttempts"
567634
private const val PARAM_TOTAL_EMAIL_CONFIRMATION = "totalEmailConfirmationJobs"
635+
636+
private const val PARAM_KEY_BROKER = "data_broker"
637+
private const val PARAM_KEY_PARENT = "parent"
638+
private const val PARAM_KEY_STAGE = "stage"
639+
private const val PARAM_KEY_PATTERN = "pattern"
640+
private const val PARAM_KEY_ACTION_TYPE = "action_type"
568641
}
569642
}
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
/*
2+
* Copyright (c) 2025 DuckDuckGo
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.duckduckgo.pir.impl.pixels
18+
19+
enum class PirStage(val stageName: String) {
20+
/**
21+
*
22+
* Start of an opt-out job execution, after verifying all dependencies
23+
*/
24+
START("start"),
25+
26+
/**
27+
* Stage before querying dbp-api v0 for a generated email.
28+
*/
29+
EMAIL_GENERATE("email-generate"),
30+
31+
/**
32+
* Stage where we start the getCaptchaInfo action
33+
*/
34+
CAPTCHA_PARSE("captcha-parse"),
35+
36+
/**
37+
* Stage after captcha info is parsed and before it's submitted to the captcha service
38+
*/
39+
CAPTCHA_SEND("captcha-send"),
40+
41+
/**
42+
* Stage during the solveCaptcha action and just before submitting the captcha to be solved
43+
*/
44+
CAPTCHA_SOLVE("captcha-solve"),
45+
46+
/**
47+
* Stage can be set in two places:
48+
* (1) at the start of the expectation action
49+
* (2) right before executing the emailConfirmation action (prior to email decoupling flow changes)
50+
*/
51+
SUBMIT("submit"),
52+
53+
/**
54+
* Stage after halting opt-out jobs at email confirmation step.
55+
*/
56+
EMAIL_CONFIRM_HALTED("email-confirm-halted"),
57+
58+
/**
59+
* Stage when email confirmation job resumes, after verifying all dependencies.
60+
*/
61+
EMAIL_CONFIRM_DECOUPLED("email-confirm-decoupled"),
62+
63+
/**
64+
* Stage when finalizing an opt-out job, after it has been submitted and right before submitting a dbp_optout_process_submit-success pixel.
65+
*/
66+
VALIDATE("validate"),
67+
68+
/**
69+
* Catch-all stage
70+
*/
71+
OTHER("other"),
72+
73+
/**
74+
* Stage at the start of the click and fillForm actions.
75+
*/
76+
FILL_FORM("fill-form"),
77+
78+
/**
79+
* Stage when the opt-out's condition action meets its expectation.
80+
*/
81+
CONDITION_FOUND("condition-found"),
82+
83+
/**
84+
*
85+
* Stage when either:
86+
* (1) the opt-out's condition action completes with no follow-up actions or
87+
* (2) when it doesn't meet its expectation, continuing with regular action execution.
88+
*/
89+
CONDITION_NOT_FOUND("condition-not-found"),
90+
}

0 commit comments

Comments
 (0)