Skip to content

Commit 21fc4c1

Browse files
PIR: Add missing models and repository cleanup (#6608)
Task/Issue URL: https://app.asana.com/1/137249556945/project/72649045549333/task/1211054416774966?focus=true ### Description See attached task description ### Steps to test this PR - [ ] Smoke test PIR and confirm that scans and opt out don't crash --------- Co-authored-by: Domen Lanišnik <[email protected]>
1 parent ada7866 commit 21fc4c1

File tree

23 files changed

+580
-366
lines changed

23 files changed

+580
-366
lines changed

pir/pir-impl/src/main/java/com/duckduckgo/pir/impl/common/PirRunStateHandler.kt

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ import com.duckduckgo.pir.impl.scripts.models.PirSuccessResponse.FillFormRespons
4141
import com.duckduckgo.pir.impl.scripts.models.PirSuccessResponse.GetCaptchaInfoResponse
4242
import com.duckduckgo.pir.impl.scripts.models.PirSuccessResponse.NavigateResponse
4343
import com.duckduckgo.pir.impl.scripts.models.PirSuccessResponse.SolveCaptchaResponse
44+
import com.duckduckgo.pir.impl.store.PirEventsRepository
4445
import com.duckduckgo.pir.impl.store.PirRepository
4546
import com.duckduckgo.pir.impl.store.db.BrokerScanEventType.BROKER_ERROR
4647
import com.duckduckgo.pir.impl.store.db.BrokerScanEventType.BROKER_STARTED
@@ -133,6 +134,7 @@ interface PirRunStateHandler {
133134
@ContributesBinding(AppScope::class)
134135
class RealPirRunStateHandler @Inject constructor(
135136
private val repository: PirRepository,
137+
private val eventsRepository: PirEventsRepository,
136138
private val pixelSender: PirPixelSender,
137139
private val dispatcherProvider: DispatcherProvider,
138140
private val jobRecordUpdater: JobRecordUpdater,
@@ -172,7 +174,7 @@ class RealPirRunStateHandler @Inject constructor(
172174

173175
private suspend fun handleBrokerManualScanStarted(state: BrokerManualScanStarted) {
174176
pixelSender.reportBrokerScanStarted(state.brokerName)
175-
repository.saveBrokerScanLog(
177+
eventsRepository.saveBrokerScanLog(
176178
PirBrokerScanLog(
177179
eventTimeInMillis = state.eventTimeInMillis,
178180
brokerName = state.brokerName,
@@ -188,14 +190,14 @@ class RealPirRunStateHandler @Inject constructor(
188190
totalTimeInMillis = state.totalTimeMillis,
189191
isSuccess = state.isSuccess,
190192
)
191-
repository.saveBrokerScanLog(
193+
eventsRepository.saveBrokerScanLog(
192194
PirBrokerScanLog(
193195
eventTimeInMillis = state.eventTimeInMillis,
194196
brokerName = state.brokerName,
195197
eventType = if (state.isSuccess) BROKER_SUCCESS else BROKER_ERROR,
196198
),
197199
)
198-
repository.saveScanCompletedBroker(
200+
eventsRepository.saveScanCompletedBroker(
199201
brokerName = state.brokerName,
200202
profileQueryId = state.profileQueryId,
201203
startTimeInMillis = state.startTimeInMillis,
@@ -206,7 +208,7 @@ class RealPirRunStateHandler @Inject constructor(
206208

207209
private suspend fun handleBrokerScheduledScanStarted(state: BrokerScheduledScanStarted) {
208210
pixelSender.reportBrokerScanStarted(state.brokerName)
209-
repository.saveBrokerScanLog(
211+
eventsRepository.saveBrokerScanLog(
210212
PirBrokerScanLog(
211213
eventTimeInMillis = state.eventTimeInMillis,
212214
brokerName = state.brokerName,
@@ -222,14 +224,14 @@ class RealPirRunStateHandler @Inject constructor(
222224
totalTimeInMillis = state.totalTimeMillis,
223225
isSuccess = state.isSuccess,
224226
)
225-
repository.saveBrokerScanLog(
227+
eventsRepository.saveBrokerScanLog(
226228
PirBrokerScanLog(
227229
eventTimeInMillis = state.eventTimeInMillis,
228230
brokerName = state.brokerName,
229231
eventType = if (state.isSuccess) BROKER_SUCCESS else BROKER_ERROR,
230232
),
231233
)
232-
repository.saveScanCompletedBroker(
234+
eventsRepository.saveScanCompletedBroker(
233235
brokerName = state.brokerName,
234236
profileQueryId = state.profileQueryId,
235237
startTimeInMillis = state.startTimeInMillis,
@@ -295,7 +297,7 @@ class RealPirRunStateHandler @Inject constructor(
295297
totalTimeInMillis = state.endTimeInMillis - state.startTimeInMillis,
296298
isSuccess = state.isSubmitSuccess,
297299
)
298-
repository.saveOptOutCompleted(
300+
eventsRepository.saveOptOutCompleted(
299301
brokerName = state.brokerName,
300302
extractedProfile = state.extractedProfile,
301303
startTimeInMillis = state.startTimeInMillis,
@@ -305,7 +307,7 @@ class RealPirRunStateHandler @Inject constructor(
305307
}
306308

307309
private suspend fun handleBrokerOptOutActionSucceeded(state: BrokerOptOutActionSucceeded) {
308-
repository.saveOptOutActionLog(
310+
eventsRepository.saveOptOutActionLog(
309311
brokerName = state.brokerName,
310312
extractedProfile = state.extractedProfile,
311313
completionTimeInMillis = state.completionTimeInMillis,
@@ -316,7 +318,7 @@ class RealPirRunStateHandler @Inject constructor(
316318
}
317319

318320
private suspend fun handleBrokerOptOutActionFailed(state: BrokerOptOutActionFailed) {
319-
repository.saveOptOutActionLog(
321+
eventsRepository.saveOptOutActionLog(
320322
brokerName = state.brokerName,
321323
extractedProfile = state.extractedProfile,
322324
completionTimeInMillis = state.completionTimeInMillis,

pir/pir-impl/src/main/java/com/duckduckgo/pir/impl/dashboard/messaging/handlers/PirWebInitialScanStatusMessageHandler.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import com.duckduckgo.js.messaging.api.JsMessageCallback
2424
import com.duckduckgo.js.messaging.api.JsMessaging
2525
import com.duckduckgo.pir.impl.dashboard.messaging.PirDashboardWebMessages
2626
import com.duckduckgo.pir.impl.dashboard.messaging.model.PirWebMessageResponse
27-
import com.duckduckgo.pir.impl.store.PirRepository
27+
import com.duckduckgo.pir.impl.store.PirEventsRepository
2828
import com.duckduckgo.pir.impl.store.db.EventType.MANUAL_SCAN_COMPLETED
2929
import com.duckduckgo.pir.impl.store.db.EventType.MANUAL_SCAN_STARTED
3030
import com.squareup.anvil.annotations.ContributesMultibinding
@@ -42,7 +42,7 @@ import logcat.logcat
4242
boundType = PirWebJsMessageHandler::class,
4343
)
4444
class PirWebInitialScanStatusMessageHandler @Inject constructor(
45-
private val repository: PirRepository,
45+
private val eventsRepository: PirEventsRepository,
4646
private val dispatcherProvider: DispatcherProvider,
4747
@AppCoroutineScope private val appCoroutineScope: CoroutineScope,
4848
) : PirWebJsMessageHandler() {
@@ -57,7 +57,7 @@ class PirWebInitialScanStatusMessageHandler @Inject constructor(
5757
logcat { "PIR-WEB: InitialScanStatusMessageHandler: process $jsMessage" }
5858

5959
appCoroutineScope.launch(dispatcherProvider.io()) {
60-
val eventLogs = repository.getAllEventLogsFlow().firstOrNull().orEmpty()
60+
val eventLogs = eventsRepository.getAllEventLogsFlow().firstOrNull().orEmpty()
6161

6262
// TODO get actual scan progress results from the repository
6363
jsMessaging.sendResponse(

pir/pir-impl/src/main/java/com/duckduckgo/pir/impl/di/PirModule.kt

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,13 @@ import com.duckduckgo.pir.impl.store.RealPirDataStore
4040
import com.duckduckgo.pir.impl.store.RealPirRepository
4141
import com.duckduckgo.pir.impl.store.db.BrokerDao
4242
import com.duckduckgo.pir.impl.store.db.BrokerJsonDao
43+
import com.duckduckgo.pir.impl.store.db.ExtractedProfileDao
4344
import com.duckduckgo.pir.impl.store.db.JobSchedulingDao
4445
import com.duckduckgo.pir.impl.store.db.OptOutResultsDao
4546
import com.duckduckgo.pir.impl.store.db.ScanLogDao
4647
import com.duckduckgo.pir.impl.store.db.ScanResultsDao
4748
import com.duckduckgo.pir.impl.store.db.UserProfileDao
4849
import com.squareup.anvil.annotations.ContributesTo
49-
import com.squareup.moshi.Moshi
5050
import dagger.Module
5151
import dagger.Provides
5252
import dagger.SingleInstanceIn
@@ -107,32 +107,32 @@ class PirModule {
107107
return database.jobSchedulingDao()
108108
}
109109

110+
@SingleInstanceIn(AppScope::class)
111+
@Provides
112+
fun provideExtractedProfileDao(database: PirDatabase): ExtractedProfileDao {
113+
return database.extractedProfileDao()
114+
}
115+
110116
@Provides
111117
@SingleInstanceIn(AppScope::class)
112118
fun providePirRepository(
113119
sharedPreferencesProvider: SharedPreferencesProvider,
114120
dispatcherProvider: DispatcherProvider,
115121
brokerJsonDao: BrokerJsonDao,
116122
brokerDao: BrokerDao,
117-
scanResultsDao: ScanResultsDao,
118123
currentTimeProvider: CurrentTimeProvider,
119-
moshi: Moshi,
120124
userProfileDao: UserProfileDao,
121-
scanLogDao: ScanLogDao,
122125
dbpService: DbpService,
123-
outResultsDao: OptOutResultsDao,
126+
extractedProfileDao: ExtractedProfileDao,
124127
): PirRepository = RealPirRepository(
125-
moshi,
126128
dispatcherProvider,
127129
RealPirDataStore(sharedPreferencesProvider),
128130
currentTimeProvider,
129131
brokerJsonDao,
130132
brokerDao,
131-
scanResultsDao,
132133
userProfileDao,
133-
scanLogDao,
134134
dbpService,
135-
outResultsDao,
135+
extractedProfileDao,
136136
)
137137

138138
@Provides
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
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.models
18+
19+
data class Broker(
20+
val name: String,
21+
val fileName: String,
22+
val url: String,
23+
val version: String,
24+
val parent: String?,
25+
val addedDatetime: Long,
26+
val removedAt: Long,
27+
)
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
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.models
18+
19+
data class MirrorSite(
20+
val name: String,
21+
val url: String,
22+
val addedAt: Long,
23+
val removedAt: Long,
24+
val optOutUrl: String,
25+
val parentSite: String,
26+
)
27+
28+
fun MirrorSite.isExtant(timeInMillis: Long): Boolean {
29+
return if (removedAt != 0L) {
30+
timeInMillis in (addedAt + 1)..<removedAt
31+
} else {
32+
addedAt < timeInMillis
33+
}
34+
}

pir/pir-impl/src/main/java/com/duckduckgo/pir/impl/optout/PirOptOut.kt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ import com.duckduckgo.pir.impl.common.splitIntoParts
3636
import com.duckduckgo.pir.impl.models.ProfileQuery
3737
import com.duckduckgo.pir.impl.models.scheduling.JobRecord.OptOutJobRecord
3838
import com.duckduckgo.pir.impl.scripts.PirCssScriptLoader
39+
import com.duckduckgo.pir.impl.store.PirEventsRepository
3940
import com.duckduckgo.pir.impl.store.PirRepository
4041
import com.duckduckgo.pir.impl.store.db.EventType
4142
import com.duckduckgo.pir.impl.store.db.PirEventLog
@@ -103,6 +104,7 @@ interface PirOptOut {
103104
@SingleInstanceIn(AppScope::class)
104105
class RealPirOptOut @Inject constructor(
105106
private val repository: PirRepository,
107+
private val eventsRepository: PirEventsRepository,
106108
private val brokerStepsParser: BrokerStepsParser,
107109
private val pirCssScriptLoader: PirCssScriptLoader,
108110
private val pirActionsRunnerFactory: RealPirActionsRunner.Factory,
@@ -380,7 +382,7 @@ class RealPirOptOut @Inject constructor(
380382
}
381383

382384
private suspend fun emitStartPixel() {
383-
repository.saveScanLog(
385+
eventsRepository.saveScanLog(
384386
PirEventLog(
385387
eventTimeInMillis = currentTimeProvider.currentTimeMillis(),
386388
eventType = EventType.MANUAL_OPTOUT_STARTED,
@@ -389,7 +391,7 @@ class RealPirOptOut @Inject constructor(
389391
}
390392

391393
private suspend fun emitCompletedPixel() {
392-
repository.saveScanLog(
394+
eventsRepository.saveScanLog(
393395
PirEventLog(
394396
eventTimeInMillis = currentTimeProvider.currentTimeMillis(),
395397
eventType = EventType.MANUAL_OPTOUT_COMPLETED,

pir/pir-impl/src/main/java/com/duckduckgo/pir/impl/scan/PirScan.kt

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import com.duckduckgo.pir.impl.common.splitIntoParts
3434
import com.duckduckgo.pir.impl.models.ProfileQuery
3535
import com.duckduckgo.pir.impl.models.scheduling.JobRecord.ScanJobRecord
3636
import com.duckduckgo.pir.impl.scripts.PirCssScriptLoader
37+
import com.duckduckgo.pir.impl.store.PirEventsRepository
3738
import com.duckduckgo.pir.impl.store.PirRepository
3839
import com.duckduckgo.pir.impl.store.db.EventType
3940
import com.duckduckgo.pir.impl.store.db.PirEventLog
@@ -94,6 +95,7 @@ interface PirScan {
9495
@SingleInstanceIn(AppScope::class)
9596
class RealPirScan @Inject constructor(
9697
private val repository: PirRepository,
98+
private val eventsRepository: PirEventsRepository,
9799
private val brokerStepsParser: BrokerStepsParser,
98100
private val pirCssScriptLoader: PirCssScriptLoader,
99101
private val pirActionsRunnerFactory: RealPirActionsRunner.Factory,
@@ -285,7 +287,7 @@ class RealPirScan @Inject constructor(
285287
}
286288
runners.clear()
287289
}
288-
repository.deleteAllScanResults()
290+
eventsRepository.deleteAllScanResults()
289291
}
290292

291293
private suspend fun obtainProfiles(): List<ProfileQuery> {
@@ -313,14 +315,14 @@ class RealPirScan @Inject constructor(
313315

314316
private suspend fun emitScanStartPixel(runType: RunType) {
315317
if (runType == RunType.MANUAL) {
316-
repository.saveScanLog(
318+
eventsRepository.saveScanLog(
317319
PirEventLog(
318320
eventTimeInMillis = currentTimeProvider.currentTimeMillis(),
319321
eventType = EventType.MANUAL_SCAN_STARTED,
320322
),
321323
)
322324
} else {
323-
repository.saveScanLog(
325+
eventsRepository.saveScanLog(
324326
PirEventLog(
325327
eventTimeInMillis = currentTimeProvider.currentTimeMillis(),
326328
eventType = EventType.SCHEDULED_SCAN_STARTED,
@@ -333,14 +335,14 @@ class RealPirScan @Inject constructor(
333335
runType: RunType,
334336
) {
335337
if (runType == RunType.MANUAL) {
336-
repository.saveScanLog(
338+
eventsRepository.saveScanLog(
337339
PirEventLog(
338340
eventTimeInMillis = currentTimeProvider.currentTimeMillis(),
339341
eventType = EventType.MANUAL_SCAN_COMPLETED,
340342
),
341343
)
342344
} else {
343-
repository.saveScanLog(
345+
eventsRepository.saveScanLog(
344346
PirEventLog(
345347
eventTimeInMillis = currentTimeProvider.currentTimeMillis(),
346348
eventType = EventType.SCHEDULED_SCAN_COMPLETED,

pir/pir-impl/src/main/java/com/duckduckgo/pir/impl/scan/PirScanScheduler.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ import com.duckduckgo.di.scopes.AppScope
3333
import com.duckduckgo.pir.impl.common.PirJobConstants.SCHEDULED_SCAN_INTERVAL_HOURS
3434
import com.duckduckgo.pir.impl.pixels.PirPixelSender
3535
import com.duckduckgo.pir.impl.scan.PirScheduledScanRemoteWorker.Companion.TAG_SCHEDULED_SCAN
36-
import com.duckduckgo.pir.impl.store.PirRepository
36+
import com.duckduckgo.pir.impl.store.PirEventsRepository
3737
import com.duckduckgo.pir.impl.store.db.EventType
3838
import com.duckduckgo.pir.impl.store.db.PirEventLog
3939
import com.squareup.anvil.annotations.ContributesBinding
@@ -55,7 +55,7 @@ class RealPirScanScheduler @Inject constructor(
5555
@AppCoroutineScope private val coroutineScope: CoroutineScope,
5656
private val currentTimeProvider: CurrentTimeProvider,
5757
private val pirPixelSender: PirPixelSender,
58-
private val repository: PirRepository,
58+
private val eventsRepository: PirEventsRepository,
5959
) : PirScanScheduler {
6060
override fun scheduleScans() {
6161
logcat { "PIR-SCHEDULED: Scheduling periodic scan appId: ${appBuildConfig.applicationId}" }
@@ -77,7 +77,7 @@ class RealPirScanScheduler @Inject constructor(
7777

7878
pirPixelSender.reportScheduledScanScheduled()
7979
coroutineScope.launch {
80-
repository.saveScanLog(
80+
eventsRepository.saveScanLog(
8181
PirEventLog(
8282
eventTimeInMillis = currentTimeProvider.currentTimeMillis(),
8383
eventType = EventType.SCHEDULED_SCAN_SCHEDULED,

pir/pir-impl/src/main/java/com/duckduckgo/pir/impl/store/PirDatabase.kt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,14 @@ import androidx.room.RoomDatabase
2121
import androidx.room.TypeConverter
2222
import androidx.room.TypeConverters
2323
import androidx.room.migration.Migration
24-
import com.duckduckgo.pir.impl.store.db.Broker
2524
import com.duckduckgo.pir.impl.store.db.BrokerDao
25+
import com.duckduckgo.pir.impl.store.db.BrokerEntity
2626
import com.duckduckgo.pir.impl.store.db.BrokerJsonDao
2727
import com.duckduckgo.pir.impl.store.db.BrokerJsonEtag
2828
import com.duckduckgo.pir.impl.store.db.BrokerOptOut
2929
import com.duckduckgo.pir.impl.store.db.BrokerScan
3030
import com.duckduckgo.pir.impl.store.db.BrokerSchedulingConfigEntity
31+
import com.duckduckgo.pir.impl.store.db.ExtractedProfileDao
3132
import com.duckduckgo.pir.impl.store.db.JobSchedulingDao
3233
import com.duckduckgo.pir.impl.store.db.MirrorSiteEntity
3334
import com.duckduckgo.pir.impl.store.db.OptOutActionLog
@@ -52,7 +53,7 @@ import com.squareup.moshi.Types
5253
version = 8,
5354
entities = [
5455
BrokerJsonEtag::class,
55-
Broker::class,
56+
BrokerEntity::class,
5657
BrokerOptOut::class,
5758
BrokerScan::class,
5859
BrokerSchedulingConfigEntity::class,
@@ -77,6 +78,7 @@ abstract class PirDatabase : RoomDatabase() {
7778
abstract fun scanLogDao(): ScanLogDao
7879
abstract fun optOutResultsDao(): OptOutResultsDao
7980
abstract fun jobSchedulingDao(): JobSchedulingDao
81+
abstract fun extractedProfileDao(): ExtractedProfileDao
8082

8183
companion object {
8284
val ALL_MIGRATIONS: List<Migration> = emptyList()

0 commit comments

Comments
 (0)