import android.text.TextUtils;
import android.text.style.URLSpan;
import android.util.Log;
+import android.util.proto.ProtoOutputStream;
import com.android.internal.util.ArrayUtils;
+import libcore.io.IoUtils;
+
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
-import libcore.io.IoUtils;
/**
* Representation of a clipped data on the clipboard.
b.append("NULL");
}
}
+
+ /** @hide */
+ public void writeToProto(ProtoOutputStream proto, long fieldId) {
+ final long token = proto.start(fieldId);
+
+ if (mHtmlText != null) {
+ proto.write(ClipDataProto.Item.HTML_TEXT, mHtmlText);
+ } else if (mText != null) {
+ proto.write(ClipDataProto.Item.TEXT, mText.toString());
+ } else if (mUri != null) {
+ proto.write(ClipDataProto.Item.URI, mUri.toString());
+ } else if (mIntent != null) {
+ mIntent.writeToProto(proto, ClipDataProto.Item.INTENT, true, true, true, true);
+ } else {
+ proto.write(ClipDataProto.Item.NOTHING, true);
+ }
+
+ proto.end(token);
+ }
}
/**
}
/** @hide */
+ public void writeToProto(ProtoOutputStream proto, long fieldId) {
+ final long token = proto.start(fieldId);
+
+ if (mClipDescription != null) {
+ mClipDescription.writeToProto(proto, ClipDataProto.DESCRIPTION);
+ }
+ if (mIcon != null) {
+ final long iToken = proto.start(ClipDataProto.ICON);
+ proto.write(ClipDataProto.Icon.WIDTH, mIcon.getWidth());
+ proto.write(ClipDataProto.Icon.HEIGHT, mIcon.getHeight());
+ proto.end(iToken);
+ }
+ for (int i = 0; i < mItems.size(); i++) {
+ mItems.get(i).writeToProto(proto, ClipDataProto.ITEMS);
+ }
+
+ proto.end(token);
+ }
+
+ /** @hide */
public void collectUris(List<Uri> out) {
for (int i = 0; i < mItems.size(); ++i) {
ClipData.Item item = getItemAt(i);
import android.os.PersistableBundle;
import android.text.TextUtils;
import android.util.TimeUtils;
+import android.util.proto.ProtoOutputStream;
import java.util.ArrayList;
import java.util.Arrays;
return !first;
}
+ /** @hide */
+ public void writeToProto(ProtoOutputStream proto, long fieldId) {
+ final long token = proto.start(fieldId);
+
+ final int size = mMimeTypes.size();
+ for (int i = 0; i < size; i++) {
+ proto.write(ClipDescriptionProto.MIME_TYPES, mMimeTypes.get(i));
+ }
+
+ if (mLabel != null) {
+ proto.write(ClipDescriptionProto.LABEL, mLabel.toString());
+ }
+ if (mExtras != null) {
+ mExtras.writeToProto(proto, ClipDescriptionProto.EXTRAS);
+ }
+ if (mTimeStamp > 0) {
+ proto.write(ClipDescriptionProto.TIMESTAMP_MS, mTimeStamp);
+ }
+
+ proto.end(token);
+ }
+
@Override
public int describeContents() {
return 0;
}
/** Put this here so that individual services don't have to reimplement this. @hide */
- public void toProto(ProtoOutputStream proto) {
+ public void writeToProto(ProtoOutputStream proto, long fieldId) {
+ final long token = proto.start(fieldId);
proto.write(ComponentNameProto.PACKAGE_NAME, mPackage);
proto.write(ComponentNameProto.CLASS_NAME, mClass);
+ proto.end(token);
}
@Override
}
/** @hide */
+ public void writeToProto(ProtoOutputStream proto, long fieldId) {
+ // Same input parameters that toString() gives to toShortString().
+ writeToProto(proto, fieldId, true, true, true, false);
+ }
+
+ /** @hide */
public void writeToProto(ProtoOutputStream proto, long fieldId, boolean secure, boolean comp,
boolean extras, boolean clip) {
long token = proto.start(fieldId);
import android.system.ErrnoException;
import android.system.Os;
import android.system.OsConstants;
+import android.util.proto.ProtoOutputStream;
import com.android.okhttp.internalandroidapi.Dns;
import com.android.okhttp.internalandroidapi.HttpURLConnectionFactory;
public String toString() {
return Integer.toString(netId);
}
+
+ /** @hide */
+ public void writeToProto(ProtoOutputStream proto, long fieldId) {
+ final long token = proto.start(fieldId);
+ proto.write(NetworkProto.NET_ID, netId);
+ proto.end(token);
+ }
}
import android.net.ConnectivityManager.NetworkCallback;
import android.os.Parcel;
import android.os.Parcelable;
+import android.util.proto.ProtoOutputStream;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.BitUtils;
return "[" + transports + capabilities + upBand + dnBand + specifier + signalStrength + "]";
}
+ /** @hide */
+ public void writeToProto(ProtoOutputStream proto, long fieldId) {
+ final long token = proto.start(fieldId);
+
+ for (int transport : getTransportTypes()) {
+ proto.write(NetworkCapabilitiesProto.TRANSPORTS, transport);
+ }
+
+ for (int capability : getCapabilities()) {
+ proto.write(NetworkCapabilitiesProto.CAPABILITIES, capability);
+ }
+
+ proto.write(NetworkCapabilitiesProto.LINK_UP_BANDWIDTH_KBPS, mLinkUpBandwidthKbps);
+ proto.write(NetworkCapabilitiesProto.LINK_DOWN_BANDWIDTH_KBPS, mLinkDownBandwidthKbps);
+
+ if (mNetworkSpecifier != null) {
+ proto.write(NetworkCapabilitiesProto.NETWORK_SPECIFIER, mNetworkSpecifier.toString());
+ }
+
+ proto.write(NetworkCapabilitiesProto.CAN_REPORT_SIGNAL_STRENGTH, hasSignalStrength());
+ proto.write(NetworkCapabilitiesProto.SIGNAL_STRENGTH, mSignalStrength);
+
+ proto.end(token);
+ }
+
/**
* @hide
*/
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
+import android.util.proto.ProtoOutputStream;
import java.util.Objects;
", " + networkCapabilities.toString() + " ]";
}
+ private int typeToProtoEnum(Type t) {
+ switch (t) {
+ case NONE:
+ return NetworkRequestProto.TYPE_NONE;
+ case LISTEN:
+ return NetworkRequestProto.TYPE_LISTEN;
+ case TRACK_DEFAULT:
+ return NetworkRequestProto.TYPE_TRACK_DEFAULT;
+ case REQUEST:
+ return NetworkRequestProto.TYPE_REQUEST;
+ case BACKGROUND_REQUEST:
+ return NetworkRequestProto.TYPE_BACKGROUND_REQUEST;
+ default:
+ return NetworkRequestProto.TYPE_UNKNOWN;
+ }
+ }
+
+ /** @hide */
+ public void writeToProto(ProtoOutputStream proto, long fieldId) {
+ final long token = proto.start(fieldId);
+
+ proto.write(NetworkRequestProto.TYPE, typeToProtoEnum(type));
+ proto.write(NetworkRequestProto.REQUEST_ID, requestId);
+ proto.write(NetworkRequestProto.LEGACY_TYPE, legacyType);
+ networkCapabilities.writeToProto(proto, NetworkRequestProto.NETWORK_CAPABILITIES);
+
+ proto.end(token);
+ }
+
public boolean equals(Object obj) {
if (obj instanceof NetworkRequest == false) return false;
NetworkRequest that = (NetworkRequest)obj;
import android.util.Size;
import android.util.SizeF;
import android.util.SparseArray;
+import android.util.proto.ProtoOutputStream;
import com.android.internal.annotations.VisibleForTesting;
}
return mMap.toString();
}
+
+ /** @hide */
+ public void writeToProto(ProtoOutputStream proto, long fieldId) {
+ final long token = proto.start(fieldId);
+
+ if (mParcelledData != null) {
+ if (isEmptyParcel()) {
+ proto.write(BundleProto.PARCELLED_DATA_SIZE, 0);
+ } else {
+ proto.write(BundleProto.PARCELLED_DATA_SIZE, mParcelledData.dataSize());
+ }
+ } else {
+ proto.write(BundleProto.MAP_DATA, mMap.toString());
+ }
+
+ proto.end(token);
+ }
}
import android.annotation.Nullable;
import android.util.ArrayMap;
+import android.util.proto.ProtoOutputStream;
import com.android.internal.util.XmlUtils;
}
return mMap.toString();
}
+
+ /** @hide */
+ public void writeToProto(ProtoOutputStream proto, long fieldId) {
+ final long token = proto.start(fieldId);
+
+ if (mParcelledData != null) {
+ if (isEmptyParcel()) {
+ proto.write(PersistableBundleProto.PARCELLED_DATA_SIZE, 0);
+ } else {
+ proto.write(PersistableBundleProto.PARCELLED_DATA_SIZE, mParcelledData.dataSize());
+ }
+ } else {
+ proto.write(PersistableBundleProto.MAP_DATA, mMap.toString());
+ }
+
+ proto.end(token);
+ }
}
--- /dev/null
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+syntax = "proto2";
+package android.content;
+
+option java_multiple_files = true;
+
+import "frameworks/base/core/proto/android/content/clipdescription.proto";
+import "frameworks/base/core/proto/android/content/intent.proto";
+
+// An android.content.ClipData object.
+message ClipDataProto {
+ optional android.content.ClipDescriptionProto description = 1;
+
+ // Custom dump of an android.graphics.Bitmap object.
+ message Icon {
+ optional int32 width = 1;
+ optional int32 height = 2;
+ }
+ optional Icon icon = 2;
+
+ // An android.content.ClipData.Item object.
+ message Item {
+ oneof data {
+ string html_text = 1;
+ string text = 2;
+ string uri = 3;
+ android.content.IntentProto intent = 4;
+ bool nothing = 5;
+ }
+ }
+ repeated Item items = 3;
+}
--- /dev/null
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+syntax = "proto2";
+package android.content;
+
+option java_multiple_files = true;
+
+import "frameworks/base/core/proto/android/os/persistablebundle.proto";
+
+// An android.content.ClipDescription object.
+message ClipDescriptionProto {
+ repeated string mime_types = 1;
+ optional string label = 2;
+ optional android.os.PersistableBundleProto extras = 3;
+ optional int64 timestamp_ms = 4;
+}
--- /dev/null
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+syntax = "proto2";
+option java_multiple_files = true;
+
+package android.net;
+
+/**
+ * An android.net.Network object.
+ */
+message NetworkProto {
+ optional int32 net_id = 1;
+}
--- /dev/null
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+syntax = "proto2";
+
+package android.net;
+
+option java_multiple_files = true;
+
+/**
+ * An android.net.NetworkCapabilities object.
+ */
+message NetworkCapabilitiesProto {
+ enum Transport {
+ // Indicates this network uses a Cellular transport.
+ TRANSPORT_CELLULAR = 0;
+ // Indicates this network uses a Wi-Fi transport.
+ TRANSPORT_WIFI = 1;
+ // Indicates this network uses a Bluetooth transport.
+ TRANSPORT_BLUETOOTH = 2;
+ // Indicates this network uses an Ethernet transport.
+ TRANSPORT_ETHERNET = 3;
+ // Indicates this network uses a VPN transport.
+ TRANSPORT_VPN = 4;
+ // Indicates this network uses a Wi-Fi Aware transport.
+ TRANSPORT_WIFI_AWARE = 5;
+ // Indicates this network uses a LoWPAN transport.
+ TRANSPORT_LOWPAN = 6;
+ }
+ repeated Transport transports = 1;
+
+ enum NetCapability {
+ // Indicates this is a network that has the ability to reach the
+ // carrier's MMSC for sending and receiving MMS messages.
+ NET_CAPABILITY_MMS = 0;
+ // Indicates this is a network that has the ability to reach the
+ // carrier's SUPL server, used to retrieve GPS information.
+ NET_CAPABILITY_SUPL = 1;
+ // Indicates this is a network that has the ability to reach the
+ // carrier's DUN or tethering gateway.
+ NET_CAPABILITY_DUN = 2;
+ // Indicates this is a network that has the ability to reach the
+ // carrier's FOTA portal, used for over the air updates.
+ NET_CAPABILITY_FOTA = 3;
+ // Indicates this is a network that has the ability to reach the
+ // carrier's IMS servers, used for network registration and signaling.
+ NET_CAPABILITY_IMS = 4;
+ // Indicates this is a network that has the ability to reach the
+ // carrier's CBS servers, used for carrier specific services.
+ NET_CAPABILITY_CBS = 5;
+ // Indicates this is a network that has the ability to reach a Wi-Fi
+ // direct peer.
+ NET_CAPABILITY_WIFI_P2P = 6;
+ // Indicates this is a network that has the ability to reach a carrier's
+ // Initial Attach servers.
+ NET_CAPABILITY_IA = 7;
+ // Indicates this is a network that has the ability to reach a carrier's
+ // RCS servers, used for Rich Communication Services.
+ NET_CAPABILITY_RCS = 8;
+ // Indicates this is a network that has the ability to reach a carrier's
+ // XCAP servers, used for configuration and control.
+ NET_CAPABILITY_XCAP = 9;
+ // Indicates this is a network that has the ability to reach a carrier's
+ // Emergency IMS servers or other services, used for network signaling
+ // during emergency calls.
+ NET_CAPABILITY_EIMS = 10;
+ // Indicates that this network is unmetered.
+ NET_CAPABILITY_NOT_METERED = 11;
+ // Indicates that this network should be able to reach the internet.
+ NET_CAPABILITY_INTERNET = 12;
+ // Indicates that this network is available for general use. If this is
+ // not set applications should not attempt to communicate on this
+ // network. Note that this is simply informative and not enforcement -
+ // enforcement is handled via other means. Set by default.
+ NET_CAPABILITY_NOT_RESTRICTED = 13;
+ // Indicates that the user has indicated implicit trust of this network.
+ // This generally means it's a sim-selected carrier, a plugged in
+ // ethernet, a paired BT device or a wifi the user asked to connect to.
+ // Untrusted networks are probably limited to unknown wifi AP. Set by
+ // default.
+ NET_CAPABILITY_TRUSTED = 14;
+ // Indicates that this network is not a VPN. This capability is set by
+ // default and should be explicitly cleared for VPN networks.
+ NET_CAPABILITY_NOT_VPN = 15;
+ // Indicates that connectivity on this network was successfully
+ // validated. For example, for a network with NET_CAPABILITY_INTERNET,
+ // it means that Internet connectivity was successfully detected.
+ NET_CAPABILITY_VALIDATED = 16;
+ // Indicates that this network was found to have a captive portal in
+ // place last time it was probed.
+ NET_CAPABILITY_CAPTIVE_PORTAL = 17;
+ // Indicates that this network is not roaming.
+ NET_CAPABILITY_NOT_ROAMING = 18;
+ // Indicates that this network is available for use by apps, and not a
+ // network that is being kept up in the background to facilitate fast
+ // network switching.
+ NET_CAPABILITY_FOREGROUND = 19;
+ }
+ repeated NetCapability capabilities = 2;
+
+ // Passive link bandwidth. This is a rough guide of the expected peak
+ // bandwidth for the first hop on the given transport. It is not measured,
+ // but may take into account link parameters (Radio technology, allocated
+ // channels, etc).
+ optional int32 link_up_bandwidth_kbps = 3;
+ optional int32 link_down_bandwidth_kbps = 4;
+
+ optional string network_specifier = 5;
+
+ // True if this object specifies a signal strength.
+ optional bool can_report_signal_strength = 6;
+ // This is a signed integer, and higher values indicate better signal. The
+ // exact units are bearer-dependent. For example, Wi-Fi uses RSSI.
+ // Only valid if can_report_signal_strength is true.
+ optional sint32 signal_strength = 7;
+}
--- /dev/null
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+syntax = "proto2";
+
+package android.net;
+
+option java_multiple_files = true;
+
+import "frameworks/base/core/proto/android/net/networkcapabilities.proto";
+
+/**
+ * An android.net.NetworkRequest object.
+ */
+message NetworkRequestProto {
+ enum Type {
+ TYPE_UNKNOWN = 0;
+ // Only used by applications. When an application creates a
+ // NetworkRequest, it does not have a type; the type is set by the
+ // system depending on the method used to file the request
+ // (requestNetwork, registerNetworkCallback, etc.).
+ TYPE_NONE = 1;
+ // The framework will issue callbacks about any and all networks that
+ // match the specified NetworkCapabilities.
+ TYPE_LISTEN = 2;
+ // A hybrid of the two designed such that the framework will issue
+ // callbacks for the single, highest scoring current network (if any)
+ // that matches the capabilities of the default Internet request
+ // (mDefaultRequest), but which cannot cause the framework to either
+ // create or retain the existence of any specific network. Note that
+ // from the point of view of the request matching code, TRACK_DEFAULT is
+ // identical to REQUEST: its special behaviour is not due to different
+ // semantics, but to the fact that the system will only ever create a
+ // TRACK_DEFAULT with capabilities that are identical to the default
+ // request's capabilities, thus causing it to share fate in every way
+ // with the default request.
+ TYPE_TRACK_DEFAULT = 3;
+ // Capable of causing a specific network to be created first (e.g. a
+ // telephony DUN request), the framework will issue callbacks about the
+ // single, highest scoring current network (if any) that matches the
+ // specified NetworkCapabilities.
+ TYPE_REQUEST = 4;
+ // Like REQUEST but does not cause any networks to retain the
+ // NET_CAPABILITY_FOREGROUND capability. A network with no foreground
+ // requests is in the background. A network that has one or more
+ // background requests and loses its last foreground request to a
+ // higher-scoring network will not go into the background immediately,
+ // but will linger and go into the background after the linger timeout.
+ TYPE_BACKGROUND_REQUEST = 5;
+ }
+ // The type of the request. This is only used by the system and is always
+ // NONE elsewhere.
+ optional Type type = 1;
+ // Identifies the request.
+ optional int32 request_id = 2;
+ // Set for legacy requests and the default.
+ optional int32 legacy_type = 3;
+ optional NetworkCapabilitiesProto network_capabilities = 4;
+}
--- /dev/null
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+syntax = "proto2";
+package android.os;
+
+option java_multiple_files = true;
+
+// An android.os.Bundle object.
+message BundleProto {
+ oneof data {
+ int32 parcelled_data_size = 1;
+ string map_data = 2;
+ }
+}
import "frameworks/base/core/proto/android/server/activitymanagerservice.proto";
import "frameworks/base/core/proto/android/server/alarmmanagerservice.proto";
import "frameworks/base/core/proto/android/server/fingerprint.proto";
+import "frameworks/base/core/proto/android/server/jobscheduler.proto";
import "frameworks/base/core/proto/android/server/powermanagerservice.proto";
import "frameworks/base/core/proto/android/server/windowmanagerservice.proto";
import "frameworks/base/core/proto/android/service/appwidget.proto";
(section).args = "graphicsstats --proto"
];
+ optional com.android.server.job.JobSchedulerServiceDumpProto jobscheduler = 3020 [
+ (section).type = SECTION_DUMPSYS,
+ (section).args = "jobscheduler --proto"
+ ];
}
--- /dev/null
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+syntax = "proto2";
+package android.os;
+
+option java_multiple_files = true;
+
+// An android.os.PersistableBundle object.
+message PersistableBundleProto {
+ oneof data {
+ int32 parcelled_data_size = 1;
+ string map_data = 2;
+ }
+}
--- /dev/null
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+syntax = "proto2";
+
+package com.android.server.job;
+
+option java_multiple_files = true;
+
+import "frameworks/base/core/proto/android/app/jobparameters.proto";
+import "frameworks/base/core/proto/android/content/clipdata.proto";
+import "frameworks/base/core/proto/android/content/component_name.proto";
+import "frameworks/base/core/proto/android/content/intent.proto";
+import "frameworks/base/core/proto/android/net/network.proto";
+import "frameworks/base/core/proto/android/net/networkrequest.proto";
+import "frameworks/base/core/proto/android/os/bundle.proto";
+import "frameworks/base/core/proto/android/os/persistablebundle.proto";
+import "frameworks/base/core/proto/android/server/forceappstandbytracker.proto";
+
+message JobSchedulerServiceDumpProto {
+ optional ConstantsProto settings = 1;
+
+ repeated int32 started_users = 2;
+
+ message RegisteredJob {
+ optional JobStatusShortInfoProto info = 1;
+ optional JobStatusDumpProto dump = 2;
+
+ // A job is ready to be executed if:
+ // is_job_ready && is_user_started && !is_job_pending &&
+ // !is_job_currently_active && !is_uid_backing_up &&
+ // is_component_present.
+ optional bool is_job_ready = 3;
+ optional bool is_user_started = 4;
+ optional bool is_job_pending = 5;
+ optional bool is_job_currently_active = 6;
+ optional bool is_uid_backing_up = 7;
+ optional bool is_component_present = 8;
+ }
+ repeated RegisteredJob registered_jobs = 3;
+
+ repeated StateControllerProto controllers = 4;
+
+ // Which uids are currently in the foreground.
+ message PriorityOverride {
+ optional int32 uid = 1;
+ // Use sint32 instead of an enum since priorities can technically be
+ // negative.
+ optional sint32 override_value = 2;
+ }
+ repeated PriorityOverride priority_overrides = 5;
+
+ // UIDs that are currently performing backups, so their jobs won't be
+ // allowed to run.
+ repeated int32 backing_up_uids = 6;
+
+ optional JobPackageHistoryProto history = 7;
+ optional JobPackageTrackerDumpProto package_tracker = 8;
+
+ message PendingJob {
+ optional JobStatusShortInfoProto info = 1;
+ optional JobStatusDumpProto dump = 2;
+ optional sint32 evaluated_priority = 3;
+ // How long this job has been pending.
+ optional int64 enqueued_duration_ms = 4;
+ }
+ repeated PendingJob pending_jobs = 9;
+
+ // From a service that has currently active or pending jobs.
+ message ActiveJob {
+ message InactiveJob {
+ optional int64 time_since_stopped_ms = 1;
+ // This is not always provided.
+ optional string stopped_reason = 2;
+ }
+ message RunningJob {
+ optional JobStatusShortInfoProto info = 1;
+ // How long this job has been running for.
+ optional int64 running_duration_ms = 2;
+ optional int64 time_until_timeout_ms = 3;
+
+ optional JobStatusDumpProto dump = 4;
+
+ optional sint32 evaluated_priority = 5;
+
+ optional int64 time_since_made_active_ms = 6;
+ // How long this job has been pending.
+ optional int64 pending_duration_ms = 7;
+ }
+ oneof job {
+ InactiveJob inactive = 1;
+ RunningJob running = 2;
+ }
+ }
+ repeated ActiveJob active_jobs = 10;
+
+ // True when JobScheduler is allowed to run third party apps.
+ optional bool is_ready_to_rock = 11;
+ // What was last reported to DeviceIdleController about whether the device
+ // is active.
+ optional bool reported_active = 12;
+ // The current limit on the number of concurrent JobServiceContext entries
+ // we want to keep actively running a job.
+ optional int32 max_active_jobs = 13;
+}
+
+// A com.android.server.job.JobSchedulerService.Constants object.
+message ConstantsProto {
+ // Minimum # of idle jobs that must be ready in order to force the JMS to
+ // schedule things early.
+ optional int32 min_idle_count = 1;
+ // Minimum # of charging jobs that must be ready in order to force the JMS
+ // to schedule things early.
+ optional int32 min_charging_count = 2;
+ // Minimum # of "battery not low" jobs that must be ready in order to force
+ // the JMS to schedule things early.
+ optional int32 min_battery_not_low_count = 3;
+ // Minimum # of "storage not low" jobs that must be ready in order to force
+ // the JMS to schedule things early.
+ optional int32 min_storage_not_low_count = 4;
+ // Minimum # of connectivity jobs that must be ready in order to force the
+ // JMS to schedule things early. 1 == Run connectivity jobs as soon as
+ // ready.
+ optional int32 min_connectivity_count = 5;
+ // Minimum # of content trigger jobs that must be ready in order to force
+ // the JMS to schedule things early.
+ optional int32 min_content_count = 6;
+ // Minimum # of jobs (with no particular constraints) for which the JMS will
+ // be happy running some work early. This (and thus the other min counts)
+ // is now set to 1, to prevent any batching at this level. Since we now do
+ // batching through doze, that is a much better mechanism.
+ optional int32 min_ready_jobs_count = 7;
+ // This is the job execution factor that is considered to be heavy use of
+ // the system.
+ optional double heavy_use_factor = 8;
+ // This is the job execution factor that is considered to be moderate use of
+ // the system.
+ optional double moderate_use_factor = 9;
+ // The number of MAX_JOB_CONTEXTS_COUNT we reserve for the foreground app.
+ optional int32 fg_job_count = 10;
+ // The maximum number of background jobs we allow when the system is in a
+ // normal memory state.
+ optional int32 bg_normal_job_count = 11;
+ // The maximum number of background jobs we allow when the system is in a
+ // moderate memory state.
+ optional int32 bg_moderate_job_count = 12;
+ // The maximum number of background jobs we allow when the system is in a
+ // low memory state.
+ optional int32 bg_low_job_count = 13;
+ // The maximum number of background jobs we allow when the system is in a
+ // critical memory state.
+ optional int32 bg_critical_job_count = 14;
+ // The maximum number of times we allow a job to have itself rescheduled
+ // before giving up on it, for standard jobs.
+ optional int32 max_standard_reschedule_count = 15;
+ // The maximum number of times we allow a job to have itself rescheduled
+ // before giving up on it, for jobs that are executing work.
+ optional int32 max_work_reschedule_count = 16;
+ // The minimum backoff time to allow for linear backoff.
+ optional int64 min_linear_backoff_time_ms = 17;
+ // The minimum backoff time to allow for exponential backoff.
+ optional int64 min_exp_backoff_time_ms = 18;
+ // How often we recalculate runnability based on apps' standby bucket
+ // assignment. This should be prime relative to common time interval lengths
+ // such as a quarter-hour or day, so that the heartbeat drifts relative to
+ // wall-clock milestones.
+ optional int64 standby_heartbeat_time_ms = 19;
+ // Mapping: standby bucket -> number of heartbeats between each sweep of
+ // that bucket's jobs.
+ // Bucket assignments as recorded in the JobStatus objects are normalized to
+ // be indices into this array, rather than the raw constants used by
+ // AppIdleHistory.
+ repeated int32 standby_beats = 20;
+}
+
+message StateControllerProto {
+ message AppIdleController {
+ optional bool is_parole_on = 1;
+
+ message TrackedJob {
+ optional JobStatusShortInfoProto info = 1;
+ optional int32 source_uid = 2;
+ optional string source_package_name = 3;
+ // If the constraints are satisfied, then the controller will mark
+ // the job as RUNNABLE, otherwise, it will be WAITING.
+ optional bool are_constraints_satisfied = 4;
+ }
+ repeated TrackedJob tracked_jobs = 2;
+ }
+ message BackgroundJobsController {
+ optional com.android.server.ForceAppStandbyTrackerProto force_app_standby_tracker = 1;
+
+ message TrackedJob {
+ optional JobStatusShortInfoProto info = 1;
+ optional int32 source_uid = 2;
+ optional string source_package_name = 3;
+ optional bool is_in_foreground = 4;
+ optional bool is_whitelisted = 5;
+ optional bool can_run_any_in_background = 6;
+ // If the constraints are satisfied, then the controller will mark
+ // the job as RUNNABLE, otherwise, it will be WAITING.
+ optional bool are_constraints_satisfied = 7;
+ }
+ repeated TrackedJob tracked_jobs = 2;
+ }
+ message BatteryController {
+ optional bool is_on_stable_power = 1;
+ optional bool is_battery_not_low = 2;
+
+ // Whether or not the controller is monitoring battery changes.
+ optional bool is_monitoring = 3;
+ // Only valid if is_monitoring is true.
+ optional int32 last_broadcast_sequence_number = 4;
+
+ message TrackedJob {
+ optional JobStatusShortInfoProto info = 1;
+ optional int32 source_uid = 2;
+ }
+ repeated TrackedJob tracked_jobs = 5;
+ }
+ message ConnectivityController {
+ optional bool is_connected = 1;
+
+ message TrackedJob {
+ optional JobStatusShortInfoProto info = 1;
+ optional int32 source_uid = 2;
+ optional .android.net.NetworkRequestProto required_network = 3;
+ }
+ repeated TrackedJob tracked_jobs = 2;
+ }
+ message ContentObserverController {
+ message TrackedJob {
+ optional JobStatusShortInfoProto info = 1;
+ optional int32 source_uid = 2;
+ }
+ repeated TrackedJob tracked_jobs = 1;
+
+ message Observer {
+ optional int32 user_id = 1;
+
+ message TriggerContentData {
+ optional string uri = 1;
+ optional int32 flags = 2;
+
+ // A
+ // com.android.server.job.controllers.ContentObserverController.JobInstance
+ // object.
+ message JobInstance {
+ optional JobStatusShortInfoProto info = 1;
+ optional int32 source_uid = 2;
+
+ optional int64 trigger_content_update_delay_ms = 3;
+ optional int64 trigger_content_max_delay_ms = 4;
+
+ repeated string changed_authorities = 5;
+ repeated string changed_uris = 6;
+ }
+ repeated JobInstance jobs = 3;
+ }
+ repeated TriggerContentData triggers = 2;
+ }
+ repeated Observer observers = 2;
+ }
+ message DeviceIdleJobsController {
+ // True when in device idle mode.
+ optional bool is_device_idle_mode = 1;
+
+ message TrackedJob {
+ optional JobStatusShortInfoProto info = 1;
+ optional int32 source_uid = 2;
+ optional string source_package_name = 3;
+ // If the constraints are satisfied, then the controller will mark
+ // the job as RUNNABLE, otherwise, it will be WAITING.
+ optional bool are_constraints_satisfied = 4;
+ optional bool is_doze_whitelisted = 5;
+ // A job that is exempted from Doze when the app is temp whitelisted
+ // or in the foreground.
+ optional bool is_allowed_in_doze = 6;
+ }
+ repeated TrackedJob tracked_jobs = 2;
+ }
+ message IdleController {
+ optional bool is_idle = 1;
+
+ message TrackedJob {
+ optional JobStatusShortInfoProto info = 1;
+ optional int32 source_uid = 2;
+ }
+ repeated TrackedJob tracked_jobs = 2;
+ }
+ message StorageController {
+ optional bool is_storage_not_low = 1;
+ optional int32 last_broadcast_sequence_number = 2;
+
+ message TrackedJob {
+ optional JobStatusShortInfoProto info = 1;
+ optional int32 source_uid = 2;
+ }
+ repeated TrackedJob tracked_jobs = 3;
+ }
+ message TimeController {
+ optional int64 now_elapsed_realtime = 1;
+ optional int64 time_until_next_delay_alarm_ms = 2;
+ optional int64 time_until_next_deadline_alarm_ms = 3;
+
+ message TrackedJob {
+ optional JobStatusShortInfoProto info = 1;
+ optional int32 source_uid = 2;
+
+ optional bool has_timing_delay_constraint = 3;
+ // Only valid if has_timing_delay_constraint is true. Can be
+ // negative if the delay is in the past.
+ optional int64 delay_time_remaining_ms = 4;
+
+ optional bool has_deadline_constraint = 5;
+ // Only valid if has_timing_delay_constraint is true. Can be
+ // negative in certain situations.
+ optional int64 time_remaining_until_deadline_ms = 6;
+ }
+ repeated TrackedJob tracked_jobs = 4;
+ }
+ oneof controller {
+ AppIdleController app_idle = 1;
+ BackgroundJobsController background = 2;
+ BatteryController battery = 3;
+ ConnectivityController connectivity = 4;
+ ContentObserverController content_observer = 5;
+ DeviceIdleJobsController device_idle = 6;
+ IdleController idle = 7;
+ StorageController storage = 8;
+ TimeController time = 9;
+ }
+}
+
+// A com.android.server.job.JobPackageTracker.DataSet object.
+message DataSetProto {
+ optional int64 start_clock_time_ms = 1;
+ // How much time has elapsed since the DataSet was instantiated.
+ optional int64 elapsed_time_ms = 2;
+ optional int64 period_ms = 3;
+
+ // Represents a com.android.server.job.JobPackageTracker.PackageEntry
+ // object, but with some extra data.
+ message PackageEntryProto {
+ optional int32 uid = 1;
+ optional string package_name = 2;
+
+ message State {
+ optional int64 duration_ms = 1;
+ optional int32 count = 2;
+ }
+ optional State pending_state = 3;
+ optional State active_state = 4;
+ optional State active_top_state = 5;
+
+ // True if the PackageEntry is currently pending or has been pending in
+ // the past.
+ optional bool pending = 6;
+ // True if the PackageEntry is currently active or has been active in
+ // the past.
+ optional bool active = 7;
+ // True if the PackageEntry is currently active top or has been active
+ // top in the past.
+ optional bool active_top = 8;
+
+ message StopReasonCount {
+ optional .android.app.JobParametersProto.CancelReason reason = 1;
+ optional int32 count = 2;
+ }
+ repeated StopReasonCount stop_reasons = 9;
+ }
+ repeated PackageEntryProto package_entries = 4;
+
+ optional int32 max_concurrency = 5;
+ optional int32 max_foreground_concurrency = 6;
+}
+
+// Dump from com.android.server.job.GrantedUriPermissions.
+message GrantedUriPermissionsDumpProto {
+ optional int32 flags = 1;
+ optional int32 source_user_id = 2;
+ optional string tag = 3;
+ optional string permission_owner = 4;
+ repeated string uris = 5;
+}
+
+message JobPackageTrackerDumpProto {
+ repeated DataSetProto historical_stats = 1;
+ optional DataSetProto current_stats = 2;
+}
+
+message JobPackageHistoryProto {
+ enum Event {
+ UNKNOWN = 0;
+ START_JOB = 1;
+ STOP_JOB = 2;
+ START_PERIODIC_JOB = 3;
+ STOP_PERIODIC_JOB = 4;
+ }
+ message HistoryEvent {
+ optional Event event = 1;
+ optional int64 time_since_event_ms = 2;
+ optional int32 uid = 3;
+ // Job IDs can technically be negative.
+ optional int32 job_id = 4;
+ optional string tag = 5;
+ // Only valid for STOP_JOB or STOP_PERIODIC_JOB Events.
+ optional .android.app.JobParametersProto.CancelReason stop_reason = 6;
+ }
+ repeated HistoryEvent history_event = 1;
+}
+
+message JobStatusShortInfoProto {
+ optional int32 calling_uid = 1;
+ // Job IDs can technically be negative.
+ optional int32 job_id = 2;
+ optional string battery_name = 3;
+}
+
+// Dump from a com.android.server.job.controllers.JobStatus object.
+message JobStatusDumpProto {
+ // The UID that scheduled the job.
+ optional int32 calling_uid = 1;
+ optional string tag = 2;
+
+ // The UID for which the job is being run.
+ optional int32 source_uid = 3;
+ optional int32 source_user_id = 4;
+ // The package for which the job is being run.
+ optional string source_package_name = 5;
+
+ // Custom dump of android.app.job.JobInfo object.
+ message JobInfo {
+ optional .android.content.ComponentNameProto service = 1;
+
+ optional bool is_periodic = 2;
+ // Only valid if is_periodic is true.
+ optional int64 period_interval_ms = 3;
+ // Only valid if is_periodic is true.
+ optional int64 period_flex_ms = 4;
+
+ optional bool is_persisted = 5;
+ optional sint32 priority = 6;
+ optional int32 flags = 7;
+
+ optional bool requires_charging = 8;
+ optional bool requires_battery_not_low = 9;
+ optional bool requires_device_idle = 10;
+
+ message TriggerContentUri {
+ optional int32 flags = 1;
+ optional string uri = 2;
+ }
+ repeated TriggerContentUri trigger_content_uris = 11;
+ optional int64 trigger_content_update_delay_ms = 12;
+ optional int64 trigger_content_max_delay_ms = 13;
+
+ optional .android.os.PersistableBundleProto extras = 14;
+ optional .android.os.BundleProto transient_extras = 15;
+ optional .android.content.ClipDataProto clip_data = 16;
+
+ optional GrantedUriPermissionsDumpProto granted_uri_permissions = 17;
+
+ optional .android.net.NetworkRequestProto required_network = 18;
+
+ optional int64 total_network_bytes = 19;
+
+ optional int64 min_latency_ms = 20;
+ optional int64 max_execution_delay_ms = 21;
+
+ message Backoff {
+ enum Policy {
+ BACKOFF_POLICY_LINEAR = 0;
+ BACKOFF_POLICY_EXPONENTIAL = 1;
+ }
+ optional Policy policy = 1;
+ optional int64 initial_backoff_ms = 2;
+ }
+ optional Backoff backoff_policy = 22;
+
+ optional bool has_early_constraint = 23;
+ optional bool has_late_constraint = 24;
+ }
+ optional JobInfo job_info = 6;
+
+ enum Constraint {
+ CONSTRAINT_CHARGING = 1;
+ CONSTRAINT_BATTERY_NOT_LOW = 2;
+ CONSTRAINT_STORAGE_NOT_LOW = 3;
+ CONSTRAINT_TIMING_DELAY = 4;
+ CONSTRAINT_DEADLINE = 5;
+ CONSTRAINT_IDLE = 6;
+ CONSTRAINT_CONNECTIVITY = 7;
+ CONSTRAINT_APP_NOT_IDLE = 8;
+ CONSTRAINT_CONTENT_TRIGGER = 9;
+ CONSTRAINT_DEVICE_NOT_DOZING = 10;
+ }
+ repeated Constraint required_constraints = 7;
+ repeated Constraint satisfied_constraints = 8;
+ repeated Constraint unsatisfied_constraints = 9;
+ optional bool is_doze_whitelisted = 10;
+
+ enum TrackingController {
+ TRACKING_BATTERY = 0;
+ TRACKING_CONNECTIVITY = 1;
+ TRACKING_CONTENT = 2;
+ TRACKING_IDLE = 3;
+ TRACKING_STORAGE = 4;
+ TRACKING_TIME = 5;
+ }
+ // Controllers that are currently tracking the job.
+ repeated TrackingController tracking_controllers = 11;
+
+ repeated string changed_authorities = 12;
+ repeated string changed_uris = 13;
+
+ optional .android.net.NetworkProto network = 14;
+
+ // Only the desired data from an android.app.job.JobWorkItem object.
+ message JobWorkItem {
+ optional int32 work_id = 1;
+ optional int32 delivery_count = 2;
+ optional .android.content.IntentProto intent = 3;
+ optional GrantedUriPermissionsDumpProto uri_grants = 4;
+ }
+ repeated JobWorkItem pending_work = 15;
+ repeated JobWorkItem executing_work = 16;
+
+ enum Bucket {
+ ACTIVE = 0;
+ WORKING_SET = 1;
+ FREQUENT = 2;
+ RARE = 3;
+ NEVER = 4;
+ }
+ optional Bucket standby_bucket = 17;
+
+ optional int64 enqueue_duration_ms = 18;
+ // Can be negative if the earliest runtime deadline has passed.
+ optional sint64 time_until_earliest_runtime_ms = 19;
+ // Can be negative if the latest runtime deadline has passed.
+ optional sint64 time_until_latest_runtime_ms = 20;
+
+ optional int32 num_failures = 21;
+
+ optional int64 last_successful_run_time = 22;
+ optional int64 last_failed_run_time = 23;
+}
import android.os.RemoteException;
import android.os.UserHandle;
import android.util.Slog;
+import android.util.proto.ProtoOutputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
pw.println(mUris.get(i));
}
}
+
+ public void dump(ProtoOutputStream proto, long fieldId) {
+ final long token = proto.start(fieldId);
+
+ proto.write(GrantedUriPermissionsDumpProto.FLAGS, mGrantFlags);
+ proto.write(GrantedUriPermissionsDumpProto.SOURCE_USER_ID, mSourceUserId);
+ proto.write(GrantedUriPermissionsDumpProto.TAG, mTag);
+ proto.write(GrantedUriPermissionsDumpProto.PERMISSION_OWNER, mPermissionOwner.toString());
+ for (int i = 0; i < mUris.size(); i++) {
+ Uri u = mUris.get(i);
+ if (u != null) {
+ proto.write(GrantedUriPermissionsDumpProto.URIS, u.toString());
+ }
+ }
+
+ proto.end(token);
+ }
}
import android.util.SparseArray;
import android.util.SparseIntArray;
import android.util.TimeUtils;
+import android.util.proto.ProtoOutputStream;
import com.android.internal.util.RingBufferIndices;
import com.android.server.job.controllers.JobStatus;
}
}
- void dump(PrintWriter pw, String header, String prefix, long now, long nowEllapsed,
+ void dump(PrintWriter pw, String header, String prefix, long now, long nowElapsed,
int filterUid) {
final long period = getTotalTime(now);
pw.print(prefix); pw.print(header); pw.print(" at ");
pw.print(DateFormat.format("yyyy-MM-dd-HH-mm-ss", mStartClockTime).toString());
pw.print(" (");
- TimeUtils.formatDuration(mStartElapsedTime, nowEllapsed, pw);
+ TimeUtils.formatDuration(mStartElapsedTime, nowElapsed, pw);
pw.print(") over ");
TimeUtils.formatDuration(period, pw);
pw.println(":");
pw.print(mMaxTotalActive); pw.print(" total, ");
pw.print(mMaxFgActive); pw.println(" foreground");
}
+
+ private void printPackageEntryState(ProtoOutputStream proto, long fieldId,
+ long duration, int count) {
+ final long token = proto.start(fieldId);
+ proto.write(DataSetProto.PackageEntryProto.State.DURATION_MS, duration);
+ proto.write(DataSetProto.PackageEntryProto.State.COUNT, count);
+ proto.end(token);
+ }
+
+ void dump(ProtoOutputStream proto, long fieldId, long now, long nowElapsed, int filterUid) {
+ final long token = proto.start(fieldId);
+ final long period = getTotalTime(now);
+
+ proto.write(DataSetProto.START_CLOCK_TIME_MS, mStartClockTime);
+ proto.write(DataSetProto.ELAPSED_TIME_MS, nowElapsed - mStartElapsedTime);
+ proto.write(DataSetProto.PERIOD_MS, period);
+
+ final int NE = mEntries.size();
+ for (int i = 0; i < NE; i++) {
+ int uid = mEntries.keyAt(i);
+ if (filterUid != -1 && filterUid != UserHandle.getAppId(uid)) {
+ continue;
+ }
+ ArrayMap<String, PackageEntry> uidMap = mEntries.valueAt(i);
+ final int NP = uidMap.size();
+ for (int j = 0; j < NP; j++) {
+ final long peToken = proto.start(DataSetProto.PACKAGE_ENTRIES);
+ PackageEntry pe = uidMap.valueAt(j);
+
+ proto.write(DataSetProto.PackageEntryProto.UID, uid);
+ proto.write(DataSetProto.PackageEntryProto.PACKAGE_NAME, uidMap.keyAt(j));
+
+ printPackageEntryState(proto, DataSetProto.PackageEntryProto.PENDING_STATE,
+ pe.getPendingTime(now), pe.pendingCount);
+ printPackageEntryState(proto, DataSetProto.PackageEntryProto.ACTIVE_STATE,
+ pe.getActiveTime(now), pe.activeCount);
+ printPackageEntryState(proto, DataSetProto.PackageEntryProto.ACTIVE_TOP_STATE,
+ pe.getActiveTopTime(now), pe.activeTopCount);
+
+ proto.write(DataSetProto.PackageEntryProto.PENDING,
+ pe.pendingNesting > 0 || pe.hadPending);
+ proto.write(DataSetProto.PackageEntryProto.ACTIVE,
+ pe.activeNesting > 0 || pe.hadActive);
+ proto.write(DataSetProto.PackageEntryProto.ACTIVE_TOP,
+ pe.activeTopNesting > 0 || pe.hadActiveTop);
+
+ for (int k = 0; k < pe.stopReasons.size(); k++) {
+ final long srcToken =
+ proto.start(DataSetProto.PackageEntryProto.STOP_REASONS);
+
+ proto.write(DataSetProto.PackageEntryProto.StopReasonCount.REASON,
+ pe.stopReasons.keyAt(k));
+ proto.write(DataSetProto.PackageEntryProto.StopReasonCount.COUNT,
+ pe.stopReasons.valueAt(k));
+
+ proto.end(srcToken);
+ }
+
+ proto.end(peToken);
+ }
+ }
+
+ proto.write(DataSetProto.MAX_CONCURRENCY, mMaxTotalActive);
+ proto.write(DataSetProto.MAX_FOREGROUND_CONCURRENCY, mMaxFgActive);
+
+ proto.end(token);
+ }
}
void rebatchIfNeeded(long now) {
public void dump(PrintWriter pw, String prefix, int filterUid) {
final long now = sUptimeMillisClock.millis();
- final long nowEllapsed = sElapsedRealtimeClock.millis();
+ final long nowElapsed = sElapsedRealtimeClock.millis();
final DataSet total;
if (mLastDataSets[0] != null) {
total = new DataSet(mLastDataSets[0]);
mCurDataSet.addTo(total, now);
for (int i = 1; i < mLastDataSets.length; i++) {
if (mLastDataSets[i] != null) {
- mLastDataSets[i].dump(pw, "Historical stats", prefix, now, nowEllapsed, filterUid);
+ mLastDataSets[i].dump(pw, "Historical stats", prefix, now, nowElapsed, filterUid);
pw.println();
}
}
- total.dump(pw, "Current stats", prefix, now, nowEllapsed, filterUid);
+ total.dump(pw, "Current stats", prefix, now, nowElapsed, filterUid);
+ }
+
+ public void dump(ProtoOutputStream proto, long fieldId, int filterUid) {
+ final long token = proto.start(fieldId);
+ final long now = sUptimeMillisClock.millis();
+ final long nowElapsed = sElapsedRealtimeClock.millis();
+
+ final DataSet total;
+ if (mLastDataSets[0] != null) {
+ total = new DataSet(mLastDataSets[0]);
+ mLastDataSets[0].addTo(total, now);
+ } else {
+ total = new DataSet(mCurDataSet);
+ }
+ mCurDataSet.addTo(total, now);
+
+ for (int i = 1; i < mLastDataSets.length; i++) {
+ if (mLastDataSets[i] != null) {
+ mLastDataSets[i].dump(proto, JobPackageTrackerDumpProto.HISTORICAL_STATS,
+ now, nowElapsed, filterUid);
+ }
+ }
+ total.dump(proto, JobPackageTrackerDumpProto.CURRENT_STATS,
+ now, nowElapsed, filterUid);
+
+ proto.end(token);
}
public boolean dumpHistory(PrintWriter pw, String prefix, int filterUid) {
}
return true;
}
+
+ public void dumpHistory(ProtoOutputStream proto, long fieldId, int filterUid) {
+ final int size = mEventIndices.size();
+ if (size == 0) {
+ return;
+ }
+ final long token = proto.start(fieldId);
+
+ final long now = sElapsedRealtimeClock.millis();
+ for (int i = 0; i < size; i++) {
+ final int index = mEventIndices.indexOf(i);
+ final int uid = mEventUids[index];
+ if (filterUid != -1 && filterUid != UserHandle.getAppId(uid)) {
+ continue;
+ }
+ final int cmd = mEventCmds[index] & EVENT_CMD_MASK;
+ if (cmd == EVENT_NULL) {
+ continue;
+ }
+ final long heToken = proto.start(JobPackageHistoryProto.HISTORY_EVENT);
+
+ proto.write(JobPackageHistoryProto.HistoryEvent.EVENT, cmd);
+ proto.write(JobPackageHistoryProto.HistoryEvent.TIME_SINCE_EVENT_MS, now - mEventTimes[index]);
+ proto.write(JobPackageHistoryProto.HistoryEvent.UID, uid);
+ proto.write(JobPackageHistoryProto.HistoryEvent.JOB_ID, mEventJobIds[index]);
+ proto.write(JobPackageHistoryProto.HistoryEvent.TAG, mEventTags[index]);
+ if (cmd == EVENT_STOP_JOB || cmd == EVENT_STOP_PERIODIC_JOB) {
+ proto.write(JobPackageHistoryProto.HistoryEvent.STOP_REASON,
+ (mEventCmds[index] & EVENT_STOP_REASON_MASK) >> EVENT_STOP_REASON_SHIFT);
+ }
+
+ proto.end(heToken);
+ }
+
+ proto.end(token);
+ }
}
import android.util.SparseArray;
import android.util.SparseIntArray;
import android.util.TimeUtils;
+import android.util.proto.ProtoOutputStream;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.IBatteryStats;
import com.android.server.DeviceIdleController;
import com.android.server.FgThread;
import com.android.server.LocalServices;
+import com.android.server.job.JobSchedulerServiceDumpProto.ActiveJob;
+import com.android.server.job.JobSchedulerServiceDumpProto.PendingJob;
import com.android.server.job.JobStore.JobStatusFunctor;
import com.android.server.job.controllers.AppIdleController;
import com.android.server.job.controllers.BackgroundJobsController;
int mMaxActiveJobs = 1;
/**
- * Which uids are currently in the foreground.
+ * A mapping of which uids are currently in the foreground to their effective priority.
*/
final SparseIntArray mUidPriorityOverride = new SparseIntArray();
}
pw.println('}');
}
+
+ void dump(ProtoOutputStream proto, long fieldId) {
+ final long token = proto.start(fieldId);
+
+ proto.write(ConstantsProto.MIN_IDLE_COUNT, MIN_IDLE_COUNT);
+ proto.write(ConstantsProto.MIN_CHARGING_COUNT, MIN_CHARGING_COUNT);
+ proto.write(ConstantsProto.MIN_BATTERY_NOT_LOW_COUNT, MIN_BATTERY_NOT_LOW_COUNT);
+ proto.write(ConstantsProto.MIN_STORAGE_NOT_LOW_COUNT, MIN_STORAGE_NOT_LOW_COUNT);
+ proto.write(ConstantsProto.MIN_CONNECTIVITY_COUNT, MIN_CONNECTIVITY_COUNT);
+ proto.write(ConstantsProto.MIN_CONTENT_COUNT, MIN_CONTENT_COUNT);
+ proto.write(ConstantsProto.MIN_READY_JOBS_COUNT, MIN_READY_JOBS_COUNT);
+ proto.write(ConstantsProto.HEAVY_USE_FACTOR, HEAVY_USE_FACTOR);
+ proto.write(ConstantsProto.MODERATE_USE_FACTOR, MODERATE_USE_FACTOR);
+ proto.write(ConstantsProto.FG_JOB_COUNT, FG_JOB_COUNT);
+ proto.write(ConstantsProto.BG_NORMAL_JOB_COUNT, BG_NORMAL_JOB_COUNT);
+ proto.write(ConstantsProto.BG_MODERATE_JOB_COUNT, BG_MODERATE_JOB_COUNT);
+ proto.write(ConstantsProto.BG_LOW_JOB_COUNT, BG_LOW_JOB_COUNT);
+ proto.write(ConstantsProto.BG_CRITICAL_JOB_COUNT, BG_CRITICAL_JOB_COUNT);
+ proto.write(ConstantsProto.MAX_STANDARD_RESCHEDULE_COUNT, MAX_STANDARD_RESCHEDULE_COUNT);
+ proto.write(ConstantsProto.MAX_WORK_RESCHEDULE_COUNT, MAX_WORK_RESCHEDULE_COUNT);
+ proto.write(ConstantsProto.MIN_LINEAR_BACKOFF_TIME_MS, MIN_LINEAR_BACKOFF_TIME);
+ proto.write(ConstantsProto.MIN_EXP_BACKOFF_TIME_MS, MIN_EXP_BACKOFF_TIME);
+ proto.write(ConstantsProto.STANDBY_HEARTBEAT_TIME_MS, STANDBY_HEARTBEAT_TIME);
+
+ for (int period : STANDBY_BEATS) {
+ proto.write(ConstantsProto.STANDBY_BEATS, period);
+ }
+
+ proto.end(token);
+ }
}
final Constants mConstants;
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
if (!DumpUtils.checkDumpAndUsageStatsPermission(getContext(), TAG, pw)) return;
+ int filterUid = -1;
+ boolean proto = false;
+ if (!ArrayUtils.isEmpty(args)) {
+ int opti = 0;
+ while (opti < args.length) {
+ String arg = args[opti];
+ if ("-h".equals(arg)) {
+ dumpHelp(pw);
+ return;
+ } else if ("-a".equals(arg)) {
+ // Ignore, we always dump all.
+ } else if ("--proto".equals(arg)) {
+ proto = true;
+ } else if (arg.length() > 0 && arg.charAt(0) == '-') {
+ pw.println("Unknown option: " + arg);
+ return;
+ } else {
+ break;
+ }
+ opti++;
+ }
+ if (opti < args.length) {
+ String pkg = args[opti];
+ try {
+ filterUid = getContext().getPackageManager().getPackageUid(pkg,
+ PackageManager.MATCH_ANY_USER);
+ } catch (NameNotFoundException ignored) {
+ pw.println("Invalid package: " + pkg);
+ return;
+ }
+ }
+ }
+
long identityToken = Binder.clearCallingIdentity();
try {
- JobSchedulerService.this.dumpInternal(pw, args);
+ if (proto) {
+ JobSchedulerService.this.dumpInternalProto(fd, filterUid);
+ } else {
+ JobSchedulerService.this.dumpInternal(pw, filterUid);
+ }
} finally {
Binder.restoreCallingIdentity(identityToken);
}
pw.println(" [package] is an optional package name to limit the output to.");
}
- void dumpInternal(final PrintWriter pw, String[] args) {
- int filterUid = -1;
- if (!ArrayUtils.isEmpty(args)) {
- int opti = 0;
- while (opti < args.length) {
- String arg = args[opti];
- if ("-h".equals(arg)) {
- dumpHelp(pw);
- return;
- } else if ("-a".equals(arg)) {
- // Ignore, we always dump all.
- } else if (arg.length() > 0 && arg.charAt(0) == '-') {
- pw.println("Unknown option: " + arg);
- return;
- } else {
- break;
+ /** Sort jobs by caller UID, then by Job ID. */
+ private static void sortJobs(List<JobStatus> jobs) {
+ Collections.sort(jobs, new Comparator<JobStatus>() {
+ @Override
+ public int compare(JobStatus o1, JobStatus o2) {
+ int uid1 = o1.getUid();
+ int uid2 = o2.getUid();
+ int id1 = o1.getJobId();
+ int id2 = o2.getJobId();
+ if (uid1 != uid2) {
+ return uid1 < uid2 ? -1 : 1;
}
- opti++;
+ return id1 < id2 ? -1 : (id1 > id2 ? 1 : 0);
}
- if (opti < args.length) {
- String pkg = args[opti];
- try {
- filterUid = getContext().getPackageManager().getPackageUid(pkg,
- PackageManager.MATCH_ANY_USER);
- } catch (NameNotFoundException ignored) {
- pw.println("Invalid package: " + pkg);
- return;
- }
- }
- }
+ });
+ }
+ void dumpInternal(final PrintWriter pw, int filterUid) {
final int filterUidFinal = UserHandle.getAppId(filterUid);
final long nowElapsed = sElapsedRealtimeClock.millis();
final long nowUptime = sUptimeMillisClock.millis();
pw.println(" jobs:");
if (mJobs.size() > 0) {
final List<JobStatus> jobs = mJobs.mJobSet.getAllJobs();
- Collections.sort(jobs, new Comparator<JobStatus>() {
- @Override
- public int compare(JobStatus o1, JobStatus o2) {
- int uid1 = o1.getUid();
- int uid2 = o2.getUid();
- int id1 = o1.getJobId();
- int id2 = o2.getJobId();
- if (uid1 != uid2) {
- return uid1 < uid2 ? -1 : 1;
- }
- return id1 < id2 ? -1 : (id1 > id2 ? 1 : 0);
- }
- });
+ sortJobs(jobs);
for (JobStatus job : jobs) {
pw.print(" JOB #"); job.printUniqueId(pw); pw.print(": ");
pw.println(job.toShortStringExceptUniqueId());
}
pw.println();
}
+
+ void dumpInternalProto(final FileDescriptor fd, int filterUid) {
+ ProtoOutputStream proto = new ProtoOutputStream(fd);
+ final int filterUidFinal = UserHandle.getAppId(filterUid);
+ final long nowElapsed = sElapsedRealtimeClock.millis();
+ final long nowUptime = sUptimeMillisClock.millis();
+
+ synchronized (mLock) {
+ mConstants.dump(proto, JobSchedulerServiceDumpProto.SETTINGS);
+ for (int u : mStartedUsers) {
+ proto.write(JobSchedulerServiceDumpProto.STARTED_USERS, u);
+ }
+ if (mJobs.size() > 0) {
+ final List<JobStatus> jobs = mJobs.mJobSet.getAllJobs();
+ sortJobs(jobs);
+ for (JobStatus job : jobs) {
+ final long rjToken = proto.start(JobSchedulerServiceDumpProto.REGISTERED_JOBS);
+ job.writeToShortProto(proto, JobSchedulerServiceDumpProto.RegisteredJob.INFO);
+
+ // Skip printing details if the caller requested a filter
+ if (!job.shouldDump(filterUidFinal)) {
+ continue;
+ }
+
+ job.dump(proto, JobSchedulerServiceDumpProto.RegisteredJob.DUMP, true, nowElapsed);
+
+ // isReadyToBeExecuted
+ proto.write(JobSchedulerServiceDumpProto.RegisteredJob.IS_JOB_READY,
+ job.isReady());
+ proto.write(JobSchedulerServiceDumpProto.RegisteredJob.IS_USER_STARTED,
+ ArrayUtils.contains(mStartedUsers, job.getUserId()));
+ proto.write(JobSchedulerServiceDumpProto.RegisteredJob.IS_JOB_PENDING,
+ mPendingJobs.contains(job));
+ proto.write(JobSchedulerServiceDumpProto.RegisteredJob.IS_JOB_CURRENTLY_ACTIVE,
+ isCurrentlyActiveLocked(job));
+ proto.write(JobSchedulerServiceDumpProto.RegisteredJob.IS_UID_BACKING_UP,
+ mBackingUpUids.indexOfKey(job.getSourceUid()) >= 0);
+ boolean componentPresent = false;
+ try {
+ componentPresent = (AppGlobals.getPackageManager().getServiceInfo(
+ job.getServiceComponent(),
+ PackageManager.MATCH_DEBUG_TRIAGED_MISSING,
+ job.getUserId()) != null);
+ } catch (RemoteException e) {
+ }
+ proto.write(JobSchedulerServiceDumpProto.RegisteredJob.IS_COMPONENT_PRESENT,
+ componentPresent);
+
+ proto.end(rjToken);
+ }
+ }
+ for (StateController controller : mControllers) {
+ controller.dumpControllerStateLocked(
+ proto, JobSchedulerServiceDumpProto.CONTROLLERS, filterUidFinal);
+ }
+ for (int i=0; i< mUidPriorityOverride.size(); i++) {
+ int uid = mUidPriorityOverride.keyAt(i);
+ if (filterUidFinal == -1 || filterUidFinal == UserHandle.getAppId(uid)) {
+ long pToken = proto.start(JobSchedulerServiceDumpProto.PRIORITY_OVERRIDES);
+ proto.write(JobSchedulerServiceDumpProto.PriorityOverride.UID, uid);
+ proto.write(JobSchedulerServiceDumpProto.PriorityOverride.OVERRIDE_VALUE,
+ mUidPriorityOverride.valueAt(i));
+ proto.end(pToken);
+ }
+ }
+ for (int i = 0; i < mBackingUpUids.size(); i++) {
+ int uid = mBackingUpUids.keyAt(i);
+ if (filterUidFinal == -1 || filterUidFinal == UserHandle.getAppId(uid)) {
+ proto.write(JobSchedulerServiceDumpProto.BACKING_UP_UIDS, uid);
+ }
+ }
+
+ mJobPackageTracker.dump(proto, JobSchedulerServiceDumpProto.PACKAGE_TRACKER,
+ filterUidFinal);
+ mJobPackageTracker.dumpHistory(proto, JobSchedulerServiceDumpProto.HISTORY,
+ filterUidFinal);
+
+ for (JobStatus job : mPendingJobs) {
+ final long pjToken = proto.start(JobSchedulerServiceDumpProto.PENDING_JOBS);
+
+ job.writeToShortProto(proto, PendingJob.INFO);
+ job.dump(proto, PendingJob.DUMP, false, nowElapsed);
+ int priority = evaluateJobPriorityLocked(job);
+ if (priority != JobInfo.PRIORITY_DEFAULT) {
+ proto.write(PendingJob.EVALUATED_PRIORITY, priority);
+ }
+ proto.write(PendingJob.ENQUEUED_DURATION_MS, nowUptime - job.madePending);
+
+ proto.end(pjToken);
+ }
+ for (JobServiceContext jsc : mActiveServices) {
+ final long ajToken = proto.start(JobSchedulerServiceDumpProto.ACTIVE_JOBS);
+ final JobStatus job = jsc.getRunningJobLocked();
+
+ if (job == null) {
+ final long ijToken = proto.start(ActiveJob.INACTIVE);
+
+ proto.write(ActiveJob.InactiveJob.TIME_SINCE_STOPPED_MS,
+ nowElapsed - jsc.mStoppedTime);
+ if (jsc.mStoppedReason != null) {
+ proto.write(ActiveJob.InactiveJob.STOPPED_REASON,
+ jsc.mStoppedReason);
+ }
+
+ proto.end(ijToken);
+ } else {
+ final long rjToken = proto.start(ActiveJob.RUNNING);
+
+ job.writeToShortProto(proto, ActiveJob.RunningJob.INFO);
+
+ proto.write(ActiveJob.RunningJob.RUNNING_DURATION_MS,
+ nowElapsed - jsc.getExecutionStartTimeElapsed());
+ proto.write(ActiveJob.RunningJob.TIME_UNTIL_TIMEOUT_MS,
+ jsc.getTimeoutElapsed() - nowElapsed);
+
+ job.dump(proto, ActiveJob.RunningJob.DUMP, false, nowElapsed);
+
+ int priority = evaluateJobPriorityLocked(jsc.getRunningJobLocked());
+ if (priority != JobInfo.PRIORITY_DEFAULT) {
+ proto.write(ActiveJob.RunningJob.EVALUATED_PRIORITY, priority);
+ }
+
+ proto.write(ActiveJob.RunningJob.TIME_SINCE_MADE_ACTIVE_MS,
+ nowUptime - job.madeActive);
+ proto.write(ActiveJob.RunningJob.PENDING_DURATION_MS,
+ job.madeActive - job.madePending);
+
+ proto.end(rjToken);
+ }
+ proto.end(ajToken);
+ }
+ if (filterUid == -1) {
+ proto.write(JobSchedulerServiceDumpProto.IS_READY_TO_ROCK, mReadyToRock);
+ proto.write(JobSchedulerServiceDumpProto.REPORTED_ACTIVE, mReportedActive);
+ proto.write(JobSchedulerServiceDumpProto.MAX_ACTIVE_JOBS, mMaxActiveJobs);
+ }
+ }
+
+ proto.flush();
+ }
}
import android.content.Context;
import android.os.UserHandle;
import android.util.Slog;
+import android.util.proto.ProtoOutputStream;
import com.android.server.LocalServices;
import com.android.server.job.JobSchedulerService;
import com.android.server.job.JobStore;
+import com.android.server.job.StateControllerProto;
import java.io.PrintWriter;
});
}
+ @Override
+ public void dumpControllerStateLocked(ProtoOutputStream proto, long fieldId, int filterUid) {
+ final long token = proto.start(fieldId);
+ final long mToken = proto.start(StateControllerProto.APP_IDLE);
+
+ proto.write(StateControllerProto.AppIdleController.IS_PAROLE_ON, mAppIdleParoleOn);
+
+ mJobSchedulerService.getJobStore().forEachJob(new JobStore.JobStatusFunctor() {
+ @Override public void process(JobStatus js) {
+ // Skip printing details if the caller requested a filter
+ if (!js.shouldDump(filterUid)) {
+ return;
+ }
+
+ final long jsToken =
+ proto.start(StateControllerProto.AppIdleController.TRACKED_JOBS);
+ js.writeToShortProto(proto, StateControllerProto.AppIdleController.TrackedJob.INFO);
+ proto.write(StateControllerProto.AppIdleController.TrackedJob.SOURCE_UID,
+ js.getSourceUid());
+ proto.write(StateControllerProto.AppIdleController.TrackedJob.SOURCE_PACKAGE_NAME,
+ js.getSourcePackageName());
+ proto.write(
+ StateControllerProto.AppIdleController.TrackedJob.ARE_CONSTRAINTS_SATISFIED,
+ (js.satisfiedConstraints & JobStatus.CONSTRAINT_APP_NOT_IDLE) != 0);
+ proto.end(jsToken);
+ }
+ });
+
+ proto.end(mToken);
+ proto.end(token);
+ }
+
void setAppIdleParoleOn(boolean isAppIdleParoleOn) {
// Flag if any app's idle state has changed
boolean changed = false;
import android.os.SystemClock;
import android.os.UserHandle;
import android.util.Slog;
+import android.util.proto.ProtoOutputStream;
import com.android.internal.util.ArrayUtils;
import com.android.server.ForceAppStandbyTracker;
import com.android.server.ForceAppStandbyTracker.Listener;
import com.android.server.job.JobSchedulerService;
import com.android.server.job.JobStore;
+import com.android.server.job.StateControllerProto;
+import com.android.server.job.StateControllerProto.BackgroundJobsController.TrackedJob;
import java.io.PrintWriter;
return;
}
final int uid = jobStatus.getSourceUid();
+ final String sourcePkg = jobStatus.getSourcePackageName();
pw.print(" #");
jobStatus.printUniqueId(pw);
pw.print(" from ");
pw.print(", whitelisted");
}
pw.print(": ");
- pw.print(jobStatus.getSourcePackageName());
+ pw.print(sourcePkg);
pw.print(" [RUN_ANY_IN_BACKGROUND ");
- pw.print(mForceAppStandbyTracker.isRunAnyInBackgroundAppOpsAllowed(
- jobStatus.getSourceUid(), jobStatus.getSourcePackageName())
+ pw.print(mForceAppStandbyTracker.isRunAnyInBackgroundAppOpsAllowed(uid, sourcePkg)
? "allowed]" : "disallowed]");
if ((jobStatus.satisfiedConstraints
});
}
+ @Override
+ public void dumpControllerStateLocked(ProtoOutputStream proto, long fieldId, int filterUid) {
+ final long token = proto.start(fieldId);
+ final long mToken = proto.start(StateControllerProto.BACKGROUND);
+
+ mForceAppStandbyTracker.dumpProto(proto,
+ StateControllerProto.BackgroundJobsController.FORCE_APP_STANDBY_TRACKER);
+
+ mJobSchedulerService.getJobStore().forEachJob((jobStatus) -> {
+ if (!jobStatus.shouldDump(filterUid)) {
+ return;
+ }
+ final long jsToken =
+ proto.start(StateControllerProto.BackgroundJobsController.TRACKED_JOBS);
+
+ jobStatus.writeToShortProto(proto,
+ TrackedJob.INFO);
+ final int sourceUid = jobStatus.getSourceUid();
+ proto.write(TrackedJob.SOURCE_UID, sourceUid);
+ final String sourcePkg = jobStatus.getSourcePackageName();
+ proto.write(TrackedJob.SOURCE_PACKAGE_NAME, sourcePkg);
+
+ proto.write(TrackedJob.IS_IN_FOREGROUND,
+ mForceAppStandbyTracker.isInForeground(sourceUid));
+ proto.write(TrackedJob.IS_WHITELISTED,
+ mForceAppStandbyTracker.isUidPowerSaveWhitelisted(sourceUid) ||
+ mForceAppStandbyTracker.isUidTempPowerSaveWhitelisted(sourceUid));
+
+ proto.write(
+ TrackedJob.CAN_RUN_ANY_IN_BACKGROUND,
+ mForceAppStandbyTracker.isRunAnyInBackgroundAppOpsAllowed(
+ sourceUid, sourcePkg));
+
+ proto.write(
+ TrackedJob.ARE_CONSTRAINTS_SATISFIED,
+ (jobStatus.satisfiedConstraints &
+ JobStatus.CONSTRAINT_BACKGROUND_NOT_RESTRICTED) != 0);
+
+ proto.end(jsToken);
+ });
+
+ proto.end(mToken);
+ proto.end(token);
+ }
+
private void updateAllJobRestrictionsLocked() {
updateJobRestrictionsLocked(/*filterUid=*/ -1);
}
import android.os.UserHandle;
import android.util.ArraySet;
import android.util.Slog;
+import android.util.proto.ProtoOutputStream;
import com.android.internal.annotations.VisibleForTesting;
import com.android.server.LocalServices;
import com.android.server.job.JobSchedulerService;
import com.android.server.job.StateChangedListener;
+import com.android.server.job.StateControllerProto;
import java.io.PrintWriter;
pw.println();
}
}
+
+ @Override
+ public void dumpControllerStateLocked(ProtoOutputStream proto, long fieldId, int filterUid) {
+ final long token = proto.start(fieldId);
+ final long mToken = proto.start(StateControllerProto.BATTERY);
+
+ proto.write(StateControllerProto.BatteryController.IS_ON_STABLE_POWER,
+ mChargeTracker.isOnStablePower());
+ proto.write(StateControllerProto.BatteryController.IS_BATTERY_NOT_LOW,
+ mChargeTracker.isBatteryNotLow());
+
+ proto.write(StateControllerProto.BatteryController.IS_MONITORING,
+ mChargeTracker.isMonitoring());
+ proto.write(StateControllerProto.BatteryController.LAST_BROADCAST_SEQUENCE_NUMBER,
+ mChargeTracker.getSeq());
+
+ for (int i = 0; i < mTrackedTasks.size(); i++) {
+ final JobStatus js = mTrackedTasks.valueAt(i);
+ if (!js.shouldDump(filterUid)) {
+ continue;
+ }
+ final long jsToken = proto.start(StateControllerProto.BatteryController.TRACKED_JOBS);
+ js.writeToShortProto(proto, StateControllerProto.BatteryController.TrackedJob.INFO);
+ proto.write(StateControllerProto.BatteryController.TrackedJob.SOURCE_UID,
+ js.getSourceUid());
+ proto.end(jsToken);
+ }
+
+ proto.end(mToken);
+ proto.end(token);
+ }
}
import android.net.NetworkCapabilities;
import android.net.NetworkInfo;
import android.net.NetworkPolicyManager;
+import android.net.NetworkRequest;
import android.net.TrafficStats;
import android.os.Process;
import android.os.UserHandle;
import android.text.format.DateUtils;
import android.util.ArraySet;
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.JobServiceContext;
import com.android.server.job.StateChangedListener;
+import com.android.server.job.StateControllerProto;
import java.io.PrintWriter;
}
}
}
+
+ @Override
+ public void dumpControllerStateLocked(ProtoOutputStream proto, long fieldId, int filterUid) {
+ final long token = proto.start(fieldId);
+ final long mToken = proto.start(StateControllerProto.CONNECTIVITY);
+
+ proto.write(StateControllerProto.ConnectivityController.IS_CONNECTED, mConnected);
+
+ for (int i = 0; i < mTrackedJobs.size(); i++) {
+ final JobStatus js = mTrackedJobs.valueAt(i);
+ if (!js.shouldDump(filterUid)) {
+ continue;
+ }
+ final long jsToken = proto.start(StateControllerProto.ConnectivityController.TRACKED_JOBS);
+ js.writeToShortProto(proto, StateControllerProto.ConnectivityController.TrackedJob.INFO);
+ proto.write(StateControllerProto.ConnectivityController.TrackedJob.SOURCE_UID,
+ js.getSourceUid());
+ NetworkRequest rn = js.getJob().getRequiredNetwork();
+ if (rn != null) {
+ rn.writeToProto(proto,
+ StateControllerProto.ConnectivityController.TrackedJob.REQUIRED_NETWORK);
+ }
+ proto.end(jsToken);
+ }
+
+ proto.end(mToken);
+ proto.end(token);
+ }
}
import android.util.TimeUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
+import android.util.proto.ProtoOutputStream;
import com.android.internal.annotations.VisibleForTesting;
import com.android.server.job.JobSchedulerService;
import com.android.server.job.StateChangedListener;
+import com.android.server.job.StateControllerProto;
+import com.android.server.job.StateControllerProto.ContentObserverController.Observer.TriggerContentData;
import java.io.PrintWriter;
import java.util.ArrayList;
}
}
}
+
+ @Override
+ public void dumpControllerStateLocked(ProtoOutputStream proto, long fieldId, int filterUid) {
+ final long token = proto.start(fieldId);
+ final long mToken = proto.start(StateControllerProto.CONTENT_OBSERVER);
+
+ for (int i = 0; i < mTrackedTasks.size(); i++) {
+ JobStatus js = mTrackedTasks.valueAt(i);
+ if (!js.shouldDump(filterUid)) {
+ continue;
+ }
+ final long jsToken =
+ proto.start(StateControllerProto.ContentObserverController.TRACKED_JOBS);
+ js.writeToShortProto(proto,
+ StateControllerProto.ContentObserverController.TrackedJob.INFO);
+ proto.write(StateControllerProto.ContentObserverController.TrackedJob.SOURCE_UID,
+ js.getSourceUid());
+ proto.end(jsToken);
+ }
+
+ final int n = mObservers.size();
+ for (int userIdx = 0; userIdx < n; userIdx++) {
+ final long oToken =
+ proto.start(StateControllerProto.ContentObserverController.OBSERVERS);
+ final int userId = mObservers.keyAt(userIdx);
+
+ proto.write(StateControllerProto.ContentObserverController.Observer.USER_ID, userId);
+
+ ArrayMap<JobInfo.TriggerContentUri, ObserverInstance> observersOfUser =
+ mObservers.get(userId);
+ int numbOfObserversPerUser = observersOfUser.size();
+ for (int observerIdx = 0 ; observerIdx < numbOfObserversPerUser; observerIdx++) {
+ ObserverInstance obs = observersOfUser.valueAt(observerIdx);
+ int m = obs.mJobs.size();
+ boolean shouldDump = false;
+ for (int j = 0; j < m; j++) {
+ JobInstance inst = obs.mJobs.valueAt(j);
+ if (inst.mJobStatus.shouldDump(filterUid)) {
+ shouldDump = true;
+ break;
+ }
+ }
+ if (!shouldDump) {
+ continue;
+ }
+ final long tToken = proto.start(
+ StateControllerProto.ContentObserverController.Observer.TRIGGERS);
+
+ JobInfo.TriggerContentUri trigger = observersOfUser.keyAt(observerIdx);
+ Uri u = trigger.getUri();
+ if (u != null) {
+ proto.write(TriggerContentData.URI, u.toString());
+ }
+ proto.write(TriggerContentData.FLAGS, trigger.getFlags());
+
+ for (int j = 0; j < m; j++) {
+ final long jToken = proto.start(TriggerContentData.JOBS);
+ JobInstance inst = obs.mJobs.valueAt(j);
+
+ inst.mJobStatus.writeToShortProto(proto, TriggerContentData.JobInstance.INFO);
+ proto.write(TriggerContentData.JobInstance.SOURCE_UID,
+ inst.mJobStatus.getSourceUid());
+
+ if (inst.mChangedAuthorities == null) {
+ proto.end(jToken);
+ continue;
+ }
+ if (inst.mTriggerPending) {
+ proto.write(TriggerContentData.JobInstance.TRIGGER_CONTENT_UPDATE_DELAY_MS,
+ inst.mJobStatus.getTriggerContentUpdateDelay());
+ proto.write(TriggerContentData.JobInstance.TRIGGER_CONTENT_MAX_DELAY_MS,
+ inst.mJobStatus.getTriggerContentMaxDelay());
+ }
+ for (int k = 0; k < inst.mChangedAuthorities.size(); k++) {
+ proto.write(TriggerContentData.JobInstance.CHANGED_AUTHORITIES,
+ inst.mChangedAuthorities.valueAt(k));
+ }
+ if (inst.mChangedUris != null) {
+ for (int k = 0; k < inst.mChangedUris.size(); k++) {
+ u = inst.mChangedUris.valueAt(k);
+ if (u != null) {
+ proto.write(TriggerContentData.JobInstance.CHANGED_URIS,
+ u.toString());
+ }
+ }
+ }
+
+ proto.end(jToken);
+ }
+
+ proto.end(tToken);
+ }
+
+ proto.end(oToken);
+ }
+
+ proto.end(mToken);
+ proto.end(token);
+ }
}
import android.util.ArraySet;
import android.util.Slog;
import android.util.SparseBooleanArray;
+import android.util.proto.ProtoOutputStream;
import com.android.internal.util.ArrayUtils;
import com.android.server.DeviceIdleController;
import com.android.server.LocalServices;
import com.android.server.job.JobSchedulerService;
import com.android.server.job.JobStore;
+import com.android.server.job.StateControllerProto;
+import com.android.server.job.StateControllerProto.DeviceIdleJobsController.TrackedJob;
import java.io.PrintWriter;
import java.util.Arrays;
});
}
+ @Override
+ public void dumpControllerStateLocked(ProtoOutputStream proto, long fieldId, int filterUid) {
+ final long token = proto.start(fieldId);
+ final long mToken = proto.start(StateControllerProto.DEVICE_IDLE);
+
+ proto.write(StateControllerProto.DeviceIdleJobsController.IS_DEVICE_IDLE_MODE,
+ mDeviceIdleMode);
+ mJobSchedulerService.getJobStore().forEachJob(new JobStore.JobStatusFunctor() {
+ @Override public void process(JobStatus jobStatus) {
+ if (!jobStatus.shouldDump(filterUid)) {
+ return;
+ }
+ final long jsToken =
+ proto.start(StateControllerProto.DeviceIdleJobsController.TRACKED_JOBS);
+
+ jobStatus.writeToShortProto(proto, TrackedJob.INFO);
+ proto.write(TrackedJob.SOURCE_UID, jobStatus.getSourceUid());
+ proto.write(TrackedJob.SOURCE_PACKAGE_NAME, jobStatus.getSourcePackageName());
+ proto.write(TrackedJob.ARE_CONSTRAINTS_SATISFIED,
+ (jobStatus.satisfiedConstraints &
+ JobStatus.CONSTRAINT_DEVICE_NOT_DOZING) != 0);
+ proto.write(TrackedJob.IS_DOZE_WHITELISTED, jobStatus.dozeWhitelisted);
+ proto.write(TrackedJob.IS_ALLOWED_IN_DOZE, mAllowInIdleJobs.contains(jobStatus));
+
+ proto.end(jsToken);
+ }
+ });
+
+ proto.end(mToken);
+ proto.end(token);
+ }
+
final class DeviceIdleUpdateFunctor implements JobStore.JobStatusFunctor {
boolean mChanged;
}
}
}
-}
\ No newline at end of file
+}
import android.os.UserHandle;
import android.util.ArraySet;
import android.util.Slog;
+import android.util.proto.ProtoOutputStream;
import com.android.server.am.ActivityManagerService;
import com.android.server.job.JobSchedulerService;
import com.android.server.job.StateChangedListener;
+import com.android.server.job.StateControllerProto;
import java.io.PrintWriter;
pw.println();
}
}
+
+ @Override
+ public void dumpControllerStateLocked(ProtoOutputStream proto, long fieldId, int filterUid) {
+ final long token = proto.start(fieldId);
+ final long mToken = proto.start(StateControllerProto.IDLE);
+
+ proto.write(StateControllerProto.IdleController.IS_IDLE, mIdleTracker.isIdle());
+
+ for (int i = 0; i < mTrackedTasks.size(); i++) {
+ final JobStatus js = mTrackedTasks.valueAt(i);
+ if (!js.shouldDump(filterUid)) {
+ continue;
+ }
+ final long jsToken = proto.start(StateControllerProto.IdleController.TRACKED_JOBS);
+ js.writeToShortProto(proto, StateControllerProto.IdleController.TrackedJob.INFO);
+ proto.write(StateControllerProto.IdleController.TrackedJob.SOURCE_UID,
+ js.getSourceUid());
+ proto.end(jsToken);
+ }
+
+ proto.end(mToken);
+ proto.end(token);
+ }
}
import android.util.Pair;
import android.util.Slog;
import android.util.TimeUtils;
+import android.util.proto.ProtoOutputStream;
import com.android.server.LocalServices;
import com.android.server.job.GrantedUriPermissions;
import com.android.server.job.JobSchedulerInternal;
import com.android.server.job.JobSchedulerService;
+import com.android.server.job.JobStatusDumpProto;
+import com.android.server.job.JobStatusShortInfoProto;
import java.io.PrintWriter;
import java.util.ArrayList;
return sb.toString();
}
+ /**
+ * Convenience function to dump data that identifies a job uniquely to proto. This is intended
+ * to mimic {@link #toShortString}.
+ */
+ public void writeToShortProto(ProtoOutputStream proto, long fieldId) {
+ final long token = proto.start(fieldId);
+
+ proto.write(JobStatusShortInfoProto.CALLING_UID, callingUid);
+ proto.write(JobStatusShortInfoProto.JOB_ID, job.getId());
+ proto.write(JobStatusShortInfoProto.BATTERY_NAME, batteryName);
+
+ proto.end(token);
+ }
+
void dumpConstraints(PrintWriter pw, int constraints) {
if ((constraints&CONSTRAINT_CHARGING) != 0) {
pw.print(" CHARGING");
}
}
+ /** Writes constraints to the given repeating proto field. */
+ void dumpConstraints(ProtoOutputStream proto, long fieldId, int constraints) {
+ if ((constraints & CONSTRAINT_CHARGING) != 0) {
+ proto.write(fieldId, JobStatusDumpProto.CONSTRAINT_CHARGING);
+ }
+ if ((constraints & CONSTRAINT_BATTERY_NOT_LOW) != 0) {
+ proto.write(fieldId, JobStatusDumpProto.CONSTRAINT_BATTERY_NOT_LOW);
+ }
+ if ((constraints & CONSTRAINT_STORAGE_NOT_LOW) != 0) {
+ proto.write(fieldId, JobStatusDumpProto.CONSTRAINT_STORAGE_NOT_LOW);
+ }
+ if ((constraints & CONSTRAINT_TIMING_DELAY) != 0) {
+ proto.write(fieldId, JobStatusDumpProto.CONSTRAINT_TIMING_DELAY);
+ }
+ if ((constraints & CONSTRAINT_DEADLINE) != 0) {
+ proto.write(fieldId, JobStatusDumpProto.CONSTRAINT_DEADLINE);
+ }
+ if ((constraints & CONSTRAINT_IDLE) != 0) {
+ proto.write(fieldId, JobStatusDumpProto.CONSTRAINT_IDLE);
+ }
+ if ((constraints & CONSTRAINT_CONNECTIVITY) != 0) {
+ proto.write(fieldId, JobStatusDumpProto.CONSTRAINT_CONNECTIVITY);
+ }
+ if ((constraints & CONSTRAINT_APP_NOT_IDLE) != 0) {
+ proto.write(fieldId, JobStatusDumpProto.CONSTRAINT_APP_NOT_IDLE);
+ }
+ if ((constraints & CONSTRAINT_CONTENT_TRIGGER) != 0) {
+ proto.write(fieldId, JobStatusDumpProto.CONSTRAINT_CONTENT_TRIGGER);
+ }
+ if ((constraints & CONSTRAINT_DEVICE_NOT_DOZING) != 0) {
+ proto.write(fieldId, JobStatusDumpProto.CONSTRAINT_DEVICE_NOT_DOZING);
+ }
+ }
+
private void dumpJobWorkItem(PrintWriter pw, String prefix, JobWorkItem work, int index) {
pw.print(prefix); pw.print(" #"); pw.print(index); pw.print(": #");
pw.print(work.getWorkId()); pw.print(" "); pw.print(work.getDeliveryCount());
}
}
+ private void dumpJobWorkItem(ProtoOutputStream proto, long fieldId, JobWorkItem work) {
+ final long token = proto.start(fieldId);
+
+ proto.write(JobStatusDumpProto.JobWorkItem.WORK_ID, work.getWorkId());
+ proto.write(JobStatusDumpProto.JobWorkItem.DELIVERY_COUNT, work.getDeliveryCount());
+ if (work.getIntent() != null) {
+ work.getIntent().writeToProto(proto, JobStatusDumpProto.JobWorkItem.INTENT);
+ }
+ Object grants = work.getGrants();
+ if (grants != null) {
+ ((GrantedUriPermissions) grants).dump(proto, JobStatusDumpProto.JobWorkItem.URI_GRANTS);
+ }
+
+ proto.end(token);
+ }
+
// normalized bucket indices, not the AppStandby constants
private String bucketName(int bucket) {
switch (bucket) {
pw.println(t.format(format));
}
}
+
+ public void dump(ProtoOutputStream proto, long fieldId, boolean full, long elapsedRealtimeMillis) {
+ final long token = proto.start(fieldId);
+
+ proto.write(JobStatusDumpProto.CALLING_UID, callingUid);
+ proto.write(JobStatusDumpProto.TAG, tag);
+ proto.write(JobStatusDumpProto.SOURCE_UID, getSourceUid());
+ proto.write(JobStatusDumpProto.SOURCE_USER_ID, getSourceUserId());
+ proto.write(JobStatusDumpProto.SOURCE_PACKAGE_NAME, getSourcePackageName());
+
+ if (full) {
+ final long jiToken = proto.start(JobStatusDumpProto.JOB_INFO);
+
+ job.getService().writeToProto(proto, JobStatusDumpProto.JobInfo.SERVICE);
+
+ proto.write(JobStatusDumpProto.JobInfo.IS_PERIODIC, job.isPeriodic());
+ proto.write(JobStatusDumpProto.JobInfo.PERIOD_INTERVAL_MS, job.getIntervalMillis());
+ proto.write(JobStatusDumpProto.JobInfo.PERIOD_FLEX_MS, job.getFlexMillis());
+
+ proto.write(JobStatusDumpProto.JobInfo.IS_PERSISTED, job.isPersisted());
+ proto.write(JobStatusDumpProto.JobInfo.PRIORITY, job.getPriority());
+ proto.write(JobStatusDumpProto.JobInfo.FLAGS, job.getFlags());
+
+ proto.write(JobStatusDumpProto.JobInfo.REQUIRES_CHARGING, job.isRequireCharging());
+ proto.write(JobStatusDumpProto.JobInfo.REQUIRES_BATTERY_NOT_LOW, job.isRequireBatteryNotLow());
+ proto.write(JobStatusDumpProto.JobInfo.REQUIRES_DEVICE_IDLE, job.isRequireDeviceIdle());
+
+ if (job.getTriggerContentUris() != null) {
+ for (int i = 0; i < job.getTriggerContentUris().length; i++) {
+ final long tcuToken = proto.start(JobStatusDumpProto.JobInfo.TRIGGER_CONTENT_URIS);
+ JobInfo.TriggerContentUri trig = job.getTriggerContentUris()[i];
+
+ proto.write(JobStatusDumpProto.JobInfo.TriggerContentUri.FLAGS, trig.getFlags());
+ Uri u = trig.getUri();
+ if (u != null) {
+ proto.write(JobStatusDumpProto.JobInfo.TriggerContentUri.URI, u.toString());
+ }
+
+ proto.end(tcuToken);
+ }
+ if (job.getTriggerContentUpdateDelay() >= 0) {
+ proto.write(JobStatusDumpProto.JobInfo.TRIGGER_CONTENT_UPDATE_DELAY_MS,
+ job.getTriggerContentUpdateDelay());
+ }
+ if (job.getTriggerContentMaxDelay() >= 0) {
+ proto.write(JobStatusDumpProto.JobInfo.TRIGGER_CONTENT_MAX_DELAY_MS,
+ job.getTriggerContentMaxDelay());
+ }
+ }
+ if (job.getExtras() != null && !job.getExtras().maybeIsEmpty()) {
+ job.getExtras().writeToProto(proto, JobStatusDumpProto.JobInfo.EXTRAS);
+ }
+ if (job.getTransientExtras() != null && !job.getTransientExtras().maybeIsEmpty()) {
+ job.getTransientExtras().writeToProto(proto, JobStatusDumpProto.JobInfo.TRANSIENT_EXTRAS);
+ }
+ if (job.getClipData() != null) {
+ job.getClipData().writeToProto(proto, JobStatusDumpProto.JobInfo.CLIP_DATA);
+ }
+ if (uriPerms != null) {
+ uriPerms.dump(proto, JobStatusDumpProto.JobInfo.GRANTED_URI_PERMISSIONS);
+ }
+ if (job.getRequiredNetwork() != null) {
+ job.getRequiredNetwork().writeToProto(proto, JobStatusDumpProto.JobInfo.REQUIRED_NETWORK);
+ }
+ if (totalNetworkBytes != JobInfo.NETWORK_BYTES_UNKNOWN) {
+ proto.write(JobStatusDumpProto.JobInfo.TOTAL_NETWORK_BYTES, totalNetworkBytes);
+ }
+ proto.write(JobStatusDumpProto.JobInfo.MIN_LATENCY_MS, job.getMinLatencyMillis());
+ proto.write(JobStatusDumpProto.JobInfo.MAX_EXECUTION_DELAY_MS, job.getMaxExecutionDelayMillis());
+
+ final long bpToken = proto.start(JobStatusDumpProto.JobInfo.BACKOFF_POLICY);
+ proto.write(JobStatusDumpProto.JobInfo.Backoff.POLICY, job.getBackoffPolicy());
+ proto.write(JobStatusDumpProto.JobInfo.Backoff.INITIAL_BACKOFF_MS,
+ job.getInitialBackoffMillis());
+ proto.end(bpToken);
+
+ proto.write(JobStatusDumpProto.JobInfo.HAS_EARLY_CONSTRAINT, job.hasEarlyConstraint());
+ proto.write(JobStatusDumpProto.JobInfo.HAS_LATE_CONSTRAINT, job.hasLateConstraint());
+
+ proto.end(jiToken);
+ }
+
+ dumpConstraints(proto, JobStatusDumpProto.REQUIRED_CONSTRAINTS, requiredConstraints);
+ if (full) {
+ dumpConstraints(proto, JobStatusDumpProto.SATISFIED_CONSTRAINTS, satisfiedConstraints);
+ dumpConstraints(proto, JobStatusDumpProto.UNSATISFIED_CONSTRAINTS,
+ (requiredConstraints & ~satisfiedConstraints));
+ proto.write(JobStatusDumpProto.IS_DOZE_WHITELISTED, dozeWhitelisted);
+ }
+
+ // Tracking controllers
+ if ((trackingControllers&TRACKING_BATTERY) != 0) {
+ proto.write(JobStatusDumpProto.TRACKING_CONTROLLERS,
+ JobStatusDumpProto.TRACKING_BATTERY);
+ }
+ if ((trackingControllers&TRACKING_CONNECTIVITY) != 0) {
+ proto.write(JobStatusDumpProto.TRACKING_CONTROLLERS,
+ JobStatusDumpProto.TRACKING_CONNECTIVITY);
+ }
+ if ((trackingControllers&TRACKING_CONTENT) != 0) {
+ proto.write(JobStatusDumpProto.TRACKING_CONTROLLERS,
+ JobStatusDumpProto.TRACKING_CONTENT);
+ }
+ if ((trackingControllers&TRACKING_IDLE) != 0) {
+ proto.write(JobStatusDumpProto.TRACKING_CONTROLLERS,
+ JobStatusDumpProto.TRACKING_IDLE);
+ }
+ if ((trackingControllers&TRACKING_STORAGE) != 0) {
+ proto.write(JobStatusDumpProto.TRACKING_CONTROLLERS,
+ JobStatusDumpProto.TRACKING_STORAGE);
+ }
+ if ((trackingControllers&TRACKING_TIME) != 0) {
+ proto.write(JobStatusDumpProto.TRACKING_CONTROLLERS,
+ JobStatusDumpProto.TRACKING_TIME);
+ }
+
+ if (changedAuthorities != null) {
+ for (int k = 0; k < changedAuthorities.size(); k++) {
+ proto.write(JobStatusDumpProto.CHANGED_AUTHORITIES, changedAuthorities.valueAt(k));
+ }
+ }
+ if (changedUris != null) {
+ for (int i = 0; i < changedUris.size(); i++) {
+ Uri u = changedUris.valueAt(i);
+ proto.write(JobStatusDumpProto.CHANGED_URIS, u.toString());
+ }
+ }
+
+ if (network != null) {
+ network.writeToProto(proto, JobStatusDumpProto.NETWORK);
+ }
+
+ if (pendingWork != null && pendingWork.size() > 0) {
+ for (int i = 0; i < pendingWork.size(); i++) {
+ dumpJobWorkItem(proto, JobStatusDumpProto.PENDING_WORK, pendingWork.get(i));
+ }
+ }
+ if (executingWork != null && executingWork.size() > 0) {
+ for (int i = 0; i < executingWork.size(); i++) {
+ dumpJobWorkItem(proto, JobStatusDumpProto.EXECUTING_WORK, executingWork.get(i));
+ }
+ }
+
+ proto.write(JobStatusDumpProto.STANDBY_BUCKET, standbyBucket);
+ proto.write(JobStatusDumpProto.ENQUEUE_DURATION_MS, elapsedRealtimeMillis - enqueueTime);
+ if (earliestRunTimeElapsedMillis == NO_EARLIEST_RUNTIME) {
+ proto.write(JobStatusDumpProto.TIME_UNTIL_EARLIEST_RUNTIME_MS, 0);
+ } else {
+ proto.write(JobStatusDumpProto.TIME_UNTIL_EARLIEST_RUNTIME_MS,
+ earliestRunTimeElapsedMillis - elapsedRealtimeMillis);
+ }
+ if (latestRunTimeElapsedMillis == NO_LATEST_RUNTIME) {
+ proto.write(JobStatusDumpProto.TIME_UNTIL_LATEST_RUNTIME_MS, 0);
+ } else {
+ proto.write(JobStatusDumpProto.TIME_UNTIL_LATEST_RUNTIME_MS,
+ latestRunTimeElapsedMillis - elapsedRealtimeMillis);
+ }
+
+ proto.write(JobStatusDumpProto.NUM_FAILURES, numFailures);
+ proto.write(JobStatusDumpProto.LAST_SUCCESSFUL_RUN_TIME, mLastSuccessfulRunTime);
+ proto.write(JobStatusDumpProto.LAST_FAILED_RUN_TIME, mLastFailedRunTime);
+
+ proto.end(token);
+ }
}
package com.android.server.job.controllers;
import android.content.Context;
+import android.util.proto.ProtoOutputStream;
import com.android.server.job.JobSchedulerService;
import com.android.server.job.StateChangedListener;
}
public abstract void dumpControllerStateLocked(PrintWriter pw, int filterUid);
+ public abstract void dumpControllerStateLocked(ProtoOutputStream proto, long fieldId,
+ int filterUid);
}
import android.os.UserHandle;
import android.util.ArraySet;
import android.util.Slog;
+import android.util.proto.ProtoOutputStream;
import com.android.internal.annotations.VisibleForTesting;
import com.android.server.job.JobSchedulerService;
import com.android.server.job.StateChangedListener;
+import com.android.server.job.StateControllerProto;
import com.android.server.storage.DeviceStorageMonitorService;
import java.io.PrintWriter;
*/
private boolean mStorageLow;
/** Sequence number of last broadcast. */
- private int mLastBatterySeq = -1;
+ private int mLastStorageSeq = -1;
public StorageTracker() {
}
}
public int getSeq() {
- return mLastBatterySeq;
+ return mLastStorageSeq;
}
@Override
@VisibleForTesting
public void onReceiveInternal(Intent intent) {
final String action = intent.getAction();
- mLastBatterySeq = intent.getIntExtra(DeviceStorageMonitorService.EXTRA_SEQUENCE,
- mLastBatterySeq);
+ mLastStorageSeq = intent.getIntExtra(DeviceStorageMonitorService.EXTRA_SEQUENCE,
+ mLastStorageSeq);
if (Intent.ACTION_DEVICE_STORAGE_LOW.equals(action)) {
if (DEBUG) {
Slog.d(TAG, "Available storage too low to do work. @ "
pw.println();
}
}
+
+ @Override
+ public void dumpControllerStateLocked(ProtoOutputStream proto, long fieldId, int filterUid) {
+ final long token = proto.start(fieldId);
+ final long mToken = proto.start(StateControllerProto.STORAGE);
+
+ proto.write(StateControllerProto.StorageController.IS_STORAGE_NOT_LOW,
+ mStorageTracker.isStorageNotLow());
+ proto.write(StateControllerProto.StorageController.LAST_BROADCAST_SEQUENCE_NUMBER,
+ mStorageTracker.getSeq());
+
+ for (int i = 0; i < mTrackedTasks.size(); i++) {
+ final JobStatus js = mTrackedTasks.valueAt(i);
+ if (!js.shouldDump(filterUid)) {
+ continue;
+ }
+ final long jsToken = proto.start(StateControllerProto.StorageController.TRACKED_JOBS);
+ js.writeToShortProto(proto, StateControllerProto.StorageController.TrackedJob.INFO);
+ proto.write(StateControllerProto.StorageController.TrackedJob.SOURCE_UID,
+ js.getSourceUid());
+ proto.end(jsToken);
+ }
+
+ proto.end(mToken);
+ proto.end(token);
+ }
}
import android.os.WorkSource;
import android.util.Slog;
import android.util.TimeUtils;
+import android.util.proto.ProtoOutputStream;
import com.android.server.job.JobSchedulerService;
import com.android.server.job.StateChangedListener;
+import com.android.server.job.StateControllerProto;
import java.io.PrintWriter;
import java.util.Iterator;
public void dumpControllerStateLocked(PrintWriter pw, int filterUid) {
final long nowElapsed = sElapsedRealtimeClock.millis();
pw.print("Alarms: now=");
- pw.print(sElapsedRealtimeClock.millis());
+ pw.print(nowElapsed);
pw.println();
pw.print("Next delay alarm in ");
TimeUtils.formatDuration(mNextDelayExpiredElapsedMillis, nowElapsed, pw);
pw.println();
}
}
-}
\ No newline at end of file
+
+ @Override
+ public void dumpControllerStateLocked(ProtoOutputStream proto, long fieldId, int filterUid) {
+ final long token = proto.start(fieldId);
+ final long mToken = proto.start(StateControllerProto.TIME);
+
+ final long nowElapsed = sElapsedRealtimeClock.millis();
+ proto.write(StateControllerProto.TimeController.NOW_ELAPSED_REALTIME, nowElapsed);
+ proto.write(StateControllerProto.TimeController.TIME_UNTIL_NEXT_DELAY_ALARM_MS,
+ mNextDelayExpiredElapsedMillis - nowElapsed);
+ proto.write(StateControllerProto.TimeController.TIME_UNTIL_NEXT_DEADLINE_ALARM_MS,
+ mNextJobExpiredElapsedMillis - nowElapsed);
+
+ for (JobStatus ts : mTrackedJobs) {
+ if (!ts.shouldDump(filterUid)) {
+ continue;
+ }
+ final long tsToken = proto.start(StateControllerProto.TimeController.TRACKED_JOBS);
+ ts.writeToShortProto(proto, StateControllerProto.TimeController.TrackedJob.INFO);
+
+ proto.write(StateControllerProto.TimeController.TrackedJob.HAS_TIMING_DELAY_CONSTRAINT,
+ ts.hasTimingDelayConstraint());
+ proto.write(StateControllerProto.TimeController.TrackedJob.DELAY_TIME_REMAINING_MS,
+ ts.getEarliestRunTime() - nowElapsed);
+
+ proto.write(StateControllerProto.TimeController.TrackedJob.HAS_DEADLINE_CONSTRAINT,
+ ts.hasDeadlineConstraint());
+ proto.write(StateControllerProto.TimeController.TrackedJob.TIME_REMAINING_UNTIL_DEADLINE_MS,
+ ts.getLatestRunTimeElapsed() - nowElapsed);
+
+ proto.end(tsToken);
+ }
+
+ proto.end(mToken);
+ proto.end(token);
+ }
+}
for (ComponentName cmpt : mEnabledServicesForCurrentProfiles) {
if (filter != null && !filter.matches(cmpt)) continue;
- final long cToken = proto.start(ManagedServicesProto.ENABLED);
- cmpt.toProto(proto);
- proto.end(cToken);
+ cmpt.writeToProto(proto, ManagedServicesProto.ENABLED);
}
for (ManagedServiceInfo info : mServices) {
if (filter != null && !filter.matches(info.component)) continue;
- final long lToken = proto.start(ManagedServicesProto.LIVE_SERVICES);
- info.toProto(proto, this);
- proto.end(lToken);
+ info.writeToProto(proto, ManagedServicesProto.LIVE_SERVICES, this);
}
for (ComponentName name : mSnoozingForCurrentProfiles) {
- final long cToken = proto.start(ManagedServicesProto.SNOOZED);
- name.toProto(proto);
- proto.end(cToken);
+ name.writeToProto(proto, ManagedServicesProto.SNOOZED);
}
}
.append(']').toString();
}
- public void toProto(ProtoOutputStream proto, ManagedServices host) {
- final long cToken = proto.start(ManagedServiceInfoProto.COMPONENT);
- component.toProto(proto);
- proto.end(cToken);
+ public void writeToProto(ProtoOutputStream proto, long fieldId, ManagedServices host) {
+ final long token = proto.start(fieldId);
+
+ component.writeToProto(proto, ManagedServiceInfoProto.COMPONENT);
proto.write(ManagedServiceInfoProto.USER_ID, userid);
proto.write(ManagedServiceInfoProto.SERVICE, service.getClass().getName());
proto.write(ManagedServiceInfoProto.IS_SYSTEM, isSystem);
proto.write(ManagedServiceInfoProto.IS_GUEST, isGuest(host));
+
+ proto.end(token);
}
public boolean enabledAndUserMatches(int nid) {
mListenersDisablingEffects.valueAt(i);
for (int j = 0; j < listeners.size(); j++) {
final ManagedServiceInfo listener = listeners.valueAt(i);
- listenersToken = proto.start(ListenersDisablingEffectsProto.LISTENERS);
- listener.toProto(proto, null);
- proto.end(listenersToken);
+ listener.writeToProto(proto, ListenersDisablingEffectsProto.LISTENERS, null);
}
proto.end(effectsToken);