1 /* <lambda>null2 * Copyright (C) 2020 The Android Open Source Project 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.android.statementservice.domain.worker 18 19 import android.content.Context 20 import androidx.work.NetworkType 21 import androidx.work.WorkerParameters 22 import com.android.statementservice.domain.VerifyStatus 23 import com.android.statementservice.utils.AndroidUtils 24 import kotlinx.coroutines.async 25 import kotlinx.coroutines.awaitAll 26 import kotlinx.coroutines.coroutineScope 27 import kotlinx.coroutines.isActive 28 import java.util.UUID 29 30 /** 31 * Scheduled every 24 hours with [NetworkType.CONNECTED] and every 72 hours without any constraints 32 * to retry all domains for all packages with a failing error code. 33 */ 34 class RetryRequestWorker( 35 appContext: Context, 36 params: WorkerParameters 37 ) : BaseRequestWorker(appContext, params) { 38 39 data class VerifyResult(val domainSetId: UUID, val host: String, val status: VerifyStatus) 40 41 override suspend fun doWork() = coroutineScope { 42 if (!AndroidUtils.isReceiverV2Enabled(appContext)) { 43 return@coroutineScope Result.success() 44 } 45 46 val packageNames = verificationManager.queryValidVerificationPackageNames() 47 48 verifier.collectHosts(packageNames) 49 .map { (domainSetId, packageName, host) -> 50 async { 51 if (isActive && !isStopped) { 52 val (_, status) = verifier.verifyHost(host, packageName, params.network) 53 VerifyResult(domainSetId, host, status) 54 } else { 55 // If the job gets cancelled, stop the remaining hosts, but continue the 56 // job to commit the results for hosts that were already requested. 57 null 58 } 59 } 60 } 61 .awaitAll() 62 .filterNotNull() // TODO(b/159952358): Fast fail packages which can't be retrieved. 63 .groupBy { it.domainSetId } 64 .forEach { (domainSetId, resultsById) -> 65 resultsById.groupBy { it.status } 66 .mapValues { it.value.map(VerifyResult::host).toSet() } 67 .forEach { (status, hosts) -> 68 verificationManager.setDomainVerificationStatus( 69 domainSetId, 70 hosts, 71 status.value 72 ) 73 } 74 } 75 76 // Succeed regardless of results since this retry is best effort and not required 77 Result.success() 78 } 79 } 80