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.server.notification; 18 19 import static android.app.job.JobScheduler.RESULT_SUCCESS; 20 21 import android.app.job.JobInfo; 22 import android.app.job.JobParameters; 23 import android.app.job.JobScheduler; 24 import android.app.job.JobService; 25 import android.content.ComponentName; 26 import android.content.Context; 27 import android.os.CancellationSignal; 28 import android.util.Slog; 29 30 import com.android.internal.annotations.VisibleForTesting; 31 import com.android.server.LocalServices; 32 33 import java.util.concurrent.TimeUnit; 34 35 /** 36 * This service runs every twenty minutes to ensure the retention policy for notification history 37 * data. 38 */ 39 public class NotificationHistoryJobService extends JobService { 40 private final static String TAG = "NotificationHistoryJob"; 41 private static final long JOB_RUN_INTERVAL = TimeUnit.MINUTES.toMillis(20); 42 43 static final int BASE_JOB_ID = 237039804; 44 scheduleJob(Context context)45 static void scheduleJob(Context context) { 46 JobScheduler jobScheduler = context.getSystemService(JobScheduler.class); 47 if (jobScheduler.getPendingJob(BASE_JOB_ID) == null) { 48 ComponentName component = 49 new ComponentName(context, NotificationHistoryJobService.class); 50 JobInfo newJob = new JobInfo.Builder(BASE_JOB_ID, component) 51 .setRequiresDeviceIdle(false) 52 .setPeriodic(JOB_RUN_INTERVAL) 53 .build(); 54 if (jobScheduler.schedule(newJob) != RESULT_SUCCESS) { 55 Slog.w(TAG, "Failed to schedule history cleanup job"); 56 } 57 } 58 } 59 60 private CancellationSignal mSignal; 61 62 @Override onStartJob(JobParameters params)63 public boolean onStartJob(JobParameters params) { 64 mSignal = new CancellationSignal(); 65 new Thread(() -> { 66 NotificationManagerInternal nmInternal = 67 LocalServices.getService(NotificationManagerInternal.class); 68 nmInternal.cleanupHistoryFiles(); 69 jobFinished(params, mSignal.isCanceled()); 70 }).start(); 71 return true; 72 } 73 74 @Override onStopJob(JobParameters params)75 public boolean onStopJob(JobParameters params) { 76 if (mSignal != null) { 77 mSignal.cancel(); 78 } 79 return false; 80 } 81 82 @Override 83 @VisibleForTesting attachBaseContext(Context base)84 protected void attachBaseContext(Context base) { 85 super.attachBaseContext(base); 86 } 87 } 88 89