Merge "Don't allow empty namespaces." into udc-dev

This commit is contained in:
Kweku Adams
2023-03-31 00:16:50 +00:00
committed by Android (Google) Code Review
3 changed files with 40 additions and 15 deletions

View File

@@ -65,8 +65,12 @@ public class JobSchedulerImpl extends JobScheduler {
@NonNull
@Override
public JobScheduler forNamespace(@NonNull String namespace) {
namespace = sanitizeNamespace(namespace);
if (namespace == null) {
throw new IllegalArgumentException("namespace cannot be null");
throw new NullPointerException("namespace cannot be null");
}
if (namespace.isEmpty()) {
throw new IllegalArgumentException("namespace cannot be empty");
}
return new JobSchedulerImpl(this, namespace);
}

View File

@@ -270,6 +270,9 @@ public abstract class JobScheduler {
* otherwise. Attempting to update a job scheduled in another namespace will not be possible
* but will instead create or update the job inside the current namespace. A JobScheduler
* instance dedicated to a namespace must be used to schedule or update jobs in that namespace.
*
* <p class="note">Since leading and trailing whitespace can lead to hard-to-debug issues,
* they will be {@link String#trim() trimmed}. An empty String (after trimming) is not allowed.
* @see #getNamespace()
*/
@NonNull
@@ -287,6 +290,15 @@ public abstract class JobScheduler {
throw new RuntimeException("Not implemented. Must override in a subclass.");
}
/** @hide */
@Nullable
public static String sanitizeNamespace(@Nullable String namespace) {
if (namespace == null) {
return null;
}
return namespace.trim().intern();
}
/**
* Schedule a job to be executed. Will replace any currently scheduled job with the same
* ID with the new information in the {@link JobInfo}. If a job with the given ID is currently

View File

@@ -4024,6 +4024,18 @@ public class JobSchedulerService extends com.android.server.SystemService
return JobScheduler.RESULT_SUCCESS;
}
/** Returns a sanitized namespace if valid, or throws an exception if not. */
private String validateNamespace(@Nullable String namespace) {
namespace = JobScheduler.sanitizeNamespace(namespace);
if (namespace != null) {
if (namespace.isEmpty()) {
throw new IllegalArgumentException("namespace cannot be empty");
}
namespace = namespace.intern();
}
return namespace;
}
private int validateRunUserInitiatedJobsPermission(int uid, String packageName) {
final int state = getRunUserInitiatedJobsPermissionState(uid, packageName);
if (state == PermissionChecker.PERMISSION_HARD_DENIED) {
@@ -4071,9 +4083,7 @@ public class JobSchedulerService extends com.android.server.SystemService
return result;
}
if (namespace != null) {
namespace = namespace.intern();
}
namespace = validateNamespace(namespace);
final long ident = Binder.clearCallingIdentity();
try {
@@ -4104,9 +4114,7 @@ public class JobSchedulerService extends com.android.server.SystemService
return result;
}
if (namespace != null) {
namespace = namespace.intern();
}
namespace = validateNamespace(namespace);
final long ident = Binder.clearCallingIdentity();
try {
@@ -4145,9 +4153,7 @@ public class JobSchedulerService extends com.android.server.SystemService
return result;
}
if (namespace != null) {
namespace = namespace.intern();
}
namespace = validateNamespace(namespace);
final long ident = Binder.clearCallingIdentity();
try {
@@ -4184,7 +4190,8 @@ public class JobSchedulerService extends com.android.server.SystemService
final long ident = Binder.clearCallingIdentity();
try {
return new ParceledListSlice<>(
JobSchedulerService.this.getPendingJobsInNamespace(uid, namespace));
JobSchedulerService.this.getPendingJobsInNamespace(uid,
validateNamespace(namespace)));
} finally {
Binder.restoreCallingIdentity(ident);
}
@@ -4196,7 +4203,8 @@ public class JobSchedulerService extends com.android.server.SystemService
final long ident = Binder.clearCallingIdentity();
try {
return JobSchedulerService.this.getPendingJob(uid, namespace, jobId);
return JobSchedulerService.this.getPendingJob(
uid, validateNamespace(namespace), jobId);
} finally {
Binder.restoreCallingIdentity(ident);
}
@@ -4208,7 +4216,8 @@ public class JobSchedulerService extends com.android.server.SystemService
final long ident = Binder.clearCallingIdentity();
try {
return JobSchedulerService.this.getPendingJobReason(uid, namespace, jobId);
return JobSchedulerService.this.getPendingJobReason(
uid, validateNamespace(namespace), jobId);
} finally {
Binder.restoreCallingIdentity(ident);
}
@@ -4238,7 +4247,7 @@ public class JobSchedulerService extends com.android.server.SystemService
JobSchedulerService.this.cancelJobsForUid(uid,
// Documentation says only jobs scheduled BY the app will be cancelled
/* includeSourceApp */ false,
/* namespaceOnly */ true, namespace,
/* namespaceOnly */ true, validateNamespace(namespace),
JobParameters.STOP_REASON_CANCELLED_BY_APP,
JobParameters.INTERNAL_STOP_REASON_CANCELED,
"cancelAllInNamespace() called by app, callingUid=" + uid);
@@ -4253,7 +4262,7 @@ public class JobSchedulerService extends com.android.server.SystemService
final long ident = Binder.clearCallingIdentity();
try {
JobSchedulerService.this.cancelJob(uid, namespace, jobId, uid,
JobSchedulerService.this.cancelJob(uid, validateNamespace(namespace), jobId, uid,
JobParameters.STOP_REASON_CANCELLED_BY_APP);
} finally {
Binder.restoreCallingIdentity(ident);