1 /* 2 * Copyright (C) 2018 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 android.annotation.TargetApi; 20 import android.app.job.JobInfo; 21 import android.support.test.InstrumentationRegistry; 22 import android.support.test.uiautomator.UiDevice; 23 24 /** 25 * Make sure the state of {@link android.app.job.JobScheduler} is correct. 26 */ 27 @TargetApi(28) 28 public class DeviceStatesTest extends ConstraintTest { 29 /** Unique identifier for the job scheduled by this suite of tests. */ 30 public static final int STATE_JOB_ID = DeviceStatesTest.class.hashCode(); 31 32 private JobInfo.Builder mBuilder; 33 private UiDevice mUiDevice; 34 35 @Override 36 public void setUp() throws Exception { 37 super.setUp(); 38 mBuilder = new JobInfo.Builder(STATE_JOB_ID, kJobServiceComponent); 39 mUiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()); 40 } 41 42 @Override 43 public void tearDown() throws Exception { 44 mJobScheduler.cancel(STATE_JOB_ID); 45 // Put device back in to normal operation. 46 toggleScreenOn(true /* screen on */); 47 } 48 49 void assertJobReady() throws Exception { 50 assertJobReady(STATE_JOB_ID); 51 } 52 53 void assertJobWaiting() throws Exception { 54 assertJobWaiting(STATE_JOB_ID); 55 } 56 57 void assertJobNotReady() throws Exception { 58 assertJobNotReady(STATE_JOB_ID); 59 } 60 61 /** 62 * Toggle device is dock idle or dock active. 63 */ 64 private void toggleFakeDeviceDockState(final boolean idle) throws Exception { 65 mUiDevice.executeShellCommand("cmd jobscheduler trigger-dock-state " 66 + (idle ? "idle" : "active")); 67 } 68 69 /** 70 * Make sure the screen state. 71 */ 72 private void toggleScreenOn(final boolean screenon) throws Exception { 73 if (screenon) { 74 mUiDevice.wakeUp(); 75 } else { 76 mUiDevice.sleep(); 77 } 78 // Since the screen on/off intent is ordered, they will not be sent right now. 79 Thread.sleep(3000); 80 } 81 82 /** 83 * Simulated for idle, and then perform idle maintenance now. 84 */ 85 private void triggerIdleMaintenance() throws Exception { 86 mUiDevice.executeShellCommand("cmd activity idle-maintenance"); 87 } 88 89 /** 90 * Schedule a job that requires the device is idle, and assert it fired to make 91 * sure the device is idle. 92 */ 93 void verifyIdleState() throws Exception { 94 kTestEnvironment.setExpectedExecutions(1); 95 kTestEnvironment.setExpectedWaitForRun(); 96 mJobScheduler.schedule(mBuilder.setRequiresDeviceIdle(true).build()); 97 assertJobReady(); 98 kTestEnvironment.readyToRun(); 99 100 assertTrue("Job with idle constraint did not fire on idle", 101 kTestEnvironment.awaitExecution()); 102 } 103 104 /** 105 * Schedule a job that requires the device is idle, and assert it failed to make 106 * sure the device is active. 107 */ 108 void verifyActiveState() throws Exception { 109 kTestEnvironment.setExpectedExecutions(0); 110 kTestEnvironment.setExpectedWaitForRun(); 111 mJobScheduler.schedule(mBuilder.setRequiresDeviceIdle(true).build()); 112 assertJobWaiting(); 113 assertJobNotReady(); 114 kTestEnvironment.readyToRun(); 115 116 assertFalse("Job with idle constraint fired while not on idle.", 117 kTestEnvironment.awaitExecution(250)); 118 } 119 120 /** 121 * Ensure that device can switch state normally. 122 */ 123 public void testDeviceChangeIdleActiveState() throws Exception { 124 toggleScreenOn(true /* screen on */); 125 verifyActiveState(); 126 127 // Assert device is idle when screen is off for a while. 128 toggleScreenOn(false /* screen off */); 129 triggerIdleMaintenance(); 130 verifyIdleState(); 131 132 // Assert device is back to active when screen is on. 133 toggleScreenOn(true /* screen on */); 134 verifyActiveState(); 135 } 136 137 /** 138 * Ensure that device can switch state on dock normally. 139 */ 140 public void testScreenOnDeviceOnDockChangeState() throws Exception { 141 toggleScreenOn(true /* screen on */); 142 verifyActiveState(); 143 144 // Assert device go to idle if user doesn't interact with device for a while. 145 toggleFakeDeviceDockState(true /* idle */); 146 triggerIdleMaintenance(); 147 verifyIdleState(); 148 149 // Assert device go back to active if user interacts with device. 150 toggleFakeDeviceDockState(false /* active */); 151 verifyActiveState(); 152 } 153 154 /** 155 * Ensure that ignores this dock intent during screen off. 156 */ 157 public void testScreenOffDeviceOnDockNoChangeState() throws Exception { 158 toggleScreenOn(false /* screen off */); 159 triggerIdleMaintenance(); 160 verifyIdleState(); 161 162 toggleFakeDeviceDockState(false /* active */); 163 verifyIdleState(); 164 } 165 } 166