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

Commit cdff2be1 authored by Christopher Tate's avatar Christopher Tate Committed by android-build-merger
Browse files

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

am: 5b330438

Change-Id: Ibddc2496e4aa33ec5c8a34cc3f99b0a722146422
parents f26d22dd 5b330438
Loading
Loading
Loading
Loading
+54 −4
Original line number Original line Diff line number Diff line
@@ -28,6 +28,7 @@ import java.util.Comparator;
import java.util.Iterator;
import java.util.Iterator;
import java.util.List;
import java.util.List;


import android.app.Activity;
import android.app.ActivityManager;
import android.app.ActivityManager;
import android.app.ActivityManagerNative;
import android.app.ActivityManagerNative;
import android.app.AppGlobals;
import android.app.AppGlobals;
@@ -43,7 +44,9 @@ import android.content.ContentResolver;
import android.content.Context;
import android.content.Context;
import android.content.Intent;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageManager;
import android.content.pm.IPackageManager;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager;
import android.content.pm.ServiceInfo;
import android.content.pm.ServiceInfo;
import android.content.pm.PackageManager.NameNotFoundException;
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() {
    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
        @Override
        @Override
        public void onReceive(Context context, Intent intent) {
        public void onReceive(Context context, Intent intent) {
            final String action = intent.getAction();
            if (DEBUG) {
            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
                // 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.
                // the case the component name will be a bare package name.
                final String pkgName = getPackageName(intent);
                final String pkgName = getPackageName(intent);
@@ -433,7 +437,7 @@ public final class JobSchedulerService extends com.android.server.SystemService
                } else {
                } else {
                    Slog.w(TAG, "PACKAGE_CHANGED for " + pkgName + " / uid " + pkgUid);
                    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
                // If this is an outright uninstall rather than the first half of an
                // app update sequence, cancel the jobs associated with the app.
                // app update sequence, cancel the jobs associated with the app.
                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
@@ -443,12 +447,43 @@ public final class JobSchedulerService extends com.android.server.SystemService
                    }
                    }
                    cancelJobsForUid(uidRemoved, true);
                    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);
                final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
                if (DEBUG) {
                if (DEBUG) {
                    Slog.d(TAG, "Removing jobs for user: " + userId);
                    Slog.d(TAG, "Removing jobs for user: " + userId);
                }
                }
                cancelJobsForUser(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.
     * 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
     * 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();
            final IntentFilter filter = new IntentFilter();
            filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
            filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
            filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
            filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
            filter.addAction(Intent.ACTION_PACKAGE_RESTARTED);
            filter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
            filter.addDataScheme("package");
            filter.addDataScheme("package");
            getContext().registerReceiverAsUser(
            getContext().registerReceiverAsUser(
                    mBroadcastReceiver, UserHandle.ALL, filter, null, null);
                    mBroadcastReceiver, UserHandle.ALL, filter, null, null);