summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Yi Jin <jinyithu@google.com> 2017-11-28 14:23:56 -0800
committer Yi Jin <jinyithu@google.com> 2018-01-23 16:49:58 -0800
commit148d7f4291d675fc17852d530be32b7dba06fc93 (patch)
tree269619facc7ef65d2bec11d968b6df1cb49d677f
parent5dd54fdfb6df623c85bfdafc87b578750160f455 (diff)
Implement activity --proto --processes
Bug: 66729158 Test: out/host/linux-x86/bin/incident_report -w amprocesses Change-Id: Iae043203bca954bfc4aadad0460cc56621e9ba05
-rw-r--r--core/java/android/app/ProfilerInfo.java15
-rw-r--r--core/java/android/content/pm/ApplicationInfo.java100
-rw-r--r--core/java/android/content/pm/PackageItemInfo.java21
-rw-r--r--core/java/android/os/PowerManager.java16
-rw-r--r--core/java/android/os/PowerManagerInternal.java18
-rw-r--r--core/java/android/util/proto/ProtoUtils.java22
-rw-r--r--core/proto/android/app/activitymanager.proto14
-rw-r--r--core/proto/android/app/profilerinfo.proto33
-rw-r--r--core/proto/android/content/package_item_info.proto82
-rw-r--r--core/proto/android/os/incident.proto5
-rw-r--r--core/proto/android/os/powermanager.proto10
-rw-r--r--core/proto/android/server/activitymanagerservice.proto370
-rw-r--r--services/core/java/com/android/server/am/ActiveInstrumentation.java25
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java583
-rw-r--r--services/core/java/com/android/server/am/AppErrors.java74
-rw-r--r--services/core/java/com/android/server/am/AppTimeTracker.java22
-rw-r--r--services/core/java/com/android/server/am/ConnectionRecord.java88
-rw-r--r--services/core/java/com/android/server/am/ProcessList.java48
-rw-r--r--services/core/java/com/android/server/am/ProcessRecord.java1
-rw-r--r--services/core/java/com/android/server/am/UidRecord.java48
-rw-r--r--services/core/java/com/android/server/am/UserController.java36
-rw-r--r--services/core/java/com/android/server/am/UserState.java21
-rw-r--r--services/core/java/com/android/server/am/VrController.java24
-rw-r--r--services/core/java/com/android/server/notification/ManagedServices.java4
24 files changed, 1557 insertions, 123 deletions
diff --git a/core/java/android/app/ProfilerInfo.java b/core/java/android/app/ProfilerInfo.java
index a295c4c61a8c..0ed1b0824946 100644
--- a/core/java/android/app/ProfilerInfo.java
+++ b/core/java/android/app/ProfilerInfo.java
@@ -20,6 +20,7 @@ import android.os.Parcel;
import android.os.ParcelFileDescriptor;
import android.os.Parcelable;
import android.util.Slog;
+import android.util.proto.ProtoOutputStream;
import java.io.IOException;
import java.util.Objects;
@@ -124,6 +125,20 @@ public class ProfilerInfo implements Parcelable {
out.writeBoolean(attachAgentDuringBind);
}
+ /** @hide */
+ public void writeToProto(ProtoOutputStream proto, long fieldId) {
+ final long token = proto.start(fieldId);
+ proto.write(ProfilerInfoProto.PROFILE_FILE, profileFile);
+ if (profileFd != null) {
+ proto.write(ProfilerInfoProto.PROFILE_FD, profileFd.getFd());
+ }
+ proto.write(ProfilerInfoProto.SAMPLING_INTERVAL, samplingInterval);
+ proto.write(ProfilerInfoProto.AUTO_STOP_PROFILER, autoStopProfiler);
+ proto.write(ProfilerInfoProto.STREAMING_OUTPUT, streamingOutput);
+ proto.write(ProfilerInfoProto.AGENT, agent);
+ proto.end(token);
+ }
+
public static final Parcelable.Creator<ProfilerInfo> CREATOR =
new Parcelable.Creator<ProfilerInfo>() {
@Override
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index 84cbdb472c13..7bdf72ff463e 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -34,6 +34,7 @@ import android.os.storage.StorageManager;
import android.text.TextUtils;
import android.util.Printer;
import android.util.SparseArray;
+import android.util.proto.ProtoOutputStream;
import com.android.internal.util.ArrayUtils;
@@ -1183,6 +1184,105 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
super.dumpBack(pw, prefix);
}
+ /** {@hide} */
+ public void writeToProto(ProtoOutputStream proto, long fieldId, int dumpFlags) {
+ long token = proto.start(fieldId);
+ super.writeToProto(proto, ApplicationInfoProto.PACKAGE);
+ proto.write(ApplicationInfoProto.PERMISSION, permission);
+ proto.write(ApplicationInfoProto.PROCESS_NAME, processName);
+ proto.write(ApplicationInfoProto.UID, uid);
+ proto.write(ApplicationInfoProto.FLAGS, flags);
+ proto.write(ApplicationInfoProto.PRIVATE_FLAGS, privateFlags);
+ proto.write(ApplicationInfoProto.THEME, theme);
+ proto.write(ApplicationInfoProto.SOURCE_DIR, sourceDir);
+ if (!Objects.equals(sourceDir, publicSourceDir)) {
+ proto.write(ApplicationInfoProto.PUBLIC_SOURCE_DIR, publicSourceDir);
+ }
+ if (!ArrayUtils.isEmpty(splitSourceDirs)) {
+ for (String dir : splitSourceDirs) {
+ proto.write(ApplicationInfoProto.SPLIT_SOURCE_DIRS, dir);
+ }
+ }
+ if (!ArrayUtils.isEmpty(splitPublicSourceDirs)
+ && !Arrays.equals(splitSourceDirs, splitPublicSourceDirs)) {
+ for (String dir : splitPublicSourceDirs) {
+ proto.write(ApplicationInfoProto.SPLIT_PUBLIC_SOURCE_DIRS, dir);
+ }
+ }
+ if (resourceDirs != null) {
+ for (String dir : resourceDirs) {
+ proto.write(ApplicationInfoProto.RESOURCE_DIRS, dir);
+ }
+ }
+ proto.write(ApplicationInfoProto.DATA_DIR, dataDir);
+ proto.write(ApplicationInfoProto.CLASS_LOADER_NAME, classLoaderName);
+ if (!ArrayUtils.isEmpty(splitClassLoaderNames)) {
+ for (String name : splitClassLoaderNames) {
+ proto.write(ApplicationInfoProto.SPLIT_CLASS_LOADER_NAMES, name);
+ }
+ }
+
+ long versionToken = proto.start(ApplicationInfoProto.VERSION);
+ proto.write(ApplicationInfoProto.Version.ENABLED, enabled);
+ proto.write(ApplicationInfoProto.Version.MIN_SDK_VERSION, minSdkVersion);
+ proto.write(ApplicationInfoProto.Version.TARGET_SDK_VERSION, targetSdkVersion);
+ proto.write(ApplicationInfoProto.Version.VERSION_CODE, versionCode);
+ proto.write(ApplicationInfoProto.Version.TARGET_SANDBOX_VERSION, targetSandboxVersion);
+ proto.end(versionToken);
+
+ if ((dumpFlags & DUMP_FLAG_DETAILS) != 0) {
+ long detailToken = proto.start(ApplicationInfoProto.DETAIL);
+ if (className != null) {
+ proto.write(ApplicationInfoProto.Detail.CLASS_NAME, className);
+ }
+ proto.write(ApplicationInfoProto.Detail.TASK_AFFINITY, taskAffinity);
+ proto.write(ApplicationInfoProto.Detail.REQUIRES_SMALLEST_WIDTH_DP,
+ requiresSmallestWidthDp);
+ proto.write(ApplicationInfoProto.Detail.COMPATIBLE_WIDTH_LIMIT_DP,
+ compatibleWidthLimitDp);
+ proto.write(ApplicationInfoProto.Detail.LARGEST_WIDTH_LIMIT_DP,
+ largestWidthLimitDp);
+ if (seInfo != null) {
+ proto.write(ApplicationInfoProto.Detail.SEINFO, seInfo);
+ proto.write(ApplicationInfoProto.Detail.SEINFO_USER, seInfoUser);
+ }
+ proto.write(ApplicationInfoProto.Detail.DEVICE_PROTECTED_DATA_DIR,
+ deviceProtectedDataDir);
+ proto.write(ApplicationInfoProto.Detail.CREDENTIAL_PROTECTED_DATA_DIR,
+ credentialProtectedDataDir);
+ if (sharedLibraryFiles != null) {
+ for (String f : sharedLibraryFiles) {
+ proto.write(ApplicationInfoProto.Detail.SHARED_LIBRARY_FILES, f);
+ }
+ }
+ if (manageSpaceActivityName != null) {
+ proto.write(ApplicationInfoProto.Detail.MANAGE_SPACE_ACTIVITY_NAME,
+ manageSpaceActivityName);
+ }
+ if (descriptionRes != 0) {
+ proto.write(ApplicationInfoProto.Detail.DESCRIPTION_RES, descriptionRes);
+ }
+ if (uiOptions != 0) {
+ proto.write(ApplicationInfoProto.Detail.UI_OPTIONS, uiOptions);
+ }
+ proto.write(ApplicationInfoProto.Detail.SUPPORTS_RTL, hasRtlSupport());
+ if (fullBackupContent > 0) {
+ proto.write(ApplicationInfoProto.Detail.CONTENT, "@xml/" + fullBackupContent);
+ } else {
+ proto.write(ApplicationInfoProto.Detail.IS_FULL_BACKUP, fullBackupContent == 0);
+ }
+ if (networkSecurityConfigRes != 0) {
+ proto.write(ApplicationInfoProto.Detail.NETWORK_SECURITY_CONFIG_RES,
+ networkSecurityConfigRes);
+ }
+ if (category != CATEGORY_UNDEFINED) {
+ proto.write(ApplicationInfoProto.Detail.CATEGORY, category);
+ }
+ proto.end(detailToken);
+ }
+ proto.end(token);
+ }
+
/**
* @return true if "supportsRtl" has been set to true in the AndroidManifest
* @hide
diff --git a/core/java/android/content/pm/PackageItemInfo.java b/core/java/android/content/pm/PackageItemInfo.java
index 11830c294116..2c0c6ad0723e 100644
--- a/core/java/android/content/pm/PackageItemInfo.java
+++ b/core/java/android/content/pm/PackageItemInfo.java
@@ -19,7 +19,6 @@ package android.content.pm;
import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.content.res.XmlResourceParser;
-
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Parcel;
@@ -28,6 +27,8 @@ import android.text.Html;
import android.text.TextPaint;
import android.text.TextUtils;
import android.util.Printer;
+import android.util.proto.ProtoOutputStream;
+
import java.text.Collator;
import java.util.Comparator;
@@ -386,6 +387,24 @@ public class PackageItemInfo {
dest.writeInt(showUserIcon);
}
+ /**
+ * @hide
+ */
+ public void writeToProto(ProtoOutputStream proto, long fieldId) {
+ long token = proto.start(fieldId);
+ if (name != null) {
+ proto.write(PackageItemInfoProto.NAME, name);
+ }
+ proto.write(PackageItemInfoProto.PACKAGE_NAME, packageName);
+ if (labelRes != 0 || nonLocalizedLabel != null || icon != 0 || banner != 0) {
+ proto.write(PackageItemInfoProto.LABEL_RES, labelRes);
+ proto.write(PackageItemInfoProto.NON_LOCALIZED_LABEL, nonLocalizedLabel.toString());
+ proto.write(PackageItemInfoProto.ICON, icon);
+ proto.write(PackageItemInfoProto.BANNER, banner);
+ }
+ proto.end(token);
+ }
+
protected PackageItemInfo(Parcel source) {
name = source.readString();
packageName = source.readString();
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index 3798a5ec15b5..61172e11fec2 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -23,6 +23,7 @@ import android.annotation.SystemApi;
import android.annotation.SystemService;
import android.content.Context;
import android.util.Log;
+import android.util.proto.ProtoOutputStream;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -1652,6 +1653,21 @@ public final class PowerManager {
}
}
+ /** @hide */
+ public void writeToProto(ProtoOutputStream proto, long fieldId) {
+ synchronized (mToken) {
+ final long token = proto.start(fieldId);
+ proto.write(PowerManagerProto.WakeLockProto.HEX_STRING,
+ Integer.toHexString(System.identityHashCode(this)));
+ proto.write(PowerManagerProto.WakeLockProto.HELD, mHeld);
+ proto.write(PowerManagerProto.WakeLockProto.INTERNAL_COUNT, mInternalCount);
+ if (mWorkSource != null) {
+ mWorkSource.writeToProto(proto, PowerManagerProto.WakeLockProto.WORK_SOURCE);
+ }
+ proto.end(token);
+ }
+ }
+
/**
* Wraps a Runnable such that this method immediately acquires the wake lock and then
* once the Runnable is done the wake lock is released.
diff --git a/core/java/android/os/PowerManagerInternal.java b/core/java/android/os/PowerManagerInternal.java
index 3ef0961f7633..c7d89b0c6e4f 100644
--- a/core/java/android/os/PowerManagerInternal.java
+++ b/core/java/android/os/PowerManagerInternal.java
@@ -71,6 +71,24 @@ public abstract class PowerManagerInternal {
}
/**
+ * Converts platform constants to proto enums.
+ */
+ public static int wakefulnessToProtoEnum(int wakefulness) {
+ switch (wakefulness) {
+ case WAKEFULNESS_ASLEEP:
+ return PowerManagerInternalProto.WAKEFULNESS_ASLEEP;
+ case WAKEFULNESS_AWAKE:
+ return PowerManagerInternalProto.WAKEFULNESS_AWAKE;
+ case WAKEFULNESS_DREAMING:
+ return PowerManagerInternalProto.WAKEFULNESS_DREAMING;
+ case WAKEFULNESS_DOZING:
+ return PowerManagerInternalProto.WAKEFULNESS_DOZING;
+ default:
+ return wakefulness;
+ }
+ }
+
+ /**
* Returns true if the wakefulness state represents an interactive state
* as defined by {@link android.os.PowerManager#isInteractive}.
*/
diff --git a/core/java/android/util/proto/ProtoUtils.java b/core/java/android/util/proto/ProtoUtils.java
index 85b7ec8265d1..c7bbb9f2a044 100644
--- a/core/java/android/util/proto/ProtoUtils.java
+++ b/core/java/android/util/proto/ProtoUtils.java
@@ -48,4 +48,26 @@ public class ProtoUtils {
proto.write(Duration.END_MS, endMs);
proto.end(token);
}
+
+ /**
+ * Helper function to write bit-wise flags to proto as repeated enums
+ * @hide
+ */
+ public static void writeBitWiseFlagsToProtoEnum(ProtoOutputStream proto, long fieldId,
+ int flags, int[] origEnums, int[] protoEnums) {
+ if (protoEnums.length != origEnums.length) {
+ throw new IllegalArgumentException("The length of origEnums must match protoEnums");
+ }
+ int len = origEnums.length;
+ for (int i = 0; i < len; i++) {
+ // handle zero flag case.
+ if (origEnums[i] == 0 && flags == 0) {
+ proto.write(fieldId, protoEnums[i]);
+ return;
+ }
+ if ((flags & origEnums[i]) != 0) {
+ proto.write(fieldId, protoEnums[i]);
+ }
+ }
+ }
}
diff --git a/core/proto/android/app/activitymanager.proto b/core/proto/android/app/activitymanager.proto
index 3412a32e7b75..03f820435151 100644
--- a/core/proto/android/app/activitymanager.proto
+++ b/core/proto/android/app/activitymanager.proto
@@ -19,6 +19,7 @@ syntax = "proto2";
package android.app;
option java_multiple_files = true;
+option java_outer_classname = "ActivityManagerProto";
// ActivityManager.java PROCESS_STATEs
enum ProcessState {
@@ -79,3 +80,16 @@ enum ProcessState {
PROCESS_STATE_NONEXISTENT = 1900;
}
+// ActivityManager.java UID_OBSERVERs flags
+enum UidObserverFlag {
+ // report changes in process state, original value is 1 << 0
+ UID_OBSERVER_FLAG_PROCSTATE = 1;
+ // report uid gone, original value is 1 << 1
+ UID_OBSERVER_FLAG_GONE = 2;
+ // report uid has become idle, original value is 1 << 2
+ UID_OBSERVER_FLAG_IDLE = 3;
+ // report uid has become active, original value is 1 << 3
+ UID_OBSERVER_FLAG_ACTIVE = 4;
+ // report uid cached state has changed, original value is 1 << 4
+ UID_OBSERVER_FLAG_CACHED = 5;
+}
diff --git a/core/proto/android/app/profilerinfo.proto b/core/proto/android/app/profilerinfo.proto
new file mode 100644
index 000000000000..ca1b935c8a25
--- /dev/null
+++ b/core/proto/android/app/profilerinfo.proto
@@ -0,0 +1,33 @@
+/*
+ * 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_package = "android.app";
+option java_multiple_files = true;
+
+package android.app;
+
+/**
+ * An android.app.ProfilerInfo object.
+ */
+message ProfilerInfoProto {
+ optional string profile_file = 1;
+ optional int32 profile_fd = 2;
+ optional int32 sampling_interval = 3;
+ optional bool auto_stop_profiler = 4;
+ optional bool streaming_output = 5;
+ optional string agent = 6;
+}
diff --git a/core/proto/android/content/package_item_info.proto b/core/proto/android/content/package_item_info.proto
new file mode 100644
index 000000000000..847015955d38
--- /dev/null
+++ b/core/proto/android/content/package_item_info.proto
@@ -0,0 +1,82 @@
+/*
+ * 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_package = "android.content.pm";
+option java_multiple_files = true;
+
+package android.content.pm;
+
+message PackageItemInfoProto {
+ optional string name = 1;
+ optional string package_name = 2;
+ optional int32 label_res = 3;
+ optional string non_localized_label = 4;
+ optional int32 icon = 5;
+ optional int32 banner = 6;
+}
+
+// Proto of android.content.pm.ApplicationInfo which extends PackageItemInfo
+message ApplicationInfoProto {
+ optional PackageItemInfoProto package = 1;
+ optional string permission = 2;
+ optional string process_name = 3;
+ optional int32 uid = 4;
+ optional int32 flags = 5;
+ optional int32 private_flags = 6;
+ optional int32 theme = 7;
+ optional string source_dir = 8;
+ optional string public_source_dir = 9;
+ repeated string split_source_dirs = 10;
+ repeated string split_public_source_dirs = 11;
+ repeated string resource_dirs = 12;
+ optional string data_dir = 13;
+ optional string class_loader_name = 14;
+ repeated string split_class_loader_names = 15;
+
+ message Version {
+ optional bool enabled = 1;
+ optional int32 min_sdk_version = 2;
+ optional int32 target_sdk_version = 3;
+ optional int32 version_code = 4;
+ optional int32 target_sandbox_version = 5;
+ }
+ optional Version version = 16;
+
+ message Detail {
+ optional string class_name = 1;
+ optional string task_affinity = 2;
+ optional int32 requires_smallest_width_dp = 3;
+ optional int32 compatible_width_limit_dp = 4;
+ optional int32 largest_width_limit_dp = 5;
+ optional string seinfo = 6;
+ optional string seinfo_user = 7;
+ optional string device_protected_data_dir = 8;
+ optional string credential_protected_data_dir = 9;
+ repeated string shared_library_files = 10;
+ optional string manage_space_activity_name = 11;
+ optional int32 description_res = 12;
+ optional int32 ui_options = 13;
+ optional bool supports_rtl = 14;
+ oneof full_backup_content {
+ string content = 15;
+ bool is_full_backup = 16;
+ }
+ optional int32 networkSecurity_config_res = 17;
+ optional int32 category = 18;
+ }
+ optional Detail detail = 17;
+}
diff --git a/core/proto/android/os/incident.proto b/core/proto/android/os/incident.proto
index e5efb90c922e..828a55f45979 100644
--- a/core/proto/android/os/incident.proto
+++ b/core/proto/android/os/incident.proto
@@ -226,7 +226,10 @@ message IncidentProto {
(section).args = "activity --proto service"
];
- optional com.android.server.am.proto.ProcessProto amprocesses = 3015;
+ optional com.android.server.am.proto.ProcessesProto amprocesses = 3015 [
+ (section).type = SECTION_DUMPSYS,
+ (section).args = "activity --proto processes"
+ ];
optional com.android.server.AlarmManagerServiceProto alarm = 3016 [
(section).type = SECTION_DUMPSYS,
diff --git a/core/proto/android/os/powermanager.proto b/core/proto/android/os/powermanager.proto
index e9f409d0d75d..8e0a607ef5a5 100644
--- a/core/proto/android/os/powermanager.proto
+++ b/core/proto/android/os/powermanager.proto
@@ -19,6 +19,8 @@ package android.os;
option java_multiple_files = true;
+import "frameworks/base/core/proto/android/os/worksource.proto";
+
message PowerManagerProto {
/* User activity events in PowerManager.java. */
enum UserActivityEvent {
@@ -85,6 +87,14 @@ message PowerManagerProto {
// the dozing state.
DRAW_WAKE_LOCK = 128;
}
+
+ // WakeLock class in android.os.PowerManager, it is the one used by sdk
+ message WakeLockProto {
+ optional string hex_string = 1;
+ optional bool held = 2;
+ optional int32 internal_count = 3;
+ optional WorkSourceProto work_source = 4;
+ }
}
message PowerManagerInternalProto {
diff --git a/core/proto/android/server/activitymanagerservice.proto b/core/proto/android/server/activitymanagerservice.proto
index d3ca496995a9..1434d820403a 100644
--- a/core/proto/android/server/activitymanagerservice.proto
+++ b/core/proto/android/server/activitymanagerservice.proto
@@ -18,11 +18,17 @@ syntax = "proto2";
package com.android.server.am.proto;
+import "frameworks/base/core/proto/android/app/activitymanager.proto";
import "frameworks/base/core/proto/android/app/notification.proto";
+import "frameworks/base/core/proto/android/app/profilerinfo.proto";
+import "frameworks/base/core/proto/android/content/component_name.proto";
+import "frameworks/base/core/proto/android/content/configuration.proto";
import "frameworks/base/core/proto/android/content/intent.proto";
+import "frameworks/base/core/proto/android/content/package_item_info.proto";
import "frameworks/base/core/proto/android/graphics/rect.proto";
import "frameworks/base/core/proto/android/internal/processstats.proto";
import "frameworks/base/core/proto/android/os/looper.proto";
+import "frameworks/base/core/proto/android/os/powermanager.proto";
import "frameworks/base/core/proto/android/server/intentresolver.proto";
import "frameworks/base/core/proto/android/server/windowmanagerservice.proto";
import "frameworks/base/core/proto/android/util/common.proto";
@@ -36,7 +42,7 @@ message ActivityManagerServiceProto {
optional ActiveServicesProto services = 3;
- optional ProcessProto processes = 4;
+ optional ProcessesProto processes = 4;
}
// "dumpsys activity --proto activities"
@@ -130,6 +136,7 @@ message ProcessRecordProto {
optional int32 user_id = 4;
optional int32 app_id = 5;
optional int32 isolated_app_id = 6;
+ optional bool persistent = 7;
}
message BroadcastRecordProto {
@@ -459,7 +466,7 @@ message ConnectionRecordProto {
WAIVE_PRIORITY = 6;
IMPORTANT = 7;
ADJUST_WITH_ACTIVITY = 8;
- FG_SERVICE_WHILE_WAKE = 9;
+ FG_SERVICE_WHILE_AWAKE = 9;
FG_SERVICE = 10;
TREAT_LIKE_ACTIVITY = 11;
VISIBLE = 12;
@@ -492,5 +499,362 @@ message IntentBindRecordProto {
}
// TODO: "dumpsys activity --proto processes"
-message ProcessProto {
+message ProcessesProto {
+ repeated ProcessRecordProto procs = 1;
+ repeated ProcessRecordProto isolated_procs = 2;
+ repeated ActiveInstrumentationProto active_instrumentations = 3;
+ repeated UidRecordProto active_uids = 4;
+ repeated UidRecordProto validate_uids = 5;
+
+ // Process LRU list (sorted by oom_adj)
+ message LruProcesses {
+ optional int32 size = 1;
+ optional int32 non_act_at = 2;
+ optional int32 non_svc_at = 3;
+ repeated ProcessOomProto list = 4;
+ }
+ optional LruProcesses lru_procs = 6;
+ repeated ProcessRecordProto pids_self_locked = 7;
+ // Foreground Processes
+ repeated ImportanceTokenProto important_procs = 8;
+ // Persisent processes that are starting
+ repeated ProcessRecordProto persistent_starting_procs = 9;
+ // Processes that are being removed
+ repeated ProcessRecordProto removed_procs = 10;
+ // Processes that are on old until the system is ready
+ repeated ProcessRecordProto on_hold_procs = 11;
+ // Processes that are waiting to GC
+ repeated ProcessToGcProto gc_procs = 12;
+ optional AppErrorsProto app_errors = 13;
+ optional UserControllerProto user_controller = 14;
+ optional ProcessRecordProto home_proc = 15;
+ optional ProcessRecordProto previous_proc = 16;
+ optional int64 previous_proc_visible_time_ms = 17;
+ optional ProcessRecordProto heavy_weight_proc = 18;
+ optional .android.content.ConfigurationProto global_configuration = 19;
+ // ActivityStackSupervisorProto dumps these values as well, still here?
+ // repeated ActivityDisplayProto displays = 20;
+
+ optional bool config_will_change = 21;
+
+ message ScreenCompatPackage {
+ optional string package = 1;
+ optional int32 mode = 2;
+ }
+ repeated ScreenCompatPackage screen_compat_packages = 22;
+
+ message UidObserverRegistrationProto {
+ optional int32 uid = 1;
+ optional string package = 2;
+ repeated .android.app.UidObserverFlag flags = 3;
+ optional int32 cut_point = 4; // only available when UID_OBSERVER_PROCSTATE is on
+
+ message ProcState {
+ optional int32 uid = 1;
+ optional int32 state = 2;
+ }
+ repeated ProcState last_proc_states = 5;
+ }
+ repeated UidObserverRegistrationProto uid_observers = 23;
+ repeated int32 device_idle_whitelist = 24;
+ repeated int32 device_idle_temp_whitelist = 25;
+
+ message PendingTempWhitelist {
+ optional int32 target_uid = 1;
+ optional int64 duration_ms = 2;
+ optional string tag = 3;
+ }
+ repeated PendingTempWhitelist pending_temp_whitelist = 26;
+
+ message SleepStatus {
+ optional .android.os.PowerManagerInternalProto.Wakefulness wakefulness = 1;
+ repeated string sleep_tokens = 2;
+ optional bool sleeping = 3;
+ optional bool shutting_down = 4;
+ optional bool test_pss_mode = 5;
+ }
+ optional SleepStatus sleep_status = 27;
+
+ message VoiceProto {
+ optional string session = 1;
+ optional .android.os.PowerManagerProto.WakeLockProto wakelock = 2;
+ }
+ optional VoiceProto running_voice = 28;
+
+ message VrControllerProto {
+ enum VrMode {
+ FLAG_NON_VR_MODE = 0;
+ FLAG_VR_MODE = 1;
+ FLAG_PERSISTENT_VR_MODE = 2;
+ }
+ repeated VrMode vr_mode = 1;
+ optional int32 render_thread_id = 2;
+ }
+ optional VrControllerProto vr_controller = 29;
+
+ message DebugApp {
+ optional string debug_app = 1;
+ optional string orig_debug_app = 2;
+ optional bool debug_transient = 3;
+ optional bool orig_wait_for_debugger = 4;
+ }
+ optional DebugApp debug = 30;
+ optional AppTimeTrackerProto current_tracker = 31;
+
+ message MemWatchProcess {
+ message Process {
+ optional string name = 1;
+
+ message MemStats {
+ optional int32 uid = 1;
+ optional string size = 2;
+ optional string report_to = 3;
+ }
+ repeated MemStats mem_stats = 2;
+ }
+ repeated Process procs = 1;
+
+ message Dump {
+ optional string proc_name = 1;
+ optional string file = 2;
+ optional int32 pid = 3;
+ optional int32 uid = 4;
+ }
+ optional Dump dump = 2;
+ }
+ optional MemWatchProcess mem_watch_processes = 32;
+ optional string track_allocation_app = 33;
+
+ message Profile {
+ optional string app_name = 1;
+ optional ProcessRecordProto proc = 2;
+ optional .android.app.ProfilerInfoProto info = 3;
+ optional int32 type = 4;
+ }
+ optional Profile profile = 34;
+ optional string native_debugging_app = 35;
+ optional bool always_finish_activities = 36;
+
+ message Controller {
+ optional string controller = 1;
+ optional bool is_a_monkey = 2;
+ }
+ optional Controller controller = 37;
+
+ optional int32 total_persistent_procs = 38;
+ optional bool processes_ready = 39;
+ optional bool system_ready = 40;
+ optional bool booted = 41;
+ optional int32 factory_test = 42;
+ optional bool booting = 43;
+ optional bool call_finish_booting = 44;
+ optional bool boot_animation_complete = 45;
+ optional int64 last_power_check_uptime_ms = 46;
+ optional .android.os.PowerManagerProto.WakeLockProto going_to_sleep = 47;
+ optional .android.os.PowerManagerProto.WakeLockProto launching_activity = 48;
+ optional int32 adj_seq = 49;
+ optional int32 lru_seq = 50;
+ optional int32 num_non_cached_procs = 51;
+ optional int32 num_cached_hidden_procs = 52;
+ optional int32 num_service_procs = 53;
+ optional int32 new_num_service_procs = 54;
+ optional bool allow_lower_mem_level = 55;
+ optional int32 last_memory_level = 56;
+ optional int32 last_num_processes = 57;
+ optional .android.util.Duration last_idle_time = 58;
+ optional int64 low_ram_since_last_idle_ms = 59;
+}
+
+message ActiveInstrumentationProto {
+ optional .android.content.ComponentNameProto class = 1;
+ optional bool finished = 2;
+ repeated ProcessRecordProto running_processes = 3;
+ repeated string target_processes = 4;
+ optional .android.content.pm.ApplicationInfoProto target_info = 5;
+ optional string profile_file = 6;
+ optional string watcher = 7;
+ optional string ui_automation_connection = 8;
+ optional string arguments = 9;
+}
+
+// Proto definition of com.android.server.am.UidRecord.java
+message UidRecordProto {
+ optional string hex_hash = 1;
+ optional int32 uid = 2;
+ optional .android.app.ProcessState current = 3;
+ optional bool ephemeral = 4;
+ optional bool fg_services = 5;
+ optional bool whilelist = 6;
+ optional .android.util.Duration last_background_time = 7;
+ optional bool idle = 8;
+
+ enum Change {
+ CHANGE_GONE = 0;
+ CHANGE_IDLE = 1;
+ CHANGE_ACTIVE = 2;
+ CHANGE_CACHED = 3;
+ CHANGE_UNCACHED = 4;
+ }
+ repeated Change last_reported_changes = 9;
+ optional int32 num_procs = 10;
+
+ message ProcStateSequence {
+ optional int64 cururent = 1;
+ optional int64 last_network_updated = 2;
+ optional int64 last_dispatched = 3;
+ }
+ optional ProcStateSequence network_state_update = 11;
+}
+
+// proto of class ImportanceToken in ActivityManagerService
+message ImportanceTokenProto {
+ optional int32 pid = 1;
+ optional string token = 2;
+ optional string reason = 3;
+}
+
+message ProcessOomProto {
+ optional bool persistent = 1;
+ optional int32 num = 2;
+ optional string oom_adj = 3;
+
+ // Activity manager's version of Process enum, see ProcessList.java
+ enum SchedGroup {
+ SCHED_GROUP_UNKNOWN = -1;
+ SCHED_GROUP_BACKGROUND = 0;
+ SCHED_GROUP_DEFAULT = 1;
+ SCHED_GROUP_TOP_APP = 2;
+ SCHED_GROUP_TOP_APP_BOUND = 3;
+ }
+ optional SchedGroup sched_group = 4 [ default = SCHED_GROUP_UNKNOWN];
+
+ oneof Foreground {
+ bool activities = 5;
+ bool services = 6;
+ }
+
+ optional .android.app.ProcessState state = 7;
+ optional int32 trim_memory_level = 8;
+ optional ProcessRecordProto proc = 9;
+ optional string adj_type = 10;
+
+ oneof AdjTarget {
+ .android.content.ComponentNameProto adj_target_component_name = 11;
+ string adj_target_object = 12;
+ }
+
+ oneof AdjSource {
+ ProcessRecordProto adj_source_proc = 13;
+ string adj_source_object = 14;
+ }
+
+ message Detail {
+ optional int32 max_adj = 1;
+ optional int32 cur_raw_adj = 2;
+ optional int32 set_raw_adj = 3;
+ optional int32 cur_adj = 4;
+ optional int32 set_adj = 5;
+ optional .android.app.ProcessState current_state = 7;
+ optional .android.app.ProcessState set_state = 8;
+ optional string last_pss = 9;
+ optional string last_swap_pss = 10;
+ optional string last_cached_pss = 11;
+ optional bool cached = 12;
+ optional bool empty = 13;
+ optional bool has_above_client = 14;
+
+ // only make sense if process is a service
+ message CpuRunTime {
+ optional int64 over_ms = 1;
+ optional int64 used_ms = 2;
+ optional float ultilization = 3; // ratio of cpu time usage
+ }
+ optional CpuRunTime service_run_time = 15;
+ }
+ optional Detail detail = 15;
+}
+
+message ProcessToGcProto {
+ optional ProcessRecordProto proc = 1;
+ optional bool report_low_memory = 2;
+ optional int64 now_uptime_ms = 3;
+ optional int64 last_gced_ms = 4;
+ optional int64 last_low_memory_ms = 5;
+}
+
+// sync with com.android.server.am.AppErrors.java
+message AppErrorsProto {
+
+ optional int64 now_uptime_ms = 1;
+
+ message ProcessCrashTime {
+ optional string process_name = 1;
+
+ message Entry {
+ optional int32 uid = 1;
+ optional int64 last_crashed_at_ms = 2;
+ }
+ repeated Entry entries = 2;
+ }
+ repeated ProcessCrashTime process_crash_times = 2;
+
+ message BadProcess {
+ optional string process_name = 1;
+
+ message Entry {
+ optional int32 uid = 1;
+ optional int64 crashed_at_ms = 2;
+ optional string short_msg = 3;
+ optional string long_msg = 4;
+ optional string stack = 5;
+ }
+ repeated Entry entries = 2;
+ }
+ repeated BadProcess bad_processes = 3;
+}
+
+// sync with com.android.server.am.UserState.java
+message UserStateProto {
+ enum State {
+ STATE_BOOTING = 0;
+ STATE_RUNNING_LOCKED = 1;
+ STATE_RUNNING_UNLOCKING = 2;
+ STATE_RUNNING_UNLOCKED = 3;
+ STATE_STOPPING = 4;
+ STATE_SHUTDOWN = 5;
+ }
+ optional State state = 1;
+ optional bool switching = 2;
+}
+
+// sync with com.android.server.am.UserController.java
+message UserControllerProto {
+ message User {
+ optional int32 id = 1;
+ optional UserStateProto state = 2;
+ }
+ repeated User started_users = 1;
+ repeated int32 started_user_array = 2;
+ repeated int32 user_lru = 3;
+
+ message UserProfile {
+ optional int32 user = 1;
+ optional int32 profile = 2;
+ }
+ repeated UserProfile user_profile_group_ids = 4;
+}
+
+// sync with com.android.server.am.AppTimeTracker.java
+message AppTimeTrackerProto {
+ optional string receiver = 1;
+ optional int64 total_duration_ms = 2;
+
+ message PackageTime {
+ optional string package = 1;
+ optional int64 duration_ms = 2;
+ }
+ repeated PackageTime package_times = 3;
+
+ optional .android.util.Duration started_time = 4;
+ optional string started_package = 5;
}
diff --git a/services/core/java/com/android/server/am/ActiveInstrumentation.java b/services/core/java/com/android/server/am/ActiveInstrumentation.java
index 84e4ea9d0ee8..4a657334f4fb 100644
--- a/services/core/java/com/android/server/am/ActiveInstrumentation.java
+++ b/services/core/java/com/android/server/am/ActiveInstrumentation.java
@@ -22,6 +22,9 @@ import android.content.ComponentName;
import android.content.pm.ApplicationInfo;
import android.os.Bundle;
import android.util.PrintWriterPrinter;
+import android.util.proto.ProtoOutputStream;
+
+import com.android.server.am.proto.ActiveInstrumentationProto;
import java.io.PrintWriter;
import java.util.ArrayList;
@@ -119,4 +122,26 @@ class ActiveInstrumentation {
pw.print(prefix); pw.print("mArguments=");
pw.println(mArguments);
}
+
+ void writeToProto(ProtoOutputStream proto, long fieldId) {
+ long token = proto.start(fieldId);
+ mClass.writeToProto(proto, ActiveInstrumentationProto.CLASS);
+ proto.write(ActiveInstrumentationProto.FINISHED, mFinished);
+ for (int i=0; i<mRunningProcesses.size(); i++) {
+ mRunningProcesses.get(i).writeToProto(proto,
+ ActiveInstrumentationProto.RUNNING_PROCESSES);
+ }
+ for (String p : mTargetProcesses) {
+ proto.write(ActiveInstrumentationProto.TARGET_PROCESSES, p);
+ }
+ if (mTargetInfo != null) {
+ mTargetInfo.writeToProto(proto, ActiveInstrumentationProto.TARGET_INFO);
+ }
+ proto.write(ActiveInstrumentationProto.PROFILE_FILE, mProfileFile);
+ proto.write(ActiveInstrumentationProto.WATCHER, mWatcher.toString());
+ proto.write(ActiveInstrumentationProto.UI_AUTOMATION_CONNECTION,
+ mUiAutomationConnection.toString());
+ proto.write(ActiveInstrumentationProto.ARGUMENTS, mArguments.toString());
+ proto.end(token);
+ }
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 1eec982a0a9a..48c748b3054b 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -216,6 +216,7 @@ import android.app.ActivityManager.TaskSnapshot;
import android.app.ActivityManagerInternal;
import android.app.ActivityManagerInternal.ScreenObserver;
import android.app.ActivityManagerInternal.SleepToken;
+import android.app.ActivityManagerProto;
import android.app.ActivityOptions;
import android.app.ActivityThread;
import android.app.AlertDialog;
@@ -372,6 +373,7 @@ import android.util.TimeUtils;
import android.util.TimingsTraceLog;
import android.util.Xml;
import android.util.proto.ProtoOutputStream;
+import android.util.proto.ProtoUtils;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.RemoteAnimationDefinition;
@@ -432,8 +434,13 @@ import com.android.server.am.EventLogTags;
import com.android.server.am.proto.ActivityManagerServiceProto;
import com.android.server.am.proto.BroadcastProto;
import com.android.server.am.proto.GrantUriProto;
+import com.android.server.am.proto.ImportanceTokenProto;
import com.android.server.am.proto.MemInfoProto;
import com.android.server.am.proto.NeededUriGrantsProto;
+import com.android.server.am.proto.ProcessOomProto;
+import com.android.server.am.proto.ProcessToGcProto;
+import com.android.server.am.proto.ProcessesProto;
+import com.android.server.am.proto.ProcessesProto.UidObserverRegistrationProto;
import com.android.server.am.proto.StickyBroadcastProto;
import com.android.server.firewall.IntentFirewall;
import com.android.server.job.JobSchedulerInternal;
@@ -939,6 +946,16 @@ public class ActivityManagerService extends IActivityManager.Stub
return "ImportanceToken { " + Integer.toHexString(System.identityHashCode(this))
+ " " + reason + " " + pid + " " + token + " }";
}
+
+ void writeToProto(ProtoOutputStream proto, long fieldId) {
+ final long pToken = proto.start(fieldId);
+ proto.write(ImportanceTokenProto.PID, pid);
+ if (token != null) {
+ proto.write(ImportanceTokenProto.TOKEN, token.toString());
+ }
+ proto.write(ImportanceTokenProto.REASON, reason);
+ proto.end(pToken);
+ }
}
final SparseArray<ImportanceToken> mImportantProcesses = new SparseArray<ImportanceToken>();
@@ -1317,6 +1334,14 @@ public class ActivityManagerService extends IActivityManager.Stub
duration = _duration;
tag = _tag;
}
+
+ void writeToProto(ProtoOutputStream proto, long fieldId) {
+ final long token = proto.start(fieldId);
+ proto.write(ProcessesProto.PendingTempWhitelist.TARGET_UID, targetUid);
+ proto.write(ProcessesProto.PendingTempWhitelist.DURATION_MS, duration);
+ proto.write(ProcessesProto.PendingTempWhitelist.TAG, tag);
+ proto.end(token);
+ }
}
final SparseArray<PendingTempWhitelist> mPendingTempWhitelist = new SparseArray<>();
@@ -1641,6 +1666,20 @@ public class ActivityManagerService extends IActivityManager.Stub
final SparseIntArray lastProcStates;
+ // Please keep the enum lists in sync
+ private static int[] ORIG_ENUMS = new int[]{
+ ActivityManager.UID_OBSERVER_IDLE,
+ ActivityManager.UID_OBSERVER_ACTIVE,
+ ActivityManager.UID_OBSERVER_GONE,
+ ActivityManager.UID_OBSERVER_PROCSTATE,
+ };
+ private static int[] PROTO_ENUMS = new int[]{
+ ActivityManagerProto.UID_OBSERVER_FLAG_IDLE,
+ ActivityManagerProto.UID_OBSERVER_FLAG_ACTIVE,
+ ActivityManagerProto.UID_OBSERVER_FLAG_GONE,
+ ActivityManagerProto.UID_OBSERVER_FLAG_PROCSTATE,
+ };
+
UidObserverRegistration(int _uid, String _pkg, int _which, int _cutpoint) {
uid = _uid;
pkg = _pkg;
@@ -1652,6 +1691,25 @@ public class ActivityManagerService extends IActivityManager.Stub
lastProcStates = null;
}
}
+
+ void writeToProto(ProtoOutputStream proto, long fieldId) {
+ final long token = proto.start(fieldId);
+ proto.write(UidObserverRegistrationProto.UID, uid);
+ proto.write(UidObserverRegistrationProto.PACKAGE, pkg);
+ ProtoUtils.writeBitWiseFlagsToProtoEnum(proto, UidObserverRegistrationProto.FLAGS,
+ which, ORIG_ENUMS, PROTO_ENUMS);
+ proto.write(UidObserverRegistrationProto.CUT_POINT, cutpoint);
+ if (lastProcStates != null) {
+ final int NI = lastProcStates.size();
+ for (int i=0; i<NI; i++) {
+ final long pToken = proto.start(UidObserverRegistrationProto.LAST_PROC_STATES);
+ proto.write(UidObserverRegistrationProto.ProcState.UID, lastProcStates.keyAt(i));
+ proto.write(UidObserverRegistrationProto.ProcState.STATE, lastProcStates.valueAt(i));
+ proto.end(pToken);
+ }
+ }
+ proto.end(token);
+ }
}
final List<ScreenObserver> mScreenObservers = new ArrayList<>();
@@ -15251,7 +15309,6 @@ public class ActivityManagerService extends IActivityManager.Stub
boolean dumpVisibleStacksOnly = false;
boolean dumpFocusedStackOnly = false;
String dumpPackage = null;
- int dumpAppId = -1;
int opti = 0;
while (opti < args.length) {
@@ -15325,6 +15382,15 @@ public class ActivityManagerService extends IActivityManager.Stub
}
} else if ("service".equals(cmd)) {
mServices.writeToProto(proto);
+ } else if ("processes".equals(cmd) || "p".equals(cmd)) {
+ if (opti < args.length) {
+ dumpPackage = args[opti];
+ opti++;
+ }
+ // output proto is ProcessProto
+ synchronized (this) {
+ writeProcessesToProtoLocked(proto, dumpPackage);
+ }
} else {
// default option, dump everything, output is ActivityManagerServiceProto
synchronized (this) {
@@ -15339,6 +15405,10 @@ public class ActivityManagerService extends IActivityManager.Stub
long serviceToken = proto.start(ActivityManagerServiceProto.SERVICES);
mServices.writeToProto(proto);
proto.end(serviceToken);
+
+ long processToken = proto.start(ActivityManagerServiceProto.PROCESSES);
+ writeProcessesToProtoLocked(proto, dumpPackage);
+ proto.end(processToken);
}
}
proto.flush();
@@ -15346,16 +15416,7 @@ public class ActivityManagerService extends IActivityManager.Stub
return;
}
- if (dumpPackage != null) {
- try {
- ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
- dumpPackage, 0);
- dumpAppId = UserHandle.getAppId(info.uid);
- } catch (NameNotFoundException e) {
- e.printStackTrace();
- }
- }
-
+ int dumpAppId = getAppId(dumpPackage);
boolean more = false;
// Is the caller requesting to dump a particular piece of data?
if (opti < args.length) {
@@ -15397,33 +15458,17 @@ public class ActivityManagerService extends IActivityManager.Stub
pw.println(BinderInternal.nGetBinderProxyCount(Integer.parseInt(uid)));
}
} else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
- String[] newArgs;
- String name;
- if (opti >= args.length) {
- name = null;
- newArgs = EMPTY_STRING_ARRAY;
- } else {
+ if (opti < args.length) {
dumpPackage = args[opti];
opti++;
- newArgs = new String[args.length - opti];
- if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
- args.length - opti);
}
synchronized (this) {
dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
}
} else if ("broadcast-stats".equals(cmd)) {
- String[] newArgs;
- String name;
- if (opti >= args.length) {
- name = null;
- newArgs = EMPTY_STRING_ARRAY;
- } else {
+ if (opti < args.length) {
dumpPackage = args[opti];
opti++;
- newArgs = new String[args.length - opti];
- if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
- args.length - opti);
}
synchronized (this) {
if (dumpCheckinFormat) {
@@ -15434,33 +15479,17 @@ public class ActivityManagerService extends IActivityManager.Stub
}
}
} else if ("intents".equals(cmd) || "i".equals(cmd)) {
- String[] newArgs;
- String name;
- if (opti >= args.length) {
- name = null;
- newArgs = EMPTY_STRING_ARRAY;
- } else {
+ if (opti < args.length) {
dumpPackage = args[opti];
opti++;
- newArgs = new String[args.length - opti];
- if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
- args.length - opti);
}
synchronized (this) {
dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
}
} else if ("processes".equals(cmd) || "p".equals(cmd)) {
- String[] newArgs;
- String name;
- if (opti >= args.length) {
- name = null;
- newArgs = EMPTY_STRING_ARRAY;
- } else {
+ if (opti < args.length) {
dumpPackage = args[opti];
opti++;
- newArgs = new String[args.length - opti];
- if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
- args.length - opti);
}
synchronized (this) {
dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage, dumpAppId);
@@ -15881,8 +15910,21 @@ public class ActivityManagerService extends IActivityManager.Stub
}
}
+ private int getAppId(String dumpPackage) {
+ if (dumpPackage != null) {
+ try {
+ ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
+ dumpPackage, 0);
+ return UserHandle.getAppId(info.uid);
+ } catch (NameNotFoundException e) {
+ e.printStackTrace();
+ }
+ }
+ return -1;
+ }
+
boolean dumpUids(PrintWriter pw, String dumpPackage, int dumpAppId, SparseArray<UidRecord> uids,
- String header, boolean needSep) {
+ String header, boolean needSep) {
boolean printed = false;
for (int i=0; i<uids.size(); i++) {
UidRecord uidRec = uids.valueAt(i);
@@ -16100,7 +16142,7 @@ public class ActivityManagerService extends IActivityManager.Stub
"OnHold Norm", "OnHold PERS", dumpPackage);
}
- needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
+ needSep = dumpProcessesToGc(pw, needSep, dumpPackage);
needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
@@ -16385,8 +16427,327 @@ public class ActivityManagerService extends IActivityManager.Stub
pw.println(" mForceBackgroundCheck=" + mForceBackgroundCheck);
}
- boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
- int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
+ void writeProcessesToProtoLocked(ProtoOutputStream proto, String dumpPackage) {
+ int numPers = 0;
+
+ final int NP = mProcessNames.getMap().size();
+ for (int ip=0; ip<NP; ip++) {
+ SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
+ final int NA = procs.size();
+ for (int ia = 0; ia<NA; ia++) {
+ ProcessRecord r = procs.valueAt(ia);
+ if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
+ continue;
+ }
+ r.writeToProto(proto, ProcessesProto.PROCS);
+ if (r.persistent) {
+ numPers++;
+ }
+ }
+ }
+
+ for (int i=0; i<mIsolatedProcesses.size(); i++) {
+ ProcessRecord r = mIsolatedProcesses.valueAt(i);
+ if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
+ continue;
+ }
+ r.writeToProto(proto, ProcessesProto.ISOLATED_PROCS);
+ }
+
+ for (int i=0; i<mActiveInstrumentation.size(); i++) {
+ ActiveInstrumentation ai = mActiveInstrumentation.get(i);
+ if (dumpPackage != null && !ai.mClass.getPackageName().equals(dumpPackage)
+ && !ai.mTargetInfo.packageName.equals(dumpPackage)) {
+ continue;
+ }
+ ai.writeToProto(proto, ProcessesProto.ACTIVE_INSTRUMENTATIONS);
+ }
+
+ int whichAppId = getAppId(dumpPackage);
+ for (int i=0; i<mActiveUids.size(); i++) {
+ UidRecord uidRec = mActiveUids.valueAt(i);
+ if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
+ continue;
+ }
+ uidRec.writeToProto(proto, ProcessesProto.ACTIVE_UIDS);
+ }
+
+ for (int i=0; i<mValidateUids.size(); i++) {
+ UidRecord uidRec = mValidateUids.valueAt(i);
+ if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
+ continue;
+ }
+ uidRec.writeToProto(proto, ProcessesProto.VALIDATE_UIDS);
+ }
+
+ if (mLruProcesses.size() > 0) {
+ long lruToken = proto.start(ProcessesProto.LRU_PROCS);
+ int total = mLruProcesses.size();
+ proto.write(ProcessesProto.LruProcesses.SIZE, total);
+ proto.write(ProcessesProto.LruProcesses.NON_ACT_AT, total-mLruProcessActivityStart);
+ proto.write(ProcessesProto.LruProcesses.NON_SVC_AT, total-mLruProcessServiceStart);
+ writeProcessOomListToProto(proto, ProcessesProto.LruProcesses.LIST, this,
+ mLruProcesses,false, dumpPackage);
+ proto.end(lruToken);
+ }
+
+ if (dumpPackage != null) {
+ synchronized (mPidsSelfLocked) {
+ for (int i=0; i<mPidsSelfLocked.size(); i++) {
+ ProcessRecord r = mPidsSelfLocked.valueAt(i);
+ if (!r.pkgList.containsKey(dumpPackage)) {
+ continue;
+ }
+ r.writeToProto(proto, ProcessesProto.PIDS_SELF_LOCKED);
+ }
+ }
+ }
+
+ if (mImportantProcesses.size() > 0) {
+ synchronized (mPidsSelfLocked) {
+ for (int i=0; i<mImportantProcesses.size(); i++) {
+ ImportanceToken it = mImportantProcesses.valueAt(i);
+ ProcessRecord r = mPidsSelfLocked.get(it.pid);
+ if (dumpPackage != null && (r == null
+ || !r.pkgList.containsKey(dumpPackage))) {
+ continue;
+ }
+ it.writeToProto(proto, ProcessesProto.IMPORTANT_PROCS);
+ }
+ }
+ }
+
+ for (int i=0; i<mPersistentStartingProcesses.size(); i++) {
+ ProcessRecord r = mPersistentStartingProcesses.get(i);
+ if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
+ continue;
+ }
+ r.writeToProto(proto, ProcessesProto.PERSISTENT_STARTING_PROCS);
+ }
+
+ for (int i=0; i<mRemovedProcesses.size(); i++) {
+ ProcessRecord r = mRemovedProcesses.get(i);
+ if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
+ continue;
+ }
+ r.writeToProto(proto, ProcessesProto.REMOVED_PROCS);
+ }
+
+ for (int i=0; i<mProcessesOnHold.size(); i++) {
+ ProcessRecord r = mProcessesOnHold.get(i);
+ if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
+ continue;
+ }
+ r.writeToProto(proto, ProcessesProto.ON_HOLD_PROCS);
+ }
+
+ writeProcessesToGcToProto(proto, ProcessesProto.GC_PROCS, dumpPackage);
+ mAppErrors.writeToProto(proto, ProcessesProto.APP_ERRORS, dumpPackage);
+
+ if (dumpPackage == null) {
+ mUserController.writeToProto(proto, ProcessesProto.USER_CONTROLLER);
+ getGlobalConfiguration().writeToProto(proto, ProcessesProto.GLOBAL_CONFIGURATION);
+ proto.write(ProcessesProto.CONFIG_WILL_CHANGE, getFocusedStack().mConfigWillChange);
+ }
+
+ if (mHomeProcess != null && (dumpPackage == null
+ || mHomeProcess.pkgList.containsKey(dumpPackage))) {
+ mHomeProcess.writeToProto(proto, ProcessesProto.HOME_PROC);
+ }
+
+ if (mPreviousProcess != null && (dumpPackage == null
+ || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
+ mPreviousProcess.writeToProto(proto, ProcessesProto.PREVIOUS_PROC);
+ proto.write(ProcessesProto.PREVIOUS_PROC_VISIBLE_TIME_MS, mPreviousProcessVisibleTime);
+ }
+
+ if (mHeavyWeightProcess != null && (dumpPackage == null
+ || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
+ mHeavyWeightProcess.writeToProto(proto, ProcessesProto.HEAVY_WEIGHT_PROC);
+ }
+
+ for (Map.Entry<String, Integer> entry : mCompatModePackages.getPackages().entrySet()) {
+ String pkg = entry.getKey();
+ int mode = entry.getValue();
+ if (dumpPackage == null || dumpPackage.equals(pkg)) {
+ long compatToken = proto.start(ProcessesProto.SCREEN_COMPAT_PACKAGES);
+ proto.write(ProcessesProto.ScreenCompatPackage.PACKAGE, pkg);
+ proto.write(ProcessesProto.ScreenCompatPackage.MODE, mode);
+ proto.end(compatToken);
+ }
+ }
+
+ final int NI = mUidObservers.getRegisteredCallbackCount();
+ for (int i=0; i<NI; i++) {
+ final UidObserverRegistration reg = (UidObserverRegistration)
+ mUidObservers.getRegisteredCallbackCookie(i);
+ if (dumpPackage == null || dumpPackage.equals(reg.pkg)) {
+ reg.writeToProto(proto, ProcessesProto.UID_OBSERVERS);
+ }
+ }
+
+ for (int v : mDeviceIdleWhitelist) {
+ proto.write(ProcessesProto.DEVICE_IDLE_WHITELIST, v);
+ }
+
+ for (int v : mDeviceIdleTempWhitelist) {
+ proto.write(ProcessesProto.DEVICE_IDLE_TEMP_WHITELIST, v);
+ }
+
+ if (mPendingTempWhitelist.size() > 0) {
+ for (int i=0; i < mPendingTempWhitelist.size(); i++) {
+ mPendingTempWhitelist.valueAt(i).writeToProto(proto,
+ ProcessesProto.PENDING_TEMP_WHITELIST);
+ }
+ }
+
+ if (dumpPackage == null) {
+ final long sleepToken = proto.start(ProcessesProto.SLEEP_STATUS);
+ proto.write(ProcessesProto.SleepStatus.WAKEFULNESS,
+ PowerManagerInternal.wakefulnessToProtoEnum(mWakefulness));
+ for (SleepToken st : mStackSupervisor.mSleepTokens) {
+ proto.write(ProcessesProto.SleepStatus.SLEEP_TOKENS, st.toString());
+ }
+ proto.write(ProcessesProto.SleepStatus.SLEEPING, mSleeping);
+ proto.write(ProcessesProto.SleepStatus.SHUTTING_DOWN, mShuttingDown);
+ proto.write(ProcessesProto.SleepStatus.TEST_PSS_MODE, mTestPssMode);
+ proto.end(sleepToken);
+
+ if (mRunningVoice != null) {
+ final long vrToken = proto.start(ProcessesProto.RUNNING_VOICE);
+ proto.write(ProcessesProto.VoiceProto.SESSION, mRunningVoice.toString());
+ mVoiceWakeLock.writeToProto(proto, ProcessesProto.VoiceProto.WAKELOCK);
+ proto.end(vrToken);
+ }
+
+ mVrController.writeToProto(proto, ProcessesProto.VR_CONTROLLER);
+ }
+
+ if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
+ || mOrigWaitForDebugger) {
+ if (dumpPackage == null || dumpPackage.equals(mDebugApp)
+ || dumpPackage.equals(mOrigDebugApp)) {
+ final long debugAppToken = proto.start(ProcessesProto.DEBUG);
+ proto.write(ProcessesProto.DebugApp.DEBUG_APP, mDebugApp);
+ proto.write(ProcessesProto.DebugApp.ORIG_DEBUG_APP, mOrigDebugApp);
+ proto.write(ProcessesProto.DebugApp.DEBUG_TRANSIENT, mDebugTransient);
+ proto.write(ProcessesProto.DebugApp.ORIG_WAIT_FOR_DEBUGGER, mOrigWaitForDebugger);
+ proto.end(debugAppToken);
+ }
+ }
+
+ if (mCurAppTimeTracker != null) {
+ mCurAppTimeTracker.writeToProto(proto, ProcessesProto.CURRENT_TRACKER, true);
+ }
+
+ if (mMemWatchProcesses.getMap().size() > 0) {
+ final long token = proto.start(ProcessesProto.MEM_WATCH_PROCESSES);
+ ArrayMap<String, SparseArray<Pair<Long, String>>> procs = mMemWatchProcesses.getMap();
+ for (int i=0; i<procs.size(); i++) {
+ final String proc = procs.keyAt(i);
+ final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
+ final long ptoken = proto.start(ProcessesProto.MemWatchProcess.PROCS);
+ proto.write(ProcessesProto.MemWatchProcess.Process.NAME, proc);
+ for (int j=0; j<uids.size(); j++) {
+ final long utoken = proto.start(ProcessesProto.MemWatchProcess.Process.MEM_STATS);
+ Pair<Long, String> val = uids.valueAt(j);
+ proto.write(ProcessesProto.MemWatchProcess.Process.MemStats.UID, uids.keyAt(j));
+ proto.write(ProcessesProto.MemWatchProcess.Process.MemStats.SIZE,
+ DebugUtils.sizeValueToString(val.first, new StringBuilder()));
+ proto.write(ProcessesProto.MemWatchProcess.Process.MemStats.REPORT_TO, val.second);
+ proto.end(utoken);
+ }
+ proto.end(ptoken);
+ }
+
+ final long dtoken = proto.start(ProcessesProto.MemWatchProcess.DUMP);
+ proto.write(ProcessesProto.MemWatchProcess.Dump.PROC_NAME, mMemWatchDumpProcName);
+ proto.write(ProcessesProto.MemWatchProcess.Dump.FILE, mMemWatchDumpFile);
+ proto.write(ProcessesProto.MemWatchProcess.Dump.PID, mMemWatchDumpPid);
+ proto.write(ProcessesProto.MemWatchProcess.Dump.UID, mMemWatchDumpUid);
+ proto.end(dtoken);
+
+ proto.end(token);
+ }
+
+ if (mTrackAllocationApp != null) {
+ if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
+ proto.write(ProcessesProto.TRACK_ALLOCATION_APP, mTrackAllocationApp);
+ }
+ }
+
+ if (mProfileApp != null || mProfileProc != null || (mProfilerInfo != null &&
+ (mProfilerInfo.profileFile != null || mProfilerInfo.profileFd != null))) {
+ if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
+ final long token = proto.start(ProcessesProto.PROFILE);
+ proto.write(ProcessesProto.Profile.APP_NAME, mProfileApp);
+ mProfileProc.writeToProto(proto,ProcessesProto.Profile.PROC);
+ if (mProfilerInfo != null) {
+ mProfilerInfo.writeToProto(proto, ProcessesProto.Profile.INFO);
+ proto.write(ProcessesProto.Profile.TYPE, mProfileType);
+ }
+ proto.end(token);
+ }
+ }
+
+ if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
+ proto.write(ProcessesProto.NATIVE_DEBUGGING_APP, mNativeDebuggingApp);
+ }
+
+ if (dumpPackage == null) {
+ proto.write(ProcessesProto.ALWAYS_FINISH_ACTIVITIES, mAlwaysFinishActivities);
+ if (mController != null) {
+ final long token = proto.start(ProcessesProto.CONTROLLER);
+ proto.write(ProcessesProto.Controller.CONTROLLER, mController.toString());
+ proto.write(ProcessesProto.Controller.IS_A_MONKEY, mControllerIsAMonkey);
+ proto.end(token);
+ }
+ proto.write(ProcessesProto.TOTAL_PERSISTENT_PROCS, numPers);
+ proto.write(ProcessesProto.PROCESSES_READY, mProcessesReady);
+ proto.write(ProcessesProto.SYSTEM_READY, mSystemReady);
+ proto.write(ProcessesProto.BOOTED, mBooted);
+ proto.write(ProcessesProto.FACTORY_TEST, mFactoryTest);
+ proto.write(ProcessesProto.BOOTING, mBooting);
+ proto.write(ProcessesProto.CALL_FINISH_BOOTING, mCallFinishBooting);
+ proto.write(ProcessesProto.BOOT_ANIMATION_COMPLETE, mBootAnimationComplete);
+ proto.write(ProcessesProto.LAST_POWER_CHECK_UPTIME_MS, mLastPowerCheckUptime);
+ mStackSupervisor.mGoingToSleep.writeToProto(proto, ProcessesProto.GOING_TO_SLEEP);
+ mStackSupervisor.mLaunchingActivity.writeToProto(proto, ProcessesProto.LAUNCHING_ACTIVITY);
+ proto.write(ProcessesProto.ADJ_SEQ, mAdjSeq);
+ proto.write(ProcessesProto.LRU_SEQ, mLruSeq);
+ proto.write(ProcessesProto.NUM_NON_CACHED_PROCS, mNumNonCachedProcs);
+ proto.write(ProcessesProto.NUM_SERVICE_PROCS, mNumServiceProcs);
+ proto.write(ProcessesProto.NEW_NUM_SERVICE_PROCS, mNewNumServiceProcs);
+ proto.write(ProcessesProto.ALLOW_LOWER_MEM_LEVEL, mAllowLowerMemLevel);
+ proto.write(ProcessesProto.LAST_MEMORY_LEVEL, mLastMemoryLevel);
+ proto.write(ProcessesProto.LAST_NUM_PROCESSES, mLastNumProcesses);
+ long now = SystemClock.uptimeMillis();
+ ProtoUtils.toDuration(proto, ProcessesProto.LAST_IDLE_TIME, mLastIdleTime, now);
+ proto.write(ProcessesProto.LOW_RAM_SINCE_LAST_IDLE_MS, getLowRamTimeSinceIdle(now));
+ }
+
+ }
+
+ void writeProcessesToGcToProto(ProtoOutputStream proto, long fieldId, String dumpPackage) {
+ if (mProcessesToGc.size() > 0) {
+ long now = SystemClock.uptimeMillis();
+ for (int i=0; i<mProcessesToGc.size(); i++) {
+ ProcessRecord r = mProcessesToGc.get(i);
+ if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
+ continue;
+ }
+ final long token = proto.start(fieldId);
+ r.writeToProto(proto, ProcessToGcProto.PROC);
+ proto.write(ProcessToGcProto.REPORT_LOW_MEMORY, r.reportLowMemory);
+ proto.write(ProcessToGcProto.NOW_UPTIME_MS, now);
+ proto.write(ProcessToGcProto.LAST_GCED_MS, r.lastRequestedGc);
+ proto.write(ProcessToGcProto.LAST_LOW_MEMORY_MS, r.lastLowMemory);
+ proto.end(token);
+ }
+ }
+ }
+
+ boolean dumpProcessesToGc(PrintWriter pw, boolean needSep, String dumpPackage) {
if (mProcessesToGc.size() > 0) {
boolean printed = false;
long now = SystemClock.uptimeMillis();
@@ -16464,7 +16825,7 @@ public class ActivityManagerService extends IActivityManager.Stub
needSep = true;
}
- dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
+ dumpProcessesToGc(pw, needSep, null);
pw.println();
pw.println(" mHomeProcess: " + mHomeProcess);
@@ -17015,11 +17376,8 @@ public class ActivityManagerService extends IActivityManager.Stub
return numPers;
}
- private static final boolean dumpProcessOomList(PrintWriter pw,
- ActivityManagerService service, List<ProcessRecord> origList,
- String prefix, String normalLabel, String persistentLabel,
- boolean inclDetails, String dumpPackage) {
-
+ private static final ArrayList<Pair<ProcessRecord, Integer>>
+ sortProcessOomList(List<ProcessRecord> origList, String dumpPackage) {
ArrayList<Pair<ProcessRecord, Integer>> list
= new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
for (int i=0; i<origList.size(); i++) {
@@ -17030,10 +17388,6 @@ public class ActivityManagerService extends IActivityManager.Stub
list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
}
- if (list.size() <= 0) {
- return false;
- }
-
Comparator<Pair<ProcessRecord, Integer>> comparator
= new Comparator<Pair<ProcessRecord, Integer>>() {
@Override
@@ -17053,6 +17407,113 @@ public class ActivityManagerService extends IActivityManager.Stub
};
Collections.sort(list, comparator);
+ return list;
+ }
+
+ private static final boolean writeProcessOomListToProto(ProtoOutputStream proto, long fieldId,
+ ActivityManagerService service, List<ProcessRecord> origList,
+ boolean inclDetails, String dumpPackage) {
+ ArrayList<Pair<ProcessRecord, Integer>> list = sortProcessOomList(origList, dumpPackage);
+ if (list.isEmpty()) return false;
+
+ final long curUptime = SystemClock.uptimeMillis();
+
+ for (int i = list.size() - 1; i >= 0; i--) {
+ ProcessRecord r = list.get(i).first;
+ long token = proto.start(fieldId);
+ String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
+ proto.write(ProcessOomProto.PERSISTENT, r.persistent);
+ proto.write(ProcessOomProto.NUM, (origList.size()-1)-list.get(i).second);
+ proto.write(ProcessOomProto.OOM_ADJ, oomAdj);
+ int schedGroup = ProcessOomProto.SCHED_GROUP_UNKNOWN;
+ switch (r.setSchedGroup) {
+ case ProcessList.SCHED_GROUP_BACKGROUND:
+ schedGroup = ProcessOomProto.SCHED_GROUP_BACKGROUND;
+ break;
+ case ProcessList.SCHED_GROUP_DEFAULT:
+ schedGroup = ProcessOomProto.SCHED_GROUP_DEFAULT;
+ break;
+ case ProcessList.SCHED_GROUP_TOP_APP:
+ schedGroup = ProcessOomProto.SCHED_GROUP_TOP_APP;
+ break;
+ case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
+ schedGroup = ProcessOomProto.SCHED_GROUP_TOP_APP_BOUND;
+ break;
+ }
+ if (schedGroup != ProcessOomProto.SCHED_GROUP_UNKNOWN) {
+ proto.write(ProcessOomProto.SCHED_GROUP, schedGroup);
+ }
+ if (r.foregroundActivities) {
+ proto.write(ProcessOomProto.ACTIVITIES, true);
+ } else if (r.foregroundServices) {
+ proto.write(ProcessOomProto.SERVICES, true);
+ }
+ proto.write(ProcessOomProto.STATE, ProcessList.makeProcStateProtoEnum(r.curProcState));
+ proto.write(ProcessOomProto.TRIM_MEMORY_LEVEL, r.trimMemoryLevel);
+ r.writeToProto(proto, ProcessOomProto.PROC);
+ proto.write(ProcessOomProto.ADJ_TYPE, r.adjType);
+ if (r.adjSource != null || r.adjTarget != null) {
+ if (r.adjTarget instanceof ComponentName) {
+ ComponentName cn = (ComponentName) r.adjTarget;
+ cn.writeToProto(proto, ProcessOomProto.ADJ_TARGET_COMPONENT_NAME);
+ } else if (r.adjTarget != null) {
+ proto.write(ProcessOomProto.ADJ_TARGET_OBJECT, r.adjTarget.toString());
+ }
+ if (r.adjSource instanceof ProcessRecord) {
+ ProcessRecord p = (ProcessRecord) r.adjSource;
+ p.writeToProto(proto, ProcessOomProto.ADJ_SOURCE_PROC);
+ } else if (r.adjSource != null) {
+ proto.write(ProcessOomProto.ADJ_SOURCE_OBJECT, r.adjSource.toString());
+ }
+ }
+ if (inclDetails) {
+ long detailToken = proto.start(ProcessOomProto.DETAIL);
+ proto.write(ProcessOomProto.Detail.MAX_ADJ, r.maxAdj);
+ proto.write(ProcessOomProto.Detail.CUR_RAW_ADJ, r.curRawAdj);
+ proto.write(ProcessOomProto.Detail.SET_RAW_ADJ, r.setRawAdj);
+ proto.write(ProcessOomProto.Detail.CUR_ADJ, r.curAdj);
+ proto.write(ProcessOomProto.Detail.SET_ADJ, r.setAdj);
+ proto.write(ProcessOomProto.Detail.CURRENT_STATE,
+ ProcessList.makeProcStateProtoEnum(r.curProcState));
+ proto.write(ProcessOomProto.Detail.SET_STATE,
+ ProcessList.makeProcStateProtoEnum(r.setProcState));
+ proto.write(ProcessOomProto.Detail.LAST_PSS, DebugUtils.sizeValueToString(
+ r.lastPss*1024, new StringBuilder()));
+ proto.write(ProcessOomProto.Detail.LAST_SWAP_PSS, DebugUtils.sizeValueToString(
+ r.lastSwapPss*1024, new StringBuilder()));
+ proto.write(ProcessOomProto.Detail.LAST_CACHED_PSS, DebugUtils.sizeValueToString(
+ r.lastCachedPss*1024, new StringBuilder()));
+ proto.write(ProcessOomProto.Detail.CACHED, r.cached);
+ proto.write(ProcessOomProto.Detail.EMPTY, r.empty);
+ proto.write(ProcessOomProto.Detail.HAS_ABOVE_CLIENT, r.hasAboveClient);
+
+ if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
+ if (r.lastCpuTime != 0) {
+ long uptimeSince = curUptime - service.mLastPowerCheckUptime;
+ long timeUsed = r.curCpuTime - r.lastCpuTime;
+ long cpuTimeToken = proto.start(ProcessOomProto.Detail.SERVICE_RUN_TIME);
+ proto.write(ProcessOomProto.Detail.CpuRunTime.OVER_MS, uptimeSince);
+ proto.write(ProcessOomProto.Detail.CpuRunTime.USED_MS, timeUsed);
+ proto.write(ProcessOomProto.Detail.CpuRunTime.ULTILIZATION,
+ (100.0*timeUsed)/uptimeSince);
+ proto.end(cpuTimeToken);
+ }
+ }
+ proto.end(detailToken);
+ }
+ proto.end(token);
+ }
+
+ return true;
+ }
+
+ private static final boolean dumpProcessOomList(PrintWriter pw,
+ ActivityManagerService service, List<ProcessRecord> origList,
+ String prefix, String normalLabel, String persistentLabel,
+ boolean inclDetails, String dumpPackage) {
+
+ ArrayList<Pair<ProcessRecord, Integer>> list = sortProcessOomList(origList, dumpPackage);
+ if (list.isEmpty()) return false;
final long curUptime = SystemClock.uptimeMillis();
final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
diff --git a/services/core/java/com/android/server/am/AppErrors.java b/services/core/java/com/android/server/am/AppErrors.java
index 0da7e0ec2f6d..c7d93be893fc 100644
--- a/services/core/java/com/android/server/am/AppErrors.java
+++ b/services/core/java/com/android/server/am/AppErrors.java
@@ -22,6 +22,7 @@ import com.android.internal.logging.nano.MetricsProto;
import com.android.internal.os.ProcessCpuTracker;
import com.android.server.RescueParty;
import com.android.server.Watchdog;
+import com.android.server.am.proto.AppErrorsProto;
import android.app.ActivityManager;
import android.app.ActivityOptions;
@@ -48,6 +49,7 @@ import android.util.Log;
import android.util.Slog;
import android.util.SparseArray;
import android.util.TimeUtils;
+import android.util.proto.ProtoOutputStream;
import java.io.File;
import java.io.FileDescriptor;
@@ -103,8 +105,76 @@ class AppErrors {
mContext = context;
}
- boolean dumpLocked(FileDescriptor fd, PrintWriter pw, boolean needSep,
- String dumpPackage) {
+ void writeToProto(ProtoOutputStream proto, long fieldId, String dumpPackage) {
+ if (mProcessCrashTimes.getMap().isEmpty() && mBadProcesses.getMap().isEmpty()) {
+ return;
+ }
+
+ final long token = proto.start(fieldId);
+ final long now = SystemClock.uptimeMillis();
+ proto.write(AppErrorsProto.NOW_UPTIME_MS, now);
+
+ if (!mProcessCrashTimes.getMap().isEmpty()) {
+ final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
+ final int procCount = pmap.size();
+ for (int ip = 0; ip < procCount; ip++) {
+ final long ctoken = proto.start(AppErrorsProto.PROCESS_CRASH_TIMES);
+ final String pname = pmap.keyAt(ip);
+ final SparseArray<Long> uids = pmap.valueAt(ip);
+ final int uidCount = uids.size();
+
+ proto.write(AppErrorsProto.ProcessCrashTime.PROCESS_NAME, pname);
+ for (int i = 0; i < uidCount; i++) {
+ final int puid = uids.keyAt(i);
+ final ProcessRecord r = mService.mProcessNames.get(pname, puid);
+ if (dumpPackage != null && (r == null || !r.pkgList.containsKey(dumpPackage))) {
+ continue;
+ }
+ final long etoken = proto.start(AppErrorsProto.ProcessCrashTime.ENTRIES);
+ proto.write(AppErrorsProto.ProcessCrashTime.Entry.UID, puid);
+ proto.write(AppErrorsProto.ProcessCrashTime.Entry.LAST_CRASHED_AT_MS,
+ uids.valueAt(i));
+ proto.end(etoken);
+ }
+ proto.end(ctoken);
+ }
+
+ }
+
+ if (!mBadProcesses.getMap().isEmpty()) {
+ final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
+ final int processCount = pmap.size();
+ for (int ip = 0; ip < processCount; ip++) {
+ final long btoken = proto.start(AppErrorsProto.BAD_PROCESSES);
+ final String pname = pmap.keyAt(ip);
+ final SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
+ final int uidCount = uids.size();
+
+ proto.write(AppErrorsProto.BadProcess.PROCESS_NAME, pname);
+ for (int i = 0; i < uidCount; i++) {
+ final int puid = uids.keyAt(i);
+ final ProcessRecord r = mService.mProcessNames.get(pname, puid);
+ if (dumpPackage != null && (r == null
+ || !r.pkgList.containsKey(dumpPackage))) {
+ continue;
+ }
+ final BadProcessInfo info = uids.valueAt(i);
+ final long etoken = proto.start(AppErrorsProto.BadProcess.ENTRIES);
+ proto.write(AppErrorsProto.BadProcess.Entry.UID, puid);
+ proto.write(AppErrorsProto.BadProcess.Entry.CRASHED_AT_MS, info.time);
+ proto.write(AppErrorsProto.BadProcess.Entry.SHORT_MSG, info.shortMsg);
+ proto.write(AppErrorsProto.BadProcess.Entry.LONG_MSG, info.longMsg);
+ proto.write(AppErrorsProto.BadProcess.Entry.STACK, info.stack);
+ proto.end(etoken);
+ }
+ proto.end(btoken);
+ }
+ }
+
+ proto.end(token);
+ }
+
+ boolean dumpLocked(FileDescriptor fd, PrintWriter pw, boolean needSep, String dumpPackage) {
if (!mProcessCrashTimes.getMap().isEmpty()) {
boolean printed = false;
final long now = SystemClock.uptimeMillis();
diff --git a/services/core/java/com/android/server/am/AppTimeTracker.java b/services/core/java/com/android/server/am/AppTimeTracker.java
index 910f33dcaf39..d96364ade168 100644
--- a/services/core/java/com/android/server/am/AppTimeTracker.java
+++ b/services/core/java/com/android/server/am/AppTimeTracker.java
@@ -25,6 +25,10 @@ import android.os.SystemClock;
import android.util.ArrayMap;
import android.util.MutableLong;
import android.util.TimeUtils;
+import android.util.proto.ProtoOutputStream;
+import android.util.proto.ProtoUtils;
+
+import com.android.server.am.proto.AppTimeTrackerProto;
import java.io.PrintWriter;
@@ -119,4 +123,22 @@ public class AppTimeTracker {
pw.print(prefix); pw.print("mStartedPackage="); pw.println(mStartedPackage);
}
}
+
+ void writeToProto(ProtoOutputStream proto, long fieldId, boolean details) {
+ final long token = proto.start(fieldId);
+ proto.write(AppTimeTrackerProto.RECEIVER, mReceiver.toString());
+ proto.write(AppTimeTrackerProto.TOTAL_DURATION_MS, mTotalTime);
+ for (int i=0; i<mPackageTimes.size(); i++) {
+ final long ptoken = proto.start(AppTimeTrackerProto.PACKAGE_TIMES);
+ proto.write(AppTimeTrackerProto.PackageTime.PACKAGE, mPackageTimes.keyAt(i));
+ proto.write(AppTimeTrackerProto.PackageTime.DURATION_MS, mPackageTimes.valueAt(i).value);
+ proto.end(ptoken);
+ }
+ if (details && mStartedTime != 0) {
+ ProtoUtils.toDuration(proto, AppTimeTrackerProto.STARTED_TIME,
+ mStartedTime, SystemClock.elapsedRealtime());
+ proto.write(AppTimeTrackerProto.STARTED_PACKAGE, mStartedPackage);
+ }
+ proto.end(token);
+ }
}
diff --git a/services/core/java/com/android/server/am/ConnectionRecord.java b/services/core/java/com/android/server/am/ConnectionRecord.java
index 6df283ca0a77..d320fb1d0560 100644
--- a/services/core/java/com/android/server/am/ConnectionRecord.java
+++ b/services/core/java/com/android/server/am/ConnectionRecord.java
@@ -20,6 +20,7 @@ import android.app.IServiceConnection;
import android.app.PendingIntent;
import android.content.Context;
import android.util.proto.ProtoOutputStream;
+import android.util.proto.ProtoUtils;
import com.android.server.am.proto.ConnectionRecordProto;
@@ -37,7 +38,43 @@ final class ConnectionRecord {
final PendingIntent clientIntent; // How to launch the client.
String stringName; // Caching of toString.
boolean serviceDead; // Well is it?
-
+
+ // Please keep the following two enum list synced.
+ private static int[] BIND_ORIG_ENUMS = new int[] {
+ Context.BIND_AUTO_CREATE,
+ Context.BIND_DEBUG_UNBIND,
+ Context.BIND_NOT_FOREGROUND,
+ Context.BIND_IMPORTANT_BACKGROUND,
+ Context.BIND_ABOVE_CLIENT,
+ Context.BIND_ALLOW_OOM_MANAGEMENT,
+ Context.BIND_WAIVE_PRIORITY,
+ Context.BIND_IMPORTANT,
+ Context.BIND_ADJUST_WITH_ACTIVITY,
+ Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE,
+ Context.BIND_FOREGROUND_SERVICE,
+ Context.BIND_TREAT_LIKE_ACTIVITY,
+ Context.BIND_VISIBLE,
+ Context.BIND_SHOWING_UI,
+ Context.BIND_NOT_VISIBLE,
+ };
+ private static int[] BIND_PROTO_ENUMS = new int[] {
+ ConnectionRecordProto.AUTO_CREATE,
+ ConnectionRecordProto.DEBUG_UNBIND,
+ ConnectionRecordProto.NOT_FG,
+ ConnectionRecordProto.IMPORTANT_BG,
+ ConnectionRecordProto.ABOVE_CLIENT,
+ ConnectionRecordProto.ALLOW_OOM_MANAGEMENT,
+ ConnectionRecordProto.WAIVE_PRIORITY,
+ ConnectionRecordProto.IMPORTANT,
+ ConnectionRecordProto.ADJUST_WITH_ACTIVITY,
+ ConnectionRecordProto.FG_SERVICE_WHILE_AWAKE,
+ ConnectionRecordProto.FG_SERVICE,
+ ConnectionRecordProto.TREAT_LIKE_ACTIVITY,
+ ConnectionRecordProto.VISIBLE,
+ ConnectionRecordProto.SHOWING_UI,
+ ConnectionRecordProto.NOT_VISIBLE,
+ };
+
void dump(PrintWriter pw, String prefix) {
pw.println(prefix + "binding=" + binding);
if (activity != null) {
@@ -46,7 +83,7 @@ final class ConnectionRecord {
pw.println(prefix + "conn=" + conn.asBinder()
+ " flags=0x" + Integer.toHexString(flags));
}
-
+
ConnectionRecord(AppBindRecord _binding, ActivityRecord _activity,
IServiceConnection _conn, int _flags,
int _clientLabel, PendingIntent _clientIntent) {
@@ -131,51 +168,8 @@ final class ConnectionRecord {
if (binding.client != null) {
proto.write(ConnectionRecordProto.USER_ID, binding.client.userId);
}
- if ((flags&Context.BIND_AUTO_CREATE) != 0) {
- proto.write(ConnectionRecordProto.FLAGS, ConnectionRecordProto.AUTO_CREATE);
- }
- if ((flags&Context.BIND_DEBUG_UNBIND) != 0) {
- proto.write(ConnectionRecordProto.FLAGS, ConnectionRecordProto.DEBUG_UNBIND);
- }
- if ((flags&Context.BIND_NOT_FOREGROUND) != 0) {
- proto.write(ConnectionRecordProto.FLAGS, ConnectionRecordProto.NOT_FG);
- }
- if ((flags&Context.BIND_IMPORTANT_BACKGROUND) != 0) {
- proto.write(ConnectionRecordProto.FLAGS, ConnectionRecordProto.IMPORTANT_BG);
- }
- if ((flags&Context.BIND_ABOVE_CLIENT) != 0) {
- proto.write(ConnectionRecordProto.FLAGS, ConnectionRecordProto.ABOVE_CLIENT);
- }
- if ((flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
- proto.write(ConnectionRecordProto.FLAGS, ConnectionRecordProto.ALLOW_OOM_MANAGEMENT);
- }
- if ((flags&Context.BIND_WAIVE_PRIORITY) != 0) {
- proto.write(ConnectionRecordProto.FLAGS, ConnectionRecordProto.WAIVE_PRIORITY);
- }
- if ((flags&Context.BIND_IMPORTANT) != 0) {
- proto.write(ConnectionRecordProto.FLAGS, ConnectionRecordProto.IMPORTANT);
- }
- if ((flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
- proto.write(ConnectionRecordProto.FLAGS, ConnectionRecordProto.ADJUST_WITH_ACTIVITY);
- }
- if ((flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE) != 0) {
- proto.write(ConnectionRecordProto.FLAGS, ConnectionRecordProto.FG_SERVICE_WHILE_WAKE);
- }
- if ((flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
- proto.write(ConnectionRecordProto.FLAGS, ConnectionRecordProto.FG_SERVICE);
- }
- if ((flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
- proto.write(ConnectionRecordProto.FLAGS, ConnectionRecordProto.TREAT_LIKE_ACTIVITY);
- }
- if ((flags&Context.BIND_VISIBLE) != 0) {
- proto.write(ConnectionRecordProto.FLAGS, ConnectionRecordProto.VISIBLE);
- }
- if ((flags&Context.BIND_SHOWING_UI) != 0) {
- proto.write(ConnectionRecordProto.FLAGS, ConnectionRecordProto.SHOWING_UI);
- }
- if ((flags&Context.BIND_NOT_VISIBLE) != 0) {
- proto.write(ConnectionRecordProto.FLAGS, ConnectionRecordProto.NOT_VISIBLE);
- }
+ ProtoUtils.writeBitWiseFlagsToProtoEnum(proto, ConnectionRecordProto.FLAGS,
+ flags, BIND_ORIG_ENUMS, BIND_PROTO_ENUMS);
if (serviceDead) {
proto.write(ConnectionRecordProto.FLAGS, ConnectionRecordProto.DEAD);
}
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index 77f5c169f911..29bfebe631c7 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -24,6 +24,7 @@ import java.io.OutputStream;
import java.nio.ByteBuffer;
import android.app.ActivityManager;
+import android.app.ActivityManagerProto;
import android.os.Build;
import android.os.SystemClock;
import com.android.internal.util.MemInfoReader;
@@ -416,6 +417,53 @@ public final class ProcessList {
return procState;
}
+ public static int makeProcStateProtoEnum(int curProcState) {
+ switch (curProcState) {
+ case ActivityManager.PROCESS_STATE_PERSISTENT:
+ return ActivityManagerProto.PROCESS_STATE_PERSISTENT;
+ case ActivityManager.PROCESS_STATE_PERSISTENT_UI:
+ return ActivityManagerProto.PROCESS_STATE_PERSISTENT_UI;
+ case ActivityManager.PROCESS_STATE_TOP:
+ return ActivityManagerProto.PROCESS_STATE_TOP;
+ case ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE:
+ return ActivityManagerProto.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
+ case ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE:
+ return ActivityManagerProto.PROCESS_STATE_FOREGROUND_SERVICE;
+ case ActivityManager.PROCESS_STATE_TOP_SLEEPING:
+ return ActivityManagerProto.PROCESS_STATE_TOP_SLEEPING;
+ case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
+ return ActivityManagerProto.PROCESS_STATE_IMPORTANT_FOREGROUND;
+ case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
+ return ActivityManagerProto.PROCESS_STATE_IMPORTANT_BACKGROUND;
+ case ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND:
+ return ActivityManagerProto.PROCESS_STATE_TRANSIENT_BACKGROUND;
+ case ActivityManager.PROCESS_STATE_BACKUP:
+ return ActivityManagerProto.PROCESS_STATE_BACKUP;
+ case ActivityManager.PROCESS_STATE_HEAVY_WEIGHT:
+ return ActivityManagerProto.PROCESS_STATE_HEAVY_WEIGHT;
+ case ActivityManager.PROCESS_STATE_SERVICE:
+ return ActivityManagerProto.PROCESS_STATE_SERVICE;
+ case ActivityManager.PROCESS_STATE_RECEIVER:
+ return ActivityManagerProto.PROCESS_STATE_RECEIVER;
+ case ActivityManager.PROCESS_STATE_HOME:
+ return ActivityManagerProto.PROCESS_STATE_HOME;
+ case ActivityManager.PROCESS_STATE_LAST_ACTIVITY:
+ return ActivityManagerProto.PROCESS_STATE_LAST_ACTIVITY;
+ case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
+ return ActivityManagerProto.PROCESS_STATE_CACHED_ACTIVITY;
+ case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
+ return ActivityManagerProto.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
+ case ActivityManager.PROCESS_STATE_CACHED_RECENT:
+ return ActivityManagerProto.PROCESS_STATE_CACHED_RECENT;
+ case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
+ return ActivityManagerProto.PROCESS_STATE_CACHED_EMPTY;
+ case ActivityManager.PROCESS_STATE_NONEXISTENT:
+ return ActivityManagerProto.PROCESS_STATE_NONEXISTENT;
+ default:
+ return -1;
+ }
+ }
+
public static void appendRamKb(StringBuilder sb, long ramKb) {
for (int j=0, fact=10; j<6; j++, fact*=10) {
if (ramKb < fact) {
diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java
index a1e594726c35..03e140de4ee0 100644
--- a/services/core/java/com/android/server/am/ProcessRecord.java
+++ b/services/core/java/com/android/server/am/ProcessRecord.java
@@ -679,6 +679,7 @@ final class ProcessRecord {
proto.write(ProcessRecordProto.ISOLATED_APP_ID, UserHandle.getAppId(uid));
}
}
+ proto.write(ProcessRecordProto.PERSISTENT, persistent);
proto.end(token);
}
diff --git a/services/core/java/com/android/server/am/UidRecord.java b/services/core/java/com/android/server/am/UidRecord.java
index 8efcb4f2990f..3886e5a9f965 100644
--- a/services/core/java/com/android/server/am/UidRecord.java
+++ b/services/core/java/com/android/server/am/UidRecord.java
@@ -18,13 +18,17 @@ package com.android.server.am;
import android.Manifest;
import android.app.ActivityManager;
+import android.app.ActivityManagerProto;
import android.content.pm.PackageManager;
import android.os.SystemClock;
import android.os.UserHandle;
import android.util.TimeUtils;
+import android.util.proto.ProtoOutputStream;
+import android.util.proto.ProtoUtils;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.am.proto.UidRecordProto;
/**
* Overall information about a uid that has actively running processes.
@@ -86,6 +90,22 @@ public final class UidRecord {
static final int CHANGE_CACHED = 1<<3;
static final int CHANGE_UNCACHED = 1<<4;
+ // Keep the enum lists in sync
+ private static int[] ORIG_ENUMS = new int[] {
+ CHANGE_GONE,
+ CHANGE_IDLE,
+ CHANGE_ACTIVE,
+ CHANGE_CACHED,
+ CHANGE_UNCACHED,
+ };
+ private static int[] PROTO_ENUMS = new int[] {
+ UidRecordProto.CHANGE_GONE,
+ UidRecordProto.CHANGE_IDLE,
+ UidRecordProto.CHANGE_ACTIVE,
+ UidRecordProto.CHANGE_CACHED,
+ UidRecordProto.CHANGE_UNCACHED,
+ };
+
static final class ChangeItem {
UidRecord uidRecord;
int uid;
@@ -125,6 +145,34 @@ public final class UidRecord {
}
}
+
+ void writeToProto(ProtoOutputStream proto, long fieldId) {
+ long token = proto.start(fieldId);
+ proto.write(UidRecordProto.HEX_HASH, Integer.toHexString(System.identityHashCode(this)));
+ proto.write(UidRecordProto.UID, uid);
+ proto.write(UidRecordProto.CURRENT, ProcessList.makeProcStateProtoEnum(curProcState));
+ proto.write(UidRecordProto.EPHEMERAL, ephemeral);
+ proto.write(UidRecordProto.FG_SERVICES, foregroundServices);
+ proto.write(UidRecordProto.WHILELIST, curWhitelist);
+ ProtoUtils.toDuration(proto, UidRecordProto.LAST_BACKGROUND_TIME,
+ lastBackgroundTime, SystemClock.elapsedRealtime());
+ proto.write(UidRecordProto.IDLE, idle);
+ if (lastReportedChange != 0) {
+ ProtoUtils.writeBitWiseFlagsToProtoEnum(proto, UidRecordProto.LAST_REPORTED_CHANGES,
+ lastReportedChange, ORIG_ENUMS, PROTO_ENUMS);
+ }
+ proto.write(UidRecordProto.NUM_PROCS, numProcs);
+
+ long seqToken = proto.start(UidRecordProto.NETWORK_STATE_UPDATE);
+ proto.write(UidRecordProto.ProcStateSequence.CURURENT, curProcStateSeq);
+ proto.write(UidRecordProto.ProcStateSequence.LAST_NETWORK_UPDATED,
+ lastNetworkUpdatedProcStateSeq);
+ proto.write(UidRecordProto.ProcStateSequence.LAST_DISPATCHED, lastDispatchedProcStateSeq);
+ proto.end(seqToken);
+
+ proto.end(token);
+ }
+
public String toString() {
StringBuilder sb = new StringBuilder(128);
sb.append("UidRecord{");
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index 5ada484e9e32..7b0c714b0b4e 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -83,6 +83,7 @@ import android.util.Slog;
import android.util.SparseArray;
import android.util.SparseIntArray;
import android.util.TimingsTraceLog;
+import android.util.proto.ProtoOutputStream;
import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
@@ -94,6 +95,7 @@ import com.android.internal.widget.LockPatternUtils;
import com.android.server.FgThread;
import com.android.server.LocalServices;
import com.android.server.SystemServiceManager;
+import com.android.server.am.proto.UserControllerProto;
import com.android.server.pm.UserManagerService;
import com.android.server.wm.WindowManagerService;
@@ -1844,6 +1846,36 @@ class UserController implements Handler.Callback {
}
}
+ void writeToProto(ProtoOutputStream proto, long fieldId) {
+ synchronized (mLock) {
+ long token = proto.start(fieldId);
+ for (int i = 0; i < mStartedUsers.size(); i++) {
+ UserState uss = mStartedUsers.valueAt(i);
+ final long uToken = proto.start(UserControllerProto.STARTED_USERS);
+ proto.write(UserControllerProto.User.ID, uss.mHandle.getIdentifier());
+ uss.writeToProto(proto, UserControllerProto.User.STATE);
+ proto.end(uToken);
+ }
+ for (int i = 0; i < mStartedUserArray.length; i++) {
+ proto.write(UserControllerProto.STARTED_USER_ARRAY, mStartedUserArray[i]);
+ }
+ for (int i = 0; i < mUserLru.size(); i++) {
+ proto.write(UserControllerProto.USER_LRU, mUserLru.get(i));
+ }
+ if (mUserProfileGroupIds.size() > 0) {
+ for (int i = 0; i < mUserProfileGroupIds.size(); i++) {
+ final long uToken = proto.start(UserControllerProto.USER_PROFILE_GROUP_IDS);
+ proto.write(UserControllerProto.UserProfile.USER,
+ mUserProfileGroupIds.keyAt(i));
+ proto.write(UserControllerProto.UserProfile.PROFILE,
+ mUserProfileGroupIds.valueAt(i));
+ proto.end(uToken);
+ }
+ }
+ proto.end(token);
+ }
+ }
+
void dump(PrintWriter pw, boolean dumpAll) {
synchronized (mLock) {
pw.println(" mStartedUsers:");
@@ -1868,10 +1900,6 @@ class UserController implements Handler.Callback {
pw.print(mUserLru.get(i));
}
pw.println("]");
- if (dumpAll) {
- pw.print(" mStartedUserArray: ");
- pw.println(Arrays.toString(mStartedUserArray));
- }
if (mUserProfileGroupIds.size() > 0) {
pw.println(" mUserProfileGroupIds:");
for (int i=0; i< mUserProfileGroupIds.size(); i++) {
diff --git a/services/core/java/com/android/server/am/UserState.java b/services/core/java/com/android/server/am/UserState.java
index d36d9cbef930..00597e242d79 100644
--- a/services/core/java/com/android/server/am/UserState.java
+++ b/services/core/java/com/android/server/am/UserState.java
@@ -24,8 +24,10 @@ import android.os.Trace;
import android.os.UserHandle;
import android.util.ArrayMap;
import android.util.Slog;
+import android.util.proto.ProtoOutputStream;
import com.android.internal.util.ProgressReporter;
+import com.android.server.am.proto.UserStateProto;
import java.io.PrintWriter;
import java.util.ArrayList;
@@ -112,10 +114,29 @@ public final class UserState {
}
}
+ public static int stateToProtoEnum(int state) {
+ switch (state) {
+ case STATE_BOOTING: return UserStateProto.STATE_BOOTING;
+ case STATE_RUNNING_LOCKED: return UserStateProto.STATE_RUNNING_LOCKED;
+ case STATE_RUNNING_UNLOCKING: return UserStateProto.STATE_RUNNING_UNLOCKING;
+ case STATE_RUNNING_UNLOCKED: return UserStateProto.STATE_RUNNING_UNLOCKED;
+ case STATE_STOPPING: return UserStateProto.STATE_STOPPING;
+ case STATE_SHUTDOWN: return UserStateProto.STATE_SHUTDOWN;
+ default: return state;
+ }
+ }
+
void dump(String prefix, PrintWriter pw) {
pw.print(prefix);
pw.print("state="); pw.print(stateToString(state));
if (switching) pw.print(" SWITCHING");
pw.println();
}
+
+ void writeToProto(ProtoOutputStream proto, long fieldId) {
+ final long token = proto.start(fieldId);
+ proto.write(UserStateProto.STATE, stateToProtoEnum(state));
+ proto.write(UserStateProto.SWITCHING, switching);
+ proto.end(token);
+ }
}
diff --git a/services/core/java/com/android/server/am/VrController.java b/services/core/java/com/android/server/am/VrController.java
index feddfe3a2169..d32db7ea2ed9 100644
--- a/services/core/java/com/android/server/am/VrController.java
+++ b/services/core/java/com/android/server/am/VrController.java
@@ -20,7 +20,11 @@ import android.content.ComponentName;
import android.os.Process;
import android.service.vr.IPersistentVrStateCallbacks;
import android.util.Slog;
+import android.util.proto.ProtoOutputStream;
+import android.util.proto.ProtoUtils;
+
import com.android.server.LocalServices;
+import com.android.server.am.proto.ProcessesProto.VrControllerProto;
import com.android.server.vr.VrManagerInternal;
/**
@@ -49,6 +53,18 @@ final class VrController {
private static final int FLAG_VR_MODE = 1;
private static final int FLAG_PERSISTENT_VR_MODE = 2;
+ // Keep the enum lists in sync
+ private static int[] ORIG_ENUMS = new int[] {
+ FLAG_NON_VR_MODE,
+ FLAG_VR_MODE,
+ FLAG_PERSISTENT_VR_MODE,
+ };
+ private static int[] PROTO_ENUMS = new int[] {
+ VrControllerProto.FLAG_NON_VR_MODE,
+ VrControllerProto.FLAG_VR_MODE,
+ VrControllerProto.FLAG_PERSISTENT_VR_MODE,
+ };
+
// Invariants maintained for mVrState
//
// Always true:
@@ -420,4 +436,12 @@ final class VrController {
public String toString() {
return String.format("[VrState=0x%x,VrRenderThreadTid=%d]", mVrState, mVrRenderThreadTid);
}
+
+ void writeToProto(ProtoOutputStream proto, long fieldId) {
+ final long token = proto.start(fieldId);
+ ProtoUtils.writeBitWiseFlagsToProtoEnum(proto, VrControllerProto.VR_MODE,
+ mVrState, ORIG_ENUMS, PROTO_ENUMS);
+ proto.write(VrControllerProto.RENDER_THREAD_ID, mVrRenderThreadTid);
+ proto.end(token);
+ }
}
diff --git a/services/core/java/com/android/server/notification/ManagedServices.java b/services/core/java/com/android/server/notification/ManagedServices.java
index 42093e87e455..502760a2cfc4 100644
--- a/services/core/java/com/android/server/notification/ManagedServices.java
+++ b/services/core/java/com/android/server/notification/ManagedServices.java
@@ -254,13 +254,11 @@ abstract public class ManagedServices {
for (ComponentName cmpt : mEnabledServicesForCurrentProfiles) {
if (filter != null && !filter.matches(cmpt)) continue;
-
cmpt.writeToProto(proto, ManagedServicesProto.ENABLED);
}
for (ManagedServiceInfo info : mServices) {
if (filter != null && !filter.matches(info.component)) continue;
-
info.writeToProto(proto, ManagedServicesProto.LIVE_SERVICES, this);
}
@@ -1145,13 +1143,11 @@ abstract public class ManagedServices {
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);
}