1 /*
2  * Copyright (C) 2023 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.measurement.util;
18 
19 import static com.android.adservices.service.measurement.util.JobLockHolder.Type.AGGREGATE_REPORTING;
20 import static com.android.adservices.service.measurement.util.JobLockHolder.Type.ASYNC_REGISTRATION_PROCESSING;
21 import static com.android.adservices.service.measurement.util.JobLockHolder.Type.ATTRIBUTION_PROCESSING;
22 import static com.android.adservices.service.measurement.util.JobLockHolder.Type.DEBUG_REPORTING;
23 import static com.android.adservices.service.measurement.util.JobLockHolder.Type.EVENT_REPORTING;
24 import static com.android.adservices.service.measurement.util.JobLockHolder.Type.VERBOSE_DEBUG_REPORTING;
25 
26 import java.util.Map;
27 import java.util.concurrent.locks.ReentrantLock;
28 
29 /**
30  * Holds the lock to be used by the background jobs. The locks will be used by multiple jobs,
31  * fallback jobs, and similar functions that could perform the same action. However, only one of
32  * these functions should be able to process at a time. This is to prevent conflicts and ensure that
33  * the system runs smoothly.
34  */
35 public class JobLockHolder {
36     public enum Type {
37         AGGREGATE_REPORTING,
38         ASYNC_REGISTRATION_PROCESSING,
39         ATTRIBUTION_PROCESSING,
40         DEBUG_REPORTING,
41         EVENT_REPORTING,
42         VERBOSE_DEBUG_REPORTING
43     }
44 
45     private static final Map<Type, JobLockHolder> INSTANCES =
46             Map.of(
47                     AGGREGATE_REPORTING, new JobLockHolder(),
48                     ASYNC_REGISTRATION_PROCESSING, new JobLockHolder(),
49                     ATTRIBUTION_PROCESSING, new JobLockHolder(),
50                     DEBUG_REPORTING, new JobLockHolder(),
51                     EVENT_REPORTING, new JobLockHolder(),
52                     VERBOSE_DEBUG_REPORTING, new JobLockHolder());
53 
54     /* Holds the lock that will be given per instance */
55     private final ReentrantLock mLock;
56 
JobLockHolder()57     private JobLockHolder() {
58         mLock = new ReentrantLock();
59     }
60 
61     /**
62      * Retrieves an instance that has already been created based on its type.
63      *
64      * @param type of lock to be shared by similar tasks
65      * @return lock instance
66      */
getInstance(Type type)67     public static JobLockHolder getInstance(Type type) {
68         return INSTANCES.get(type);
69     }
70 
71     /**
72      * Tries to acquire the lock. Returns true if the lock was acquired successfully or false if it
73      * has already been acquired by another thread. If lock was acquired, at the end of processing,
74      * a call to {@link JobLockHolder#unlock()} will need to be made.
75      *
76      * @return a boolean determining if the lock was successfully acquired or not.
77      */
tryLock()78     public boolean tryLock() {
79         return mLock.tryLock();
80     }
81 
82     /**
83      * Releases the lock that was previously acquired. It must be called after the lock has been
84      * successfully acquired.
85      */
unlock()86     public void unlock() {
87         mLock.unlock();
88     }
89 }
90