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

Commit 31047c97 authored by Android Build Coastguard Worker's avatar Android Build Coastguard Worker
Browse files

Snap for 11186783 from 3d182295 to 24Q1-release

Change-Id: I989da825156b978cfb29793c1a079b37f5776467
parents 7942c913 3d182295
Loading
Loading
Loading
Loading
+13 −3
Original line number Diff line number Diff line
@@ -1433,10 +1433,10 @@ public class JobSchedulerService extends com.android.server.SystemService
                        Slog.d(TAG, "Removing jobs for pkg " + pkgName + " at uid " + pkgUid);
                    }
                    synchronized (mLock) {
                        // Exclude jobs scheduled on behalf of this app for now because SyncManager
                        // Exclude jobs scheduled on behalf of this app because SyncManager
                        // and other job proxy agents may not know to reschedule the job properly
                        // after force stop.
                        // TODO(209852664): determine how to best handle syncs & other proxied jobs
                        // Proxied jobs will not be allowed to run if the source app is stopped.
                        cancelJobsForPackageAndUidLocked(pkgName, pkgUid,
                                /* includeSchedulingApp */ true, /* includeSourceApp */ false,
                                JobParameters.STOP_REASON_USER,
@@ -1448,7 +1448,9 @@ public class JobSchedulerService extends com.android.server.SystemService
        }
    };

    private String getPackageName(Intent intent) {
    /** Returns the package name stored in the intent's data. */
    @Nullable
    public static String getPackageName(Intent intent) {
        Uri uri = intent.getData();
        String pkg = uri != null ? uri.getSchemeSpecificPart() : null;
        return pkg;
@@ -5365,6 +5367,14 @@ public class JobSchedulerService extends com.android.server.SystemService
            }
            pw.println();

            pw.println("Aconfig flags:");
            pw.increaseIndent();
            pw.print(Flags.FLAG_THROW_ON_UNSUPPORTED_BIAS_USAGE,
                    Flags.throwOnUnsupportedBiasUsage());
            pw.println();
            pw.decreaseIndent();
            pw.println();

            for (int i = mJobRestrictions.size() - 1; i >= 0; i--) {
                mJobRestrictions.get(i).dumpConstants(pw);
            }
+27 −0
Original line number Diff line number Diff line
@@ -58,6 +58,8 @@ public final class JobSchedulerShellCommand extends BasicShellCommandHandler {
                    return cancelJob(pw);
                case "monitor-battery":
                    return monitorBattery(pw);
                case "get-aconfig-flag-state":
                    return getAconfigFlagState(pw);
                case "get-battery-seq":
                    return getBatterySeq(pw);
                case "get-battery-charging":
@@ -336,6 +338,28 @@ public final class JobSchedulerShellCommand extends BasicShellCommandHandler {
        return 0;
    }

    private int getAconfigFlagState(PrintWriter pw) throws Exception {
        checkPermission("get aconfig flag state");

        final String flagName = getNextArgRequired();

        switch (flagName) {
            case android.app.job.Flags.FLAG_JOB_DEBUG_INFO_APIS:
                pw.println(android.app.job.Flags.jobDebugInfoApis());
                break;
            case android.app.job.Flags.FLAG_ENFORCE_MINIMUM_TIME_WINDOWS:
                pw.println(android.app.job.Flags.enforceMinimumTimeWindows());
                break;
            case com.android.server.job.Flags.FLAG_THROW_ON_UNSUPPORTED_BIAS_USAGE:
                pw.println(com.android.server.job.Flags.throwOnUnsupportedBiasUsage());
                break;
            default:
                pw.println("Unknown flag: " + flagName);
                break;
        }
        return 0;
    }

    private int getBatterySeq(PrintWriter pw) {
        int seq = mInternal.getBatterySeq();
        pw.println(seq);
@@ -693,6 +717,9 @@ public final class JobSchedulerShellCommand extends BasicShellCommandHandler {
        pw.println("  monitor-battery [on|off]");
        pw.println("    Control monitoring of all battery changes.  Off by default.  Turning");
        pw.println("    on makes get-battery-seq useful.");
        pw.println("  get-aconfig-flag-state FULL_FLAG_NAME");
        pw.println("    Return the state of the specified aconfig flag, if known. The flag name");
        pw.println("         must be fully qualified.");
        pw.println("  get-battery-seq");
        pw.println("    Return the last battery update sequence number that was received.");
        pw.println("  get-battery-charging");
+115 −4
Original line number Diff line number Diff line
@@ -17,18 +17,26 @@
package com.android.server.job.controllers;

import static com.android.server.job.JobSchedulerService.NEVER_INDEX;
import static com.android.server.job.JobSchedulerService.getPackageName;
import static com.android.server.job.JobSchedulerService.sElapsedRealtimeClock;

import android.app.ActivityManager;
import android.app.ActivityManagerInternal;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManagerInternal;
import android.os.SystemClock;
import android.os.UserHandle;
import android.util.ArraySet;
import android.util.IndentingPrintWriter;
import android.util.Log;
import android.util.Slog;
import android.util.SparseArrayMap;
import android.util.proto.ProtoOutputStream;

import com.android.internal.annotations.GuardedBy;
import com.android.server.AppStateTracker;
import com.android.server.AppStateTrackerImpl;
import com.android.server.AppStateTrackerImpl.Listener;
@@ -50,6 +58,8 @@ import java.util.function.Predicate;
 *
 * - the uid-active boolean state expressed by the AppStateTracker.  Jobs in 'active'
 *    uids are inherently eligible to run jobs regardless of the uid's standby bucket.
 *
 * - the app's stopped state
 */
public final class BackgroundJobsController extends StateController {
    private static final String TAG = "JobScheduler.Background";
@@ -63,9 +73,48 @@ public final class BackgroundJobsController extends StateController {

    private final ActivityManagerInternal mActivityManagerInternal;
    private final AppStateTrackerImpl mAppStateTracker;
    private final PackageManagerInternal mPackageManagerInternal;

    @GuardedBy("mLock")
    private final SparseArrayMap<String, Boolean> mPackageStoppedState = new SparseArrayMap<>();

    private final UpdateJobFunctor mUpdateJobFunctor = new UpdateJobFunctor();

    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            final String pkgName = getPackageName(intent);
            final int pkgUid = intent.getIntExtra(Intent.EXTRA_UID, -1);
            final String action = intent.getAction();
            if (pkgUid == -1) {
                Slog.e(TAG, "Didn't get package UID in intent (" + action + ")");
                return;
            }

            if (DEBUG) {
                Slog.d(TAG, "Got " + action + " for " + pkgUid + "/" + pkgName);
            }

            switch (action) {
                case Intent.ACTION_PACKAGE_RESTARTED: {
                    synchronized (mLock) {
                        mPackageStoppedState.add(pkgUid, pkgName, Boolean.TRUE);
                        updateJobRestrictionsForUidLocked(pkgUid, false);
                    }
                }
                break;

                case Intent.ACTION_PACKAGE_UNSTOPPED: {
                    synchronized (mLock) {
                        mPackageStoppedState.add(pkgUid, pkgName, Boolean.FALSE);
                        updateJobRestrictionsLocked(pkgUid, UNKNOWN);
                    }
                }
                break;
            }
        }
    };

    public BackgroundJobsController(JobSchedulerService service) {
        super(service);

@@ -73,11 +122,18 @@ public final class BackgroundJobsController extends StateController {
                LocalServices.getService(ActivityManagerInternal.class));
        mAppStateTracker = (AppStateTrackerImpl) Objects.requireNonNull(
                LocalServices.getService(AppStateTracker.class));
        mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class);
    }

    @Override
    public void startTrackingLocked() {
        mAppStateTracker.addListener(mForceAppStandbyListener);
        final IntentFilter filter = new IntentFilter();
        filter.addAction(Intent.ACTION_PACKAGE_RESTARTED);
        filter.addAction(Intent.ACTION_PACKAGE_UNSTOPPED);
        filter.addDataScheme("package");
        mContext.registerReceiverAsUser(
                mBroadcastReceiver, UserHandle.ALL, filter, null, null);
    }

    @Override
@@ -98,12 +154,46 @@ public final class BackgroundJobsController extends StateController {
        }
    }

    @Override
    public void onAppRemovedLocked(String packageName, int uid) {
        mPackageStoppedState.delete(uid, packageName);
    }

    @Override
    public void onUserRemovedLocked(int userId) {
        for (int u = mPackageStoppedState.numMaps() - 1; u >= 0; --u) {
            final int uid = mPackageStoppedState.keyAt(u);
            if (UserHandle.getUserId(uid) == userId) {
                mPackageStoppedState.deleteAt(u);
            }
        }
    }

    @Override
    public void dumpControllerStateLocked(final IndentingPrintWriter pw,
            final Predicate<JobStatus> predicate) {
        pw.println("Aconfig flags:");
        pw.increaseIndent();
        pw.print(android.content.pm.Flags.FLAG_STAY_STOPPED,
                android.content.pm.Flags.stayStopped());
        pw.println();
        pw.decreaseIndent();
        pw.println();

        mAppStateTracker.dump(pw);
        pw.println();

        pw.println("Stopped packages:");
        pw.increaseIndent();
        mPackageStoppedState.forEach((uid, pkgName, isStopped) -> {
            pw.print(uid);
            pw.print(":");
            pw.print(pkgName);
            pw.print("=");
            pw.println(isStopped);
        });
        pw.println();

        mService.getJobStore().forEachJob(predicate, (jobStatus) -> {
            final int uid = jobStatus.getSourceUid();
            final String sourcePkg = jobStatus.getSourcePackageName();
@@ -205,14 +295,34 @@ public final class BackgroundJobsController extends StateController {
        }
    }

    private boolean isPackageStopped(String packageName, int uid) {
        if (mPackageStoppedState.contains(uid, packageName)) {
            return mPackageStoppedState.get(uid, packageName);
        }
        final boolean isStopped = mPackageManagerInternal.isPackageStopped(packageName, uid);
        mPackageStoppedState.add(uid, packageName, isStopped);
        return isStopped;
    }

    boolean updateSingleJobRestrictionLocked(JobStatus jobStatus, final long nowElapsed,
            int activeState) {
        final int uid = jobStatus.getSourceUid();
        final String packageName = jobStatus.getSourcePackageName();

        final boolean isUserBgRestricted =
                !mActivityManagerInternal.isBgAutoRestrictedBucketFeatureFlagEnabled()
                        && !mAppStateTracker.isRunAnyInBackgroundAppOpsAllowed(uid, packageName);
        final boolean isSourcePkgStopped =
                isPackageStopped(jobStatus.getSourcePackageName(), jobStatus.getSourceUid());
        final boolean isCallingPkgStopped;
        if (!jobStatus.isProxyJob()) {
            isCallingPkgStopped = isSourcePkgStopped;
        } else {
            isCallingPkgStopped =
                    isPackageStopped(jobStatus.getCallingPackageName(), jobStatus.getUid());
        }
        final boolean isStopped = android.content.pm.Flags.stayStopped()
                && (isCallingPkgStopped || isSourcePkgStopped);
        final boolean isUserBgRestricted = isStopped
                || (!mActivityManagerInternal.isBgAutoRestrictedBucketFeatureFlagEnabled()
                        && !mAppStateTracker.isRunAnyInBackgroundAppOpsAllowed(uid, packageName));
        // If a job started with the foreground flag, it'll cause the UID to stay active
        // and thus cause areJobsRestricted() to always return false, so if
        // areJobsRestricted() returns false and the app is BG restricted and not TOP,
@@ -233,7 +343,8 @@ public final class BackgroundJobsController extends StateController {
                && isUserBgRestricted
                && mService.getUidProcState(uid)
                        > ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
        final boolean canRun = !shouldStopImmediately
        // Don't let jobs (including proxied jobs) run if the app is in the stopped state.
        final boolean canRun = !isStopped && !shouldStopImmediately
                && !mAppStateTracker.areJobsRestricted(
                        uid, packageName, jobStatus.canRunInBatterySaver());

+6 −0
Original line number Diff line number Diff line
@@ -1102,6 +1102,12 @@ public final class JobStatus {
        return job.getService();
    }

    /** Return the package name of the app that scheduled the job. */
    public String getCallingPackageName() {
        return job.getService().getPackageName();
    }

    /** Return the package name of the app on whose behalf the job was scheduled. */
    public String getSourcePackageName() {
        return sourcePackageName;
    }
+5 −0
Original line number Diff line number Diff line
@@ -86,6 +86,7 @@ cc_library {
            static_libs: [
                "libidmap2_policies",
                "libidmap2_protos",
                "libpng",
            ],
            shared_libs: [
                "libandroidfw",
@@ -107,6 +108,7 @@ cc_library {
                "libcutils",
                "libidmap2_policies",
                "libidmap2_protos",
                "libpng",
                "libprotobuf-cpp-lite",
                "libutils",
                "libz",
@@ -185,6 +187,7 @@ cc_test {
    static_libs: [
        "libgmock",
        "libidmap2_protos",
        "libpng",
    ],
    target: {
        android: {
@@ -258,6 +261,7 @@ cc_binary {
                "libbase",
                "libcutils",
                "libidmap2",
                "libpng",
                "libprotobuf-cpp-lite",
                "libutils",
                "libz",
@@ -275,6 +279,7 @@ cc_binary {
                "libidmap2",
                "libidmap2_policies",
                "liblog",
                "libpng",
                "libprotobuf-cpp-lite",
                "libutils",
                "libziparchive",
Loading