13ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla/* 23ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla * Copyright (C) 2017 The Android Open Source Project 33ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla * 43ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla * Licensed under the Apache License, Version 2.0 (the "License"); 53ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla * you may not use this file except in compliance with the License. 63ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla * You may obtain a copy of the License at 73ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla * 83ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla * http://www.apache.org/licenses/LICENSE-2.0 93ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla * 103ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla * Unless required by applicable law or agreed to in writing, software 113ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla * distributed under the License is distributed on an "AS IS" BASIS, 123ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 133ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla * See the License for the specific language governing permissions and 143ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla * limitations under the License 153ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla */ 163ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla 173ac1daac4044c70ad4ee673214074306de499a18Suprabh Shuklapackage com.android.server.job.controllers; 183ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla 199be0140c1474dfd23d46121c51e636040a8080dfMakoto Onukiimport android.os.SystemClock; 203ac1daac4044c70ad4ee673214074306de499a18Suprabh Shuklaimport android.os.UserHandle; 2101bb530242eea8ff32fa3e0db70cbb40951fce24Jeff Sharkeyimport android.util.Log; 223ac1daac4044c70ad4ee673214074306de499a18Suprabh Shuklaimport android.util.Slog; 2385f2fbcb1fc3277ea825ec3dc52f636b47302425Kweku Adamsimport android.util.proto.ProtoOutputStream; 243ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla 25fee8c7b42aeebf3a11b978ee657803da0dfa8147Jeff Sharkeyimport com.android.internal.util.IndentingPrintWriter; 26e491821c5f28440a664bf880682953d8284ad4eeMakoto Onukiimport com.android.internal.util.Preconditions; 27e491821c5f28440a664bf880682953d8284ad4eeMakoto Onukiimport com.android.server.AppStateTracker; 28e491821c5f28440a664bf880682953d8284ad4eeMakoto Onukiimport com.android.server.AppStateTracker.Listener; 29e491821c5f28440a664bf880682953d8284ad4eeMakoto Onukiimport com.android.server.LocalServices; 303ac1daac4044c70ad4ee673214074306de499a18Suprabh Shuklaimport com.android.server.job.JobSchedulerService; 3120afddd2ed37c2c9c0214b382cc3edd6d4ee81a8Christopher Tateimport com.android.server.job.JobStore; 3285f2fbcb1fc3277ea825ec3dc52f636b47302425Kweku Adamsimport com.android.server.job.StateControllerProto; 3385f2fbcb1fc3277ea825ec3dc52f636b47302425Kweku Adamsimport com.android.server.job.StateControllerProto.BackgroundJobsController.TrackedJob; 343ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla 35fee8c7b42aeebf3a11b978ee657803da0dfa8147Jeff Sharkeyimport java.util.function.Consumer; 36fee8c7b42aeebf3a11b978ee657803da0dfa8147Jeff Sharkeyimport java.util.function.Predicate; 373ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla 3820afddd2ed37c2c9c0214b382cc3edd6d4ee81a8Christopher Tate/** 3920afddd2ed37c2c9c0214b382cc3edd6d4ee81a8Christopher Tate * Tracks the following pieces of JobStatus state: 4020afddd2ed37c2c9c0214b382cc3edd6d4ee81a8Christopher Tate * 4120afddd2ed37c2c9c0214b382cc3edd6d4ee81a8Christopher Tate * - the CONSTRAINT_BACKGROUND_NOT_RESTRICTED general constraint bit, which 4220afddd2ed37c2c9c0214b382cc3edd6d4ee81a8Christopher Tate * is used to selectively permit battery-saver exempted jobs to run; and 4320afddd2ed37c2c9c0214b382cc3edd6d4ee81a8Christopher Tate * 4420afddd2ed37c2c9c0214b382cc3edd6d4ee81a8Christopher Tate * - the uid-active boolean state expressed by the AppStateTracker. Jobs in 'active' 4520afddd2ed37c2c9c0214b382cc3edd6d4ee81a8Christopher Tate * uids are inherently eligible to run jobs regardless of the uid's standby bucket. 4620afddd2ed37c2c9c0214b382cc3edd6d4ee81a8Christopher Tate */ 473ac1daac4044c70ad4ee673214074306de499a18Suprabh Shuklapublic final class BackgroundJobsController extends StateController { 4801bb530242eea8ff32fa3e0db70cbb40951fce24Jeff Sharkey private static final String TAG = "JobScheduler.Background"; 4901bb530242eea8ff32fa3e0db70cbb40951fce24Jeff Sharkey private static final boolean DEBUG = JobSchedulerService.DEBUG 5001bb530242eea8ff32fa3e0db70cbb40951fce24Jeff Sharkey || Log.isLoggable(TAG, Log.DEBUG); 513ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla 5220afddd2ed37c2c9c0214b382cc3edd6d4ee81a8Christopher Tate // Tri-state about possible "is this uid 'active'?" knowledge 5320afddd2ed37c2c9c0214b382cc3edd6d4ee81a8Christopher Tate static final int UNKNOWN = 0; 5420afddd2ed37c2c9c0214b382cc3edd6d4ee81a8Christopher Tate static final int KNOWN_ACTIVE = 1; 5520afddd2ed37c2c9c0214b382cc3edd6d4ee81a8Christopher Tate static final int KNOWN_INACTIVE = 2; 5620afddd2ed37c2c9c0214b382cc3edd6d4ee81a8Christopher Tate 57e491821c5f28440a664bf880682953d8284ad4eeMakoto Onuki private final AppStateTracker mAppStateTracker; 583ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla 59ac2e8efa4395d30ebeda5885dcb7cb679f793d4cJeff Sharkey public BackgroundJobsController(JobSchedulerService service) { 60ac2e8efa4395d30ebeda5885dcb7cb679f793d4cJeff Sharkey super(service); 613ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla 62e491821c5f28440a664bf880682953d8284ad4eeMakoto Onuki mAppStateTracker = Preconditions.checkNotNull( 63e491821c5f28440a664bf880682953d8284ad4eeMakoto Onuki LocalServices.getService(AppStateTracker.class)); 64e491821c5f28440a664bf880682953d8284ad4eeMakoto Onuki mAppStateTracker.addListener(mForceAppStandbyListener); 653ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla } 663ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla 673ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla @Override 683ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla public void maybeStartTrackingJobLocked(JobStatus jobStatus, JobStatus lastJob) { 6920afddd2ed37c2c9c0214b382cc3edd6d4ee81a8Christopher Tate updateSingleJobRestrictionLocked(jobStatus, UNKNOWN); 703ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla } 713ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla 723ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla @Override 733ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla public void maybeStopTrackingJobLocked(JobStatus jobStatus, JobStatus incomingJob, 743ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla boolean forUpdate) { 753ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla } 763ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla 773ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla @Override 78fee8c7b42aeebf3a11b978ee657803da0dfa8147Jeff Sharkey public void dumpControllerStateLocked(final IndentingPrintWriter pw, 79fee8c7b42aeebf3a11b978ee657803da0dfa8147Jeff Sharkey final Predicate<JobStatus> predicate) { 80fee8c7b42aeebf3a11b978ee657803da0dfa8147Jeff Sharkey mAppStateTracker.dump(pw); 81fee8c7b42aeebf3a11b978ee657803da0dfa8147Jeff Sharkey pw.println(); 829be0140c1474dfd23d46121c51e636040a8080dfMakoto Onuki 83ac2e8efa4395d30ebeda5885dcb7cb679f793d4cJeff Sharkey mService.getJobStore().forEachJob(predicate, (jobStatus) -> { 849be0140c1474dfd23d46121c51e636040a8080dfMakoto Onuki final int uid = jobStatus.getSourceUid(); 8585f2fbcb1fc3277ea825ec3dc52f636b47302425Kweku Adams final String sourcePkg = jobStatus.getSourcePackageName(); 86fee8c7b42aeebf3a11b978ee657803da0dfa8147Jeff Sharkey pw.print("#"); 879be0140c1474dfd23d46121c51e636040a8080dfMakoto Onuki jobStatus.printUniqueId(pw); 889be0140c1474dfd23d46121c51e636040a8080dfMakoto Onuki pw.print(" from "); 899be0140c1474dfd23d46121c51e636040a8080dfMakoto Onuki UserHandle.formatUid(pw, uid); 90e491821c5f28440a664bf880682953d8284ad4eeMakoto Onuki pw.print(mAppStateTracker.isUidActive(uid) ? " active" : " idle"); 91e491821c5f28440a664bf880682953d8284ad4eeMakoto Onuki if (mAppStateTracker.isUidPowerSaveWhitelisted(uid) || 92e491821c5f28440a664bf880682953d8284ad4eeMakoto Onuki mAppStateTracker.isUidTempPowerSaveWhitelisted(uid)) { 939be0140c1474dfd23d46121c51e636040a8080dfMakoto Onuki pw.print(", whitelisted"); 949be0140c1474dfd23d46121c51e636040a8080dfMakoto Onuki } 959be0140c1474dfd23d46121c51e636040a8080dfMakoto Onuki pw.print(": "); 9685f2fbcb1fc3277ea825ec3dc52f636b47302425Kweku Adams pw.print(sourcePkg); 979be0140c1474dfd23d46121c51e636040a8080dfMakoto Onuki 982206af39a28e8ef9d242015f791dc8abb6c3b3ccMakoto Onuki pw.print(" [RUN_ANY_IN_BACKGROUND "); 99e491821c5f28440a664bf880682953d8284ad4eeMakoto Onuki pw.print(mAppStateTracker.isRunAnyInBackgroundAppOpsAllowed(uid, sourcePkg) 1002206af39a28e8ef9d242015f791dc8abb6c3b3ccMakoto Onuki ? "allowed]" : "disallowed]"); 1019be0140c1474dfd23d46121c51e636040a8080dfMakoto Onuki 1029be0140c1474dfd23d46121c51e636040a8080dfMakoto Onuki if ((jobStatus.satisfiedConstraints 1039be0140c1474dfd23d46121c51e636040a8080dfMakoto Onuki & JobStatus.CONSTRAINT_BACKGROUND_NOT_RESTRICTED) != 0) { 1049be0140c1474dfd23d46121c51e636040a8080dfMakoto Onuki pw.println(" RUNNABLE"); 1059be0140c1474dfd23d46121c51e636040a8080dfMakoto Onuki } else { 1069be0140c1474dfd23d46121c51e636040a8080dfMakoto Onuki pw.println(" WAITING"); 1073ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla } 1083ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla }); 1093ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla } 1103ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla 11185f2fbcb1fc3277ea825ec3dc52f636b47302425Kweku Adams @Override 112fee8c7b42aeebf3a11b978ee657803da0dfa8147Jeff Sharkey public void dumpControllerStateLocked(ProtoOutputStream proto, long fieldId, 113fee8c7b42aeebf3a11b978ee657803da0dfa8147Jeff Sharkey Predicate<JobStatus> predicate) { 11485f2fbcb1fc3277ea825ec3dc52f636b47302425Kweku Adams final long token = proto.start(fieldId); 11585f2fbcb1fc3277ea825ec3dc52f636b47302425Kweku Adams final long mToken = proto.start(StateControllerProto.BACKGROUND); 11685f2fbcb1fc3277ea825ec3dc52f636b47302425Kweku Adams 117e491821c5f28440a664bf880682953d8284ad4eeMakoto Onuki mAppStateTracker.dumpProto(proto, 11885f2fbcb1fc3277ea825ec3dc52f636b47302425Kweku Adams StateControllerProto.BackgroundJobsController.FORCE_APP_STANDBY_TRACKER); 11985f2fbcb1fc3277ea825ec3dc52f636b47302425Kweku Adams 120ac2e8efa4395d30ebeda5885dcb7cb679f793d4cJeff Sharkey mService.getJobStore().forEachJob(predicate, (jobStatus) -> { 12185f2fbcb1fc3277ea825ec3dc52f636b47302425Kweku Adams final long jsToken = 12285f2fbcb1fc3277ea825ec3dc52f636b47302425Kweku Adams proto.start(StateControllerProto.BackgroundJobsController.TRACKED_JOBS); 12385f2fbcb1fc3277ea825ec3dc52f636b47302425Kweku Adams 12485f2fbcb1fc3277ea825ec3dc52f636b47302425Kweku Adams jobStatus.writeToShortProto(proto, 12585f2fbcb1fc3277ea825ec3dc52f636b47302425Kweku Adams TrackedJob.INFO); 12685f2fbcb1fc3277ea825ec3dc52f636b47302425Kweku Adams final int sourceUid = jobStatus.getSourceUid(); 12785f2fbcb1fc3277ea825ec3dc52f636b47302425Kweku Adams proto.write(TrackedJob.SOURCE_UID, sourceUid); 12885f2fbcb1fc3277ea825ec3dc52f636b47302425Kweku Adams final String sourcePkg = jobStatus.getSourcePackageName(); 12985f2fbcb1fc3277ea825ec3dc52f636b47302425Kweku Adams proto.write(TrackedJob.SOURCE_PACKAGE_NAME, sourcePkg); 13085f2fbcb1fc3277ea825ec3dc52f636b47302425Kweku Adams 13185f2fbcb1fc3277ea825ec3dc52f636b47302425Kweku Adams proto.write(TrackedJob.IS_IN_FOREGROUND, 132e491821c5f28440a664bf880682953d8284ad4eeMakoto Onuki mAppStateTracker.isUidActive(sourceUid)); 13385f2fbcb1fc3277ea825ec3dc52f636b47302425Kweku Adams proto.write(TrackedJob.IS_WHITELISTED, 134e491821c5f28440a664bf880682953d8284ad4eeMakoto Onuki mAppStateTracker.isUidPowerSaveWhitelisted(sourceUid) || 135e491821c5f28440a664bf880682953d8284ad4eeMakoto Onuki mAppStateTracker.isUidTempPowerSaveWhitelisted(sourceUid)); 13685f2fbcb1fc3277ea825ec3dc52f636b47302425Kweku Adams 13785f2fbcb1fc3277ea825ec3dc52f636b47302425Kweku Adams proto.write( 13885f2fbcb1fc3277ea825ec3dc52f636b47302425Kweku Adams TrackedJob.CAN_RUN_ANY_IN_BACKGROUND, 139e491821c5f28440a664bf880682953d8284ad4eeMakoto Onuki mAppStateTracker.isRunAnyInBackgroundAppOpsAllowed( 14085f2fbcb1fc3277ea825ec3dc52f636b47302425Kweku Adams sourceUid, sourcePkg)); 14185f2fbcb1fc3277ea825ec3dc52f636b47302425Kweku Adams 14285f2fbcb1fc3277ea825ec3dc52f636b47302425Kweku Adams proto.write( 14385f2fbcb1fc3277ea825ec3dc52f636b47302425Kweku Adams TrackedJob.ARE_CONSTRAINTS_SATISFIED, 14485f2fbcb1fc3277ea825ec3dc52f636b47302425Kweku Adams (jobStatus.satisfiedConstraints & 14585f2fbcb1fc3277ea825ec3dc52f636b47302425Kweku Adams JobStatus.CONSTRAINT_BACKGROUND_NOT_RESTRICTED) != 0); 14685f2fbcb1fc3277ea825ec3dc52f636b47302425Kweku Adams 14785f2fbcb1fc3277ea825ec3dc52f636b47302425Kweku Adams proto.end(jsToken); 14885f2fbcb1fc3277ea825ec3dc52f636b47302425Kweku Adams }); 14985f2fbcb1fc3277ea825ec3dc52f636b47302425Kweku Adams 15085f2fbcb1fc3277ea825ec3dc52f636b47302425Kweku Adams proto.end(mToken); 15185f2fbcb1fc3277ea825ec3dc52f636b47302425Kweku Adams proto.end(token); 15285f2fbcb1fc3277ea825ec3dc52f636b47302425Kweku Adams } 15385f2fbcb1fc3277ea825ec3dc52f636b47302425Kweku Adams 1549be0140c1474dfd23d46121c51e636040a8080dfMakoto Onuki private void updateAllJobRestrictionsLocked() { 15520afddd2ed37c2c9c0214b382cc3edd6d4ee81a8Christopher Tate updateJobRestrictionsLocked(/*filterUid=*/ -1, UNKNOWN); 1563ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla } 1573ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla 15820afddd2ed37c2c9c0214b382cc3edd6d4ee81a8Christopher Tate private void updateJobRestrictionsForUidLocked(int uid, boolean isActive) { 15920afddd2ed37c2c9c0214b382cc3edd6d4ee81a8Christopher Tate updateJobRestrictionsLocked(uid, (isActive) ? KNOWN_ACTIVE : KNOWN_INACTIVE); 1603ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla } 1613ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla 16220afddd2ed37c2c9c0214b382cc3edd6d4ee81a8Christopher Tate private void updateJobRestrictionsLocked(int filterUid, int newActiveState) { 16320afddd2ed37c2c9c0214b382cc3edd6d4ee81a8Christopher Tate final UpdateJobFunctor updateTrackedJobs = new UpdateJobFunctor(newActiveState); 1649be0140c1474dfd23d46121c51e636040a8080dfMakoto Onuki 1659be0140c1474dfd23d46121c51e636040a8080dfMakoto Onuki final long start = DEBUG ? SystemClock.elapsedRealtimeNanos() : 0; 1669be0140c1474dfd23d46121c51e636040a8080dfMakoto Onuki 16720afddd2ed37c2c9c0214b382cc3edd6d4ee81a8Christopher Tate final JobStore store = mService.getJobStore(); 16820afddd2ed37c2c9c0214b382cc3edd6d4ee81a8Christopher Tate if (filterUid > 0) { 16920afddd2ed37c2c9c0214b382cc3edd6d4ee81a8Christopher Tate store.forEachJobForSourceUid(filterUid, updateTrackedJobs); 17020afddd2ed37c2c9c0214b382cc3edd6d4ee81a8Christopher Tate } else { 17120afddd2ed37c2c9c0214b382cc3edd6d4ee81a8Christopher Tate store.forEachJob(updateTrackedJobs); 17220afddd2ed37c2c9c0214b382cc3edd6d4ee81a8Christopher Tate } 1739be0140c1474dfd23d46121c51e636040a8080dfMakoto Onuki 1749be0140c1474dfd23d46121c51e636040a8080dfMakoto Onuki final long time = DEBUG ? (SystemClock.elapsedRealtimeNanos() - start) : 0; 1759be0140c1474dfd23d46121c51e636040a8080dfMakoto Onuki if (DEBUG) { 17601bb530242eea8ff32fa3e0db70cbb40951fce24Jeff Sharkey Slog.d(TAG, String.format( 1779be0140c1474dfd23d46121c51e636040a8080dfMakoto Onuki "Job status updated: %d/%d checked/total jobs, %d us", 1789be0140c1474dfd23d46121c51e636040a8080dfMakoto Onuki updateTrackedJobs.mCheckedCount, 1799be0140c1474dfd23d46121c51e636040a8080dfMakoto Onuki updateTrackedJobs.mTotalCount, 1809be0140c1474dfd23d46121c51e636040a8080dfMakoto Onuki (time / 1000) 1819be0140c1474dfd23d46121c51e636040a8080dfMakoto Onuki )); 1823ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla } 1833ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla 1849be0140c1474dfd23d46121c51e636040a8080dfMakoto Onuki if (updateTrackedJobs.mChanged) { 1859be0140c1474dfd23d46121c51e636040a8080dfMakoto Onuki mStateChangedListener.onControllerStateChanged(); 1863ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla } 1873ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla } 1883ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla 18920afddd2ed37c2c9c0214b382cc3edd6d4ee81a8Christopher Tate boolean updateSingleJobRestrictionLocked(JobStatus jobStatus, int activeState) { 1903ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla 1919be0140c1474dfd23d46121c51e636040a8080dfMakoto Onuki final int uid = jobStatus.getSourceUid(); 1929be0140c1474dfd23d46121c51e636040a8080dfMakoto Onuki final String packageName = jobStatus.getSourcePackageName(); 1939be0140c1474dfd23d46121c51e636040a8080dfMakoto Onuki 194e491821c5f28440a664bf880682953d8284ad4eeMakoto Onuki final boolean canRun = !mAppStateTracker.areJobsRestricted(uid, packageName, 19515407846682b269e6b7fd0c24b84f709257fab5dMakoto Onuki (jobStatus.getInternalFlags() & JobStatus.INTERNAL_FLAG_HAS_FOREGROUND_EXEMPTION) 19615407846682b269e6b7fd0c24b84f709257fab5dMakoto Onuki != 0); 1979be0140c1474dfd23d46121c51e636040a8080dfMakoto Onuki 19820afddd2ed37c2c9c0214b382cc3edd6d4ee81a8Christopher Tate final boolean isActive; 19920afddd2ed37c2c9c0214b382cc3edd6d4ee81a8Christopher Tate if (activeState == UNKNOWN) { 20020afddd2ed37c2c9c0214b382cc3edd6d4ee81a8Christopher Tate isActive = mAppStateTracker.isUidActive(uid); 20120afddd2ed37c2c9c0214b382cc3edd6d4ee81a8Christopher Tate } else { 20220afddd2ed37c2c9c0214b382cc3edd6d4ee81a8Christopher Tate isActive = (activeState == KNOWN_ACTIVE); 20320afddd2ed37c2c9c0214b382cc3edd6d4ee81a8Christopher Tate } 20420afddd2ed37c2c9c0214b382cc3edd6d4ee81a8Christopher Tate boolean didChange = jobStatus.setBackgroundNotRestrictedConstraintSatisfied(canRun); 20520afddd2ed37c2c9c0214b382cc3edd6d4ee81a8Christopher Tate didChange |= jobStatus.setUidActive(isActive); 20620afddd2ed37c2c9c0214b382cc3edd6d4ee81a8Christopher Tate return didChange; 2073ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla } 2083ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla 209fee8c7b42aeebf3a11b978ee657803da0dfa8147Jeff Sharkey private final class UpdateJobFunctor implements Consumer<JobStatus> { 21020afddd2ed37c2c9c0214b382cc3edd6d4ee81a8Christopher Tate final int activeState; 2119be0140c1474dfd23d46121c51e636040a8080dfMakoto Onuki boolean mChanged = false; 2129be0140c1474dfd23d46121c51e636040a8080dfMakoto Onuki int mTotalCount = 0; 2139be0140c1474dfd23d46121c51e636040a8080dfMakoto Onuki int mCheckedCount = 0; 2149be0140c1474dfd23d46121c51e636040a8080dfMakoto Onuki 21520afddd2ed37c2c9c0214b382cc3edd6d4ee81a8Christopher Tate public UpdateJobFunctor(int newActiveState) { 21620afddd2ed37c2c9c0214b382cc3edd6d4ee81a8Christopher Tate activeState = newActiveState; 2173ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla } 2183ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla 2193ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla @Override 220fee8c7b42aeebf3a11b978ee657803da0dfa8147Jeff Sharkey public void accept(JobStatus jobStatus) { 2219be0140c1474dfd23d46121c51e636040a8080dfMakoto Onuki mTotalCount++; 2229be0140c1474dfd23d46121c51e636040a8080dfMakoto Onuki mCheckedCount++; 22320afddd2ed37c2c9c0214b382cc3edd6d4ee81a8Christopher Tate if (updateSingleJobRestrictionLocked(jobStatus, activeState)) { 2249be0140c1474dfd23d46121c51e636040a8080dfMakoto Onuki mChanged = true; 2253ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla } 2263ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla } 2273ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla } 2289be0140c1474dfd23d46121c51e636040a8080dfMakoto Onuki 2299be0140c1474dfd23d46121c51e636040a8080dfMakoto Onuki private final Listener mForceAppStandbyListener = new Listener() { 2309be0140c1474dfd23d46121c51e636040a8080dfMakoto Onuki @Override 2312206af39a28e8ef9d242015f791dc8abb6c3b3ccMakoto Onuki public void updateAllJobs() { 232998fb4e80e2edad9baf5c07432442b6418e2674cChristopher Tate synchronized (mLock) { 233998fb4e80e2edad9baf5c07432442b6418e2674cChristopher Tate updateAllJobRestrictionsLocked(); 234998fb4e80e2edad9baf5c07432442b6418e2674cChristopher Tate } 2352206af39a28e8ef9d242015f791dc8abb6c3b3ccMakoto Onuki } 2362206af39a28e8ef9d242015f791dc8abb6c3b3ccMakoto Onuki 2372206af39a28e8ef9d242015f791dc8abb6c3b3ccMakoto Onuki @Override 23820afddd2ed37c2c9c0214b382cc3edd6d4ee81a8Christopher Tate public void updateJobsForUid(int uid, boolean isActive) { 239998fb4e80e2edad9baf5c07432442b6418e2674cChristopher Tate synchronized (mLock) { 24020afddd2ed37c2c9c0214b382cc3edd6d4ee81a8Christopher Tate updateJobRestrictionsForUidLocked(uid, isActive); 241998fb4e80e2edad9baf5c07432442b6418e2674cChristopher Tate } 2429be0140c1474dfd23d46121c51e636040a8080dfMakoto Onuki } 2439be0140c1474dfd23d46121c51e636040a8080dfMakoto Onuki 2449be0140c1474dfd23d46121c51e636040a8080dfMakoto Onuki @Override 24520afddd2ed37c2c9c0214b382cc3edd6d4ee81a8Christopher Tate public void updateJobsForUidPackage(int uid, String packageName, boolean isActive) { 246998fb4e80e2edad9baf5c07432442b6418e2674cChristopher Tate synchronized (mLock) { 24720afddd2ed37c2c9c0214b382cc3edd6d4ee81a8Christopher Tate updateJobRestrictionsForUidLocked(uid, isActive); 248998fb4e80e2edad9baf5c07432442b6418e2674cChristopher Tate } 2499be0140c1474dfd23d46121c51e636040a8080dfMakoto Onuki } 2509be0140c1474dfd23d46121c51e636040a8080dfMakoto Onuki }; 2513ac1daac4044c70ad4ee673214074306de499a18Suprabh Shukla} 252