summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Jeff Sharkey <jsharkey@google.com> 2016-04-29 22:53:20 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2016-04-29 22:53:22 +0000
commit9a977b7d45df0d3d59c5eec7f9534c3bd5fcd91d (patch)
treed95d0ffca6cd4a7e4883374a94665d4d7cc6a2e1
parent8e060d31d14163858e55b412f0490b19b2f44dd1 (diff)
parent1b6519bd87a59a10e9928e5772a17976692611da (diff)
Merge "Flag to mark foreground jobs, fix data saver." into nyc-dev
-rw-r--r--core/java/android/app/job/JobInfo.java37
-rw-r--r--core/java/android/net/ConnectivityManager.java21
-rw-r--r--core/java/android/net/IConnectivityManager.aidl6
-rw-r--r--core/java/android/net/INetworkPolicyManager.aidl3
-rw-r--r--services/core/java/com/android/server/ConnectivityService.java109
-rw-r--r--services/core/java/com/android/server/job/JobStore.java5
-rw-r--r--services/core/java/com/android/server/job/controllers/ConnectivityController.java5
-rw-r--r--services/core/java/com/android/server/job/controllers/JobStatus.java23
-rw-r--r--services/core/java/com/android/server/net/NetworkPolicyManagerService.java108
9 files changed, 229 insertions, 88 deletions
diff --git a/core/java/android/app/job/JobInfo.java b/core/java/android/app/job/JobInfo.java
index ecfc527cb7f3..c47557501b64 100644
--- a/core/java/android/app/job/JobInfo.java
+++ b/core/java/android/app/job/JobInfo.java
@@ -16,6 +16,8 @@
package android.app.job;
+import static android.util.TimeUtils.formatDuration;
+
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.ComponentName;
@@ -24,7 +26,6 @@ import android.os.Parcel;
import android.os.Parcelable;
import android.os.PersistableBundle;
import android.util.Log;
-import static android.util.TimeUtils.formatDuration;
import java.util.ArrayList;
@@ -154,6 +155,20 @@ public class JobInfo implements Parcelable {
*/
public static final int PRIORITY_ADJ_ALWAYS_RUNNING = -80;
+ /**
+ * Indicates that the implementation of this job will be using
+ * {@link JobService#startForeground(int, android.app.Notification)} to run
+ * in the foreground.
+ * <p>
+ * When set, the internal scheduling of this job will ignore any background
+ * network restrictions for the requesting app. Note that this flag alone
+ * doesn't actually place your {@link JobService} in the foreground; you
+ * still need to post the notification yourself.
+ *
+ * @hide
+ */
+ public static final int FLAG_WILL_BE_FOREGROUND = 1 << 0;
+
private final int jobId;
private final PersistableBundle extras;
private final ComponentName service;
@@ -174,6 +189,7 @@ public class JobInfo implements Parcelable {
private final long initialBackoffMillis;
private final int backoffPolicy;
private final int priority;
+ private final int flags;
/**
* Unique job id associated with this class. This is assigned to your job by the scheduler.
@@ -201,6 +217,11 @@ public class JobInfo implements Parcelable {
return priority;
}
+ /** @hide */
+ public int getFlags() {
+ return flags;
+ }
+
/**
* Whether this job needs the device to be plugged in.
*/
@@ -356,6 +377,7 @@ public class JobInfo implements Parcelable {
hasEarlyConstraint = in.readInt() == 1;
hasLateConstraint = in.readInt() == 1;
priority = in.readInt();
+ flags = in.readInt();
}
private JobInfo(JobInfo.Builder b) {
@@ -381,6 +403,7 @@ public class JobInfo implements Parcelable {
hasEarlyConstraint = b.mHasEarlyConstraint;
hasLateConstraint = b.mHasLateConstraint;
priority = b.mPriority;
+ flags = b.mFlags;
}
@Override
@@ -410,6 +433,7 @@ public class JobInfo implements Parcelable {
out.writeInt(hasEarlyConstraint ? 1 : 0);
out.writeInt(hasLateConstraint ? 1 : 0);
out.writeInt(priority);
+ out.writeInt(this.flags);
}
public static final Creator<JobInfo> CREATOR = new Creator<JobInfo>() {
@@ -504,6 +528,7 @@ public class JobInfo implements Parcelable {
private PersistableBundle mExtras = PersistableBundle.EMPTY;
private ComponentName mJobService;
private int mPriority = PRIORITY_DEFAULT;
+ private int mFlags;
// Requirements.
private boolean mRequiresCharging;
private boolean mRequiresDeviceIdle;
@@ -539,14 +564,18 @@ public class JobInfo implements Parcelable {
mJobId = jobId;
}
- /**
- * @hide
- */
+ /** @hide */
public Builder setPriority(int priority) {
mPriority = priority;
return this;
}
+ /** @hide */
+ public Builder setFlags(int flags) {
+ mFlags = flags;
+ return this;
+ }
+
/**
* Set optional extras. This is persisted, so we only allow primitive types.
* @param extras Bundle containing extras you want the scheduler to hold on to for you.
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index faf5c64e5a00..933dddf4a948 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -774,8 +774,13 @@ public class ConnectivityManager {
* @hide
*/
public Network getActiveNetworkForUid(int uid) {
+ return getActiveNetworkForUid(uid, false);
+ }
+
+ /** {@hide} */
+ public Network getActiveNetworkForUid(int uid, boolean ignoreBlocked) {
try {
- return mService.getActiveNetworkForUid(uid);
+ return mService.getActiveNetworkForUid(uid, ignoreBlocked);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -836,8 +841,13 @@ public class ConnectivityManager {
* {@hide}
*/
public NetworkInfo getActiveNetworkInfoForUid(int uid) {
+ return getActiveNetworkInfoForUid(uid, false);
+ }
+
+ /** {@hide} */
+ public NetworkInfo getActiveNetworkInfoForUid(int uid, boolean ignoreBlocked) {
try {
- return mService.getActiveNetworkInfoForUid(uid);
+ return mService.getActiveNetworkInfoForUid(uid, ignoreBlocked);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -880,8 +890,13 @@ public class ConnectivityManager {
* is not valid.
*/
public NetworkInfo getNetworkInfo(Network network) {
+ return getNetworkInfoForUid(network, Process.myUid(), false);
+ }
+
+ /** {@hide} */
+ public NetworkInfo getNetworkInfoForUid(Network network, int uid, boolean ignoreBlocked) {
try {
- return mService.getNetworkInfoForNetwork(network);
+ return mService.getNetworkInfoForUid(network, uid, ignoreBlocked);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl
index c897c4506c1f..aec6b3ec23fe 100644
--- a/core/java/android/net/IConnectivityManager.aidl
+++ b/core/java/android/net/IConnectivityManager.aidl
@@ -44,11 +44,11 @@ import com.android.internal.net.VpnProfile;
interface IConnectivityManager
{
Network getActiveNetwork();
- Network getActiveNetworkForUid(int uid);
+ Network getActiveNetworkForUid(int uid, boolean ignoreBlocked);
NetworkInfo getActiveNetworkInfo();
- NetworkInfo getActiveNetworkInfoForUid(int uid);
+ NetworkInfo getActiveNetworkInfoForUid(int uid, boolean ignoreBlocked);
NetworkInfo getNetworkInfo(int networkType);
- NetworkInfo getNetworkInfoForNetwork(in Network network);
+ NetworkInfo getNetworkInfoForUid(in Network network, int uid, boolean ignoreBlocked);
NetworkInfo[] getAllNetworkInfo();
Network getNetworkForType(int networkType);
Network[] getAllNetworks();
diff --git a/core/java/android/net/INetworkPolicyManager.aidl b/core/java/android/net/INetworkPolicyManager.aidl
index 2b8b28d91bd0..224ff5b395c7 100644
--- a/core/java/android/net/INetworkPolicyManager.aidl
+++ b/core/java/android/net/INetworkPolicyManager.aidl
@@ -38,6 +38,9 @@ interface INetworkPolicyManager {
boolean isUidForeground(int uid);
+ /** Higher priority listener before general event dispatch */
+ void setConnectivityListener(INetworkPolicyListener listener);
+
void registerListener(INetworkPolicyListener listener);
void unregisterListener(INetworkPolicyListener listener);
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index d85827e99079..f5e9d1968eb8 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -29,8 +29,12 @@ import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
import static android.net.NetworkPolicyManager.RULE_ALLOW_ALL;
+import static android.net.NetworkPolicyManager.RULE_ALLOW_METERED;
import static android.net.NetworkPolicyManager.RULE_REJECT_ALL;
import static android.net.NetworkPolicyManager.RULE_REJECT_METERED;
+import static android.net.NetworkPolicyManager.RULE_TEMPORARY_ALLOW_METERED;
+import static android.net.NetworkPolicyManager.RULE_UNKNOWN;
+
import android.annotation.Nullable;
import android.app.BroadcastOptions;
import android.app.Notification;
@@ -96,8 +100,10 @@ import android.security.Credentials;
import android.security.KeyStore;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
+import android.util.ArraySet;
import android.util.LocalLog;
import android.util.LocalLog.ReadOnlyLocalLog;
+import android.util.Log;
import android.util.Pair;
import android.util.Slog;
import android.util.SparseArray;
@@ -121,9 +127,9 @@ import com.android.internal.util.XmlUtils;
import com.android.server.am.BatteryStatsService;
import com.android.server.connectivity.DataConnectionStats;
import com.android.server.connectivity.KeepaliveTracker;
-import com.android.server.connectivity.NetworkDiagnostics;
import com.android.server.connectivity.Nat464Xlat;
import com.android.server.connectivity.NetworkAgentInfo;
+import com.android.server.connectivity.NetworkDiagnostics;
import com.android.server.connectivity.NetworkMonitor;
import com.android.server.connectivity.PacManager;
import com.android.server.connectivity.PermissionMonitor;
@@ -131,8 +137,8 @@ import com.android.server.connectivity.Tethering;
import com.android.server.connectivity.Vpn;
import com.android.server.net.BaseNetworkObserver;
import com.android.server.net.LockdownVpnTracker;
+
import com.google.android.collect.Lists;
-import com.google.android.collect.Sets;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
@@ -152,11 +158,11 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
-import java.util.SortedSet;
-import java.util.TreeSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
+import java.util.SortedSet;
+import java.util.TreeSet;
/**
* @hide
@@ -202,9 +208,14 @@ public class ConnectivityService extends IConnectivityManager.Stub
/** Lock around {@link #mUidRules} and {@link #mMeteredIfaces}. */
private Object mRulesLock = new Object();
/** Currently active network rules by UID. */
+ @GuardedBy("mRulesLock")
private SparseIntArray mUidRules = new SparseIntArray();
/** Set of ifaces that are costly. */
- private HashSet<String> mMeteredIfaces = Sets.newHashSet();
+ @GuardedBy("mRulesLock")
+ private ArraySet<String> mMeteredIfaces = new ArraySet<>();
+ /** Flag indicating if background data is restricted. */
+ @GuardedBy("mRulesLock")
+ private boolean mRestrictBackground;
final private Context mContext;
private int mNetworkPreference;
@@ -651,7 +662,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
mTelephonyManager = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
try {
- mPolicyManager.registerListener(mPolicyListener);
+ mPolicyManager.setConnectivityListener(mPolicyListener);
+ mRestrictBackground = mPolicyManager.getRestrictBackground();
} catch (RemoteException e) {
// ouch, no rules updates means some processes may never get network
loge("unable to register INetworkPolicyListener" + e.toString());
@@ -819,7 +831,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
throw new IllegalStateException("No free netIds");
}
- private NetworkState getFilteredNetworkState(int networkType, int uid) {
+ private NetworkState getFilteredNetworkState(int networkType, int uid, boolean ignoreBlocked) {
if (mLegacyTypeTracker.isTypeSupported(networkType)) {
final NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType);
final NetworkState state;
@@ -834,7 +846,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
state = new NetworkState(info, new LinkProperties(), new NetworkCapabilities(),
null, null, null);
}
- filterNetworkStateForUid(state, uid);
+ filterNetworkStateForUid(state, uid, ignoreBlocked);
return state;
} else {
return NetworkState.EMPTY;
@@ -890,22 +902,36 @@ public class ConnectivityService extends IConnectivityManager.Stub
/**
* Check if UID should be blocked from using the network with the given LinkProperties.
*/
- private boolean isNetworkWithLinkPropertiesBlocked(LinkProperties lp, int uid) {
- final boolean networkCostly;
+ private boolean isNetworkWithLinkPropertiesBlocked(LinkProperties lp, int uid,
+ boolean ignoreBlocked) {
+ // Networks aren't blocked when ignoring blocked status
+ if (ignoreBlocked) return false;
+ // Networks are never blocked for system services
+ if (uid < Process.FIRST_APPLICATION_UID) return false;
+
+ final boolean networkMetered;
final int uidRules;
final String iface = (lp == null ? "" : lp.getInterfaceName());
synchronized (mRulesLock) {
- networkCostly = mMeteredIfaces.contains(iface);
- uidRules = mUidRules.get(uid, RULE_ALLOW_ALL);
+ networkMetered = mMeteredIfaces.contains(iface);
+ uidRules = mUidRules.get(uid, RULE_UNKNOWN);
}
- if (uidRules == RULE_REJECT_ALL) {
- return true;
- } else if ((uidRules == RULE_REJECT_METERED) && networkCostly) {
- return true;
- } else {
- return false;
+ switch (uidRules) {
+ case RULE_ALLOW_ALL:
+ case RULE_ALLOW_METERED:
+ case RULE_TEMPORARY_ALLOW_METERED:
+ return false;
+ case RULE_REJECT_METERED:
+ return networkMetered;
+ case RULE_REJECT_ALL:
+ return true;
+ case RULE_UNKNOWN:
+ default:
+ // When background data is restricted device-wide, the default
+ // behavior for apps should be like RULE_REJECT_METERED
+ return mRestrictBackground ? networkMetered : false;
}
}
@@ -930,10 +956,10 @@ public class ConnectivityService extends IConnectivityManager.Stub
* on {@link #isNetworkWithLinkPropertiesBlocked}, or
* {@link NetworkInfo#isMetered()} based on network policies.
*/
- private void filterNetworkStateForUid(NetworkState state, int uid) {
+ private void filterNetworkStateForUid(NetworkState state, int uid, boolean ignoreBlocked) {
if (state == null || state.networkInfo == null || state.linkProperties == null) return;
- if (isNetworkWithLinkPropertiesBlocked(state.linkProperties, uid)) {
+ if (isNetworkWithLinkPropertiesBlocked(state.linkProperties, uid, ignoreBlocked)) {
state.networkInfo.setDetailedState(DetailedState.BLOCKED, null, null);
}
if (mLockdownTracker != null) {
@@ -962,7 +988,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
enforceAccessPermission();
final int uid = Binder.getCallingUid();
final NetworkState state = getUnfilteredActiveNetworkState(uid);
- filterNetworkStateForUid(state, uid);
+ filterNetworkStateForUid(state, uid, false);
maybeLogBlockedNetworkInfo(state.networkInfo, uid);
return state.networkInfo;
}
@@ -970,16 +996,16 @@ public class ConnectivityService extends IConnectivityManager.Stub
@Override
public Network getActiveNetwork() {
enforceAccessPermission();
- return getActiveNetworkForUidInternal(Binder.getCallingUid());
+ return getActiveNetworkForUidInternal(Binder.getCallingUid(), false);
}
@Override
- public Network getActiveNetworkForUid(int uid) {
+ public Network getActiveNetworkForUid(int uid, boolean ignoreBlocked) {
enforceConnectivityInternalPermission();
- return getActiveNetworkForUidInternal(uid);
+ return getActiveNetworkForUidInternal(uid, ignoreBlocked);
}
- private Network getActiveNetworkForUidInternal(final int uid) {
+ private Network getActiveNetworkForUidInternal(final int uid, boolean ignoreBlocked) {
final int user = UserHandle.getUserId(uid);
int vpnNetId = NETID_UNSET;
synchronized (mVpns) {
@@ -994,7 +1020,10 @@ public class ConnectivityService extends IConnectivityManager.Stub
if (nai != null) return nai.network;
}
nai = getDefaultNetwork();
- if (nai != null && isNetworkWithLinkPropertiesBlocked(nai.linkProperties, uid)) nai = null;
+ if (nai != null
+ && isNetworkWithLinkPropertiesBlocked(nai.linkProperties, uid, ignoreBlocked)) {
+ nai = null;
+ }
return nai != null ? nai.network : null;
}
@@ -1006,10 +1035,10 @@ public class ConnectivityService extends IConnectivityManager.Stub
}
@Override
- public NetworkInfo getActiveNetworkInfoForUid(int uid) {
+ public NetworkInfo getActiveNetworkInfoForUid(int uid, boolean ignoreBlocked) {
enforceConnectivityInternalPermission();
final NetworkState state = getUnfilteredActiveNetworkState(uid);
- filterNetworkStateForUid(state, uid);
+ filterNetworkStateForUid(state, uid, ignoreBlocked);
return state.networkInfo;
}
@@ -1023,22 +1052,21 @@ public class ConnectivityService extends IConnectivityManager.Stub
// getUnfilteredActiveNetworkState.
final NetworkState state = getUnfilteredActiveNetworkState(uid);
if (state.networkInfo != null && state.networkInfo.getType() == networkType) {
- filterNetworkStateForUid(state, uid);
+ filterNetworkStateForUid(state, uid, false);
return state.networkInfo;
}
}
- final NetworkState state = getFilteredNetworkState(networkType, uid);
+ final NetworkState state = getFilteredNetworkState(networkType, uid, false);
return state.networkInfo;
}
@Override
- public NetworkInfo getNetworkInfoForNetwork(Network network) {
+ public NetworkInfo getNetworkInfoForUid(Network network, int uid, boolean ignoreBlocked) {
enforceAccessPermission();
- final int uid = Binder.getCallingUid();
final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
if (nai != null) {
final NetworkState state = nai.getNetworkState();
- filterNetworkStateForUid(state, uid);
+ filterNetworkStateForUid(state, uid, ignoreBlocked);
return state.networkInfo;
} else {
return null;
@@ -1063,8 +1091,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
public Network getNetworkForType(int networkType) {
enforceAccessPermission();
final int uid = Binder.getCallingUid();
- NetworkState state = getFilteredNetworkState(networkType, uid);
- if (!isNetworkWithLinkPropertiesBlocked(state.linkProperties, uid)) {
+ NetworkState state = getFilteredNetworkState(networkType, uid, false);
+ if (!isNetworkWithLinkPropertiesBlocked(state.linkProperties, uid, false)) {
return state.network;
}
return null;
@@ -1381,6 +1409,11 @@ public class ConnectivityService extends IConnectivityManager.Stub
if (LOGD_RULES) {
log("onRestrictBackgroundChanged(restrictBackground=" + restrictBackground + ")");
}
+
+ synchronized (mRulesLock) {
+ mRestrictBackground = restrictBackground;
+ }
+
if (restrictBackground) {
log("onRestrictBackgroundChanged(true): disabling tethering");
mTethering.untetherAll();
@@ -1824,6 +1857,10 @@ public class ConnectivityService extends IConnectivityManager.Stub
pw.decreaseIndent();
pw.println();
+ pw.print("Restrict background: ");
+ pw.println(mRestrictBackground);
+ pw.println();
+
pw.println("Network Requests:");
pw.increaseIndent();
for (NetworkRequestInfo nri : mNetworkRequests.values()) {
@@ -2765,7 +2802,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
// which isn't meant to work on uncreated networks.
if (!nai.created) return;
- if (isNetworkWithLinkPropertiesBlocked(nai.linkProperties, uid)) return;
+ if (isNetworkWithLinkPropertiesBlocked(nai.linkProperties, uid, false)) return;
nai.networkMonitor.sendMessage(NetworkMonitor.CMD_FORCE_REEVALUATION, uid);
}
diff --git a/services/core/java/com/android/server/job/JobStore.java b/services/core/java/com/android/server/job/JobStore.java
index 5ad988a42792..1f7d3128d655 100644
--- a/services/core/java/com/android/server/job/JobStore.java
+++ b/services/core/java/com/android/server/job/JobStore.java
@@ -333,6 +333,7 @@ public class JobStore {
out.attribute(null, "sourceUserId", String.valueOf(jobStatus.getSourceUserId()));
out.attribute(null, "uid", Integer.toString(jobStatus.getUid()));
out.attribute(null, "priority", String.valueOf(jobStatus.getPriority()));
+ out.attribute(null, "flags", String.valueOf(jobStatus.getFlags()));
}
private void writeBundleToXml(PersistableBundle extras, XmlSerializer out)
@@ -543,6 +544,10 @@ public class JobStore {
if (val != null) {
jobBuilder.setPriority(Integer.parseInt(val));
}
+ val = parser.getAttributeValue(null, "flags");
+ if (val != null) {
+ jobBuilder.setFlags(Integer.parseInt(val));
+ }
val = parser.getAttributeValue(null, "sourceUserId");
sourceUserId = val == null ? -1 : Integer.parseInt(val);
} catch (NumberFormatException e) {
diff --git a/services/core/java/com/android/server/job/controllers/ConnectivityController.java b/services/core/java/com/android/server/job/controllers/ConnectivityController.java
index 88cf322ed913..f5aac087f9b0 100644
--- a/services/core/java/com/android/server/job/controllers/ConnectivityController.java
+++ b/services/core/java/com/android/server/job/controllers/ConnectivityController.java
@@ -16,6 +16,7 @@
package com.android.server.job.controllers;
+import android.app.job.JobInfo;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -97,7 +98,9 @@ public class ConnectivityController extends StateController implements
}
private boolean updateConstraintsSatisfied(JobStatus jobStatus) {
- final NetworkInfo info = mConnManager.getActiveNetworkInfoForUid(jobStatus.getSourceUid());
+ final boolean ignoreBlocked = (jobStatus.getFlags() & JobInfo.FLAG_WILL_BE_FOREGROUND) != 0;
+ final NetworkInfo info = mConnManager.getActiveNetworkInfoForUid(jobStatus.getSourceUid(),
+ ignoreBlocked);
final boolean connected = (info != null) && info.isConnected();
final boolean unmetered = connected && !info.isMetered();
final boolean notRoaming = connected && !info.isRoaming();
diff --git a/services/core/java/com/android/server/job/controllers/JobStatus.java b/services/core/java/com/android/server/job/controllers/JobStatus.java
index 590d075446cf..19bede97c503 100644
--- a/services/core/java/com/android/server/job/controllers/JobStatus.java
+++ b/services/core/java/com/android/server/job/controllers/JobStatus.java
@@ -297,6 +297,10 @@ public final class JobStatus {
return job.getPriority();
}
+ public int getFlags() {
+ return job.getFlags();
+ }
+
public boolean hasConnectivityConstraint() {
return (requiredConstraints&CONSTRAINT_CONNECTIVITY) != 0;
}
@@ -416,12 +420,12 @@ public final class JobStatus {
// satisfied).
// AppNotIdle implicit constraint must be satisfied
// DeviceNotDozing implicit constraint must be satisfied
- return (isConstraintsSatisfied()
- || (!job.isPeriodic()
- && hasDeadlineConstraint() && (satisfiedConstraints&CONSTRAINT_DEADLINE) != 0)
- )
- && (satisfiedConstraints & CONSTRAINT_APP_NOT_IDLE) != 0
- && (satisfiedConstraints & CONSTRAINT_DEVICE_NOT_DOZING) != 0;
+ final boolean deadlineSatisfied = (!job.isPeriodic() && hasDeadlineConstraint()
+ && (satisfiedConstraints & CONSTRAINT_DEADLINE) != 0);
+ final boolean notIdle = (satisfiedConstraints & CONSTRAINT_APP_NOT_IDLE) != 0;
+ final boolean notDozing = (satisfiedConstraints & CONSTRAINT_DEVICE_NOT_DOZING) != 0
+ || (job.getFlags() & JobInfo.FLAG_WILL_BE_FOREGROUND) != 0;
+ return (isConstraintsSatisfied() || deadlineSatisfied) && notIdle && notDozing;
}
static final int CONSTRAINTS_OF_INTEREST =
@@ -561,6 +565,10 @@ public final class JobStatus {
if (job.getPriority() != 0) {
pw.print(prefix); pw.print(" Priority: "); pw.println(job.getPriority());
}
+ if (job.getFlags() != 0) {
+ pw.print(prefix); pw.print(" Flags: ");
+ pw.println(Integer.toHexString(job.getFlags()));
+ }
pw.print(prefix); pw.print(" Requires: charging=");
pw.print(job.isRequireCharging()); pw.print(" deviceIdle=");
pw.println(job.isRequireDeviceIdle());
@@ -613,6 +621,9 @@ public final class JobStatus {
pw.print(prefix); pw.print("Satisfied constraints:");
dumpConstraints(pw, satisfiedConstraints);
pw.println();
+ pw.print(prefix); pw.print("Unsatisfied constraints:");
+ dumpConstraints(pw, (requiredConstraints & ~satisfiedConstraints));
+ pw.println();
}
if (changedAuthorities != null) {
pw.print(prefix); pw.println("Changed authorities:");
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index 30aab8cc5897..50d936853fed 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -48,7 +48,6 @@ import static android.net.NetworkPolicyManager.FIREWALL_RULE_DEFAULT;
import static android.net.NetworkPolicyManager.FIREWALL_RULE_DENY;
import static android.net.NetworkPolicyManager.POLICY_NONE;
import static android.net.NetworkPolicyManager.POLICY_REJECT_METERED_BACKGROUND;
-import static android.net.NetworkPolicyManager.RULE_ALLOW_ALL;
import static android.net.NetworkPolicyManager.RULE_ALLOW_METERED;
import static android.net.NetworkPolicyManager.RULE_REJECT_METERED;
import static android.net.NetworkPolicyManager.RULE_TEMPORARY_ALLOW_METERED;
@@ -349,6 +348,9 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
/** Foreground at UID granularity. */
final SparseIntArray mUidState = new SparseIntArray();
+ /** Higher priority listener before general event dispatch */
+ private INetworkPolicyListener mConnectivityListener;
+
private final RemoteCallbackList<INetworkPolicyListener>
mListeners = new RemoteCallbackList<>();
@@ -1391,6 +1393,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
final String tag = in.getName();
if (type == START_TAG) {
if (TAG_POLICY_LIST.equals(tag)) {
+ final boolean oldValue = mRestrictBackground;
version = readIntAttribute(in, ATTR_VERSION);
if (version >= VERSION_ADDED_RESTRICT_BACKGROUND) {
mRestrictBackground = readBooleanAttribute(
@@ -1398,6 +1401,12 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
} else {
mRestrictBackground = false;
}
+ if (mRestrictBackground != oldValue) {
+ // Some early services may have read the default value,
+ // so notify them that it's changed
+ mHandler.obtainMessage(MSG_RESTRICT_BACKGROUND_CHANGED,
+ mRestrictBackground ? 1 : 0, 0).sendToTarget();
+ }
} else if (TAG_NETWORK_POLICY.equals(tag)) {
final int networkTemplate = readIntAttribute(in, ATTR_NETWORK_TEMPLATE);
@@ -1766,20 +1775,25 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
}
@Override
+ public void setConnectivityListener(INetworkPolicyListener listener) {
+ mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
+ if (mConnectivityListener != null) {
+ throw new IllegalStateException("Connectivity listener already registered");
+ }
+ mConnectivityListener = listener;
+ }
+
+ @Override
public void registerListener(INetworkPolicyListener listener) {
// TODO: create permission for observing network policy
mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
-
mListeners.register(listener);
-
- // TODO: consider dispatching existing rules to new listeners
}
@Override
public void unregisterListener(INetworkPolicyListener listener) {
// TODO: create permission for observing network policy
mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
-
mListeners.unregister(listener);
}
@@ -2754,8 +2768,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
final boolean isBlacklisted = (uidPolicy & POLICY_REJECT_METERED_BACKGROUND) != 0;
final boolean isWhitelisted = mRestrictBackgroundWhitelistUids.get(uid);
- int newRule = RULE_ALLOW_ALL;
- final int oldRule = mUidRules.get(uid);
+ int newRule = RULE_UNKNOWN;
+ final int oldRule = mUidRules.get(uid, RULE_UNKNOWN);
// First step: define the new rule based on user restrictions and foreground state.
if (isForeground) {
@@ -2777,8 +2791,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
+ ", oldRule: " + ruleToString(oldRule));
}
-
- if (newRule == RULE_ALLOW_ALL) {
+ if (newRule == RULE_UNKNOWN) {
mUidRules.delete(uid);
} else {
mUidRules.put(uid, newRule);
@@ -2858,6 +2871,45 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
}
}
+ private void dispatchUidRulesChanged(INetworkPolicyListener listener, int uid, int uidRules) {
+ if (listener != null) {
+ try {
+ listener.onUidRulesChanged(uid, uidRules);
+ } catch (RemoteException ignored) {
+ }
+ }
+ }
+
+ private void dispatchMeteredIfacesChanged(INetworkPolicyListener listener,
+ String[] meteredIfaces) {
+ if (listener != null) {
+ try {
+ listener.onMeteredIfacesChanged(meteredIfaces);
+ } catch (RemoteException ignored) {
+ }
+ }
+ }
+
+ private void dispatchRestrictBackgroundChanged(INetworkPolicyListener listener,
+ boolean restrictBackground) {
+ if (listener != null) {
+ try {
+ listener.onRestrictBackgroundChanged(restrictBackground);
+ } catch (RemoteException ignored) {
+ }
+ }
+ }
+
+ private void dispatchRestrictBackgroundWhitelistChanged(INetworkPolicyListener listener,
+ int uid, boolean whitelisted) {
+ if (listener != null) {
+ try {
+ listener.onRestrictBackgroundWhitelistChanged(uid, whitelisted);
+ } catch (RemoteException ignored) {
+ }
+ }
+ }
+
private Handler.Callback mHandlerCallback = new Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {
@@ -2865,30 +2917,22 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
case MSG_RULES_CHANGED: {
final int uid = msg.arg1;
final int uidRules = msg.arg2;
+ dispatchUidRulesChanged(mConnectivityListener, uid, uidRules);
final int length = mListeners.beginBroadcast();
for (int i = 0; i < length; i++) {
final INetworkPolicyListener listener = mListeners.getBroadcastItem(i);
- if (listener != null) {
- try {
- listener.onUidRulesChanged(uid, uidRules);
- } catch (RemoteException e) {
- }
- }
+ dispatchUidRulesChanged(listener, uid, uidRules);
}
mListeners.finishBroadcast();
return true;
}
case MSG_METERED_IFACES_CHANGED: {
final String[] meteredIfaces = (String[]) msg.obj;
+ dispatchMeteredIfacesChanged(mConnectivityListener, meteredIfaces);
final int length = mListeners.beginBroadcast();
for (int i = 0; i < length; i++) {
final INetworkPolicyListener listener = mListeners.getBroadcastItem(i);
- if (listener != null) {
- try {
- listener.onMeteredIfacesChanged(meteredIfaces);
- } catch (RemoteException e) {
- }
- }
+ dispatchMeteredIfacesChanged(listener, meteredIfaces);
}
mListeners.finishBroadcast();
return true;
@@ -2915,15 +2959,11 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
}
case MSG_RESTRICT_BACKGROUND_CHANGED: {
final boolean restrictBackground = msg.arg1 != 0;
+ dispatchRestrictBackgroundChanged(mConnectivityListener, restrictBackground);
final int length = mListeners.beginBroadcast();
for (int i = 0; i < length; i++) {
final INetworkPolicyListener listener = mListeners.getBroadcastItem(i);
- if (listener != null) {
- try {
- listener.onRestrictBackgroundChanged(restrictBackground);
- } catch (RemoteException e) {
- }
- }
+ dispatchRestrictBackgroundChanged(listener, restrictBackground);
}
mListeners.finishBroadcast();
final Intent intent =
@@ -2947,18 +2987,16 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
final boolean changed = msg.arg2 == 1;
final Boolean whitelisted = (Boolean) msg.obj;
+ // First notify internal listeners...
if (whitelisted != null) {
+ final boolean whitelistedBool = whitelisted.booleanValue();
+ dispatchRestrictBackgroundWhitelistChanged(mConnectivityListener, uid,
+ whitelistedBool);
final int length = mListeners.beginBroadcast();
for (int i = 0; i < length; i++) {
- // First notify internal listeners...
final INetworkPolicyListener listener = mListeners.getBroadcastItem(i);
- if (listener != null) {
- try {
- listener.onRestrictBackgroundWhitelistChanged(uid,
- whitelisted.booleanValue());
- } catch (RemoteException e) {
- }
- }
+ dispatchRestrictBackgroundWhitelistChanged(listener, uid,
+ whitelistedBool);
}
mListeners.finishBroadcast();
}