OSDN Git Service

Provide explicit Network via JobParameters.
authorJeff Sharkey <jsharkey@android.com>
Tue, 24 Oct 2017 22:55:04 +0000 (16:55 -0600)
committerJeff Sharkey <jsharkey@android.com>
Wed, 25 Oct 2017 17:23:22 +0000 (11:23 -0600)
On devices with multiple active networks, or rapidly switching
between networks, we need an API to tell jobs explicitly which
network to use.  (For example, the default route could meet all
job criteria, but we could have changed the default network by the
time we spun up the JobService.)

This also paves the way for us choosing to run jobs over
non-default networks.

Test: verified via DownloadManager
Bug: 64133169
Change-Id: Ic8d654707e39236c8da85a5e172161ac39e5f0b3

api/current.txt
api/system-current.txt
api/test-current.txt
core/java/android/app/job/JobInfo.java
core/java/android/app/job/JobParameters.java
services/core/java/com/android/server/job/JobServiceContext.java
services/core/java/com/android/server/job/controllers/ConnectivityController.java
services/core/java/com/android/server/job/controllers/JobStatus.java

index 8b3c740..eca3a8b 100644 (file)
@@ -6899,6 +6899,7 @@ package android.app.job {
     method public int getClipGrantFlags();
     method public android.os.PersistableBundle getExtras();
     method public int getJobId();
+    method public android.net.Network getNetwork();
     method public android.os.Bundle getTransientExtras();
     method public java.lang.String[] getTriggeredContentAuthorities();
     method public android.net.Uri[] getTriggeredContentUris();
@@ -52072,7 +52073,6 @@ package android.widget {
     method public android.graphics.Typeface getTypeface();
     method public android.text.style.URLSpan[] getUrls();
     method public boolean hasSelection();
-    method public void invalidate(int, int, int, int);
     method public boolean isAllCaps();
     method public boolean isCursorVisible();
     method public boolean isElegantTextHeight();
index ee23b6d..6d828e3 100644 (file)
@@ -7341,6 +7341,7 @@ package android.app.job {
     method public int getClipGrantFlags();
     method public android.os.PersistableBundle getExtras();
     method public int getJobId();
+    method public android.net.Network getNetwork();
     method public android.os.Bundle getTransientExtras();
     method public java.lang.String[] getTriggeredContentAuthorities();
     method public android.net.Uri[] getTriggeredContentUris();
@@ -56176,7 +56177,6 @@ package android.widget {
     method public android.graphics.Typeface getTypeface();
     method public android.text.style.URLSpan[] getUrls();
     method public boolean hasSelection();
-    method public void invalidate(int, int, int, int);
     method public boolean isAllCaps();
     method public boolean isCursorVisible();
     method public boolean isElegantTextHeight();
index 9a241ad..954cb48 100644 (file)
@@ -6970,6 +6970,7 @@ package android.app.job {
     method public int getClipGrantFlags();
     method public android.os.PersistableBundle getExtras();
     method public int getJobId();
+    method public android.net.Network getNetwork();
     method public android.os.Bundle getTransientExtras();
     method public java.lang.String[] getTriggeredContentAuthorities();
     method public android.net.Uri[] getTriggeredContentUris();
@@ -52680,7 +52681,6 @@ package android.widget {
     method public android.graphics.Typeface getTypeface();
     method public android.text.style.URLSpan[] getUrls();
     method public boolean hasSelection();
-    method public void invalidate(int, int, int, int);
     method public boolean isAllCaps();
     method public boolean isCursorVisible();
     method public boolean isElegantTextHeight();
index 1434c9b..1cde73a 100644 (file)
@@ -909,12 +909,21 @@ public class JobInfo implements Parcelable {
         }
 
         /**
-         * Set some description of the kind of network type your job needs to have.
-         * Not calling this function means the network is not necessary, as the default is
-         * {@link #NETWORK_TYPE_NONE}.
-         * Bear in mind that calling this function 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 behaviour.
+         * Set some description of the kind of network type your job needs to
+         * have. Not calling this function means the network is not necessary,
+         * as the default is {@link #NETWORK_TYPE_NONE}. Bear in mind that
+         * calling this function 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
+         * behaviour.
+         * <p class="note">
+         * 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 JobParameters#getNetwork()
          */
         public Builder setRequiredNetworkType(@NetworkType int networkType) {
             mNetworkType = networkType;
index a6f6be2..5053dc6 100644 (file)
@@ -20,6 +20,7 @@ import android.annotation.NonNull;
 import android.annotation.Nullable;
 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;
@@ -66,6 +67,7 @@ public class JobParameters implements Parcelable {
     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
 
@@ -73,7 +75,7 @@ public class JobParameters implements Parcelable {
     public JobParameters(IBinder callback, int jobId, PersistableBundle extras,
             Bundle transientExtras, ClipData clipData, int clipGrantFlags,
             boolean overrideDeadlineExpired, Uri[] triggeredContentUris,
-            String[] triggeredContentAuthorities) {
+            String[] triggeredContentAuthorities, Network network) {
         this.jobId = jobId;
         this.extras = extras;
         this.transientExtras = transientExtras;
@@ -83,6 +85,7 @@ public class JobParameters implements Parcelable {
         this.overrideDeadlineExpired = overrideDeadlineExpired;
         this.mTriggeredContentUris = triggeredContentUris;
         this.mTriggeredContentAuthorities = triggeredContentAuthorities;
+        this.network = network;
     }
 
     /**
@@ -171,6 +174,28 @@ public class JobParameters implements Parcelable {
     }
 
     /**
+     * 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
@@ -257,6 +282,11 @@ public class JobParameters implements Parcelable {
         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();
     }
 
@@ -286,6 +316,12 @@ public class JobParameters implements Parcelable {
         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);
     }
 
index d3fd3a9..ae01c43 100644 (file)
@@ -216,7 +216,7 @@ public final class JobServiceContext implements ServiceConnection {
             final JobInfo ji = job.getJob();
             mParams = new JobParameters(mRunningCallback, job.getJobId(), ji.getExtras(),
                     ji.getTransientExtras(), ji.getClipData(), ji.getClipGrantFlags(),
-                    isDeadlineExpired, triggeredUris, triggeredAuthorities);
+                    isDeadlineExpired, triggeredUris, triggeredAuthorities, job.network);
             mExecutionStartTimeElapsed = SystemClock.elapsedRealtime();
 
             // Once we'e begun executing a job, we by definition no longer care whether
index 78367fe..c928c07 100644 (file)
@@ -125,6 +125,11 @@ public final class ConnectivityController extends StateController implements
         changed |= jobStatus.setUnmeteredConstraintSatisfied(unmetered);
         changed |= jobStatus.setNotRoamingConstraintSatisfied(notRoaming);
 
+        // Pass along the evaluated network for job to use; prevents race
+        // conditions as default routes change over time, and opens the door to
+        // using non-default routes.
+        jobStatus.network = network;
+
         // Track system-uid connected/validated as a general reportable proxy for the
         // overall state of connectivity constraint satisfiability.
         if (jobUid == Process.SYSTEM_UID) {
index 23caa8c..1a27c0a 100644 (file)
@@ -22,6 +22,7 @@ import android.app.job.JobInfo;
 import android.app.job.JobWorkItem;
 import android.content.ClipData;
 import android.content.ComponentName;
+import android.net.Network;
 import android.net.Uri;
 import android.os.RemoteException;
 import android.os.SystemClock;
@@ -167,6 +168,7 @@ public final class JobStatus {
     // These are filled in by controllers when preparing for execution.
     public ArraySet<Uri> changedUris;
     public ArraySet<String> changedAuthorities;
+    public Network network;
 
     public int lastEvaluatedPriority;
 
@@ -1101,6 +1103,9 @@ public final class JobStatus {
                 }
             }
         }
+        if (network != null) {
+            pw.print(prefix); pw.print("Network: "); pw.println(network);
+        }
         if (pendingWork != null && pendingWork.size() > 0) {
             pw.print(prefix); pw.println("Pending work:");
             for (int i = 0; i < pendingWork.size(); i++) {