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

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

Merge "Stop caching entire ServiceInfo object."

parents 4d83b158 60538aeb
Loading
Loading
Loading
Loading
+3 −4
Original line number Diff line number Diff line
@@ -2575,9 +2575,9 @@ public class JobSchedulerService extends com.android.server.SystemService
    }

    private boolean isComponentUsable(@NonNull JobStatus job) {
        final ServiceInfo service = job.serviceInfo;
        final String processName = job.serviceProcessName;

        if (service == null) {
        if (processName == null) {
            if (DEBUG) {
                Slog.v(TAG, "isComponentUsable: " + job.toShortString()
                        + " component not present");
@@ -2586,8 +2586,7 @@ public class JobSchedulerService extends com.android.server.SystemService
        }

        // Everything else checked out so far, so this is the final yes/no check
        final boolean appIsBad = mActivityManagerInternal.isAppBad(
                service.processName, service.applicationInfo.uid);
        final boolean appIsBad = mActivityManagerInternal.isAppBad(processName, job.getUid());
        if (DEBUG && appIsBad) {
            Slog.i(TAG, "App is bad for " + job.toShortString() + " so not runnable");
        }
+28 −22
Original line number Diff line number Diff line
@@ -93,7 +93,12 @@ public class ComponentController extends StateController {
        }
    };

    private final SparseArrayMap<ComponentName, ServiceInfo> mServiceInfoCache =
    /**
     * Cache containing the processName of the ServiceInfo (see {@link ServiceInfo#processName})
     * if the Service exists and is available.
     * {@code null} will be stored if the service is currently unavailable.
     */
    private final SparseArrayMap<ComponentName, String> mServiceProcessCache =
            new SparseArrayMap<>();

    private final ComponentStateUpdateFunctor mComponentStateUpdateFunctor =
@@ -135,18 +140,18 @@ public class ComponentController extends StateController {
    @Override
    @GuardedBy("mLock")
    public void onUserRemovedLocked(int userId) {
        mServiceInfoCache.delete(userId);
        mServiceProcessCache.delete(userId);
    }

    @Nullable
    @GuardedBy("mLock")
    private ServiceInfo getServiceInfoLocked(JobStatus jobStatus) {
    private String getServiceProcessLocked(JobStatus jobStatus) {
        final ComponentName service = jobStatus.getServiceComponent();
        final int userId = jobStatus.getUserId();
        if (mServiceInfoCache.contains(userId, service)) {
        if (mServiceProcessCache.contains(userId, service)) {
            // Return whatever is in the cache, even if it's null. When something changes, we
            // clear the cache.
            return mServiceInfoCache.get(userId, service);
            return mServiceProcessCache.get(userId, service);
        }

        ServiceInfo si;
@@ -165,30 +170,31 @@ public class ComponentController extends StateController {
            // Write null to the cache so we don't keep querying PM.
            si = null;
        }
        mServiceInfoCache.add(userId, service, si);
        final String processName = si == null ? null : si.processName;
        mServiceProcessCache.add(userId, service, processName);

        return si;
        return processName;
    }

    @GuardedBy("mLock")
    private boolean updateComponentEnabledStateLocked(JobStatus jobStatus) {
        final ServiceInfo service = getServiceInfoLocked(jobStatus);
        final String processName = getServiceProcessLocked(jobStatus);

        if (DEBUG && service == null) {
        if (DEBUG && processName == null) {
            Slog.v(TAG, jobStatus.toShortString() + " component not present");
        }
        final ServiceInfo ogService = jobStatus.serviceInfo;
        jobStatus.serviceInfo = service;
        return !Objects.equals(ogService, service);
        final String ogProcess = jobStatus.serviceProcessName;
        jobStatus.serviceProcessName = processName;
        return !Objects.equals(ogProcess, processName);
    }

    @GuardedBy("mLock")
    private void clearComponentsForPackageLocked(final int userId, final String pkg) {
        final int uIdx = mServiceInfoCache.indexOfKey(userId);
        for (int c = mServiceInfoCache.numElementsForKey(userId) - 1; c >= 0; --c) {
            final ComponentName cn = mServiceInfoCache.keyAt(uIdx, c);
        final int uIdx = mServiceProcessCache.indexOfKey(userId);
        for (int c = mServiceProcessCache.numElementsForKey(userId) - 1; c >= 0; --c) {
            final ComponentName cn = mServiceProcessCache.keyAt(uIdx, c);
            if (cn.getPackageName().equals(pkg)) {
                mServiceInfoCache.delete(userId, cn);
                mServiceProcessCache.delete(userId, cn);
            }
        }
    }
@@ -207,7 +213,7 @@ public class ComponentController extends StateController {

    private void updateComponentStateForUser(final int userId) {
        synchronized (mLock) {
            mServiceInfoCache.delete(userId);
            mServiceProcessCache.delete(userId);
            updateComponentStatesLocked(jobStatus -> {
                // Using user ID instead of source user ID because the service will run under the
                // user ID, not source user ID.
@@ -247,15 +253,15 @@ public class ComponentController extends StateController {
    @Override
    @GuardedBy("mLock")
    public void dumpControllerStateLocked(IndentingPrintWriter pw, Predicate<JobStatus> predicate) {
        for (int u = 0; u < mServiceInfoCache.numMaps(); ++u) {
            final int userId = mServiceInfoCache.keyAt(u);
            for (int p = 0; p < mServiceInfoCache.numElementsForKey(userId); ++p) {
                final ComponentName componentName = mServiceInfoCache.keyAt(u, p);
        for (int u = 0; u < mServiceProcessCache.numMaps(); ++u) {
            final int userId = mServiceProcessCache.keyAt(u);
            for (int p = 0; p < mServiceProcessCache.numElementsForKey(userId); ++p) {
                final ComponentName componentName = mServiceProcessCache.keyAt(u, p);
                pw.print(userId);
                pw.print("-");
                pw.print(componentName);
                pw.print(": ");
                pw.print(mServiceInfoCache.valueAt(u, p));
                pw.print(mServiceProcessCache.valueAt(u, p));
                pw.println();
            }
        }
+3 −4
Original line number Diff line number Diff line
@@ -35,7 +35,6 @@ import android.app.job.JobParameters;
import android.app.job.JobWorkItem;
import android.content.ClipData;
import android.content.ComponentName;
import android.content.pm.ServiceInfo;
import android.net.Network;
import android.net.NetworkRequest;
import android.net.Uri;
@@ -356,7 +355,7 @@ public final class JobStatus {
    public ArraySet<Uri> changedUris;
    public ArraySet<String> changedAuthorities;
    public Network network;
    public ServiceInfo serviceInfo;
    public String serviceProcessName;

    /** The evaluated bias of the job when it started running. */
    public int lastEvaluatedBias;
@@ -1757,7 +1756,7 @@ public final class JobStatus {
        // run if its constraints are satisfied).
        // DeviceNotDozing implicit constraint must be satisfied
        // NotRestrictedInBackground implicit constraint must be satisfied
        return mReadyNotDozing && mReadyNotRestrictedInBg && (serviceInfo != null)
        return mReadyNotDozing && mReadyNotRestrictedInBg && (serviceProcessName != null)
                && (mReadyDeadlineSatisfied || isConstraintsSatisfied(satisfiedConstraints));
    }

@@ -2296,7 +2295,7 @@ public final class JobStatus {
            pw.println(mReadyDynamicSatisfied);
        }
        pw.print("readyComponentEnabled: ");
        pw.println(serviceInfo != null);
        pw.println(serviceProcessName != null);
        if ((getFlags() & JobInfo.FLAG_EXPEDITED) != 0) {
            pw.print("expeditedQuotaApproved: ");
            pw.print(mExpeditedQuotaApproved);
+1 −2
Original line number Diff line number Diff line
@@ -34,7 +34,6 @@ import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManagerInternal;
import android.content.pm.ServiceInfo;
import android.os.BatteryManagerInternal;
import android.os.RemoteException;
import android.util.ArraySet;
@@ -190,7 +189,7 @@ public class BatteryControllerTest {
            JobInfo jobInfo) {
        JobStatus js = JobStatus.createFromJobInfo(
                jobInfo, callingUid, packageName, SOURCE_USER_ID, testTag);
        js.serviceInfo = mock(ServiceInfo.class);
        js.serviceProcessName = "testProcess";
        // Make sure tests aren't passing just because the default bucket is likely ACTIVE.
        js.setStandbyBucket(FREQUENT_INDEX);
        return js;
+1 −2
Original line number Diff line number Diff line
@@ -51,7 +51,6 @@ import android.app.job.JobInfo;
import android.app.usage.UsageStatsManagerInternal;
import android.content.ComponentName;
import android.content.pm.PackageManagerInternal;
import android.content.pm.ServiceInfo;
import android.net.Uri;
import android.os.SystemClock;
import android.provider.MediaStore;
@@ -887,7 +886,7 @@ public class JobStatusTest {

    private static JobStatus createJobStatus(JobInfo job) {
        JobStatus jobStatus = JobStatus.createFromJobInfo(job, 0, null, -1, "JobStatusTest");
        jobStatus.serviceInfo = mock(ServiceInfo.class);
        jobStatus.serviceProcessName = "testProcess";
        return jobStatus;
    }
}
Loading