Loading apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java +30 −29 Original line number Original line Diff line number Diff line Loading @@ -746,12 +746,15 @@ public class JobSchedulerService extends com.android.server.SystemService Slog.d(TAG, "Removing jobs for package " + pkgName Slog.d(TAG, "Removing jobs for package " + pkgName + " in user " + userId); + " in user " + userId); } } // By the time we get here, the process should have already synchronized (mLock) { // been stopped, so the app wouldn't get the stop reason, // By the time we get here, the process should have // so just put USER instead of UNINSTALL or DISABLED. // already been stopped, so the app wouldn't get the cancelJobsForPackageAndUid(pkgName, pkgUid, // stop reason, so just put USER instead of UNINSTALL // or DISABLED. cancelJobsForPackageAndUidLocked(pkgName, pkgUid, JobParameters.STOP_REASON_USER, "app disabled"); JobParameters.STOP_REASON_USER, "app disabled"); } } } } catch (RemoteException|IllegalArgumentException e) { } catch (RemoteException|IllegalArgumentException e) { /* /* * IllegalArgumentException means that the package doesn't exist. * IllegalArgumentException means that the package doesn't exist. Loading Loading @@ -791,9 +794,9 @@ public class JobSchedulerService extends com.android.server.SystemService // By the time we get here, the process should have already // By the time we get here, the process should have already // been stopped, so the app wouldn't get the stop reason, // been stopped, so the app wouldn't get the stop reason, // so just put USER instead of UNINSTALL or DISABLED. // so just put USER instead of UNINSTALL or DISABLED. cancelJobsForPackageAndUid(pkgName, uidRemoved, JobParameters.STOP_REASON_USER, "app uninstalled"); synchronized (mLock) { synchronized (mLock) { cancelJobsForPackageAndUidLocked(pkgName, uidRemoved, JobParameters.STOP_REASON_USER, "app uninstalled"); for (int c = 0; c < mControllers.size(); ++c) { for (int c = 0; c < mControllers.size(); ++c) { mControllers.get(c).onAppRemovedLocked(pkgName, pkgUid); mControllers.get(c).onAppRemovedLocked(pkgName, pkgUid); } } Loading @@ -812,8 +815,8 @@ public class JobSchedulerService extends com.android.server.SystemService if (DEBUG) { if (DEBUG) { Slog.d(TAG, "Removing jobs for user: " + userId); Slog.d(TAG, "Removing jobs for user: " + userId); } } cancelJobsForUser(userId); synchronized (mLock) { synchronized (mLock) { cancelJobsForUserLocked(userId); for (int c = 0; c < mControllers.size(); ++c) { for (int c = 0; c < mControllers.size(); ++c) { mControllers.get(c).onUserRemovedLocked(userId); mControllers.get(c).onUserRemovedLocked(userId); } } Loading Loading @@ -844,11 +847,13 @@ public class JobSchedulerService extends com.android.server.SystemService if (DEBUG) { if (DEBUG) { Slog.d(TAG, "Removing jobs for pkg " + pkgName + " at uid " + pkgUid); Slog.d(TAG, "Removing jobs for pkg " + pkgName + " at uid " + pkgUid); } } cancelJobsForPackageAndUid(pkgName, pkgUid, synchronized (mLock) { cancelJobsForPackageAndUidLocked(pkgName, pkgUid, JobParameters.STOP_REASON_USER, "app force stopped"); JobParameters.STOP_REASON_USER, "app force stopped"); } } } } } } } }; }; private String getPackageName(Intent intent) { private String getPackageName(Intent intent) { Loading Loading @@ -1106,8 +1111,7 @@ public class JobSchedulerService extends com.android.server.SystemService } } } } void cancelJobsForUser(int userHandle) { private void cancelJobsForUserLocked(int userHandle) { synchronized (mLock) { final List<JobStatus> jobsForUser = mJobs.getJobsByUser(userHandle); final List<JobStatus> jobsForUser = mJobs.getJobsByUser(userHandle); for (int i = 0; i < jobsForUser.size(); i++) { for (int i = 0; i < jobsForUser.size(); i++) { JobStatus toRemove = jobsForUser.get(i); JobStatus toRemove = jobsForUser.get(i); Loading @@ -1117,7 +1121,6 @@ public class JobSchedulerService extends com.android.server.SystemService "user removed"); "user removed"); } } } } } private void cancelJobsForNonExistentUsers() { private void cancelJobsForNonExistentUsers() { UserManagerInternal umi = LocalServices.getService(UserManagerInternal.class); UserManagerInternal umi = LocalServices.getService(UserManagerInternal.class); Loading @@ -1126,13 +1129,12 @@ public class JobSchedulerService extends com.android.server.SystemService } } } } void cancelJobsForPackageAndUid(String pkgName, int uid, @JobParameters.StopReason int reason, private void cancelJobsForPackageAndUidLocked(String pkgName, int uid, String debugReason) { @JobParameters.StopReason int reason, String debugReason) { if ("android".equals(pkgName)) { if ("android".equals(pkgName)) { Slog.wtfStack(TAG, "Can't cancel all jobs for system package"); Slog.wtfStack(TAG, "Can't cancel all jobs for system package"); return; return; } } synchronized (mLock) { final List<JobStatus> jobsForUid = mJobs.getJobsByUid(uid); final List<JobStatus> jobsForUid = mJobs.getJobsByUid(uid); for (int i = jobsForUid.size() - 1; i >= 0; i--) { for (int i = jobsForUid.size() - 1; i >= 0; i--) { final JobStatus job = jobsForUid.get(i); final JobStatus job = jobsForUid.get(i); Loading @@ -1141,7 +1143,6 @@ public class JobSchedulerService extends com.android.server.SystemService } } } } } } } /** /** * Entry point from client to cancel all jobs originating from their uid. * Entry point from client to cancel all jobs originating from their uid. Loading apex/jobscheduler/service/java/com/android/server/job/controllers/ConnectivityController.java +35 −22 Original line number Original line Diff line number Diff line Loading @@ -226,10 +226,23 @@ public final class ConnectivityController extends RestrictingController implemen jobs.remove(jobStatus); jobs.remove(jobStatus); } } UidStats us = mUidStats.get(jobStatus.getSourceUid()); UidStats us = mUidStats.get(jobStatus.getSourceUid()); if (us == null) { // This shouldn't be happening. We create a UidStats object for the app when the // first job is scheduled in maybeStartTrackingJobLocked() and only ever drop the // object if the app is uninstalled or the user is removed. That means that if we // end up in this situation, onAppRemovedLocked() or onUserRemovedLocked() was // called before maybeStopTrackingJobLocked(), which is the reverse order of what // JobSchedulerService does (JSS calls maybeStopTrackingJobLocked() for all jobs // before calling onAppRemovedLocked() or onUserRemovedLocked()). Slog.wtfStack(TAG, "UidStats was null after job for " + jobStatus.getSourcePackageName() + " was registered"); } else { us.numReadyWithConnectivity--; us.numReadyWithConnectivity--; if (jobStatus.madeActive != 0) { if (jobStatus.madeActive != 0) { us.numRunning--; us.numRunning--; } } } maybeRevokeStandbyExceptionLocked(jobStatus); maybeRevokeStandbyExceptionLocked(jobStatus); maybeAdjustRegisteredCallbacksLocked(); maybeAdjustRegisteredCallbacksLocked(); } } Loading Loading @@ -773,8 +786,8 @@ public final class ConnectivityController extends RestrictingController implemen * @param filterNetwork only update jobs that would use this * @param filterNetwork only update jobs that would use this * {@link Network}, or {@code null} to update all tracked jobs. * {@link Network}, or {@code null} to update all tracked jobs. */ */ private void updateTrackedJobs(int filterUid, Network filterNetwork) { @GuardedBy("mLock") synchronized (mLock) { private void updateTrackedJobsLocked(int filterUid, Network filterNetwork) { boolean changed = false; boolean changed = false; if (filterUid == -1) { if (filterUid == -1) { for (int i = mTrackedJobs.size() - 1; i >= 0; i--) { for (int i = mTrackedJobs.size() - 1; i >= 0; i--) { Loading @@ -787,8 +800,8 @@ public final class ConnectivityController extends RestrictingController implemen mStateChangedListener.onControllerStateChanged(); mStateChangedListener.onControllerStateChanged(); } } } } } @GuardedBy("mLock") private boolean updateTrackedJobsLocked(ArraySet<JobStatus> jobs, Network filterNetwork) { private boolean updateTrackedJobsLocked(ArraySet<JobStatus> jobs, Network filterNetwork) { if (jobs == null || jobs.size() == 0) { if (jobs == null || jobs.size() == 0) { return false; return false; Loading Loading @@ -875,10 +888,10 @@ public final class ConnectivityController extends RestrictingController implemen } } synchronized (mLock) { synchronized (mLock) { mAvailableNetworks.put(network, capabilities); mAvailableNetworks.put(network, capabilities); } updateTrackedJobsLocked(-1, network); updateTrackedJobs(-1, network); maybeAdjustRegisteredCallbacksLocked(); maybeAdjustRegisteredCallbacksLocked(); } } } @Override @Override public void onLost(Network network) { public void onLost(Network network) { Loading @@ -893,10 +906,10 @@ public final class ConnectivityController extends RestrictingController implemen callback.mDefaultNetwork = null; callback.mDefaultNetwork = null; } } } } } updateTrackedJobsLocked(-1, network); updateTrackedJobs(-1, network); maybeAdjustRegisteredCallbacksLocked(); maybeAdjustRegisteredCallbacksLocked(); } } } }; }; private class CcHandler extends Handler { private class CcHandler extends Handler { Loading @@ -909,7 +922,7 @@ public final class ConnectivityController extends RestrictingController implemen synchronized (mLock) { synchronized (mLock) { switch (msg.what) { switch (msg.what) { case MSG_REEVALUATE_JOBS: case MSG_REEVALUATE_JOBS: updateTrackedJobs(-1, null); updateTrackedJobsLocked(-1, null); break; break; } } } } Loading Loading @@ -949,8 +962,8 @@ public final class ConnectivityController extends RestrictingController implemen synchronized (mLock) { synchronized (mLock) { mDefaultNetwork = network; mDefaultNetwork = network; mBlocked = blocked; mBlocked = blocked; updateTrackedJobsLocked(mUid, network); } } updateTrackedJobs(mUid, network); } } // Network transitions have some complicated behavior that JS doesn't handle very well. // Network transitions have some complicated behavior that JS doesn't handle very well. Loading Loading @@ -993,8 +1006,8 @@ public final class ConnectivityController extends RestrictingController implemen if (Objects.equals(mDefaultNetwork, network)) { if (Objects.equals(mDefaultNetwork, network)) { mDefaultNetwork = null; mDefaultNetwork = null; } } updateTrackedJobsLocked(mUid, network); } } updateTrackedJobs(mUid, network); } } private void dumpLocked(IndentingPrintWriter pw) { private void dumpLocked(IndentingPrintWriter pw) { Loading Loading
apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java +30 −29 Original line number Original line Diff line number Diff line Loading @@ -746,12 +746,15 @@ public class JobSchedulerService extends com.android.server.SystemService Slog.d(TAG, "Removing jobs for package " + pkgName Slog.d(TAG, "Removing jobs for package " + pkgName + " in user " + userId); + " in user " + userId); } } // By the time we get here, the process should have already synchronized (mLock) { // been stopped, so the app wouldn't get the stop reason, // By the time we get here, the process should have // so just put USER instead of UNINSTALL or DISABLED. // already been stopped, so the app wouldn't get the cancelJobsForPackageAndUid(pkgName, pkgUid, // stop reason, so just put USER instead of UNINSTALL // or DISABLED. cancelJobsForPackageAndUidLocked(pkgName, pkgUid, JobParameters.STOP_REASON_USER, "app disabled"); JobParameters.STOP_REASON_USER, "app disabled"); } } } } catch (RemoteException|IllegalArgumentException e) { } catch (RemoteException|IllegalArgumentException e) { /* /* * IllegalArgumentException means that the package doesn't exist. * IllegalArgumentException means that the package doesn't exist. Loading Loading @@ -791,9 +794,9 @@ public class JobSchedulerService extends com.android.server.SystemService // By the time we get here, the process should have already // By the time we get here, the process should have already // been stopped, so the app wouldn't get the stop reason, // been stopped, so the app wouldn't get the stop reason, // so just put USER instead of UNINSTALL or DISABLED. // so just put USER instead of UNINSTALL or DISABLED. cancelJobsForPackageAndUid(pkgName, uidRemoved, JobParameters.STOP_REASON_USER, "app uninstalled"); synchronized (mLock) { synchronized (mLock) { cancelJobsForPackageAndUidLocked(pkgName, uidRemoved, JobParameters.STOP_REASON_USER, "app uninstalled"); for (int c = 0; c < mControllers.size(); ++c) { for (int c = 0; c < mControllers.size(); ++c) { mControllers.get(c).onAppRemovedLocked(pkgName, pkgUid); mControllers.get(c).onAppRemovedLocked(pkgName, pkgUid); } } Loading @@ -812,8 +815,8 @@ public class JobSchedulerService extends com.android.server.SystemService if (DEBUG) { if (DEBUG) { Slog.d(TAG, "Removing jobs for user: " + userId); Slog.d(TAG, "Removing jobs for user: " + userId); } } cancelJobsForUser(userId); synchronized (mLock) { synchronized (mLock) { cancelJobsForUserLocked(userId); for (int c = 0; c < mControllers.size(); ++c) { for (int c = 0; c < mControllers.size(); ++c) { mControllers.get(c).onUserRemovedLocked(userId); mControllers.get(c).onUserRemovedLocked(userId); } } Loading Loading @@ -844,11 +847,13 @@ public class JobSchedulerService extends com.android.server.SystemService if (DEBUG) { if (DEBUG) { Slog.d(TAG, "Removing jobs for pkg " + pkgName + " at uid " + pkgUid); Slog.d(TAG, "Removing jobs for pkg " + pkgName + " at uid " + pkgUid); } } cancelJobsForPackageAndUid(pkgName, pkgUid, synchronized (mLock) { cancelJobsForPackageAndUidLocked(pkgName, pkgUid, JobParameters.STOP_REASON_USER, "app force stopped"); JobParameters.STOP_REASON_USER, "app force stopped"); } } } } } } } }; }; private String getPackageName(Intent intent) { private String getPackageName(Intent intent) { Loading Loading @@ -1106,8 +1111,7 @@ public class JobSchedulerService extends com.android.server.SystemService } } } } void cancelJobsForUser(int userHandle) { private void cancelJobsForUserLocked(int userHandle) { synchronized (mLock) { final List<JobStatus> jobsForUser = mJobs.getJobsByUser(userHandle); final List<JobStatus> jobsForUser = mJobs.getJobsByUser(userHandle); for (int i = 0; i < jobsForUser.size(); i++) { for (int i = 0; i < jobsForUser.size(); i++) { JobStatus toRemove = jobsForUser.get(i); JobStatus toRemove = jobsForUser.get(i); Loading @@ -1117,7 +1121,6 @@ public class JobSchedulerService extends com.android.server.SystemService "user removed"); "user removed"); } } } } } private void cancelJobsForNonExistentUsers() { private void cancelJobsForNonExistentUsers() { UserManagerInternal umi = LocalServices.getService(UserManagerInternal.class); UserManagerInternal umi = LocalServices.getService(UserManagerInternal.class); Loading @@ -1126,13 +1129,12 @@ public class JobSchedulerService extends com.android.server.SystemService } } } } void cancelJobsForPackageAndUid(String pkgName, int uid, @JobParameters.StopReason int reason, private void cancelJobsForPackageAndUidLocked(String pkgName, int uid, String debugReason) { @JobParameters.StopReason int reason, String debugReason) { if ("android".equals(pkgName)) { if ("android".equals(pkgName)) { Slog.wtfStack(TAG, "Can't cancel all jobs for system package"); Slog.wtfStack(TAG, "Can't cancel all jobs for system package"); return; return; } } synchronized (mLock) { final List<JobStatus> jobsForUid = mJobs.getJobsByUid(uid); final List<JobStatus> jobsForUid = mJobs.getJobsByUid(uid); for (int i = jobsForUid.size() - 1; i >= 0; i--) { for (int i = jobsForUid.size() - 1; i >= 0; i--) { final JobStatus job = jobsForUid.get(i); final JobStatus job = jobsForUid.get(i); Loading @@ -1141,7 +1143,6 @@ public class JobSchedulerService extends com.android.server.SystemService } } } } } } } /** /** * Entry point from client to cancel all jobs originating from their uid. * Entry point from client to cancel all jobs originating from their uid. Loading
apex/jobscheduler/service/java/com/android/server/job/controllers/ConnectivityController.java +35 −22 Original line number Original line Diff line number Diff line Loading @@ -226,10 +226,23 @@ public final class ConnectivityController extends RestrictingController implemen jobs.remove(jobStatus); jobs.remove(jobStatus); } } UidStats us = mUidStats.get(jobStatus.getSourceUid()); UidStats us = mUidStats.get(jobStatus.getSourceUid()); if (us == null) { // This shouldn't be happening. We create a UidStats object for the app when the // first job is scheduled in maybeStartTrackingJobLocked() and only ever drop the // object if the app is uninstalled or the user is removed. That means that if we // end up in this situation, onAppRemovedLocked() or onUserRemovedLocked() was // called before maybeStopTrackingJobLocked(), which is the reverse order of what // JobSchedulerService does (JSS calls maybeStopTrackingJobLocked() for all jobs // before calling onAppRemovedLocked() or onUserRemovedLocked()). Slog.wtfStack(TAG, "UidStats was null after job for " + jobStatus.getSourcePackageName() + " was registered"); } else { us.numReadyWithConnectivity--; us.numReadyWithConnectivity--; if (jobStatus.madeActive != 0) { if (jobStatus.madeActive != 0) { us.numRunning--; us.numRunning--; } } } maybeRevokeStandbyExceptionLocked(jobStatus); maybeRevokeStandbyExceptionLocked(jobStatus); maybeAdjustRegisteredCallbacksLocked(); maybeAdjustRegisteredCallbacksLocked(); } } Loading Loading @@ -773,8 +786,8 @@ public final class ConnectivityController extends RestrictingController implemen * @param filterNetwork only update jobs that would use this * @param filterNetwork only update jobs that would use this * {@link Network}, or {@code null} to update all tracked jobs. * {@link Network}, or {@code null} to update all tracked jobs. */ */ private void updateTrackedJobs(int filterUid, Network filterNetwork) { @GuardedBy("mLock") synchronized (mLock) { private void updateTrackedJobsLocked(int filterUid, Network filterNetwork) { boolean changed = false; boolean changed = false; if (filterUid == -1) { if (filterUid == -1) { for (int i = mTrackedJobs.size() - 1; i >= 0; i--) { for (int i = mTrackedJobs.size() - 1; i >= 0; i--) { Loading @@ -787,8 +800,8 @@ public final class ConnectivityController extends RestrictingController implemen mStateChangedListener.onControllerStateChanged(); mStateChangedListener.onControllerStateChanged(); } } } } } @GuardedBy("mLock") private boolean updateTrackedJobsLocked(ArraySet<JobStatus> jobs, Network filterNetwork) { private boolean updateTrackedJobsLocked(ArraySet<JobStatus> jobs, Network filterNetwork) { if (jobs == null || jobs.size() == 0) { if (jobs == null || jobs.size() == 0) { return false; return false; Loading Loading @@ -875,10 +888,10 @@ public final class ConnectivityController extends RestrictingController implemen } } synchronized (mLock) { synchronized (mLock) { mAvailableNetworks.put(network, capabilities); mAvailableNetworks.put(network, capabilities); } updateTrackedJobsLocked(-1, network); updateTrackedJobs(-1, network); maybeAdjustRegisteredCallbacksLocked(); maybeAdjustRegisteredCallbacksLocked(); } } } @Override @Override public void onLost(Network network) { public void onLost(Network network) { Loading @@ -893,10 +906,10 @@ public final class ConnectivityController extends RestrictingController implemen callback.mDefaultNetwork = null; callback.mDefaultNetwork = null; } } } } } updateTrackedJobsLocked(-1, network); updateTrackedJobs(-1, network); maybeAdjustRegisteredCallbacksLocked(); maybeAdjustRegisteredCallbacksLocked(); } } } }; }; private class CcHandler extends Handler { private class CcHandler extends Handler { Loading @@ -909,7 +922,7 @@ public final class ConnectivityController extends RestrictingController implemen synchronized (mLock) { synchronized (mLock) { switch (msg.what) { switch (msg.what) { case MSG_REEVALUATE_JOBS: case MSG_REEVALUATE_JOBS: updateTrackedJobs(-1, null); updateTrackedJobsLocked(-1, null); break; break; } } } } Loading Loading @@ -949,8 +962,8 @@ public final class ConnectivityController extends RestrictingController implemen synchronized (mLock) { synchronized (mLock) { mDefaultNetwork = network; mDefaultNetwork = network; mBlocked = blocked; mBlocked = blocked; updateTrackedJobsLocked(mUid, network); } } updateTrackedJobs(mUid, network); } } // Network transitions have some complicated behavior that JS doesn't handle very well. // Network transitions have some complicated behavior that JS doesn't handle very well. Loading Loading @@ -993,8 +1006,8 @@ public final class ConnectivityController extends RestrictingController implemen if (Objects.equals(mDefaultNetwork, network)) { if (Objects.equals(mDefaultNetwork, network)) { mDefaultNetwork = null; mDefaultNetwork = null; } } updateTrackedJobsLocked(mUid, network); } } updateTrackedJobs(mUid, network); } } private void dumpLocked(IndentingPrintWriter pw) { private void dumpLocked(IndentingPrintWriter pw) { Loading