diff --git a/protos/third_party/android/frameworks/base/proto/tracing/frameworks_base_common.proto b/protos/third_party/android/frameworks/base/proto/tracing/frameworks_base_common.proto index 92da942a3a..c1adecf65f 100644 --- a/protos/third_party/android/frameworks/base/proto/tracing/frameworks_base_common.proto +++ b/protos/third_party/android/frameworks/base/proto/tracing/frameworks_base_common.proto @@ -57,6 +57,20 @@ enum UnfreezeReason { UFR_OOM_ADJ_REASON_BATCH_UPDATE_REQUEST = 33; } +enum ProcessGroup { + PROCESS_GROUP_UNSPECIFIED = 0; + PROCESS_GROUP_DEFAULT = 1; + PROCESS_GROUP_BACKGROUND = 2; + PROCESS_GROUP_FOREGROUND = 3; + PROCESS_GROUP_SYSTEM = 4; + PROCESS_GROUP_AUDIO_APP = 5; + PROCESS_GROUP_AUDIO_SYS = 6; + PROCESS_GROUP_TOP_APP = 7; + PROCESS_GROUP_RT_APP = 8; + PROCESS_GROUP_RESTRICTED = 9; + PROCESS_GROUP_FOREGROUND_WINDOW = 10; +} + enum SchedGroup { SCHED_GROUP_UNSPECIFIED = 0; SCHED_GROUP_BACKGROUND = 1; diff --git a/protos/third_party/android/frameworks/base/proto/tracing/frameworks_base_track_event.proto b/protos/third_party/android/frameworks/base/proto/tracing/frameworks_base_track_event.proto index 4249d8611b..5979b469ef 100644 --- a/protos/third_party/android/frameworks/base/proto/tracing/frameworks_base_track_event.proto +++ b/protos/third_party/android/frameworks/base/proto/tracing/frameworks_base_track_event.proto @@ -775,6 +775,12 @@ message AndroidProcessStateChangedEvent { // Current ActivityManager scheduling group (Constants.SCHED_GROUP_*). optional SchedGroup cur_sched_group = 15; + + // Previous kernel process group (android.os.Process.THREAD_GROUP_*). + optional ProcessGroup prev_process_group = 16; + + // Current kernel process group (android.os.Process.THREAD_GROUP_*). + optional ProcessGroup cur_process_group = 17; } message AndroidServiceStateChangedEvent { diff --git a/src/trace_processor/plugins/android_process_state/android_process_state_module.cc b/src/trace_processor/plugins/android_process_state/android_process_state_module.cc index ea19e5514a..11f914fdb2 100644 --- a/src/trace_processor/plugins/android_process_state/android_process_state_module.cc +++ b/src/trace_processor/plugins/android_process_state/android_process_state_module.cc @@ -64,27 +64,38 @@ void AndroidProcessStateTracker::ParseChange(int64_t ts, static_cast(p.uid())); } - // Record the prev_* state of this process's earliest delta. + // Record the prev_* state of this process's earliest delta per-field. EarliestDelta& earliest = earliest_prev_[upid]; - if (ts < earliest.ts) { - earliest.ts = ts; - earliest.values.upid = upid; - earliest.values.pid = pid; - if (p.has_uid()) { - earliest.values.uid = p.uid(); - } - if (p.has_prev_proc_state()) { - earliest.values.proc_state = static_cast(p.prev_proc_state()); - } - if (p.has_prev_oom_score()) { - earliest.values.oom_score = p.prev_oom_score(); - } - if (p.has_prev_capability_flags()) { - earliest.values.capability_flags = p.prev_capability_flags(); - } - if (p.has_prev_sched_group()) { - earliest.values.sched_group = static_cast(p.prev_sched_group()); - } + earliest.upid = upid; + earliest.pid = pid; + if (p.has_uid()) { + earliest.uid = p.uid(); + } + bool is_oom_event = p.has_cur_proc_state() || p.has_cur_oom_score() || + p.has_reason() || p.has_cur_capability_flags(); + + if (p.has_prev_proc_state() && ts < earliest.proc_state_ts) { + earliest.proc_state = static_cast(p.prev_proc_state()); + earliest.proc_state_ts = ts; + } + if (p.has_prev_oom_score() && ts < earliest.oom_score_ts) { + earliest.oom_score = p.prev_oom_score(); + earliest.oom_score_ts = ts; + } + if (p.has_prev_capability_flags() && ts < earliest.capability_flags_ts) { + earliest.capability_flags = p.prev_capability_flags(); + earliest.capability_flags_ts = ts; + } + if (p.has_prev_sched_group() && ts < earliest.sched_group_ts) { + earliest.sched_group = static_cast(p.prev_sched_group()); + earliest.sched_group_ts = ts; + } else if (p.has_prev_proc_state() && ts < earliest.sched_group_ts) { + earliest.sched_group = 0; + earliest.sched_group_ts = ts; + } + if (p.has_prev_process_group() && ts < earliest.process_group_ts) { + earliest.process_group = static_cast(p.prev_process_group()); + earliest.process_group_ts = ts; } // Insert the change row. @@ -107,10 +118,21 @@ void AndroidProcessStateTracker::ParseChange(int64_t ts, if (p.has_cur_capability_flags()) { row.capability_flags = p.cur_capability_flags(); } + if (p.has_cur_process_group()) { + row.process_group = + InternEnum(process_group_cache_, ".com.android.internal.ProcessGroup", + static_cast(p.cur_process_group())); + } else if (!is_oom_event) { + row.process_group = InternEnum(process_group_cache_, + ".com.android.internal.ProcessGroup", 0); + } if (p.has_cur_sched_group()) { row.sched_group = InternEnum(sched_group_cache_, ".com.android.internal.SchedGroup", static_cast(p.cur_sched_group())); + } else if (is_oom_event) { + row.sched_group = + InternEnum(sched_group_cache_, ".com.android.internal.SchedGroup", 0); } if (p.has_reason()) { row.reason = @@ -139,30 +161,49 @@ void AndroidProcessStateTracker::ParseDump(protozero::ConstBytes blob) { context_->process_tracker->SetProcessUid(v.upid, static_cast(*v.uid)); } - if (rec.has_proc_state()) { - v.proc_state = static_cast(rec.proc_state()); - } - if (rec.has_oom_score()) { - v.oom_score = rec.oom_score(); - } - if (rec.has_capability_flags()) { - v.capability_flags = rec.capability_flags(); - } - if (rec.has_sched_group()) { - v.sched_group = static_cast(rec.sched_group()); - } + v.proc_state = + rec.has_proc_state() ? static_cast(rec.proc_state()) : 0; + v.oom_score = rec.has_oom_score() ? rec.oom_score() : 0; + v.capability_flags = + rec.has_capability_flags() ? rec.capability_flags() : 0; + v.sched_group = + rec.has_sched_group() ? static_cast(rec.sched_group()) : 0; + v.process_group = 0; dump_[v.upid] = v; } } void AndroidProcessStateTracker::Finalize() { - // Start from the trace-stop dump (the initial state of every process that did - // not change), then let a changed process's earliest-delta prev_* override - // it. + // Start from the trace-stop dump (the final state of every process that did + // not change). std::map initial = dump_; + + // Merge in each earliest-delta prev_* field (which takes precedence over + // dump_ because it reflects the starting state before the first transition). for (const auto& [upid, earliest] : earliest_prev_) { - initial[upid] = earliest.values; + auto& v = initial[upid]; + v.upid = upid; + v.pid = earliest.pid; + if (earliest.uid.has_value()) { + v.uid = earliest.uid; + } + if (earliest.proc_state.has_value()) { + v.proc_state = earliest.proc_state; + } + if (earliest.oom_score.has_value()) { + v.oom_score = earliest.oom_score; + } + if (earliest.capability_flags.has_value()) { + v.capability_flags = earliest.capability_flags; + } + if (earliest.sched_group.has_value()) { + v.sched_group = earliest.sched_group; + } + if (earliest.process_group.has_value()) { + v.process_group = earliest.process_group; + } } + for (const auto& [upid, v] : initial) { EmitInitialRow(v); } @@ -177,21 +218,17 @@ void AndroidProcessStateTracker::EmitInitialRow(const ProcessStateValues& v) { } row.ts = std::nullopt; row.is_initial = 1; - if (v.proc_state.has_value()) { - row.proc_state = - InternEnum(proc_state_cache_, ".com.android.internal.ProcessStateEnum", - *v.proc_state); - } - if (v.oom_score.has_value()) { - row.oom_score = *v.oom_score; - } - if (v.capability_flags.has_value()) { - row.capability_flags = *v.capability_flags; - } - if (v.sched_group.has_value()) { - row.sched_group = InternEnum( - sched_group_cache_, ".com.android.internal.SchedGroup", *v.sched_group); - } + int32_t ps = v.proc_state.value_or(0); + row.proc_state = InternEnum(proc_state_cache_, + ".com.android.internal.ProcessStateEnum", ps); + row.oom_score = v.oom_score.value_or(0); + row.capability_flags = v.capability_flags.value_or(0); + int32_t pg = v.process_group.value_or(0); + row.process_group = InternEnum(process_group_cache_, + ".com.android.internal.ProcessGroup", pg); + int32_t sg = v.sched_group.value_or(0); + row.sched_group = + InternEnum(sched_group_cache_, ".com.android.internal.SchedGroup", sg); process_state_table_->Insert(row); } diff --git a/src/trace_processor/plugins/android_process_state/android_process_state_module.h b/src/trace_processor/plugins/android_process_state/android_process_state_module.h index 3dd1ca9570..cf98de5aed 100644 --- a/src/trace_processor/plugins/android_process_state/android_process_state_module.h +++ b/src/trace_processor/plugins/android_process_state/android_process_state_module.h @@ -62,12 +62,24 @@ class AndroidProcessStateTracker { std::optional oom_score; std::optional proc_state; std::optional capability_flags; + std::optional process_group; std::optional sched_group; }; struct EarliestDelta { - int64_t ts = std::numeric_limits::max(); - ProcessStateValues values; + UniquePid upid = 0; + int32_t pid = 0; + std::optional uid; + std::optional oom_score; + int64_t oom_score_ts = std::numeric_limits::max(); + std::optional proc_state; + int64_t proc_state_ts = std::numeric_limits::max(); + std::optional capability_flags; + int64_t capability_flags_ts = std::numeric_limits::max(); + std::optional process_group; + int64_t process_group_ts = std::numeric_limits::max(); + std::optional sched_group; + int64_t sched_group_ts = std::numeric_limits::max(); }; void EmitInitialRow(const ProcessStateValues& v); @@ -81,6 +93,7 @@ class AndroidProcessStateTracker { DescriptorPool::CachedDescriptor proc_state_cache_; DescriptorPool::CachedDescriptor reason_cache_; + DescriptorPool::CachedDescriptor process_group_cache_; DescriptorPool::CachedDescriptor sched_group_cache_; std::map earliest_prev_; diff --git a/src/trace_processor/plugins/android_process_state/tables.py b/src/trace_processor/plugins/android_process_state/tables.py index 24bd0dc09c..e4e17f89b4 100644 --- a/src/trace_processor/plugins/android_process_state/tables.py +++ b/src/trace_processor/plugins/android_process_state/tables.py @@ -35,6 +35,7 @@ C('capability_flags', CppOptional(CppInt32())), C('reason', CppOptional(CppString())), C('seq_id', CppOptional(CppInt64())), + C('process_group', CppOptional(CppString())), C('sched_group', CppOptional(CppString())), C('is_initial', CppOptional(CppUint32())), ], @@ -56,6 +57,8 @@ 'OOM score.', 'capability_flags': 'Capability flags.', + 'process_group': + 'Kernel process group enum name or value.', 'sched_group': 'ActivityManager scheduling group enum name or value.', 'reason':