1 /*
2  * Copyright (C) 2021 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 android.jobscheduler.cts;
18 
19 import static android.jobscheduler.cts.JobThrottlingTest.setTestPackageStandbyBucket;
20 import static android.jobscheduler.cts.TestAppInterface.TEST_APP_PACKAGE;
21 
22 import static org.junit.Assert.assertTrue;
23 
24 import android.app.ActivityManager;
25 import android.app.AppOpsManager;
26 import android.content.Context;
27 import android.jobscheduler.cts.jobtestapp.TestJobSchedulerReceiver;
28 import android.os.SystemClock;
29 import android.os.UserHandle;
30 import android.support.test.uiautomator.UiDevice;
31 
32 import androidx.test.InstrumentationRegistry;
33 import androidx.test.runner.AndroidJUnit4;
34 
35 import com.android.compatibility.common.util.AppOpsUtils;
36 
37 import org.junit.After;
38 import org.junit.Before;
39 import org.junit.Test;
40 import org.junit.runner.RunWith;
41 
42 import java.util.Collections;
43 import java.util.Map;
44 
45 @RunWith(AndroidJUnit4.class)
46 public class ExpeditedJobTest {
47     private static final long DEFAULT_WAIT_TIMEOUT_MS = 2_000;
48     private static final String APP_OP_GET_USAGE_STATS = "android:get_usage_stats";
49 
50     private Context mContext;
51     private UiDevice mUiDevice;
52     private int mTestJobId;
53     private TestAppInterface mTestAppInterface;
54 
55     @Before
setUp()56     public void setUp() throws Exception {
57         mContext = InstrumentationRegistry.getTargetContext();
58         mUiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
59         mTestJobId = (int) (SystemClock.uptimeMillis() / 1000);
60         mTestAppInterface = new TestAppInterface(mContext, mTestJobId);
61         setTestPackageStandbyBucket(mUiDevice, JobThrottlingTest.Bucket.ACTIVE);
62         AppOpsUtils.setOpMode(TEST_APP_PACKAGE, APP_OP_GET_USAGE_STATS,
63                 AppOpsManager.MODE_ALLOWED);
64     }
65 
66     @After
tearDown()67     public void tearDown() throws Exception {
68         mTestAppInterface.cleanup();
69         AppOpsUtils.reset(TEST_APP_PACKAGE);
70     }
71 
72     @Test
testJobUidState()73     public void testJobUidState() throws Exception {
74         mTestAppInterface.scheduleJob(Map.of(
75                 TestJobSchedulerReceiver.EXTRA_AS_EXPEDITED, true,
76                 TestJobSchedulerReceiver.EXTRA_REQUEST_JOB_UID_STATE, true
77         ), Collections.emptyMap());
78         forceRunJob();
79         assertTrue("Job did not start after scheduling",
80                 mTestAppInterface.awaitJobStart(DEFAULT_WAIT_TIMEOUT_MS));
81         mTestAppInterface.assertJobUidState(ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND,
82                 ActivityManager.PROCESS_CAPABILITY_NETWORK,
83                 225 /* ProcessList.PERCEPTIBLE_MEDIUM_APP_ADJ */);
84     }
85 
86     /** Forces JobScheduler to run the job */
forceRunJob()87     private void forceRunJob() throws Exception {
88         mUiDevice.executeShellCommand("cmd jobscheduler run -f"
89                 + " -u " + UserHandle.myUserId() + " " + TEST_APP_PACKAGE + " " + mTestJobId);
90     }
91 }
92