Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6242b006 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Fix async behavior and address possible race conditions." into sc-dev

parents c092d80a 626ec290
Loading
Loading
Loading
Loading
+30 −29
Original line number Diff line number Diff line
@@ -746,12 +746,15 @@ public class JobSchedulerService extends com.android.server.SystemService
                                            Slog.d(TAG, "Removing jobs for package " + pkgName
                                                    + " in user " + userId);
                                        }
                                        // By the time we get here, the process should have already
                                        // been stopped, so the app wouldn't get the stop reason,
                                        // so just put USER instead of UNINSTALL or DISABLED.
                                        cancelJobsForPackageAndUid(pkgName, pkgUid,
                                        synchronized (mLock) {
                                            // By the time we get here, the process should have
                                            // already been stopped, so the app wouldn't get the
                                            // stop reason, so just put USER instead of UNINSTALL
                                            // or DISABLED.
                                            cancelJobsForPackageAndUidLocked(pkgName, pkgUid,
                                                    JobParameters.STOP_REASON_USER, "app disabled");
                                        }
                                    }
                                } catch (RemoteException|IllegalArgumentException e) {
                                    /*
                                     * IllegalArgumentException means that the package doesn't exist.
@@ -791,9 +794,9 @@ public class JobSchedulerService extends com.android.server.SystemService
                    // By the time we get here, the process should have already
                    // been stopped, so the app wouldn't get the stop reason,
                    // so just put USER instead of UNINSTALL or DISABLED.
                    cancelJobsForPackageAndUid(pkgName, uidRemoved,
                            JobParameters.STOP_REASON_USER, "app uninstalled");
                    synchronized (mLock) {
                        cancelJobsForPackageAndUidLocked(pkgName, uidRemoved,
                                JobParameters.STOP_REASON_USER, "app uninstalled");
                        for (int c = 0; c < mControllers.size(); ++c) {
                            mControllers.get(c).onAppRemovedLocked(pkgName, pkgUid);
                        }
@@ -812,8 +815,8 @@ public class JobSchedulerService extends com.android.server.SystemService
                if (DEBUG) {
                    Slog.d(TAG, "Removing jobs for user: " + userId);
                }
                cancelJobsForUser(userId);
                synchronized (mLock) {
                    cancelJobsForUserLocked(userId);
                    for (int c = 0; c < mControllers.size(); ++c) {
                        mControllers.get(c).onUserRemovedLocked(userId);
                    }
@@ -844,11 +847,13 @@ public class JobSchedulerService extends com.android.server.SystemService
                    if (DEBUG) {
                        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");
                    }
                }
            }
        }
    };

    private String getPackageName(Intent intent) {
@@ -1106,8 +1111,7 @@ public class JobSchedulerService extends com.android.server.SystemService
        }
    }

    void cancelJobsForUser(int userHandle) {
        synchronized (mLock) {
    private void cancelJobsForUserLocked(int userHandle) {
        final List<JobStatus> jobsForUser = mJobs.getJobsByUser(userHandle);
        for (int i = 0; i < jobsForUser.size(); i++) {
            JobStatus toRemove = jobsForUser.get(i);
@@ -1117,7 +1121,6 @@ public class JobSchedulerService extends com.android.server.SystemService
                    "user removed");
        }
    }
    }

    private void cancelJobsForNonExistentUsers() {
        UserManagerInternal umi = LocalServices.getService(UserManagerInternal.class);
@@ -1126,13 +1129,12 @@ public class JobSchedulerService extends com.android.server.SystemService
        }
    }

    void cancelJobsForPackageAndUid(String pkgName, int uid, @JobParameters.StopReason int reason,
            String debugReason) {
    private void cancelJobsForPackageAndUidLocked(String pkgName, int uid,
            @JobParameters.StopReason int reason, String debugReason) {
        if ("android".equals(pkgName)) {
            Slog.wtfStack(TAG, "Can't cancel all jobs for system package");
            return;
        }
        synchronized (mLock) {
        final List<JobStatus> jobsForUid = mJobs.getJobsByUid(uid);
        for (int i = jobsForUid.size() - 1; i >= 0; i--) {
            final JobStatus job = jobsForUid.get(i);
@@ -1141,7 +1143,6 @@ public class JobSchedulerService extends com.android.server.SystemService
            }
        }
    }
    }

    /**
     * Entry point from client to cancel all jobs originating from their uid.
+35 −22
Original line number Diff line number Diff line
@@ -226,10 +226,23 @@ public final class ConnectivityController extends RestrictingController implemen
                jobs.remove(jobStatus);
            }
            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--;
                if (jobStatus.madeActive != 0) {
                    us.numRunning--;
                }
            }
            maybeRevokeStandbyExceptionLocked(jobStatus);
            maybeAdjustRegisteredCallbacksLocked();
        }
@@ -773,8 +786,8 @@ public final class ConnectivityController extends RestrictingController implemen
     * @param filterNetwork only update jobs that would use this
     *                      {@link Network}, or {@code null} to update all tracked jobs.
     */
    private void updateTrackedJobs(int filterUid, Network filterNetwork) {
        synchronized (mLock) {
    @GuardedBy("mLock")
    private void updateTrackedJobsLocked(int filterUid, Network filterNetwork) {
        boolean changed = false;
        if (filterUid == -1) {
            for (int i = mTrackedJobs.size() - 1; i >= 0; i--) {
@@ -787,8 +800,8 @@ public final class ConnectivityController extends RestrictingController implemen
            mStateChangedListener.onControllerStateChanged();
        }
    }
    }

    @GuardedBy("mLock")
    private boolean updateTrackedJobsLocked(ArraySet<JobStatus> jobs, Network filterNetwork) {
        if (jobs == null || jobs.size() == 0) {
            return false;
@@ -875,10 +888,10 @@ public final class ConnectivityController extends RestrictingController implemen
            }
            synchronized (mLock) {
                mAvailableNetworks.put(network, capabilities);
            }
            updateTrackedJobs(-1, network);
                updateTrackedJobsLocked(-1, network);
                maybeAdjustRegisteredCallbacksLocked();
            }
        }

        @Override
        public void onLost(Network network) {
@@ -893,10 +906,10 @@ public final class ConnectivityController extends RestrictingController implemen
                        callback.mDefaultNetwork = null;
                    }
                }
            }
            updateTrackedJobs(-1, network);
                updateTrackedJobsLocked(-1, network);
                maybeAdjustRegisteredCallbacksLocked();
            }
        }
    };

    private class CcHandler extends Handler {
@@ -909,7 +922,7 @@ public final class ConnectivityController extends RestrictingController implemen
            synchronized (mLock) {
                switch (msg.what) {
                    case MSG_REEVALUATE_JOBS:
                        updateTrackedJobs(-1, null);
                        updateTrackedJobsLocked(-1, null);
                        break;
                }
            }
@@ -949,8 +962,8 @@ public final class ConnectivityController extends RestrictingController implemen
            synchronized (mLock) {
                mDefaultNetwork = network;
                mBlocked = blocked;
                updateTrackedJobsLocked(mUid, network);
            }
            updateTrackedJobs(mUid, network);
        }

        // Network transitions have some complicated behavior that JS doesn't handle very well.
@@ -993,8 +1006,8 @@ public final class ConnectivityController extends RestrictingController implemen
                if (Objects.equals(mDefaultNetwork, network)) {
                    mDefaultNetwork = null;
                }
                updateTrackedJobsLocked(mUid, network);
            }
            updateTrackedJobs(mUid, network);
        }

        private void dumpLocked(IndentingPrintWriter pw) {