Loading services/core/java/com/android/server/job/JobSchedulerService.java +1 −4 Original line number Diff line number Diff line Loading @@ -231,10 +231,7 @@ public class JobSchedulerService extends com.android.server.SystemService } public int scheduleAsPackage(JobInfo job, int uId, String packageName, int userId) { JobStatus jobStatus = new JobStatus(job, uId); if (packageName != null) { jobStatus.setSource(packageName, userId); } JobStatus jobStatus = new JobStatus(job, uId, packageName, userId); try { if (ActivityManagerNative.getDefault().getAppStartMode(uId, job.getService().getPackageName()) == ActivityManager.APP_START_MODE_DISABLED) { Loading services/core/java/com/android/server/job/JobStore.java +6 −9 Original line number Diff line number Diff line Loading @@ -282,8 +282,7 @@ public class JobStore { continue; } JobStatus copy = new JobStatus(jobStatus.getJob(), jobStatus.getUid(), jobStatus.getEarliestRunTime(), jobStatus.getLatestRunTimeElapsed()); JobStatus copy = new JobStatus(jobStatus); mStoreCopy.add(copy); } } Loading Loading @@ -544,7 +543,7 @@ public class JobStore { private JobStatus restoreJobFromXml(XmlPullParser parser) throws XmlPullParserException, IOException { JobInfo.Builder jobBuilder; int uid, userId; int uid, sourceUserId; // Read out job identifier attributes and priority. try { Loading @@ -557,7 +556,7 @@ public class JobStore { jobBuilder.setPriority(Integer.valueOf(val)); } val = parser.getAttributeValue(null, "sourceUserId"); userId = val == null ? -1 : Integer.valueOf(val); sourceUserId = val == null ? -1 : Integer.valueOf(val); } catch (NumberFormatException e) { Slog.e(TAG, "Error parsing job's required fields, skipping"); return null; Loading Loading @@ -608,9 +607,9 @@ public class JobStore { try { String val = parser.getAttributeValue(null, "period"); final long periodMillis = Long.valueOf(val); jobBuilder.setPeriodic(periodMillis); val = parser.getAttributeValue(null, "flex"); final long flexMillis = (val != null) ? Long.valueOf(val) : periodMillis; jobBuilder.setPeriodic(periodMillis, flexMillis); // As a sanity check, cap the recreated run time to be no later than flex+period // from now. This is the latest the periodic could be pushed out. This could // happen if the periodic ran early (at flex time before period), and then the Loading Loading @@ -679,10 +678,8 @@ public class JobStore { parser.nextTag(); // Consume </extras> JobStatus js = new JobStatus( jobBuilder.build(), uid, elapsedRuntimes.first, elapsedRuntimes.second); if (userId != -1) { js.setSource(sourcePackageName, userId); } jobBuilder.build(), uid, sourcePackageName, sourceUserId, elapsedRuntimes.first, elapsedRuntimes.second); return js; } Loading services/core/java/com/android/server/job/controllers/JobStatus.java +50 −45 Original line number Diff line number Diff line Loading @@ -48,13 +48,13 @@ public class JobStatus { final JobInfo job; /** Uid of the package requesting this job. */ final int uId; final int callingUid; final String name; final String tag; String sourcePackageName; int sourceUserId = -1; int sourceUid = -1; final String sourcePackageName; final int sourceUserId; final int sourceUid; // Constraints. final AtomicBoolean chargingConstraintSatisfied = new AtomicBoolean(); Loading Loading @@ -91,30 +91,55 @@ public class JobStatus { /** Provide a handle to the service that this job will be run on. */ public int getServiceToken() { return uId; return callingUid; } private JobStatus(JobInfo job, int uId, int numFailures) { private JobStatus(JobInfo job, int callingUid, String sourcePackageName, int sourceUserId, int numFailures) { this.job = job; this.uId = uId; this.sourceUid = uId; this.callingUid = callingUid; this.name = job.getService().flattenToShortString(); this.tag = "*job*/" + this.name; this.numFailures = numFailures; int tempSourceUid = -1; if (sourceUserId != -1 && sourcePackageName != null) { try { tempSourceUid = AppGlobals.getPackageManager().getPackageUid(sourcePackageName, 0, sourceUserId); } catch (RemoteException ex) { // Can't happen, PackageManager runs in the same process. } } if (tempSourceUid == -1) { this.sourceUid = callingUid; this.sourceUserId = UserHandle.getUserId(callingUid); this.sourcePackageName = job.getService().getPackageName(); } else { this.sourceUid = tempSourceUid; this.sourceUserId = sourceUserId; this.sourcePackageName = sourcePackageName; } } /** Copy constructor. */ public JobStatus(JobStatus jobStatus) { this(jobStatus.getJob(), jobStatus.getUid(), jobStatus.getNumFailures()); this.sourceUserId = jobStatus.sourceUserId; this.sourcePackageName = jobStatus.sourcePackageName; this(jobStatus.getJob(), jobStatus.getUid(), jobStatus.getSourcePackageName(), jobStatus.getSourceUserId(), jobStatus.getNumFailures()); this.earliestRunTimeElapsedMillis = jobStatus.getEarliestRunTime(); this.latestRunTimeElapsedMillis = jobStatus.getLatestRunTimeElapsed(); } /** Create a newly scheduled job. */ public JobStatus(JobInfo job, int uId) { this(job, uId, 0); /** * Create a newly scheduled job. * @param callingUid Uid of the package that scheduled this job. * @param sourcePackageName Package name on whose behalf this job is scheduled. Null indicates * the calling package is the source. * @param sourceUserId User id for whom this job is scheduled. -1 indicates this is same as the * calling userId. */ public JobStatus(JobInfo job, int callingUid, String sourcePackageName, int sourceUserId) { this(job, callingUid, sourcePackageName, sourceUserId, 0); final long elapsedNow = SystemClock.elapsedRealtime(); Loading @@ -136,9 +161,9 @@ public class JobStatus { * wallclock runtime rather than resetting it on every boot. * We consider a freshly loaded job to no longer be in back-off. */ public JobStatus(JobInfo job, int uId, long earliestRunTimeElapsedMillis, long latestRunTimeElapsedMillis) { this(job, uId, 0); public JobStatus(JobInfo job, int callingUid, String sourcePackageName, int sourceUserId, long earliestRunTimeElapsedMillis, long latestRunTimeElapsedMillis) { this(job, callingUid, sourcePackageName, sourceUserId, 0); this.earliestRunTimeElapsedMillis = earliestRunTimeElapsedMillis; this.latestRunTimeElapsedMillis = latestRunTimeElapsedMillis; Loading @@ -147,9 +172,8 @@ public class JobStatus { /** Create a new job to be rescheduled with the provided parameters. */ public JobStatus(JobStatus rescheduling, long newEarliestRuntimeElapsedMillis, long newLatestRuntimeElapsedMillis, int backoffAttempt) { this(rescheduling.job, rescheduling.getUid(), backoffAttempt); this.sourceUserId = rescheduling.sourceUserId; this.sourcePackageName = rescheduling.sourcePackageName; this(rescheduling.job, rescheduling.getUid(), rescheduling.getSourcePackageName(), rescheduling.getSourceUserId(), backoffAttempt); earliestRunTimeElapsedMillis = newEarliestRuntimeElapsedMillis; latestRunTimeElapsedMillis = newLatestRuntimeElapsedMillis; Loading @@ -172,7 +196,7 @@ public class JobStatus { } public String getSourcePackageName() { return sourcePackageName != null ? sourcePackageName : job.getService().getPackageName(); return sourcePackageName; } public int getSourceUid() { Loading @@ -180,18 +204,15 @@ public class JobStatus { } public int getSourceUserId() { if (sourceUserId == -1) { sourceUserId = getUserId(); } return sourceUserId; } public int getUserId() { return UserHandle.getUserId(uId); return UserHandle.getUserId(callingUid); } public int getUid() { return uId; return callingUid; } public String getName() { Loading Loading @@ -278,7 +299,7 @@ public class JobStatus { } public boolean matches(int uid, int jobId) { return this.job.getId() == jobId && this.uId == uid; return this.job.getId() == jobId && this.callingUid == uid; } @Override Loading Loading @@ -312,22 +333,6 @@ public class JobStatus { } } public void setSource(String sourcePackageName, int sourceUserId) { this.sourcePackageName = sourcePackageName; this.sourceUserId = sourceUserId; try { sourceUid = AppGlobals.getPackageManager().getPackageUid(sourcePackageName, 0, sourceUserId); } catch (RemoteException ex) { // Can't happen, PackageManager runs in the same process. } if (sourceUid == -1) { sourceUid = uId; this.sourceUserId = getUserId(); this.sourcePackageName = null; } } /** * Convenience function to identify a job uniquely without pulling all the data that * {@link #toString()} returns. Loading @@ -338,7 +343,7 @@ public class JobStatus { sb.append(" jId="); sb.append(job.getId()); sb.append(" uid="); UserHandle.formatUid(sb, uId); UserHandle.formatUid(sb, callingUid); sb.append(' '); sb.append(job.getService().flattenToShortString()); return sb.toString(); Loading @@ -346,7 +351,7 @@ public class JobStatus { // Dumpsys infrastructure public void dump(PrintWriter pw, String prefix) { pw.print(prefix); UserHandle.formatUid(pw, uId); pw.print(prefix); UserHandle.formatUid(pw, callingUid); pw.print(" tag="); pw.println(tag); pw.print(prefix); pw.print("Source: uid="); UserHandle.formatUid(pw, getSourceUid()); Loading services/tests/servicestests/src/com/android/server/job/JobStoreTest.java +57 −15 Original line number Diff line number Diff line Loading @@ -58,7 +58,7 @@ public class JobStoreTest extends AndroidTestCase { .setMinimumLatency(runFromMillis) .setPersisted(true) .build(); final JobStatus ts = new JobStatus(task, SOME_UID); final JobStatus ts = new JobStatus(task, SOME_UID, null, -1); mTaskStoreUnderTest.add(ts); Thread.sleep(IO_WAIT); // Manually load tasks from xml file. Loading Loading @@ -91,8 +91,8 @@ public class JobStoreTest extends AndroidTestCase { .setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED) .setPersisted(true) .build(); final JobStatus taskStatus1 = new JobStatus(task1, SOME_UID); final JobStatus taskStatus2 = new JobStatus(task2, SOME_UID); final JobStatus taskStatus1 = new JobStatus(task1, SOME_UID, null, -1); final JobStatus taskStatus2 = new JobStatus(task2, SOME_UID, null, -1); mTaskStoreUnderTest.add(taskStatus1); mTaskStoreUnderTest.add(taskStatus2); Thread.sleep(IO_WAIT); Loading Loading @@ -140,7 +140,7 @@ public class JobStoreTest extends AndroidTestCase { extras.putInt("into", 3); b.setExtras(extras); final JobInfo task = b.build(); JobStatus taskStatus = new JobStatus(task, SOME_UID); JobStatus taskStatus = new JobStatus(task, SOME_UID, null, -1); mTaskStoreUnderTest.add(taskStatus); Thread.sleep(IO_WAIT); Loading @@ -151,17 +151,59 @@ public class JobStoreTest extends AndroidTestCase { JobStatus loaded = jobStatusSet.iterator().next(); assertTasksEqual(task, loaded.getJob()); } public void testWritingTaskWithSourcePackage() throws Exception { JobInfo.Builder b = new Builder(8, mComponent) .setRequiresDeviceIdle(true) .setPeriodic(10000L) .setRequiresCharging(true) .setPersisted(true); JobStatus taskStatus = new JobStatus(b.build(), SOME_UID, "com.google.android.gms", 0); mTaskStoreUnderTest.add(taskStatus); Thread.sleep(IO_WAIT); final ArraySet<JobStatus> jobStatusSet = new ArraySet<JobStatus>(); mTaskStoreUnderTest.readJobMapFromDisk(jobStatusSet); assertEquals("Incorrect # of persisted tasks.", 1, jobStatusSet.size()); JobStatus loaded = jobStatusSet.iterator().next(); assertEquals("Source package not equal.", loaded.getSourcePackageName(), taskStatus.getSourcePackageName()); assertEquals("Source user not equal.", loaded.getSourceUserId(), taskStatus.getSourceUserId()); } public void testWritingTaskWithFlex() throws Exception { JobInfo.Builder b = new Builder(8, mComponent) .setRequiresDeviceIdle(true) .setPeriodic(5*60*60*1000, 1*60*60*1000) .setRequiresCharging(true) .setPersisted(true); JobStatus taskStatus = new JobStatus(b.build(), SOME_UID, null, -1); mTaskStoreUnderTest.add(taskStatus); Thread.sleep(IO_WAIT); final ArraySet<JobStatus> jobStatusSet = new ArraySet<JobStatus>(); mTaskStoreUnderTest.readJobMapFromDisk(jobStatusSet); assertEquals("Incorrect # of persisted tasks.", 1, jobStatusSet.size()); JobStatus loaded = jobStatusSet.iterator().next(); assertEquals("Period not equal.", loaded.getJob().getIntervalMillis(), taskStatus.getJob().getIntervalMillis()); assertEquals("Flex not equal.", loaded.getJob().getFlexMillis(), taskStatus.getJob().getFlexMillis()); } public void testMassivePeriodClampedOnRead() throws Exception { final long TEN_SECONDS = 10000L; final long ONE_HOUR = 60*60*1000L; // flex final long TWO_HOURS = 2 * ONE_HOUR; // period JobInfo.Builder b = new Builder(8, mComponent) .setPeriodic(TEN_SECONDS) .setPeriodic(TWO_HOURS, ONE_HOUR) .setPersisted(true); final long invalidLateRuntimeElapsedMillis = SystemClock.elapsedRealtime() + (TEN_SECONDS * 2) + 5000; // >2P from now. SystemClock.elapsedRealtime() + (TWO_HOURS * ONE_HOUR) + TWO_HOURS; // > period+flex final long invalidEarlyRuntimeElapsedMillis = invalidLateRuntimeElapsedMillis - TEN_SECONDS; // Early is (late - period). final JobStatus js = new JobStatus(b.build(), SOME_UID, invalidLateRuntimeElapsedMillis - TWO_HOURS; // Early is (late - period). final JobStatus js = new JobStatus(b.build(), SOME_UID, "somePackage", 0 /* sourceUserId */, invalidEarlyRuntimeElapsedMillis, invalidLateRuntimeElapsedMillis); mTaskStoreUnderTest.add(js); Loading @@ -176,10 +218,10 @@ public class JobStoreTest extends AndroidTestCase { // call SystemClock.elapsedRealtime after doing the disk i/o. final long newNowElapsed = SystemClock.elapsedRealtime(); assertTrue("Early runtime wasn't correctly clamped.", loaded.getEarliestRunTime() <= newNowElapsed + TEN_SECONDS); // Assert late runtime was clamped to be now + period*2. loaded.getEarliestRunTime() <= newNowElapsed + TWO_HOURS); // Assert late runtime was clamped to be now + period + flex. assertTrue("Early runtime wasn't correctly clamped.", loaded.getEarliestRunTime() <= newNowElapsed + TEN_SECONDS * 2); loaded.getEarliestRunTime() <= newNowElapsed + TWO_HOURS + ONE_HOUR); } public void testPriorityPersisted() throws Exception { Loading @@ -187,7 +229,7 @@ public class JobStoreTest extends AndroidTestCase { .setOverrideDeadline(5000) .setPriority(42) .setPersisted(true); final JobStatus js = new JobStatus(b.build(), SOME_UID); final JobStatus js = new JobStatus(b.build(), SOME_UID, null, -1); mTaskStoreUnderTest.add(js); Thread.sleep(IO_WAIT); final ArraySet<JobStatus> jobStatusSet = new ArraySet<JobStatus>(); Loading @@ -203,12 +245,12 @@ public class JobStoreTest extends AndroidTestCase { JobInfo.Builder b = new Builder(42, mComponent) .setOverrideDeadline(10000) .setPersisted(false); JobStatus jsNonPersisted = new JobStatus(b.build(), SOME_UID); JobStatus jsNonPersisted = new JobStatus(b.build(), SOME_UID, null, -1); mTaskStoreUnderTest.add(jsNonPersisted); b = new Builder(43, mComponent) .setOverrideDeadline(10000) .setPersisted(true); JobStatus jsPersisted = new JobStatus(b.build(), SOME_UID); JobStatus jsPersisted = new JobStatus(b.build(), SOME_UID, null, -1); mTaskStoreUnderTest.add(jsPersisted); Thread.sleep(IO_WAIT); final ArraySet<JobStatus> jobStatusSet = new ArraySet<JobStatus>(); Loading Loading
services/core/java/com/android/server/job/JobSchedulerService.java +1 −4 Original line number Diff line number Diff line Loading @@ -231,10 +231,7 @@ public class JobSchedulerService extends com.android.server.SystemService } public int scheduleAsPackage(JobInfo job, int uId, String packageName, int userId) { JobStatus jobStatus = new JobStatus(job, uId); if (packageName != null) { jobStatus.setSource(packageName, userId); } JobStatus jobStatus = new JobStatus(job, uId, packageName, userId); try { if (ActivityManagerNative.getDefault().getAppStartMode(uId, job.getService().getPackageName()) == ActivityManager.APP_START_MODE_DISABLED) { Loading
services/core/java/com/android/server/job/JobStore.java +6 −9 Original line number Diff line number Diff line Loading @@ -282,8 +282,7 @@ public class JobStore { continue; } JobStatus copy = new JobStatus(jobStatus.getJob(), jobStatus.getUid(), jobStatus.getEarliestRunTime(), jobStatus.getLatestRunTimeElapsed()); JobStatus copy = new JobStatus(jobStatus); mStoreCopy.add(copy); } } Loading Loading @@ -544,7 +543,7 @@ public class JobStore { private JobStatus restoreJobFromXml(XmlPullParser parser) throws XmlPullParserException, IOException { JobInfo.Builder jobBuilder; int uid, userId; int uid, sourceUserId; // Read out job identifier attributes and priority. try { Loading @@ -557,7 +556,7 @@ public class JobStore { jobBuilder.setPriority(Integer.valueOf(val)); } val = parser.getAttributeValue(null, "sourceUserId"); userId = val == null ? -1 : Integer.valueOf(val); sourceUserId = val == null ? -1 : Integer.valueOf(val); } catch (NumberFormatException e) { Slog.e(TAG, "Error parsing job's required fields, skipping"); return null; Loading Loading @@ -608,9 +607,9 @@ public class JobStore { try { String val = parser.getAttributeValue(null, "period"); final long periodMillis = Long.valueOf(val); jobBuilder.setPeriodic(periodMillis); val = parser.getAttributeValue(null, "flex"); final long flexMillis = (val != null) ? Long.valueOf(val) : periodMillis; jobBuilder.setPeriodic(periodMillis, flexMillis); // As a sanity check, cap the recreated run time to be no later than flex+period // from now. This is the latest the periodic could be pushed out. This could // happen if the periodic ran early (at flex time before period), and then the Loading Loading @@ -679,10 +678,8 @@ public class JobStore { parser.nextTag(); // Consume </extras> JobStatus js = new JobStatus( jobBuilder.build(), uid, elapsedRuntimes.first, elapsedRuntimes.second); if (userId != -1) { js.setSource(sourcePackageName, userId); } jobBuilder.build(), uid, sourcePackageName, sourceUserId, elapsedRuntimes.first, elapsedRuntimes.second); return js; } Loading
services/core/java/com/android/server/job/controllers/JobStatus.java +50 −45 Original line number Diff line number Diff line Loading @@ -48,13 +48,13 @@ public class JobStatus { final JobInfo job; /** Uid of the package requesting this job. */ final int uId; final int callingUid; final String name; final String tag; String sourcePackageName; int sourceUserId = -1; int sourceUid = -1; final String sourcePackageName; final int sourceUserId; final int sourceUid; // Constraints. final AtomicBoolean chargingConstraintSatisfied = new AtomicBoolean(); Loading Loading @@ -91,30 +91,55 @@ public class JobStatus { /** Provide a handle to the service that this job will be run on. */ public int getServiceToken() { return uId; return callingUid; } private JobStatus(JobInfo job, int uId, int numFailures) { private JobStatus(JobInfo job, int callingUid, String sourcePackageName, int sourceUserId, int numFailures) { this.job = job; this.uId = uId; this.sourceUid = uId; this.callingUid = callingUid; this.name = job.getService().flattenToShortString(); this.tag = "*job*/" + this.name; this.numFailures = numFailures; int tempSourceUid = -1; if (sourceUserId != -1 && sourcePackageName != null) { try { tempSourceUid = AppGlobals.getPackageManager().getPackageUid(sourcePackageName, 0, sourceUserId); } catch (RemoteException ex) { // Can't happen, PackageManager runs in the same process. } } if (tempSourceUid == -1) { this.sourceUid = callingUid; this.sourceUserId = UserHandle.getUserId(callingUid); this.sourcePackageName = job.getService().getPackageName(); } else { this.sourceUid = tempSourceUid; this.sourceUserId = sourceUserId; this.sourcePackageName = sourcePackageName; } } /** Copy constructor. */ public JobStatus(JobStatus jobStatus) { this(jobStatus.getJob(), jobStatus.getUid(), jobStatus.getNumFailures()); this.sourceUserId = jobStatus.sourceUserId; this.sourcePackageName = jobStatus.sourcePackageName; this(jobStatus.getJob(), jobStatus.getUid(), jobStatus.getSourcePackageName(), jobStatus.getSourceUserId(), jobStatus.getNumFailures()); this.earliestRunTimeElapsedMillis = jobStatus.getEarliestRunTime(); this.latestRunTimeElapsedMillis = jobStatus.getLatestRunTimeElapsed(); } /** Create a newly scheduled job. */ public JobStatus(JobInfo job, int uId) { this(job, uId, 0); /** * Create a newly scheduled job. * @param callingUid Uid of the package that scheduled this job. * @param sourcePackageName Package name on whose behalf this job is scheduled. Null indicates * the calling package is the source. * @param sourceUserId User id for whom this job is scheduled. -1 indicates this is same as the * calling userId. */ public JobStatus(JobInfo job, int callingUid, String sourcePackageName, int sourceUserId) { this(job, callingUid, sourcePackageName, sourceUserId, 0); final long elapsedNow = SystemClock.elapsedRealtime(); Loading @@ -136,9 +161,9 @@ public class JobStatus { * wallclock runtime rather than resetting it on every boot. * We consider a freshly loaded job to no longer be in back-off. */ public JobStatus(JobInfo job, int uId, long earliestRunTimeElapsedMillis, long latestRunTimeElapsedMillis) { this(job, uId, 0); public JobStatus(JobInfo job, int callingUid, String sourcePackageName, int sourceUserId, long earliestRunTimeElapsedMillis, long latestRunTimeElapsedMillis) { this(job, callingUid, sourcePackageName, sourceUserId, 0); this.earliestRunTimeElapsedMillis = earliestRunTimeElapsedMillis; this.latestRunTimeElapsedMillis = latestRunTimeElapsedMillis; Loading @@ -147,9 +172,8 @@ public class JobStatus { /** Create a new job to be rescheduled with the provided parameters. */ public JobStatus(JobStatus rescheduling, long newEarliestRuntimeElapsedMillis, long newLatestRuntimeElapsedMillis, int backoffAttempt) { this(rescheduling.job, rescheduling.getUid(), backoffAttempt); this.sourceUserId = rescheduling.sourceUserId; this.sourcePackageName = rescheduling.sourcePackageName; this(rescheduling.job, rescheduling.getUid(), rescheduling.getSourcePackageName(), rescheduling.getSourceUserId(), backoffAttempt); earliestRunTimeElapsedMillis = newEarliestRuntimeElapsedMillis; latestRunTimeElapsedMillis = newLatestRuntimeElapsedMillis; Loading @@ -172,7 +196,7 @@ public class JobStatus { } public String getSourcePackageName() { return sourcePackageName != null ? sourcePackageName : job.getService().getPackageName(); return sourcePackageName; } public int getSourceUid() { Loading @@ -180,18 +204,15 @@ public class JobStatus { } public int getSourceUserId() { if (sourceUserId == -1) { sourceUserId = getUserId(); } return sourceUserId; } public int getUserId() { return UserHandle.getUserId(uId); return UserHandle.getUserId(callingUid); } public int getUid() { return uId; return callingUid; } public String getName() { Loading Loading @@ -278,7 +299,7 @@ public class JobStatus { } public boolean matches(int uid, int jobId) { return this.job.getId() == jobId && this.uId == uid; return this.job.getId() == jobId && this.callingUid == uid; } @Override Loading Loading @@ -312,22 +333,6 @@ public class JobStatus { } } public void setSource(String sourcePackageName, int sourceUserId) { this.sourcePackageName = sourcePackageName; this.sourceUserId = sourceUserId; try { sourceUid = AppGlobals.getPackageManager().getPackageUid(sourcePackageName, 0, sourceUserId); } catch (RemoteException ex) { // Can't happen, PackageManager runs in the same process. } if (sourceUid == -1) { sourceUid = uId; this.sourceUserId = getUserId(); this.sourcePackageName = null; } } /** * Convenience function to identify a job uniquely without pulling all the data that * {@link #toString()} returns. Loading @@ -338,7 +343,7 @@ public class JobStatus { sb.append(" jId="); sb.append(job.getId()); sb.append(" uid="); UserHandle.formatUid(sb, uId); UserHandle.formatUid(sb, callingUid); sb.append(' '); sb.append(job.getService().flattenToShortString()); return sb.toString(); Loading @@ -346,7 +351,7 @@ public class JobStatus { // Dumpsys infrastructure public void dump(PrintWriter pw, String prefix) { pw.print(prefix); UserHandle.formatUid(pw, uId); pw.print(prefix); UserHandle.formatUid(pw, callingUid); pw.print(" tag="); pw.println(tag); pw.print(prefix); pw.print("Source: uid="); UserHandle.formatUid(pw, getSourceUid()); Loading
services/tests/servicestests/src/com/android/server/job/JobStoreTest.java +57 −15 Original line number Diff line number Diff line Loading @@ -58,7 +58,7 @@ public class JobStoreTest extends AndroidTestCase { .setMinimumLatency(runFromMillis) .setPersisted(true) .build(); final JobStatus ts = new JobStatus(task, SOME_UID); final JobStatus ts = new JobStatus(task, SOME_UID, null, -1); mTaskStoreUnderTest.add(ts); Thread.sleep(IO_WAIT); // Manually load tasks from xml file. Loading Loading @@ -91,8 +91,8 @@ public class JobStoreTest extends AndroidTestCase { .setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED) .setPersisted(true) .build(); final JobStatus taskStatus1 = new JobStatus(task1, SOME_UID); final JobStatus taskStatus2 = new JobStatus(task2, SOME_UID); final JobStatus taskStatus1 = new JobStatus(task1, SOME_UID, null, -1); final JobStatus taskStatus2 = new JobStatus(task2, SOME_UID, null, -1); mTaskStoreUnderTest.add(taskStatus1); mTaskStoreUnderTest.add(taskStatus2); Thread.sleep(IO_WAIT); Loading Loading @@ -140,7 +140,7 @@ public class JobStoreTest extends AndroidTestCase { extras.putInt("into", 3); b.setExtras(extras); final JobInfo task = b.build(); JobStatus taskStatus = new JobStatus(task, SOME_UID); JobStatus taskStatus = new JobStatus(task, SOME_UID, null, -1); mTaskStoreUnderTest.add(taskStatus); Thread.sleep(IO_WAIT); Loading @@ -151,17 +151,59 @@ public class JobStoreTest extends AndroidTestCase { JobStatus loaded = jobStatusSet.iterator().next(); assertTasksEqual(task, loaded.getJob()); } public void testWritingTaskWithSourcePackage() throws Exception { JobInfo.Builder b = new Builder(8, mComponent) .setRequiresDeviceIdle(true) .setPeriodic(10000L) .setRequiresCharging(true) .setPersisted(true); JobStatus taskStatus = new JobStatus(b.build(), SOME_UID, "com.google.android.gms", 0); mTaskStoreUnderTest.add(taskStatus); Thread.sleep(IO_WAIT); final ArraySet<JobStatus> jobStatusSet = new ArraySet<JobStatus>(); mTaskStoreUnderTest.readJobMapFromDisk(jobStatusSet); assertEquals("Incorrect # of persisted tasks.", 1, jobStatusSet.size()); JobStatus loaded = jobStatusSet.iterator().next(); assertEquals("Source package not equal.", loaded.getSourcePackageName(), taskStatus.getSourcePackageName()); assertEquals("Source user not equal.", loaded.getSourceUserId(), taskStatus.getSourceUserId()); } public void testWritingTaskWithFlex() throws Exception { JobInfo.Builder b = new Builder(8, mComponent) .setRequiresDeviceIdle(true) .setPeriodic(5*60*60*1000, 1*60*60*1000) .setRequiresCharging(true) .setPersisted(true); JobStatus taskStatus = new JobStatus(b.build(), SOME_UID, null, -1); mTaskStoreUnderTest.add(taskStatus); Thread.sleep(IO_WAIT); final ArraySet<JobStatus> jobStatusSet = new ArraySet<JobStatus>(); mTaskStoreUnderTest.readJobMapFromDisk(jobStatusSet); assertEquals("Incorrect # of persisted tasks.", 1, jobStatusSet.size()); JobStatus loaded = jobStatusSet.iterator().next(); assertEquals("Period not equal.", loaded.getJob().getIntervalMillis(), taskStatus.getJob().getIntervalMillis()); assertEquals("Flex not equal.", loaded.getJob().getFlexMillis(), taskStatus.getJob().getFlexMillis()); } public void testMassivePeriodClampedOnRead() throws Exception { final long TEN_SECONDS = 10000L; final long ONE_HOUR = 60*60*1000L; // flex final long TWO_HOURS = 2 * ONE_HOUR; // period JobInfo.Builder b = new Builder(8, mComponent) .setPeriodic(TEN_SECONDS) .setPeriodic(TWO_HOURS, ONE_HOUR) .setPersisted(true); final long invalidLateRuntimeElapsedMillis = SystemClock.elapsedRealtime() + (TEN_SECONDS * 2) + 5000; // >2P from now. SystemClock.elapsedRealtime() + (TWO_HOURS * ONE_HOUR) + TWO_HOURS; // > period+flex final long invalidEarlyRuntimeElapsedMillis = invalidLateRuntimeElapsedMillis - TEN_SECONDS; // Early is (late - period). final JobStatus js = new JobStatus(b.build(), SOME_UID, invalidLateRuntimeElapsedMillis - TWO_HOURS; // Early is (late - period). final JobStatus js = new JobStatus(b.build(), SOME_UID, "somePackage", 0 /* sourceUserId */, invalidEarlyRuntimeElapsedMillis, invalidLateRuntimeElapsedMillis); mTaskStoreUnderTest.add(js); Loading @@ -176,10 +218,10 @@ public class JobStoreTest extends AndroidTestCase { // call SystemClock.elapsedRealtime after doing the disk i/o. final long newNowElapsed = SystemClock.elapsedRealtime(); assertTrue("Early runtime wasn't correctly clamped.", loaded.getEarliestRunTime() <= newNowElapsed + TEN_SECONDS); // Assert late runtime was clamped to be now + period*2. loaded.getEarliestRunTime() <= newNowElapsed + TWO_HOURS); // Assert late runtime was clamped to be now + period + flex. assertTrue("Early runtime wasn't correctly clamped.", loaded.getEarliestRunTime() <= newNowElapsed + TEN_SECONDS * 2); loaded.getEarliestRunTime() <= newNowElapsed + TWO_HOURS + ONE_HOUR); } public void testPriorityPersisted() throws Exception { Loading @@ -187,7 +229,7 @@ public class JobStoreTest extends AndroidTestCase { .setOverrideDeadline(5000) .setPriority(42) .setPersisted(true); final JobStatus js = new JobStatus(b.build(), SOME_UID); final JobStatus js = new JobStatus(b.build(), SOME_UID, null, -1); mTaskStoreUnderTest.add(js); Thread.sleep(IO_WAIT); final ArraySet<JobStatus> jobStatusSet = new ArraySet<JobStatus>(); Loading @@ -203,12 +245,12 @@ public class JobStoreTest extends AndroidTestCase { JobInfo.Builder b = new Builder(42, mComponent) .setOverrideDeadline(10000) .setPersisted(false); JobStatus jsNonPersisted = new JobStatus(b.build(), SOME_UID); JobStatus jsNonPersisted = new JobStatus(b.build(), SOME_UID, null, -1); mTaskStoreUnderTest.add(jsNonPersisted); b = new Builder(43, mComponent) .setOverrideDeadline(10000) .setPersisted(true); JobStatus jsPersisted = new JobStatus(b.build(), SOME_UID); JobStatus jsPersisted = new JobStatus(b.build(), SOME_UID, null, -1); mTaskStoreUnderTest.add(jsPersisted); Thread.sleep(IO_WAIT); final ArraySet<JobStatus> jobStatusSet = new ArraySet<JobStatus>(); Loading