App 2.19.1: Foreground apps diagnostic on the Logs tab

Read-only: recent foreground apps (usage events), open tasks,
policy_control and the status bar height, for finding the CarPlay
package before a full-screen experiment.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-23 20:30:54 +02:00
co-authored by Claude Opus 5.5
parent 461f9d5578
commit 209a231511
9 changed files with 345 additions and 7 deletions
@@ -203,6 +203,46 @@ public class MainActivity extends AppCompatActivity {
}
((TextView) findViewById(R.id.header_title)).setText(PAGE_TITLES[position]);
((TextView) findViewById(R.id.header_subtitle)).setText(PAGE_SUBTITLES[position]);
if (panes != null && panes[position] == logPane) refreshForeground();
}
private TextView foregroundText;
private final java.util.concurrent.ExecutorService diagReader =
java.util.concurrent.Executors.newSingleThreadExecutor(r -> new Thread(r, "foreground-read"));
/** Logs tab diagnostic: reads which apps were in front, off the main thread. Changes nothing. */
private void refreshForeground() {
if (foregroundText == null) return;
try {
diagReader.execute(() -> {
ForegroundProbe.Result r = ForegroundProbe.read(getApplicationContext());
runOnUiThread(() -> { if (!isDestroyed()) foregroundText.setText(foregroundReport(r)); });
});
} catch (java.util.concurrent.RejectedExecutionException ignored) {
// Activity going away.
}
}
private String foregroundReport(ForegroundProbe.Result r) {
StringBuilder sb = new StringBuilder();
if (r.recent == null) {
sb.append(getString(R.string.foreground_unavailable)).append('\n');
} else if (r.recent.isEmpty()) {
sb.append(getString(R.string.foreground_none)).append('\n');
} else {
sb.append(getString(R.string.foreground_recent)).append('\n');
for (String line : r.recent) sb.append(line).append('\n');
}
if (!r.tasks.isEmpty()) {
sb.append('\n').append(getString(R.string.foreground_tasks)).append('\n');
for (String t : r.tasks) sb.append(t).append('\n');
}
sb.append('\n').append(getString(R.string.foreground_policy,
r.policyControl == null ? getString(R.string.foreground_policy_unset) : r.policyControl));
if (r.statusBarPx != null) {
sb.append('\n').append(getString(R.string.foreground_status_bar, r.statusBarPx));
}
return sb.toString();
}
/** Refreshes state + call log while the screen is visible. */
@@ -255,6 +295,8 @@ public class MainActivity extends AppCompatActivity {
statusText = servicePane.findViewById(R.id.status_text);
callLogText = logPane.findViewById(R.id.call_log_text);
logPane.findViewById(R.id.flush_now_button).setOnClickListener(v -> manualFlush());
foregroundText = logPane.findViewById(R.id.foreground_text);
logPane.findViewById(R.id.foreground_refresh_button).setOnClickListener(v -> refreshForeground());
setUpPager();
// Back on the page that was open when the activity was recreated (accent colour change).
@@ -343,6 +385,11 @@ public class MainActivity extends AppCompatActivity {
// Poll state and log only while the screen is up; onPause cancels it.
uiHandler.post(uiRefresh);
uiHandler.post(overviewRefresh);
// Back from another app (CarPlay) on the Logs tab: show where we were.
if (panes != null) {
ViewPager2 pager = findViewById(R.id.content);
if (panes[pager.getCurrentItem()] == logPane) refreshForeground();
}
}
@Override
@@ -395,6 +442,7 @@ public class MainActivity extends AppCompatActivity {
@Override
protected void onDestroy() {
carReader.shutdownNow();
diagReader.shutdownNow();
super.onDestroy();
}