Commit f647de8f authored by Mugdha Lakhani's avatar Mugdha Lakhani Committed by Commit Bot

[BackgroundTaskScheduler] Check requirements before firing exact task.

Check that the requirements set for the BackgroundTask that is supposed
to fire at a fixed time are met before starting it.

Bug: 970160
Change-Id: I03edb499cd607c747b583b4eca2f500c1e105ff1
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1964613
Commit-Queue: Mugdha Lakhani <nator@chromium.org>
Reviewed-by: default avatarDavid Trainor <dtrainor@chromium.org>
Reviewed-by: default avatarRichard Knoll <knollr@chromium.org>
Cr-Commit-Position: refs/heads/master@{#728165}
parent bb9c4049
...@@ -70,7 +70,6 @@ if (is_android) { ...@@ -70,7 +70,6 @@ if (is_android) {
testonly = true testonly = true
sources = [ sources = [
"android/javatests/src/org/chromium/components/background_task_scheduler/BackgroundTaskBroadcastReceiverTest.java",
"android/javatests/src/org/chromium/components/background_task_scheduler/BackgroundTaskSchedulerImplWithMockTest.java", "android/javatests/src/org/chromium/components/background_task_scheduler/BackgroundTaskSchedulerImplWithMockTest.java",
"android/javatests/src/org/chromium/components/background_task_scheduler/BackgroundTaskSchedulerJobServiceTest.java", "android/javatests/src/org/chromium/components/background_task_scheduler/BackgroundTaskSchedulerJobServiceTest.java",
"android/javatests/src/org/chromium/components/background_task_scheduler/BundleToPersistableBundleConverterTest.java", "android/javatests/src/org/chromium/components/background_task_scheduler/BundleToPersistableBundleConverterTest.java",
...@@ -101,6 +100,7 @@ if (is_android) { ...@@ -101,6 +100,7 @@ if (is_android) {
"android/junit/src/org/chromium/components/background_task_scheduler/BackgroundTaskSchedulerImplTest.java", "android/junit/src/org/chromium/components/background_task_scheduler/BackgroundTaskSchedulerImplTest.java",
"android/junit/src/org/chromium/components/background_task_scheduler/BackgroundTaskSchedulerPrefsTest.java", "android/junit/src/org/chromium/components/background_task_scheduler/BackgroundTaskSchedulerPrefsTest.java",
"android/junit/src/org/chromium/components/background_task_scheduler/BackgroundTaskSchedulerUmaTest.java", "android/junit/src/org/chromium/components/background_task_scheduler/BackgroundTaskSchedulerUmaTest.java",
"android/junit/src/org/chromium/components/background_task_scheduler/BroadcastReceiverRobolectricTest.java",
"android/junit/src/org/chromium/components/background_task_scheduler/ExtrasToProtoConverterTest.java", "android/junit/src/org/chromium/components/background_task_scheduler/ExtrasToProtoConverterTest.java",
"android/junit/src/org/chromium/components/background_task_scheduler/ShadowGcmNetworkManager.java", "android/junit/src/org/chromium/components/background_task_scheduler/ShadowGcmNetworkManager.java",
"android/junit/src/org/chromium/components/background_task_scheduler/TaskInfoTest.java", "android/junit/src/org/chromium/components/background_task_scheduler/TaskInfoTest.java",
......
...@@ -7,6 +7,12 @@ package org.chromium.components.background_task_scheduler; ...@@ -7,6 +7,12 @@ package org.chromium.components.background_task_scheduler;
import android.content.BroadcastReceiver; import android.content.BroadcastReceiver;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.net.Network;
import android.net.NetworkInfo;
import android.os.BatteryManager;
import android.os.Build;
import android.os.PowerManager; import android.os.PowerManager;
import android.text.format.DateUtils; import android.text.format.DateUtils;
...@@ -18,8 +24,6 @@ import org.chromium.content_public.browser.UiThreadTaskTraits; ...@@ -18,8 +24,6 @@ import org.chromium.content_public.browser.UiThreadTaskTraits;
/** /**
* Starts running the BackgroundTask at the specified triggering time. * Starts running the BackgroundTask at the specified triggering time.
* TODO (crbug.com/970160): Check that the requirements set for the BackgroundTask are met before
* starting it.
* *
* Receives the information through a broadcast, which is synchronous in the Main thread. The * Receives the information through a broadcast, which is synchronous in the Main thread. The
* execution of the task will be detached to a best effort task. * execution of the task will be detached to a best effort task.
...@@ -96,8 +100,33 @@ public class BackgroundTaskBroadcastReceiver extends BroadcastReceiver { ...@@ -96,8 +100,33 @@ public class BackgroundTaskBroadcastReceiver extends BroadcastReceiver {
return; return;
} }
int taskId = taskParams.getTaskId();
ScheduledTaskProto.ScheduledTask scheduledTask =
BackgroundTaskSchedulerPrefs.getScheduledTask(taskId);
if (scheduledTask == null) {
Log.e(TAG, "Cannot get information about task with task ID " + taskId);
return;
}
// Only continue if network requirements match network status.
if (!networkRequirementsMet(context, taskId,
convertToTaskInfoNetworkType(scheduledTask.getRequiredNetworkType()))) {
Log.w(TAG,
"Failed to start task. Network requirements not satisfied for task with task ID"
+ taskId);
return;
}
// Check if battery requirements match.
if (!batteryRequirementsMet(context, taskId, scheduledTask.getRequiresCharging())) {
Log.w(TAG,
"Failed to start task. Battery requirements not satisfied for task with task ID"
+ taskId);
return;
}
final BackgroundTask backgroundTask = final BackgroundTask backgroundTask =
BackgroundTaskSchedulerFactory.getBackgroundTaskFromTaskId(taskParams.getTaskId()); BackgroundTaskSchedulerFactory.getBackgroundTaskFromTaskId(taskId);
if (backgroundTask == null) { if (backgroundTask == null) {
Log.w(TAG, "Failed to start task. Could not instantiate BackgroundTask class."); Log.w(TAG, "Failed to start task. Could not instantiate BackgroundTask class.");
// Cancel task if the BackgroundTask class is not found anymore. We assume this means // Cancel task if the BackgroundTask class is not found anymore. We assume this means
...@@ -116,4 +145,52 @@ public class BackgroundTaskBroadcastReceiver extends BroadcastReceiver { ...@@ -116,4 +145,52 @@ public class BackgroundTaskBroadcastReceiver extends BroadcastReceiver {
TaskExecutor taskExecutor = new TaskExecutor(context, wakeLock, taskParams, backgroundTask); TaskExecutor taskExecutor = new TaskExecutor(context, wakeLock, taskParams, backgroundTask);
PostTask.postTask(UiThreadTaskTraits.BEST_EFFORT, taskExecutor::execute); PostTask.postTask(UiThreadTaskTraits.BEST_EFFORT, taskExecutor::execute);
} }
private boolean networkRequirementsMet(Context context, int taskId, int requiredNetworkType) {
if (requiredNetworkType == TaskInfo.NetworkType.NONE) return true;
ConnectivityManager connectivityManager =
(ConnectivityManager) context.getApplicationContext().getSystemService(
Context.CONNECTIVITY_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
Network network = connectivityManager.getActiveNetwork();
if (requiredNetworkType == TaskInfo.NetworkType.ANY) return (network != null);
} else {
NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
if (requiredNetworkType == TaskInfo.NetworkType.ANY) return (networkInfo != null);
}
return (!connectivityManager.isActiveNetworkMetered());
}
private boolean batteryRequirementsMet(Context context, int taskId, boolean requiresCharging) {
if (!requiresCharging) return true;
BatteryManager batteryManager =
(BatteryManager) context.getSystemService(Context.BATTERY_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
return batteryManager.isCharging();
}
IntentFilter intentFilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
Intent batteryStatus = context.registerReceiver(null, intentFilter);
int status = batteryStatus.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
return status == BatteryManager.BATTERY_STATUS_CHARGING
|| status == BatteryManager.BATTERY_STATUS_FULL;
}
private @TaskInfo.NetworkType int convertToTaskInfoNetworkType(
ScheduledTaskProto.ScheduledTask.RequiredNetworkType networkType) {
switch (networkType) {
case NONE:
return TaskInfo.NetworkType.NONE;
case ANY:
return TaskInfo.NetworkType.ANY;
case UNMETERED:
return TaskInfo.NetworkType.UNMETERED;
default:
assert false : "Incorrect value of RequiredNetworkType";
return -1;
}
}
} }
...@@ -40,6 +40,7 @@ public class BackgroundTaskSchedulerAlarmManager implements BackgroundTaskSchedu ...@@ -40,6 +40,7 @@ public class BackgroundTaskSchedulerAlarmManager implements BackgroundTaskSchedu
ScheduledTaskProto.ScheduledTask scheduledTask = ScheduledTaskProto.ScheduledTask scheduledTask =
BackgroundTaskSchedulerPrefs.getScheduledTask(taskId); BackgroundTaskSchedulerPrefs.getScheduledTask(taskId);
if (scheduledTask == null) { if (scheduledTask == null) {
Log.e(TAG, "Cannot get information about task with task ID " + taskId); Log.e(TAG, "Cannot get information about task with task ID " + taskId);
return null; return null;
......
...@@ -109,7 +109,8 @@ public class BackgroundTaskSchedulerPrefs { ...@@ -109,7 +109,8 @@ public class BackgroundTaskSchedulerPrefs {
public static void addScheduledTask(TaskInfo taskInfo) { public static void addScheduledTask(TaskInfo taskInfo) {
try (TraceEvent te = TraceEvent.scoped("BackgroundTaskSchedulerPrefs.addScheduledTask", try (TraceEvent te = TraceEvent.scoped("BackgroundTaskSchedulerPrefs.addScheduledTask",
Integer.toString(taskInfo.getTaskId()))) { Integer.toString(taskInfo.getTaskId()))) {
ScheduledTaskProtoVisitor visitor = new ScheduledTaskProtoVisitor(taskInfo.getExtras()); ScheduledTaskProtoVisitor visitor = new ScheduledTaskProtoVisitor(taskInfo.getExtras(),
taskInfo.getRequiredNetworkType(), taskInfo.requiresCharging());
taskInfo.getTimingInfo().accept(visitor); taskInfo.getTimingInfo().accept(visitor);
getSharedPreferences() getSharedPreferences()
...@@ -123,9 +124,15 @@ public class BackgroundTaskSchedulerPrefs { ...@@ -123,9 +124,15 @@ public class BackgroundTaskSchedulerPrefs {
private static class ScheduledTaskProtoVisitor implements TaskInfo.TimingInfoVisitor { private static class ScheduledTaskProtoVisitor implements TaskInfo.TimingInfoVisitor {
private String mSerializedScheduledTask; private String mSerializedScheduledTask;
private final Bundle mExtras; private final Bundle mExtras;
@TaskInfo.NetworkType
private final int mRequiredNetworkType;
private final boolean mRequiresCharging;
ScheduledTaskProtoVisitor(Bundle extras) { ScheduledTaskProtoVisitor(Bundle extras, @TaskInfo.NetworkType int requiredNetworkType,
boolean requiresCharging) {
mExtras = extras; mExtras = extras;
mRequiredNetworkType = requiredNetworkType;
mRequiresCharging = requiresCharging;
} }
// Only valid after a TimingInfo object was visited. // Only valid after a TimingInfo object was visited.
...@@ -159,6 +166,9 @@ public class BackgroundTaskSchedulerPrefs { ...@@ -159,6 +166,9 @@ public class BackgroundTaskSchedulerPrefs {
ScheduledTaskProto.ScheduledTask.newBuilder() ScheduledTaskProto.ScheduledTask.newBuilder()
.setType(ScheduledTaskProto.ScheduledTask.Type.EXACT) .setType(ScheduledTaskProto.ScheduledTask.Type.EXACT)
.setTriggerMs(exactInfo.getTriggerAtMs()) .setTriggerMs(exactInfo.getTriggerAtMs())
.setRequiredNetworkType(
convertToRequiredNetworkType(mRequiredNetworkType))
.setRequiresCharging(mRequiresCharging)
.addAllExtras( .addAllExtras(
ExtrasToProtoConverter.convertExtrasToProtoExtras(mExtras)) ExtrasToProtoConverter.convertExtrasToProtoExtras(mExtras))
.build(); .build();
...@@ -283,4 +293,19 @@ public class BackgroundTaskSchedulerPrefs { ...@@ -283,4 +293,19 @@ public class BackgroundTaskSchedulerPrefs {
.apply(); .apply();
} }
} }
private static ScheduledTaskProto.ScheduledTask.RequiredNetworkType
convertToRequiredNetworkType(@TaskInfo.NetworkType int networkType) {
switch (networkType) {
case TaskInfo.NetworkType.NONE:
return ScheduledTaskProto.ScheduledTask.RequiredNetworkType.NONE;
case TaskInfo.NetworkType.ANY:
return ScheduledTaskProto.ScheduledTask.RequiredNetworkType.ANY;
case TaskInfo.NetworkType.UNMETERED:
return ScheduledTaskProto.ScheduledTask.RequiredNetworkType.UNMETERED;
default:
assert false : "Incorrect value of TaskInfo.NetworkType";
return ScheduledTaskProto.ScheduledTask.RequiredNetworkType.NONE;
}
}
} }
\ No newline at end of file
...@@ -18,6 +18,12 @@ message ScheduledTask { ...@@ -18,6 +18,12 @@ message ScheduledTask {
EXACT = 2; EXACT = 2;
} }
enum RequiredNetworkType {
NONE = 0;
ANY = 1;
UNMETERED = 2;
}
// The type of the scheduled task. // The type of the scheduled task.
Type type = 1; Type type = 1;
...@@ -62,4 +68,14 @@ message ScheduledTask { ...@@ -62,4 +68,14 @@ message ScheduledTask {
// PeriodicTask objects store their extras through their scheduling backend // PeriodicTask objects store their extras through their scheduling backend
// (JobScheduler and GcmNetworkManager). // (JobScheduler and GcmNetworkManager).
repeated ExtraItem extras = 3; repeated ExtraItem extras = 3;
// Required network type, stored for an ExactTask. OneOffTask and PeriodicTask
// objects store their required network type through their scheduling backend
// (JobScheduler and GCMNetworkManager).
RequiredNetworkType required_network_type = 4;
// Bool representing whether the task requires charging. Stored for an
// ExactTask. OneOffTask and PeriodicTask objects store this info through
// their scheduling backend (JobScheduler and GCMNetworkManager).
bool requires_charging = 5;
} }
\ No newline at end of file
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.components.background_task_scheduler;
import static org.junit.Assert.assertEquals;
import android.content.Context;
import android.content.Intent;
import android.support.test.filters.MediumTest;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.chromium.base.ContextUtils;
import org.chromium.base.ThreadUtils;
import org.chromium.base.test.BaseJUnit4ClassRunner;
import org.chromium.content_public.browser.test.util.CriteriaHelper;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;
/** Tests for {@link BackgroundTaskBroadcastReceiver}. */
@RunWith(BaseJUnit4ClassRunner.class)
public class BackgroundTaskBroadcastReceiverTest {
class TestBackgroundTask implements BackgroundTask {
public TestBackgroundTask() {}
@Override
public boolean onStartTask(
Context context, TaskParameters taskParameters, TaskFinishedCallback callback) {
ThreadUtils.assertOnUiThread();
mScheduled++;
return false;
}
@Override
public boolean onStopTask(Context context, TaskParameters taskParameters) {
ThreadUtils.assertOnUiThread();
mStopped++;
return false;
}
@Override
public void reschedule(Context context) {
ThreadUtils.assertOnUiThread();
mRescheduled++;
}
}
class TestBackgroundTaskFactory implements BackgroundTaskFactory {
@Override
public BackgroundTask getBackgroundTaskFromTaskId(int taskId) {
if (taskId == TaskIds.TEST) {
return new TestBackgroundTask();
}
return null;
}
}
private int mScheduled;
private int mStopped;
private int mRescheduled;
@Before
public void setUp() {
mScheduled = 0;
mStopped = 0;
mRescheduled = 0;
BackgroundTaskSchedulerFactory.setBackgroundTaskFactory(new TestBackgroundTaskFactory());
}
@Test
@MediumTest
public void testStartExact() {
TaskInfo.TimingInfo exactInfo =
TaskInfo.ExactInfo.create().setTriggerAtMs(System.currentTimeMillis()).build();
TaskInfo exactTask = TaskInfo.createTask(TaskIds.TEST, exactInfo).build();
BackgroundTaskSchedulerPrefs.addScheduledTask(exactTask);
Intent intent = new Intent(
ContextUtils.getApplicationContext(), BackgroundTaskBroadcastReceiver.class)
.putExtra(BackgroundTaskSchedulerDelegate.BACKGROUND_TASK_ID_KEY,
TaskIds.TEST);
BackgroundTaskBroadcastReceiver receiver = new BackgroundTaskBroadcastReceiver();
receiver.onReceive(ContextUtils.getApplicationContext(), intent);
Callable<Boolean> hasScheduled = () -> mScheduled == 1;
CriteriaHelper.pollUiThread(hasScheduled, "Failed to schedule task",
/*maxTimeoutMs=*/TimeUnit.MINUTES.toMillis(2), /*checkIntervalMs=*/50);
assertEquals(0, mStopped);
assertEquals(0, mRescheduled);
}
}
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.components.background_task_scheduler;
import static org.junit.Assert.assertEquals;
import static org.robolectric.Shadows.shadowOf;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.os.BatteryManager;
import android.os.Build;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowBatteryManager;
import org.robolectric.shadows.ShadowConnectivityManager;
import org.chromium.base.ContextUtils;
import org.chromium.base.ThreadUtils;
import org.chromium.base.test.BaseRobolectricTestRunner;
import org.chromium.base.test.util.Feature;
import org.chromium.base.test.util.MinAndroidSdkLevel;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
/** Robolectric tests for BackgroundTaskBroadcastReceiver. */
@RunWith(BaseRobolectricTestRunner.class)
@Config(manifest = Config.NONE,
shadows = {ShadowBatteryManager.class, ShadowConnectivityManager.class})
public final class BroadcastReceiverRobolectricTest {
private static final long WAIT_TIME_MS = 10;
private CountDownLatch mScheduleLatch;
private int mStopped;
private int mRescheduled;
private BatteryManager mBatteryManager;
private ShadowBatteryManager mShadowBatteryManager;
private ConnectivityManager mConnectivityManager;
private ShadowConnectivityManager mShadowConnectivityManager;
class TestBackgroundTask implements BackgroundTask {
public TestBackgroundTask() {}
@Override
public boolean onStartTask(
Context context, TaskParameters taskParameters, TaskFinishedCallback callback) {
ThreadUtils.assertOnUiThread();
mScheduleLatch.countDown();
return false;
}
@Override
public boolean onStopTask(Context context, TaskParameters taskParameters) {
ThreadUtils.assertOnUiThread();
mStopped++;
return false;
}
@Override
public void reschedule(Context context) {
ThreadUtils.assertOnUiThread();
mRescheduled++;
}
}
class TestBackgroundTaskFactory implements BackgroundTaskFactory {
@Override
public BackgroundTask getBackgroundTaskFromTaskId(int taskId) {
if (taskId == TaskIds.TEST) {
return new TestBackgroundTask();
}
return null;
}
}
@Before
public void setUp() {
mScheduleLatch = new CountDownLatch(1);
mStopped = 0;
mRescheduled = 0;
BackgroundTaskSchedulerFactory.setBackgroundTaskFactory(new TestBackgroundTaskFactory());
mBatteryManager = (BatteryManager) ContextUtils.getApplicationContext().getSystemService(
Context.BATTERY_SERVICE);
mShadowBatteryManager = shadowOf(mBatteryManager);
mConnectivityManager =
(ConnectivityManager) ContextUtils.getApplicationContext().getSystemService(
Context.CONNECTIVITY_SERVICE);
mShadowConnectivityManager = shadowOf(mConnectivityManager);
}
@Test
@Feature({"BackgroundTaskScheduler"})
public void testStartExact() throws InterruptedException {
TaskInfo.TimingInfo exactInfo =
TaskInfo.ExactInfo.create().setTriggerAtMs(System.currentTimeMillis()).build();
TaskInfo exactTask = TaskInfo.createTask(TaskIds.TEST, exactInfo).build();
BackgroundTaskSchedulerPrefs.addScheduledTask(exactTask);
Intent intent = new Intent(
ContextUtils.getApplicationContext(), BackgroundTaskBroadcastReceiver.class)
.putExtra(BackgroundTaskSchedulerDelegate.BACKGROUND_TASK_ID_KEY,
TaskIds.TEST);
BackgroundTaskBroadcastReceiver receiver = new BackgroundTaskBroadcastReceiver();
receiver.onReceive(ContextUtils.getApplicationContext(), intent);
Assert.assertTrue(mScheduleLatch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
assertEquals(0, mStopped);
assertEquals(0, mRescheduled);
}
@Test
@Feature({"BackgroundTaskScheduler"})
public void noChargingRequired() throws InterruptedException {
TaskInfo.TimingInfo exactInfo =
TaskInfo.ExactInfo.create().setTriggerAtMs(System.currentTimeMillis()).build();
TaskInfo exactTask =
TaskInfo.createTask(TaskIds.TEST, exactInfo).setRequiresCharging(false).build();
BackgroundTaskSchedulerPrefs.addScheduledTask(exactTask);
Intent intent = new Intent(
ContextUtils.getApplicationContext(), BackgroundTaskBroadcastReceiver.class)
.putExtra(BackgroundTaskSchedulerDelegate.BACKGROUND_TASK_ID_KEY,
TaskIds.TEST);
BackgroundTaskBroadcastReceiver receiver = new BackgroundTaskBroadcastReceiver();
receiver.onReceive(ContextUtils.getApplicationContext(), intent);
Assert.assertTrue(mScheduleLatch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
assertEquals(0, mStopped);
assertEquals(0, mRescheduled);
}
@Test
@MinAndroidSdkLevel(Build.VERSION_CODES.M)
@Feature({"BackgroundTaskScheduler"})
public void withChargingRequired() throws InterruptedException {
// Set device in charging mode
mShadowBatteryManager.setIsCharging(true);
Assert.assertTrue(mBatteryManager.isCharging());
TaskInfo.TimingInfo exactInfo =
TaskInfo.ExactInfo.create().setTriggerAtMs(System.currentTimeMillis()).build();
TaskInfo exactTask =
TaskInfo.createTask(TaskIds.TEST, exactInfo).setRequiresCharging(true).build();
BackgroundTaskSchedulerPrefs.addScheduledTask(exactTask);
Intent intent = new Intent(
ContextUtils.getApplicationContext(), BackgroundTaskBroadcastReceiver.class)
.putExtra(BackgroundTaskSchedulerDelegate.BACKGROUND_TASK_ID_KEY,
TaskIds.TEST);
BackgroundTaskBroadcastReceiver receiver = new BackgroundTaskBroadcastReceiver();
receiver.onReceive(ContextUtils.getApplicationContext(), intent);
Assert.assertTrue(mScheduleLatch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
assertEquals(0, mStopped);
assertEquals(0, mRescheduled);
}
@Test
@Feature({"BackgroundTaskScheduler"})
public void noNetworkRequirements() throws InterruptedException {
TaskInfo.TimingInfo exactInfo =
TaskInfo.ExactInfo.create().setTriggerAtMs(System.currentTimeMillis()).build();
TaskInfo exactTask = TaskInfo.createTask(TaskIds.TEST, exactInfo)
.setRequiredNetworkType(TaskInfo.NetworkType.NONE)
.build();
BackgroundTaskSchedulerPrefs.addScheduledTask(exactTask);
Intent intent = new Intent(
ContextUtils.getApplicationContext(), BackgroundTaskBroadcastReceiver.class)
.putExtra(BackgroundTaskSchedulerDelegate.BACKGROUND_TASK_ID_KEY,
TaskIds.TEST);
BackgroundTaskBroadcastReceiver receiver = new BackgroundTaskBroadcastReceiver();
receiver.onReceive(ContextUtils.getApplicationContext(), intent);
Assert.assertTrue(mScheduleLatch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
assertEquals(0, mStopped);
assertEquals(0, mRescheduled);
}
@Test
@MinAndroidSdkLevel(Build.VERSION_CODES.L)
@Feature({"BackgroundTaskScheduler"})
public void withAnyNetworkRequired() throws InterruptedException {
mShadowConnectivityManager.setDefaultNetworkActive(true);
TaskInfo.TimingInfo exactInfo =
TaskInfo.ExactInfo.create().setTriggerAtMs(System.currentTimeMillis()).build();
TaskInfo exactTask = TaskInfo.createTask(TaskIds.TEST, exactInfo)
.setRequiredNetworkType(TaskInfo.NetworkType.ANY)
.build();
BackgroundTaskSchedulerPrefs.addScheduledTask(exactTask);
Intent intent = new Intent(
ContextUtils.getApplicationContext(), BackgroundTaskBroadcastReceiver.class)
.putExtra(BackgroundTaskSchedulerDelegate.BACKGROUND_TASK_ID_KEY,
TaskIds.TEST);
BackgroundTaskBroadcastReceiver receiver = new BackgroundTaskBroadcastReceiver();
receiver.onReceive(ContextUtils.getApplicationContext(), intent);
Assert.assertTrue(mScheduleLatch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
assertEquals(0, mStopped);
assertEquals(0, mRescheduled);
}
@Test
@MinAndroidSdkLevel(Build.VERSION_CODES.M)
@Feature({"BackgroundTaskScheduler"})
public void withAnyNetworkRequiredButNoConnectivity() throws InterruptedException {
mShadowConnectivityManager.setDefaultNetworkActive(false);
TaskInfo.TimingInfo exactInfo =
TaskInfo.ExactInfo.create().setTriggerAtMs(System.currentTimeMillis()).build();
TaskInfo exactTask = TaskInfo.createTask(TaskIds.TEST, exactInfo)
.setRequiredNetworkType(TaskInfo.NetworkType.ANY)
.build();
BackgroundTaskSchedulerPrefs.addScheduledTask(exactTask);
Intent intent = new Intent(
ContextUtils.getApplicationContext(), BackgroundTaskBroadcastReceiver.class)
.putExtra(BackgroundTaskSchedulerDelegate.BACKGROUND_TASK_ID_KEY,
TaskIds.TEST);
BackgroundTaskBroadcastReceiver receiver = new BackgroundTaskBroadcastReceiver();
receiver.onReceive(ContextUtils.getApplicationContext(), intent);
// TODO(crbug.com/1964613): Explore ways to avoid waiting for WAIT_TIME_MS here.
Assert.assertFalse(mScheduleLatch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
assertEquals(0, mStopped);
assertEquals(0, mRescheduled);
}
@Test
@Feature({"BackgroundTaskScheduler"})
public void withUnmeteredNetworkRequired() throws InterruptedException {
mShadowConnectivityManager.setActiveNetworkInfo(
mConnectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI));
TaskInfo.TimingInfo exactInfo =
TaskInfo.ExactInfo.create().setTriggerAtMs(System.currentTimeMillis()).build();
TaskInfo exactTask = TaskInfo.createTask(TaskIds.TEST, exactInfo)
.setRequiredNetworkType(TaskInfo.NetworkType.UNMETERED)
.build();
BackgroundTaskSchedulerPrefs.addScheduledTask(exactTask);
Intent intent = new Intent(
ContextUtils.getApplicationContext(), BackgroundTaskBroadcastReceiver.class)
.putExtra(BackgroundTaskSchedulerDelegate.BACKGROUND_TASK_ID_KEY,
TaskIds.TEST);
BackgroundTaskBroadcastReceiver receiver = new BackgroundTaskBroadcastReceiver();
receiver.onReceive(ContextUtils.getApplicationContext(), intent);
Assert.assertTrue(mScheduleLatch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
assertEquals(0, mStopped);
assertEquals(0, mRescheduled);
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment