blob: 77e813e086ce91d77b86923ec3a0dac10dd31705 [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.content.Context;
Matthew Williams6de79e22014-05-01 10:47:00 -070025import android.net.ConnectivityManager;
Christopher Tate8bbe7042017-03-15 11:07:46 -070026import android.net.ConnectivityManager.NetworkCallback;
Jeff Sharkeyf07c7b92016-04-22 09:50:16 -060027import android.net.INetworkPolicyListener;
Christopher Tate8bbe7042017-03-15 11:07:46 -070028import android.net.Network;
29import android.net.NetworkCapabilities;
Matthew Williams6de79e22014-05-01 10:47:00 -070030import android.net.NetworkInfo;
Jeff Sharkeyf07c7b92016-04-22 09:50:16 -060031import android.net.NetworkPolicyManager;
Kweku Adams85f2fbc2017-12-18 12:04:12 -080032import android.net.NetworkRequest;
Jeff Sharkeycaa3f8d2017-10-25 16:12:00 -060033import android.net.TrafficStats;
Christopher Tate8bbe7042017-03-15 11:07:46 -070034import android.os.Process;
Matthew Williams6de79e22014-05-01 10:47:00 -070035import android.os.UserHandle;
Jeff Sharkeycaa3f8d2017-10-25 16:12:00 -060036import android.text.format.DateUtils;
Dianne Hackbornf9bac162017-04-20 17:17:48 -070037import android.util.ArraySet;
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;
Christopher Tate7060b042014-06-09 19:50:00 -070043import com.android.server.job.JobSchedulerService;
Jeff Sharkeycaa3f8d2017-10-25 16:12:00 -060044import com.android.server.job.JobServiceContext;
Christopher Tate7060b042014-06-09 19:50:00 -070045import com.android.server.job.StateChangedListener;
Kweku Adams85f2fbc2017-12-18 12:04:12 -080046import com.android.server.job.StateControllerProto;
Matthew Williams6de79e22014-05-01 10:47:00 -070047
Matthew Williamseffacfa2014-06-05 20:56:40 -070048import java.io.PrintWriter;
Matthew Williams6de79e22014-05-01 10:47:00 -070049
50/**
Matthew Williams9b9244b62014-05-14 11:06:04 -070051 * Handles changes in connectivity.
Jeff Sharkeyf07c7b92016-04-22 09:50:16 -060052 * <p>
53 * Each app can have a different default networks or different connectivity
54 * status due to user-requested network policies, so we need to check
55 * constraints on a per-UID basis.
Matthew Williams6de79e22014-05-01 10:47:00 -070056 */
Dianne Hackborn6466c1c2017-06-13 10:33:19 -070057public final class ConnectivityController extends StateController implements
Matthew Williamseffacfa2014-06-05 20:56:40 -070058 ConnectivityManager.OnNetworkActiveListener {
Christopher Tate7060b042014-06-09 19:50:00 -070059 private static final String TAG = "JobScheduler.Conn";
Christopher Tate8bbe7042017-03-15 11:07:46 -070060 private static final boolean DEBUG = false;
Matthew Williams6de79e22014-05-01 10:47:00 -070061
Jeff Sharkeyf07c7b92016-04-22 09:50:16 -060062 private final ConnectivityManager mConnManager;
63 private final NetworkPolicyManager mNetPolicyManager;
Christopher Tate8bbe7042017-03-15 11:07:46 -070064 private boolean mConnected;
Jeff Sharkeyf07c7b92016-04-22 09:50:16 -060065
66 @GuardedBy("mLock")
Dianne Hackbornf9bac162017-04-20 17:17:48 -070067 private final ArraySet<JobStatus> mTrackedJobs = new ArraySet<>();
Jeff Sharkeyf07c7b92016-04-22 09:50:16 -060068
Matthew Williams9b9244b62014-05-14 11:06:04 -070069 /** Singleton. */
Jeff Sharkey9252b342018-01-19 07:58:35 +090070 private static ConnectivityController sSingleton;
Matthew Williamseffacfa2014-06-05 20:56:40 -070071 private static Object sCreationLock = new Object();
Matthew Williams691e93e2014-05-12 15:33:09 -070072
Christopher Tate7060b042014-06-09 19:50:00 -070073 public static ConnectivityController get(JobSchedulerService jms) {
Matthew Williamseffacfa2014-06-05 20:56:40 -070074 synchronized (sCreationLock) {
Jeff Sharkey9252b342018-01-19 07:58:35 +090075 if (sSingleton == null) {
76 sSingleton = new ConnectivityController(jms, jms.getContext(), jms.getLock());
Matthew Williamseffacfa2014-06-05 20:56:40 -070077 }
Jeff Sharkey9252b342018-01-19 07:58:35 +090078 return sSingleton;
Matthew Williams9b9244b62014-05-14 11:06:04 -070079 }
Matthew Williams9b9244b62014-05-14 11:06:04 -070080 }
81
Dianne Hackborn33d31c52016-02-16 10:30:33 -080082 private ConnectivityController(StateChangedListener stateChangedListener, Context context,
83 Object lock) {
84 super(stateChangedListener, context, lock);
Jeff Sharkeyf07c7b92016-04-22 09:50:16 -060085
86 mConnManager = mContext.getSystemService(ConnectivityManager.class);
87 mNetPolicyManager = mContext.getSystemService(NetworkPolicyManager.class);
88
Jeff Sharkeyd0fff2e2017-11-07 16:55:06 -070089 mConnected = false;
Jeff Sharkeyf07c7b92016-04-22 09:50:16 -060090
Christopher Tate8bbe7042017-03-15 11:07:46 -070091 mConnManager.registerDefaultNetworkCallback(mNetworkCallback);
Jeff Sharkeyf07c7b92016-04-22 09:50:16 -060092 mNetPolicyManager.registerListener(mNetPolicyListener);
Matthew Williams6de79e22014-05-01 10:47:00 -070093 }
94
Andreas Gampea36dc622018-02-05 17:19:22 -080095 @GuardedBy("mLock")
Matthew Williams6de79e22014-05-01 10:47:00 -070096 @Override
Dianne Hackbornb0001f62016-02-16 10:30:33 -080097 public void maybeStartTrackingJobLocked(JobStatus jobStatus, JobStatus lastJob) {
Christopher Tate60977f42017-04-13 13:48:46 -070098 if (jobStatus.hasConnectivityConstraint()) {
Jeff Sharkey43d2a172017-07-12 10:50:42 -060099 updateConstraintsSatisfied(jobStatus);
Dianne Hackbornb0001f62016-02-16 10:30:33 -0800100 mTrackedJobs.add(jobStatus);
Dianne Hackbornf9bac162017-04-20 17:17:48 -0700101 jobStatus.setTrackingController(JobStatus.TRACKING_CONNECTIVITY);
Matthew Williamseffacfa2014-06-05 20:56:40 -0700102 }
103 }
104
Andreas Gampea36dc622018-02-05 17:19:22 -0800105 @GuardedBy("mLock")
Matthew Williamseffacfa2014-06-05 20:56:40 -0700106 @Override
Jeff Sharkeyf07c7b92016-04-22 09:50:16 -0600107 public void maybeStopTrackingJobLocked(JobStatus jobStatus, JobStatus incomingJob,
108 boolean forUpdate) {
Dianne Hackbornf9bac162017-04-20 17:17:48 -0700109 if (jobStatus.clearTrackingController(JobStatus.TRACKING_CONNECTIVITY)) {
Dianne Hackbornb0001f62016-02-16 10:30:33 -0800110 mTrackedJobs.remove(jobStatus);
Matthew Williamseffacfa2014-06-05 20:56:40 -0700111 }
Matthew Williams6de79e22014-05-01 10:47:00 -0700112 }
113
Jeff Sharkeycaa3f8d2017-10-25 16:12:00 -0600114 /**
Jeff Sharkey9252b342018-01-19 07:58:35 +0900115 * Test to see if running the given job on the given network is insane.
Jeff Sharkeycaa3f8d2017-10-25 16:12:00 -0600116 * <p>
117 * For example, if a job is trying to send 10MB over a 128Kbps EDGE
118 * connection, it would take 10.4 minutes, and has no chance of succeeding
119 * before the job times out, so we'd be insane to try running it.
120 */
Jeff Sharkey9252b342018-01-19 07:58:35 +0900121 @SuppressWarnings("unused")
122 private static boolean isInsane(JobStatus jobStatus, Network network,
123 NetworkCapabilities capabilities) {
Jeff Sharkeycaa3f8d2017-10-25 16:12:00 -0600124 final long estimatedBytes = jobStatus.getEstimatedNetworkBytes();
125 if (estimatedBytes == JobInfo.NETWORK_BYTES_UNKNOWN) {
126 // We don't know how large the job is; cross our fingers!
Jeff Sharkey9252b342018-01-19 07:58:35 +0900127 return false;
Jeff Sharkeycaa3f8d2017-10-25 16:12:00 -0600128 }
129
130 // We don't ask developers to differentiate between upstream/downstream
131 // in their size estimates, so test against the slowest link direction.
Jeff Sharkey9252b342018-01-19 07:58:35 +0900132 final long slowest = NetworkCapabilities.minBandwidth(
133 capabilities.getLinkDownstreamBandwidthKbps(),
134 capabilities.getLinkUpstreamBandwidthKbps());
135 if (slowest == LINK_BANDWIDTH_UNSPECIFIED) {
Jeff Sharkeycaa3f8d2017-10-25 16:12:00 -0600136 // We don't know what the network is like; cross our fingers!
Jeff Sharkey9252b342018-01-19 07:58:35 +0900137 return false;
Jeff Sharkeycaa3f8d2017-10-25 16:12:00 -0600138 }
139
140 final long estimatedMillis = ((estimatedBytes * DateUtils.SECOND_IN_MILLIS)
141 / (slowest * TrafficStats.KB_IN_BYTES / 8));
142 if (estimatedMillis > JobServiceContext.EXECUTING_TIMESLICE_MILLIS) {
143 // If we'd never finish before the timeout, we'd be insane!
144 Slog.w(TAG, "Estimated " + estimatedBytes + " bytes over " + slowest
145 + " kbps network would take " + estimatedMillis + "ms; that's insane!");
Jeff Sharkeycaa3f8d2017-10-25 16:12:00 -0600146 return true;
Jeff Sharkey9252b342018-01-19 07:58:35 +0900147 } else {
148 return false;
Jeff Sharkeycaa3f8d2017-10-25 16:12:00 -0600149 }
150 }
151
Jeff Sharkey9252b342018-01-19 07:58:35 +0900152 @SuppressWarnings("unused")
153 private static boolean isCongestionDelayed(JobStatus jobStatus, Network network,
154 NetworkCapabilities capabilities) {
155 // If network is congested, and job is less than 50% through the
156 // developer-requested window, then we're okay delaying the job.
157 if (!capabilities.hasCapability(NET_CAPABILITY_NOT_CONGESTED)) {
158 return jobStatus.getFractionRunTime() < 0.5;
159 } else {
160 return false;
161 }
162 }
163
164 @SuppressWarnings("unused")
165 private static boolean isStrictSatisfied(JobStatus jobStatus, Network network,
166 NetworkCapabilities capabilities) {
167 return jobStatus.getJob().getRequiredNetwork().networkCapabilities
168 .satisfiedByNetworkCapabilities(capabilities);
169 }
170
171 @SuppressWarnings("unused")
172 private static boolean isRelaxedSatisfied(JobStatus jobStatus, Network network,
173 NetworkCapabilities capabilities) {
174 // Only consider doing this for prefetching jobs
175 if ((jobStatus.getJob().getFlags() & JobInfo.FLAG_IS_PREFETCH) == 0) {
176 return false;
177 }
178
179 // See if we match after relaxing any unmetered request
180 final NetworkCapabilities relaxed = new NetworkCapabilities(
181 jobStatus.getJob().getRequiredNetwork().networkCapabilities)
182 .removeCapability(NET_CAPABILITY_NOT_METERED);
183 if (relaxed.satisfiedByNetworkCapabilities(capabilities)) {
184 // TODO: treat this as "maybe" response; need to check quotas
185 return jobStatus.getFractionRunTime() > 0.5;
186 } else {
187 return false;
188 }
189 }
190
191 @VisibleForTesting
192 static boolean isSatisfied(JobStatus jobStatus, Network network,
193 NetworkCapabilities capabilities) {
194 // Zeroth, we gotta have a network to think about being satisfied
195 if (network == null || capabilities == null) return false;
196
197 // First, are we insane?
198 if (isInsane(jobStatus, network, capabilities)) return false;
199
200 // Second, is the network congested?
201 if (isCongestionDelayed(jobStatus, network, capabilities)) return false;
202
203 // Third, is the network a strict match?
204 if (isStrictSatisfied(jobStatus, network, capabilities)) return true;
205
206 // Third, is the network a relaxed match?
207 if (isRelaxedSatisfied(jobStatus, network, capabilities)) return true;
208
209 return false;
210 }
211
Jeff Sharkey43d2a172017-07-12 10:50:42 -0600212 private boolean updateConstraintsSatisfied(JobStatus jobStatus) {
Jeff Sharkeyd0fff2e2017-11-07 16:55:06 -0700213 // TODO: consider matching against non-active networks
214
Christopher Tate8bbe7042017-03-15 11:07:46 -0700215 final int jobUid = jobStatus.getSourceUid();
Jeff Sharkey1b6519b2016-04-28 15:33:18 -0600216 final boolean ignoreBlocked = (jobStatus.getFlags() & JobInfo.FLAG_WILL_BE_FOREGROUND) != 0;
Jeff Sharkey9252b342018-01-19 07:58:35 +0900217
Jeff Sharkey43d2a172017-07-12 10:50:42 -0600218 final Network network = mConnManager.getActiveNetworkForUid(jobUid, ignoreBlocked);
Jeff Sharkeycaa3f8d2017-10-25 16:12:00 -0600219 final NetworkInfo info = mConnManager.getNetworkInfoForUid(network, jobUid, ignoreBlocked);
Jeff Sharkeyd0fff2e2017-11-07 16:55:06 -0700220 final NetworkCapabilities capabilities = mConnManager.getNetworkCapabilities(network);
Christopher Tate8bbe7042017-03-15 11:07:46 -0700221
Jeff Sharkeycaa3f8d2017-10-25 16:12:00 -0600222 final boolean connected = (info != null) && info.isConnected();
Jeff Sharkey9252b342018-01-19 07:58:35 +0900223 final boolean satisfied = isSatisfied(jobStatus, network, capabilities);
Jeff Sharkey43d2a172017-07-12 10:50:42 -0600224
Jeff Sharkeyd0fff2e2017-11-07 16:55:06 -0700225 final boolean changed = jobStatus
Jeff Sharkey9252b342018-01-19 07:58:35 +0900226 .setConnectivityConstraintSatisfied(connected && satisfied);
Christopher Tate8bbe7042017-03-15 11:07:46 -0700227
Jeff Sharkey76a02412017-10-24 16:55:04 -0600228 // Pass along the evaluated network for job to use; prevents race
229 // conditions as default routes change over time, and opens the door to
230 // using non-default routes.
231 jobStatus.network = network;
232
Christopher Tate8bbe7042017-03-15 11:07:46 -0700233 // Track system-uid connected/validated as a general reportable proxy for the
234 // overall state of connectivity constraint satisfiability.
235 if (jobUid == Process.SYSTEM_UID) {
236 mConnected = connected;
Christopher Tate8bbe7042017-03-15 11:07:46 -0700237 }
238
239 if (DEBUG) {
240 Slog.i(TAG, "Connectivity " + (changed ? "CHANGED" : "unchanged")
Jeff Sharkeyd0fff2e2017-11-07 16:55:06 -0700241 + " for " + jobStatus + ": connected=" + connected
Jeff Sharkey9252b342018-01-19 07:58:35 +0900242 + " satisfied=" + satisfied);
Christopher Tate8bbe7042017-03-15 11:07:46 -0700243 }
Jeff Sharkeyf07c7b92016-04-22 09:50:16 -0600244 return changed;
245 }
246
Matthew Williams6de79e22014-05-01 10:47:00 -0700247 /**
Jeff Sharkeyf07c7b92016-04-22 09:50:16 -0600248 * Update all jobs tracked by this controller.
249 *
250 * @param uid only update jobs belonging to this UID, or {@code -1} to
251 * update all tracked jobs.
Matthew Williams6de79e22014-05-01 10:47:00 -0700252 */
Jeff Sharkey43d2a172017-07-12 10:50:42 -0600253 private void updateTrackedJobs(int uid) {
Dianne Hackborn33d31c52016-02-16 10:30:33 -0800254 synchronized (mLock) {
Matthew Williamseffacfa2014-06-05 20:56:40 -0700255 boolean changed = false;
Dianne Hackbornf9bac162017-04-20 17:17:48 -0700256 for (int i = mTrackedJobs.size()-1; i >= 0; i--) {
257 final JobStatus js = mTrackedJobs.valueAt(i);
Jeff Sharkeyf07c7b92016-04-22 09:50:16 -0600258 if (uid == -1 || uid == js.getSourceUid()) {
Jeff Sharkey43d2a172017-07-12 10:50:42 -0600259 changed |= updateConstraintsSatisfied(js);
Matthew Williamseffacfa2014-06-05 20:56:40 -0700260 }
Matthew Williamseffacfa2014-06-05 20:56:40 -0700261 }
262 if (changed) {
263 mStateChangedListener.onControllerStateChanged();
Matthew Williams6de79e22014-05-01 10:47:00 -0700264 }
265 }
Matthew Williamseffacfa2014-06-05 20:56:40 -0700266 }
267
268 /**
Christopher Tate7060b042014-06-09 19:50:00 -0700269 * We know the network has just come up. We want to run any jobs that are ready.
Matthew Williamseffacfa2014-06-05 20:56:40 -0700270 */
Jeff Sharkeyf07c7b92016-04-22 09:50:16 -0600271 @Override
Dianne Hackborn532ea262017-03-17 17:50:55 -0700272 public void onNetworkActive() {
Dianne Hackborn33d31c52016-02-16 10:30:33 -0800273 synchronized (mLock) {
Dianne Hackbornf9bac162017-04-20 17:17:48 -0700274 for (int i = mTrackedJobs.size()-1; i >= 0; i--) {
275 final JobStatus js = mTrackedJobs.valueAt(i);
Christopher Tate7060b042014-06-09 19:50:00 -0700276 if (js.isReady()) {
Matthew Williamseffacfa2014-06-05 20:56:40 -0700277 if (DEBUG) {
Christopher Tate7060b042014-06-09 19:50:00 -0700278 Slog.d(TAG, "Running " + js + " due to network activity.");
Matthew Williamseffacfa2014-06-05 20:56:40 -0700279 }
Christopher Tate7060b042014-06-09 19:50:00 -0700280 mStateChangedListener.onRunJobNow(js);
Matthew Williamseffacfa2014-06-05 20:56:40 -0700281 }
282 }
Matthew Williams9b9244b62014-05-14 11:06:04 -0700283 }
Matthew Williams6de79e22014-05-01 10:47:00 -0700284 }
285
Christopher Tate8bbe7042017-03-15 11:07:46 -0700286 private final NetworkCallback mNetworkCallback = new NetworkCallback() {
Matthew Williams6de79e22014-05-01 10:47:00 -0700287 @Override
Christopher Tate8bbe7042017-03-15 11:07:46 -0700288 public void onCapabilitiesChanged(Network network, NetworkCapabilities networkCapabilities) {
289 if (DEBUG) {
290 Slog.v(TAG, "onCapabilitiesChanged() : " + networkCapabilities);
291 }
Jeff Sharkey43d2a172017-07-12 10:50:42 -0600292 updateTrackedJobs(-1);
Christopher Tate8bbe7042017-03-15 11:07:46 -0700293 }
294
295 @Override
296 public void onLost(Network network) {
297 if (DEBUG) {
298 Slog.v(TAG, "Network lost");
299 }
Jeff Sharkey43d2a172017-07-12 10:50:42 -0600300 updateTrackedJobs(-1);
Jeff Sharkeyf07c7b92016-04-22 09:50:16 -0600301 }
302 };
303
Jeff Sharkey75d31892018-01-18 22:01:59 +0900304 private final INetworkPolicyListener mNetPolicyListener = new NetworkPolicyManager.Listener() {
Jeff Sharkeyf07c7b92016-04-22 09:50:16 -0600305 @Override
306 public void onUidRulesChanged(int uid, int uidRules) {
Christopher Tate8bbe7042017-03-15 11:07:46 -0700307 if (DEBUG) {
308 Slog.v(TAG, "Uid rules changed for " + uid);
309 }
Jeff Sharkey43d2a172017-07-12 10:50:42 -0600310 updateTrackedJobs(uid);
Jeff Sharkeyf07c7b92016-04-22 09:50:16 -0600311 }
312
313 @Override
Jeff Sharkeyf07c7b92016-04-22 09:50:16 -0600314 public void onRestrictBackgroundChanged(boolean restrictBackground) {
Christopher Tate8bbe7042017-03-15 11:07:46 -0700315 if (DEBUG) {
316 Slog.v(TAG, "Background restriction change to " + restrictBackground);
317 }
Jeff Sharkey43d2a172017-07-12 10:50:42 -0600318 updateTrackedJobs(-1);
Jeff Sharkeyf07c7b92016-04-22 09:50:16 -0600319 }
320
321 @Override
Felipe Leme0ecfcd12016-09-06 12:49:48 -0700322 public void onUidPoliciesChanged(int uid, int uidPolicies) {
Christopher Tate8bbe7042017-03-15 11:07:46 -0700323 if (DEBUG) {
324 Slog.v(TAG, "Uid policy changed for " + uid);
325 }
Jeff Sharkey43d2a172017-07-12 10:50:42 -0600326 updateTrackedJobs(uid);
Felipe Leme99d5d3d2016-05-16 13:30:57 -0700327 }
Matthew Williams6de79e22014-05-01 10:47:00 -0700328 };
Matthew Williamseffacfa2014-06-05 20:56:40 -0700329
Andreas Gampea36dc622018-02-05 17:19:22 -0800330 @GuardedBy("mLock")
Matthew Williamseffacfa2014-06-05 20:56:40 -0700331 @Override
Dianne Hackbornef3aa6e2016-04-29 18:18:08 -0700332 public void dumpControllerStateLocked(PrintWriter pw, int filterUid) {
Christopher Tate8bbe7042017-03-15 11:07:46 -0700333 pw.print("Connectivity: connected=");
Makoto Onukide10e242018-02-05 12:56:20 -0800334 pw.println(mConnected);
335
Dianne Hackborne9a988c2016-05-27 17:59:40 -0700336 pw.print("Tracking ");
337 pw.print(mTrackedJobs.size());
Makoto Onukide10e242018-02-05 12:56:20 -0800338 pw.println(" jobs");
339
Jeff Sharkeyf07c7b92016-04-22 09:50:16 -0600340 for (int i = 0; i < mTrackedJobs.size(); i++) {
Dianne Hackbornf9bac162017-04-20 17:17:48 -0700341 final JobStatus js = mTrackedJobs.valueAt(i);
Dianne Hackbornef3aa6e2016-04-29 18:18:08 -0700342 if (js.shouldDump(filterUid)) {
Dianne Hackborne9a988c2016-05-27 17:59:40 -0700343 pw.print(" #");
344 js.printUniqueId(pw);
345 pw.print(" from ");
346 UserHandle.formatUid(pw, js.getSourceUid());
Makoto Onukide10e242018-02-05 12:56:20 -0800347 pw.print(": ");
348 pw.print(js.getJob().getRequiredNetwork());
349 pw.println();
Dianne Hackbornef3aa6e2016-04-29 18:18:08 -0700350 }
Matthew Williamseffacfa2014-06-05 20:56:40 -0700351 }
352 }
Kweku Adams85f2fbc2017-12-18 12:04:12 -0800353
Andreas Gampea36dc622018-02-05 17:19:22 -0800354 @GuardedBy("mLock")
Kweku Adams85f2fbc2017-12-18 12:04:12 -0800355 @Override
356 public void dumpControllerStateLocked(ProtoOutputStream proto, long fieldId, int filterUid) {
357 final long token = proto.start(fieldId);
358 final long mToken = proto.start(StateControllerProto.CONNECTIVITY);
359
360 proto.write(StateControllerProto.ConnectivityController.IS_CONNECTED, mConnected);
361
362 for (int i = 0; i < mTrackedJobs.size(); i++) {
363 final JobStatus js = mTrackedJobs.valueAt(i);
364 if (!js.shouldDump(filterUid)) {
365 continue;
366 }
367 final long jsToken = proto.start(StateControllerProto.ConnectivityController.TRACKED_JOBS);
368 js.writeToShortProto(proto, StateControllerProto.ConnectivityController.TrackedJob.INFO);
369 proto.write(StateControllerProto.ConnectivityController.TrackedJob.SOURCE_UID,
370 js.getSourceUid());
371 NetworkRequest rn = js.getJob().getRequiredNetwork();
372 if (rn != null) {
373 rn.writeToProto(proto,
374 StateControllerProto.ConnectivityController.TrackedJob.REQUIRED_NETWORK);
375 }
376 proto.end(jsToken);
377 }
378
379 proto.end(mToken);
380 proto.end(token);
381 }
Robert Greenwalt6078b502014-06-11 16:05:07 -0700382}