summaryrefslogtreecommitdiff
path: root/core/java/android
diff options
context:
space:
mode:
authorMakoto Onuki <omakoto@google.com>2019-08-12 18:49:51 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2019-08-12 18:49:51 +0000
commit3fedfcb409d85937c5b773d95ca7fdf8694c532e (patch)
tree811a3e44f22f93d45b47a08f2a2839c006595dea /core/java/android
parentd5a2c65eb1015d7b6a880a0974679e4e1c642bcb (diff)
parent62242c48e0511bd06a94b6e471cc70a2fb9d8a2a (diff)
Merge "Introduce framework-minus-apex and create jobscheduler-framework.jar"
Diffstat (limited to 'core/java/android')
-rw-r--r--core/java/android/app/JobSchedulerImpl.java121
-rw-r--r--core/java/android/app/job/IJobCallback.aidl68
-rw-r--r--core/java/android/app/job/IJobScheduler.aidl38
-rw-r--r--core/java/android/app/job/IJobService.aidl34
-rw-r--r--core/java/android/app/job/JobInfo.aidl19
-rw-r--r--core/java/android/app/job/JobInfo.java1597
-rw-r--r--core/java/android/app/job/JobParameters.aidl19
-rw-r--r--core/java/android/app/job/JobParameters.java372
-rw-r--r--core/java/android/app/job/JobScheduler.java191
-rw-r--r--core/java/android/app/job/JobSchedulerFrameworkInitializer.java39
-rw-r--r--core/java/android/app/job/JobService.java157
-rw-r--r--core/java/android/app/job/JobServiceEngine.java220
-rw-r--r--core/java/android/app/job/JobSnapshot.aidl19
-rw-r--r--core/java/android/app/job/JobSnapshot.java119
-rw-r--r--core/java/android/app/job/JobWorkItem.aidl20
-rw-r--r--core/java/android/app/job/JobWorkItem.java212
16 files changed, 0 insertions, 3245 deletions
diff --git a/core/java/android/app/JobSchedulerImpl.java b/core/java/android/app/JobSchedulerImpl.java
deleted file mode 100644
index 924a70809747..000000000000
--- a/core/java/android/app/JobSchedulerImpl.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-// in android.app so ContextImpl has package access
-package android.app;
-
-import android.app.job.IJobScheduler;
-import android.app.job.JobInfo;
-import android.app.job.JobScheduler;
-import android.app.job.JobSnapshot;
-import android.app.job.JobWorkItem;
-import android.os.RemoteException;
-
-import java.util.List;
-
-
-// APEX NOTE: Class path referred to by robolectric, so can't move it.
-
-/**
- * Concrete implementation of the JobScheduler interface
- * @hide
- */
-public class JobSchedulerImpl extends JobScheduler {
- IJobScheduler mBinder;
-
- public JobSchedulerImpl(IJobScheduler binder) {
- mBinder = binder;
- }
-
- @Override
- public int schedule(JobInfo job) {
- try {
- return mBinder.schedule(job);
- } catch (RemoteException e) {
- return JobScheduler.RESULT_FAILURE;
- }
- }
-
- @Override
- public int enqueue(JobInfo job, JobWorkItem work) {
- try {
- return mBinder.enqueue(job, work);
- } catch (RemoteException e) {
- return JobScheduler.RESULT_FAILURE;
- }
- }
-
- @Override
- public int scheduleAsPackage(JobInfo job, String packageName, int userId, String tag) {
- try {
- return mBinder.scheduleAsPackage(job, packageName, userId, tag);
- } catch (RemoteException e) {
- return JobScheduler.RESULT_FAILURE;
- }
- }
-
- @Override
- public void cancel(int jobId) {
- try {
- mBinder.cancel(jobId);
- } catch (RemoteException e) {}
-
- }
-
- @Override
- public void cancelAll() {
- try {
- mBinder.cancelAll();
- } catch (RemoteException e) {}
-
- }
-
- @Override
- public List<JobInfo> getAllPendingJobs() {
- try {
- return mBinder.getAllPendingJobs().getList();
- } catch (RemoteException e) {
- return null;
- }
- }
-
- @Override
- public JobInfo getPendingJob(int jobId) {
- try {
- return mBinder.getPendingJob(jobId);
- } catch (RemoteException e) {
- return null;
- }
- }
-
- @Override
- public List<JobInfo> getStartedJobs() {
- try {
- return mBinder.getStartedJobs();
- } catch (RemoteException e) {
- return null;
- }
- }
-
- @Override
- public List<JobSnapshot> getAllJobSnapshots() {
- try {
- return mBinder.getAllJobSnapshots().getList();
- } catch (RemoteException e) {
- return null;
- }
- }
-}
diff --git a/core/java/android/app/job/IJobCallback.aidl b/core/java/android/app/job/IJobCallback.aidl
deleted file mode 100644
index d281da037fde..000000000000
--- a/core/java/android/app/job/IJobCallback.aidl
+++ /dev/null
@@ -1,68 +0,0 @@
-/**
- * Copyright 2014, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.app.job;
-
-import android.app.job.JobWorkItem;
-
-/**
- * The server side of the JobScheduler IPC protocols. The app-side implementation
- * invokes on this interface to indicate completion of the (asynchronous) instructions
- * issued by the server.
- *
- * In all cases, the 'who' parameter is the caller's service binder, used to track
- * which Job Service instance is reporting.
- *
- * {@hide}
- */
-interface IJobCallback {
- /**
- * Immediate callback to the system after sending a start signal, used to quickly detect ANR.
- *
- * @param jobId Unique integer used to identify this job.
- * @param ongoing True to indicate that the client is processing the job. False if the job is
- * complete
- */
- @UnsupportedAppUsage
- void acknowledgeStartMessage(int jobId, boolean ongoing);
- /**
- * Immediate callback to the system after sending a stop signal, used to quickly detect ANR.
- *
- * @param jobId Unique integer used to identify this job.
- * @param reschedule Whether or not to reschedule this job.
- */
- @UnsupportedAppUsage
- void acknowledgeStopMessage(int jobId, boolean reschedule);
- /*
- * Called to deqeue next work item for the job.
- */
- @UnsupportedAppUsage
- JobWorkItem dequeueWork(int jobId);
- /*
- * Called to report that job has completed processing a work item.
- */
- @UnsupportedAppUsage
- boolean completeWork(int jobId, int workId);
- /*
- * Tell the job manager that the client is done with its execution, so that it can go on to
- * the next one and stop attributing wakelock time to us etc.
- *
- * @param jobId Unique integer used to identify this job.
- * @param reschedule Whether or not to reschedule this job.
- */
- @UnsupportedAppUsage
- void jobFinished(int jobId, boolean reschedule);
-}
diff --git a/core/java/android/app/job/IJobScheduler.aidl b/core/java/android/app/job/IJobScheduler.aidl
deleted file mode 100644
index 3006f50e54fc..000000000000
--- a/core/java/android/app/job/IJobScheduler.aidl
+++ /dev/null
@@ -1,38 +0,0 @@
-/**
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.app.job;
-
-import android.app.job.JobInfo;
-import android.app.job.JobSnapshot;
-import android.app.job.JobWorkItem;
-import android.content.pm.ParceledListSlice;
-
- /**
- * IPC interface that supports the app-facing {@link #JobScheduler} api.
- * {@hide}
- */
-interface IJobScheduler {
- int schedule(in JobInfo job);
- int enqueue(in JobInfo job, in JobWorkItem work);
- int scheduleAsPackage(in JobInfo job, String packageName, int userId, String tag);
- void cancel(int jobId);
- void cancelAll();
- ParceledListSlice getAllPendingJobs();
- JobInfo getPendingJob(int jobId);
- List<JobInfo> getStartedJobs();
- ParceledListSlice getAllJobSnapshots();
-}
diff --git a/core/java/android/app/job/IJobService.aidl b/core/java/android/app/job/IJobService.aidl
deleted file mode 100644
index 22ad252b9639..000000000000
--- a/core/java/android/app/job/IJobService.aidl
+++ /dev/null
@@ -1,34 +0,0 @@
-/**
- * Copyright 2014, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.app.job;
-
-import android.app.job.JobParameters;
-
-/**
- * Interface that the framework uses to communicate with application code that implements a
- * JobService. End user code does not implement this interface directly; instead, the app's
- * service implementation will extend android.app.job.JobService.
- * {@hide}
- */
-oneway interface IJobService {
- /** Begin execution of application's job. */
- @UnsupportedAppUsage
- void startJob(in JobParameters jobParams);
- /** Stop execution of application's job. */
- @UnsupportedAppUsage
- void stopJob(in JobParameters jobParams);
-}
diff --git a/core/java/android/app/job/JobInfo.aidl b/core/java/android/app/job/JobInfo.aidl
deleted file mode 100644
index 7b198a8ab14d..000000000000
--- a/core/java/android/app/job/JobInfo.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/**
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.app.job;
-
-parcelable JobInfo;
diff --git a/core/java/android/app/job/JobInfo.java b/core/java/android/app/job/JobInfo.java
deleted file mode 100644
index 8b3b3a28f2bc..000000000000
--- a/core/java/android/app/job/JobInfo.java
+++ /dev/null
@@ -1,1597 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package android.app.job;
-
-import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
-import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
-import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING;
-import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN;
-import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
-import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
-import static android.util.TimeUtils.formatDuration;
-
-import android.annotation.BytesLong;
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.RequiresPermission;
-import android.annotation.UnsupportedAppUsage;
-import android.content.ClipData;
-import android.content.ComponentName;
-import android.net.NetworkRequest;
-import android.net.NetworkSpecifier;
-import android.net.Uri;
-import android.os.BaseBundle;
-import android.os.Build;
-import android.os.Bundle;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.os.PersistableBundle;
-import android.util.Log;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Objects;
-
-/**
- * Container of data passed to the {@link android.app.job.JobScheduler} fully encapsulating the
- * parameters required to schedule work against the calling application. These are constructed
- * using the {@link JobInfo.Builder}.
- * You must specify at least one sort of constraint on the JobInfo object that you are creating.
- * The goal here is to provide the scheduler with high-level semantics about the work you want to
- * accomplish. Doing otherwise with throw an exception in your app.
- */
-public class JobInfo implements Parcelable {
- private static String TAG = "JobInfo";
-
- /** @hide */
- @IntDef(prefix = { "NETWORK_TYPE_" }, value = {
- NETWORK_TYPE_NONE,
- NETWORK_TYPE_ANY,
- NETWORK_TYPE_UNMETERED,
- NETWORK_TYPE_NOT_ROAMING,
- NETWORK_TYPE_CELLULAR,
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface NetworkType {}
-
- /** Default. */
- public static final int NETWORK_TYPE_NONE = 0;
- /** This job requires network connectivity. */
- public static final int NETWORK_TYPE_ANY = 1;
- /** This job requires network connectivity that is unmetered. */
- public static final int NETWORK_TYPE_UNMETERED = 2;
- /** This job requires network connectivity that is not roaming. */
- public static final int NETWORK_TYPE_NOT_ROAMING = 3;
- /** This job requires network connectivity that is a cellular network. */
- public static final int NETWORK_TYPE_CELLULAR = 4;
-
- /**
- * This job requires metered connectivity such as most cellular data
- * networks.
- *
- * @deprecated Cellular networks may be unmetered, or Wi-Fi networks may be
- * metered, so this isn't a good way of selecting a specific
- * transport. Instead, use {@link #NETWORK_TYPE_CELLULAR} or
- * {@link android.net.NetworkRequest.Builder#addTransportType(int)}
- * if your job requires a specific network transport.
- */
- @Deprecated
- public static final int NETWORK_TYPE_METERED = NETWORK_TYPE_CELLULAR;
-
- /** Sentinel value indicating that bytes are unknown. */
- public static final int NETWORK_BYTES_UNKNOWN = -1;
-
- /**
- * Amount of backoff a job has initially by default, in milliseconds.
- */
- public static final long DEFAULT_INITIAL_BACKOFF_MILLIS = 30000L; // 30 seconds.
-
- /**
- * Maximum backoff we allow for a job, in milliseconds.
- */
- public static final long MAX_BACKOFF_DELAY_MILLIS = 5 * 60 * 60 * 1000; // 5 hours.
-
- /** @hide */
- @IntDef(prefix = { "BACKOFF_POLICY_" }, value = {
- BACKOFF_POLICY_LINEAR,
- BACKOFF_POLICY_EXPONENTIAL,
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface BackoffPolicy {}
-
- /**
- * Linearly back-off a failed job. See
- * {@link android.app.job.JobInfo.Builder#setBackoffCriteria(long, int)}
- * retry_time(current_time, num_failures) =
- * current_time + initial_backoff_millis * num_failures, num_failures >= 1
- */
- public static final int BACKOFF_POLICY_LINEAR = 0;
-
- /**
- * Exponentially back-off a failed job. See
- * {@link android.app.job.JobInfo.Builder#setBackoffCriteria(long, int)}
- *
- * retry_time(current_time, num_failures) =
- * current_time + initial_backoff_millis * 2 ^ (num_failures - 1), num_failures >= 1
- */
- public static final int BACKOFF_POLICY_EXPONENTIAL = 1;
-
- /* Minimum interval for a periodic job, in milliseconds. */
- private static final long MIN_PERIOD_MILLIS = 15 * 60 * 1000L; // 15 minutes
-
- /* Minimum flex for a periodic job, in milliseconds. */
- private static final long MIN_FLEX_MILLIS = 5 * 60 * 1000L; // 5 minutes
-
- /**
- * Minimum backoff interval for a job, in milliseconds
- * @hide
- */
- public static final long MIN_BACKOFF_MILLIS = 10 * 1000L; // 10 seconds
-
- /**
- * Query the minimum interval allowed for periodic scheduled jobs. Attempting
- * to declare a smaller period that this when scheduling a job will result in a
- * job that is still periodic, but will run with this effective period.
- *
- * @return The minimum available interval for scheduling periodic jobs, in milliseconds.
- */
- public static final long getMinPeriodMillis() {
- return MIN_PERIOD_MILLIS;
- }
-
- /**
- * Query the minimum flex time allowed for periodic scheduled jobs. Attempting
- * to declare a shorter flex time than this when scheduling such a job will
- * result in this amount as the effective flex time for the job.
- *
- * @return The minimum available flex time for scheduling periodic jobs, in milliseconds.
- */
- public static final long getMinFlexMillis() {
- return MIN_FLEX_MILLIS;
- }
-
- /**
- * Query the minimum automatic-reschedule backoff interval permitted for jobs.
- * @hide
- */
- public static final long getMinBackoffMillis() {
- return MIN_BACKOFF_MILLIS;
- }
-
- /**
- * Default type of backoff.
- * @hide
- */
- public static final int DEFAULT_BACKOFF_POLICY = BACKOFF_POLICY_EXPONENTIAL;
-
- /**
- * Default of {@link #getPriority}.
- * @hide
- */
- public static final int PRIORITY_DEFAULT = 0;
-
- /**
- * Value of {@link #getPriority} for expedited syncs.
- * @hide
- */
- public static final int PRIORITY_SYNC_EXPEDITED = 10;
-
- /**
- * Value of {@link #getPriority} for first time initialization syncs.
- * @hide
- */
- public static final int PRIORITY_SYNC_INITIALIZATION = 20;
-
- /**
- * Value of {@link #getPriority} for a BFGS app (overrides the supplied
- * JobInfo priority if it is smaller).
- * @hide
- */
- public static final int PRIORITY_BOUND_FOREGROUND_SERVICE = 30;
-
- /** @hide For backward compatibility. */
- @UnsupportedAppUsage
- public static final int PRIORITY_FOREGROUND_APP = PRIORITY_BOUND_FOREGROUND_SERVICE;
-
- /**
- * Value of {@link #getPriority} for a FG service app (overrides the supplied
- * JobInfo priority if it is smaller).
- * @hide
- */
- @UnsupportedAppUsage
- public static final int PRIORITY_FOREGROUND_SERVICE = 35;
-
- /**
- * Value of {@link #getPriority} for the current top app (overrides the supplied
- * JobInfo priority if it is smaller).
- * @hide
- */
- public static final int PRIORITY_TOP_APP = 40;
-
- /**
- * Adjustment of {@link #getPriority} if the app has often (50% or more of the time)
- * been running jobs.
- * @hide
- */
- public static final int PRIORITY_ADJ_OFTEN_RUNNING = -40;
-
- /**
- * Adjustment of {@link #getPriority} if the app has always (90% or more of the time)
- * been running jobs.
- * @hide
- */
- public static final int PRIORITY_ADJ_ALWAYS_RUNNING = -80;
-
- /**
- * Indicates that the implementation of this job will be using
- * {@link JobService#startForeground(int, android.app.Notification)} to run
- * in the foreground.
- * <p>
- * When set, the internal scheduling of this job will ignore any background
- * network restrictions for the requesting app. Note that this flag alone
- * doesn't actually place your {@link JobService} in the foreground; you
- * still need to post the notification yourself.
- * <p>
- * To use this flag, the caller must hold the
- * {@link android.Manifest.permission#CONNECTIVITY_INTERNAL} permission.
- *
- * @hide
- */
- @UnsupportedAppUsage
- public static final int FLAG_WILL_BE_FOREGROUND = 1 << 0;
-
- /**
- * Allows this job to run despite doze restrictions as long as the app is in the foreground
- * or on the temporary whitelist
- * @hide
- */
- public static final int FLAG_IMPORTANT_WHILE_FOREGROUND = 1 << 1;
-
- /**
- * @hide
- */
- public static final int FLAG_PREFETCH = 1 << 2;
-
- /**
- * This job needs to be exempted from the app standby throttling. Only the system (UID 1000)
- * can set it. Jobs with a time constrant must not have it.
- *
- * @hide
- */
- public static final int FLAG_EXEMPT_FROM_APP_STANDBY = 1 << 3;
-
- /**
- * @hide
- */
- public static final int CONSTRAINT_FLAG_CHARGING = 1 << 0;
-
- /**
- * @hide
- */
- public static final int CONSTRAINT_FLAG_BATTERY_NOT_LOW = 1 << 1;
-
- /**
- * @hide
- */
- public static final int CONSTRAINT_FLAG_DEVICE_IDLE = 1 << 2;
-
- /**
- * @hide
- */
- public static final int CONSTRAINT_FLAG_STORAGE_NOT_LOW = 1 << 3;
-
- @UnsupportedAppUsage
- private final int jobId;
- private final PersistableBundle extras;
- private final Bundle transientExtras;
- private final ClipData clipData;
- private final int clipGrantFlags;
- @UnsupportedAppUsage
- private final ComponentName service;
- private final int constraintFlags;
- private final TriggerContentUri[] triggerContentUris;
- private final long triggerContentUpdateDelay;
- private final long triggerContentMaxDelay;
- private final boolean hasEarlyConstraint;
- private final boolean hasLateConstraint;
- private final NetworkRequest networkRequest;
- private final long networkDownloadBytes;
- private final long networkUploadBytes;
- private final long minLatencyMillis;
- private final long maxExecutionDelayMillis;
- private final boolean isPeriodic;
- private final boolean isPersisted;
- private final long intervalMillis;
- private final long flexMillis;
- private final long initialBackoffMillis;
- private final int backoffPolicy;
- private final int priority;
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
- private final int flags;
-
- /**
- * Unique job id associated with this application (uid). This is the same job ID
- * you supplied in the {@link Builder} constructor.
- */
- public int getId() {
- return jobId;
- }
-
- /**
- * @see JobInfo.Builder#setExtras(PersistableBundle)
- */
- public @NonNull PersistableBundle getExtras() {
- return extras;
- }
-
- /**
- * @see JobInfo.Builder#setTransientExtras(Bundle)
- */
- public @NonNull Bundle getTransientExtras() {
- return transientExtras;
- }
-
- /**
- * @see JobInfo.Builder#setClipData(ClipData, int)
- */
- public @Nullable ClipData getClipData() {
- return clipData;
- }
-
- /**
- * @see JobInfo.Builder#setClipData(ClipData, int)
- */
- public int getClipGrantFlags() {
- return clipGrantFlags;
- }
-
- /**
- * Name of the service endpoint that will be called back into by the JobScheduler.
- */
- public @NonNull ComponentName getService() {
- return service;
- }
-
- /** @hide */
- public int getPriority() {
- return priority;
- }
-
- /** @hide */
- public int getFlags() {
- return flags;
- }
-
- /** @hide */
- public boolean isExemptedFromAppStandby() {
- return ((flags & FLAG_EXEMPT_FROM_APP_STANDBY) != 0) && !isPeriodic();
- }
-
- /**
- * @see JobInfo.Builder#setRequiresCharging(boolean)
- */
- public boolean isRequireCharging() {
- return (constraintFlags & CONSTRAINT_FLAG_CHARGING) != 0;
- }
-
- /**
- * @see JobInfo.Builder#setRequiresBatteryNotLow(boolean)
- */
- public boolean isRequireBatteryNotLow() {
- return (constraintFlags & CONSTRAINT_FLAG_BATTERY_NOT_LOW) != 0;
- }
-
- /**
- * @see JobInfo.Builder#setRequiresDeviceIdle(boolean)
- */
- public boolean isRequireDeviceIdle() {
- return (constraintFlags & CONSTRAINT_FLAG_DEVICE_IDLE) != 0;
- }
-
- /**
- * @see JobInfo.Builder#setRequiresStorageNotLow(boolean)
- */
- public boolean isRequireStorageNotLow() {
- return (constraintFlags & CONSTRAINT_FLAG_STORAGE_NOT_LOW) != 0;
- }
-
- /**
- * @hide
- */
- public int getConstraintFlags() {
- return constraintFlags;
- }
-
- /**
- * Which content: URIs must change for the job to be scheduled. Returns null
- * if there are none required.
- * @see JobInfo.Builder#addTriggerContentUri(TriggerContentUri)
- */
- public @Nullable TriggerContentUri[] getTriggerContentUris() {
- return triggerContentUris;
- }
-
- /**
- * When triggering on content URI changes, this is the delay from when a change
- * is detected until the job is scheduled.
- * @see JobInfo.Builder#setTriggerContentUpdateDelay(long)
- */
- public long getTriggerContentUpdateDelay() {
- return triggerContentUpdateDelay;
- }
-
- /**
- * When triggering on content URI changes, this is the maximum delay we will
- * use before scheduling the job.
- * @see JobInfo.Builder#setTriggerContentMaxDelay(long)
- */
- public long getTriggerContentMaxDelay() {
- return triggerContentMaxDelay;
- }
-
- /**
- * Return the basic description of the kind of network this job requires.
- *
- * @deprecated This method attempts to map {@link #getRequiredNetwork()}
- * into the set of simple constants, which results in a loss of
- * fidelity. Callers should move to using
- * {@link #getRequiredNetwork()} directly.
- * @see Builder#setRequiredNetworkType(int)
- */
- @Deprecated
- public @NetworkType int getNetworkType() {
- if (networkRequest == null) {
- return NETWORK_TYPE_NONE;
- } else if (networkRequest.networkCapabilities.hasCapability(NET_CAPABILITY_NOT_METERED)) {
- return NETWORK_TYPE_UNMETERED;
- } else if (networkRequest.networkCapabilities.hasCapability(NET_CAPABILITY_NOT_ROAMING)) {
- return NETWORK_TYPE_NOT_ROAMING;
- } else if (networkRequest.networkCapabilities.hasTransport(TRANSPORT_CELLULAR)) {
- return NETWORK_TYPE_CELLULAR;
- } else {
- return NETWORK_TYPE_ANY;
- }
- }
-
- /**
- * Return the detailed description of the kind of network this job requires,
- * or {@code null} if no specific kind of network is required.
- *
- * @see Builder#setRequiredNetwork(NetworkRequest)
- */
- public @Nullable NetworkRequest getRequiredNetwork() {
- return networkRequest;
- }
-
- /**
- * Return the estimated size of download traffic that will be performed by
- * this job, in bytes.
- *
- * @return Estimated size of download traffic, or
- * {@link #NETWORK_BYTES_UNKNOWN} when unknown.
- * @see Builder#setEstimatedNetworkBytes(long, long)
- */
- public @BytesLong long getEstimatedNetworkDownloadBytes() {
- return networkDownloadBytes;
- }
-
- /**
- * Return the estimated size of upload traffic that will be performed by
- * this job, in bytes.
- *
- * @return Estimated size of upload traffic, or
- * {@link #NETWORK_BYTES_UNKNOWN} when unknown.
- * @see Builder#setEstimatedNetworkBytes(long, long)
- */
- public @BytesLong long getEstimatedNetworkUploadBytes() {
- return networkUploadBytes;
- }
-
- /**
- * Set for a job that does not recur periodically, to specify a delay after which the job
- * will be eligible for execution. This value is not set if the job recurs periodically.
- * @see JobInfo.Builder#setMinimumLatency(long)
- */
- public long getMinLatencyMillis() {
- return minLatencyMillis;
- }
-
- /**
- * @see JobInfo.Builder#setOverrideDeadline(long)
- */
- public long getMaxExecutionDelayMillis() {
- return maxExecutionDelayMillis;
- }
-
- /**
- * Track whether this job will repeat with a given period.
- * @see JobInfo.Builder#setPeriodic(long)
- * @see JobInfo.Builder#setPeriodic(long, long)
- */
- public boolean isPeriodic() {
- return isPeriodic;
- }
-
- /**
- * @see JobInfo.Builder#setPersisted(boolean)
- */
- public boolean isPersisted() {
- return isPersisted;
- }
-
- /**
- * Set to the interval between occurrences of this job. This value is <b>not</b> set if the
- * job does not recur periodically.
- * @see JobInfo.Builder#setPeriodic(long)
- * @see JobInfo.Builder#setPeriodic(long, long)
- */
- public long getIntervalMillis() {
- return intervalMillis;
- }
-
- /**
- * Flex time for this job. Only valid if this is a periodic job. The job can
- * execute at any time in a window of flex length at the end of the period.
- * @see JobInfo.Builder#setPeriodic(long)
- * @see JobInfo.Builder#setPeriodic(long, long)
- */
- public long getFlexMillis() {
- return flexMillis;
- }
-
- /**
- * The amount of time the JobScheduler will wait before rescheduling a failed job. This value
- * will be increased depending on the backoff policy specified at job creation time. Defaults
- * to 30 seconds, minimum is currently 10 seconds.
- * @see JobInfo.Builder#setBackoffCriteria(long, int)
- */
- public long getInitialBackoffMillis() {
- return initialBackoffMillis;
- }
-
- /**
- * Return the backoff policy of this job.
- * @see JobInfo.Builder#setBackoffCriteria(long, int)
- */
- public @BackoffPolicy int getBackoffPolicy() {
- return backoffPolicy;
- }
-
- /**
- * @see JobInfo.Builder#setImportantWhileForeground(boolean)
- */
- public boolean isImportantWhileForeground() {
- return (flags & FLAG_IMPORTANT_WHILE_FOREGROUND) != 0;
- }
-
- /**
- * @see JobInfo.Builder#setPrefetch(boolean)
- */
- public boolean isPrefetch() {
- return (flags & FLAG_PREFETCH) != 0;
- }
-
- /**
- * User can specify an early constraint of 0L, which is valid, so we keep track of whether the
- * function was called at all.
- * @hide
- */
- public boolean hasEarlyConstraint() {
- return hasEarlyConstraint;
- }
-
- /**
- * User can specify a late constraint of 0L, which is valid, so we keep track of whether the
- * function was called at all.
- * @hide
- */
- public boolean hasLateConstraint() {
- return hasLateConstraint;
- }
-
- private static boolean kindofEqualsBundle(BaseBundle a, BaseBundle b) {
- return (a == b) || (a != null && a.kindofEquals(b));
- }
-
- @Override
- public boolean equals(Object o) {
- if (!(o instanceof JobInfo)) {
- return false;
- }
- JobInfo j = (JobInfo) o;
- if (jobId != j.jobId) {
- return false;
- }
- // XXX won't be correct if one is parcelled and the other not.
- if (!kindofEqualsBundle(extras, j.extras)) {
- return false;
- }
- // XXX won't be correct if one is parcelled and the other not.
- if (!kindofEqualsBundle(transientExtras, j.transientExtras)) {
- return false;
- }
- // XXX for now we consider two different clip data objects to be different,
- // regardless of whether their contents are the same.
- if (clipData != j.clipData) {
- return false;
- }
- if (clipGrantFlags != j.clipGrantFlags) {
- return false;
- }
- if (!Objects.equals(service, j.service)) {
- return false;
- }
- if (constraintFlags != j.constraintFlags) {
- return false;
- }
- if (!Arrays.equals(triggerContentUris, j.triggerContentUris)) {
- return false;
- }
- if (triggerContentUpdateDelay != j.triggerContentUpdateDelay) {
- return false;
- }
- if (triggerContentMaxDelay != j.triggerContentMaxDelay) {
- return false;
- }
- if (hasEarlyConstraint != j.hasEarlyConstraint) {
- return false;
- }
- if (hasLateConstraint != j.hasLateConstraint) {
- return false;
- }
- if (!Objects.equals(networkRequest, j.networkRequest)) {
- return false;
- }
- if (networkDownloadBytes != j.networkDownloadBytes) {
- return false;
- }
- if (networkUploadBytes != j.networkUploadBytes) {
- return false;
- }
- if (minLatencyMillis != j.minLatencyMillis) {
- return false;
- }
- if (maxExecutionDelayMillis != j.maxExecutionDelayMillis) {
- return false;
- }
- if (isPeriodic != j.isPeriodic) {
- return false;
- }
- if (isPersisted != j.isPersisted) {
- return false;
- }
- if (intervalMillis != j.intervalMillis) {
- return false;
- }
- if (flexMillis != j.flexMillis) {
- return false;
- }
- if (initialBackoffMillis != j.initialBackoffMillis) {
- return false;
- }
- if (backoffPolicy != j.backoffPolicy) {
- return false;
- }
- if (priority != j.priority) {
- return false;
- }
- if (flags != j.flags) {
- return false;
- }
- return true;
- }
-
- @Override
- public int hashCode() {
- int hashCode = jobId;
- if (extras != null) {
- hashCode = 31 * hashCode + extras.hashCode();
- }
- if (transientExtras != null) {
- hashCode = 31 * hashCode + transientExtras.hashCode();
- }
- if (clipData != null) {
- hashCode = 31 * hashCode + clipData.hashCode();
- }
- hashCode = 31*hashCode + clipGrantFlags;
- if (service != null) {
- hashCode = 31 * hashCode + service.hashCode();
- }
- hashCode = 31 * hashCode + constraintFlags;
- if (triggerContentUris != null) {
- hashCode = 31 * hashCode + Arrays.hashCode(triggerContentUris);
- }
- hashCode = 31 * hashCode + Long.hashCode(triggerContentUpdateDelay);
- hashCode = 31 * hashCode + Long.hashCode(triggerContentMaxDelay);
- hashCode = 31 * hashCode + Boolean.hashCode(hasEarlyConstraint);
- hashCode = 31 * hashCode + Boolean.hashCode(hasLateConstraint);
- if (networkRequest != null) {
- hashCode = 31 * hashCode + networkRequest.hashCode();
- }
- hashCode = 31 * hashCode + Long.hashCode(networkDownloadBytes);
- hashCode = 31 * hashCode + Long.hashCode(networkUploadBytes);
- hashCode = 31 * hashCode + Long.hashCode(minLatencyMillis);
- hashCode = 31 * hashCode + Long.hashCode(maxExecutionDelayMillis);
- hashCode = 31 * hashCode + Boolean.hashCode(isPeriodic);
- hashCode = 31 * hashCode + Boolean.hashCode(isPersisted);
- hashCode = 31 * hashCode + Long.hashCode(intervalMillis);
- hashCode = 31 * hashCode + Long.hashCode(flexMillis);
- hashCode = 31 * hashCode + Long.hashCode(initialBackoffMillis);
- hashCode = 31 * hashCode + backoffPolicy;
- hashCode = 31 * hashCode + priority;
- hashCode = 31 * hashCode + flags;
- return hashCode;
- }
-
- private JobInfo(Parcel in) {
- jobId = in.readInt();
- extras = in.readPersistableBundle();
- transientExtras = in.readBundle();
- if (in.readInt() != 0) {
- clipData = ClipData.CREATOR.createFromParcel(in);
- clipGrantFlags = in.readInt();
- } else {
- clipData = null;
- clipGrantFlags = 0;
- }
- service = in.readParcelable(null);
- constraintFlags = in.readInt();
- triggerContentUris = in.createTypedArray(TriggerContentUri.CREATOR);
- triggerContentUpdateDelay = in.readLong();
- triggerContentMaxDelay = in.readLong();
- if (in.readInt() != 0) {
- networkRequest = NetworkRequest.CREATOR.createFromParcel(in);
- } else {
- networkRequest = null;
- }
- networkDownloadBytes = in.readLong();
- networkUploadBytes = in.readLong();
- minLatencyMillis = in.readLong();
- maxExecutionDelayMillis = in.readLong();
- isPeriodic = in.readInt() == 1;
- isPersisted = in.readInt() == 1;
- intervalMillis = in.readLong();
- flexMillis = in.readLong();
- initialBackoffMillis = in.readLong();
- backoffPolicy = in.readInt();
- hasEarlyConstraint = in.readInt() == 1;
- hasLateConstraint = in.readInt() == 1;
- priority = in.readInt();
- flags = in.readInt();
- }
-
- private JobInfo(JobInfo.Builder b) {
- jobId = b.mJobId;
- extras = b.mExtras.deepCopy();
- transientExtras = b.mTransientExtras.deepCopy();
- clipData = b.mClipData;
- clipGrantFlags = b.mClipGrantFlags;
- service = b.mJobService;
- constraintFlags = b.mConstraintFlags;
- triggerContentUris = b.mTriggerContentUris != null
- ? b.mTriggerContentUris.toArray(new TriggerContentUri[b.mTriggerContentUris.size()])
- : null;
- triggerContentUpdateDelay = b.mTriggerContentUpdateDelay;
- triggerContentMaxDelay = b.mTriggerContentMaxDelay;
- networkRequest = b.mNetworkRequest;
- networkDownloadBytes = b.mNetworkDownloadBytes;
- networkUploadBytes = b.mNetworkUploadBytes;
- minLatencyMillis = b.mMinLatencyMillis;
- maxExecutionDelayMillis = b.mMaxExecutionDelayMillis;
- isPeriodic = b.mIsPeriodic;
- isPersisted = b.mIsPersisted;
- intervalMillis = b.mIntervalMillis;
- flexMillis = b.mFlexMillis;
- initialBackoffMillis = b.mInitialBackoffMillis;
- backoffPolicy = b.mBackoffPolicy;
- hasEarlyConstraint = b.mHasEarlyConstraint;
- hasLateConstraint = b.mHasLateConstraint;
- priority = b.mPriority;
- flags = b.mFlags;
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel out, int flags) {
- out.writeInt(jobId);
- out.writePersistableBundle(extras);
- out.writeBundle(transientExtras);
- if (clipData != null) {
- out.writeInt(1);
- clipData.writeToParcel(out, flags);
- out.writeInt(clipGrantFlags);
- } else {
- out.writeInt(0);
- }
- out.writeParcelable(service, flags);
- out.writeInt(constraintFlags);
- out.writeTypedArray(triggerContentUris, flags);
- out.writeLong(triggerContentUpdateDelay);
- out.writeLong(triggerContentMaxDelay);
- if (networkRequest != null) {
- out.writeInt(1);
- networkRequest.writeToParcel(out, flags);
- } else {
- out.writeInt(0);
- }
- out.writeLong(networkDownloadBytes);
- out.writeLong(networkUploadBytes);
- out.writeLong(minLatencyMillis);
- out.writeLong(maxExecutionDelayMillis);
- out.writeInt(isPeriodic ? 1 : 0);
- out.writeInt(isPersisted ? 1 : 0);
- out.writeLong(intervalMillis);
- out.writeLong(flexMillis);
- out.writeLong(initialBackoffMillis);
- out.writeInt(backoffPolicy);
- out.writeInt(hasEarlyConstraint ? 1 : 0);
- out.writeInt(hasLateConstraint ? 1 : 0);
- out.writeInt(priority);
- out.writeInt(this.flags);
- }
-
- public static final @android.annotation.NonNull Creator<JobInfo> CREATOR = new Creator<JobInfo>() {
- @Override
- public JobInfo createFromParcel(Parcel in) {
- return new JobInfo(in);
- }
-
- @Override
- public JobInfo[] newArray(int size) {
- return new JobInfo[size];
- }
- };
-
- @Override
- public String toString() {
- return "(job:" + jobId + "/" + service.flattenToShortString() + ")";
- }
-
- /**
- * Information about a content URI modification that a job would like to
- * trigger on.
- */
- public static final class TriggerContentUri implements Parcelable {
- private final Uri mUri;
- private final int mFlags;
-
- /** @hide */
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(flag = true, prefix = { "FLAG_" }, value = {
- FLAG_NOTIFY_FOR_DESCENDANTS,
- })
- public @interface Flags { }
-
- /**
- * Flag for trigger: also trigger if any descendants of the given URI change.
- * Corresponds to the <var>notifyForDescendants</var> of
- * {@link android.content.ContentResolver#registerContentObserver}.
- */
- public static final int FLAG_NOTIFY_FOR_DESCENDANTS = 1<<0;
-
- /**
- * Create a new trigger description.
- * @param uri The URI to observe. Must be non-null.
- * @param flags Flags for the observer.
- */
- public TriggerContentUri(@NonNull Uri uri, @Flags int flags) {
- mUri = uri;
- mFlags = flags;
- }
-
- /**
- * Return the Uri this trigger was created for.
- */
- public Uri getUri() {
- return mUri;
- }
-
- /**
- * Return the flags supplied for the trigger.
- */
- public @Flags int getFlags() {
- return mFlags;
- }
-
- @Override
- public boolean equals(Object o) {
- if (!(o instanceof TriggerContentUri)) {
- return false;
- }
- TriggerContentUri t = (TriggerContentUri) o;
- return Objects.equals(t.mUri, mUri) && t.mFlags == mFlags;
- }
-
- @Override
- public int hashCode() {
- return (mUri == null ? 0 : mUri.hashCode()) ^ mFlags;
- }
-
- private TriggerContentUri(Parcel in) {
- mUri = Uri.CREATOR.createFromParcel(in);
- mFlags = in.readInt();
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel out, int flags) {
- mUri.writeToParcel(out, flags);
- out.writeInt(mFlags);
- }
-
- public static final @android.annotation.NonNull Creator<TriggerContentUri> CREATOR = new Creator<TriggerContentUri>() {
- @Override
- public TriggerContentUri createFromParcel(Parcel in) {
- return new TriggerContentUri(in);
- }
-
- @Override
- public TriggerContentUri[] newArray(int size) {
- return new TriggerContentUri[size];
- }
- };
- }
-
- /** Builder class for constructing {@link JobInfo} objects. */
- public static final class Builder {
- private final int mJobId;
- private final ComponentName mJobService;
- private PersistableBundle mExtras = PersistableBundle.EMPTY;
- private Bundle mTransientExtras = Bundle.EMPTY;
- private ClipData mClipData;
- private int mClipGrantFlags;
- private int mPriority = PRIORITY_DEFAULT;
- private int mFlags;
- // Requirements.
- private int mConstraintFlags;
- private NetworkRequest mNetworkRequest;
- private long mNetworkDownloadBytes = NETWORK_BYTES_UNKNOWN;
- private long mNetworkUploadBytes = NETWORK_BYTES_UNKNOWN;
- private ArrayList<TriggerContentUri> mTriggerContentUris;
- private long mTriggerContentUpdateDelay = -1;
- private long mTriggerContentMaxDelay = -1;
- private boolean mIsPersisted;
- // One-off parameters.
- private long mMinLatencyMillis;
- private long mMaxExecutionDelayMillis;
- // Periodic parameters.
- private boolean mIsPeriodic;
- private boolean mHasEarlyConstraint;
- private boolean mHasLateConstraint;
- private long mIntervalMillis;
- private long mFlexMillis;
- // Back-off parameters.
- private long mInitialBackoffMillis = DEFAULT_INITIAL_BACKOFF_MILLIS;
- private int mBackoffPolicy = DEFAULT_BACKOFF_POLICY;
- /** Easy way to track whether the client has tried to set a back-off policy. */
- private boolean mBackoffPolicySet = false;
-
- /**
- * Initialize a new Builder to construct a {@link JobInfo}.
- *
- * @param jobId Application-provided id for this job. Subsequent calls to cancel, or
- * jobs created with the same jobId, will update the pre-existing job with
- * the same id. This ID must be unique across all clients of the same uid
- * (not just the same package). You will want to make sure this is a stable
- * id across app updates, so probably not based on a resource ID.
- * @param jobService The endpoint that you implement that will receive the callback from the
- * JobScheduler.
- */
- public Builder(int jobId, @NonNull ComponentName jobService) {
- mJobService = jobService;
- mJobId = jobId;
- }
-
- /** @hide */
- @UnsupportedAppUsage
- public Builder setPriority(int priority) {
- mPriority = priority;
- return this;
- }
-
- /** @hide */
- @UnsupportedAppUsage
- public Builder setFlags(int flags) {
- mFlags = flags;
- return this;
- }
-
- /**
- * Set optional extras. This is persisted, so we only allow primitive types.
- * @param extras Bundle containing extras you want the scheduler to hold on to for you.
- * @see JobInfo#getExtras()
- */
- public Builder setExtras(@NonNull PersistableBundle extras) {
- mExtras = extras;
- return this;
- }
-
- /**
- * Set optional transient extras.
- *
- * <p>Because setting this property is not compatible with persisted
- * jobs, doing so will throw an {@link java.lang.IllegalArgumentException} when
- * {@link android.app.job.JobInfo.Builder#build()} is called.</p>
- *
- * @param extras Bundle containing extras you want the scheduler to hold on to for you.
- * @see JobInfo#getTransientExtras()
- */
- public Builder setTransientExtras(@NonNull Bundle extras) {
- mTransientExtras = extras;
- return this;
- }
-
- /**
- * Set a {@link ClipData} associated with this Job.
- *
- * <p>The main purpose of providing a ClipData is to allow granting of
- * URI permissions for data associated with the clip. The exact kind
- * of permission grant to perform is specified through <var>grantFlags</var>.
- *
- * <p>If the ClipData contains items that are Intents, any
- * grant flags in those Intents will be ignored. Only flags provided as an argument
- * to this method are respected, and will be applied to all Uri or
- * Intent items in the clip (or sub-items of the clip).
- *
- * <p>Because setting this property is not compatible with persisted
- * jobs, doing so will throw an {@link java.lang.IllegalArgumentException} when
- * {@link android.app.job.JobInfo.Builder#build()} is called.</p>
- *
- * @param clip The new clip to set. May be null to clear the current clip.
- * @param grantFlags The desired permissions to grant for any URIs. This should be
- * a combination of {@link android.content.Intent#FLAG_GRANT_READ_URI_PERMISSION},
- * {@link android.content.Intent#FLAG_GRANT_WRITE_URI_PERMISSION}, and
- * {@link android.content.Intent#FLAG_GRANT_PREFIX_URI_PERMISSION}.
- * @see JobInfo#getClipData()
- * @see JobInfo#getClipGrantFlags()
- */
- public Builder setClipData(@Nullable ClipData clip, int grantFlags) {
- mClipData = clip;
- mClipGrantFlags = grantFlags;
- return this;
- }
-
- /**
- * Set basic description of the kind of network your job requires. If
- * you need more precise control over network capabilities, see
- * {@link #setRequiredNetwork(NetworkRequest)}.
- * <p>
- * If your job doesn't need a network connection, you don't need to call
- * this method, as the default value is {@link #NETWORK_TYPE_NONE}.
- * <p>
- * Calling this method defines network as a strict requirement for your
- * job. If the network requested is not available your job will never
- * run. See {@link #setOverrideDeadline(long)} to change this behavior.
- * Calling this method will override any requirements previously defined
- * by {@link #setRequiredNetwork(NetworkRequest)}; you typically only
- * want to call one of these methods.
- * <p class="note">
- * When your job executes in
- * {@link JobService#onStartJob(JobParameters)}, be sure to use the
- * specific network returned by {@link JobParameters#getNetwork()},
- * otherwise you'll use the default network which may not meet this
- * constraint.
- *
- * @see #setRequiredNetwork(NetworkRequest)
- * @see JobInfo#getNetworkType()
- * @see JobParameters#getNetwork()
- */
- public Builder setRequiredNetworkType(@NetworkType int networkType) {
- if (networkType == NETWORK_TYPE_NONE) {
- return setRequiredNetwork(null);
- } else {
- final NetworkRequest.Builder builder = new NetworkRequest.Builder();
-
- // All types require validated Internet
- builder.addCapability(NET_CAPABILITY_INTERNET);
- builder.addCapability(NET_CAPABILITY_VALIDATED);
- builder.removeCapability(NET_CAPABILITY_NOT_VPN);
-
- if (networkType == NETWORK_TYPE_ANY) {
- // No other capabilities
- } else if (networkType == NETWORK_TYPE_UNMETERED) {
- builder.addCapability(NET_CAPABILITY_NOT_METERED);
- } else if (networkType == NETWORK_TYPE_NOT_ROAMING) {
- builder.addCapability(NET_CAPABILITY_NOT_ROAMING);
- } else if (networkType == NETWORK_TYPE_CELLULAR) {
- builder.addTransportType(TRANSPORT_CELLULAR);
- }
-
- return setRequiredNetwork(builder.build());
- }
- }
-
- /**
- * Set detailed description of the kind of network your job requires.
- * <p>
- * If your job doesn't need a network connection, you don't need to call
- * this method, as the default is {@code null}.
- * <p>
- * Calling this method defines network as a strict requirement for your
- * job. If the network requested is not available your job will never
- * run. See {@link #setOverrideDeadline(long)} to change this behavior.
- * Calling this method will override any requirements previously defined
- * by {@link #setRequiredNetworkType(int)}; you typically only want to
- * call one of these methods.
- * <p class="note">
- * When your job executes in
- * {@link JobService#onStartJob(JobParameters)}, be sure to use the
- * specific network returned by {@link JobParameters#getNetwork()},
- * otherwise you'll use the default network which may not meet this
- * constraint.
- *
- * @param networkRequest The detailed description of the kind of network
- * this job requires, or {@code null} if no specific kind of
- * network is required. Defining a {@link NetworkSpecifier}
- * is only supported for jobs that aren't persisted.
- * @see #setRequiredNetworkType(int)
- * @see JobInfo#getRequiredNetwork()
- * @see JobParameters#getNetwork()
- */
- public Builder setRequiredNetwork(@Nullable NetworkRequest networkRequest) {
- mNetworkRequest = networkRequest;
- return this;
- }
-
- /**
- * Set the estimated size of network traffic that will be performed by
- * this job, in bytes.
- * <p>
- * Apps are encouraged to provide values that are as accurate as
- * possible, but when the exact size isn't available, an
- * order-of-magnitude estimate can be provided instead. Here are some
- * specific examples:
- * <ul>
- * <li>A job that is backing up a photo knows the exact size of that
- * photo, so it should provide that size as the estimate.
- * <li>A job that refreshes top news stories wouldn't know an exact
- * size, but if the size is expected to be consistently around 100KB, it
- * can provide that order-of-magnitude value as the estimate.
- * <li>A job that synchronizes email could end up using an extreme range
- * of data, from under 1KB when nothing has changed, to dozens of MB
- * when there are new emails with attachments. Jobs that cannot provide
- * reasonable estimates should use the sentinel value
- * {@link JobInfo#NETWORK_BYTES_UNKNOWN}.
- * </ul>
- * Note that the system may choose to delay jobs with large network
- * usage estimates when the device has a poor network connection, in
- * order to save battery.
- * <p>
- * The values provided here only reflect the traffic that will be
- * performed by the base job; if you're using {@link JobWorkItem} then
- * you also need to define the network traffic used by each work item
- * when constructing them.
- *
- * @param downloadBytes The estimated size of network traffic that will
- * be downloaded by this job, in bytes.
- * @param uploadBytes The estimated size of network traffic that will be
- * uploaded by this job, in bytes.
- * @see JobInfo#getEstimatedNetworkDownloadBytes()
- * @see JobInfo#getEstimatedNetworkUploadBytes()
- * @see JobWorkItem#JobWorkItem(android.content.Intent, long, long)
- */
- public Builder setEstimatedNetworkBytes(@BytesLong long downloadBytes,
- @BytesLong long uploadBytes) {
- mNetworkDownloadBytes = downloadBytes;
- mNetworkUploadBytes = uploadBytes;
- return this;
- }
-
- /**
- * Specify that to run this job, the device must be charging (or be a
- * non-battery-powered device connected to permanent power, such as Android TV
- * devices). This defaults to {@code false}.
- *
- * <p class="note">For purposes of running jobs, a battery-powered device
- * "charging" is not quite the same as simply being connected to power. If the
- * device is so busy that the battery is draining despite a power connection, jobs
- * with this constraint will <em>not</em> run. This can happen during some
- * common use cases such as video chat, particularly if the device is plugged in
- * to USB rather than to wall power.
- *
- * @param requiresCharging Pass {@code true} to require that the device be
- * charging in order to run the job.
- * @see JobInfo#isRequireCharging()
- */
- public Builder setRequiresCharging(boolean requiresCharging) {
- mConstraintFlags = (mConstraintFlags&~CONSTRAINT_FLAG_CHARGING)
- | (requiresCharging ? CONSTRAINT_FLAG_CHARGING : 0);
- return this;
- }
-
- /**
- * Specify that to run this job, the device's battery level must not be low.
- * This defaults to false. If true, the job will only run when the battery level
- * is not low, which is generally the point where the user is given a "low battery"
- * warning.
- * @param batteryNotLow Whether or not the device's battery level must not be low.
- * @see JobInfo#isRequireBatteryNotLow()
- */
- public Builder setRequiresBatteryNotLow(boolean batteryNotLow) {
- mConstraintFlags = (mConstraintFlags&~CONSTRAINT_FLAG_BATTERY_NOT_LOW)
- | (batteryNotLow ? CONSTRAINT_FLAG_BATTERY_NOT_LOW : 0);
- return this;
- }
-
- /**
- * When set {@code true}, ensure that this job will not run if the device is in active use.
- * The default state is {@code false}: that is, the for the job to be runnable even when
- * someone is interacting with the device.
- *
- * <p>This state is a loose definition provided by the system. In general, it means that
- * the device is not currently being used interactively, and has not been in use for some
- * time. As such, it is a good time to perform resource heavy jobs. Bear in mind that
- * battery usage will still be attributed to your application, and surfaced to the user in
- * battery stats.</p>
- *
- * <p class="note">Despite the similar naming, this job constraint is <em>not</em>
- * related to the system's "device idle" or "doze" states. This constraint only
- * determines whether a job is allowed to run while the device is directly in use.
- *
- * @param requiresDeviceIdle Pass {@code true} to prevent the job from running
- * while the device is being used interactively.
- * @see JobInfo#isRequireDeviceIdle()
- */
- public Builder setRequiresDeviceIdle(boolean requiresDeviceIdle) {
- mConstraintFlags = (mConstraintFlags&~CONSTRAINT_FLAG_DEVICE_IDLE)
- | (requiresDeviceIdle ? CONSTRAINT_FLAG_DEVICE_IDLE : 0);
- return this;
- }
-
- /**
- * Specify that to run this job, the device's available storage must not be low.
- * This defaults to false. If true, the job will only run when the device is not
- * in a low storage state, which is generally the point where the user is given a
- * "low storage" warning.
- * @param storageNotLow Whether or not the device's available storage must not be low.
- * @see JobInfo#isRequireStorageNotLow()
- */
- public Builder setRequiresStorageNotLow(boolean storageNotLow) {
- mConstraintFlags = (mConstraintFlags&~CONSTRAINT_FLAG_STORAGE_NOT_LOW)
- | (storageNotLow ? CONSTRAINT_FLAG_STORAGE_NOT_LOW : 0);
- return this;
- }
-
- /**
- * Add a new content: URI that will be monitored with a
- * {@link android.database.ContentObserver}, and will cause the job to execute if changed.
- * If you have any trigger content URIs associated with a job, it will not execute until
- * there has been a change report for one or more of them.
- *
- * <p>Note that trigger URIs can not be used in combination with
- * {@link #setPeriodic(long)} or {@link #setPersisted(boolean)}. To continually monitor
- * for content changes, you need to schedule a new JobInfo observing the same URIs
- * before you finish execution of the JobService handling the most recent changes.
- * Following this pattern will ensure you do not lost any content changes: while your
- * job is running, the system will continue monitoring for content changes, and propagate
- * any it sees over to the next job you schedule.</p>
- *
- * <p>Because setting this property is not compatible with periodic or
- * persisted jobs, doing so will throw an {@link java.lang.IllegalArgumentException} when
- * {@link android.app.job.JobInfo.Builder#build()} is called.</p>
- *
- * <p>The following example shows how this feature can be used to monitor for changes
- * in the photos on a device.</p>
- *
- * {@sample development/samples/ApiDemos/src/com/example/android/apis/content/PhotosContentJob.java
- * job}
- *
- * @param uri The content: URI to monitor.
- * @see JobInfo#getTriggerContentUris()
- */
- public Builder addTriggerContentUri(@NonNull TriggerContentUri uri) {
- if (mTriggerContentUris == null) {
- mTriggerContentUris = new ArrayList<>();
- }
- mTriggerContentUris.add(uri);
- return this;
- }
-
- /**
- * Set the delay (in milliseconds) from when a content change is detected until
- * the job is scheduled. If there are more changes during that time, the delay
- * will be reset to start at the time of the most recent change.
- * @param durationMs Delay after most recent content change, in milliseconds.
- * @see JobInfo#getTriggerContentUpdateDelay()
- */
- public Builder setTriggerContentUpdateDelay(long durationMs) {
- mTriggerContentUpdateDelay = durationMs;
- return this;
- }
-
- /**
- * Set the maximum total delay (in milliseconds) that is allowed from the first
- * time a content change is detected until the job is scheduled.
- * @param durationMs Delay after initial content change, in milliseconds.
- * @see JobInfo#getTriggerContentMaxDelay()
- */
- public Builder setTriggerContentMaxDelay(long durationMs) {
- mTriggerContentMaxDelay = durationMs;
- return this;
- }
-
- /**
- * Specify that this job should recur with the provided interval, not more than once per
- * period. You have no control over when within this interval this job will be executed,
- * only the guarantee that it will be executed at most once within this interval.
- * Setting this function on the builder with {@link #setMinimumLatency(long)} or
- * {@link #setOverrideDeadline(long)} will result in an error.
- * @param intervalMillis Millisecond interval for which this job will repeat.
- * @see JobInfo#getIntervalMillis()
- * @see JobInfo#getFlexMillis()
- */
- public Builder setPeriodic(long intervalMillis) {
- return setPeriodic(intervalMillis, intervalMillis);
- }
-
- /**
- * Specify that this job should recur with the provided interval and flex. The job can
- * execute at any time in a window of flex length at the end of the period.
- * @param intervalMillis Millisecond interval for which this job will repeat. A minimum
- * value of {@link #getMinPeriodMillis()} is enforced.
- * @param flexMillis Millisecond flex for this job. Flex is clamped to be at least
- * {@link #getMinFlexMillis()} or 5 percent of the period, whichever is
- * higher.
- * @see JobInfo#getIntervalMillis()
- * @see JobInfo#getFlexMillis()
- */
- public Builder setPeriodic(long intervalMillis, long flexMillis) {
- final long minPeriod = getMinPeriodMillis();
- if (intervalMillis < minPeriod) {
- Log.w(TAG, "Requested interval " + formatDuration(intervalMillis) + " for job "
- + mJobId + " is too small; raising to " + formatDuration(minPeriod));
- intervalMillis = minPeriod;
- }
-
- final long percentClamp = 5 * intervalMillis / 100;
- final long minFlex = Math.max(percentClamp, getMinFlexMillis());
- if (flexMillis < minFlex) {
- Log.w(TAG, "Requested flex " + formatDuration(flexMillis) + " for job " + mJobId
- + " is too small; raising to " + formatDuration(minFlex));
- flexMillis = minFlex;
- }
-
- mIsPeriodic = true;
- mIntervalMillis = intervalMillis;
- mFlexMillis = flexMillis;
- mHasEarlyConstraint = mHasLateConstraint = true;
- return this;
- }
-
- /**
- * Specify that this job should be delayed by the provided amount of time.
- * Because it doesn't make sense setting this property on a periodic job, doing so will
- * throw an {@link java.lang.IllegalArgumentException} when
- * {@link android.app.job.JobInfo.Builder#build()} is called.
- * @param minLatencyMillis Milliseconds before which this job will not be considered for
- * execution.
- * @see JobInfo#getMinLatencyMillis()
- */
- public Builder setMinimumLatency(long minLatencyMillis) {
- mMinLatencyMillis = minLatencyMillis;
- mHasEarlyConstraint = true;
- return this;
- }
-
- /**
- * Set deadline which is the maximum scheduling latency. The job will be run by this
- * deadline even if other requirements are not met. Because it doesn't make sense setting
- * this property on a periodic job, doing so will throw an
- * {@link java.lang.IllegalArgumentException} when
- * {@link android.app.job.JobInfo.Builder#build()} is called.
- * @see JobInfo#getMaxExecutionDelayMillis()
- */
- public Builder setOverrideDeadline(long maxExecutionDelayMillis) {
- mMaxExecutionDelayMillis = maxExecutionDelayMillis;
- mHasLateConstraint = true;
- return this;
- }
-
- /**
- * Set up the back-off/retry policy.
- * This defaults to some respectable values: {30 seconds, Exponential}. We cap back-off at
- * 5hrs.
- * Note that trying to set a backoff criteria for a job with
- * {@link #setRequiresDeviceIdle(boolean)} will throw an exception when you call build().
- * This is because back-off typically does not make sense for these types of jobs. See
- * {@link android.app.job.JobService#jobFinished(android.app.job.JobParameters, boolean)}
- * for more description of the return value for the case of a job executing while in idle
- * mode.
- * @param initialBackoffMillis Millisecond time interval to wait initially when job has
- * failed.
- * @see JobInfo#getInitialBackoffMillis()
- * @see JobInfo#getBackoffPolicy()
- */
- public Builder setBackoffCriteria(long initialBackoffMillis,
- @BackoffPolicy int backoffPolicy) {
- final long minBackoff = getMinBackoffMillis();
- if (initialBackoffMillis < minBackoff) {
- Log.w(TAG, "Requested backoff " + formatDuration(initialBackoffMillis) + " for job "
- + mJobId + " is too small; raising to " + formatDuration(minBackoff));
- initialBackoffMillis = minBackoff;
- }
-
- mBackoffPolicySet = true;
- mInitialBackoffMillis = initialBackoffMillis;
- mBackoffPolicy = backoffPolicy;
- return this;
- }
-
- /**
- * Setting this to true indicates that this job is important while the scheduling app
- * is in the foreground or on the temporary whitelist for background restrictions.
- * This means that the system will relax doze restrictions on this job during this time.
- *
- * Apps should use this flag only for short jobs that are essential for the app to function
- * properly in the foreground.
- *
- * Note that once the scheduling app is no longer whitelisted from background restrictions
- * and in the background, or the job failed due to unsatisfied constraints,
- * this job should be expected to behave like other jobs without this flag.
- *
- * @param importantWhileForeground whether to relax doze restrictions for this job when the
- * app is in the foreground. False by default.
- * @see JobInfo#isImportantWhileForeground()
- */
- public Builder setImportantWhileForeground(boolean importantWhileForeground) {
- if (importantWhileForeground) {
- mFlags |= FLAG_IMPORTANT_WHILE_FOREGROUND;
- } else {
- mFlags &= (~FLAG_IMPORTANT_WHILE_FOREGROUND);
- }
- return this;
- }
-
- /**
- * Setting this to true indicates that this job is designed to prefetch
- * content that will make a material improvement to the experience of
- * the specific user of this device. For example, fetching top headlines
- * of interest to the current user.
- * <p>
- * The system may use this signal to relax the network constraints you
- * originally requested, such as allowing a
- * {@link JobInfo#NETWORK_TYPE_UNMETERED} job to run over a metered
- * network when there is a surplus of metered data available. The system
- * may also use this signal in combination with end user usage patterns
- * to ensure data is prefetched before the user launches your app.
- * @see JobInfo#isPrefetch()
- */
- public Builder setPrefetch(boolean prefetch) {
- if (prefetch) {
- mFlags |= FLAG_PREFETCH;
- } else {
- mFlags &= (~FLAG_PREFETCH);
- }
- return this;
- }
-
- /**
- * Set whether or not to persist this job across device reboots.
- *
- * @param isPersisted True to indicate that the job will be written to
- * disk and loaded at boot.
- * @see JobInfo#isPersisted()
- */
- @RequiresPermission(android.Manifest.permission.RECEIVE_BOOT_COMPLETED)
- public Builder setPersisted(boolean isPersisted) {
- mIsPersisted = isPersisted;
- return this;
- }
-
- /**
- * @return The job object to hand to the JobScheduler. This object is immutable.
- */
- public JobInfo build() {
- // Check that network estimates require network type
- if ((mNetworkDownloadBytes > 0 || mNetworkUploadBytes > 0) && mNetworkRequest == null) {
- throw new IllegalArgumentException(
- "Can't provide estimated network usage without requiring a network");
- }
- // We can't serialize network specifiers
- if (mIsPersisted && mNetworkRequest != null
- && mNetworkRequest.networkCapabilities.getNetworkSpecifier() != null) {
- throw new IllegalArgumentException(
- "Network specifiers aren't supported for persistent jobs");
- }
- // Check that a deadline was not set on a periodic job.
- if (mIsPeriodic) {
- if (mMaxExecutionDelayMillis != 0L) {
- throw new IllegalArgumentException("Can't call setOverrideDeadline() on a " +
- "periodic job.");
- }
- if (mMinLatencyMillis != 0L) {
- throw new IllegalArgumentException("Can't call setMinimumLatency() on a " +
- "periodic job");
- }
- if (mTriggerContentUris != null) {
- throw new IllegalArgumentException("Can't call addTriggerContentUri() on a " +
- "periodic job");
- }
- }
- if (mIsPersisted) {
- if (mTriggerContentUris != null) {
- throw new IllegalArgumentException("Can't call addTriggerContentUri() on a " +
- "persisted job");
- }
- if (!mTransientExtras.isEmpty()) {
- throw new IllegalArgumentException("Can't call setTransientExtras() on a " +
- "persisted job");
- }
- if (mClipData != null) {
- throw new IllegalArgumentException("Can't call setClipData() on a " +
- "persisted job");
- }
- }
- if ((mFlags & FLAG_IMPORTANT_WHILE_FOREGROUND) != 0 && mHasEarlyConstraint) {
- throw new IllegalArgumentException("An important while foreground job cannot "
- + "have a time delay");
- }
- if (mBackoffPolicySet && (mConstraintFlags & CONSTRAINT_FLAG_DEVICE_IDLE) != 0) {
- throw new IllegalArgumentException("An idle mode job will not respect any" +
- " back-off policy, so calling setBackoffCriteria with" +
- " setRequiresDeviceIdle is an error.");
- }
- return new JobInfo(this);
- }
-
- /**
- * @hide
- */
- public String summarize() {
- final String service = (mJobService != null)
- ? mJobService.flattenToShortString()
- : "null";
- return "JobInfo.Builder{job:" + mJobId + "/" + service + "}";
- }
- }
-
- /**
- * Convert a priority integer into a human readable string for debugging.
- * @hide
- */
- public static String getPriorityString(int priority) {
- switch (priority) {
- case PRIORITY_DEFAULT:
- return PRIORITY_DEFAULT + " [DEFAULT]";
- case PRIORITY_SYNC_EXPEDITED:
- return PRIORITY_SYNC_EXPEDITED + " [SYNC_EXPEDITED]";
- case PRIORITY_SYNC_INITIALIZATION:
- return PRIORITY_SYNC_INITIALIZATION + " [SYNC_INITIALIZATION]";
- case PRIORITY_BOUND_FOREGROUND_SERVICE:
- return PRIORITY_BOUND_FOREGROUND_SERVICE + " [BFGS_APP]";
- case PRIORITY_FOREGROUND_SERVICE:
- return PRIORITY_FOREGROUND_SERVICE + " [FGS_APP]";
- case PRIORITY_TOP_APP:
- return PRIORITY_TOP_APP + " [TOP_APP]";
-
- // PRIORITY_ADJ_* are adjustments and not used as real priorities.
- // No need to convert to strings.
- }
- return priority + " [UNKNOWN]";
- }
-}
diff --git a/core/java/android/app/job/JobParameters.aidl b/core/java/android/app/job/JobParameters.aidl
deleted file mode 100644
index e7551b9ab9f2..000000000000
--- a/core/java/android/app/job/JobParameters.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/**
- * Copyright 2014, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.app.job;
-
-parcelable JobParameters;
diff --git a/core/java/android/app/job/JobParameters.java b/core/java/android/app/job/JobParameters.java
deleted file mode 100644
index ecc859d8320c..000000000000
--- a/core/java/android/app/job/JobParameters.java
+++ /dev/null
@@ -1,372 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package android.app.job;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.UnsupportedAppUsage;
-import android.app.job.IJobCallback;
-import android.content.ClipData;
-import android.net.Network;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.IBinder;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.os.PersistableBundle;
-import android.os.RemoteException;
-
-/**
- * Contains the parameters used to configure/identify your job. You do not create this object
- * yourself, instead it is handed in to your application by the System.
- */
-public class JobParameters implements Parcelable {
-
- /** @hide */
- public static final int REASON_CANCELED = JobProtoEnums.STOP_REASON_CANCELLED; // 0.
- /** @hide */
- public static final int REASON_CONSTRAINTS_NOT_SATISFIED =
- JobProtoEnums.STOP_REASON_CONSTRAINTS_NOT_SATISFIED; //1.
- /** @hide */
- public static final int REASON_PREEMPT = JobProtoEnums.STOP_REASON_PREEMPT; // 2.
- /** @hide */
- public static final int REASON_TIMEOUT = JobProtoEnums.STOP_REASON_TIMEOUT; // 3.
- /** @hide */
- public static final int REASON_DEVICE_IDLE = JobProtoEnums.STOP_REASON_DEVICE_IDLE; // 4.
- /** @hide */
- public static final int REASON_DEVICE_THERMAL = JobProtoEnums.STOP_REASON_DEVICE_THERMAL; // 5.
-
- /**
- * All the stop reason codes. This should be regarded as an immutable array at runtime.
- * @hide
- */
- public static final int[] JOB_STOP_REASON_CODES = {
- REASON_CANCELED,
- REASON_CONSTRAINTS_NOT_SATISFIED,
- REASON_PREEMPT,
- REASON_TIMEOUT,
- REASON_DEVICE_IDLE,
- REASON_DEVICE_THERMAL,
- };
-
- /** @hide */
- public static String getReasonName(int reason) {
- switch (reason) {
- case REASON_CANCELED: return "canceled";
- case REASON_CONSTRAINTS_NOT_SATISFIED: return "constraints";
- case REASON_PREEMPT: return "preempt";
- case REASON_TIMEOUT: return "timeout";
- case REASON_DEVICE_IDLE: return "device_idle";
- case REASON_DEVICE_THERMAL: return "thermal";
- default: return "unknown:" + reason;
- }
- }
-
- @UnsupportedAppUsage
- private final int jobId;
- private final PersistableBundle extras;
- private final Bundle transientExtras;
- private final ClipData clipData;
- private final int clipGrantFlags;
- @UnsupportedAppUsage
- private final IBinder callback;
- private final boolean overrideDeadlineExpired;
- private final Uri[] mTriggeredContentUris;
- private final String[] mTriggeredContentAuthorities;
- private final Network network;
-
- private int stopReason; // Default value of stopReason is REASON_CANCELED
- private String debugStopReason; // Human readable stop reason for debugging.
-
- /** @hide */
- public JobParameters(IBinder callback, int jobId, PersistableBundle extras,
- Bundle transientExtras, ClipData clipData, int clipGrantFlags,
- boolean overrideDeadlineExpired, Uri[] triggeredContentUris,
- String[] triggeredContentAuthorities, Network network) {
- this.jobId = jobId;
- this.extras = extras;
- this.transientExtras = transientExtras;
- this.clipData = clipData;
- this.clipGrantFlags = clipGrantFlags;
- this.callback = callback;
- this.overrideDeadlineExpired = overrideDeadlineExpired;
- this.mTriggeredContentUris = triggeredContentUris;
- this.mTriggeredContentAuthorities = triggeredContentAuthorities;
- this.network = network;
- }
-
- /**
- * @return The unique id of this job, specified at creation time.
- */
- public int getJobId() {
- return jobId;
- }
-
- /**
- * Reason onStopJob() was called on this job.
- * @hide
- */
- public int getStopReason() {
- return stopReason;
- }
-
- /**
- * Reason onStopJob() was called on this job.
- * @hide
- */
- public String getDebugStopReason() {
- return debugStopReason;
- }
-
- /**
- * @return The extras you passed in when constructing this job with
- * {@link android.app.job.JobInfo.Builder#setExtras(android.os.PersistableBundle)}. This will
- * never be null. If you did not set any extras this will be an empty bundle.
- */
- public @NonNull PersistableBundle getExtras() {
- return extras;
- }
-
- /**
- * @return The transient extras you passed in when constructing this job with
- * {@link android.app.job.JobInfo.Builder#setTransientExtras(android.os.Bundle)}. This will
- * never be null. If you did not set any extras this will be an empty bundle.
- */
- public @NonNull Bundle getTransientExtras() {
- return transientExtras;
- }
-
- /**
- * @return The clip you passed in when constructing this job with
- * {@link android.app.job.JobInfo.Builder#setClipData(ClipData, int)}. Will be null
- * if it was not set.
- */
- public @Nullable ClipData getClipData() {
- return clipData;
- }
-
- /**
- * @return The clip grant flags you passed in when constructing this job with
- * {@link android.app.job.JobInfo.Builder#setClipData(ClipData, int)}. Will be 0
- * if it was not set.
- */
- public int getClipGrantFlags() {
- return clipGrantFlags;
- }
-
- /**
- * For jobs with {@link android.app.job.JobInfo.Builder#setOverrideDeadline(long)} set, this
- * provides an easy way to tell whether the job is being executed due to the deadline
- * expiring. Note: If the job is running because its deadline expired, it implies that its
- * constraints will not be met.
- */
- public boolean isOverrideDeadlineExpired() {
- return overrideDeadlineExpired;
- }
-
- /**
- * For jobs with {@link android.app.job.JobInfo.Builder#addTriggerContentUri} set, this
- * reports which URIs have triggered the job. This will be null if either no URIs have
- * triggered it (it went off due to a deadline or other reason), or the number of changed
- * URIs is too large to report. Whether or not the number of URIs is too large, you can
- * always use {@link #getTriggeredContentAuthorities()} to determine whether the job was
- * triggered due to any content changes and the authorities they are associated with.
- */
- public @Nullable Uri[] getTriggeredContentUris() {
- return mTriggeredContentUris;
- }
-
- /**
- * For jobs with {@link android.app.job.JobInfo.Builder#addTriggerContentUri} set, this
- * reports which content authorities have triggered the job. It will only be null if no
- * authorities have triggered it -- that is, the job executed for some other reason, such
- * as a deadline expiring. If this is non-null, you can use {@link #getTriggeredContentUris()}
- * to retrieve the details of which URIs changed (as long as that has not exceeded the maximum
- * number it can reported).
- */
- public @Nullable String[] getTriggeredContentAuthorities() {
- return mTriggeredContentAuthorities;
- }
-
- /**
- * Return the network that should be used to perform any network requests
- * for this job.
- * <p>
- * Devices may have multiple active network connections simultaneously, or
- * they may not have a default network route at all. To correctly handle all
- * situations like this, your job should always use the network returned by
- * this method instead of implicitly using the default network route.
- * <p>
- * Note that the system may relax the constraints you originally requested,
- * such as allowing a {@link JobInfo#NETWORK_TYPE_UNMETERED} job to run over
- * a metered network when there is a surplus of metered data available.
- *
- * @return the network that should be used to perform any network requests
- * for this job, or {@code null} if this job didn't set any required
- * network type.
- * @see JobInfo.Builder#setRequiredNetworkType(int)
- */
- public @Nullable Network getNetwork() {
- return network;
- }
-
- /**
- * Dequeue the next pending {@link JobWorkItem} from these JobParameters associated with their
- * currently running job. Calling this method when there is no more work available and all
- * previously dequeued work has been completed will result in the system taking care of
- * stopping the job for you --
- * you should not call {@link JobService#jobFinished(JobParameters, boolean)} yourself
- * (otherwise you risk losing an upcoming JobWorkItem that is being enqueued at the same time).
- *
- * <p>Once you are done with the {@link JobWorkItem} returned by this method, you must call
- * {@link #completeWork(JobWorkItem)} with it to inform the system that you are done
- * executing the work. The job will not be finished until all dequeued work has been
- * completed. You do not, however, have to complete each returned work item before deqeueing
- * the next one -- you can use {@link #dequeueWork()} multiple times before completing
- * previous work if you want to process work in parallel, and you can complete the work
- * in whatever order you want.</p>
- *
- * <p>If the job runs to the end of its available time period before all work has been
- * completed, it will stop as normal. You should return true from
- * {@link JobService#onStopJob(JobParameters)} in order to have the job rescheduled, and by
- * doing so any pending as well as remaining uncompleted work will be re-queued
- * for the next time the job runs.</p>
- *
- * <p>This example shows how to construct a JobService that will serially dequeue and
- * process work that is available for it:</p>
- *
- * {@sample development/samples/ApiDemos/src/com/example/android/apis/app/JobWorkService.java
- * service}
- *
- * @return Returns a new {@link JobWorkItem} if there is one pending, otherwise null.
- * If null is returned, the system will also stop the job if all work has also been completed.
- * (This means that for correct operation, you must always call dequeueWork() after you have
- * completed other work, to check either for more work or allow the system to stop the job.)
- */
- public @Nullable JobWorkItem dequeueWork() {
- try {
- return getCallback().dequeueWork(getJobId());
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Report the completion of executing a {@link JobWorkItem} previously returned by
- * {@link #dequeueWork()}. This tells the system you are done with the
- * work associated with that item, so it will not be returned again. Note that if this
- * is the last work in the queue, completing it here will <em>not</em> finish the overall
- * job -- for that to happen, you still need to call {@link #dequeueWork()}
- * again.
- *
- * <p>If you are enqueueing work into a job, you must call this method for each piece
- * of work you process. Do <em>not</em> call
- * {@link JobService#jobFinished(JobParameters, boolean)}
- * or else you can lose work in your queue.</p>
- *
- * @param work The work you have completed processing, as previously returned by
- * {@link #dequeueWork()}
- */
- public void completeWork(@NonNull JobWorkItem work) {
- try {
- if (!getCallback().completeWork(getJobId(), work.getWorkId())) {
- throw new IllegalArgumentException("Given work is not active: " + work);
- }
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /** @hide */
- @UnsupportedAppUsage
- public IJobCallback getCallback() {
- return IJobCallback.Stub.asInterface(callback);
- }
-
- private JobParameters(Parcel in) {
- jobId = in.readInt();
- extras = in.readPersistableBundle();
- transientExtras = in.readBundle();
- if (in.readInt() != 0) {
- clipData = ClipData.CREATOR.createFromParcel(in);
- clipGrantFlags = in.readInt();
- } else {
- clipData = null;
- clipGrantFlags = 0;
- }
- callback = in.readStrongBinder();
- overrideDeadlineExpired = in.readInt() == 1;
- mTriggeredContentUris = in.createTypedArray(Uri.CREATOR);
- mTriggeredContentAuthorities = in.createStringArray();
- if (in.readInt() != 0) {
- network = Network.CREATOR.createFromParcel(in);
- } else {
- network = null;
- }
- stopReason = in.readInt();
- debugStopReason = in.readString();
- }
-
- /** @hide */
- public void setStopReason(int reason, String debugStopReason) {
- stopReason = reason;
- this.debugStopReason = debugStopReason;
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(jobId);
- dest.writePersistableBundle(extras);
- dest.writeBundle(transientExtras);
- if (clipData != null) {
- dest.writeInt(1);
- clipData.writeToParcel(dest, flags);
- dest.writeInt(clipGrantFlags);
- } else {
- dest.writeInt(0);
- }
- dest.writeStrongBinder(callback);
- dest.writeInt(overrideDeadlineExpired ? 1 : 0);
- dest.writeTypedArray(mTriggeredContentUris, flags);
- dest.writeStringArray(mTriggeredContentAuthorities);
- if (network != null) {
- dest.writeInt(1);
- network.writeToParcel(dest, flags);
- } else {
- dest.writeInt(0);
- }
- dest.writeInt(stopReason);
- dest.writeString(debugStopReason);
- }
-
- public static final @android.annotation.NonNull Creator<JobParameters> CREATOR = new Creator<JobParameters>() {
- @Override
- public JobParameters createFromParcel(Parcel in) {
- return new JobParameters(in);
- }
-
- @Override
- public JobParameters[] newArray(int size) {
- return new JobParameters[size];
- }
- };
-}
diff --git a/core/java/android/app/job/JobScheduler.java b/core/java/android/app/job/JobScheduler.java
deleted file mode 100644
index 08b1c2b9f548..000000000000
--- a/core/java/android/app/job/JobScheduler.java
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package android.app.job;
-
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.RequiresPermission;
-import android.annotation.SystemApi;
-import android.annotation.SystemService;
-import android.content.ClipData;
-import android.content.Context;
-import android.os.Bundle;
-import android.os.PersistableBundle;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.List;
-
-/**
- * This is an API for scheduling various types of jobs against the framework that will be executed
- * in your application's own process.
- * <p>
- * See {@link android.app.job.JobInfo} for more description of the types of jobs that can be run
- * and how to construct them. You will construct these JobInfo objects and pass them to the
- * JobScheduler with {@link #schedule(JobInfo)}. When the criteria declared are met, the
- * system will execute this job on your application's {@link android.app.job.JobService}.
- * You identify the service component that implements the logic for your job when you
- * construct the JobInfo using
- * {@link android.app.job.JobInfo.Builder#JobInfo.Builder(int,android.content.ComponentName)}.
- * </p>
- * <p>
- * The framework will be intelligent about when it executes jobs, and attempt to batch
- * and defer them as much as possible. Typically if you don't specify a deadline on a job, it
- * can be run at any moment depending on the current state of the JobScheduler's internal queue.
- * <p>
- * While a job is running, the system holds a wakelock on behalf of your app. For this reason,
- * you do not need to take any action to guarantee that the device stays awake for the
- * duration of the job.
- * </p>
- * <p>You do not
- * instantiate this class directly; instead, retrieve it through
- * {@link android.content.Context#getSystemService
- * Context.getSystemService(Context.JOB_SCHEDULER_SERVICE)}.
- */
-@SystemService(Context.JOB_SCHEDULER_SERVICE)
-public abstract class JobScheduler {
- /** @hide */
- @IntDef(prefix = { "RESULT_" }, value = {
- RESULT_FAILURE,
- RESULT_SUCCESS,
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface Result {}
-
- /**
- * Returned from {@link #schedule(JobInfo)} when an invalid parameter was supplied. This can occur
- * if the run-time for your job is too short, or perhaps the system can't resolve the
- * requisite {@link JobService} in your package.
- */
- public static final int RESULT_FAILURE = 0;
- /**
- * Returned from {@link #schedule(JobInfo)} if this job has been successfully scheduled.
- */
- public static final int RESULT_SUCCESS = 1;
-
- /**
- * 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
- * running, it will be stopped.
- *
- * @param job The job you wish scheduled. See
- * {@link android.app.job.JobInfo.Builder JobInfo.Builder} for more detail on the sorts of jobs
- * you can schedule.
- * @return the result of the schedule request.
- */
- public abstract @Result int schedule(@NonNull JobInfo job);
-
- /**
- * Similar to {@link #schedule}, but allows you to enqueue work for a new <em>or existing</em>
- * job. If a job with the same ID is already scheduled, it will be replaced with the
- * new {@link JobInfo}, but any previously enqueued work will remain and be dispatched the
- * next time it runs. If a job with the same ID is already running, the new work will be
- * enqueued for it.
- *
- * <p>The work you enqueue is later retrieved through
- * {@link JobParameters#dequeueWork() JobParameters.dequeueWork}. Be sure to see there
- * about how to process work; the act of enqueueing work changes how you should handle the
- * overall lifecycle of an executing job.</p>
- *
- * <p>It is strongly encouraged that you use the same {@link JobInfo} for all work you
- * enqueue. This will allow the system to optimally schedule work along with any pending
- * and/or currently running work. If the JobInfo changes from the last time the job was
- * enqueued, the system will need to update the associated JobInfo, which can cause a disruption
- * in execution. In particular, this can result in any currently running job that is processing
- * previous work to be stopped and restarted with the new JobInfo.</p>
- *
- * <p>It is recommended that you avoid using
- * {@link JobInfo.Builder#setExtras(PersistableBundle)} or
- * {@link JobInfo.Builder#setTransientExtras(Bundle)} with a JobInfo you are using to
- * enqueue work. The system will try to compare these extras with the previous JobInfo,
- * but there are situations where it may get this wrong and count the JobInfo as changing.
- * (That said, you should be relatively safe with a simple set of consistent data in these
- * fields.) You should never use {@link JobInfo.Builder#setClipData(ClipData, int)} with
- * work you are enqueue, since currently this will always be treated as a different JobInfo,
- * even if the ClipData contents are exactly the same.</p>
- *
- * @param job The job you wish to enqueue work for. See
- * {@link android.app.job.JobInfo.Builder JobInfo.Builder} for more detail on the sorts of jobs
- * you can schedule.
- * @param work New work to enqueue. This will be available later when the job starts running.
- * @return the result of the enqueue request.
- */
- public abstract @Result int enqueue(@NonNull JobInfo job, @NonNull JobWorkItem work);
-
- /**
- *
- * @param job The job to be scheduled.
- * @param packageName The package on behalf of which the job is to be scheduled. This will be
- * used to track battery usage and appIdleState.
- * @param userId User on behalf of whom this job is to be scheduled.
- * @param tag Debugging tag for dumps associated with this job (instead of the service class)
- * @hide
- */
- @SystemApi
- @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS)
- public abstract @Result int scheduleAsPackage(@NonNull JobInfo job, @NonNull String packageName,
- int userId, String tag);
-
- /**
- * Cancel the specified job. If the job is currently executing, it is stopped
- * immediately and the return value from its {@link JobService#onStopJob(JobParameters)}
- * method is ignored.
- *
- * @param jobId unique identifier for the job to be canceled, as supplied to
- * {@link JobInfo.Builder#JobInfo.Builder(int, android.content.ComponentName)
- * JobInfo.Builder(int, android.content.ComponentName)}.
- */
- public abstract void cancel(int jobId);
-
- /**
- * Cancel <em>all</em> jobs that have been scheduled by the calling application.
- */
- public abstract void cancelAll();
-
- /**
- * Retrieve all jobs that have been scheduled by the calling application.
- *
- * @return a list of all of the app's scheduled jobs. This includes jobs that are
- * currently started as well as those that are still waiting to run.
- */
- public abstract @NonNull List<JobInfo> getAllPendingJobs();
-
- /**
- * Look up the description of a scheduled job.
- *
- * @return The {@link JobInfo} description of the given scheduled job, or {@code null}
- * if the supplied job ID does not correspond to any job.
- */
- public abstract @Nullable JobInfo getPendingJob(int jobId);
-
- /**
- * <b>For internal system callers only!</b>
- * Returns a list of all currently-executing jobs.
- * @hide
- */
- public abstract List<JobInfo> getStartedJobs();
-
- /**
- * <b>For internal system callers only!</b>
- * Returns a snapshot of the state of all jobs known to the system.
- *
- * <p class="note">This is a slow operation, so it should be called sparingly.
- * @hide
- */
- public abstract List<JobSnapshot> getAllJobSnapshots();
-} \ No newline at end of file
diff --git a/core/java/android/app/job/JobSchedulerFrameworkInitializer.java b/core/java/android/app/job/JobSchedulerFrameworkInitializer.java
deleted file mode 100644
index c90b8728bf4a..000000000000
--- a/core/java/android/app/job/JobSchedulerFrameworkInitializer.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.app.job;
-
-import android.app.JobSchedulerImpl;
-import android.app.SystemServiceRegistry;
-import android.content.Context;
-import android.os.BatteryStats;
-
-/**
- * This class needs to be pre-loaded by zygote. This is where the job scheduler service wrapper
- * is registered.
- *
- * @hide
- */
-public class JobSchedulerFrameworkInitializer {
- static {
- SystemServiceRegistry.registerStaticService(
- Context.JOB_SCHEDULER_SERVICE, JobScheduler.class,
- (b) -> new JobSchedulerImpl(IJobScheduler.Stub.asInterface(b)));
-
- BatteryStats.setJobStopReasons(JobParameters.JOB_STOP_REASON_CODES,
- JobParameters::getReasonName);
- }
-}
diff --git a/core/java/android/app/job/JobService.java b/core/java/android/app/job/JobService.java
deleted file mode 100644
index 61afadab9b0c..000000000000
--- a/core/java/android/app/job/JobService.java
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package android.app.job;
-
-import android.app.Service;
-import android.content.Intent;
-import android.os.IBinder;
-
-/**
- * <p>Entry point for the callback from the {@link android.app.job.JobScheduler}.</p>
- * <p>This is the base class that handles asynchronous requests that were previously scheduled. You
- * are responsible for overriding {@link JobService#onStartJob(JobParameters)}, which is where
- * you will implement your job logic.</p>
- * <p>This service executes each incoming job on a {@link android.os.Handler} running on your
- * application's main thread. This means that you <b>must</b> offload your execution logic to
- * another thread/handler/{@link android.os.AsyncTask} of your choosing. Not doing so will result
- * in blocking any future callbacks from the JobManager - specifically
- * {@link #onStopJob(android.app.job.JobParameters)}, which is meant to inform you that the
- * scheduling requirements are no longer being met.</p>
- */
-public abstract class JobService extends Service {
- private static final String TAG = "JobService";
-
- /**
- * Job services must be protected with this permission:
- *
- * <pre class="prettyprint">
- * &#60;service android:name="MyJobService"
- * android:permission="android.permission.BIND_JOB_SERVICE" &#62;
- * ...
- * &#60;/service&#62;
- * </pre>
- *
- * <p>If a job service is declared in the manifest but not protected with this
- * permission, that service will be ignored by the system.
- */
- public static final String PERMISSION_BIND =
- "android.permission.BIND_JOB_SERVICE";
-
- private JobServiceEngine mEngine;
-
- /** @hide */
- public final IBinder onBind(Intent intent) {
- if (mEngine == null) {
- mEngine = new JobServiceEngine(this) {
- @Override
- public boolean onStartJob(JobParameters params) {
- return JobService.this.onStartJob(params);
- }
-
- @Override
- public boolean onStopJob(JobParameters params) {
- return JobService.this.onStopJob(params);
- }
- };
- }
- return mEngine.getBinder();
- }
-
- /**
- * Call this to inform the JobScheduler that the job has finished its work. When the
- * system receives this message, it releases the wakelock being held for the job.
- * <p>
- * You can request that the job be scheduled again by passing {@code true} as
- * the <code>wantsReschedule</code> parameter. This will apply back-off policy
- * for the job; this policy can be adjusted through the
- * {@link android.app.job.JobInfo.Builder#setBackoffCriteria(long, int)} method
- * when the job is originally scheduled. The job's initial
- * requirements are preserved when jobs are rescheduled, regardless of backed-off
- * policy.
- * <p class="note">
- * A job running while the device is dozing will not be rescheduled with the normal back-off
- * policy. Instead, the job will be re-added to the queue and executed again during
- * a future idle maintenance window.
- * </p>
- *
- * @param params The parameters identifying this job, as supplied to
- * the job in the {@link #onStartJob(JobParameters)} callback.
- * @param wantsReschedule {@code true} if this job should be rescheduled according
- * to the back-off criteria specified when it was first scheduled; {@code false}
- * otherwise.
- */
- public final void jobFinished(JobParameters params, boolean wantsReschedule) {
- mEngine.jobFinished(params, wantsReschedule);
- }
-
- /**
- * Called to indicate that the job has begun executing. Override this method with the
- * logic for your job. Like all other component lifecycle callbacks, this method executes
- * on your application's main thread.
- * <p>
- * Return {@code true} from this method if your job needs to continue running. If you
- * do this, the job remains active until you call
- * {@link #jobFinished(JobParameters, boolean)} to tell the system that it has completed
- * its work, or until the job's required constraints are no longer satisfied. For
- * example, if the job was scheduled using
- * {@link JobInfo.Builder#setRequiresCharging(boolean) setRequiresCharging(true)},
- * it will be immediately halted by the system if the user unplugs the device from power,
- * the job's {@link #onStopJob(JobParameters)} callback will be invoked, and the app
- * will be expected to shut down all ongoing work connected with that job.
- * <p>
- * The system holds a wakelock on behalf of your app as long as your job is executing.
- * This wakelock is acquired before this method is invoked, and is not released until either
- * you call {@link #jobFinished(JobParameters, boolean)}, or after the system invokes
- * {@link #onStopJob(JobParameters)} to notify your job that it is being shut down
- * prematurely.
- * <p>
- * Returning {@code false} from this method means your job is already finished. The
- * system's wakelock for the job will be released, and {@link #onStopJob(JobParameters)}
- * will not be invoked.
- *
- * @param params Parameters specifying info about this job, including the optional
- * extras configured with {@link JobInfo.Builder#setExtras(android.os.PersistableBundle).
- * This object serves to identify this specific running job instance when calling
- * {@link #jobFinished(JobParameters, boolean)}.
- * @return {@code true} if your service will continue running, using a separate thread
- * when appropriate. {@code false} means that this job has completed its work.
- */
- public abstract boolean onStartJob(JobParameters params);
-
- /**
- * This method is called if the system has determined that you must stop execution of your job
- * even before you've had a chance to call {@link #jobFinished(JobParameters, boolean)}.
- *
- * <p>This will happen if the requirements specified at schedule time are no longer met. For
- * example you may have requested WiFi with
- * {@link android.app.job.JobInfo.Builder#setRequiredNetworkType(int)}, yet while your
- * job was executing the user toggled WiFi. Another example is if you had specified
- * {@link android.app.job.JobInfo.Builder#setRequiresDeviceIdle(boolean)}, and the phone left its
- * idle maintenance window. You are solely responsible for the behavior of your application
- * upon receipt of this message; your app will likely start to misbehave if you ignore it.
- * <p>
- * Once this method returns, the system releases the wakelock that it is holding on
- * behalf of the job.</p>
- *
- * @param params The parameters identifying this job, as supplied to
- * the job in the {@link #onStartJob(JobParameters)} callback.
- * @return {@code true} to indicate to the JobManager whether you'd like to reschedule
- * this job based on the retry criteria provided at job creation-time; or {@code false}
- * to end the job entirely. Regardless of the value returned, your job must stop executing.
- */
- public abstract boolean onStopJob(JobParameters params);
-}
diff --git a/core/java/android/app/job/JobServiceEngine.java b/core/java/android/app/job/JobServiceEngine.java
deleted file mode 100644
index ab94da843635..000000000000
--- a/core/java/android/app/job/JobServiceEngine.java
+++ /dev/null
@@ -1,220 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package android.app.job;
-
-import android.app.Service;
-import android.content.Context;
-import android.content.Intent;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Looper;
-import android.os.Message;
-import android.os.RemoteException;
-import android.util.Log;
-
-import com.android.internal.annotations.GuardedBy;
-
-import java.lang.ref.WeakReference;
-
-/**
- * Helper for implementing a {@link android.app.Service} that interacts with
- * {@link JobScheduler}. This is not intended for use by regular applications, but
- * allows frameworks built on top of the platform to create their own
- * {@link android.app.Service} that interact with {@link JobScheduler} as well as
- * add in additional functionality. If you just want to execute jobs normally, you
- * should instead be looking at {@link JobService}.
- */
-public abstract class JobServiceEngine {
- private static final String TAG = "JobServiceEngine";
-
- /**
- * Identifier for a message that will result in a call to
- * {@link #onStartJob(android.app.job.JobParameters)}.
- */
- private static final int MSG_EXECUTE_JOB = 0;
- /**
- * Message that will result in a call to {@link #onStopJob(android.app.job.JobParameters)}.
- */
- private static final int MSG_STOP_JOB = 1;
- /**
- * Message that the client has completed execution of this job.
- */
- private static final int MSG_JOB_FINISHED = 2;
-
- private final IJobService mBinder;
-
- /**
- * Handler we post jobs to. Responsible for calling into the client logic, and handling the
- * callback to the system.
- */
- JobHandler mHandler;
-
- static final class JobInterface extends IJobService.Stub {
- final WeakReference<JobServiceEngine> mService;
-
- JobInterface(JobServiceEngine service) {
- mService = new WeakReference<>(service);
- }
-
- @Override
- public void startJob(JobParameters jobParams) throws RemoteException {
- JobServiceEngine service = mService.get();
- if (service != null) {
- Message m = Message.obtain(service.mHandler, MSG_EXECUTE_JOB, jobParams);
- m.sendToTarget();
- }
- }
-
- @Override
- public void stopJob(JobParameters jobParams) throws RemoteException {
- JobServiceEngine service = mService.get();
- if (service != null) {
- Message m = Message.obtain(service.mHandler, MSG_STOP_JOB, jobParams);
- m.sendToTarget();
- }
- }
- }
-
- /**
- * Runs on application's main thread - callbacks are meant to offboard work to some other
- * (app-specified) mechanism.
- * @hide
- */
- class JobHandler extends Handler {
- JobHandler(Looper looper) {
- super(looper);
- }
-
- @Override
- public void handleMessage(Message msg) {
- final JobParameters params = (JobParameters) msg.obj;
- switch (msg.what) {
- case MSG_EXECUTE_JOB:
- try {
- boolean workOngoing = JobServiceEngine.this.onStartJob(params);
- ackStartMessage(params, workOngoing);
- } catch (Exception e) {
- Log.e(TAG, "Error while executing job: " + params.getJobId());
- throw new RuntimeException(e);
- }
- break;
- case MSG_STOP_JOB:
- try {
- boolean ret = JobServiceEngine.this.onStopJob(params);
- ackStopMessage(params, ret);
- } catch (Exception e) {
- Log.e(TAG, "Application unable to handle onStopJob.", e);
- throw new RuntimeException(e);
- }
- break;
- case MSG_JOB_FINISHED:
- final boolean needsReschedule = (msg.arg2 == 1);
- IJobCallback callback = params.getCallback();
- if (callback != null) {
- try {
- callback.jobFinished(params.getJobId(), needsReschedule);
- } catch (RemoteException e) {
- Log.e(TAG, "Error reporting job finish to system: binder has gone" +
- "away.");
- }
- } else {
- Log.e(TAG, "finishJob() called for a nonexistent job id.");
- }
- break;
- default:
- Log.e(TAG, "Unrecognised message received.");
- break;
- }
- }
-
- private void ackStartMessage(JobParameters params, boolean workOngoing) {
- final IJobCallback callback = params.getCallback();
- final int jobId = params.getJobId();
- if (callback != null) {
- try {
- callback.acknowledgeStartMessage(jobId, workOngoing);
- } catch(RemoteException e) {
- Log.e(TAG, "System unreachable for starting job.");
- }
- } else {
- if (Log.isLoggable(TAG, Log.DEBUG)) {
- Log.d(TAG, "Attempting to ack a job that has already been processed.");
- }
- }
- }
-
- private void ackStopMessage(JobParameters params, boolean reschedule) {
- final IJobCallback callback = params.getCallback();
- final int jobId = params.getJobId();
- if (callback != null) {
- try {
- callback.acknowledgeStopMessage(jobId, reschedule);
- } catch(RemoteException e) {
- Log.e(TAG, "System unreachable for stopping job.");
- }
- } else {
- if (Log.isLoggable(TAG, Log.DEBUG)) {
- Log.d(TAG, "Attempting to ack a job that has already been processed.");
- }
- }
- }
- }
-
- /**
- * Create a new engine, ready for use.
- *
- * @param service The {@link Service} that is creating this engine and in which it will run.
- */
- public JobServiceEngine(Service service) {
- mBinder = new JobInterface(this);
- mHandler = new JobHandler(service.getMainLooper());
- }
-
- /**
- * Retrieve the engine's IPC interface that should be returned by
- * {@link Service#onBind(Intent)}.
- */
- public final IBinder getBinder() {
- return mBinder.asBinder();
- }
-
- /**
- * Engine's report that a job has started. See
- * {@link JobService#onStartJob(JobParameters) JobService.onStartJob} for more information.
- */
- public abstract boolean onStartJob(JobParameters params);
-
- /**
- * Engine's report that a job has stopped. See
- * {@link JobService#onStopJob(JobParameters) JobService.onStopJob} for more information.
- */
- public abstract boolean onStopJob(JobParameters params);
-
- /**
- * Call in to engine to report that a job has finished executing. See
- * {@link JobService#jobFinished(JobParameters, boolean)} JobService.jobFinished} for more
- * information.
- */
- public void jobFinished(JobParameters params, boolean needsReschedule) {
- if (params == null) {
- throw new NullPointerException("params");
- }
- Message m = Message.obtain(mHandler, MSG_JOB_FINISHED, params);
- m.arg2 = needsReschedule ? 1 : 0;
- m.sendToTarget();
- }
-} \ No newline at end of file
diff --git a/core/java/android/app/job/JobSnapshot.aidl b/core/java/android/app/job/JobSnapshot.aidl
deleted file mode 100644
index d40f4e39ea2e..000000000000
--- a/core/java/android/app/job/JobSnapshot.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/**
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.app.job;
-
-parcelable JobSnapshot;
diff --git a/core/java/android/app/job/JobSnapshot.java b/core/java/android/app/job/JobSnapshot.java
deleted file mode 100644
index 2c58908a6064..000000000000
--- a/core/java/android/app/job/JobSnapshot.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.app.job;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * Current-state snapshot of a scheduled job. These snapshots are not used in apps;
- * they exist only within the system process across the local call surface where JobStatus
- * is not directly accessible at build time.
- *
- * Constraints that the underlying job does not require are always reported as
- * being currently satisfied.
- * @hide
- */
-public class JobSnapshot implements Parcelable {
- private final JobInfo mJob;
- private final int mSatisfiedConstraints;
- private final boolean mIsRunnable;
-
- public JobSnapshot(JobInfo info, int satisfiedMask, boolean runnable) {
- mJob = info;
- mSatisfiedConstraints = satisfiedMask;
- mIsRunnable = runnable;
- }
-
- public JobSnapshot(Parcel in) {
- mJob = JobInfo.CREATOR.createFromParcel(in);
- mSatisfiedConstraints = in.readInt();
- mIsRunnable = in.readBoolean();
- }
-
- private boolean satisfied(int flag) {
- return (mSatisfiedConstraints & flag) != 0;
- }
-
- /**
- * Returning JobInfo bound to this snapshot
- * @return JobInfo of this snapshot
- */
- public JobInfo getJobInfo() {
- return mJob;
- }
-
- /**
- * Is this job actually runnable at this moment?
- */
- public boolean isRunnable() {
- return mIsRunnable;
- }
-
- /**
- * @see JobInfo.Builder#setRequiresCharging(boolean)
- */
- public boolean isChargingSatisfied() {
- return !mJob.isRequireCharging()
- || satisfied(JobInfo.CONSTRAINT_FLAG_CHARGING);
- }
-
- /**
- * @see JobInfo.Builder#setRequiresBatteryNotLow(boolean)
- */
- public boolean isBatteryNotLowSatisfied() {
- return !mJob.isRequireBatteryNotLow()
- || satisfied(JobInfo.CONSTRAINT_FLAG_BATTERY_NOT_LOW);
- }
-
- /**
- * @see JobInfo.Builder#setRequiresDeviceIdle(boolean)
- */
- public boolean isRequireDeviceIdleSatisfied() {
- return !mJob.isRequireDeviceIdle()
- || satisfied(JobInfo.CONSTRAINT_FLAG_DEVICE_IDLE);
- }
-
- public boolean isRequireStorageNotLowSatisfied() {
- return !mJob.isRequireStorageNotLow()
- || satisfied(JobInfo.CONSTRAINT_FLAG_STORAGE_NOT_LOW);
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel out, int flags) {
- mJob.writeToParcel(out, flags);
- out.writeInt(mSatisfiedConstraints);
- out.writeBoolean(mIsRunnable);
- }
-
- public static final @android.annotation.NonNull Creator<JobSnapshot> CREATOR = new Creator<JobSnapshot>() {
- @Override
- public JobSnapshot createFromParcel(Parcel in) {
- return new JobSnapshot(in);
- }
-
- @Override
- public JobSnapshot[] newArray(int size) {
- return new JobSnapshot[size];
- }
- };
-}
diff --git a/core/java/android/app/job/JobWorkItem.aidl b/core/java/android/app/job/JobWorkItem.aidl
deleted file mode 100644
index e8fe47d07865..000000000000
--- a/core/java/android/app/job/JobWorkItem.aidl
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.app.job;
-
-/** @hide */
-parcelable JobWorkItem;
diff --git a/core/java/android/app/job/JobWorkItem.java b/core/java/android/app/job/JobWorkItem.java
deleted file mode 100644
index c6631fa76494..000000000000
--- a/core/java/android/app/job/JobWorkItem.java
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.app.job;
-
-import static android.app.job.JobInfo.NETWORK_BYTES_UNKNOWN;
-
-import android.annotation.BytesLong;
-import android.annotation.UnsupportedAppUsage;
-import android.content.Intent;
-import android.os.Build;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * A unit of work that can be enqueued for a job using
- * {@link JobScheduler#enqueue JobScheduler.enqueue}. See
- * {@link JobParameters#dequeueWork() JobParameters.dequeueWork} for more details.
- */
-final public class JobWorkItem implements Parcelable {
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
- final Intent mIntent;
- final long mNetworkDownloadBytes;
- final long mNetworkUploadBytes;
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
- int mDeliveryCount;
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
- int mWorkId;
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
- Object mGrants;
-
- /**
- * Create a new piece of work, which can be submitted to
- * {@link JobScheduler#enqueue JobScheduler.enqueue}.
- *
- * @param intent The general Intent describing this work.
- */
- public JobWorkItem(Intent intent) {
- mIntent = intent;
- mNetworkDownloadBytes = NETWORK_BYTES_UNKNOWN;
- mNetworkUploadBytes = NETWORK_BYTES_UNKNOWN;
- }
-
- /**
- * Create a new piece of work, which can be submitted to
- * {@link JobScheduler#enqueue JobScheduler.enqueue}.
- * <p>
- * See {@link JobInfo.Builder#setEstimatedNetworkBytes(long, long)} for
- * details about how to estimate network traffic.
- *
- * @param intent The general Intent describing this work.
- * @param downloadBytes The estimated size of network traffic that will be
- * downloaded by this job work item, in bytes.
- * @param uploadBytes The estimated size of network traffic that will be
- * uploaded by this job work item, in bytes.
- */
- public JobWorkItem(Intent intent, @BytesLong long downloadBytes, @BytesLong long uploadBytes) {
- mIntent = intent;
- mNetworkDownloadBytes = downloadBytes;
- mNetworkUploadBytes = uploadBytes;
- }
-
- /**
- * Return the Intent associated with this work.
- */
- public Intent getIntent() {
- return mIntent;
- }
-
- /**
- * Return the estimated size of download traffic that will be performed by
- * this job, in bytes.
- *
- * @return Estimated size of download traffic, or
- * {@link JobInfo#NETWORK_BYTES_UNKNOWN} when unknown.
- */
- public @BytesLong long getEstimatedNetworkDownloadBytes() {
- return mNetworkDownloadBytes;
- }
-
- /**
- * Return the estimated size of upload traffic that will be performed by
- * this job work item, in bytes.
- *
- * @return Estimated size of upload traffic, or
- * {@link JobInfo#NETWORK_BYTES_UNKNOWN} when unknown.
- */
- public @BytesLong long getEstimatedNetworkUploadBytes() {
- return mNetworkUploadBytes;
- }
-
- /**
- * Return the count of the number of times this work item has been delivered
- * to the job. The value will be > 1 if it has been redelivered because the job
- * was stopped or crashed while it had previously been delivered but before the
- * job had called {@link JobParameters#completeWork JobParameters.completeWork} for it.
- */
- public int getDeliveryCount() {
- return mDeliveryCount;
- }
-
- /**
- * @hide
- */
- public void bumpDeliveryCount() {
- mDeliveryCount++;
- }
-
- /**
- * @hide
- */
- public void setWorkId(int id) {
- mWorkId = id;
- }
-
- /**
- * @hide
- */
- public int getWorkId() {
- return mWorkId;
- }
-
- /**
- * @hide
- */
- public void setGrants(Object grants) {
- mGrants = grants;
- }
-
- /**
- * @hide
- */
- public Object getGrants() {
- return mGrants;
- }
-
- public String toString() {
- StringBuilder sb = new StringBuilder(64);
- sb.append("JobWorkItem{id=");
- sb.append(mWorkId);
- sb.append(" intent=");
- sb.append(mIntent);
- if (mNetworkDownloadBytes != NETWORK_BYTES_UNKNOWN) {
- sb.append(" downloadBytes=");
- sb.append(mNetworkDownloadBytes);
- }
- if (mNetworkUploadBytes != NETWORK_BYTES_UNKNOWN) {
- sb.append(" uploadBytes=");
- sb.append(mNetworkUploadBytes);
- }
- if (mDeliveryCount != 0) {
- sb.append(" dcount=");
- sb.append(mDeliveryCount);
- }
- sb.append("}");
- return sb.toString();
- }
-
- public int describeContents() {
- return 0;
- }
-
- public void writeToParcel(Parcel out, int flags) {
- if (mIntent != null) {
- out.writeInt(1);
- mIntent.writeToParcel(out, 0);
- } else {
- out.writeInt(0);
- }
- out.writeLong(mNetworkDownloadBytes);
- out.writeLong(mNetworkUploadBytes);
- out.writeInt(mDeliveryCount);
- out.writeInt(mWorkId);
- }
-
- public static final @android.annotation.NonNull Parcelable.Creator<JobWorkItem> CREATOR
- = new Parcelable.Creator<JobWorkItem>() {
- public JobWorkItem createFromParcel(Parcel in) {
- return new JobWorkItem(in);
- }
-
- public JobWorkItem[] newArray(int size) {
- return new JobWorkItem[size];
- }
- };
-
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
- JobWorkItem(Parcel in) {
- if (in.readInt() != 0) {
- mIntent = Intent.CREATOR.createFromParcel(in);
- } else {
- mIntent = null;
- }
- mNetworkDownloadBytes = in.readLong();
- mNetworkUploadBytes = in.readLong();
- mDeliveryCount = in.readInt();
- mWorkId = in.readInt();
- }
-}