Home | History | Annotate | Download | only in shortcuts
      1 /*
      2  * Copyright (C) 2016 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.dialer.shortcuts;
     18 
     19 import android.annotation.TargetApi;
     20 import android.app.job.JobInfo;
     21 import android.app.job.JobParameters;
     22 import android.app.job.JobScheduler;
     23 import android.app.job.JobService;
     24 import android.content.ComponentName;
     25 import android.content.Context;
     26 import android.os.Build.VERSION;
     27 import android.os.Build.VERSION_CODES;
     28 import android.support.annotation.MainThread;
     29 import android.support.annotation.NonNull;
     30 import android.support.v4.os.UserManagerCompat;
     31 import com.android.dialer.common.Assert;
     32 import com.android.dialer.common.LogUtil;
     33 import com.android.dialer.constants.ScheduledJobIds;
     34 import java.util.concurrent.TimeUnit;
     35 
     36 /**
     37  * {@link JobService} which starts the periodic job to refresh dynamic and pinned shortcuts.
     38  *
     39  * <p>Only {@link #schedulePeriodicJob(Context)} should be used by callers.
     40  */
     41 @TargetApi(VERSION_CODES.N_MR1) // Shortcuts introduced in N MR1
     42 public final class PeriodicJobService extends JobService {
     43 
     44   private static final long REFRESH_PERIOD_MILLIS = TimeUnit.HOURS.toMillis(24);
     45 
     46   private RefreshShortcutsTask refreshShortcutsTask;
     47 
     48   /**
     49    * Schedules the periodic job to refresh shortcuts. If called repeatedly, the job will just be
     50    * rescheduled.
     51    *
     52    * <p>The job will not be scheduled if the build version is not at least N MR1 or if the user is
     53    * locked.
     54    */
     55   @MainThread
     56   public static void schedulePeriodicJob(@NonNull Context context) {
     57     Assert.isMainThread();
     58     LogUtil.enterBlock("PeriodicJobService.schedulePeriodicJob");
     59 
     60     if (VERSION.SDK_INT >= VERSION_CODES.N_MR1 && UserManagerCompat.isUserUnlocked(context)) {
     61       JobScheduler jobScheduler = context.getSystemService(JobScheduler.class);
     62       if (jobScheduler.getPendingJob(ScheduledJobIds.SHORTCUT_PERIODIC_JOB) != null) {
     63         LogUtil.i("PeriodicJobService.schedulePeriodicJob", "job already scheduled.");
     64         return;
     65       }
     66       JobInfo jobInfo =
     67           new JobInfo.Builder(
     68                   ScheduledJobIds.SHORTCUT_PERIODIC_JOB,
     69                   new ComponentName(context, PeriodicJobService.class))
     70               .setPeriodic(REFRESH_PERIOD_MILLIS)
     71               .setPersisted(true)
     72               .setRequiresCharging(true)
     73               .setRequiresDeviceIdle(true)
     74               .build();
     75       jobScheduler.schedule(jobInfo);
     76     }
     77   }
     78 
     79   /** Cancels the periodic job. */
     80   @MainThread
     81   public static void cancelJob(@NonNull Context context) {
     82     Assert.isMainThread();
     83     LogUtil.enterBlock("PeriodicJobService.cancelJob");
     84 
     85     context.getSystemService(JobScheduler.class).cancel(ScheduledJobIds.SHORTCUT_PERIODIC_JOB);
     86   }
     87 
     88   @Override
     89   @MainThread
     90   public boolean onStartJob(@NonNull JobParameters params) {
     91     Assert.isMainThread();
     92     LogUtil.enterBlock("PeriodicJobService.onStartJob");
     93 
     94     if (VERSION.SDK_INT >= VERSION_CODES.N_MR1) {
     95       (refreshShortcutsTask = new RefreshShortcutsTask(this)).execute(params);
     96     } else {
     97       // It is possible for the job to have been scheduled on NMR1+ and then the system was
     98       // downgraded to < NMR1. In this case, shortcuts are no longer supported so we cancel the job
     99       // which creates them.
    100       LogUtil.i("PeriodicJobService.onStartJob", "not running on NMR1, cancelling job");
    101       cancelJob(this);
    102       return false;
    103     }
    104     return true;
    105   }
    106 
    107   @Override
    108   @MainThread
    109   public boolean onStopJob(@NonNull JobParameters params) {
    110     Assert.isMainThread();
    111     LogUtil.enterBlock("PeriodicJobService.onStopJob");
    112 
    113     if (refreshShortcutsTask != null) {
    114       refreshShortcutsTask.cancel(false /* mayInterruptIfRunning */);
    115     }
    116     return false;
    117   }
    118 }
    119