16e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams/*
26e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams * Copyright (C) 2014 The Android Open Source Project
36e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams *
46e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams * Licensed under the Apache License, Version 2.0 (the "License");
56e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams * you may not use this file except in compliance with the License.
66e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams * You may obtain a copy of the License at
76e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams *
86e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams *      http://www.apache.org/licenses/LICENSE-2.0
96e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams *
106e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams * Unless required by applicable law or agreed to in writing, software
116e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams * distributed under the License is distributed on an "AS IS" BASIS,
126e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams * See the License for the specific language governing permissions and
146e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams * limitations under the License
156e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams */
166e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams
177060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tatepackage android.app.job;
186e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams
191b6519bd87a59a10e9928e5772a17976692611daJeff Sharkeyimport static android.util.TimeUtils.formatDuration;
201b6519bd87a59a10e9928e5772a17976692611daJeff Sharkey
211a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackbornimport android.annotation.NonNull;
221a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackbornimport android.annotation.Nullable;
23fa380e982e41b0dcbbcf2201803abf26808016b5Christopher Tateimport android.content.ComponentName;
241a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackbornimport android.net.Uri;
256e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williamsimport android.os.Parcel;
266e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williamsimport android.os.Parcelable;
273d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williamsimport android.os.PersistableBundle;
28e96c3b7eff5290f2a6c5e572babbfa8a3897be96Shreyas Basargeimport android.util.Log;
296e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams
301a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackbornimport java.util.ArrayList;
31121e1645d1396b47f0fefa978f8c77d2c4c6c968Dianne Hackbornimport java.util.Objects;
321a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn
336e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams/**
347060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate * Container of data passed to the {@link android.app.job.JobScheduler} fully encapsulating the
356e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams * parameters required to schedule work against the calling application. These are constructed
367060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate * using the {@link JobInfo.Builder}.
379ae3dbeefcd6bc139c74bfe3d51de823e3be4b4bMatthew Williams * You must specify at least one sort of constraint on the JobInfo object that you are creating.
389ae3dbeefcd6bc139c74bfe3d51de823e3be4b4bMatthew Williams * The goal here is to provide the scheduler with high-level semantics about the work you want to
399ae3dbeefcd6bc139c74bfe3d51de823e3be4b4bMatthew Williams * accomplish. Doing otherwise with throw an exception in your app.
406e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams */
417060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tatepublic class JobInfo implements Parcelable {
42e96c3b7eff5290f2a6c5e572babbfa8a3897be96Shreyas Basarge    private static String TAG = "JobInfo";
43d1c06753d045ad10e00e7aba53ee2adba0712cccMatthew Williams    /** Default. */
44d1c06753d045ad10e00e7aba53ee2adba0712cccMatthew Williams    public static final int NETWORK_TYPE_NONE = 0;
45d1c06753d045ad10e00e7aba53ee2adba0712cccMatthew Williams    /** This job requires network connectivity. */
46d1c06753d045ad10e00e7aba53ee2adba0712cccMatthew Williams    public static final int NETWORK_TYPE_ANY = 1;
47d1c06753d045ad10e00e7aba53ee2adba0712cccMatthew Williams    /** This job requires network connectivity that is unmetered. */
48d1c06753d045ad10e00e7aba53ee2adba0712cccMatthew Williams    public static final int NETWORK_TYPE_UNMETERED = 2;
49f07c7b9fd0a640bff4bf7690373613da217fe69bJeff Sharkey    /** This job requires network connectivity that is not roaming. */
50f07c7b9fd0a640bff4bf7690373613da217fe69bJeff Sharkey    public static final int NETWORK_TYPE_NOT_ROAMING = 3;
516e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams
526e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams    /**
537060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate     * Amount of backoff a job has initially by default, in milliseconds.
543d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams     */
55d1c06753d045ad10e00e7aba53ee2adba0712cccMatthew Williams    public static final long DEFAULT_INITIAL_BACKOFF_MILLIS = 30000L;  // 30 seconds.
563d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams
573d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams    /**
58d1c06753d045ad10e00e7aba53ee2adba0712cccMatthew Williams     * Maximum backoff we allow for a job, in milliseconds.
593d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams     */
60d1c06753d045ad10e00e7aba53ee2adba0712cccMatthew Williams    public static final long MAX_BACKOFF_DELAY_MILLIS = 5 * 60 * 60 * 1000;  // 5 hours.
61d1c06753d045ad10e00e7aba53ee2adba0712cccMatthew Williams
62effacfa75bd9c2ebc889a7bc4f002c07f82f4c31Matthew Williams    /**
63d1c06753d045ad10e00e7aba53ee2adba0712cccMatthew Williams     * Linearly back-off a failed job. See
64d1c06753d045ad10e00e7aba53ee2adba0712cccMatthew Williams     * {@link android.app.job.JobInfo.Builder#setBackoffCriteria(long, int)}
65d1c06753d045ad10e00e7aba53ee2adba0712cccMatthew Williams     * retry_time(current_time, num_failures) =
66d1c06753d045ad10e00e7aba53ee2adba0712cccMatthew Williams     *     current_time + initial_backoff_millis * num_failures, num_failures >= 1
67effacfa75bd9c2ebc889a7bc4f002c07f82f4c31Matthew Williams     */
68d1c06753d045ad10e00e7aba53ee2adba0712cccMatthew Williams    public static final int BACKOFF_POLICY_LINEAR = 0;
693d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams
703d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams    /**
71d1c06753d045ad10e00e7aba53ee2adba0712cccMatthew Williams     * Exponentially back-off a failed job. See
72d1c06753d045ad10e00e7aba53ee2adba0712cccMatthew Williams     * {@link android.app.job.JobInfo.Builder#setBackoffCriteria(long, int)}
73d1c06753d045ad10e00e7aba53ee2adba0712cccMatthew Williams     *
74d1c06753d045ad10e00e7aba53ee2adba0712cccMatthew Williams     * retry_time(current_time, num_failures) =
75d1c06753d045ad10e00e7aba53ee2adba0712cccMatthew Williams     *     current_time + initial_backoff_millis * 2 ^ (num_failures - 1), num_failures >= 1
766e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams     */
77d1c06753d045ad10e00e7aba53ee2adba0712cccMatthew Williams    public static final int BACKOFF_POLICY_EXPONENTIAL = 1;
78d1c06753d045ad10e00e7aba53ee2adba0712cccMatthew Williams
7989ee618280ea05e193afab38f9d2bf99b8274a92Shreyas Basarge    /* Minimum interval for a periodic job, in milliseconds. */
8010be4e90341630883eb9af25ddf82702e2b3fb56Christopher Tate    private static final long MIN_PERIOD_MILLIS = 15 * 60 * 1000L;   // 15 minutes
8110be4e90341630883eb9af25ddf82702e2b3fb56Christopher Tate
8289ee618280ea05e193afab38f9d2bf99b8274a92Shreyas Basarge    /* Minimum flex for a periodic job, in milliseconds. */
8310be4e90341630883eb9af25ddf82702e2b3fb56Christopher Tate    private static final long MIN_FLEX_MILLIS = 5 * 60 * 1000L; // 5 minutes
8410be4e90341630883eb9af25ddf82702e2b3fb56Christopher Tate
8510be4e90341630883eb9af25ddf82702e2b3fb56Christopher Tate    /**
8610be4e90341630883eb9af25ddf82702e2b3fb56Christopher Tate     * Query the minimum interval allowed for periodic scheduled jobs.  Attempting
8710be4e90341630883eb9af25ddf82702e2b3fb56Christopher Tate     * to declare a smaller period that this when scheduling a job will result in a
8810be4e90341630883eb9af25ddf82702e2b3fb56Christopher Tate     * job that is still periodic, but will run with this effective period.
8910be4e90341630883eb9af25ddf82702e2b3fb56Christopher Tate     *
9010be4e90341630883eb9af25ddf82702e2b3fb56Christopher Tate     * @return The minimum available interval for scheduling periodic jobs, in milliseconds.
9110be4e90341630883eb9af25ddf82702e2b3fb56Christopher Tate     */
92a9b4f3f628959eac8f853f1c87a93c5ed6530decChristopher Tate    public static final long getMinPeriodMillis() {
9310be4e90341630883eb9af25ddf82702e2b3fb56Christopher Tate        return MIN_PERIOD_MILLIS;
9410be4e90341630883eb9af25ddf82702e2b3fb56Christopher Tate    }
9510be4e90341630883eb9af25ddf82702e2b3fb56Christopher Tate
9610be4e90341630883eb9af25ddf82702e2b3fb56Christopher Tate    /**
9710be4e90341630883eb9af25ddf82702e2b3fb56Christopher Tate     * Query the minimum flex time allowed for periodic scheduled jobs.  Attempting
9810be4e90341630883eb9af25ddf82702e2b3fb56Christopher Tate     * to declare a shorter flex time than this when scheduling such a job will
9910be4e90341630883eb9af25ddf82702e2b3fb56Christopher Tate     * result in this amount as the effective flex time for the job.
10010be4e90341630883eb9af25ddf82702e2b3fb56Christopher Tate     *
10110be4e90341630883eb9af25ddf82702e2b3fb56Christopher Tate     * @return The minimum available flex time for scheduling periodic jobs, in milliseconds.
10210be4e90341630883eb9af25ddf82702e2b3fb56Christopher Tate     */
103a9b4f3f628959eac8f853f1c87a93c5ed6530decChristopher Tate    public static final long getMinFlexMillis() {
10410be4e90341630883eb9af25ddf82702e2b3fb56Christopher Tate        return MIN_FLEX_MILLIS;
10510be4e90341630883eb9af25ddf82702e2b3fb56Christopher Tate    }
10689ee618280ea05e193afab38f9d2bf99b8274a92Shreyas Basarge
107d1c06753d045ad10e00e7aba53ee2adba0712cccMatthew Williams    /**
108d1c06753d045ad10e00e7aba53ee2adba0712cccMatthew Williams     * Default type of backoff.
109d1c06753d045ad10e00e7aba53ee2adba0712cccMatthew Williams     * @hide
110d1c06753d045ad10e00e7aba53ee2adba0712cccMatthew Williams     */
111d1c06753d045ad10e00e7aba53ee2adba0712cccMatthew Williams    public static final int DEFAULT_BACKOFF_POLICY = BACKOFF_POLICY_EXPONENTIAL;
1126e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams
1131085ff6ee531931ef7f55cbadbc83616f619b292Dianne Hackborn    /**
1141085ff6ee531931ef7f55cbadbc83616f619b292Dianne Hackborn     * Default of {@link #getPriority}.
1151085ff6ee531931ef7f55cbadbc83616f619b292Dianne Hackborn     * @hide
1161085ff6ee531931ef7f55cbadbc83616f619b292Dianne Hackborn     */
1171085ff6ee531931ef7f55cbadbc83616f619b292Dianne Hackborn    public static final int PRIORITY_DEFAULT = 0;
1181085ff6ee531931ef7f55cbadbc83616f619b292Dianne Hackborn
1191085ff6ee531931ef7f55cbadbc83616f619b292Dianne Hackborn    /**
1201085ff6ee531931ef7f55cbadbc83616f619b292Dianne Hackborn     * Value of {@link #getPriority} for expedited syncs.
1211085ff6ee531931ef7f55cbadbc83616f619b292Dianne Hackborn     * @hide
1221085ff6ee531931ef7f55cbadbc83616f619b292Dianne Hackborn     */
1231085ff6ee531931ef7f55cbadbc83616f619b292Dianne Hackborn    public static final int PRIORITY_SYNC_EXPEDITED = 10;
1241085ff6ee531931ef7f55cbadbc83616f619b292Dianne Hackborn
1251085ff6ee531931ef7f55cbadbc83616f619b292Dianne Hackborn    /**
1261085ff6ee531931ef7f55cbadbc83616f619b292Dianne Hackborn     * Value of {@link #getPriority} for first time initialization syncs.
1271085ff6ee531931ef7f55cbadbc83616f619b292Dianne Hackborn     * @hide
1281085ff6ee531931ef7f55cbadbc83616f619b292Dianne Hackborn     */
1291085ff6ee531931ef7f55cbadbc83616f619b292Dianne Hackborn    public static final int PRIORITY_SYNC_INITIALIZATION = 20;
1301085ff6ee531931ef7f55cbadbc83616f619b292Dianne Hackborn
1311085ff6ee531931ef7f55cbadbc83616f619b292Dianne Hackborn    /**
132970510b9c5299d480b3ec7f8403afd8265456f87Dianne Hackborn     * Value of {@link #getPriority} for a foreground app (overrides the supplied
1331085ff6ee531931ef7f55cbadbc83616f619b292Dianne Hackborn     * JobInfo priority if it is smaller).
1341085ff6ee531931ef7f55cbadbc83616f619b292Dianne Hackborn     * @hide
1351085ff6ee531931ef7f55cbadbc83616f619b292Dianne Hackborn     */
1361085ff6ee531931ef7f55cbadbc83616f619b292Dianne Hackborn    public static final int PRIORITY_FOREGROUND_APP = 30;
1371085ff6ee531931ef7f55cbadbc83616f619b292Dianne Hackborn
138970510b9c5299d480b3ec7f8403afd8265456f87Dianne Hackborn    /**
139970510b9c5299d480b3ec7f8403afd8265456f87Dianne Hackborn     * Value of {@link #getPriority} for the current top app (overrides the supplied
140970510b9c5299d480b3ec7f8403afd8265456f87Dianne Hackborn     * JobInfo priority if it is smaller).
141970510b9c5299d480b3ec7f8403afd8265456f87Dianne Hackborn     * @hide
142970510b9c5299d480b3ec7f8403afd8265456f87Dianne Hackborn     */
143970510b9c5299d480b3ec7f8403afd8265456f87Dianne Hackborn    public static final int PRIORITY_TOP_APP = 40;
144970510b9c5299d480b3ec7f8403afd8265456f87Dianne Hackborn
145807de78c072c5a40be7b12c656d641d9e73741d2Dianne Hackborn    /**
146807de78c072c5a40be7b12c656d641d9e73741d2Dianne Hackborn     * Adjustment of {@link #getPriority} if the app has often (50% or more of the time)
147807de78c072c5a40be7b12c656d641d9e73741d2Dianne Hackborn     * been running jobs.
148807de78c072c5a40be7b12c656d641d9e73741d2Dianne Hackborn     * @hide
149807de78c072c5a40be7b12c656d641d9e73741d2Dianne Hackborn     */
150807de78c072c5a40be7b12c656d641d9e73741d2Dianne Hackborn    public static final int PRIORITY_ADJ_OFTEN_RUNNING = -40;
151807de78c072c5a40be7b12c656d641d9e73741d2Dianne Hackborn
152807de78c072c5a40be7b12c656d641d9e73741d2Dianne Hackborn    /**
153807de78c072c5a40be7b12c656d641d9e73741d2Dianne Hackborn     * Adjustment of {@link #getPriority} if the app has always (90% or more of the time)
154807de78c072c5a40be7b12c656d641d9e73741d2Dianne Hackborn     * been running jobs.
155807de78c072c5a40be7b12c656d641d9e73741d2Dianne Hackborn     * @hide
156807de78c072c5a40be7b12c656d641d9e73741d2Dianne Hackborn     */
157807de78c072c5a40be7b12c656d641d9e73741d2Dianne Hackborn    public static final int PRIORITY_ADJ_ALWAYS_RUNNING = -80;
158807de78c072c5a40be7b12c656d641d9e73741d2Dianne Hackborn
1591b6519bd87a59a10e9928e5772a17976692611daJeff Sharkey    /**
1601b6519bd87a59a10e9928e5772a17976692611daJeff Sharkey     * Indicates that the implementation of this job will be using
1611b6519bd87a59a10e9928e5772a17976692611daJeff Sharkey     * {@link JobService#startForeground(int, android.app.Notification)} to run
1621b6519bd87a59a10e9928e5772a17976692611daJeff Sharkey     * in the foreground.
1631b6519bd87a59a10e9928e5772a17976692611daJeff Sharkey     * <p>
1641b6519bd87a59a10e9928e5772a17976692611daJeff Sharkey     * When set, the internal scheduling of this job will ignore any background
1651b6519bd87a59a10e9928e5772a17976692611daJeff Sharkey     * network restrictions for the requesting app. Note that this flag alone
1661b6519bd87a59a10e9928e5772a17976692611daJeff Sharkey     * doesn't actually place your {@link JobService} in the foreground; you
1671b6519bd87a59a10e9928e5772a17976692611daJeff Sharkey     * still need to post the notification yourself.
168785f494e8752ca3bcffe1d648ecf05b0734df31cJeff Sharkey     * <p>
169785f494e8752ca3bcffe1d648ecf05b0734df31cJeff Sharkey     * To use this flag, the caller must hold the
170785f494e8752ca3bcffe1d648ecf05b0734df31cJeff Sharkey     * {@link android.Manifest.permission#CONNECTIVITY_INTERNAL} permission.
1711b6519bd87a59a10e9928e5772a17976692611daJeff Sharkey     *
1721b6519bd87a59a10e9928e5772a17976692611daJeff Sharkey     * @hide
1731b6519bd87a59a10e9928e5772a17976692611daJeff Sharkey     */
1741b6519bd87a59a10e9928e5772a17976692611daJeff Sharkey    public static final int FLAG_WILL_BE_FOREGROUND = 1 << 0;
1751b6519bd87a59a10e9928e5772a17976692611daJeff Sharkey
1767060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate    private final int jobId;
1773d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams    private final PersistableBundle extras;
1786de79e2b17fa0796ea4d39fd9555b563c484248dMatthew Williams    private final ComponentName service;
1796de79e2b17fa0796ea4d39fd9555b563c484248dMatthew Williams    private final boolean requireCharging;
1806de79e2b17fa0796ea4d39fd9555b563c484248dMatthew Williams    private final boolean requireDeviceIdle;
1811a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn    private final TriggerContentUri[] triggerContentUris;
1828db0fc15b85c6501a0418b17edee2d9c447b408aDianne Hackborn    private final long triggerContentUpdateDelay;
1838db0fc15b85c6501a0418b17edee2d9c447b408aDianne Hackborn    private final long triggerContentMaxDelay;
1849b9244b6941110ea2d940d9fc8eed0cdff96a016Matthew Williams    private final boolean hasEarlyConstraint;
1859b9244b6941110ea2d940d9fc8eed0cdff96a016Matthew Williams    private final boolean hasLateConstraint;
186d1c06753d045ad10e00e7aba53ee2adba0712cccMatthew Williams    private final int networkType;
1876de79e2b17fa0796ea4d39fd9555b563c484248dMatthew Williams    private final long minLatencyMillis;
1886de79e2b17fa0796ea4d39fd9555b563c484248dMatthew Williams    private final long maxExecutionDelayMillis;
1896de79e2b17fa0796ea4d39fd9555b563c484248dMatthew Williams    private final boolean isPeriodic;
190900c67fc51fc2672458dd1c9641250f2ecc01a31Matthew Williams    private final boolean isPersisted;
1916de79e2b17fa0796ea4d39fd9555b563c484248dMatthew Williams    private final long intervalMillis;
19289ee618280ea05e193afab38f9d2bf99b8274a92Shreyas Basarge    private final long flexMillis;
1936de79e2b17fa0796ea4d39fd9555b563c484248dMatthew Williams    private final long initialBackoffMillis;
1946de79e2b17fa0796ea4d39fd9555b563c484248dMatthew Williams    private final int backoffPolicy;
1955db09084c8e4efc6311754243c39962fc8e7a766Shreyas Basarge    private final int priority;
1961b6519bd87a59a10e9928e5772a17976692611daJeff Sharkey    private final int flags;
1976de79e2b17fa0796ea4d39fd9555b563c484248dMatthew Williams
1986e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams    /**
199e9a988caca733d2f292991a52a0047685a69812fDianne Hackborn     * Unique job id associated with this application (uid).  This is the same job ID
200e9a988caca733d2f292991a52a0047685a69812fDianne Hackborn     * you supplied in the {@link Builder} constructor.
2016e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams     */
2029b9244b6941110ea2d940d9fc8eed0cdff96a016Matthew Williams    public int getId() {
2037060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate        return jobId;
2046e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams    }
2056e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams
2066e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams    /**
2076e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams     * Bundle of extras which are returned to your application at execution time.
2086e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams     */
2093d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams    public PersistableBundle getExtras() {
2106e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams        return extras;
2116e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams    }
2126e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams
2136e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams    /**
2147060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate     * Name of the service endpoint that will be called back into by the JobScheduler.
2156e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams     */
2166de79e2b17fa0796ea4d39fd9555b563c484248dMatthew Williams    public ComponentName getService() {
2176de79e2b17fa0796ea4d39fd9555b563c484248dMatthew Williams        return service;
2186e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams    }
2196e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams
2205db09084c8e4efc6311754243c39962fc8e7a766Shreyas Basarge    /** @hide */
2215db09084c8e4efc6311754243c39962fc8e7a766Shreyas Basarge    public int getPriority() {
2225db09084c8e4efc6311754243c39962fc8e7a766Shreyas Basarge        return priority;
2235db09084c8e4efc6311754243c39962fc8e7a766Shreyas Basarge    }
2245db09084c8e4efc6311754243c39962fc8e7a766Shreyas Basarge
2251b6519bd87a59a10e9928e5772a17976692611daJeff Sharkey    /** @hide */
2261b6519bd87a59a10e9928e5772a17976692611daJeff Sharkey    public int getFlags() {
2271b6519bd87a59a10e9928e5772a17976692611daJeff Sharkey        return flags;
2281b6519bd87a59a10e9928e5772a17976692611daJeff Sharkey    }
2291b6519bd87a59a10e9928e5772a17976692611daJeff Sharkey
2306e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams    /**
2317060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate     * Whether this job needs the device to be plugged in.
2326e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams     */
2336e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams    public boolean isRequireCharging() {
2346e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams        return requireCharging;
2356e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams    }
2366e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams
2376e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams    /**
2387060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate     * Whether this job needs the device to be in an Idle maintenance window.
2396e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams     */
2406e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams    public boolean isRequireDeviceIdle() {
2416e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams        return requireDeviceIdle;
2426e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams    }
2436e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams
2446e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams    /**
2451a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn     * Which content: URIs must change for the job to be scheduled.  Returns null
2461a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn     * if there are none required.
2471a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn     */
2481a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn    @Nullable
2491a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn    public TriggerContentUri[] getTriggerContentUris() {
2501a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn        return triggerContentUris;
2511a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn    }
2521a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn
2531a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn    /**
2548db0fc15b85c6501a0418b17edee2d9c447b408aDianne Hackborn     * When triggering on content URI changes, this is the delay from when a change
2558db0fc15b85c6501a0418b17edee2d9c447b408aDianne Hackborn     * is detected until the job is scheduled.
2568db0fc15b85c6501a0418b17edee2d9c447b408aDianne Hackborn     */
2578db0fc15b85c6501a0418b17edee2d9c447b408aDianne Hackborn    public long getTriggerContentUpdateDelay() {
2588db0fc15b85c6501a0418b17edee2d9c447b408aDianne Hackborn        return triggerContentUpdateDelay;
2598db0fc15b85c6501a0418b17edee2d9c447b408aDianne Hackborn    }
2608db0fc15b85c6501a0418b17edee2d9c447b408aDianne Hackborn
2618db0fc15b85c6501a0418b17edee2d9c447b408aDianne Hackborn    /**
2628db0fc15b85c6501a0418b17edee2d9c447b408aDianne Hackborn     * When triggering on content URI changes, this is the maximum delay we will
2638db0fc15b85c6501a0418b17edee2d9c447b408aDianne Hackborn     * use before scheduling the job.
2648db0fc15b85c6501a0418b17edee2d9c447b408aDianne Hackborn     */
2658db0fc15b85c6501a0418b17edee2d9c447b408aDianne Hackborn    public long getTriggerContentMaxDelay() {
2668db0fc15b85c6501a0418b17edee2d9c447b408aDianne Hackborn        return triggerContentMaxDelay;
2678db0fc15b85c6501a0418b17edee2d9c447b408aDianne Hackborn    }
2688db0fc15b85c6501a0418b17edee2d9c447b408aDianne Hackborn
2698db0fc15b85c6501a0418b17edee2d9c447b408aDianne Hackborn    /**
270d1c06753d045ad10e00e7aba53ee2adba0712cccMatthew Williams     * One of {@link android.app.job.JobInfo#NETWORK_TYPE_ANY},
271f07c7b9fd0a640bff4bf7690373613da217fe69bJeff Sharkey     * {@link android.app.job.JobInfo#NETWORK_TYPE_NONE},
272f07c7b9fd0a640bff4bf7690373613da217fe69bJeff Sharkey     * {@link android.app.job.JobInfo#NETWORK_TYPE_UNMETERED}, or
273f07c7b9fd0a640bff4bf7690373613da217fe69bJeff Sharkey     * {@link android.app.job.JobInfo#NETWORK_TYPE_NOT_ROAMING}.
2746e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams     */
275d1c06753d045ad10e00e7aba53ee2adba0712cccMatthew Williams    public int getNetworkType() {
276d1c06753d045ad10e00e7aba53ee2adba0712cccMatthew Williams        return networkType;
2776e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams    }
2786e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams
2796e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams    /**
2807060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate     * Set for a job that does not recur periodically, to specify a delay after which the job
2817060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate     * will be eligible for execution. This value is not set if the job recurs periodically.
2826e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams     */
2836e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams    public long getMinLatencyMillis() {
2846e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams        return minLatencyMillis;
2856e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams    }
2866e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams
2876e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams    /**
2887060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate     * See {@link Builder#setOverrideDeadline(long)}. This value is not set if the job recurs
2896e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams     * periodically.
2906e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams     */
2916e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams    public long getMaxExecutionDelayMillis() {
2926e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams        return maxExecutionDelayMillis;
2936e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams    }
2946e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams
2956e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams    /**
2967060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate     * Track whether this job will repeat with a given period.
2976e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams     */
2986e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams    public boolean isPeriodic() {
2996e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams        return isPeriodic;
3006e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams    }
3016e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams
3026e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams    /**
303900c67fc51fc2672458dd1c9641250f2ecc01a31Matthew Williams     * @return Whether or not this job should be persisted across device reboots.
304900c67fc51fc2672458dd1c9641250f2ecc01a31Matthew Williams     */
305900c67fc51fc2672458dd1c9641250f2ecc01a31Matthew Williams    public boolean isPersisted() {
306900c67fc51fc2672458dd1c9641250f2ecc01a31Matthew Williams        return isPersisted;
307900c67fc51fc2672458dd1c9641250f2ecc01a31Matthew Williams    }
308900c67fc51fc2672458dd1c9641250f2ecc01a31Matthew Williams
309900c67fc51fc2672458dd1c9641250f2ecc01a31Matthew Williams    /**
3107060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate     * Set to the interval between occurrences of this job. This value is <b>not</b> set if the
3117060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate     * job does not recur periodically.
3126e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams     */
3136e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams    public long getIntervalMillis() {
314a9b4f3f628959eac8f853f1c87a93c5ed6530decChristopher Tate        return intervalMillis >= getMinPeriodMillis() ? intervalMillis : getMinPeriodMillis();
31589ee618280ea05e193afab38f9d2bf99b8274a92Shreyas Basarge    }
31689ee618280ea05e193afab38f9d2bf99b8274a92Shreyas Basarge
31789ee618280ea05e193afab38f9d2bf99b8274a92Shreyas Basarge    /**
3189e6d588c934a71ef5937cec0a5e7b7490ac5ab3dShreyas Basarge     * Flex time for this job. Only valid if this is a periodic job.  The job can
3199e6d588c934a71ef5937cec0a5e7b7490ac5ab3dShreyas Basarge     * execute at any time in a window of flex length at the end of the period.
32089ee618280ea05e193afab38f9d2bf99b8274a92Shreyas Basarge     */
32189ee618280ea05e193afab38f9d2bf99b8274a92Shreyas Basarge    public long getFlexMillis() {
32289ee618280ea05e193afab38f9d2bf99b8274a92Shreyas Basarge        long interval = getIntervalMillis();
32389ee618280ea05e193afab38f9d2bf99b8274a92Shreyas Basarge        long percentClamp = 5 * interval / 100;
324a9b4f3f628959eac8f853f1c87a93c5ed6530decChristopher Tate        long clampedFlex = Math.max(flexMillis, Math.max(percentClamp, getMinFlexMillis()));
32589ee618280ea05e193afab38f9d2bf99b8274a92Shreyas Basarge        return clampedFlex <= interval ? clampedFlex : interval;
3266e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams    }
3276e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams
3286e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams    /**
3297060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate     * The amount of time the JobScheduler will wait before rescheduling a failed job. This value
3307060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate     * will be increased depending on the backoff policy specified at job creation time. Defaults
3316e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams     * to 5 seconds.
3326e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams     */
3336e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams    public long getInitialBackoffMillis() {
3346e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams        return initialBackoffMillis;
3356e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams    }
3366e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams
3376e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams    /**
338d1c06753d045ad10e00e7aba53ee2adba0712cccMatthew Williams     * One of either {@link android.app.job.JobInfo#BACKOFF_POLICY_EXPONENTIAL}, or
339d1c06753d045ad10e00e7aba53ee2adba0712cccMatthew Williams     * {@link android.app.job.JobInfo#BACKOFF_POLICY_LINEAR}, depending on which criteria you set
340d1c06753d045ad10e00e7aba53ee2adba0712cccMatthew Williams     * when creating this job.
3416e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams     */
3426e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams    public int getBackoffPolicy() {
3436e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams        return backoffPolicy;
3446e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams    }
3456e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams
3469b9244b6941110ea2d940d9fc8eed0cdff96a016Matthew Williams    /**
3479b9244b6941110ea2d940d9fc8eed0cdff96a016Matthew Williams     * User can specify an early constraint of 0L, which is valid, so we keep track of whether the
3489b9244b6941110ea2d940d9fc8eed0cdff96a016Matthew Williams     * function was called at all.
3499b9244b6941110ea2d940d9fc8eed0cdff96a016Matthew Williams     * @hide
3509b9244b6941110ea2d940d9fc8eed0cdff96a016Matthew Williams     */
3519b9244b6941110ea2d940d9fc8eed0cdff96a016Matthew Williams    public boolean hasEarlyConstraint() {
3529b9244b6941110ea2d940d9fc8eed0cdff96a016Matthew Williams        return hasEarlyConstraint;
3539b9244b6941110ea2d940d9fc8eed0cdff96a016Matthew Williams    }
3549b9244b6941110ea2d940d9fc8eed0cdff96a016Matthew Williams
3559b9244b6941110ea2d940d9fc8eed0cdff96a016Matthew Williams    /**
3569b9244b6941110ea2d940d9fc8eed0cdff96a016Matthew Williams     * User can specify a late constraint of 0L, which is valid, so we keep track of whether the
3579b9244b6941110ea2d940d9fc8eed0cdff96a016Matthew Williams     * function was called at all.
3589b9244b6941110ea2d940d9fc8eed0cdff96a016Matthew Williams     * @hide
3599b9244b6941110ea2d940d9fc8eed0cdff96a016Matthew Williams     */
3609b9244b6941110ea2d940d9fc8eed0cdff96a016Matthew Williams    public boolean hasLateConstraint() {
3619b9244b6941110ea2d940d9fc8eed0cdff96a016Matthew Williams        return hasLateConstraint;
3629b9244b6941110ea2d940d9fc8eed0cdff96a016Matthew Williams    }
3639b9244b6941110ea2d940d9fc8eed0cdff96a016Matthew Williams
3647060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate    private JobInfo(Parcel in) {
3657060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate        jobId = in.readInt();
3663d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams        extras = in.readPersistableBundle();
367effacfa75bd9c2ebc889a7bc4f002c07f82f4c31Matthew Williams        service = in.readParcelable(null);
3686e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams        requireCharging = in.readInt() == 1;
3696e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams        requireDeviceIdle = in.readInt() == 1;
3701a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn        triggerContentUris = in.createTypedArray(TriggerContentUri.CREATOR);
3718db0fc15b85c6501a0418b17edee2d9c447b408aDianne Hackborn        triggerContentUpdateDelay = in.readLong();
3728db0fc15b85c6501a0418b17edee2d9c447b408aDianne Hackborn        triggerContentMaxDelay = in.readLong();
373d1c06753d045ad10e00e7aba53ee2adba0712cccMatthew Williams        networkType = in.readInt();
3746e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams        minLatencyMillis = in.readLong();
3756e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams        maxExecutionDelayMillis = in.readLong();
3766e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams        isPeriodic = in.readInt() == 1;
377900c67fc51fc2672458dd1c9641250f2ecc01a31Matthew Williams        isPersisted = in.readInt() == 1;
3786e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams        intervalMillis = in.readLong();
37989ee618280ea05e193afab38f9d2bf99b8274a92Shreyas Basarge        flexMillis = in.readLong();
3806e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams        initialBackoffMillis = in.readLong();
3816e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams        backoffPolicy = in.readInt();
3829b9244b6941110ea2d940d9fc8eed0cdff96a016Matthew Williams        hasEarlyConstraint = in.readInt() == 1;
3839b9244b6941110ea2d940d9fc8eed0cdff96a016Matthew Williams        hasLateConstraint = in.readInt() == 1;
3845db09084c8e4efc6311754243c39962fc8e7a766Shreyas Basarge        priority = in.readInt();
3851b6519bd87a59a10e9928e5772a17976692611daJeff Sharkey        flags = in.readInt();
3866e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams    }
3876e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams
3887060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate    private JobInfo(JobInfo.Builder b) {
3897060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate        jobId = b.mJobId;
390effacfa75bd9c2ebc889a7bc4f002c07f82f4c31Matthew Williams        extras = b.mExtras;
3917060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate        service = b.mJobService;
3926e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams        requireCharging = b.mRequiresCharging;
3936e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams        requireDeviceIdle = b.mRequiresDeviceIdle;
3941a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn        triggerContentUris = b.mTriggerContentUris != null
3951a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn                ? b.mTriggerContentUris.toArray(new TriggerContentUri[b.mTriggerContentUris.size()])
3961a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn                : null;
3978db0fc15b85c6501a0418b17edee2d9c447b408aDianne Hackborn        triggerContentUpdateDelay = b.mTriggerContentUpdateDelay;
3988db0fc15b85c6501a0418b17edee2d9c447b408aDianne Hackborn        triggerContentMaxDelay = b.mTriggerContentMaxDelay;
399d1c06753d045ad10e00e7aba53ee2adba0712cccMatthew Williams        networkType = b.mNetworkType;
4006e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams        minLatencyMillis = b.mMinLatencyMillis;
4016e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams        maxExecutionDelayMillis = b.mMaxExecutionDelayMillis;
4026e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams        isPeriodic = b.mIsPeriodic;
403900c67fc51fc2672458dd1c9641250f2ecc01a31Matthew Williams        isPersisted = b.mIsPersisted;
4046e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams        intervalMillis = b.mIntervalMillis;
40589ee618280ea05e193afab38f9d2bf99b8274a92Shreyas Basarge        flexMillis = b.mFlexMillis;
4066e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams        initialBackoffMillis = b.mInitialBackoffMillis;
4076e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams        backoffPolicy = b.mBackoffPolicy;
4089b9244b6941110ea2d940d9fc8eed0cdff96a016Matthew Williams        hasEarlyConstraint = b.mHasEarlyConstraint;
4099b9244b6941110ea2d940d9fc8eed0cdff96a016Matthew Williams        hasLateConstraint = b.mHasLateConstraint;
4105db09084c8e4efc6311754243c39962fc8e7a766Shreyas Basarge        priority = b.mPriority;
4111b6519bd87a59a10e9928e5772a17976692611daJeff Sharkey        flags = b.mFlags;
4126e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams    }
4136e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams
4146e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams    @Override
4156e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams    public int describeContents() {
4166e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams        return 0;
4176e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams    }
4186e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams
4196e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams    @Override
4206e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams    public void writeToParcel(Parcel out, int flags) {
4217060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate        out.writeInt(jobId);
4223d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams        out.writePersistableBundle(extras);
423effacfa75bd9c2ebc889a7bc4f002c07f82f4c31Matthew Williams        out.writeParcelable(service, flags);
4246e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams        out.writeInt(requireCharging ? 1 : 0);
4256e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams        out.writeInt(requireDeviceIdle ? 1 : 0);
4261a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn        out.writeTypedArray(triggerContentUris, flags);
4278db0fc15b85c6501a0418b17edee2d9c447b408aDianne Hackborn        out.writeLong(triggerContentUpdateDelay);
4288db0fc15b85c6501a0418b17edee2d9c447b408aDianne Hackborn        out.writeLong(triggerContentMaxDelay);
429d1c06753d045ad10e00e7aba53ee2adba0712cccMatthew Williams        out.writeInt(networkType);
4306e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams        out.writeLong(minLatencyMillis);
4316e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams        out.writeLong(maxExecutionDelayMillis);
4326e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams        out.writeInt(isPeriodic ? 1 : 0);
433900c67fc51fc2672458dd1c9641250f2ecc01a31Matthew Williams        out.writeInt(isPersisted ? 1 : 0);
4346e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams        out.writeLong(intervalMillis);
43589ee618280ea05e193afab38f9d2bf99b8274a92Shreyas Basarge        out.writeLong(flexMillis);
4366e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams        out.writeLong(initialBackoffMillis);
4376e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams        out.writeInt(backoffPolicy);
4389b9244b6941110ea2d940d9fc8eed0cdff96a016Matthew Williams        out.writeInt(hasEarlyConstraint ? 1 : 0);
4399b9244b6941110ea2d940d9fc8eed0cdff96a016Matthew Williams        out.writeInt(hasLateConstraint ? 1 : 0);
4405db09084c8e4efc6311754243c39962fc8e7a766Shreyas Basarge        out.writeInt(priority);
4411b6519bd87a59a10e9928e5772a17976692611daJeff Sharkey        out.writeInt(this.flags);
4426e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams    }
4436e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams
4447060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate    public static final Creator<JobInfo> CREATOR = new Creator<JobInfo>() {
4456e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams        @Override
4467060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate        public JobInfo createFromParcel(Parcel in) {
4477060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate            return new JobInfo(in);
4486e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams        }
4496e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams
4506e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams        @Override
4517060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate        public JobInfo[] newArray(int size) {
4527060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate            return new JobInfo[size];
4536e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams        }
4546e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams    };
4556e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams
456ee410da42b6b8352213f03f7725fd041f703b035Matthew Williams    @Override
457ee410da42b6b8352213f03f7725fd041f703b035Matthew Williams    public String toString() {
458ee410da42b6b8352213f03f7725fd041f703b035Matthew Williams        return "(job:" + jobId + "/" + service.flattenToShortString() + ")";
459ee410da42b6b8352213f03f7725fd041f703b035Matthew Williams    }
460ee410da42b6b8352213f03f7725fd041f703b035Matthew Williams
4611a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn    /**
4621a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn     * Information about a content URI modification that a job would like to
4631a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn     * trigger on.
4641a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn     */
4651a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn    public static final class TriggerContentUri implements Parcelable {
4661a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn        private final Uri mUri;
4671a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn        private final int mFlags;
4681a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn
4691a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn        /**
4701a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn         * Flag for trigger: also trigger if any descendants of the given URI change.
4711a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn         * Corresponds to the <var>notifyForDescendants</var> of
4721a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn         * {@link android.content.ContentResolver#registerContentObserver}.
4731a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn         */
4741a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn        public static final int FLAG_NOTIFY_FOR_DESCENDANTS = 1<<0;
4751a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn
4761a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn        /**
4771a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn         * Create a new trigger description.
4781a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn         * @param uri The URI to observe.  Must be non-null.
4791a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn         * @param flags Optional flags for the observer, either 0 or
4801a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn         * {@link #FLAG_NOTIFY_FOR_DESCENDANTS}.
4811a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn         */
4821a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn        public TriggerContentUri(@NonNull Uri uri, int flags) {
4831a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn            mUri = uri;
4841a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn            mFlags = flags;
4851a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn        }
4861a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn
4871a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn        /**
4881a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn         * Return the Uri this trigger was created for.
4891a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn         */
4901a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn        public Uri getUri() {
4911a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn            return mUri;
4921a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn        }
4931a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn
4941a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn        /**
4951a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn         * Return the flags supplied for the trigger.
4961a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn         */
4971a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn        public int getFlags() {
4981a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn            return mFlags;
4991a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn        }
5001a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn
501121e1645d1396b47f0fefa978f8c77d2c4c6c968Dianne Hackborn        @Override
502121e1645d1396b47f0fefa978f8c77d2c4c6c968Dianne Hackborn        public boolean equals(Object o) {
503121e1645d1396b47f0fefa978f8c77d2c4c6c968Dianne Hackborn            if (!(o instanceof TriggerContentUri)) {
504121e1645d1396b47f0fefa978f8c77d2c4c6c968Dianne Hackborn                return false;
505121e1645d1396b47f0fefa978f8c77d2c4c6c968Dianne Hackborn            }
506121e1645d1396b47f0fefa978f8c77d2c4c6c968Dianne Hackborn            TriggerContentUri t = (TriggerContentUri) o;
507121e1645d1396b47f0fefa978f8c77d2c4c6c968Dianne Hackborn            return Objects.equals(t.mUri, mUri) && t.mFlags == mFlags;
508121e1645d1396b47f0fefa978f8c77d2c4c6c968Dianne Hackborn        }
509121e1645d1396b47f0fefa978f8c77d2c4c6c968Dianne Hackborn
510121e1645d1396b47f0fefa978f8c77d2c4c6c968Dianne Hackborn        @Override
511121e1645d1396b47f0fefa978f8c77d2c4c6c968Dianne Hackborn        public int hashCode() {
512121e1645d1396b47f0fefa978f8c77d2c4c6c968Dianne Hackborn            return (mUri == null ? 0 : mUri.hashCode()) ^ mFlags;
513121e1645d1396b47f0fefa978f8c77d2c4c6c968Dianne Hackborn        }
514121e1645d1396b47f0fefa978f8c77d2c4c6c968Dianne Hackborn
5151a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn        private TriggerContentUri(Parcel in) {
5161a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn            mUri = Uri.CREATOR.createFromParcel(in);
5171a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn            mFlags = in.readInt();
5181a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn        }
5191a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn
5201a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn        @Override
5211a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn        public int describeContents() {
5221a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn            return 0;
5231a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn        }
5241a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn
5251a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn        @Override
5261a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn        public void writeToParcel(Parcel out, int flags) {
5271a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn            mUri.writeToParcel(out, flags);
5281a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn            out.writeInt(mFlags);
5291a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn        }
5301a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn
5311a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn        public static final Creator<TriggerContentUri> CREATOR = new Creator<TriggerContentUri>() {
5321a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn            @Override
5331a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn            public TriggerContentUri createFromParcel(Parcel in) {
5341a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn                return new TriggerContentUri(in);
5351a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn            }
5361a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn
5371a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn            @Override
5381a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn            public TriggerContentUri[] newArray(int size) {
5391a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn                return new TriggerContentUri[size];
5401a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn            }
5411a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn        };
5421a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn    }
5431a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn
5447060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate    /** Builder class for constructing {@link JobInfo} objects. */
5459b9244b6941110ea2d940d9fc8eed0cdff96a016Matthew Williams    public static final class Builder {
546e9a988caca733d2f292991a52a0047685a69812fDianne Hackborn        private final int mJobId;
547e9a988caca733d2f292991a52a0047685a69812fDianne Hackborn        private final ComponentName mJobService;
5483d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams        private PersistableBundle mExtras = PersistableBundle.EMPTY;
5491085ff6ee531931ef7f55cbadbc83616f619b292Dianne Hackborn        private int mPriority = PRIORITY_DEFAULT;
5501b6519bd87a59a10e9928e5772a17976692611daJeff Sharkey        private int mFlags;
5516e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams        // Requirements.
5526e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams        private boolean mRequiresCharging;
5536e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams        private boolean mRequiresDeviceIdle;
554d1c06753d045ad10e00e7aba53ee2adba0712cccMatthew Williams        private int mNetworkType;
5551a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn        private ArrayList<TriggerContentUri> mTriggerContentUris;
5568db0fc15b85c6501a0418b17edee2d9c447b408aDianne Hackborn        private long mTriggerContentUpdateDelay = -1;
5578db0fc15b85c6501a0418b17edee2d9c447b408aDianne Hackborn        private long mTriggerContentMaxDelay = -1;
558900c67fc51fc2672458dd1c9641250f2ecc01a31Matthew Williams        private boolean mIsPersisted;
5596e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams        // One-off parameters.
5606e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams        private long mMinLatencyMillis;
5616e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams        private long mMaxExecutionDelayMillis;
5626e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams        // Periodic parameters.
5636e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams        private boolean mIsPeriodic;
5649b9244b6941110ea2d940d9fc8eed0cdff96a016Matthew Williams        private boolean mHasEarlyConstraint;
5659b9244b6941110ea2d940d9fc8eed0cdff96a016Matthew Williams        private boolean mHasLateConstraint;
5666e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams        private long mIntervalMillis;
56789ee618280ea05e193afab38f9d2bf99b8274a92Shreyas Basarge        private long mFlexMillis;
5686e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams        // Back-off parameters.
5693d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams        private long mInitialBackoffMillis = DEFAULT_INITIAL_BACKOFF_MILLIS;
5703d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams        private int mBackoffPolicy = DEFAULT_BACKOFF_POLICY;
5716e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams        /** Easy way to track whether the client has tried to set a back-off policy. */
5726e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams        private boolean mBackoffPolicySet = false;
5736e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams
5746e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams        /**
575e9a988caca733d2f292991a52a0047685a69812fDianne Hackborn         * Initialize a new Builder to construct a {@link JobInfo}.
576e9a988caca733d2f292991a52a0047685a69812fDianne Hackborn         *
5777060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate         * @param jobId Application-provided id for this job. Subsequent calls to cancel, or
578e9a988caca733d2f292991a52a0047685a69812fDianne Hackborn         * jobs created with the same jobId, will update the pre-existing job with
579e9a988caca733d2f292991a52a0047685a69812fDianne Hackborn         * the same id.  This ID must be unique across all clients of the same uid
580e9a988caca733d2f292991a52a0047685a69812fDianne Hackborn         * (not just the same package).  You will want to make sure this is a stable
581e9a988caca733d2f292991a52a0047685a69812fDianne Hackborn         * id across app updates, so probably not based on a resource ID.
5827060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate         * @param jobService The endpoint that you implement that will receive the callback from the
583e9a988caca733d2f292991a52a0047685a69812fDianne Hackborn         * JobScheduler.
5846e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams         */
5857060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate        public Builder(int jobId, ComponentName jobService) {
5867060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate            mJobService = jobService;
5877060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate            mJobId = jobId;
5886e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams        }
5896e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams
5901b6519bd87a59a10e9928e5772a17976692611daJeff Sharkey        /** @hide */
5915db09084c8e4efc6311754243c39962fc8e7a766Shreyas Basarge        public Builder setPriority(int priority) {
5925db09084c8e4efc6311754243c39962fc8e7a766Shreyas Basarge            mPriority = priority;
5935db09084c8e4efc6311754243c39962fc8e7a766Shreyas Basarge            return this;
5945db09084c8e4efc6311754243c39962fc8e7a766Shreyas Basarge        }
5956e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams
5961b6519bd87a59a10e9928e5772a17976692611daJeff Sharkey        /** @hide */
5971b6519bd87a59a10e9928e5772a17976692611daJeff Sharkey        public Builder setFlags(int flags) {
5981b6519bd87a59a10e9928e5772a17976692611daJeff Sharkey            mFlags = flags;
5991b6519bd87a59a10e9928e5772a17976692611daJeff Sharkey            return this;
6001b6519bd87a59a10e9928e5772a17976692611daJeff Sharkey        }
6011b6519bd87a59a10e9928e5772a17976692611daJeff Sharkey
6026e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams        /**
6036e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams         * Set optional extras. This is persisted, so we only allow primitive types.
6046e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams         * @param extras Bundle containing extras you want the scheduler to hold on to for you.
6056e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams         */
6063d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams        public Builder setExtras(PersistableBundle extras) {
6076e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams            mExtras = extras;
6086e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams            return this;
6096e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams        }
6106e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams
6116e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams        /**
612d1c06753d045ad10e00e7aba53ee2adba0712cccMatthew Williams         * Set some description of the kind of network type your job needs to have.
613d1c06753d045ad10e00e7aba53ee2adba0712cccMatthew Williams         * Not calling this function means the network is not necessary, as the default is
614d1c06753d045ad10e00e7aba53ee2adba0712cccMatthew Williams         * {@link #NETWORK_TYPE_NONE}.
6156e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams         * Bear in mind that calling this function defines network as a strict requirement for your
616d1c06753d045ad10e00e7aba53ee2adba0712cccMatthew Williams         * job. If the network requested is not available your job will never run. See
6176e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams         * {@link #setOverrideDeadline(long)} to change this behaviour.
6186e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams         */
619d1c06753d045ad10e00e7aba53ee2adba0712cccMatthew Williams        public Builder setRequiredNetworkType(int networkType) {
620d1c06753d045ad10e00e7aba53ee2adba0712cccMatthew Williams            mNetworkType = networkType;
6216e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams            return this;
6226e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams        }
6236e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams
6247060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate        /**
6257060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate         * Specify that to run this job, the device needs to be plugged in. This defaults to
6266e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams         * false.
6277060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate         * @param requiresCharging Whether or not the device is plugged in.
6286e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams         */
6296e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams        public Builder setRequiresCharging(boolean requiresCharging) {
6306e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams            mRequiresCharging = requiresCharging;
6316e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams            return this;
6326e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams        }
6336e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams
6346e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams        /**
6357060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate         * Specify that to run, the job needs the device to be in idle mode. This defaults to
6366e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams         * false.
6376e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams         * <p>Idle mode is a loose definition provided by the system, which means that the device
6386e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams         * is not in use, and has not been in use for some time. As such, it is a good time to
6397060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate         * perform resource heavy jobs. Bear in mind that battery usage will still be attributed
6406e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams         * to your application, and surfaced to the user in battery stats.</p>
6416e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams         * @param requiresDeviceIdle Whether or not the device need be within an idle maintenance
6426e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams         *                           window.
6436e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams         */
6446e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams        public Builder setRequiresDeviceIdle(boolean requiresDeviceIdle) {
6456e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams            mRequiresDeviceIdle = requiresDeviceIdle;
6466e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams            return this;
6476e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams        }
6486e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams
6496e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams        /**
6501a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn         * Add a new content: URI that will be monitored with a
6511a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn         * {@link android.database.ContentObserver}, and will cause the job to execute if changed.
6521a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn         * If you have any trigger content URIs associated with a job, it will not execute until
6531a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn         * there has been a change report for one or more of them.
6541a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn         * <p>Note that trigger URIs can not be used in combination with
6551a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn         * {@link #setPeriodic(long)} or {@link #setPersisted(boolean)}.  To continually monitor
6561a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn         * for content changes, you need to schedule a new JobInfo observing the same URIs
6571a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn         * before you finish execution of the JobService handling the most recent changes.</p>
65846499a50bf7e26c4009420aa0510432fcdc8e56eDianne Hackborn         * <p>Because because setting this property is not compatible with periodic or
65946499a50bf7e26c4009420aa0510432fcdc8e56eDianne Hackborn         * persisted jobs, doing so will throw an {@link java.lang.IllegalArgumentException} when
66046499a50bf7e26c4009420aa0510432fcdc8e56eDianne Hackborn         * {@link android.app.job.JobInfo.Builder#build()} is called.</p>
661c43a7f89f7733bbaa440545eb472f1f8aa3b5d18Dianne Hackborn         *
662c43a7f89f7733bbaa440545eb472f1f8aa3b5d18Dianne Hackborn         * <p>The following example shows how this feature can be used to monitor for changes
663c43a7f89f7733bbaa440545eb472f1f8aa3b5d18Dianne Hackborn         * in the photos on a device.</p>
664c43a7f89f7733bbaa440545eb472f1f8aa3b5d18Dianne Hackborn         *
665c43a7f89f7733bbaa440545eb472f1f8aa3b5d18Dianne Hackborn         * {@sample development/samples/ApiDemos/src/com/example/android/apis/content/PhotosContentJob.java
666c43a7f89f7733bbaa440545eb472f1f8aa3b5d18Dianne Hackborn         *      job}
667c43a7f89f7733bbaa440545eb472f1f8aa3b5d18Dianne Hackborn         *
6681a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn         * @param uri The content: URI to monitor.
6691a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn         */
6701a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn        public Builder addTriggerContentUri(@NonNull TriggerContentUri uri) {
6711a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn            if (mTriggerContentUris == null) {
6721a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn                mTriggerContentUris = new ArrayList<>();
6731a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn            }
6741a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn            mTriggerContentUris.add(uri);
6751a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn            return this;
6761a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn        }
6771a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn
6781a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn        /**
6798db0fc15b85c6501a0418b17edee2d9c447b408aDianne Hackborn         * Set the delay (in milliseconds) from when a content change is detected until
6808db0fc15b85c6501a0418b17edee2d9c447b408aDianne Hackborn         * the job is scheduled.  If there are more changes during that time, the delay
6818db0fc15b85c6501a0418b17edee2d9c447b408aDianne Hackborn         * will be reset to start at the time of the most recent change.
6828db0fc15b85c6501a0418b17edee2d9c447b408aDianne Hackborn         * @param durationMs Delay after most recent content change, in milliseconds.
6838db0fc15b85c6501a0418b17edee2d9c447b408aDianne Hackborn         */
6848db0fc15b85c6501a0418b17edee2d9c447b408aDianne Hackborn        public Builder setTriggerContentUpdateDelay(long durationMs) {
6858db0fc15b85c6501a0418b17edee2d9c447b408aDianne Hackborn            mTriggerContentUpdateDelay = durationMs;
6868db0fc15b85c6501a0418b17edee2d9c447b408aDianne Hackborn            return this;
6878db0fc15b85c6501a0418b17edee2d9c447b408aDianne Hackborn        }
6888db0fc15b85c6501a0418b17edee2d9c447b408aDianne Hackborn
6898db0fc15b85c6501a0418b17edee2d9c447b408aDianne Hackborn        /**
6908db0fc15b85c6501a0418b17edee2d9c447b408aDianne Hackborn         * Set the maximum total delay (in milliseconds) that is allowed from the first
6918db0fc15b85c6501a0418b17edee2d9c447b408aDianne Hackborn         * time a content change is detected until the job is scheduled.
6928db0fc15b85c6501a0418b17edee2d9c447b408aDianne Hackborn         * @param durationMs Delay after initial content change, in milliseconds.
6938db0fc15b85c6501a0418b17edee2d9c447b408aDianne Hackborn         */
6948db0fc15b85c6501a0418b17edee2d9c447b408aDianne Hackborn        public Builder setTriggerContentMaxDelay(long durationMs) {
6958db0fc15b85c6501a0418b17edee2d9c447b408aDianne Hackborn            mTriggerContentMaxDelay = durationMs;
6968db0fc15b85c6501a0418b17edee2d9c447b408aDianne Hackborn            return this;
6978db0fc15b85c6501a0418b17edee2d9c447b408aDianne Hackborn        }
6988db0fc15b85c6501a0418b17edee2d9c447b408aDianne Hackborn
6998db0fc15b85c6501a0418b17edee2d9c447b408aDianne Hackborn        /**
7007060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate         * Specify that this job should recur with the provided interval, not more than once per
7017060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate         * period. You have no control over when within this interval this job will be executed,
7026e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams         * only the guarantee that it will be executed at most once within this interval.
7036e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams         * Setting this function on the builder with {@link #setMinimumLatency(long)} or
7046e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams         * {@link #setOverrideDeadline(long)} will result in an error.
7057060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate         * @param intervalMillis Millisecond interval for which this job will repeat.
7066e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams         */
7076e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams        public Builder setPeriodic(long intervalMillis) {
70889ee618280ea05e193afab38f9d2bf99b8274a92Shreyas Basarge            return setPeriodic(intervalMillis, intervalMillis);
70989ee618280ea05e193afab38f9d2bf99b8274a92Shreyas Basarge        }
71089ee618280ea05e193afab38f9d2bf99b8274a92Shreyas Basarge
71189ee618280ea05e193afab38f9d2bf99b8274a92Shreyas Basarge        /**
71289ee618280ea05e193afab38f9d2bf99b8274a92Shreyas Basarge         * Specify that this job should recur with the provided interval and flex. The job can
71389ee618280ea05e193afab38f9d2bf99b8274a92Shreyas Basarge         * execute at any time in a window of flex length at the end of the period.
714e96c3b7eff5290f2a6c5e572babbfa8a3897be96Shreyas Basarge         * @param intervalMillis Millisecond interval for which this job will repeat. A minimum
715a9b4f3f628959eac8f853f1c87a93c5ed6530decChristopher Tate         *                       value of {@link #getMinPeriodMillis()} is enforced.
71689ee618280ea05e193afab38f9d2bf99b8274a92Shreyas Basarge         * @param flexMillis Millisecond flex for this job. Flex is clamped to be at least
717a9b4f3f628959eac8f853f1c87a93c5ed6530decChristopher Tate         *                   {@link #getMinFlexMillis()} or 5 percent of the period, whichever is
71889ee618280ea05e193afab38f9d2bf99b8274a92Shreyas Basarge         *                   higher.
71989ee618280ea05e193afab38f9d2bf99b8274a92Shreyas Basarge         */
72089ee618280ea05e193afab38f9d2bf99b8274a92Shreyas Basarge        public Builder setPeriodic(long intervalMillis, long flexMillis) {
7216e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams            mIsPeriodic = true;
7226e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams            mIntervalMillis = intervalMillis;
72389ee618280ea05e193afab38f9d2bf99b8274a92Shreyas Basarge            mFlexMillis = flexMillis;
7249b9244b6941110ea2d940d9fc8eed0cdff96a016Matthew Williams            mHasEarlyConstraint = mHasLateConstraint = true;
7256e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams            return this;
7266e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams        }
7276e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams
7286e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams        /**
7297060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate         * Specify that this job should be delayed by the provided amount of time.
7307060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate         * Because it doesn't make sense setting this property on a periodic job, doing so will
7316e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams         * throw an {@link java.lang.IllegalArgumentException} when
7327060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate         * {@link android.app.job.JobInfo.Builder#build()} is called.
7337060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate         * @param minLatencyMillis Milliseconds before which this job will not be considered for
7346e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams         *                         execution.
7356e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams         */
7366e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams        public Builder setMinimumLatency(long minLatencyMillis) {
7376e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams            mMinLatencyMillis = minLatencyMillis;
7389b9244b6941110ea2d940d9fc8eed0cdff96a016Matthew Williams            mHasEarlyConstraint = true;
7396e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams            return this;
7406e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams        }
7416e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams
7426e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams        /**
7437060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate         * Set deadline which is the maximum scheduling latency. The job will be run by this
7446e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams         * deadline even if other requirements are not met. Because it doesn't make sense setting
7457060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate         * this property on a periodic job, doing so will throw an
7466e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams         * {@link java.lang.IllegalArgumentException} when
7477060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate         * {@link android.app.job.JobInfo.Builder#build()} is called.
7486e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams         */
7496e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams        public Builder setOverrideDeadline(long maxExecutionDelayMillis) {
7506e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams            mMaxExecutionDelayMillis = maxExecutionDelayMillis;
7519b9244b6941110ea2d940d9fc8eed0cdff96a016Matthew Williams            mHasLateConstraint = true;
7526e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams            return this;
7536e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams        }
7546e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams
7556e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams        /**
7566e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams         * Set up the back-off/retry policy.
757d1c06753d045ad10e00e7aba53ee2adba0712cccMatthew Williams         * This defaults to some respectable values: {30 seconds, Exponential}. We cap back-off at
758d1c06753d045ad10e00e7aba53ee2adba0712cccMatthew Williams         * 5hrs.
7597060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate         * Note that trying to set a backoff criteria for a job with
7606e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams         * {@link #setRequiresDeviceIdle(boolean)} will throw an exception when you call build().
7617060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate         * This is because back-off typically does not make sense for these types of jobs. See
7627060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate         * {@link android.app.job.JobService#jobFinished(android.app.job.JobParameters, boolean)}
7637060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate         * for more description of the return value for the case of a job executing while in idle
7646e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams         * mode.
7657060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate         * @param initialBackoffMillis Millisecond time interval to wait initially when job has
7666e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams         *                             failed.
767d1c06753d045ad10e00e7aba53ee2adba0712cccMatthew Williams         * @param backoffPolicy is one of {@link #BACKOFF_POLICY_LINEAR} or
768d1c06753d045ad10e00e7aba53ee2adba0712cccMatthew Williams         * {@link #BACKOFF_POLICY_EXPONENTIAL}
7696e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams         */
7706e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams        public Builder setBackoffCriteria(long initialBackoffMillis, int backoffPolicy) {
7716e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams            mBackoffPolicySet = true;
7726e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams            mInitialBackoffMillis = initialBackoffMillis;
7736e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams            mBackoffPolicy = backoffPolicy;
7746e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams            return this;
7756e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams        }
7766e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams
7776e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams        /**
778900c67fc51fc2672458dd1c9641250f2ecc01a31Matthew Williams         * Set whether or not to persist this job across device reboots. This will only have an
779900c67fc51fc2672458dd1c9641250f2ecc01a31Matthew Williams         * effect if your application holds the permission
780900c67fc51fc2672458dd1c9641250f2ecc01a31Matthew Williams         * {@link android.Manifest.permission#RECEIVE_BOOT_COMPLETED}. Otherwise an exception will
781900c67fc51fc2672458dd1c9641250f2ecc01a31Matthew Williams         * be thrown.
782900c67fc51fc2672458dd1c9641250f2ecc01a31Matthew Williams         * @param isPersisted True to indicate that the job will be written to disk and loaded at
783900c67fc51fc2672458dd1c9641250f2ecc01a31Matthew Williams         *                    boot.
784900c67fc51fc2672458dd1c9641250f2ecc01a31Matthew Williams         */
785d1c06753d045ad10e00e7aba53ee2adba0712cccMatthew Williams        public Builder setPersisted(boolean isPersisted) {
786900c67fc51fc2672458dd1c9641250f2ecc01a31Matthew Williams            mIsPersisted = isPersisted;
787900c67fc51fc2672458dd1c9641250f2ecc01a31Matthew Williams            return this;
788900c67fc51fc2672458dd1c9641250f2ecc01a31Matthew Williams        }
789900c67fc51fc2672458dd1c9641250f2ecc01a31Matthew Williams
790900c67fc51fc2672458dd1c9641250f2ecc01a31Matthew Williams        /**
7917060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate         * @return The job object to hand to the JobScheduler. This object is immutable.
7926e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams         */
7937060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate        public JobInfo build() {
7949ae3dbeefcd6bc139c74bfe3d51de823e3be4b4bMatthew Williams            // Allow jobs with no constraints - What am I, a database?
795bafeeb98135a7580cbcdd657818cd78f7bda35d8Matthew Williams            if (!mHasEarlyConstraint && !mHasLateConstraint && !mRequiresCharging &&
7961a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn                    !mRequiresDeviceIdle && mNetworkType == NETWORK_TYPE_NONE &&
7971a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn                    mTriggerContentUris == null) {
798bafeeb98135a7580cbcdd657818cd78f7bda35d8Matthew Williams                throw new IllegalArgumentException("You're trying to build a job with no " +
799bafeeb98135a7580cbcdd657818cd78f7bda35d8Matthew Williams                        "constraints, this is not allowed.");
800bafeeb98135a7580cbcdd657818cd78f7bda35d8Matthew Williams            }
8013d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams            mExtras = new PersistableBundle(mExtras);  // Make our own copy.
8027060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate            // Check that a deadline was not set on a periodic job.
8033d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams            if (mIsPeriodic && (mMaxExecutionDelayMillis != 0L)) {
8046e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams                throw new IllegalArgumentException("Can't call setOverrideDeadline() on a " +
8057060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate                        "periodic job.");
8066e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams            }
8073d86fd2bb9db6067c49634bc4c6cdb4d5235ad36Matthew Williams            if (mIsPeriodic && (mMinLatencyMillis != 0L)) {
8086e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams                throw new IllegalArgumentException("Can't call setMinimumLatency() on a " +
8097060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate                        "periodic job");
8106e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams            }
8111a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn            if (mIsPeriodic && (mTriggerContentUris != null)) {
8121a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn                throw new IllegalArgumentException("Can't call addTriggerContentUri() on a " +
8131a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn                        "periodic job");
8141a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn            }
8151a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn            if (mIsPersisted && (mTriggerContentUris != null)) {
8161a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn                throw new IllegalArgumentException("Can't call addTriggerContentUri() on a " +
8171a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn                        "persisted job");
8181a30bd9b13fd127d9bbfdc5fd4cb2f80ab7ece21Dianne Hackborn            }
8196e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams            if (mBackoffPolicySet && mRequiresDeviceIdle) {
8207060b04f6d92351b67222e636ab378a0273bf3e7Christopher Tate                throw new IllegalArgumentException("An idle mode job will not respect any" +
8216e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams                        " back-off policy, so calling setBackoffCriteria with" +
8226e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams                        " setRequiresDeviceIdle is an error.");
8236e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams            }
824e96c3b7eff5290f2a6c5e572babbfa8a3897be96Shreyas Basarge            JobInfo job = new JobInfo(this);
825b0c83ec062016ae1b0abc05dc96576701cc6bfd3Shreyas Basarge            if (job.isPeriodic()) {
826b0c83ec062016ae1b0abc05dc96576701cc6bfd3Shreyas Basarge                if (job.intervalMillis != job.getIntervalMillis()) {
827b0c83ec062016ae1b0abc05dc96576701cc6bfd3Shreyas Basarge                    StringBuilder builder = new StringBuilder();
828b0c83ec062016ae1b0abc05dc96576701cc6bfd3Shreyas Basarge                    builder.append("Specified interval for ")
829b0c83ec062016ae1b0abc05dc96576701cc6bfd3Shreyas Basarge                            .append(String.valueOf(mJobId))
830b0c83ec062016ae1b0abc05dc96576701cc6bfd3Shreyas Basarge                            .append(" is ");
831b0c83ec062016ae1b0abc05dc96576701cc6bfd3Shreyas Basarge                    formatDuration(mIntervalMillis, builder);
832b0c83ec062016ae1b0abc05dc96576701cc6bfd3Shreyas Basarge                    builder.append(". Clamped to ");
833b0c83ec062016ae1b0abc05dc96576701cc6bfd3Shreyas Basarge                    formatDuration(job.getIntervalMillis(), builder);
834b0c83ec062016ae1b0abc05dc96576701cc6bfd3Shreyas Basarge                    Log.w(TAG, builder.toString());
835b0c83ec062016ae1b0abc05dc96576701cc6bfd3Shreyas Basarge                }
836b0c83ec062016ae1b0abc05dc96576701cc6bfd3Shreyas Basarge                if (job.flexMillis != job.getFlexMillis()) {
837b0c83ec062016ae1b0abc05dc96576701cc6bfd3Shreyas Basarge                    StringBuilder builder = new StringBuilder();
838b0c83ec062016ae1b0abc05dc96576701cc6bfd3Shreyas Basarge                    builder.append("Specified flex for ")
839b0c83ec062016ae1b0abc05dc96576701cc6bfd3Shreyas Basarge                            .append(String.valueOf(mJobId))
840b0c83ec062016ae1b0abc05dc96576701cc6bfd3Shreyas Basarge                            .append(" is ");
841b0c83ec062016ae1b0abc05dc96576701cc6bfd3Shreyas Basarge                    formatDuration(mFlexMillis, builder);
842b0c83ec062016ae1b0abc05dc96576701cc6bfd3Shreyas Basarge                    builder.append(". Clamped to ");
843b0c83ec062016ae1b0abc05dc96576701cc6bfd3Shreyas Basarge                    formatDuration(job.getFlexMillis(), builder);
844b0c83ec062016ae1b0abc05dc96576701cc6bfd3Shreyas Basarge                    Log.w(TAG, builder.toString());
845b0c83ec062016ae1b0abc05dc96576701cc6bfd3Shreyas Basarge                }
846e96c3b7eff5290f2a6c5e572babbfa8a3897be96Shreyas Basarge            }
847e96c3b7eff5290f2a6c5e572babbfa8a3897be96Shreyas Basarge            return job;
8486e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams        }
8496e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams    }
8506e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams
8516e31c5c82bc5c9bddf9c01d254067ea5bebbd96bMatthew Williams}
852