diff options
| author | 2017-11-28 14:23:56 -0800 | |
|---|---|---|
| committer | 2018-01-23 16:49:58 -0800 | |
| commit | 148d7f4291d675fc17852d530be32b7dba06fc93 (patch) | |
| tree | 269619facc7ef65d2bec11d968b6df1cb49d677f | |
| parent | 5dd54fdfb6df623c85bfdafc87b578750160f455 (diff) | |
Implement activity --proto --processes
Bug: 66729158
Test: out/host/linux-x86/bin/incident_report -w amprocesses
Change-Id: Iae043203bca954bfc4aadad0460cc56621e9ba05
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); } |