1/*
2 * Copyright (C) 2015 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
17package com.android.server.job;
18
19import android.annotation.TargetApi;
20import android.app.job.JobInfo;
21import android.app.job.JobScheduler;
22import android.content.ComponentName;
23import android.content.Context;
24import android.test.AndroidTestCase;
25import com.android.server.job.MockPriorityJobService.TestEnvironment;
26import com.android.server.job.MockPriorityJobService.TestEnvironment.Event;
27
28import java.util.ArrayList;
29
30@TargetApi(24)
31public class PrioritySchedulingTest extends AndroidTestCase {
32    /** Environment that notifies of JobScheduler callbacks. */
33    static TestEnvironment kTestEnvironment = TestEnvironment.getTestEnvironment();
34    /** Handle for the service which receives the execution callbacks from the JobScheduler. */
35    static ComponentName kJobServiceComponent;
36    JobScheduler mJobScheduler;
37
38    @Override
39    public void setUp() throws Exception {
40        super.setUp();
41        kTestEnvironment.setUp();
42        kJobServiceComponent = new ComponentName(getContext(), MockPriorityJobService.class);
43        mJobScheduler = (JobScheduler) getContext().getSystemService(Context.JOB_SCHEDULER_SERVICE);
44        mJobScheduler.cancelAll();
45    }
46
47    @Override
48    public void tearDown() throws Exception {
49        mJobScheduler.cancelAll();
50        super.tearDown();
51    }
52
53    public void testLowerPriorityJobPreempted() throws Exception {
54        JobInfo job1 = new JobInfo.Builder(111, kJobServiceComponent)
55                .setPriority(1)
56                .setOverrideDeadline(7000L)
57                .build();
58        JobInfo job2 = new JobInfo.Builder(222, kJobServiceComponent)
59                .setPriority(1)
60                .setOverrideDeadline(7000L)
61                .build();
62        JobInfo job3 = new JobInfo.Builder(333, kJobServiceComponent)
63                .setPriority(1)
64                .setOverrideDeadline(7000L)
65                .build();
66        JobInfo job4 = new JobInfo.Builder(444, kJobServiceComponent)
67                .setPriority(2)
68                .setMinimumLatency(2000L)
69                .setOverrideDeadline(7000L)
70                .build();
71        mJobScheduler.schedule(job1);
72        mJobScheduler.schedule(job2);
73        mJobScheduler.schedule(job3);
74        mJobScheduler.schedule(job4);
75        Thread.sleep(10000);  // Wait for job 4 to preempt one of the lower priority jobs
76
77        Event job4Execution = new Event(TestEnvironment.EVENT_START_JOB, 444);
78        ArrayList<Event> executedEvents = kTestEnvironment.getExecutedEvents();
79        boolean wasJob4Executed = executedEvents.contains(job4Execution);
80        boolean wasSomeJobPreempted = false;
81        for (Event event: executedEvents) {
82            if (event.event == TestEnvironment.EVENT_PREEMPT_JOB) {
83                wasSomeJobPreempted = true;
84                break;
85            }
86        }
87        assertTrue("No job was preempted.", wasSomeJobPreempted);
88        assertTrue("Lower priority jobs were not preempted.",  wasJob4Executed);
89    }
90
91    public void testHigherPriorityJobNotPreempted() throws Exception {
92        JobInfo job1 = new JobInfo.Builder(111, kJobServiceComponent)
93                .setPriority(2)
94                .setOverrideDeadline(7000L)
95                .build();
96        JobInfo job2 = new JobInfo.Builder(222, kJobServiceComponent)
97                .setPriority(2)
98                .setOverrideDeadline(7000L)
99                .build();
100        JobInfo job3 = new JobInfo.Builder(333, kJobServiceComponent)
101                .setPriority(2)
102                .setOverrideDeadline(7000L)
103                .build();
104        JobInfo job4 = new JobInfo.Builder(444, kJobServiceComponent)
105                .setPriority(1)
106                .setMinimumLatency(2000L)
107                .setOverrideDeadline(7000L)
108                .build();
109        mJobScheduler.schedule(job1);
110        mJobScheduler.schedule(job2);
111        mJobScheduler.schedule(job3);
112        mJobScheduler.schedule(job4);
113        Thread.sleep(10000);  // Wait for job 4 to preempt one of the higher priority jobs
114
115        Event job4Execution = new Event(TestEnvironment.EVENT_START_JOB, 444);
116        boolean wasJob4Executed = kTestEnvironment.getExecutedEvents().contains(job4Execution);
117        assertFalse("Higher priority job was preempted.", wasJob4Executed);
118    }
119}
120