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 android.app.job.JobInfo;
20 import android.app.job.JobParameters;
21 import android.app.job.JobScheduler;
22 import android.app.job.JobService;
23 import android.content.ComponentName;
24 import android.content.Context;
25 
26 import com.android.internal.annotations.VisibleForTesting;
27 import com.android.server.LocalServices;
28 
29 /**
30  * JobService implementation for scheduling the notification informing users about
31  * notification permissions updates and taking them to review their existing permissions.
32  * @hide
33  */
34 public class ReviewNotificationPermissionsJobService extends JobService {
35     public static final String TAG = "ReviewNotificationPermissionsJobService";
36 
37     @VisibleForTesting
38     protected static final int JOB_ID = 225373531;
39 
40     /**
41      *  Schedule a new job that will show a notification the specified amount of time in the future.
42      */
scheduleJob(Context context, long rescheduleTimeMillis)43     public static void scheduleJob(Context context, long rescheduleTimeMillis) {
44         JobScheduler jobScheduler = context.getSystemService(JobScheduler.class);
45         ComponentName component = new ComponentName(
46                 context, ReviewNotificationPermissionsJobService.class);
47         JobInfo newJob = new JobInfo.Builder(JOB_ID, component)
48                 .setPersisted(true) // make sure it'll still get rescheduled after reboot
49                 .setMinimumLatency(rescheduleTimeMillis)  // run after specified amount of time
50                 .build();
51         jobScheduler.schedule(newJob);
52     }
53 
54     @Override
onStartJob(JobParameters params)55     public boolean onStartJob(JobParameters params) {
56         // While jobs typically should be run on different threads, this
57         // job only posts a notification, which is not a long-running operation
58         // as notification posting is asynchronous.
59         NotificationManagerInternal nmi =
60                 LocalServices.getService(NotificationManagerInternal.class);
61         nmi.sendReviewPermissionsNotification();
62 
63         // once the notification is posted, the job is done, so no need to
64         // keep it alive afterwards
65         return false;
66     }
67 
68     @Override
onStopJob(JobParameters params)69     public boolean onStopJob(JobParameters params) {
70         // If we're interrupted for some reason, try again (though this may not
71         // ever happen due to onStartJob not leaving a job running after being
72         // called)
73         return true;
74     }
75 }
76