Improve Debug Report with condition performance and event activity - #1081
Open
vibhor1102 wants to merge 13 commits into
Open
Improve Debug Report with condition performance and event activity#1081vibhor1102 wants to merge 13 commits into
vibhor1102 wants to merge 13 commits into
Conversation
vibhor1102
marked this pull request as draft
August 29, 2026 15:43
vibhor1102
marked this pull request as ready for review
August 30, 2026 08:45
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR completes the Debug Report work started in the foundation-only draft #1065.
It adds the per-condition performance UI proposed in discussion #1064, together with the practical report improvements proposed in discussion #958: Event activity, detection/action timing, faster navigation, clearer filtering, and consistent sorting interactions.
The low-level measurement architecture and its real-device overhead validation are documented in #1065.
Conditions tab
Debug Report now has a third tab dedicated to condition performance. Enabling Debug Report generation automatically collects the data; there is no separate profiling mode.
Every condition currently configured in the Scenario is listed, including conditions that were not reached because of event ordering, disabled paths, or AND/OR short-circuiting. Each card shows:
The list can be sorted by total time, average per check, check count, or Scenario order. Total time is the default because it most directly identifies the conditions with the greatest overall effect. Durations use four meaningful digits, very small non-zero measurements remain visible, and an explanatory footer defines the percentage denominator.
In the rare case where a report persists across an app update from before condition profiling was introduced, missing profile data is treated as empty data so the report still opens safely.
Event activity
Overview now contains an Event activity summary showing:
Opening the summary displays a detailed list separated into Screen Events and Trigger Events. Configured events with no occurrences remain visible in a subdued state, which helps distinguish an unreached event from one missing from the Scenario.
The detailed list can be sorted by Scenario order, most frequent, or first execution. Counts are derived from the existing report occurrences, so this feature does not record duplicate event data.
Timeline timing
Timeline occurrences now use the moment their conditions become fulfilled as their timestamp, instead of the later point at which their actions have completed.
Each modern Timeline card replaces the absolute timestamp with two elapsed phases:
+175.9 ms detecting: elapsed time from the previous event's action completion (or Scenario start for the first event) until this event is fulfilled;+86.9 ms actions: elapsed time from fulfillment until this event's actions and immediate processing are complete.Detection and action timings therefore belong to the event that performed them and form one continuous sequence without losing the time between occurrences. Values remain in milliseconds for direct comparison. Events without actions omit the action row.
The exact millisecond detection timestamp remains available in the event-occurrence details, alongside its frame or trigger metadata. Legacy reports retain their existing timestamp under the neutral Recorded at label and do not display a fabricated detection/action split.
Overview also shows Execution Limiter idle time as the percentage of detection-related time deliberately spent waiting for the limiter. Event action phases are excluded from its denominator.
Timeline and report navigation
Scope notes
Verification
master.FAQ
Why is condition performance a third tab while Event activity opens from Overview?
Event activity is a compact aggregate extension of the existing Overview. Condition performance is a larger analytical view containing visuals, several metrics, sorting, unreached conditions, and explanatory context. A dedicated tab keeps that information accessible without overloading Overview.
What exactly does a condition percentage represent?
It is the condition's cumulative duration divided by the sum of all recorded condition durations. It is not a percentage of total Scenario time, CPU use, battery use, or system activity.
Why are detection and action time shown separately?
The interval between two fulfilled events can contain both the previous event's actions and work spent finding the next event. Assigning the complete interval to either event would be misleading. Capturing fulfillment and action-completion boundaries lets every action duration remain with the event that executed those actions.
Why is Timeline detection time not calculated from the condition profiler?
Condition profiles are aggregate totals intended to identify expensive conditions. They cannot reconstruct an individual occurrence's boundaries or account for unsuccessful event checks, frame waiting, Execution Limiter waiting, and other processing between fulfilled events. Timeline timing therefore uses dedicated monotonic per-occurrence boundaries.
What is included in “detecting”?
It is elapsed time spent reaching the next fulfilled event, not a claim about CPU-active time alone. It includes condition processing, unsuccessful checks, frame waiting, Execution Limiter waiting, and intervening processing. Keeping those parts together gives users a simple, continuous Timeline while the Conditions tab provides the detailed performance breakdown they can act on.
How do the Timeline durations avoid gaps or overlap?
For the first occurrence, detection starts at the report session boundary. Afterwards it starts at the previous occurrence's action-completion boundary. Action time starts at the current occurrence's fulfillment boundary and ends at its own completion boundary. All values use the same monotonic clock, so consecutive phases meet exactly. Any time after the final occurrence remains outside the Timeline because there is no later event card to own it.
Why are unreached conditions and events shown?
Zero checks or occurrences can be diagnostically important. Keeping configured entries visible lets the user distinguish “present but never reached” from “not configured,” and it makes Scenario-order views complete.
Why derive Event activity from Timeline occurrences?
The report already records every event occurrence needed for these counts. Deriving the summary avoids another stored aggregate and prevents two sources of event-count data from disagreeing.
How are duplicate names and overlapping IDs handled?
Condition entries use their database IDs. Event activity identifies an event by both its event type and database ID, so Screen and Trigger Events with the same numeric ID cannot merge. Names are display metadata and do not determine identity.
Why use anchored sort popups?
The available sort choices are short and immediately applicable. An anchored popup keeps the underlying report visible, clearly marks the current selection, and avoids a full-screen dialog in landscape.
Why preserve the viewport position rather than the visible card when sorting?
Sorting is expected to rearrange the content beneath a stationary viewport. Following the previously visible card to its new location caused unexpected jumps through the list and made the new order harder to inspect.
Why use a custom scrollbar instead of RecyclerView's normal indicator?
The normal indicator is visual only and can become extremely small on long reports. The custom view provides a minimum draggable thumb, a larger touch corridor, continuous scrolling, and explicit drag feedback while leaving RecyclerView as the source of scroll state.
How do older reports behave?
The added protobuf fields use new field numbers, so existing Overview and Timeline data remain readable. If condition-profile data is absent, it falls back to empty data and the report remains safe to open. If the new occurrence boundaries are absent, Timeline keeps the legacy recorded timestamp and does not invent detection or action durations.
Where should the profiling architecture itself be reviewed?
The measurement boundary, disabled-path behavior, bounded aggregation, protobuf storage, benchmark design, and overhead interpretation are covered in #1065.