1 /*
2  * Copyright (C) 2022 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.adservices.service.common;
18 
19 import static com.android.adservices.spe.AdServicesJobInfo.COBALT_LOGGING_JOB;
20 import static com.android.adservices.spe.AdServicesJobInfo.CONSENT_NOTIFICATION_JOB;
21 import static com.android.adservices.spe.AdServicesJobInfo.ENCRYPTION_KEY_PERIODIC_JOB;
22 import static com.android.adservices.spe.AdServicesJobInfo.FLEDGE_AD_SELECTION_DEBUG_REPORT_SENDER_JOB;
23 import static com.android.adservices.spe.AdServicesJobInfo.FLEDGE_BACKGROUND_FETCH_JOB;
24 import static com.android.adservices.spe.AdServicesJobInfo.FLEDGE_KANON_SIGN_JOIN_BACKGROUND_JOB;
25 import static com.android.adservices.spe.AdServicesJobInfo.MAINTENANCE_JOB;
26 import static com.android.adservices.spe.AdServicesJobInfo.MEASUREMENT_AGGREGATE_FALLBACK_REPORTING_JOB;
27 import static com.android.adservices.spe.AdServicesJobInfo.MEASUREMENT_AGGREGATE_MAIN_REPORTING_JOB;
28 import static com.android.adservices.spe.AdServicesJobInfo.MEASUREMENT_ASYNC_REGISTRATION_FALLBACK_JOB;
29 import static com.android.adservices.spe.AdServicesJobInfo.MEASUREMENT_ASYNC_REGISTRATION_JOB;
30 import static com.android.adservices.spe.AdServicesJobInfo.MEASUREMENT_ATTRIBUTION_FALLBACK_JOB;
31 import static com.android.adservices.spe.AdServicesJobInfo.MEASUREMENT_ATTRIBUTION_JOB;
32 import static com.android.adservices.spe.AdServicesJobInfo.MEASUREMENT_DEBUG_REPORTING_FALLBACK_JOB;
33 import static com.android.adservices.spe.AdServicesJobInfo.MEASUREMENT_DELETE_EXPIRED_JOB;
34 import static com.android.adservices.spe.AdServicesJobInfo.MEASUREMENT_DELETE_UNINSTALLED_JOB;
35 import static com.android.adservices.spe.AdServicesJobInfo.MEASUREMENT_EVENT_FALLBACK_REPORTING_JOB;
36 import static com.android.adservices.spe.AdServicesJobInfo.MEASUREMENT_EVENT_MAIN_REPORTING_JOB;
37 import static com.android.adservices.spe.AdServicesJobInfo.MEASUREMENT_IMMEDIATE_AGGREGATE_REPORTING_JOB;
38 import static com.android.adservices.spe.AdServicesJobInfo.MEASUREMENT_REPORTING_JOB;
39 import static com.android.adservices.spe.AdServicesJobInfo.MEASUREMENT_VERBOSE_DEBUG_REPORTING_FALLBACK_JOB;
40 import static com.android.adservices.spe.AdServicesJobInfo.PERIODIC_SIGNALS_ENCODING_JOB;
41 import static com.android.adservices.spe.AdServicesJobInfo.TOPICS_EPOCH_JOB;
42 
43 import android.annotation.NonNull;
44 import android.app.job.JobScheduler;
45 import android.content.Context;
46 import android.os.Build;
47 
48 import androidx.annotation.RequiresApi;
49 
50 import com.android.adservices.cobalt.CobaltJobService;
51 import com.android.adservices.download.MddJob;
52 import com.android.adservices.download.MddJobService;
53 import com.android.adservices.service.Flags;
54 import com.android.adservices.service.FlagsFactory;
55 import com.android.adservices.service.MaintenanceJobService;
56 import com.android.adservices.service.adselection.DebugReportSenderJobService;
57 import com.android.adservices.service.consent.AdServicesApiType;
58 import com.android.adservices.service.encryptionkey.EncryptionKeyJobService;
59 import com.android.adservices.service.measurement.DeleteExpiredJobService;
60 import com.android.adservices.service.measurement.DeleteUninstalledJobService;
61 import com.android.adservices.service.measurement.attribution.AttributionFallbackJobService;
62 import com.android.adservices.service.measurement.attribution.AttributionJobService;
63 import com.android.adservices.service.measurement.registration.AsyncRegistrationFallbackJob;
64 import com.android.adservices.service.measurement.registration.AsyncRegistrationQueueJobService;
65 import com.android.adservices.service.measurement.reporting.AggregateFallbackReportingJobService;
66 import com.android.adservices.service.measurement.reporting.AggregateReportingJobService;
67 import com.android.adservices.service.measurement.reporting.DebugReportingFallbackJobService;
68 import com.android.adservices.service.measurement.reporting.EventFallbackReportingJobService;
69 import com.android.adservices.service.measurement.reporting.EventReportingJobService;
70 import com.android.adservices.service.measurement.reporting.ImmediateAggregateReportingJobService;
71 import com.android.adservices.service.measurement.reporting.ReportingJobService;
72 import com.android.adservices.service.measurement.reporting.VerboseDebugReportingFallbackJobService;
73 import com.android.adservices.service.topics.EpochJob;
74 import com.android.adservices.service.topics.EpochJobService;
75 
76 import java.util.Objects;
77 
78 /** Provides functionality to schedule or unschedule all relevant background jobs. */
79 // TODO(b/269798827): Enable for R.
80 @RequiresApi(Build.VERSION_CODES.S)
81 public class BackgroundJobsManager {
82     /**
83      * Tries to schedule all the relevant background jobs.
84      *
85      * @param context application context.
86      */
scheduleAllBackgroundJobs(@onNull Context context)87     public static void scheduleAllBackgroundJobs(@NonNull Context context) {
88         scheduleFledgeBackgroundJobs(context);
89 
90         scheduleTopicsBackgroundJobs(context);
91 
92         // TODO(b/296146348): Remove MDD Background Jobs from scheduleAllBackgroundJobs
93         scheduleMddBackgroundJobs();
94 
95         scheduleMeasurementBackgroundJobs(context);
96     }
97 
98     /**
99      * Tries to schedule all the relevant background jobs per api.
100      *
101      * @param context application context.
102      */
scheduleJobsPerApi(@onNull Context context, AdServicesApiType apiType)103     public static void scheduleJobsPerApi(@NonNull Context context, AdServicesApiType apiType) {
104         switch (apiType) {
105             case FLEDGE:
106                 scheduleFledgeBackgroundJobs(context);
107                 break;
108             case TOPICS:
109                 scheduleTopicsBackgroundJobs(context);
110                 break;
111             case MEASUREMENTS:
112                 scheduleMeasurementBackgroundJobs(context);
113                 break;
114         }
115     }
116 
117     /** Tries to unschedule all the relevant background jobs per api. */
unscheduleJobsPerApi( @onNull JobScheduler jobScheduler, AdServicesApiType apiType)118     public static void unscheduleJobsPerApi(
119             @NonNull JobScheduler jobScheduler, AdServicesApiType apiType) {
120         switch (apiType) {
121             case FLEDGE:
122                 unscheduleFledgeBackgroundJobs(jobScheduler);
123                 break;
124             case TOPICS:
125                 unscheduleTopicsBackgroundJobs(jobScheduler);
126                 break;
127             case MEASUREMENTS:
128                 unscheduleMeasurementBackgroundJobs(jobScheduler);
129                 break;
130         }
131     }
132 
133     /**
134      * Tries to schedule all the Fledge related background jobs if the FledgeSelectAdsKillSwitch is
135      * disabled.
136      *
137      * <p>Those services are:
138      *
139      * <ul>
140      *   <li>{@link MaintenanceJobService}
141      * </ul>
142      *
143      * @param context application context.
144      */
scheduleFledgeBackgroundJobs(@onNull Context context)145     public static void scheduleFledgeBackgroundJobs(@NonNull Context context) {
146         Flags flags = FlagsFactory.getFlags();
147         if (!flags.getFledgeSelectAdsKillSwitch()) {
148             MaintenanceJobService.scheduleIfNeeded(context, /* forceSchedule= */ false);
149             if (flags.getFledgeEventLevelDebugReportingEnabled()) {
150                 DebugReportSenderJobService.scheduleIfNeeded(context, false);
151             }
152         }
153     }
154 
155     /**
156      * Tries to schedule all the Topics related background jobs if the TopicsKillSwitch is disabled.
157      *
158      * <p>Those services are:
159      *
160      * <ul>
161      *   <li>{@link EpochJobService}
162      *   <li>{@link MaintenanceJobService}
163      *   <li>{@link MddJobService}
164      *   <li>{@link EncryptionKeyJobService}
165      *   <li>{@link CobaltJobService}
166      * </ul>
167      *
168      * @param context application context.
169      */
scheduleTopicsBackgroundJobs(@onNull Context context)170     public static void scheduleTopicsBackgroundJobs(@NonNull Context context) {
171         if (!FlagsFactory.getFlags().getTopicsKillSwitch()) {
172             EpochJob.schedule();
173             MaintenanceJobService.scheduleIfNeeded(context, /* forceSchedule= */ false);
174             scheduleMddBackgroundJobs();
175             scheduleEncryptionKeyBackgroundJobs(context);
176             scheduleCobaltBackgroundJob(context);
177         }
178     }
179 
180     /**
181      * Tries to schedule all the Mdd related background jobs if the MddBackgroundTaskKillSwitch is
182      * disabled.
183      */
scheduleMddBackgroundJobs()184     public static void scheduleMddBackgroundJobs() {
185         if (!FlagsFactory.getFlags().getMddBackgroundTaskKillSwitch()) {
186             MddJob.scheduleAllMddJobs();
187         }
188     }
189 
190     /**
191      * Tries to schedule EncryptionKey related background jobs if the
192      * EncryptionKeyPeriodicFetchKillSwitch is disabled.
193      *
194      * @param context application context.
195      */
scheduleEncryptionKeyBackgroundJobs(@onNull Context context)196     public static void scheduleEncryptionKeyBackgroundJobs(@NonNull Context context) {
197         if (!FlagsFactory.getFlags().getEncryptionKeyPeriodicFetchKillSwitch()) {
198             EncryptionKeyJobService.scheduleIfNeeded(context, /* forceSchedule */ false);
199         }
200     }
201 
202     /**
203      * Tries to schedule all the Measurement related background jobs if the MeasurementKillSwitch is
204      * disabled.
205      *
206      * <p>Those services are:
207      *
208      * <ul>
209      *   <li>{@link AggregateReportingJobService}
210      *   <li>{@link AggregateFallbackReportingJobService}
211      *   <li>{@link ImmediateAggregateReportingJobService}
212      *   <li>{@link ReportingJobService}
213      *   <li>{@link AttributionJobService}
214      *   <li>{@link EventReportingJobService}
215      *   <li>{@link EventFallbackReportingJobService}
216      *   <li>{@link DeleteExpiredJobService}
217      *   <li>{@link DeleteUninstalledJobService}
218      *   <li>{@link AsyncRegistrationQueueJobService}
219      *   <li>{@link AsyncRegistrationFallbackJob}
220      *   <li>{@link MddJobService}
221      *   <li>{@link EncryptionKeyJobService}
222      *   <li>{@link CobaltJobService}
223      * </ul>
224      *
225      * @param context application context.
226      */
scheduleMeasurementBackgroundJobs(@onNull Context context)227     public static void scheduleMeasurementBackgroundJobs(@NonNull Context context) {
228         if (FlagsFactory.getFlags().getMeasurementEnabled()) {
229             AggregateReportingJobService.scheduleIfNeeded(context, /* forceSchedule= */ false);
230             AggregateFallbackReportingJobService.scheduleIfNeeded(
231                     context, /* forceSchedule= */ false);
232             ImmediateAggregateReportingJobService.scheduleIfNeeded(
233                     context, /* forceSchedule= */ false);
234             ReportingJobService.scheduleIfNeeded(context, /* forceSchedule= */ false);
235             AttributionJobService.scheduleIfNeeded(context, /* forceSchedule= */ false);
236             AttributionFallbackJobService.scheduleIfNeeded(context, /* forceSchedule= */ false);
237             EventReportingJobService.scheduleIfNeeded(context, /* forceSchedule= */ false);
238             EventFallbackReportingJobService.scheduleIfNeeded(context, /* forceSchedule= */ false);
239             DeleteExpiredJobService.scheduleIfNeeded(context, /* forceSchedule= */ false);
240             DeleteUninstalledJobService.scheduleIfNeeded(context, /* forceSchedule= */ false);
241             AsyncRegistrationQueueJobService.scheduleIfNeeded(context, /* forceSchedule= */ false);
242             AsyncRegistrationFallbackJob.schedule();
243             VerboseDebugReportingFallbackJobService.scheduleIfNeeded(
244                     context, /* forceSchedule= */ false);
245             DebugReportingFallbackJobService.scheduleIfNeeded(context, /* forceSchedule= */ false);
246             scheduleMddBackgroundJobs();
247             scheduleEncryptionKeyBackgroundJobs(context);
248             scheduleCobaltBackgroundJob(context);
249         }
250     }
251 
252     /**
253      * Tries to schedule Cobalt logging related background jobs if the CobaltLoggingEnabled is true.
254      *
255      * @param context application context
256      */
scheduleCobaltBackgroundJob(Context context)257     public static void scheduleCobaltBackgroundJob(Context context) {
258         if (FlagsFactory.getFlags().getCobaltLoggingEnabled()) {
259             CobaltJobService.scheduleIfNeeded(context, /* forceSchedule= */ false);
260         }
261     }
262 
263     /**
264      * Tries to unschedule all the relevant background jobs.
265      *
266      * @param jobScheduler Job scheduler to cancel the jobs.
267      */
unscheduleAllBackgroundJobs(@onNull JobScheduler jobScheduler)268     public static void unscheduleAllBackgroundJobs(@NonNull JobScheduler jobScheduler) {
269         Objects.requireNonNull(jobScheduler);
270 
271         unscheduleTopicsBackgroundJobs(jobScheduler);
272 
273         unscheduleMeasurementBackgroundJobs(jobScheduler);
274 
275         unscheduleFledgeBackgroundJobs(jobScheduler);
276 
277         unscheduleMaintenanceJobs(jobScheduler);
278 
279         jobScheduler.cancel(CONSENT_NOTIFICATION_JOB.getJobId());
280 
281         MddJob.unscheduleAllJobs(jobScheduler);
282 
283         jobScheduler.cancel(ENCRYPTION_KEY_PERIODIC_JOB.getJobId());
284 
285         unscheduleCobaltJob(jobScheduler);
286     }
287 
288     /**
289      * Tries to unschedule all the Measurement related background jobs.
290      *
291      * @param jobScheduler Job scheduler to cancel the jobs.
292      */
unscheduleMeasurementBackgroundJobs(@onNull JobScheduler jobScheduler)293     public static void unscheduleMeasurementBackgroundJobs(@NonNull JobScheduler jobScheduler) {
294         Objects.requireNonNull(jobScheduler);
295 
296         jobScheduler.cancel(MEASUREMENT_EVENT_MAIN_REPORTING_JOB.getJobId());
297         jobScheduler.cancel(MEASUREMENT_DELETE_EXPIRED_JOB.getJobId());
298         jobScheduler.cancel(MEASUREMENT_DELETE_UNINSTALLED_JOB.getJobId());
299         jobScheduler.cancel(MEASUREMENT_ATTRIBUTION_JOB.getJobId());
300         jobScheduler.cancel(MEASUREMENT_ATTRIBUTION_FALLBACK_JOB.getJobId());
301         jobScheduler.cancel(MEASUREMENT_EVENT_FALLBACK_REPORTING_JOB.getJobId());
302         jobScheduler.cancel(MEASUREMENT_AGGREGATE_MAIN_REPORTING_JOB.getJobId());
303         jobScheduler.cancel(MEASUREMENT_AGGREGATE_FALLBACK_REPORTING_JOB.getJobId());
304         jobScheduler.cancel(MEASUREMENT_IMMEDIATE_AGGREGATE_REPORTING_JOB.getJobId());
305         jobScheduler.cancel(MEASUREMENT_REPORTING_JOB.getJobId());
306         jobScheduler.cancel(MEASUREMENT_ASYNC_REGISTRATION_JOB.getJobId());
307         jobScheduler.cancel(MEASUREMENT_ASYNC_REGISTRATION_FALLBACK_JOB.getJobId());
308         jobScheduler.cancel(MEASUREMENT_VERBOSE_DEBUG_REPORTING_FALLBACK_JOB.getJobId());
309         jobScheduler.cancel(MEASUREMENT_DEBUG_REPORTING_FALLBACK_JOB.getJobId());
310     }
311 
312     /**
313      * Tries to unschedule all the Topics related background jobs.
314      *
315      * @param jobScheduler Job scheduler to cancel the jobs.
316      */
unscheduleTopicsBackgroundJobs(@onNull JobScheduler jobScheduler)317     public static void unscheduleTopicsBackgroundJobs(@NonNull JobScheduler jobScheduler) {
318         Objects.requireNonNull(jobScheduler);
319 
320         jobScheduler.cancel(TOPICS_EPOCH_JOB.getJobId());
321     }
322 
323     /**
324      * Tries to unschedule all the Fledge related background jobs.
325      *
326      * @param jobScheduler Job scheduler to cancel the jobs.
327      */
unscheduleFledgeBackgroundJobs(@onNull JobScheduler jobScheduler)328     public static void unscheduleFledgeBackgroundJobs(@NonNull JobScheduler jobScheduler) {
329         Objects.requireNonNull(jobScheduler);
330 
331         jobScheduler.cancel(FLEDGE_BACKGROUND_FETCH_JOB.getJobId());
332         jobScheduler.cancel(FLEDGE_AD_SELECTION_DEBUG_REPORT_SENDER_JOB.getJobId());
333         jobScheduler.cancel(PERIODIC_SIGNALS_ENCODING_JOB.getJobId());
334         jobScheduler.cancel(FLEDGE_KANON_SIGN_JOIN_BACKGROUND_JOB.getJobId());
335     }
336 
337     /**
338      * Tries to unschedule all the maintenance background jobs.
339      *
340      * @param jobScheduler Job scheduler to cancel the jobs.
341      */
unscheduleMaintenanceJobs(@onNull JobScheduler jobScheduler)342     public static void unscheduleMaintenanceJobs(@NonNull JobScheduler jobScheduler) {
343         Objects.requireNonNull(jobScheduler);
344 
345         jobScheduler.cancel(MAINTENANCE_JOB.getJobId());
346     }
347 
348     /** Tries to unschedule Cobalt background job. */
unscheduleCobaltJob(@onNull JobScheduler jobScheduler)349     public static void unscheduleCobaltJob(@NonNull JobScheduler jobScheduler) {
350         Objects.requireNonNull(jobScheduler);
351 
352         jobScheduler.cancel(COBALT_LOGGING_JOB.getJobId());
353     }
354 }
355