1 // Copyright 2017 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 package org.chromium.chrome.browser.download.service; 6 7 import android.os.Bundle; 8 import android.text.format.DateUtils; 9 10 import org.chromium.base.ContextUtils; 11 import org.chromium.base.TimeUtils; 12 import org.chromium.base.annotations.CalledByNative; 13 import org.chromium.base.annotations.JNINamespace; 14 import org.chromium.chrome.browser.flags.CachedFeatureFlags; 15 import org.chromium.chrome.browser.flags.ChromeFeatureList; 16 import org.chromium.components.background_task_scheduler.BackgroundTaskScheduler; 17 import org.chromium.components.background_task_scheduler.BackgroundTaskSchedulerFactory; 18 import org.chromium.components.background_task_scheduler.TaskIds; 19 import org.chromium.components.background_task_scheduler.TaskInfo; 20 import org.chromium.components.download.DownloadTaskType; 21 22 /** 23 * A background task scheduler that schedules various types of jobs with the system with certain 24 * conditions as requested by the download service. 25 */ 26 @JNINamespace("download::android") 27 public class DownloadTaskScheduler { 28 public static final String EXTRA_BATTERY_REQUIRES_CHARGING = "extra_battery_requires_charging"; 29 public static final String EXTRA_OPTIMAL_BATTERY_PERCENTAGE = 30 "extra_optimal_battery_percentage"; 31 public static final String EXTRA_TASK_TYPE = "extra_task_type"; 32 33 @CalledByNative scheduleTask(@ownloadTaskType int taskType, boolean requiresUnmeteredNetwork, boolean requiresCharging, int optimalBatteryPercentage, long windowStartTimeSeconds, long windowEndTimeSeconds)34 private static void scheduleTask(@DownloadTaskType int taskType, 35 boolean requiresUnmeteredNetwork, boolean requiresCharging, 36 int optimalBatteryPercentage, long windowStartTimeSeconds, long windowEndTimeSeconds) { 37 Bundle bundle = new Bundle(); 38 bundle.putInt(EXTRA_TASK_TYPE, taskType); 39 bundle.putInt(EXTRA_OPTIMAL_BATTERY_PERCENTAGE, optimalBatteryPercentage); 40 bundle.putBoolean(EXTRA_BATTERY_REQUIRES_CHARGING, requiresCharging); 41 42 BackgroundTaskScheduler scheduler = BackgroundTaskSchedulerFactory.getScheduler(); 43 TaskInfo taskInfo = TaskInfo.createOneOffTask(getTaskId(taskType), 44 DateUtils.SECOND_IN_MILLIS * windowStartTimeSeconds, 45 DateUtils.SECOND_IN_MILLIS * windowEndTimeSeconds) 46 .setRequiredNetworkType(getRequiredNetworkType( 47 taskType, requiresUnmeteredNetwork)) 48 .setRequiresCharging(requiresCharging) 49 .setUpdateCurrent(true) 50 .setIsPersisted(true) 51 .setExtras(bundle) 52 .build(); 53 scheduler.schedule(ContextUtils.getApplicationContext(), taskInfo); 54 } 55 56 @CalledByNative cancelTask(@ownloadTaskType int taskType)57 private static void cancelTask(@DownloadTaskType int taskType) { 58 BackgroundTaskScheduler scheduler = BackgroundTaskSchedulerFactory.getScheduler(); 59 scheduler.cancel(ContextUtils.getApplicationContext(), getTaskId(taskType)); 60 } 61 62 /** 63 * Invoked when the system sends a reschedule() call, which might happen in case of OS or play 64 * services upgrade etc. This will schedule the tasks in future with least restrictive criteria. 65 */ rescheduleAllTasks()66 public static void rescheduleAllTasks() { 67 scheduleTask(DownloadTaskType.DOWNLOAD_TASK, false, false, 0, 68 TimeUtils.SECONDS_PER_MINUTE * 5, TimeUtils.SECONDS_PER_MINUTE * 10); 69 scheduleTask(DownloadTaskType.CLEANUP_TASK, false, false, 0, 70 TimeUtils.SECONDS_PER_HOUR * 12, TimeUtils.SECONDS_PER_HOUR * 24); 71 if (CachedFeatureFlags.isEnabled(ChromeFeatureList.DOWNLOADS_AUTO_RESUMPTION_NATIVE)) { 72 scheduleTask(DownloadTaskType.DOWNLOAD_AUTO_RESUMPTION_TASK, false, false, 0, 73 TimeUtils.SECONDS_PER_MINUTE * 5, TimeUtils.SECONDS_PER_DAY); 74 } 75 } 76 getTaskId(@ownloadTaskType int taskType)77 private static int getTaskId(@DownloadTaskType int taskType) { 78 switch (taskType) { 79 case DownloadTaskType.DOWNLOAD_TASK: 80 return TaskIds.DOWNLOAD_SERVICE_JOB_ID; 81 case DownloadTaskType.CLEANUP_TASK: 82 return TaskIds.DOWNLOAD_CLEANUP_JOB_ID; 83 case DownloadTaskType.DOWNLOAD_AUTO_RESUMPTION_TASK: 84 return TaskIds.DOWNLOAD_AUTO_RESUMPTION_JOB_ID; 85 case DownloadTaskType.DOWNLOAD_LATER_TASK: 86 return TaskIds.DOWNLOAD_LATER_JOB_ID; 87 } 88 assert false : "Unknown download task type."; 89 return -1; 90 } 91 getRequiredNetworkType( @ownloadTaskType int taskType, boolean requiresUnmeteredNetwork)92 private static int getRequiredNetworkType( 93 @DownloadTaskType int taskType, boolean requiresUnmeteredNetwork) { 94 switch (taskType) { 95 case DownloadTaskType.CLEANUP_TASK: 96 return TaskInfo.NetworkType.NONE; 97 case DownloadTaskType.DOWNLOAD_TASK: // intentional fall-through 98 case DownloadTaskType.DOWNLOAD_AUTO_RESUMPTION_TASK: 99 return requiresUnmeteredNetwork ? TaskInfo.NetworkType.UNMETERED 100 : TaskInfo.NetworkType.ANY; 101 case DownloadTaskType.DOWNLOAD_LATER_TASK: 102 return TaskInfo.NetworkType.ANY; 103 } 104 assert false : "Unknown download task type."; 105 return -1; 106 } 107 } 108