1 /*
2  * 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.car.bugreport;
18 
19 import android.app.job.JobParameters;
20 import android.app.job.JobService;
21 
22 import java.util.List;
23 import java.util.concurrent.ExecutorService;
24 import java.util.concurrent.Executors;
25 import java.util.concurrent.atomic.AtomicBoolean;
26 
27 /**
28  * Marks the old bugreport entries {@link Status#STATUS_EXPIRED} and deletes associated zip files.
29  * Bug report is considered old if it has 0 TTL points, which is decremented every system boot by
30  * {@link TtlPointsDecremental}.
31  *
32  * <p>This job will be executed in garage-mode, see
33  * {@link JobSchedulingUtils#scheduleExpireOldBugReportsJobInGarageMode}.
34  */
35 public class ExpireOldBugReportsJob extends JobService {
36     private final AtomicBoolean mIsCancelled = new AtomicBoolean(false);
37     private ExecutorService mExecutorService;
38 
39     @Override
onCreate()40     public void onCreate() {
41         super.onCreate();
42 
43         mExecutorService = Executors.newSingleThreadExecutor();
44     }
45 
46     /**
47      * @return {@code true} if your service will continue running, using a separate thread.
48      */
49     @Override
onStartJob(JobParameters params)50     public boolean onStartJob(JobParameters params) {
51         if (!Config.isBugReportEnabled()) {
52             return false;
53         }
54         mIsCancelled.set(false);
55         mExecutorService.submit(() -> run(params));
56         return true;
57     }
58 
59     /**
60      * @return {@code true} to indicate to the JobManager whether you'd like to reschedule
61      * this job based on the retry criteria provided at job creation-time; or {@code false}
62      * to end the job entirely. Regardless of the value returned, your job must stop executing.
63      */
64     @Override
onStopJob(JobParameters params)65     public boolean onStopJob(JobParameters params) {
66         mIsCancelled.set(true);
67         return false;
68     }
69 
70     /** Deletes old bugreports. Must be run in a separate thread. */
run(JobParameters params)71     private void run(JobParameters params) {
72         List<MetaBugReport> bugReportsWithZeroTtlPoints =
73                 BugStorageUtils.getUnexpiredBugReportsWithZipFile(
74                         this, /* ttlPointsReachedZero= */ true);
75         for (MetaBugReport bug : bugReportsWithZeroTtlPoints) {
76             if (mIsCancelled.get()) {
77                 break;
78             }
79             BugStorageUtils.expireBugReport(this, bug.getId());
80         }
81         jobFinished(params, /* wantsReschedule= */ false);
82     }
83 }
84