summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java11
-rw-r--r--apex/jobscheduler/service/java/com/android/server/job/controllers/ConnectivityController.java104
-rw-r--r--apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java5
-rw-r--r--apex/jobscheduler/service/java/com/android/server/job/controllers/StateController.java9
-rw-r--r--core/java/android/net/NetworkPolicyManager.java2
-rw-r--r--services/core/java/com/android/server/net/NetworkPolicyManagerService.java21
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/job/controllers/ConnectivityControllerTest.java2
7 files changed, 115 insertions, 39 deletions
diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
index af867b936d72..41b342cc258c 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
@@ -1220,6 +1220,7 @@ public class JobSchedulerService extends com.android.server.SystemService
void updateUidState(int uid, int procState) {
synchronized (mLock) {
+ final int prevPriority = mUidPriorityOverride.get(uid, JobInfo.PRIORITY_DEFAULT);
if (procState == ActivityManager.PROCESS_STATE_TOP) {
// Only use this if we are exactly the top app. All others can live
// with just the foreground priority. This means that persistent processes
@@ -1232,6 +1233,16 @@ public class JobSchedulerService extends com.android.server.SystemService
} else {
mUidPriorityOverride.delete(uid);
}
+ final int newPriority = mUidPriorityOverride.get(uid, JobInfo.PRIORITY_DEFAULT);
+ if (prevPriority != newPriority) {
+ if (DEBUG) {
+ Slog.d(TAG, "UID " + uid + " priority changed from " + prevPriority
+ + " to " + newPriority);
+ }
+ for (int c = 0; c < mControllers.size(); ++c) {
+ mControllers.get(c).onUidPriorityChangedLocked(uid, newPriority);
+ }
+ }
}
}
diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/ConnectivityController.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/ConnectivityController.java
index b97ca20b5d16..f30b75c1af93 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/controllers/ConnectivityController.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/ConnectivityController.java
@@ -29,6 +29,7 @@ import android.net.ConnectivityManager;
import android.net.ConnectivityManager.NetworkCallback;
import android.net.Network;
import android.net.NetworkCapabilities;
+import android.net.NetworkPolicyManager;
import android.net.NetworkRequest;
import android.os.Handler;
import android.os.Looper;
@@ -83,6 +84,19 @@ public final class ConnectivityController extends RestrictingController implemen
*/
private static final long MIN_STATS_UPDATE_INTERVAL_MS = 30_000L;
+ private static final int UNBYPASSABLE_BG_BLOCKED_REASONS =
+ ~ConnectivityManager.BLOCKED_REASON_NONE;
+ private static final int UNBYPASSABLE_EJ_BLOCKED_REASONS =
+ ~(ConnectivityManager.BLOCKED_REASON_APP_STANDBY
+ | ConnectivityManager.BLOCKED_REASON_BATTERY_SAVER
+ | ConnectivityManager.BLOCKED_REASON_DOZE);
+ private static final int UNBYPASSABLE_FOREGROUND_BLOCKED_REASONS =
+ ~(ConnectivityManager.BLOCKED_REASON_APP_STANDBY
+ | ConnectivityManager.BLOCKED_REASON_BATTERY_SAVER
+ | ConnectivityManager.BLOCKED_REASON_DOZE
+ | ConnectivityManager.BLOCKED_METERED_REASON_DATA_SAVER
+ | ConnectivityManager.BLOCKED_METERED_REASON_USER_RESTRICTED);
+
private final ConnectivityManager mConnManager;
private final NetworkPolicyManagerInternal mNetPolicyManagerInternal;
@@ -152,6 +166,9 @@ public final class ConnectivityController extends RestrictingController implemen
} else if (us1.earliestEJEnqueueTime > us2.earliestEJEnqueueTime) {
return 1;
}
+ if (us1.basePriority != us2.basePriority) {
+ return us2.basePriority - us1.basePriority;
+ }
if (us1.earliestEnqueueTime < us2.earliestEnqueueTime) {
return -1;
}
@@ -454,6 +471,16 @@ public final class ConnectivityController extends RestrictingController implemen
postAdjustCallbacks();
}
+ @GuardedBy("mLock")
+ @Override
+ public void onUidPriorityChangedLocked(int uid, int newPriority) {
+ UidStats uidStats = mUidStats.get(uid);
+ if (uidStats != null && uidStats.basePriority != newPriority) {
+ uidStats.basePriority = newPriority;
+ maybeAdjustRegisteredCallbacksLocked();
+ }
+ }
+
private boolean isUsable(NetworkCapabilities capabilities) {
return capabilities != null
&& capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED);
@@ -757,6 +784,42 @@ public final class ConnectivityController extends RestrictingController implemen
}
}
+ @GuardedBy("mLock")
+ @Nullable
+ private Network getNetworkLocked(@NonNull JobStatus jobStatus) {
+ final UidDefaultNetworkCallback defaultNetworkCallback =
+ mCurrentDefaultNetworkCallbacks.get(jobStatus.getSourceUid());
+ if (defaultNetworkCallback == null) {
+ return null;
+ }
+
+ UidStats uidStats = mUidStats.get(jobStatus.getSourceUid());
+
+ final int unbypassableBlockedReasons;
+ // TOP will probably have fewer reasons, so we may not have to worry about returning
+ // BG_BLOCKED for a TOP app. However, better safe than sorry.
+ if (uidStats.basePriority >= JobInfo.PRIORITY_BOUND_FOREGROUND_SERVICE
+ || (jobStatus.getFlags() & JobInfo.FLAG_WILL_BE_FOREGROUND) != 0) {
+ if (DEBUG) {
+ Slog.d(TAG, "Using FG bypass for " + jobStatus.getSourceUid());
+ }
+ unbypassableBlockedReasons = UNBYPASSABLE_FOREGROUND_BLOCKED_REASONS;
+ } else if (jobStatus.shouldTreatAsExpeditedJob() || jobStatus.startedAsExpeditedJob) {
+ if (DEBUG) {
+ Slog.d(TAG, "Using EJ bypass for " + jobStatus.getSourceUid());
+ }
+ unbypassableBlockedReasons = UNBYPASSABLE_EJ_BLOCKED_REASONS;
+ } else {
+ if (DEBUG) {
+ Slog.d(TAG, "Using BG bypass for " + jobStatus.getSourceUid());
+ }
+ unbypassableBlockedReasons = UNBYPASSABLE_BG_BLOCKED_REASONS;
+ }
+
+ return (unbypassableBlockedReasons & defaultNetworkCallback.mBlockedReasons) == 0
+ ? defaultNetworkCallback.mDefaultNetwork : null;
+ }
+
private boolean updateConstraintsSatisfied(JobStatus jobStatus) {
final long nowElapsed = sElapsedRealtimeClock.millis();
final UidDefaultNetworkCallback defaultNetworkCallback =
@@ -765,9 +828,7 @@ public final class ConnectivityController extends RestrictingController implemen
maybeRegisterDefaultNetworkCallbackLocked(jobStatus);
return updateConstraintsSatisfied(jobStatus, nowElapsed, null, null);
}
- final Network network =
- (jobStatus.shouldIgnoreNetworkBlocking() || !defaultNetworkCallback.mBlocked)
- ? defaultNetworkCallback.mDefaultNetwork : null;
+ final Network network = getNetworkLocked(jobStatus);
final NetworkCapabilities capabilities = getNetworkCapabilities(network);
return updateConstraintsSatisfied(jobStatus, nowElapsed, network, capabilities);
}
@@ -829,32 +890,15 @@ public final class ConnectivityController extends RestrictingController implemen
return false;
}
- final Network network = defaultNetworkCallback.mBlocked
- ? null : defaultNetworkCallback.mDefaultNetwork;
- final NetworkCapabilities capabilities = getNetworkCapabilities(network);
- final boolean networkMatch = (filterNetwork == null
- || Objects.equals(filterNetwork, network));
- // Ignore blocked
- final Network exemptedNetwork = defaultNetworkCallback.mDefaultNetwork;
- final NetworkCapabilities exemptedNetworkCapabilities =
- getNetworkCapabilities(exemptedNetwork);
- final boolean exemptedNetworkMatch =
- (filterNetwork == null || Objects.equals(filterNetwork, exemptedNetwork));
-
final long nowElapsed = sElapsedRealtimeClock.millis();
boolean changed = false;
for (int i = jobs.size() - 1; i >= 0; i--) {
final JobStatus js = jobs.valueAt(i);
- Network net = network;
- NetworkCapabilities netCap = capabilities;
- boolean match = networkMatch;
-
- if (js.shouldIgnoreNetworkBlocking()) {
- net = exemptedNetwork;
- netCap = exemptedNetworkCapabilities;
- match = exemptedNetworkMatch;
- }
+ final Network net = getNetworkLocked(js);
+ final NetworkCapabilities netCap = getNetworkCapabilities(net);
+ final boolean match = (filterNetwork == null
+ || Objects.equals(filterNetwork, net));
// Update either when we have a network match, or when the
// job hasn't yet been evaluated against the currently
@@ -950,7 +994,7 @@ public final class ConnectivityController extends RestrictingController implemen
private int mUid;
@Nullable
private Network mDefaultNetwork;
- private boolean mBlocked;
+ private int mBlockedReasons;
private void setUid(int uid) {
mUid = uid;
@@ -968,17 +1012,17 @@ public final class ConnectivityController extends RestrictingController implemen
}
@Override
- public void onBlockedStatusChanged(Network network, boolean blocked) {
+ public void onBlockedStatusChanged(Network network, int blockedReasons) {
if (DEBUG) {
Slog.v(TAG, "default-onBlockedStatusChanged(" + mUid + "): "
- + network + " -> " + blocked);
+ + network + " -> " + blockedReasons);
}
if (mUid == UserHandle.USER_NULL) {
return;
}
synchronized (mLock) {
mDefaultNetwork = network;
- mBlocked = blocked;
+ mBlockedReasons = blockedReasons;
updateTrackedJobsLocked(mUid, network);
}
}
@@ -1037,7 +1081,7 @@ public final class ConnectivityController extends RestrictingController implemen
pw.print("Network: ");
pw.print(mDefaultNetwork);
pw.print(" (blocked=");
- pw.print(mBlocked);
+ pw.print(NetworkPolicyManager.blockedReasonsToString(mBlockedReasons));
pw.print(")");
}
pw.println();
@@ -1046,6 +1090,7 @@ public final class ConnectivityController extends RestrictingController implemen
private static class UidStats {
public final int uid;
+ public int basePriority;
public int numRunning;
public int numReadyWithConnectivity;
public int numRequestedNetworkAvailable;
@@ -1062,6 +1107,7 @@ public final class ConnectivityController extends RestrictingController implemen
private void dumpLocked(IndentingPrintWriter pw, final long nowElapsed) {
pw.print("UidStats{");
pw.print("uid", uid);
+ pw.print("pri", basePriority);
pw.print("#run", numRunning);
pw.print("#readyWithConn", numReadyWithConnectivity);
pw.print("#netAvail", numRequestedNetworkAvailable);
diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java
index 80e68e9a883b..95eb220cfeb4 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java
@@ -1139,11 +1139,6 @@ public final class JobStatus {
&& (mDynamicConstraints & CONSTRAINT_BACKGROUND_NOT_RESTRICTED) == 0);
}
- boolean shouldIgnoreNetworkBlocking() {
- return (getFlags() & JobInfo.FLAG_WILL_BE_FOREGROUND) != 0
- || (shouldTreatAsExpeditedJob() || startedAsExpeditedJob);
- }
-
/** @return true if the constraint was changed, false otherwise. */
boolean setChargingConstraintSatisfied(final long nowElapsed, boolean state) {
return setConstraintSatisfied(CONSTRAINT_CHARGING, nowElapsed, state);
diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/StateController.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/StateController.java
index a33ba5b3f8bc..334876f57f29 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/controllers/StateController.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/StateController.java
@@ -25,6 +25,7 @@ import android.util.IndentingPrintWriter;
import android.util.Slog;
import android.util.proto.ProtoOutputStream;
+import com.android.internal.annotations.GuardedBy;
import com.android.server.job.JobSchedulerService;
import com.android.server.job.JobSchedulerService.Constants;
import com.android.server.job.StateChangedListener;
@@ -125,6 +126,14 @@ public abstract class StateController {
public void reevaluateStateLocked(int uid) {
}
+ /**
+ * Called when a UID's base priority has changed. The more positive the priority, the more
+ * important the UID is.
+ */
+ @GuardedBy("mLock")
+ public void onUidPriorityChangedLocked(int uid, int newPriority) {
+ }
+
protected boolean wouldBeReadyWithConstraintLocked(JobStatus jobStatus, int constraint) {
// This is very cheap to check (just a few conditions on data in JobStatus).
final boolean jobWouldBeReady = jobStatus.wouldBeReadyWithConstraint(constraint);
diff --git a/core/java/android/net/NetworkPolicyManager.java b/core/java/android/net/NetworkPolicyManager.java
index da3febddd973..632eb15ecdde 100644
--- a/core/java/android/net/NetworkPolicyManager.java
+++ b/core/java/android/net/NetworkPolicyManager.java
@@ -769,7 +769,7 @@ public class NetworkPolicyManager {
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
@NonNull
public static String blockedReasonsToString(int blockedReasons) {
- return DebugUtils.flagsToString(NetworkPolicyManager.class, "BLOCKED_", blockedReasons);
+ return DebugUtils.flagsToString(ConnectivityManager.class, "BLOCKED_", blockedReasons);
}
/**
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index 2494816d34a7..352eac3567fe 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -435,8 +435,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
/**
* Message to indicate that reasons for why an uid is blocked changed.
* arg1 = uid
- * arg2 = oldBlockedReasons
- * obj = newBlockedReasons
+ * arg2 = newBlockedReasons
+ * obj = oldBlockedReasons
*/
private static final int MSG_BLOCKED_REASON_CHANGED = 21;
@@ -4665,7 +4665,14 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
+ ", oldRule=" + uidRulesToString(oldUidRules & MASK_METERED_NETWORKS)
+ ", newRule=" + uidRulesToString(newUidRules & MASK_METERED_NETWORKS)
+ ", newUidRules=" + uidRulesToString(newUidRules)
- + ", oldUidRules=" + uidRulesToString(oldUidRules));
+ + ", oldUidRules=" + uidRulesToString(oldUidRules)
+ + ", oldBlockedMeteredReasons=" + NetworkPolicyManager.blockedReasonsToString(
+ uidBlockedState.blockedReasons & BLOCKED_METERED_REASON_MASK)
+ + ", oldBlockedMeteredEffectiveReasons="
+ + NetworkPolicyManager.blockedReasonsToString(
+ uidBlockedState.effectiveBlockedReasons & BLOCKED_METERED_REASON_MASK)
+ + ", oldAllowedMeteredReasons=" + NetworkPolicyManager.blockedReasonsToString(
+ uidBlockedState.allowedReasons & BLOCKED_METERED_REASON_MASK));
}
if (newUidRules == RULE_NONE) {
@@ -5897,6 +5904,9 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
effectiveBlockedReasons = blockedReasons;
// If the uid is not subject to any blocked reasons, then return early
if (blockedReasons == BLOCKED_REASON_NONE) {
+ if (LOGV) {
+ Log.v(TAG, "updateEffectiveBlockedReasons(): no blocked reasons");
+ }
return;
}
if ((allowedReasons & ALLOWED_REASON_SYSTEM) != 0) {
@@ -5929,6 +5939,11 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
if ((allowedReasons & ALLOWED_METERED_REASON_USER_EXEMPTED) != 0) {
effectiveBlockedReasons &= ~BLOCKED_METERED_REASON_DATA_SAVER;
}
+ if (LOGV) {
+ Log.v(TAG, "updateEffectiveBlockedReasons()"
+ + ": blockedReasons=" + Integer.toBinaryString(blockedReasons)
+ + ", effectiveReasons=" + Integer.toBinaryString(effectiveBlockedReasons));
+ }
}
}
diff --git a/services/tests/mockingservicestests/src/com/android/server/job/controllers/ConnectivityControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/job/controllers/ConnectivityControllerTest.java
index 1b8f9c767e3e..0cd470ae7ec4 100644
--- a/services/tests/mockingservicestests/src/com/android/server/job/controllers/ConnectivityControllerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/job/controllers/ConnectivityControllerTest.java
@@ -654,7 +654,7 @@ public class ConnectivityControllerTest {
generalCallback.onCapabilitiesChanged(net, caps);
if (uidCallback != null) {
uidCallback.onAvailable(net);
- uidCallback.onBlockedStatusChanged(net, false);
+ uidCallback.onBlockedStatusChanged(net, ConnectivityManager.BLOCKED_REASON_NONE);
uidCallback.onCapabilitiesChanged(net, caps);
}
}