Loading apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java +3 −4 Original line number Diff line number Diff line Loading @@ -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"); Loading @@ -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"); } Loading apex/jobscheduler/service/java/com/android/server/job/controllers/ComponentController.java +28 −22 Original line number Diff line number Diff line Loading @@ -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 = Loading Loading @@ -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; Loading @@ -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); } } } Loading @@ -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. Loading Loading @@ -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(); } } Loading apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java +3 −4 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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)); } Loading Loading @@ -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); Loading services/tests/mockingservicestests/src/com/android/server/job/controllers/BatteryControllerTest.java +1 −2 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading services/tests/mockingservicestests/src/com/android/server/job/controllers/JobStatusTest.java +1 −2 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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
apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java +3 −4 Original line number Diff line number Diff line Loading @@ -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"); Loading @@ -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"); } Loading
apex/jobscheduler/service/java/com/android/server/job/controllers/ComponentController.java +28 −22 Original line number Diff line number Diff line Loading @@ -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 = Loading Loading @@ -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; Loading @@ -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); } } } Loading @@ -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. Loading Loading @@ -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(); } } Loading
apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java +3 −4 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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)); } Loading Loading @@ -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); Loading
services/tests/mockingservicestests/src/com/android/server/job/controllers/BatteryControllerTest.java +1 −2 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading
services/tests/mockingservicestests/src/com/android/server/job/controllers/JobStatusTest.java +1 −2 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; } }