From 20afddd2ed37c2c9c0214b382cc3edd6d4ee81a8 Mon Sep 17 00:00:00 2001 From: Christopher Tate Date: Wed, 28 Feb 2018 15:19:19 -0800 Subject: [PATCH] Jobs in 'active' apps are not subject to standby Along the way we turn down the "app idle" tracking in the jbo scheduler: it's now redundant with standby bookkeeping, and was muddying the waters. Bug: 74017233 Test: atest CtsJobSchedulerTestCases Change-Id: I3220e6ef97f153b3f718e267a0dc4fbd3b926316 --- core/proto/android/server/jobscheduler.proto | 1 - .../com/android/server/AppStateTracker.java | 12 +- .../server/job/JobSchedulerService.java | 24 +- .../job/controllers/AppIdleController.java | 216 ------------------ .../controllers/BackgroundJobsController.java | 70 ++++-- .../server/job/controllers/JobStatus.java | 32 ++- .../android/server/AppStateTrackerTest.java | 105 ++++----- 7 files changed, 139 insertions(+), 321 deletions(-) delete mode 100644 services/core/java/com/android/server/job/controllers/AppIdleController.java diff --git a/core/proto/android/server/jobscheduler.proto b/core/proto/android/server/jobscheduler.proto index 69abed30234db..9193129def11d 100644 --- a/core/proto/android/server/jobscheduler.proto +++ b/core/proto/android/server/jobscheduler.proto @@ -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; } diff --git a/services/core/java/com/android/server/AppStateTracker.java b/services/core/java/com/android/server/AppStateTracker.java index a6b71b772d15f..16be680b17709 100644 --- a/services/core/java/com/android/server/AppStateTracker.java +++ b/services/core/java/com/android/server/AppStateTracker.java @@ -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) { } /** diff --git a/services/core/java/com/android/server/job/JobSchedulerService.java b/services/core/java/com/android/server/job/JobSchedulerService.java index 0e7e5401caafd..790d39690947b 100644 --- a/services/core/java/com/android/server/job/JobSchedulerService.java +++ b/services/core/java/com/android/server/job/JobSchedulerService.java @@ -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. diff --git a/services/core/java/com/android/server/job/controllers/AppIdleController.java b/services/core/java/com/android/server/job/controllers/AppIdleController.java deleted file mode 100644 index ed29a4c4e252a..0000000000000 --- a/services/core/java/com/android/server/job/controllers/AppIdleController.java +++ /dev/null @@ -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 { - 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 { - 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 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 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); - } - } -} diff --git a/services/core/java/com/android/server/job/controllers/BackgroundJobsController.java b/services/core/java/com/android/server/job/controllers/BackgroundJobsController.java index 36e75115712c2..b698e5bf4403f 100644 --- a/services/core/java/com/android/server/job/controllers/BackgroundJobsController.java +++ b/services/core/java/com/android/server/job/controllers/BackgroundJobsController.java @@ -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 { - 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); } } }; diff --git a/services/core/java/com/android/server/job/controllers/JobStatus.java b/services/core/java/com/android/server/job/controllers/JobStatus.java index 56161977908c9..578a32cc4b2ec 100644 --- a/services/core/java/com/android/server/job/controllers/JobStatus.java +++ b/services/core/java/com/android/server/job/controllers/JobStatus.java @@ -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:"); diff --git a/services/tests/servicestests/src/com/android/server/AppStateTrackerTest.java b/services/tests/servicestests/src/com/android/server/AppStateTrackerTest.java index b62f1ceb45962..5daacd73c915e 100644 --- a/services/tests/servicestests/src/com/android/server/AppStateTrackerTest.java +++ b/services/tests/servicestests/src/com/android/server/AppStateTrackerTest.java @@ -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());