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

Commit 5b330438 authored by Chris Tate's avatar Chris Tate Committed by Android (Google) Code Review
Browse files

Merge "Remove scheduled jobs when an app is force-stopped" into nyc-mr1-dev

parents 6aa50407 ee7805be
Loading
Loading
Loading
Loading
+54 −4
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import java.util.Comparator;
import java.util.Iterator;
import java.util.List;

import android.app.Activity;
import android.app.ActivityManager;
import android.app.ActivityManagerNative;
import android.app.AppGlobals;
@@ -43,7 +44,9 @@ import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageManager;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.ServiceInfo;
import android.content.pm.PackageManager.NameNotFoundException;
@@ -396,10 +399,11 @@ public final class JobSchedulerService extends com.android.server.SystemService
    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            final String action = intent.getAction();
            if (DEBUG) {
                Slog.d(TAG, "Receieved: " + intent.getAction());
                Slog.d(TAG, "Receieved: " + action);
            }
            if (Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())) {
            if (Intent.ACTION_PACKAGE_CHANGED.equals(action)) {
                // Purge the app's jobs if the whole package was just disabled.  When this is
                // the case the component name will be a bare package name.
                final String pkgName = getPackageName(intent);
@@ -433,7 +437,7 @@ public final class JobSchedulerService extends com.android.server.SystemService
                } else {
                    Slog.w(TAG, "PACKAGE_CHANGED for " + pkgName + " / uid " + pkgUid);
                }
            } else if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
            } else if (Intent.ACTION_PACKAGE_REMOVED.equals(action)) {
                // If this is an outright uninstall rather than the first half of an
                // app update sequence, cancel the jobs associated with the app.
                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
@@ -443,12 +447,43 @@ public final class JobSchedulerService extends com.android.server.SystemService
                    }
                    cancelJobsForUid(uidRemoved, true);
                }
            } else if (Intent.ACTION_USER_REMOVED.equals(intent.getAction())) {
            } else if (Intent.ACTION_USER_REMOVED.equals(action)) {
                final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
                if (DEBUG) {
                    Slog.d(TAG, "Removing jobs for user: " + userId);
                }
                cancelJobsForUser(userId);
            } else if (Intent.ACTION_QUERY_PACKAGE_RESTART.equals(action)) {
                // Has this package scheduled any jobs, such that we will take action
                // if it were to be force-stopped?
                final int pkgUid = intent.getIntExtra(Intent.EXTRA_UID, -1);
                final String pkgName = intent.getData().getSchemeSpecificPart();
                if (pkgUid != -1) {
                    List<JobStatus> jobsForUid;
                    synchronized (mLock) {
                        jobsForUid = mJobs.getJobsByUid(pkgUid);
                    }
                    for (int i = jobsForUid.size() - 1; i >= 0; i--) {
                        if (jobsForUid.get(i).getSourcePackageName().equals(pkgName)) {
                            if (DEBUG) {
                                Slog.d(TAG, "Restart query: package " + pkgName + " at uid "
                                        + pkgUid + " has jobs");
                            }
                            setResultCode(Activity.RESULT_OK);
                            break;
                        }
                    }
                }
            } else if (Intent.ACTION_PACKAGE_RESTARTED.equals(action)) {
                // possible force-stop
                final int pkgUid = intent.getIntExtra(Intent.EXTRA_UID, -1);
                final String pkgName = intent.getData().getSchemeSpecificPart();
                if (pkgUid != -1) {
                    if (DEBUG) {
                        Slog.d(TAG, "Removing jobs for pkg " + pkgName + " at uid " + pkgUid);
                    }
                    cancelJobsForPackageAndUid(pkgName, pkgUid);
                }
            }
        }
    };
@@ -583,6 +618,19 @@ public final class JobSchedulerService extends com.android.server.SystemService
        }
    }

    void cancelJobsForPackageAndUid(String pkgName, int uid) {
        List<JobStatus> jobsForUid;
        synchronized (mLock) {
            jobsForUid = mJobs.getJobsByUid(uid);
        }
        for (int i = jobsForUid.size() - 1; i >= 0; i--) {
            final JobStatus job = jobsForUid.get(i);
            if (job.getSourcePackageName().equals(pkgName)) {
                cancelJobImpl(job, null);
            }
        }
    }

    /**
     * Entry point from client to cancel all jobs originating from their uid.
     * This will remove the job from the master list, and cancel the job if it was staged for
@@ -754,6 +802,8 @@ public final class JobSchedulerService extends com.android.server.SystemService
            final IntentFilter filter = new IntentFilter();
            filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
            filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
            filter.addAction(Intent.ACTION_PACKAGE_RESTARTED);
            filter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
            filter.addDataScheme("package");
            getContext().registerReceiverAsUser(
                    mBroadcastReceiver, UserHandle.ALL, filter, null, null);