• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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         // if the job already exists for some reason, cancel & reschedule
46         if (jobScheduler.getPendingJob(JOB_ID) != null) {
47             jobScheduler.cancel(JOB_ID);
48         }
49         ComponentName component = new ComponentName(
50                 context, ReviewNotificationPermissionsJobService.class);
51         JobInfo newJob = new JobInfo.Builder(JOB_ID, component)
52                 .setPersisted(true) // make sure it'll still get rescheduled after reboot
53                 .setMinimumLatency(rescheduleTimeMillis)  // run after specified amount of time
54                 .build();
55         jobScheduler.schedule(newJob);
56     }
57 
58     @Override
onStartJob(JobParameters params)59     public boolean onStartJob(JobParameters params) {
60         // While jobs typically should be run on different threads, this
61         // job only posts a notification, which is not a long-running operation
62         // as notification posting is asynchronous.
63         NotificationManagerInternal nmi =
64                 LocalServices.getService(NotificationManagerInternal.class);
65         nmi.sendReviewPermissionsNotification();
66 
67         // once the notification is posted, the job is done, so no need to
68         // keep it alive afterwards
69         return false;
70     }
71 
72     @Override
onStopJob(JobParameters params)73     public boolean onStopJob(JobParameters params) {
74         // If we're interrupted for some reason, try again (though this may not
75         // ever happen due to onStartJob not leaving a job running after being
76         // called)
77         return true;
78     }
79 }
80