Merge "Jobs in 'active' apps are not subject to standby" into pi-dev am: 2d157b1bcc

am: 5ed3266401

Change-Id: I3627a1ae7f99f820aab9c6a112d3b7e4b39ea9bc
This commit is contained in:
Christopher Tate
2018-03-09 22:35:19 +00:00
committed by android-build-merger
7 changed files with 139 additions and 321 deletions

View File

@@ -614,7 +614,6 @@ message JobStatusDumpProto {
CONSTRAINT_DEADLINE = 5;
CONSTRAINT_IDLE = 6;
CONSTRAINT_CONNECTIVITY = 7;
CONSTRAINT_APP_NOT_IDLE = 8;
CONSTRAINT_CONTENT_TRIGGER = 9;
CONSTRAINT_DEVICE_NOT_DOZING = 10;
}

View File

@@ -258,7 +258,7 @@ public class AppStateTracker {
*/
private void onRunAnyAppOpsChanged(AppStateTracker sender,
int uid, @NonNull String packageName) {
updateJobsForUidPackage(uid, packageName);
updateJobsForUidPackage(uid, packageName, sender.isUidActive(uid));
if (!sender.areAlarmsRestricted(uid, packageName, /*allowWhileIdle=*/ false)) {
unblockAlarmsForUidPackage(uid, packageName);
@@ -279,9 +279,11 @@ public class AppStateTracker {
* This is called when the active/idle state changed for a UID.
*/
private void onUidActiveStateChanged(AppStateTracker sender, int uid) {
updateJobsForUid(uid);
final boolean isActive = sender.isUidActive(uid);
if (sender.isUidActive(uid)) {
updateJobsForUid(uid, isActive);
if (isActive) {
unblockAlarmsForUid(uid);
}
}
@@ -346,14 +348,14 @@ public class AppStateTracker {
* Called when the job restrictions for a UID might have changed, so the job
* scheduler should re-evaluate all restrictions for all jobs.
*/
public void updateJobsForUid(int uid) {
public void updateJobsForUid(int uid, boolean isNowActive) {
}
/**
* Called when the job restrictions for a UID - package might have changed, so the job
* scheduler should re-evaluate all restrictions for all jobs.
*/
public void updateJobsForUidPackage(int uid, String packageName) {
public void updateJobsForUidPackage(int uid, String packageName, boolean isNowActive) {
}
/**

View File

@@ -88,7 +88,6 @@ import com.android.server.LocalServices;
import com.android.server.job.JobSchedulerServiceDumpProto.ActiveJob;
import com.android.server.job.JobSchedulerServiceDumpProto.PendingJob;
import com.android.server.job.JobSchedulerServiceDumpProto.RegisteredJob;
import com.android.server.job.controllers.AppIdleController;
import com.android.server.job.controllers.BackgroundJobsController;
import com.android.server.job.controllers.BatteryController;
import com.android.server.job.controllers.ConnectivityController;
@@ -1051,7 +1050,8 @@ public final class JobSchedulerService extends com.android.server.SystemService
final JobStatus job = jsc.getRunningJobLocked();
if (job != null
&& (job.getJob().getFlags() & JobInfo.FLAG_WILL_BE_FOREGROUND) == 0
&& !job.dozeWhitelisted) {
&& !job.dozeWhitelisted
&& !job.uidActive) {
// We will report active if we have a job running and it is not an exception
// due to being in the foreground or whitelisted.
active = true;
@@ -1115,7 +1115,6 @@ public final class JobSchedulerService extends com.android.server.SystemService
mStorageController = new StorageController(this);
mControllers.add(mStorageController);
mControllers.add(new BackgroundJobsController(this));
mControllers.add(new AppIdleController(this));
mControllers.add(new ContentObserverController(this));
mDeviceIdleJobsController = new DeviceIdleJobsController(this);
mControllers.add(mDeviceIdleJobsController);
@@ -1867,6 +1866,9 @@ public final class JobSchedulerService extends com.android.server.SystemService
// scheduled are sitting there, not ready yet) and very cheap to check (just
// a few conditions on data in JobStatus).
if (!jobReady) {
if (job.getSourcePackageName().equals("android.jobscheduler.cts.jobtestapp")) {
Slog.v(TAG, " NOT READY: " + job);
}
return false;
}
@@ -1905,9 +1907,21 @@ public final class JobSchedulerService extends com.android.server.SystemService
// an appropriate amount of time since the last invocation. During device-
// wide parole, standby bucketing is ignored.
//
// But if a job has FLAG_EXEMPT_FROM_APP_STANDBY, don't check it.
if (!mInParole && !job.getJob().isExemptedFromAppStandby()) {
// Jobs in 'active' apps are not subject to standby, nor are jobs that are
// specifically marked as exempt.
if (DEBUG_STANDBY) {
Slog.v(TAG, "isReadyToBeExecutedLocked: " + job.toShortString()
+ " parole=" + mInParole + " active=" + job.uidActive
+ " exempt=" + job.getJob().isExemptedFromAppStandby());
}
if (!mInParole
&& !job.uidActive
&& !job.getJob().isExemptedFromAppStandby()) {
final int bucket = job.getStandbyBucket();
if (DEBUG_STANDBY) {
Slog.v(TAG, " bucket=" + bucket + " heartbeat=" + mHeartbeat
+ " next=" + mNextBucketHeartbeat[bucket]);
}
if (mHeartbeat < mNextBucketHeartbeat[bucket]) {
// Only skip this job if the app is still waiting for the end of its nominal
// bucket interval. Once it's waited that long, we let it go ahead and clear.

View File

@@ -1,216 +0,0 @@
/*
* Copyright (C) 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License
*/
package com.android.server.job.controllers;
import android.app.usage.UsageStatsManagerInternal;
import android.os.UserHandle;
import android.util.Log;
import android.util.Slog;
import android.util.proto.ProtoOutputStream;
import com.android.internal.util.IndentingPrintWriter;
import com.android.server.LocalServices;
import com.android.server.job.JobSchedulerService;
import com.android.server.job.StateControllerProto;
import java.util.function.Consumer;
import java.util.function.Predicate;
/**
* Controls when apps are considered idle and if jobs pertaining to those apps should
* be executed. Apps that haven't been actively launched or accessed from a foreground app
* for a certain amount of time (maybe hours or days) are considered idle. When the app comes
* out of idle state, it will be allowed to run scheduled jobs.
*/
public final class AppIdleController extends StateController {
private static final String TAG = "JobScheduler.AppIdle";
private static final boolean DEBUG = JobSchedulerService.DEBUG
|| Log.isLoggable(TAG, Log.DEBUG);
private final UsageStatsManagerInternal mUsageStatsInternal;
private boolean mInitializedParoleOn;
boolean mAppIdleParoleOn;
final class GlobalUpdateFunc implements Consumer<JobStatus> {
boolean mChanged;
@Override
public void accept(JobStatus jobStatus) {
String packageName = jobStatus.getSourcePackageName();
final boolean appIdle = !mAppIdleParoleOn && mUsageStatsInternal.isAppIdle(packageName,
jobStatus.getSourceUid(), jobStatus.getSourceUserId());
if (DEBUG) {
Slog.d(TAG, "Setting idle state of " + packageName + " to " + appIdle);
}
if (jobStatus.setAppNotIdleConstraintSatisfied(!appIdle)) {
mChanged = true;
}
}
}
final static class PackageUpdateFunc implements Consumer<JobStatus> {
final int mUserId;
final String mPackage;
final boolean mIdle;
boolean mChanged;
PackageUpdateFunc(int userId, String pkg, boolean idle) {
mUserId = userId;
mPackage = pkg;
mIdle = idle;
}
@Override
public void accept(JobStatus jobStatus) {
if (jobStatus.getSourcePackageName().equals(mPackage)
&& jobStatus.getSourceUserId() == mUserId) {
if (jobStatus.setAppNotIdleConstraintSatisfied(!mIdle)) {
if (DEBUG) {
Slog.d(TAG, "App Idle state changed, setting idle state of "
+ mPackage + " to " + mIdle);
}
mChanged = true;
}
}
}
}
public AppIdleController(JobSchedulerService service) {
super(service);
mUsageStatsInternal = LocalServices.getService(UsageStatsManagerInternal.class);
mAppIdleParoleOn = true;
mUsageStatsInternal.addAppIdleStateChangeListener(new AppIdleStateChangeListener());
}
@Override
public void maybeStartTrackingJobLocked(JobStatus jobStatus, JobStatus lastJob) {
if (!mInitializedParoleOn) {
mInitializedParoleOn = true;
mAppIdleParoleOn = mUsageStatsInternal.isAppIdleParoleOn();
}
String packageName = jobStatus.getSourcePackageName();
final boolean appIdle = !mAppIdleParoleOn && mUsageStatsInternal.isAppIdle(packageName,
jobStatus.getSourceUid(), jobStatus.getSourceUserId());
if (DEBUG) {
Slog.d(TAG, "Start tracking, setting idle state of "
+ packageName + " to " + appIdle);
}
jobStatus.setAppNotIdleConstraintSatisfied(!appIdle);
}
@Override
public void maybeStopTrackingJobLocked(JobStatus jobStatus, JobStatus incomingJob,
boolean forUpdate) {
}
@Override
public void dumpControllerStateLocked(final IndentingPrintWriter pw,
final Predicate<JobStatus> predicate) {
pw.println("Parole on: " + mAppIdleParoleOn);
pw.println();
mService.getJobStore().forEachJob(predicate, (jobStatus) -> {
pw.print("#");
jobStatus.printUniqueId(pw);
pw.print(" from ");
UserHandle.formatUid(pw, jobStatus.getSourceUid());
pw.print(": ");
pw.print(jobStatus.getSourcePackageName());
if ((jobStatus.satisfiedConstraints&JobStatus.CONSTRAINT_APP_NOT_IDLE) != 0) {
pw.println(" RUNNABLE");
} else {
pw.println(" WAITING");
}
});
}
@Override
public void dumpControllerStateLocked(ProtoOutputStream proto, long fieldId,
Predicate<JobStatus> predicate) {
final long token = proto.start(fieldId);
final long mToken = proto.start(StateControllerProto.APP_IDLE);
proto.write(StateControllerProto.AppIdleController.IS_PAROLE_ON, mAppIdleParoleOn);
mService.getJobStore().forEachJob(predicate, (js) -> {
final long jsToken =
proto.start(StateControllerProto.AppIdleController.TRACKED_JOBS);
js.writeToShortProto(proto, StateControllerProto.AppIdleController.TrackedJob.INFO);
proto.write(StateControllerProto.AppIdleController.TrackedJob.SOURCE_UID,
js.getSourceUid());
proto.write(StateControllerProto.AppIdleController.TrackedJob.SOURCE_PACKAGE_NAME,
js.getSourcePackageName());
proto.write(
StateControllerProto.AppIdleController.TrackedJob.ARE_CONSTRAINTS_SATISFIED,
(js.satisfiedConstraints & JobStatus.CONSTRAINT_APP_NOT_IDLE) != 0);
proto.end(jsToken);
});
proto.end(mToken);
proto.end(token);
}
void setAppIdleParoleOn(boolean isAppIdleParoleOn) {
// Flag if any app's idle state has changed
boolean changed = false;
synchronized (mLock) {
if (mAppIdleParoleOn == isAppIdleParoleOn) {
return;
}
mAppIdleParoleOn = isAppIdleParoleOn;
GlobalUpdateFunc update = new GlobalUpdateFunc();
mService.getJobStore().forEachJob(update);
if (update.mChanged) {
changed = true;
}
}
if (changed) {
mStateChangedListener.onControllerStateChanged();
}
}
private final class AppIdleStateChangeListener
extends UsageStatsManagerInternal.AppIdleStateChangeListener {
@Override
public void onAppIdleStateChanged(String packageName, int userId, boolean idle, int bucket,
int reason) {
boolean changed = false;
synchronized (mLock) {
if (mAppIdleParoleOn) {
return;
}
PackageUpdateFunc update = new PackageUpdateFunc(userId, packageName, idle);
mService.getJobStore().forEachJob(update);
if (update.mChanged) {
changed = true;
}
}
if (changed) {
mStateChangedListener.onControllerStateChanged();
}
}
@Override
public void onParoleStateChanged(boolean isParoleOn) {
if (DEBUG) {
Slog.d(TAG, "Parole on: " + isParoleOn);
}
setAppIdleParoleOn(isParoleOn);
}
}
}

View File

@@ -28,17 +28,32 @@ import com.android.server.AppStateTracker;
import com.android.server.AppStateTracker.Listener;
import com.android.server.LocalServices;
import com.android.server.job.JobSchedulerService;
import com.android.server.job.JobStore;
import com.android.server.job.StateControllerProto;
import com.android.server.job.StateControllerProto.BackgroundJobsController.TrackedJob;
import java.util.function.Consumer;
import java.util.function.Predicate;
/**
* Tracks the following pieces of JobStatus state:
*
* - the CONSTRAINT_BACKGROUND_NOT_RESTRICTED general constraint bit, which
* is used to selectively permit battery-saver exempted jobs to run; and
*
* - the uid-active boolean state expressed by the AppStateTracker. Jobs in 'active'
* uids are inherently eligible to run jobs regardless of the uid's standby bucket.
*/
public final class BackgroundJobsController extends StateController {
private static final String TAG = "JobScheduler.Background";
private static final boolean DEBUG = JobSchedulerService.DEBUG
|| Log.isLoggable(TAG, Log.DEBUG);
// Tri-state about possible "is this uid 'active'?" knowledge
static final int UNKNOWN = 0;
static final int KNOWN_ACTIVE = 1;
static final int KNOWN_INACTIVE = 2;
private final AppStateTracker mAppStateTracker;
public BackgroundJobsController(JobSchedulerService service) {
@@ -51,7 +66,7 @@ public final class BackgroundJobsController extends StateController {
@Override
public void maybeStartTrackingJobLocked(JobStatus jobStatus, JobStatus lastJob) {
updateSingleJobRestrictionLocked(jobStatus);
updateSingleJobRestrictionLocked(jobStatus, UNKNOWN);
}
@Override
@@ -137,23 +152,24 @@ public final class BackgroundJobsController extends StateController {
}
private void updateAllJobRestrictionsLocked() {
updateJobRestrictionsLocked(/*filterUid=*/ -1);
updateJobRestrictionsLocked(/*filterUid=*/ -1, UNKNOWN);
}
private void updateJobRestrictionsForUidLocked(int uid) {
// TODO Use forEachJobForSourceUid() once we have it.
updateJobRestrictionsLocked(/*filterUid=*/ uid);
private void updateJobRestrictionsForUidLocked(int uid, boolean isActive) {
updateJobRestrictionsLocked(uid, (isActive) ? KNOWN_ACTIVE : KNOWN_INACTIVE);
}
private void updateJobRestrictionsLocked(int filterUid) {
final UpdateJobFunctor updateTrackedJobs =
new UpdateJobFunctor(filterUid);
private void updateJobRestrictionsLocked(int filterUid, int newActiveState) {
final UpdateJobFunctor updateTrackedJobs = new UpdateJobFunctor(newActiveState);
final long start = DEBUG ? SystemClock.elapsedRealtimeNanos() : 0;
mService.getJobStore().forEachJob(updateTrackedJobs);
final JobStore store = mService.getJobStore();
if (filterUid > 0) {
store.forEachJobForSourceUid(filterUid, updateTrackedJobs);
} else {
store.forEachJob(updateTrackedJobs);
}
final long time = DEBUG ? (SystemClock.elapsedRealtimeNanos() - start) : 0;
if (DEBUG) {
@@ -170,7 +186,7 @@ public final class BackgroundJobsController extends StateController {
}
}
boolean updateSingleJobRestrictionLocked(JobStatus jobStatus) {
boolean updateSingleJobRestrictionLocked(JobStatus jobStatus, int activeState) {
final int uid = jobStatus.getSourceUid();
final String packageName = jobStatus.getSourcePackageName();
@@ -179,28 +195,32 @@ public final class BackgroundJobsController extends StateController {
(jobStatus.getInternalFlags() & JobStatus.INTERNAL_FLAG_HAS_FOREGROUND_EXEMPTION)
!= 0);
return jobStatus.setBackgroundNotRestrictedConstraintSatisfied(canRun);
final boolean isActive;
if (activeState == UNKNOWN) {
isActive = mAppStateTracker.isUidActive(uid);
} else {
isActive = (activeState == KNOWN_ACTIVE);
}
boolean didChange = jobStatus.setBackgroundNotRestrictedConstraintSatisfied(canRun);
didChange |= jobStatus.setUidActive(isActive);
return didChange;
}
private final class UpdateJobFunctor implements Consumer<JobStatus> {
private final int mFilterUid;
final int activeState;
boolean mChanged = false;
int mTotalCount = 0;
int mCheckedCount = 0;
UpdateJobFunctor(int filterUid) {
mFilterUid = filterUid;
public UpdateJobFunctor(int newActiveState) {
activeState = newActiveState;
}
@Override
public void accept(JobStatus jobStatus) {
mTotalCount++;
if ((mFilterUid > 0) && (mFilterUid != jobStatus.getSourceUid())) {
return;
}
mCheckedCount++;
if (updateSingleJobRestrictionLocked(jobStatus)) {
if (updateSingleJobRestrictionLocked(jobStatus, activeState)) {
mChanged = true;
}
}
@@ -215,16 +235,16 @@ public final class BackgroundJobsController extends StateController {
}
@Override
public void updateJobsForUid(int uid) {
public void updateJobsForUid(int uid, boolean isActive) {
synchronized (mLock) {
updateJobRestrictionsForUidLocked(uid);
updateJobRestrictionsForUidLocked(uid, isActive);
}
}
@Override
public void updateJobsForUidPackage(int uid, String packageName) {
public void updateJobsForUidPackage(int uid, String packageName, boolean isActive) {
synchronized (mLock) {
updateJobRestrictionsForUidLocked(uid);
updateJobRestrictionsForUidLocked(uid, isActive);
}
}
};

View File

@@ -73,7 +73,6 @@ public final class JobStatus {
static final int CONSTRAINT_TIMING_DELAY = 1<<31;
static final int CONSTRAINT_DEADLINE = 1<<30;
static final int CONSTRAINT_CONNECTIVITY = 1<<28;
static final int CONSTRAINT_APP_NOT_IDLE = 1<<27;
static final int CONSTRAINT_CONTENT_TRIGGER = 1<<26;
static final int CONSTRAINT_DEVICE_NOT_DOZING = 1<<25;
static final int CONSTRAINT_BACKGROUND_NOT_RESTRICTED = 1<<22;
@@ -153,6 +152,9 @@ public final class JobStatus {
// Set to true if doze constraint was satisfied due to app being whitelisted.
public boolean dozeWhitelisted;
// Set to true when the app is "active" per AppStateTracker
public boolean uidActive;
/**
* Flag for {@link #trackingControllers}: the battery controller is currently tracking this job.
*/
@@ -838,10 +840,6 @@ public final class JobStatus {
return setConstraintSatisfied(CONSTRAINT_CONNECTIVITY, state);
}
boolean setAppNotIdleConstraintSatisfied(boolean state) {
return setConstraintSatisfied(CONSTRAINT_APP_NOT_IDLE, state);
}
boolean setContentTriggerConstraintSatisfied(boolean state) {
return setConstraintSatisfied(CONSTRAINT_CONTENT_TRIGGER, state);
}
@@ -855,6 +853,14 @@ public final class JobStatus {
return setConstraintSatisfied(CONSTRAINT_BACKGROUND_NOT_RESTRICTED, state);
}
boolean setUidActive(final boolean newActiveState) {
if (newActiveState != uidActive) {
uidActive = newActiveState;
return true;
}
return false; /* unchanged */
}
boolean setConstraintSatisfied(int constraint, boolean state) {
boolean old = (satisfiedConstraints&constraint) != 0;
if (old == state) {
@@ -904,13 +910,11 @@ public final class JobStatus {
// NotRestrictedInBackground implicit constraint must be satisfied
final boolean deadlineSatisfied = (!job.isPeriodic() && hasDeadlineConstraint()
&& (satisfiedConstraints & CONSTRAINT_DEADLINE) != 0);
final boolean notIdle = (satisfiedConstraints & CONSTRAINT_APP_NOT_IDLE) != 0;
final boolean notDozing = (satisfiedConstraints & CONSTRAINT_DEVICE_NOT_DOZING) != 0
|| (job.getFlags() & JobInfo.FLAG_WILL_BE_FOREGROUND) != 0;
final boolean notRestrictedInBg =
(satisfiedConstraints & CONSTRAINT_BACKGROUND_NOT_RESTRICTED) != 0;
return (isConstraintsSatisfied() || deadlineSatisfied) && notIdle && notDozing
&& notRestrictedInBg;
return (isConstraintsSatisfied() || deadlineSatisfied) && notDozing && notRestrictedInBg;
}
static final int CONSTRAINTS_OF_INTEREST = CONSTRAINT_CHARGING | CONSTRAINT_BATTERY_NOT_LOW
@@ -990,9 +994,6 @@ public final class JobStatus {
if (job.isPersisted()) {
sb.append(" PERSISTED");
}
if ((satisfiedConstraints&CONSTRAINT_APP_NOT_IDLE) == 0) {
sb.append(" WAIT:APP_NOT_IDLE");
}
if ((satisfiedConstraints&CONSTRAINT_DEVICE_NOT_DOZING) == 0) {
sb.append(" WAIT:DEV_NOT_DOZING");
}
@@ -1091,9 +1092,6 @@ public final class JobStatus {
if ((constraints&CONSTRAINT_CONNECTIVITY) != 0) {
pw.print(" CONNECTIVITY");
}
if ((constraints&CONSTRAINT_APP_NOT_IDLE) != 0) {
pw.print(" APP_NOT_IDLE");
}
if ((constraints&CONSTRAINT_CONTENT_TRIGGER) != 0) {
pw.print(" CONTENT_TRIGGER");
}
@@ -1133,9 +1131,6 @@ public final class JobStatus {
if ((constraints & CONSTRAINT_CONNECTIVITY) != 0) {
proto.write(fieldId, JobStatusDumpProto.CONSTRAINT_CONNECTIVITY);
}
if ((constraints & CONSTRAINT_APP_NOT_IDLE) != 0) {
proto.write(fieldId, JobStatusDumpProto.CONSTRAINT_APP_NOT_IDLE);
}
if ((constraints & CONSTRAINT_CONTENT_TRIGGER) != 0) {
proto.write(fieldId, JobStatusDumpProto.CONSTRAINT_CONTENT_TRIGGER);
}
@@ -1307,6 +1302,9 @@ public final class JobStatus {
if (dozeWhitelisted) {
pw.print(prefix); pw.println("Doze whitelisted: true");
}
if (uidActive) {
pw.print(prefix); pw.println("Uid: active");
}
}
if (trackingControllers != 0) {
pw.print(prefix); pw.print("Tracking:");

View File

@@ -25,6 +25,7 @@ import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
@@ -729,8 +730,8 @@ public class AppStateTrackerTest {
private void assertNoCallbacks(Listener l) throws Exception {
waitUntilMainHandlerDrain();
verify(l, times(0)).updateAllJobs();
verify(l, times(0)).updateJobsForUid(anyInt());
verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());
verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean());
verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
verify(l, times(0)).unblockAllUnrestrictedAlarms();
verify(l, times(0)).unblockAlarmsForUid(anyInt());
@@ -752,8 +753,8 @@ public class AppStateTrackerTest {
waitUntilMainHandlerDrain();
verify(l, times(1)).updateAllJobs();
verify(l, times(0)).updateJobsForUid(anyInt());
verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());
verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean());
verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
verify(l, times(0)).unblockAllUnrestrictedAlarms();
verify(l, times(0)).unblockAlarmsForUid(anyInt());
@@ -766,8 +767,8 @@ public class AppStateTrackerTest {
waitUntilMainHandlerDrain();
verify(l, times(1)).updateAllJobs();
verify(l, times(0)).updateJobsForUid(anyInt());
verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());
verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean());
verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
verify(l, times(1)).unblockAllUnrestrictedAlarms();
verify(l, times(0)).unblockAlarmsForUid(anyInt());
@@ -796,8 +797,8 @@ public class AppStateTrackerTest {
waitUntilMainHandlerDrain();
verify(l, times(0)).updateAllJobs();
verify(l, times(0)).updateJobsForUid(anyInt());
verify(l, times(1)).updateJobsForUidPackage(eq(UID_10_2), eq(PACKAGE_2));
verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean());
verify(l, times(1)).updateJobsForUidPackage(eq(UID_10_2), eq(PACKAGE_2), anyBoolean());
verify(l, times(0)).unblockAllUnrestrictedAlarms();
verify(l, times(0)).unblockAlarmsForUid(anyInt());
@@ -808,8 +809,8 @@ public class AppStateTrackerTest {
waitUntilMainHandlerDrain();
verify(l, times(0)).updateAllJobs();
verify(l, times(0)).updateJobsForUid(anyInt());
verify(l, times(1)).updateJobsForUidPackage(eq(UID_10_2), eq(PACKAGE_2));
verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean());
verify(l, times(1)).updateJobsForUidPackage(eq(UID_10_2), eq(PACKAGE_2), anyBoolean());
verify(l, times(0)).unblockAllUnrestrictedAlarms();
verify(l, times(0)).unblockAlarmsForUid(anyInt());
@@ -819,8 +820,8 @@ public class AppStateTrackerTest {
setAppOps(UID_10_2, PACKAGE_2, false);
verify(l, times(0)).updateAllJobs();
verify(l, times(0)).updateJobsForUid(anyInt());
verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());
verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean());
verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
verify(l, times(0)).unblockAllUnrestrictedAlarms();
verify(l, times(0)).unblockAlarmsForUid(anyInt());
@@ -835,8 +836,8 @@ public class AppStateTrackerTest {
waitUntilMainHandlerDrain();
verify(l, times(1)).updateAllJobs();
verify(l, times(0)).updateJobsForUid(anyInt());
verify(l, times(1)).updateJobsForUidPackage(eq(UID_10_2), eq(PACKAGE_2));
verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean());
verify(l, times(1)).updateJobsForUidPackage(eq(UID_10_2), eq(PACKAGE_2), anyBoolean());
verify(l, times(0)).unblockAllUnrestrictedAlarms();
verify(l, times(0)).unblockAlarmsForUid(anyInt());
@@ -849,8 +850,8 @@ public class AppStateTrackerTest {
waitUntilMainHandlerDrain();
verify(l, times(1)).updateAllJobs();
verify(l, times(0)).updateJobsForUid(anyInt());
verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());
verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean());
verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
verify(l, times(1)).unblockAllUnrestrictedAlarms();
verify(l, times(0)).unblockAlarmsForUid(anyInt());
@@ -864,8 +865,8 @@ public class AppStateTrackerTest {
waitUntilMainHandlerDrain();
verify(l, times(1)).updateAllJobs();
verify(l, times(0)).updateJobsForUid(anyInt());
verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());
verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean());
verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
verify(l, times(0)).unblockAllUnrestrictedAlarms();
verify(l, times(0)).unblockAlarmsForUid(anyInt());
@@ -876,8 +877,8 @@ public class AppStateTrackerTest {
waitUntilMainHandlerDrain();
verify(l, times(1)).updateAllJobs();
verify(l, times(0)).updateJobsForUid(anyInt());
verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());
verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean());
verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
verify(l, times(1)).unblockAllUnrestrictedAlarms();
verify(l, times(0)).unblockAlarmsForUid(anyInt());
@@ -889,8 +890,8 @@ public class AppStateTrackerTest {
waitUntilMainHandlerDrain();
verify(l, times(1)).updateAllJobs();
verify(l, times(0)).updateJobsForUid(anyInt());
verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());
verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean());
verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
verify(l, times(0)).unblockAllUnrestrictedAlarms();
verify(l, times(0)).unblockAlarmsForUid(anyInt());
@@ -901,8 +902,8 @@ public class AppStateTrackerTest {
waitUntilMainHandlerDrain();
verify(l, times(1)).updateAllJobs();
verify(l, times(0)).updateJobsForUid(anyInt());
verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());
verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean());
verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
verify(l, times(0)).unblockAllUnrestrictedAlarms();
verify(l, times(0)).unblockAlarmsForUid(anyInt());
@@ -915,8 +916,8 @@ public class AppStateTrackerTest {
waitUntilMainHandlerDrain();
verify(l, times(1)).updateAllJobs();
verify(l, times(0)).updateJobsForUid(anyInt());
verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());
verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean());
verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
verify(l, times(0)).unblockAllUnrestrictedAlarms();
verify(l, times(0)).unblockAlarmsForUid(anyInt());
@@ -928,8 +929,8 @@ public class AppStateTrackerTest {
waitUntilMainHandlerDrain();
// Called once for updating all whitelist and once for updating temp whitelist
verify(l, times(2)).updateAllJobs();
verify(l, times(0)).updateJobsForUid(anyInt());
verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());
verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean());
verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
verify(l, times(0)).unblockAllUnrestrictedAlarms();
verify(l, times(0)).unblockAlarmsForUid(anyInt());
@@ -940,8 +941,8 @@ public class AppStateTrackerTest {
waitUntilMainHandlerDrain();
verify(l, times(1)).updateAllJobs();
verify(l, times(0)).updateJobsForUid(anyInt());
verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());
verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean());
verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
verify(l, times(1)).unblockAllUnrestrictedAlarms();
verify(l, times(0)).unblockAlarmsForUid(anyInt());
@@ -953,8 +954,8 @@ public class AppStateTrackerTest {
waitUntilMainHandlerDrain();
verify(l, times(1)).updateAllJobs();
verify(l, times(0)).updateJobsForUid(anyInt());
verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());
verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean());
verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
verify(l, times(0)).unblockAllUnrestrictedAlarms();
verify(l, times(0)).unblockAlarmsForUid(anyInt());
@@ -965,8 +966,8 @@ public class AppStateTrackerTest {
waitUntilMainHandlerDrain();
verify(l, times(1)).updateAllJobs();
verify(l, times(0)).updateJobsForUid(anyInt());
verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());
verify(l, times(0)).updateJobsForUid(anyInt(), anyBoolean());
verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
verify(l, times(0)).unblockAllUnrestrictedAlarms();
verify(l, times(0)).unblockAlarmsForUid(anyInt());
@@ -985,8 +986,8 @@ public class AppStateTrackerTest {
waitUntilMainHandlerDrain();
verify(l, times(0)).updateAllJobs();
verify(l, times(1)).updateJobsForUid(eq(UID_10_1));
verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());
verify(l, times(1)).updateJobsForUid(eq(UID_10_1), anyBoolean());
verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
verify(l, times(0)).unblockAllUnrestrictedAlarms();
verify(l, times(1)).unblockAlarmsForUid(eq(UID_10_1));
@@ -997,8 +998,8 @@ public class AppStateTrackerTest {
waitUntilMainHandlerDrain();
verify(l, times(0)).updateAllJobs();
verify(l, times(1)).updateJobsForUid(eq(UID_10_1));
verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());
verify(l, times(1)).updateJobsForUid(eq(UID_10_1), anyBoolean());
verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
verify(l, times(0)).unblockAllUnrestrictedAlarms();
verify(l, times(0)).unblockAlarmsForUid(anyInt());
@@ -1009,8 +1010,8 @@ public class AppStateTrackerTest {
waitUntilMainHandlerDrain();
verify(l, times(0)).updateAllJobs();
verify(l, times(1)).updateJobsForUid(eq(UID_10_1));
verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());
verify(l, times(1)).updateJobsForUid(eq(UID_10_1), anyBoolean());
verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
verify(l, times(0)).unblockAllUnrestrictedAlarms();
verify(l, times(1)).unblockAlarmsForUid(eq(UID_10_1));
@@ -1021,8 +1022,8 @@ public class AppStateTrackerTest {
waitUntilMainHandlerDrain();
verify(l, times(0)).updateAllJobs();
verify(l, times(1)).updateJobsForUid(eq(UID_10_1));
verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());
verify(l, times(1)).updateJobsForUid(eq(UID_10_1), anyBoolean());
verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
verify(l, times(0)).unblockAllUnrestrictedAlarms();
verify(l, times(0)).unblockAlarmsForUid(anyInt());
@@ -1035,8 +1036,8 @@ public class AppStateTrackerTest {
waitUntilMainHandlerDrain();
verify(l, times(1)).updateAllJobs();
verify(l, times(0)).updateJobsForUid(eq(UID_10_1));
verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());
verify(l, times(0)).updateJobsForUid(eq(UID_10_1), anyBoolean());
verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
verify(l, times(1)).unblockAllUnrestrictedAlarms();
verify(l, times(0)).unblockAlarmsForUid(anyInt());
@@ -1047,8 +1048,8 @@ public class AppStateTrackerTest {
waitUntilMainHandlerDrain();
verify(l, times(0)).updateAllJobs();
verify(l, times(1)).updateJobsForUid(eq(UID_10_1));
verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());
verify(l, times(1)).updateJobsForUid(eq(UID_10_1), anyBoolean());
verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
verify(l, times(0)).unblockAllUnrestrictedAlarms();
verify(l, times(1)).unblockAlarmsForUid(eq(UID_10_1));
@@ -1059,8 +1060,8 @@ public class AppStateTrackerTest {
waitUntilMainHandlerDrain();
verify(l, times(0)).updateAllJobs();
verify(l, times(1)).updateJobsForUid(eq(UID_10_1));
verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());
verify(l, times(1)).updateJobsForUid(eq(UID_10_1), anyBoolean());
verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
verify(l, times(0)).unblockAllUnrestrictedAlarms();
verify(l, times(0)).unblockAlarmsForUid(anyInt());
@@ -1071,8 +1072,8 @@ public class AppStateTrackerTest {
waitUntilMainHandlerDrain();
verify(l, times(0)).updateAllJobs();
verify(l, times(1)).updateJobsForUid(eq(UID_10_1));
verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());
verify(l, times(1)).updateJobsForUid(eq(UID_10_1), anyBoolean());
verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
verify(l, times(0)).unblockAllUnrestrictedAlarms();
verify(l, times(1)).unblockAlarmsForUid(eq(UID_10_1));
@@ -1083,8 +1084,8 @@ public class AppStateTrackerTest {
waitUntilMainHandlerDrain();
verify(l, times(0)).updateAllJobs();
verify(l, times(1)).updateJobsForUid(eq(UID_10_1));
verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString());
verify(l, times(1)).updateJobsForUid(eq(UID_10_1), anyBoolean());
verify(l, times(0)).updateJobsForUidPackage(anyInt(), anyString(), anyBoolean());
verify(l, times(0)).unblockAllUnrestrictedAlarms();
verify(l, times(0)).unblockAlarmsForUid(anyInt());