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 com.android.server.job; 18 19 import static junit.framework.Assert.assertFalse; 20 import static junit.framework.Assert.assertTrue; 21 22 import static org.mockito.Mockito.doReturn; 23 import static org.mockito.Mockito.mock; 24 import static org.mockito.Mockito.when; 25 26 import android.app.ActivityManagerInternal; 27 import android.app.job.JobInfo; 28 import android.content.ComponentName; 29 import android.content.Context; 30 import android.content.pm.UserInfo; 31 import android.content.res.Resources; 32 import android.os.UserHandle; 33 34 import androidx.test.filters.SmallTest; 35 import androidx.test.runner.AndroidJUnit4; 36 37 import com.android.internal.R; 38 import com.android.server.LocalServices; 39 import com.android.server.job.JobConcurrencyManager.GracePeriodObserver; 40 import com.android.server.job.controllers.JobStatus; 41 import com.android.server.pm.UserManagerInternal; 42 43 import org.junit.AfterClass; 44 import org.junit.Before; 45 import org.junit.BeforeClass; 46 import org.junit.Test; 47 import org.junit.runner.RunWith; 48 49 @RunWith(AndroidJUnit4.class) 50 @SmallTest 51 public final class JobConcurrencyManagerTest { 52 private static final int UNAVAILABLE_USER = 0; 53 private JobConcurrencyManager mJobConcurrencyManager; 54 private UserManagerInternal mUserManagerInternal; 55 private ActivityManagerInternal mActivityManagerInternal; 56 private int mNextUserId; 57 private GracePeriodObserver mGracePeriodObserver; 58 private Context mContext; 59 private Resources mResources; 60 61 @BeforeClass setUpOnce()62 public static void setUpOnce() { 63 LocalServices.addService(UserManagerInternal.class, mock(UserManagerInternal.class)); 64 LocalServices.addService( 65 ActivityManagerInternal.class, mock(ActivityManagerInternal.class)); 66 } 67 68 @AfterClass tearDownOnce()69 public static void tearDownOnce() { 70 LocalServices.removeServiceForTest(UserManagerInternal.class); 71 LocalServices.removeServiceForTest(ActivityManagerInternal.class); 72 } 73 74 @Before setUp()75 public void setUp() { 76 final JobSchedulerService jobSchedulerService = mock(JobSchedulerService.class); 77 mContext = mock(Context.class); 78 mResources = mock(Resources.class); 79 doReturn(true).when(mResources).getBoolean( 80 R.bool.config_jobSchedulerRestrictBackgroundUser); 81 when(mContext.getResources()).thenReturn(mResources); 82 doReturn(mContext).when(jobSchedulerService).getTestableContext(); 83 mJobConcurrencyManager = new JobConcurrencyManager(jobSchedulerService); 84 mGracePeriodObserver = mock(GracePeriodObserver.class); 85 mUserManagerInternal = LocalServices.getService(UserManagerInternal.class); 86 mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class); 87 mNextUserId = 10; 88 mJobConcurrencyManager.mGracePeriodObserver = mGracePeriodObserver; 89 } 90 91 @Test testShouldRunAsFgUserJob_currentUser()92 public void testShouldRunAsFgUserJob_currentUser() { 93 assertTrue(mJobConcurrencyManager.shouldRunAsFgUserJob( 94 createJob(createCurrentUser(false)))); 95 } 96 97 @Test testShouldRunAsFgUserJob_currentProfile()98 public void testShouldRunAsFgUserJob_currentProfile() { 99 assertTrue(mJobConcurrencyManager.shouldRunAsFgUserJob( 100 createJob(createCurrentUser(true)))); 101 } 102 103 @Test testShouldRunAsFgUserJob_primaryUser()104 public void testShouldRunAsFgUserJob_primaryUser() { 105 assertTrue(mJobConcurrencyManager.shouldRunAsFgUserJob( 106 createJob(createPrimaryUser(false)))); 107 } 108 109 @Test testShouldRunAsFgUserJob_primaryProfile()110 public void testShouldRunAsFgUserJob_primaryProfile() { 111 assertTrue(mJobConcurrencyManager.shouldRunAsFgUserJob( 112 createJob(createPrimaryUser(true)))); 113 } 114 115 @Test testShouldRunAsFgUserJob_UnexpiredUser()116 public void testShouldRunAsFgUserJob_UnexpiredUser() { 117 assertTrue(mJobConcurrencyManager.shouldRunAsFgUserJob( 118 createJob(createUnexpiredUser(false)))); 119 } 120 121 @Test testShouldRunAsFgUserJob_UnexpiredProfile()122 public void testShouldRunAsFgUserJob_UnexpiredProfile() { 123 assertTrue(mJobConcurrencyManager.shouldRunAsFgUserJob( 124 createJob(createUnexpiredUser(true)))); 125 } 126 127 @Test testShouldRunAsFgUserJob_restrictedUser()128 public void testShouldRunAsFgUserJob_restrictedUser() { 129 assertFalse(mJobConcurrencyManager.shouldRunAsFgUserJob( 130 createJob(createRestrictedUser(false)))); 131 } 132 133 @Test testShouldRunAsFgUserJob_restrictedProfile()134 public void testShouldRunAsFgUserJob_restrictedProfile() { 135 assertFalse(mJobConcurrencyManager.shouldRunAsFgUserJob( 136 createJob(createRestrictedUser(true)))); 137 } 138 createCurrentUser(boolean isProfile)139 private UserInfo createCurrentUser(boolean isProfile) { 140 final UserInfo ui = createNewUser(); 141 doReturn(ui.id).when(mActivityManagerInternal).getCurrentUserId(); 142 return isProfile ? createNewProfile(ui) : ui; 143 } 144 createPrimaryUser(boolean isProfile)145 private UserInfo createPrimaryUser(boolean isProfile) { 146 final UserInfo ui = createNewUser(); 147 doReturn(true).when(ui).isPrimary(); 148 return isProfile ? createNewProfile(ui) : ui; 149 } 150 createUnexpiredUser(boolean isProfile)151 private UserInfo createUnexpiredUser(boolean isProfile) { 152 final UserInfo ui = createNewUser(); 153 doReturn(true).when(mGracePeriodObserver).isWithinGracePeriodForUser(ui.id); 154 return isProfile ? createNewProfile(ui) : ui; 155 } 156 createRestrictedUser(boolean isProfile)157 private UserInfo createRestrictedUser(boolean isProfile) { 158 final UserInfo ui = createNewUser(); 159 doReturn(UNAVAILABLE_USER).when(mActivityManagerInternal).getCurrentUserId(); 160 doReturn(false).when(ui).isPrimary(); 161 doReturn(false).when(mGracePeriodObserver).isWithinGracePeriodForUser(ui.id); 162 return isProfile ? createNewProfile(ui) : ui; 163 } 164 createNewProfile(UserInfo parent)165 private UserInfo createNewProfile(UserInfo parent) { 166 final UserInfo ui = createNewUser(); 167 parent.profileGroupId = parent.id; 168 ui.profileGroupId = parent.id; 169 doReturn(true).when(ui).isProfile(); 170 return ui; 171 } 172 createNewUser()173 private UserInfo createNewUser() { 174 final UserInfo ui = mock(UserInfo.class); 175 ui.id = mNextUserId++; 176 doReturn(ui).when(mUserManagerInternal).getUserInfo(ui.id); 177 ui.profileGroupId = UserInfo.NO_PROFILE_GROUP_ID; 178 return ui; 179 } 180 createJob(UserInfo userInfo)181 private static JobStatus createJob(UserInfo userInfo) { 182 JobStatus jobStatus = JobStatus.createFromJobInfo( 183 new JobInfo.Builder(1, new ComponentName("foo", "bar")).build(), 184 userInfo.id * UserHandle.PER_USER_RANGE, 185 null, userInfo.id, "JobConcurrencyManagerTest"); 186 return jobStatus; 187 } 188 } 189