Home | History | Annotate | Download | only in scheduling
      1 /*
      2  * Copyright (C) 2017 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.voicemail.impl.scheduling;
     18 
     19 import android.annotation.TargetApi;
     20 import android.content.BroadcastReceiver;
     21 import android.content.Context;
     22 import android.content.Intent;
     23 import android.os.Build.VERSION_CODES;
     24 import android.os.Bundle;
     25 import com.android.voicemail.impl.VvmLog;
     26 import java.util.ArrayList;
     27 import java.util.List;
     28 
     29 /**
     30  * BroadcastReceiver to queue and run {@link Task} with the {@link android.app.job.JobScheduler}. A
     31  * task is queued using a explicit broadcast to this receiver. The intent should contain enough
     32  * information in {@link Intent#getExtras()} to construct the task (see {@link
     33  * Tasks#createIntent(Context, Class)}). The task will be queued directly in {@link TaskExecutor} if
     34  * it is already running, or in {@link TaskSchedulerJobService} if not.
     35  */
     36 @TargetApi(VERSION_CODES.O)
     37 public class TaskReceiver extends BroadcastReceiver {
     38 
     39   private static final String TAG = "VvmTaskReceiver";
     40 
     41   private static final List<Intent> deferredBroadcasts = new ArrayList<>();
     42 
     43   /**
     44    * When {@link TaskExecutor#isTerminating()} is {@code true}, newly added tasks will be deferred
     45    * to allow the TaskExecutor to terminate properly. After termination is completed this should be
     46    * called to add the tasks again.
     47    */
     48   public static void resendDeferredBroadcasts(Context context) {
     49     for (Intent intent : deferredBroadcasts) {
     50       context.sendBroadcast(intent);
     51     }
     52     deferredBroadcasts.clear();
     53   }
     54 
     55   @Override
     56   public void onReceive(Context context, Intent intent) {
     57     if (intent == null) {
     58       VvmLog.w(TAG, "null intent received");
     59       return;
     60     }
     61     VvmLog.i(TAG, "task received");
     62     TaskExecutor taskExecutor = TaskExecutor.getRunningInstance();
     63     if (taskExecutor != null) {
     64       VvmLog.i(TAG, "TaskExecutor already running");
     65       if (taskExecutor.isTerminating()) {
     66         // The current taskExecutor and cannot do anything and a new job cannot be scheduled. Defer
     67         // the task until a new job can be scheduled.
     68         VvmLog.w(TAG, "TaskExecutor is terminating, bouncing task");
     69         deferredBroadcasts.add(intent);
     70         return;
     71       }
     72       Task task = Tasks.createTask(context.getApplicationContext(), intent.getExtras());
     73       taskExecutor.addTask(task);
     74     } else {
     75       VvmLog.i(TAG, "scheduling new job");
     76       List<Bundle> taskList = new ArrayList<>();
     77       taskList.add(intent.getExtras());
     78       TaskSchedulerJobService.scheduleJob(context.getApplicationContext(), taskList, 0, true);
     79     }
     80   }
     81 }
     82