blob: 8365fd2e5427bfb339290ea7ff03a93c897cc69b [file] [log] [blame]
Matthew Williams6de79e22014-05-01 10:47:00 -07001/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License
15 */
16
Christopher Tate7060b042014-06-09 19:50:00 -070017package com.android.server.job.controllers;
Matthew Williams6de79e22014-05-01 10:47:00 -070018
Jeff Sharkey9252b342018-01-19 07:58:35 +090019import static android.net.NetworkCapabilities.LINK_BANDWIDTH_UNSPECIFIED;
20import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED;
21import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
22
Jeff Sharkey1b6519b2016-04-28 15:33:18 -060023import android.app.job.JobInfo;
Matthew Williams6de79e22014-05-01 10:47:00 -070024import android.net.ConnectivityManager;
Christopher Tate8bbe7042017-03-15 11:07:46 -070025import android.net.ConnectivityManager.NetworkCallback;
Jeff Sharkeyf07c7b92016-04-22 09:50:16 -060026import android.net.INetworkPolicyListener;
Christopher Tate8bbe7042017-03-15 11:07:46 -070027import android.net.Network;
28import android.net.NetworkCapabilities;
Matthew Williams6de79e22014-05-01 10:47:00 -070029import android.net.NetworkInfo;
Jeff Sharkeyf07c7b92016-04-22 09:50:16 -060030import android.net.NetworkPolicyManager;
Kweku Adams85f2fbc2017-12-18 12:04:12 -080031import android.net.NetworkRequest;
Jeff Sharkeycaa3f8d2017-10-25 16:12:00 -060032import android.net.TrafficStats;
Christopher Tate8bbe7042017-03-15 11:07:46 -070033import android.os.Process;
Matthew Williams6de79e22014-05-01 10:47:00 -070034import android.os.UserHandle;
Jeff Sharkeycaa3f8d2017-10-25 16:12:00 -060035import android.text.format.DateUtils;
Dianne Hackbornf9bac162017-04-20 17:17:48 -070036import android.util.ArraySet;
Jeff Sharkey01bb5302018-02-21 20:12:40 -070037import android.util.Log;
Matthew Williams9b9244b62014-05-14 11:06:04 -070038import android.util.Slog;
Kweku Adams85f2fbc2017-12-18 12:04:12 -080039import android.util.proto.ProtoOutputStream;
Matthew Williams6de79e22014-05-01 10:47:00 -070040
Jeff Sharkeyf07c7b92016-04-22 09:50:16 -060041import com.android.internal.annotations.GuardedBy;
Jeff Sharkey9252b342018-01-19 07:58:35 +090042import com.android.internal.annotations.VisibleForTesting;
Jeff Sharkeyfee8c7b2018-02-21 22:18:45 -070043import com.android.internal.util.IndentingPrintWriter;
Christopher Tate7060b042014-06-09 19:50:00 -070044import com.android.server.job.JobSchedulerService;
Jeff Sharkeyac2e8ef2018-02-22 16:06:44 -070045import com.android.server.job.JobSchedulerService.Constants;
Jeff Sharkeycaa3f8d2017-10-25 16:12:00 -060046import com.android.server.job.JobServiceContext;
Kweku Adams85f2fbc2017-12-18 12:04:12 -080047import com.android.server.job.StateControllerProto;
Matthew Williams6de79e22014-05-01 10:47:00 -070048
Jeff Sharkeyfee8c7b2018-02-21 22:18:45 -070049import java.util.function.Predicate;
Matthew Williams6de79e22014-05-01 10:47:00 -070050
51/**
Matthew Williams9b9244b62014-05-14 11:06:04 -070052 * Handles changes in connectivity.
Jeff Sharkeyf07c7b92016-04-22 09:50:16 -060053 * <p>
54 * Each app can have a different default networks or different connectivity
55 * status due to user-requested network policies, so we need to check
56 * constraints on a per-UID basis.
Matthew Williams6de79e22014-05-01 10:47:00 -070057 */
Dianne Hackborn6466c1c2017-06-13 10:33:19 -070058public final class ConnectivityController extends StateController implements
Matthew Williamseffacfa2014-06-05 20:56:40 -070059 ConnectivityManager.OnNetworkActiveListener {
Jeff Sharkey01bb5302018-02-21 20:12:40 -070060 private static final String TAG = "JobScheduler.Connectivity";
61 private static final boolean DEBUG = JobSchedulerService.DEBUG
62 || Log.isLoggable(TAG, Log.DEBUG);
Matthew Williams6de79e22014-05-01 10:47:00 -070063
Jeff Sharkeyf07c7b92016-04-22 09:50:16 -060064 private final ConnectivityManager mConnManager;
65 private final NetworkPolicyManager mNetPolicyManager;
Christopher Tate8bbe7042017-03-15 11:07:46 -070066 private boolean mConnected;
Jeff Sharkeyf07c7b92016-04-22 09:50:16 -060067
68 @GuardedBy("mLock")
Dianne Hackbornf9bac162017-04-20 17:17:48 -070069 private final ArraySet<JobStatus> mTrackedJobs = new ArraySet<>();
Jeff Sharkeyf07c7b92016-04-22 09:50:16 -060070
Jeff Sharkeyac2e8ef2018-02-22 16:06:44 -070071 public ConnectivityController(JobSchedulerService service) {
72 super(service);
Jeff Sharkeyf07c7b92016-04-22 09:50:16 -060073
74 mConnManager = mContext.getSystemService(ConnectivityManager.class);
75 mNetPolicyManager = mContext.getSystemService(NetworkPolicyManager.class);
76
Jeff Sharkeyd0fff2e2017-11-07 16:55:06 -070077 mConnected = false;
Jeff Sharkeyf07c7b92016-04-22 09:50:16 -060078
Christopher Tate8bbe7042017-03-15 11:07:46 -070079 mConnManager.registerDefaultNetworkCallback(mNetworkCallback);
Jeff Sharkeyf07c7b92016-04-22 09:50:16 -060080 mNetPolicyManager.registerListener(mNetPolicyListener);
Matthew Williams6de79e22014-05-01 10:47:00 -070081 }
82
Andreas Gampea36dc622018-02-05 17:19:22 -080083 @GuardedBy("mLock")
Matthew Williams6de79e22014-05-01 10:47:00 -070084 @Override
Dianne Hackbornb0001f62016-02-16 10:30:33 -080085 public void maybeStartTrackingJobLocked(JobStatus jobStatus, JobStatus lastJob) {
Christopher Tate60977f42017-04-13 13:48:46 -070086 if (jobStatus.hasConnectivityConstraint()) {
Jeff Sharkey43d2a172017-07-12 10:50:42 -060087 updateConstraintsSatisfied(jobStatus);
Dianne Hackbornb0001f62016-02-16 10:30:33 -080088 mTrackedJobs.add(jobStatus);
Dianne Hackbornf9bac162017-04-20 17:17:48 -070089 jobStatus.setTrackingController(JobStatus.TRACKING_CONNECTIVITY);
Matthew Williamseffacfa2014-06-05 20:56:40 -070090 }
91 }
92
Andreas Gampea36dc622018-02-05 17:19:22 -080093 @GuardedBy("mLock")
Matthew Williamseffacfa2014-06-05 20:56:40 -070094 @Override
Jeff Sharkeyf07c7b92016-04-22 09:50:16 -060095 public void maybeStopTrackingJobLocked(JobStatus jobStatus, JobStatus incomingJob,
96 boolean forUpdate) {
Dianne Hackbornf9bac162017-04-20 17:17:48 -070097 if (jobStatus.clearTrackingController(JobStatus.TRACKING_CONNECTIVITY)) {
Dianne Hackbornb0001f62016-02-16 10:30:33 -080098 mTrackedJobs.remove(jobStatus);
Matthew Williamseffacfa2014-06-05 20:56:40 -070099 }
Matthew Williams6de79e22014-05-01 10:47:00 -0700100 }
101
Jeff Sharkeycaa3f8d2017-10-25 16:12:00 -0600102 /**
Jeff Sharkey9252b342018-01-19 07:58:35 +0900103 * Test to see if running the given job on the given network is insane.
Jeff Sharkeycaa3f8d2017-10-25 16:12:00 -0600104 * <p>
105 * For example, if a job is trying to send 10MB over a 128Kbps EDGE
106 * connection, it would take 10.4 minutes, and has no chance of succeeding
107 * before the job times out, so we'd be insane to try running it.
108 */
Jeff Sharkey9252b342018-01-19 07:58:35 +0900109 @SuppressWarnings("unused")
110 private static boolean isInsane(JobStatus jobStatus, Network network,
Jeff Sharkeyac2e8ef2018-02-22 16:06:44 -0700111 NetworkCapabilities capabilities, Constants constants) {
Jeff Sharkeycaa3f8d2017-10-25 16:12:00 -0600112 final long estimatedBytes = jobStatus.getEstimatedNetworkBytes();
113 if (estimatedBytes == JobInfo.NETWORK_BYTES_UNKNOWN) {
114 // We don't know how large the job is; cross our fingers!
Jeff Sharkey9252b342018-01-19 07:58:35 +0900115 return false;
Jeff Sharkeycaa3f8d2017-10-25 16:12:00 -0600116 }
117
118 // We don't ask developers to differentiate between upstream/downstream
119 // in their size estimates, so test against the slowest link direction.
Jeff Sharkey9252b342018-01-19 07:58:35 +0900120 final long slowest = NetworkCapabilities.minBandwidth(
121 capabilities.getLinkDownstreamBandwidthKbps(),
122 capabilities.getLinkUpstreamBandwidthKbps());
123 if (slowest == LINK_BANDWIDTH_UNSPECIFIED) {
Jeff Sharkeycaa3f8d2017-10-25 16:12:00 -0600124 // We don't know what the network is like; cross our fingers!
Jeff Sharkey9252b342018-01-19 07:58:35 +0900125 return false;
Jeff Sharkeycaa3f8d2017-10-25 16:12:00 -0600126 }
127
128 final long estimatedMillis = ((estimatedBytes * DateUtils.SECOND_IN_MILLIS)
129 / (slowest * TrafficStats.KB_IN_BYTES / 8));
130 if (estimatedMillis > JobServiceContext.EXECUTING_TIMESLICE_MILLIS) {
131 // If we'd never finish before the timeout, we'd be insane!
132 Slog.w(TAG, "Estimated " + estimatedBytes + " bytes over " + slowest
133 + " kbps network would take " + estimatedMillis + "ms; that's insane!");
Jeff Sharkeycaa3f8d2017-10-25 16:12:00 -0600134 return true;
Jeff Sharkey9252b342018-01-19 07:58:35 +0900135 } else {
136 return false;
Jeff Sharkeycaa3f8d2017-10-25 16:12:00 -0600137 }
138 }
139
Jeff Sharkey9252b342018-01-19 07:58:35 +0900140 @SuppressWarnings("unused")
141 private static boolean isCongestionDelayed(JobStatus jobStatus, Network network,
Jeff Sharkeyac2e8ef2018-02-22 16:06:44 -0700142 NetworkCapabilities capabilities, Constants constants) {
Jeff Sharkey9252b342018-01-19 07:58:35 +0900143 // If network is congested, and job is less than 50% through the
144 // developer-requested window, then we're okay delaying the job.
145 if (!capabilities.hasCapability(NET_CAPABILITY_NOT_CONGESTED)) {
Jeff Sharkeyac2e8ef2018-02-22 16:06:44 -0700146 return jobStatus.getFractionRunTime() < constants.CONN_CONGESTION_DELAY_FRAC;
Jeff Sharkey9252b342018-01-19 07:58:35 +0900147 } else {
148 return false;
149 }
150 }
151
152 @SuppressWarnings("unused")
153 private static boolean isStrictSatisfied(JobStatus jobStatus, Network network,
Jeff Sharkeyac2e8ef2018-02-22 16:06:44 -0700154 NetworkCapabilities capabilities, Constants constants) {
Jeff Sharkey9252b342018-01-19 07:58:35 +0900155 return jobStatus.getJob().getRequiredNetwork().networkCapabilities
156 .satisfiedByNetworkCapabilities(capabilities);
157 }
158
159 @SuppressWarnings("unused")
160 private static boolean isRelaxedSatisfied(JobStatus jobStatus, Network network,
Jeff Sharkeyac2e8ef2018-02-22 16:06:44 -0700161 NetworkCapabilities capabilities, Constants constants) {
Jeff Sharkey9252b342018-01-19 07:58:35 +0900162 // Only consider doing this for prefetching jobs
Jeff Sharkey8474ca02018-03-26 19:10:02 -0600163 if (!jobStatus.getJob().isPrefetch()) {
Jeff Sharkey9252b342018-01-19 07:58:35 +0900164 return false;
165 }
166
167 // See if we match after relaxing any unmetered request
168 final NetworkCapabilities relaxed = new NetworkCapabilities(
169 jobStatus.getJob().getRequiredNetwork().networkCapabilities)
170 .removeCapability(NET_CAPABILITY_NOT_METERED);
171 if (relaxed.satisfiedByNetworkCapabilities(capabilities)) {
172 // TODO: treat this as "maybe" response; need to check quotas
Jeff Sharkeyac2e8ef2018-02-22 16:06:44 -0700173 return jobStatus.getFractionRunTime() > constants.CONN_PREFETCH_RELAX_FRAC;
Jeff Sharkey9252b342018-01-19 07:58:35 +0900174 } else {
175 return false;
176 }
177 }
178
179 @VisibleForTesting
180 static boolean isSatisfied(JobStatus jobStatus, Network network,
Jeff Sharkeyac2e8ef2018-02-22 16:06:44 -0700181 NetworkCapabilities capabilities, Constants constants) {
Jeff Sharkey9252b342018-01-19 07:58:35 +0900182 // Zeroth, we gotta have a network to think about being satisfied
183 if (network == null || capabilities == null) return false;
184
185 // First, are we insane?
Jeff Sharkeyac2e8ef2018-02-22 16:06:44 -0700186 if (isInsane(jobStatus, network, capabilities, constants)) return false;
Jeff Sharkey9252b342018-01-19 07:58:35 +0900187
188 // Second, is the network congested?
Jeff Sharkeyac2e8ef2018-02-22 16:06:44 -0700189 if (isCongestionDelayed(jobStatus, network, capabilities, constants)) return false;
Jeff Sharkey9252b342018-01-19 07:58:35 +0900190
191 // Third, is the network a strict match?
Jeff Sharkeyac2e8ef2018-02-22 16:06:44 -0700192 if (isStrictSatisfied(jobStatus, network, capabilities, constants)) return true;
Jeff Sharkey9252b342018-01-19 07:58:35 +0900193
194 // Third, is the network a relaxed match?
Jeff Sharkeyac2e8ef2018-02-22 16:06:44 -0700195 if (isRelaxedSatisfied(jobStatus, network, capabilities, constants)) return true;
Jeff Sharkey9252b342018-01-19 07:58:35 +0900196
197 return false;
198 }
199
Jeff Sharkey43d2a172017-07-12 10:50:42 -0600200 private boolean updateConstraintsSatisfied(JobStatus jobStatus) {
Jeff Sharkeyd0fff2e2017-11-07 16:55:06 -0700201 // TODO: consider matching against non-active networks
202
Christopher Tate8bbe7042017-03-15 11:07:46 -0700203 final int jobUid = jobStatus.getSourceUid();
Jeff Sharkey1b6519b2016-04-28 15:33:18 -0600204 final boolean ignoreBlocked = (jobStatus.getFlags() & JobInfo.FLAG_WILL_BE_FOREGROUND) != 0;
Jeff Sharkey9252b342018-01-19 07:58:35 +0900205
Jeff Sharkey43d2a172017-07-12 10:50:42 -0600206 final Network network = mConnManager.getActiveNetworkForUid(jobUid, ignoreBlocked);
Jeff Sharkeycaa3f8d2017-10-25 16:12:00 -0600207 final NetworkInfo info = mConnManager.getNetworkInfoForUid(network, jobUid, ignoreBlocked);
Jeff Sharkeyd0fff2e2017-11-07 16:55:06 -0700208 final NetworkCapabilities capabilities = mConnManager.getNetworkCapabilities(network);
Christopher Tate8bbe7042017-03-15 11:07:46 -0700209
Jeff Sharkeycaa3f8d2017-10-25 16:12:00 -0600210 final boolean connected = (info != null) && info.isConnected();
Jeff Sharkeyac2e8ef2018-02-22 16:06:44 -0700211 final boolean satisfied = isSatisfied(jobStatus, network, capabilities, mConstants);
Jeff Sharkey43d2a172017-07-12 10:50:42 -0600212
Jeff Sharkeyd0fff2e2017-11-07 16:55:06 -0700213 final boolean changed = jobStatus
Jeff Sharkey9252b342018-01-19 07:58:35 +0900214 .setConnectivityConstraintSatisfied(connected && satisfied);
Christopher Tate8bbe7042017-03-15 11:07:46 -0700215
Jeff Sharkey76a02412017-10-24 16:55:04 -0600216 // Pass along the evaluated network for job to use; prevents race
217 // conditions as default routes change over time, and opens the door to
218 // using non-default routes.
219 jobStatus.network = network;
220
Christopher Tate8bbe7042017-03-15 11:07:46 -0700221 // Track system-uid connected/validated as a general reportable proxy for the
222 // overall state of connectivity constraint satisfiability.
223 if (jobUid == Process.SYSTEM_UID) {
224 mConnected = connected;
Christopher Tate8bbe7042017-03-15 11:07:46 -0700225 }
226
227 if (DEBUG) {
228 Slog.i(TAG, "Connectivity " + (changed ? "CHANGED" : "unchanged")
Jeff Sharkeyd0fff2e2017-11-07 16:55:06 -0700229 + " for " + jobStatus + ": connected=" + connected
Jeff Sharkey9252b342018-01-19 07:58:35 +0900230 + " satisfied=" + satisfied);
Christopher Tate8bbe7042017-03-15 11:07:46 -0700231 }
Jeff Sharkeyf07c7b92016-04-22 09:50:16 -0600232 return changed;
233 }
234
Matthew Williams6de79e22014-05-01 10:47:00 -0700235 /**
Jeff Sharkeyf07c7b92016-04-22 09:50:16 -0600236 * Update all jobs tracked by this controller.
237 *
238 * @param uid only update jobs belonging to this UID, or {@code -1} to
239 * update all tracked jobs.
Matthew Williams6de79e22014-05-01 10:47:00 -0700240 */
Jeff Sharkey43d2a172017-07-12 10:50:42 -0600241 private void updateTrackedJobs(int uid) {
Dianne Hackborn33d31c52016-02-16 10:30:33 -0800242 synchronized (mLock) {
Matthew Williamseffacfa2014-06-05 20:56:40 -0700243 boolean changed = false;
Dianne Hackbornf9bac162017-04-20 17:17:48 -0700244 for (int i = mTrackedJobs.size()-1; i >= 0; i--) {
245 final JobStatus js = mTrackedJobs.valueAt(i);
Jeff Sharkeyf07c7b92016-04-22 09:50:16 -0600246 if (uid == -1 || uid == js.getSourceUid()) {
Jeff Sharkey43d2a172017-07-12 10:50:42 -0600247 changed |= updateConstraintsSatisfied(js);
Matthew Williamseffacfa2014-06-05 20:56:40 -0700248 }
Matthew Williamseffacfa2014-06-05 20:56:40 -0700249 }
250 if (changed) {
251 mStateChangedListener.onControllerStateChanged();
Matthew Williams6de79e22014-05-01 10:47:00 -0700252 }
253 }
Matthew Williamseffacfa2014-06-05 20:56:40 -0700254 }
255
256 /**
Christopher Tate7060b042014-06-09 19:50:00 -0700257 * We know the network has just come up. We want to run any jobs that are ready.
Matthew Williamseffacfa2014-06-05 20:56:40 -0700258 */
Jeff Sharkeyf07c7b92016-04-22 09:50:16 -0600259 @Override
Dianne Hackborn532ea262017-03-17 17:50:55 -0700260 public void onNetworkActive() {
Dianne Hackborn33d31c52016-02-16 10:30:33 -0800261 synchronized (mLock) {
Dianne Hackbornf9bac162017-04-20 17:17:48 -0700262 for (int i = mTrackedJobs.size()-1; i >= 0; i--) {
263 final JobStatus js = mTrackedJobs.valueAt(i);
Christopher Tate7060b042014-06-09 19:50:00 -0700264 if (js.isReady()) {
Matthew Williamseffacfa2014-06-05 20:56:40 -0700265 if (DEBUG) {
Christopher Tate7060b042014-06-09 19:50:00 -0700266 Slog.d(TAG, "Running " + js + " due to network activity.");
Matthew Williamseffacfa2014-06-05 20:56:40 -0700267 }
Christopher Tate7060b042014-06-09 19:50:00 -0700268 mStateChangedListener.onRunJobNow(js);
Matthew Williamseffacfa2014-06-05 20:56:40 -0700269 }
270 }
Matthew Williams9b9244b62014-05-14 11:06:04 -0700271 }
Matthew Williams6de79e22014-05-01 10:47:00 -0700272 }
273
Christopher Tate8bbe7042017-03-15 11:07:46 -0700274 private final NetworkCallback mNetworkCallback = new NetworkCallback() {
Matthew Williams6de79e22014-05-01 10:47:00 -0700275 @Override
Christopher Tate8bbe7042017-03-15 11:07:46 -0700276 public void onCapabilitiesChanged(Network network, NetworkCapabilities networkCapabilities) {
277 if (DEBUG) {
278 Slog.v(TAG, "onCapabilitiesChanged() : " + networkCapabilities);
279 }
Jeff Sharkey43d2a172017-07-12 10:50:42 -0600280 updateTrackedJobs(-1);
Christopher Tate8bbe7042017-03-15 11:07:46 -0700281 }
282
283 @Override
284 public void onLost(Network network) {
285 if (DEBUG) {
286 Slog.v(TAG, "Network lost");
287 }
Jeff Sharkey43d2a172017-07-12 10:50:42 -0600288 updateTrackedJobs(-1);
Jeff Sharkeyf07c7b92016-04-22 09:50:16 -0600289 }
290 };
291
Jeff Sharkey75d31892018-01-18 22:01:59 +0900292 private final INetworkPolicyListener mNetPolicyListener = new NetworkPolicyManager.Listener() {
Jeff Sharkeyf07c7b92016-04-22 09:50:16 -0600293 @Override
294 public void onUidRulesChanged(int uid, int uidRules) {
Christopher Tate8bbe7042017-03-15 11:07:46 -0700295 if (DEBUG) {
296 Slog.v(TAG, "Uid rules changed for " + uid);
297 }
Jeff Sharkey43d2a172017-07-12 10:50:42 -0600298 updateTrackedJobs(uid);
Jeff Sharkeyf07c7b92016-04-22 09:50:16 -0600299 }
300
301 @Override
Jeff Sharkeyf07c7b92016-04-22 09:50:16 -0600302 public void onRestrictBackgroundChanged(boolean restrictBackground) {
Christopher Tate8bbe7042017-03-15 11:07:46 -0700303 if (DEBUG) {
304 Slog.v(TAG, "Background restriction change to " + restrictBackground);
305 }
Jeff Sharkey43d2a172017-07-12 10:50:42 -0600306 updateTrackedJobs(-1);
Jeff Sharkeyf07c7b92016-04-22 09:50:16 -0600307 }
308
309 @Override
Felipe Leme0ecfcd12016-09-06 12:49:48 -0700310 public void onUidPoliciesChanged(int uid, int uidPolicies) {
Christopher Tate8bbe7042017-03-15 11:07:46 -0700311 if (DEBUG) {
312 Slog.v(TAG, "Uid policy changed for " + uid);
313 }
Jeff Sharkey43d2a172017-07-12 10:50:42 -0600314 updateTrackedJobs(uid);
Felipe Leme99d5d3d2016-05-16 13:30:57 -0700315 }
Matthew Williams6de79e22014-05-01 10:47:00 -0700316 };
Matthew Williamseffacfa2014-06-05 20:56:40 -0700317
Andreas Gampea36dc622018-02-05 17:19:22 -0800318 @GuardedBy("mLock")
Matthew Williamseffacfa2014-06-05 20:56:40 -0700319 @Override
Jeff Sharkeyfee8c7b2018-02-21 22:18:45 -0700320 public void dumpControllerStateLocked(IndentingPrintWriter pw,
321 Predicate<JobStatus> predicate) {
322 pw.println("System connected: " + mConnected);
323 pw.println();
Makoto Onukide10e242018-02-05 12:56:20 -0800324
Jeff Sharkeyf07c7b92016-04-22 09:50:16 -0600325 for (int i = 0; i < mTrackedJobs.size(); i++) {
Dianne Hackbornf9bac162017-04-20 17:17:48 -0700326 final JobStatus js = mTrackedJobs.valueAt(i);
Jeff Sharkeyfee8c7b2018-02-21 22:18:45 -0700327 if (predicate.test(js)) {
328 pw.print("#");
Dianne Hackborne9a988c2016-05-27 17:59:40 -0700329 js.printUniqueId(pw);
330 pw.print(" from ");
331 UserHandle.formatUid(pw, js.getSourceUid());
Makoto Onukide10e242018-02-05 12:56:20 -0800332 pw.print(": ");
333 pw.print(js.getJob().getRequiredNetwork());
334 pw.println();
Dianne Hackbornef3aa6e2016-04-29 18:18:08 -0700335 }
Matthew Williamseffacfa2014-06-05 20:56:40 -0700336 }
337 }
Kweku Adams85f2fbc2017-12-18 12:04:12 -0800338
Andreas Gampea36dc622018-02-05 17:19:22 -0800339 @GuardedBy("mLock")
Kweku Adams85f2fbc2017-12-18 12:04:12 -0800340 @Override
Jeff Sharkeyfee8c7b2018-02-21 22:18:45 -0700341 public void dumpControllerStateLocked(ProtoOutputStream proto, long fieldId,
342 Predicate<JobStatus> predicate) {
Kweku Adams85f2fbc2017-12-18 12:04:12 -0800343 final long token = proto.start(fieldId);
344 final long mToken = proto.start(StateControllerProto.CONNECTIVITY);
345
346 proto.write(StateControllerProto.ConnectivityController.IS_CONNECTED, mConnected);
347
348 for (int i = 0; i < mTrackedJobs.size(); i++) {
349 final JobStatus js = mTrackedJobs.valueAt(i);
Jeff Sharkeyfee8c7b2018-02-21 22:18:45 -0700350 if (!predicate.test(js)) {
Kweku Adams85f2fbc2017-12-18 12:04:12 -0800351 continue;
352 }
353 final long jsToken = proto.start(StateControllerProto.ConnectivityController.TRACKED_JOBS);
354 js.writeToShortProto(proto, StateControllerProto.ConnectivityController.TrackedJob.INFO);
355 proto.write(StateControllerProto.ConnectivityController.TrackedJob.SOURCE_UID,
356 js.getSourceUid());
357 NetworkRequest rn = js.getJob().getRequiredNetwork();
358 if (rn != null) {
359 rn.writeToProto(proto,
360 StateControllerProto.ConnectivityController.TrackedJob.REQUIRED_NETWORK);
361 }
362 proto.end(jsToken);
363 }
364
365 proto.end(mToken);
366 proto.end(token);
367 }
Robert Greenwalt6078b502014-06-11 16:05:07 -0700368}